aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include
diff options
context:
space:
mode:
authorGraf Yang <graf.yang@analog.com>2008-11-18 04:48:22 -0500
committerBryan Wu <cooloney@kernel.org>2008-11-18 04:48:22 -0500
commitb8a989893cbdeb6c97a7b5af5f38fb0e480235f9 (patch)
tree658cf6df93dac687f0d6b94111d0f53b3dd0177c /arch/blackfin/include
parent6b3087c64a92a36ae20d33479b4df6d7afc910d4 (diff)
Blackfin arch: SMP supporting patchset: Blackfin CPLB related code
Blackfin dual core BF561 processor can support SMP like features. https://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:smp-like In this patch, we provide SMP extend to Blackfin CPLB related code Signed-off-by: Graf Yang <graf.yang@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/include')
-rw-r--r--arch/blackfin/include/asm/cplb-mpu.h15
-rw-r--r--arch/blackfin/include/asm/cplb.h21
-rw-r--r--arch/blackfin/include/asm/cplbinit.h57
-rw-r--r--arch/blackfin/include/asm/mmu_context.h27
4 files changed, 86 insertions, 34 deletions
diff --git a/arch/blackfin/include/asm/cplb-mpu.h b/arch/blackfin/include/asm/cplb-mpu.h
index 75c67b99d607..80680ad7a378 100644
--- a/arch/blackfin/include/asm/cplb-mpu.h
+++ b/arch/blackfin/include/asm/cplb-mpu.h
@@ -28,6 +28,7 @@
28 */ 28 */
29#ifndef __ASM_BFIN_CPLB_MPU_H 29#ifndef __ASM_BFIN_CPLB_MPU_H
30#define __ASM_BFIN_CPLB_MPU_H 30#define __ASM_BFIN_CPLB_MPU_H
31#include <linux/threads.h>
31 32
32struct cplb_entry { 33struct cplb_entry {
33 unsigned long data, addr; 34 unsigned long data, addr;
@@ -39,22 +40,22 @@ struct mem_region {
39 unsigned long icplb_data; 40 unsigned long icplb_data;
40}; 41};
41 42
42extern struct cplb_entry dcplb_tbl[MAX_CPLBS]; 43extern struct cplb_entry dcplb_tbl[NR_CPUS][MAX_CPLBS];
43extern struct cplb_entry icplb_tbl[MAX_CPLBS]; 44extern struct cplb_entry icplb_tbl[NR_CPUS][MAX_CPLBS];
44extern int first_switched_icplb; 45extern int first_switched_icplb;
45extern int first_mask_dcplb; 46extern int first_mask_dcplb;
46extern int first_switched_dcplb; 47extern int first_switched_dcplb;
47 48
48extern int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot; 49extern int nr_dcplb_miss[], nr_icplb_miss[], nr_icplb_supv_miss[];
49extern int nr_cplb_flush; 50extern int nr_dcplb_prot[], nr_cplb_flush[];
50 51
51extern int page_mask_order; 52extern int page_mask_order;
52extern int page_mask_nelts; 53extern int page_mask_nelts;
53 54
54extern unsigned long *current_rwx_mask; 55extern unsigned long *current_rwx_mask[NR_CPUS];
55 56
56extern void flush_switched_cplbs(void); 57extern void flush_switched_cplbs(unsigned int);
57extern void set_mask_dcplbs(unsigned long *); 58extern void set_mask_dcplbs(unsigned long *, unsigned int);
58 59
59extern void __noreturn panic_cplb_error(int seqstat, struct pt_regs *); 60extern void __noreturn panic_cplb_error(int seqstat, struct pt_regs *);
60 61
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h
index 9e8b4035fcec..5f7545d06200 100644
--- a/arch/blackfin/include/asm/cplb.h
+++ b/arch/blackfin/include/asm/cplb.h
@@ -30,7 +30,6 @@
30#ifndef _CPLB_H 30#ifndef _CPLB_H
31#define _CPLB_H 31#define _CPLB_H
32 32
33#include <asm/blackfin.h>
34#include <mach/anomaly.h> 33#include <mach/anomaly.h>
35 34
36#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO) 35#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
@@ -55,13 +54,24 @@
55#endif 54#endif
56 55
57#define L1_DMEMORY (CPLB_LOCK | CPLB_COMMON) 56#define L1_DMEMORY (CPLB_LOCK | CPLB_COMMON)
57
58#ifdef CONFIG_SMP
59#define L2_ATTR (INITIAL_T | I_CPLB | D_CPLB)
60#define L2_IMEMORY (CPLB_COMMON | CPLB_LOCK)
61#define L2_DMEMORY (CPLB_COMMON | CPLB_LOCK)
62
63#else
58#ifdef CONFIG_BFIN_L2_CACHEABLE 64#ifdef CONFIG_BFIN_L2_CACHEABLE
59#define L2_IMEMORY (SDRAM_IGENERIC) 65#define L2_IMEMORY (SDRAM_IGENERIC)
60#define L2_DMEMORY (SDRAM_DGENERIC) 66#define L2_DMEMORY (SDRAM_DGENERIC)
61#else 67#else
62#define L2_IMEMORY (CPLB_COMMON) 68#define L2_IMEMORY (CPLB_COMMON)
63#define L2_DMEMORY (CPLB_COMMON) 69#define L2_DMEMORY (CPLB_COMMON)
64#endif 70#endif /* CONFIG_BFIN_L2_CACHEABLE */
71
72#define L2_ATTR (INITIAL_T | SWITCH_T | I_CPLB | D_CPLB)
73#endif /* CONFIG_SMP */
74
65#define SDRAM_DNON_CHBL (CPLB_COMMON) 75#define SDRAM_DNON_CHBL (CPLB_COMMON)
66#define SDRAM_EBIU (CPLB_COMMON) 76#define SDRAM_EBIU (CPLB_COMMON)
67#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY) 77#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
@@ -71,14 +81,7 @@
71#define SIZE_1M 0x00100000 /* 1M */ 81#define SIZE_1M 0x00100000 /* 1M */
72#define SIZE_4M 0x00400000 /* 4M */ 82#define SIZE_4M 0x00400000 /* 4M */
73 83
74#ifdef CONFIG_MPU
75#define MAX_CPLBS 16 84#define MAX_CPLBS 16
76#else
77#define MAX_CPLBS (16 * 2)
78#endif
79
80#define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
81 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)
82 85
83#define CPLB_ENABLE_ICACHE_P 0 86#define CPLB_ENABLE_ICACHE_P 0
84#define CPLB_ENABLE_DCACHE_P 1 87#define CPLB_ENABLE_DCACHE_P 1
diff --git a/arch/blackfin/include/asm/cplbinit.h b/arch/blackfin/include/asm/cplbinit.h
index f845b41147ba..6bfc25788161 100644
--- a/arch/blackfin/include/asm/cplbinit.h
+++ b/arch/blackfin/include/asm/cplbinit.h
@@ -36,6 +36,8 @@
36#ifdef CONFIG_MPU 36#ifdef CONFIG_MPU
37 37
38#include <asm/cplb-mpu.h> 38#include <asm/cplb-mpu.h>
39extern void bfin_icache_init(struct cplb_entry *icplb_tbl);
40extern void bfin_dcache_init(struct cplb_entry *icplb_tbl);
39 41
40#else 42#else
41 43
@@ -46,8 +48,40 @@
46 48
47#define IN_KERNEL 1 49#define IN_KERNEL 1
48 50
49enum 51#define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
50{ZERO_P, L1I_MEM, L1D_MEM, SDRAM_KERN , SDRAM_RAM_MTD, SDRAM_DMAZ, RES_MEM, ASYNC_MEM, L2_MEM}; 52 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)
53
54#define CPLB_MEM CONFIG_MAX_MEM_SIZE
55
56/*
57* Number of required data CPLB switchtable entries
58* MEMSIZE / 4 (we mostly install 4M page size CPLBs
59* approx 16 for smaller 1MB page size CPLBs for allignment purposes
60* 1 for L1 Data Memory
61* possibly 1 for L2 Data Memory
62* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
63* 1 for ASYNC Memory
64*/
65#define MAX_SWITCH_D_CPLBS (((CPLB_MEM / 4) + 16 + 1 + 1 + 1 \
66 + ASYNC_MEMORY_CPLB_COVERAGE) * 2)
67
68/*
69* Number of required instruction CPLB switchtable entries
70* MEMSIZE / 4 (we mostly install 4M page size CPLBs
71* approx 12 for smaller 1MB page size CPLBs for allignment purposes
72* 1 for L1 Instruction Memory
73* possibly 1 for L2 Instruction Memory
74* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
75*/
76#define MAX_SWITCH_I_CPLBS (((CPLB_MEM / 4) + 12 + 1 + 1 + 1) * 2)
77
78/* Number of CPLB table entries, used for cplb-nompu. */
79#define CPLB_TBL_ENTRIES (16 * 4)
80
81enum {
82 ZERO_P, L1I_MEM, L1D_MEM, L2_MEM, SDRAM_KERN, SDRAM_RAM_MTD, SDRAM_DMAZ,
83 RES_MEM, ASYNC_MEM, OCB_ROM
84};
51 85
52struct cplb_desc { 86struct cplb_desc {
53 u32 start; /* start address */ 87 u32 start; /* start address */
@@ -66,8 +100,8 @@ struct cplb_tab {
66 u16 size; 100 u16 size;
67}; 101};
68 102
69extern u_long icplb_table[]; 103extern u_long icplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];
70extern u_long dcplb_table[]; 104extern u_long dcplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];
71 105
72/* Till here we are discussing about the static memory management model. 106/* Till here we are discussing about the static memory management model.
73 * However, the operating envoronments commonly define more CPLB 107 * However, the operating envoronments commonly define more CPLB
@@ -78,15 +112,18 @@ extern u_long dcplb_table[];
78 * This is how Page descriptor Table is implemented in uClinux/Blackfin. 112 * This is how Page descriptor Table is implemented in uClinux/Blackfin.
79 */ 113 */
80 114
81extern u_long ipdt_table[]; 115extern u_long ipdt_tables[NR_CPUS][MAX_SWITCH_I_CPLBS+1];
82extern u_long dpdt_table[]; 116extern u_long dpdt_tables[NR_CPUS][MAX_SWITCH_D_CPLBS+1];
83#ifdef CONFIG_CPLB_INFO 117#ifdef CONFIG_CPLB_INFO
84extern u_long ipdt_swapcount_table[]; 118extern u_long ipdt_swapcount_tables[NR_CPUS][MAX_SWITCH_I_CPLBS];
85extern u_long dpdt_swapcount_table[]; 119extern u_long dpdt_swapcount_tables[NR_CPUS][MAX_SWITCH_D_CPLBS];
86#endif 120#endif
121extern void bfin_icache_init(u_long icplbs[]);
122extern void bfin_dcache_init(u_long dcplbs[]);
87 123
88#endif /* CONFIG_MPU */ 124#endif /* CONFIG_MPU */
89 125
90extern void generate_cplb_tables(void); 126#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
91 127extern void generate_cplb_tables_cpu(unsigned int cpu);
128#endif
92#endif 129#endif
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 35593dda2a4d..944e29faae48 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -37,6 +37,10 @@
37#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
38#include <asm/cplbinit.h> 38#include <asm/cplbinit.h>
39 39
40/* Note: L1 stacks are CPU-private things, so we bluntly disable this
41 feature in SMP mode, and use the per-CPU scratch SRAM bank only to
42 store the PDA instead. */
43
40extern void *current_l1_stack_save; 44extern void *current_l1_stack_save;
41extern int nr_l1stack_tasks; 45extern int nr_l1stack_tasks;
42extern void *l1_stack_base; 46extern void *l1_stack_base;
@@ -88,12 +92,15 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
88static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, 92static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
89 struct task_struct *tsk) 93 struct task_struct *tsk)
90{ 94{
95#ifdef CONFIG_MPU
96 unsigned int cpu = smp_processor_id();
97#endif
91 if (prev_mm == next_mm) 98 if (prev_mm == next_mm)
92 return; 99 return;
93#ifdef CONFIG_MPU 100#ifdef CONFIG_MPU
94 if (prev_mm->context.page_rwx_mask == current_rwx_mask) { 101 if (prev_mm->context.page_rwx_mask == current_rwx_mask[cpu]) {
95 flush_switched_cplbs(); 102 flush_switched_cplbs(cpu);
96 set_mask_dcplbs(next_mm->context.page_rwx_mask); 103 set_mask_dcplbs(next_mm->context.page_rwx_mask, cpu);
97 } 104 }
98#endif 105#endif
99 106
@@ -138,9 +145,10 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
138 145
139static inline void update_protections(struct mm_struct *mm) 146static inline void update_protections(struct mm_struct *mm)
140{ 147{
141 if (mm->context.page_rwx_mask == current_rwx_mask) { 148 unsigned int cpu = smp_processor_id();
142 flush_switched_cplbs(); 149 if (mm->context.page_rwx_mask == current_rwx_mask[cpu]) {
143 set_mask_dcplbs(mm->context.page_rwx_mask); 150 flush_switched_cplbs(cpu);
151 set_mask_dcplbs(mm->context.page_rwx_mask, cpu);
144 } 152 }
145} 153}
146#endif 154#endif
@@ -165,6 +173,9 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
165static inline void destroy_context(struct mm_struct *mm) 173static inline void destroy_context(struct mm_struct *mm)
166{ 174{
167 struct sram_list_struct *tmp; 175 struct sram_list_struct *tmp;
176#ifdef CONFIG_MPU
177 unsigned int cpu = smp_processor_id();
178#endif
168 179
169#ifdef CONFIG_APP_STACK_L1 180#ifdef CONFIG_APP_STACK_L1
170 if (current_l1_stack_save == mm->context.l1_stack_save) 181 if (current_l1_stack_save == mm->context.l1_stack_save)
@@ -179,8 +190,8 @@ static inline void destroy_context(struct mm_struct *mm)
179 kfree(tmp); 190 kfree(tmp);
180 } 191 }
181#ifdef CONFIG_MPU 192#ifdef CONFIG_MPU
182 if (current_rwx_mask == mm->context.page_rwx_mask) 193 if (current_rwx_mask[cpu] == mm->context.page_rwx_mask)
183 current_rwx_mask = NULL; 194 current_rwx_mask[cpu] = NULL;
184 free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order); 195 free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order);
185#endif 196#endif
186} 197}