aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/cplb-nompu
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/kernel/cplb-nompu
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/kernel/cplb-nompu')
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cacheinit.c9
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinfo.c55
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c89
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.S29
4 files changed, 85 insertions, 97 deletions
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
index bd0831592c2c..3a385aec67d5 100644
--- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
@@ -25,9 +25,9 @@
25#include <asm/cplbinit.h> 25#include <asm/cplbinit.h>
26 26
27#if defined(CONFIG_BFIN_ICACHE) 27#if defined(CONFIG_BFIN_ICACHE)
28void __init bfin_icache_init(void) 28void __cpuinit bfin_icache_init(u_long icplb[])
29{ 29{
30 unsigned long *table = icplb_table; 30 unsigned long *table = icplb;
31 unsigned long ctrl; 31 unsigned long ctrl;
32 int i; 32 int i;
33 33
@@ -47,9 +47,9 @@ void __init bfin_icache_init(void)
47#endif 47#endif
48 48
49#if defined(CONFIG_BFIN_DCACHE) 49#if defined(CONFIG_BFIN_DCACHE)
50void __init bfin_dcache_init(void) 50void __cpuinit bfin_dcache_init(u_long dcplb[])
51{ 51{
52 unsigned long *table = dcplb_table; 52 unsigned long *table = dcplb;
53 unsigned long ctrl; 53 unsigned long ctrl;
54 int i; 54 int i;
55 55
@@ -64,6 +64,7 @@ void __init bfin_dcache_init(void)
64 ctrl = bfin_read_DMEM_CONTROL(); 64 ctrl = bfin_read_DMEM_CONTROL();
65 ctrl |= DMEM_CNTR; 65 ctrl |= DMEM_CNTR;
66 bfin_write_DMEM_CONTROL(ctrl); 66 bfin_write_DMEM_CONTROL(ctrl);
67
67 SSYNC(); 68 SSYNC();
68} 69}
69#endif 70#endif
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinfo.c b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
index 1e74f0b97996..3f0080954e6f 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
@@ -68,22 +68,22 @@ static int cplb_find_entry(unsigned long *cplb_addr,
68 return -1; 68 return -1;
69} 69}
70 70
71static char *cplb_print_entry(char *buf, int type) 71static char *cplb_print_entry(char *buf, int type, unsigned int cpu)
72{ 72{
73 unsigned long *p_addr = dpdt_table; 73 unsigned long *p_addr = dpdt_tables[cpu];
74 unsigned long *p_data = dpdt_table + 1; 74 unsigned long *p_data = dpdt_tables[cpu] + 1;
75 unsigned long *p_icount = dpdt_swapcount_table; 75 unsigned long *p_icount = dpdt_swapcount_tables[cpu];
76 unsigned long *p_ocount = dpdt_swapcount_table + 1; 76 unsigned long *p_ocount = dpdt_swapcount_tables[cpu] + 1;
77 unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0; 77 unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
78 unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0; 78 unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
79 int entry = 0, used_cplb = 0; 79 int entry = 0, used_cplb = 0;
80 80
81 if (type == CPLB_I) { 81 if (type == CPLB_I) {
82 buf += sprintf(buf, "Instruction CPLB entry:\n"); 82 buf += sprintf(buf, "Instruction CPLB entry:\n");
83 p_addr = ipdt_table; 83 p_addr = ipdt_tables[cpu];
84 p_data = ipdt_table + 1; 84 p_data = ipdt_tables[cpu] + 1;
85 p_icount = ipdt_swapcount_table; 85 p_icount = ipdt_swapcount_tables[cpu];
86 p_ocount = ipdt_swapcount_table + 1; 86 p_ocount = ipdt_swapcount_tables[cpu] + 1;
87 cplb_addr = (unsigned long *)ICPLB_ADDR0; 87 cplb_addr = (unsigned long *)ICPLB_ADDR0;
88 cplb_data = (unsigned long *)ICPLB_DATA0; 88 cplb_data = (unsigned long *)ICPLB_DATA0;
89 } else 89 } else
@@ -134,24 +134,24 @@ static char *cplb_print_entry(char *buf, int type)
134 return buf; 134 return buf;
135} 135}
136 136
137static int cplbinfo_proc_output(char *buf) 137static int cplbinfo_proc_output(char *buf, void *data)
138{ 138{
139 unsigned int cpu = (unsigned int)data;
139 char *p; 140 char *p;
140 141
141 p = buf; 142 p = buf;
142 143
143 p += sprintf(p, "------------------ CPLB Information ------------------\n\n"); 144 p += sprintf(p, "------------- CPLB Information on CPU%u--------------\n\n", cpu);
144 145
145 if (bfin_read_IMEM_CONTROL() & ENICPLB) 146 if (bfin_read_IMEM_CONTROL() & ENICPLB)
146 p = cplb_print_entry(p, CPLB_I); 147 p = cplb_print_entry(p, CPLB_I, cpu);
147 else 148 else
148 p += sprintf(p, "Instruction CPLB is disabled.\n\n"); 149 p += sprintf(p, "Instruction CPLB is disabled.\n\n");
149 150
150 if (bfin_read_DMEM_CONTROL() & ENDCPLB) 151 if (bfin_read_DMEM_CONTROL() & ENDCPLB)
151 p = cplb_print_entry(p, CPLB_D); 152 p = cplb_print_entry(p, CPLB_D, cpu);
152 else 153 else
153 p += sprintf(p, "Data CPLB is disabled.\n"); 154 p += sprintf(p, "Data CPLB is disabled.\n");
154
155 return p - buf; 155 return p - buf;
156} 156}
157 157
@@ -160,7 +160,7 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off,
160{ 160{
161 int len; 161 int len;
162 162
163 len = cplbinfo_proc_output(page); 163 len = cplbinfo_proc_output(page, data);
164 if (len <= off + count) 164 if (len <= off + count)
165 *eof = 1; 165 *eof = 1;
166 *start = page + off; 166 *start = page + off;
@@ -174,20 +174,33 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off,
174 174
175static int __init cplbinfo_init(void) 175static int __init cplbinfo_init(void)
176{ 176{
177 struct proc_dir_entry *entry; 177 struct proc_dir_entry *parent, *entry;
178 unsigned int cpu;
179 unsigned char str[10];
180
181 parent = proc_mkdir("cplbinfo", NULL);
178 182
179 entry = create_proc_entry("cplbinfo", 0, NULL); 183 for_each_online_cpu(cpu) {
180 if (!entry) 184 sprintf(str, "cpu%u", cpu);
181 return -ENOMEM; 185 entry = create_proc_entry(str, 0, parent);
186 if (!entry)
187 return -ENOMEM;
182 188
183 entry->read_proc = cplbinfo_read_proc; 189 entry->read_proc = cplbinfo_read_proc;
184 entry->data = NULL; 190 entry->data = (void *)cpu;
191 }
185 192
186 return 0; 193 return 0;
187} 194}
188 195
189static void __exit cplbinfo_exit(void) 196static void __exit cplbinfo_exit(void)
190{ 197{
198 unsigned int cpu;
199 unsigned char str[20];
200 for_each_online_cpu(cpu) {
201 sprintf(str, "cplbinfo/cpu%u", cpu);
202 remove_proc_entry(str, NULL);
203 }
191 remove_proc_entry("cplbinfo", NULL); 204 remove_proc_entry("cplbinfo", NULL);
192} 205}
193 206
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 2debc900e246..8966c706b71a 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -27,46 +27,20 @@
27#include <asm/cplb.h> 27#include <asm/cplb.h>
28#include <asm/cplbinit.h> 28#include <asm/cplbinit.h>
29 29
30#define CPLB_MEM CONFIG_MAX_MEM_SIZE 30u_long icplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];
31 31u_long dcplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];
32/*
33* Number of required data CPLB switchtable entries
34* MEMSIZE / 4 (we mostly install 4M page size CPLBs
35* approx 16 for smaller 1MB page size CPLBs for allignment purposes
36* 1 for L1 Data Memory
37* possibly 1 for L2 Data Memory
38* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
39* 1 for ASYNC Memory
40*/
41#define MAX_SWITCH_D_CPLBS (((CPLB_MEM / 4) + 16 + 1 + 1 + 1 \
42 + ASYNC_MEMORY_CPLB_COVERAGE) * 2)
43
44/*
45* Number of required instruction CPLB switchtable entries
46* MEMSIZE / 4 (we mostly install 4M page size CPLBs
47* approx 12 for smaller 1MB page size CPLBs for allignment purposes
48* 1 for L1 Instruction Memory
49* possibly 1 for L2 Instruction Memory
50* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
51*/
52#define MAX_SWITCH_I_CPLBS (((CPLB_MEM / 4) + 12 + 1 + 1 + 1) * 2)
53
54
55u_long icplb_table[MAX_CPLBS + 1];
56u_long dcplb_table[MAX_CPLBS + 1];
57 32
58#ifdef CONFIG_CPLB_SWITCH_TAB_L1 33#ifdef CONFIG_CPLB_SWITCH_TAB_L1
59# define PDT_ATTR __attribute__((l1_data)) 34#define PDT_ATTR __attribute__((l1_data))
60#else 35#else
61# define PDT_ATTR 36#define PDT_ATTR
62#endif 37#endif
63 38
64u_long ipdt_table[MAX_SWITCH_I_CPLBS + 1] PDT_ATTR; 39u_long ipdt_tables[NR_CPUS][MAX_SWITCH_I_CPLBS+1] PDT_ATTR;
65u_long dpdt_table[MAX_SWITCH_D_CPLBS + 1] PDT_ATTR; 40u_long dpdt_tables[NR_CPUS][MAX_SWITCH_D_CPLBS+1] PDT_ATTR;
66
67#ifdef CONFIG_CPLB_INFO 41#ifdef CONFIG_CPLB_INFO
68u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS] PDT_ATTR; 42u_long ipdt_swapcount_tables[NR_CPUS][MAX_SWITCH_I_CPLBS] PDT_ATTR;
69u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS] PDT_ATTR; 43u_long dpdt_swapcount_tables[NR_CPUS][MAX_SWITCH_D_CPLBS] PDT_ATTR;
70#endif 44#endif
71 45
72struct s_cplb { 46struct s_cplb {
@@ -93,8 +67,8 @@ static struct cplb_desc cplb_data[] = {
93 .name = "Zero Pointer Guard Page", 67 .name = "Zero Pointer Guard Page",
94 }, 68 },
95 { 69 {
96 .start = L1_CODE_START, 70 .start = 0, /* dyanmic */
97 .end = L1_CODE_START + L1_CODE_LENGTH, 71 .end = 0, /* dynamic */
98 .psize = SIZE_4M, 72 .psize = SIZE_4M,
99 .attr = INITIAL_T | SWITCH_T | I_CPLB, 73 .attr = INITIAL_T | SWITCH_T | I_CPLB,
100 .i_conf = L1_IMEMORY, 74 .i_conf = L1_IMEMORY,
@@ -103,8 +77,8 @@ static struct cplb_desc cplb_data[] = {
103 .name = "L1 I-Memory", 77 .name = "L1 I-Memory",
104 }, 78 },
105 { 79 {
106 .start = L1_DATA_A_START, 80 .start = 0, /* dynamic */
107 .end = L1_DATA_B_START + L1_DATA_B_LENGTH, 81 .end = 0, /* dynamic */
108 .psize = SIZE_4M, 82 .psize = SIZE_4M,
109 .attr = INITIAL_T | SWITCH_T | D_CPLB, 83 .attr = INITIAL_T | SWITCH_T | D_CPLB,
110 .i_conf = 0, 84 .i_conf = 0,
@@ -117,6 +91,16 @@ static struct cplb_desc cplb_data[] = {
117 .name = "L1 D-Memory", 91 .name = "L1 D-Memory",
118 }, 92 },
119 { 93 {
94 .start = L2_START,
95 .end = L2_START + L2_LENGTH,
96 .psize = SIZE_1M,
97 .attr = L2_ATTR,
98 .i_conf = L2_IMEMORY,
99 .d_conf = L2_DMEMORY,
100 .valid = (L2_LENGTH > 0),
101 .name = "L2 Memory",
102 },
103 {
120 .start = 0, 104 .start = 0,
121 .end = 0, /* dynamic */ 105 .end = 0, /* dynamic */
122 .psize = 0, 106 .psize = 0,
@@ -165,16 +149,6 @@ static struct cplb_desc cplb_data[] = {
165 .name = "Asynchronous Memory Banks", 149 .name = "Asynchronous Memory Banks",
166 }, 150 },
167 { 151 {
168 .start = L2_START,
169 .end = L2_START + L2_LENGTH,
170 .psize = SIZE_1M,
171 .attr = SWITCH_T | I_CPLB | D_CPLB,
172 .i_conf = L2_IMEMORY,
173 .d_conf = L2_DMEMORY,
174 .valid = (L2_LENGTH > 0),
175 .name = "L2 Memory",
176 },
177 {
178 .start = BOOT_ROM_START, 152 .start = BOOT_ROM_START,
179 .end = BOOT_ROM_START + BOOT_ROM_LENGTH, 153 .end = BOOT_ROM_START + BOOT_ROM_LENGTH,
180 .psize = SIZE_1M, 154 .psize = SIZE_1M,
@@ -310,7 +284,7 @@ __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
310 } 284 }
311} 285}
312 286
313void __init generate_cplb_tables(void) 287void __init generate_cplb_tables_cpu(unsigned int cpu)
314{ 288{
315 289
316 u16 i, j, process; 290 u16 i, j, process;
@@ -322,8 +296,8 @@ void __init generate_cplb_tables(void)
322 296
323 printk(KERN_INFO "NOMPU: setting up cplb tables for global access\n"); 297 printk(KERN_INFO "NOMPU: setting up cplb tables for global access\n");
324 298
325 cplb.init_i.size = MAX_CPLBS; 299 cplb.init_i.size = CPLB_TBL_ENTRIES;
326 cplb.init_d.size = MAX_CPLBS; 300 cplb.init_d.size = CPLB_TBL_ENTRIES;
327 cplb.switch_i.size = MAX_SWITCH_I_CPLBS; 301 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
328 cplb.switch_d.size = MAX_SWITCH_D_CPLBS; 302 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
329 303
@@ -332,11 +306,15 @@ void __init generate_cplb_tables(void)
332 cplb.switch_i.pos = 0; 306 cplb.switch_i.pos = 0;
333 cplb.switch_d.pos = 0; 307 cplb.switch_d.pos = 0;
334 308
335 cplb.init_i.tab = icplb_table; 309 cplb.init_i.tab = icplb_tables[cpu];
336 cplb.init_d.tab = dcplb_table; 310 cplb.init_d.tab = dcplb_tables[cpu];
337 cplb.switch_i.tab = ipdt_table; 311 cplb.switch_i.tab = ipdt_tables[cpu];
338 cplb.switch_d.tab = dpdt_table; 312 cplb.switch_d.tab = dpdt_tables[cpu];
339 313
314 cplb_data[L1I_MEM].start = get_l1_code_start_cpu(cpu);
315 cplb_data[L1I_MEM].end = cplb_data[L1I_MEM].start + L1_CODE_LENGTH;
316 cplb_data[L1D_MEM].start = get_l1_data_a_start_cpu(cpu);
317 cplb_data[L1D_MEM].end = get_l1_data_b_start_cpu(cpu) + L1_DATA_B_LENGTH;
340 cplb_data[SDRAM_KERN].end = memory_end; 318 cplb_data[SDRAM_KERN].end = memory_end;
341 319
342#ifdef CONFIG_MTD_UCLINUX 320#ifdef CONFIG_MTD_UCLINUX
@@ -459,6 +437,5 @@ void __init generate_cplb_tables(void)
459 cplb.switch_d.tab[cplb.switch_d.pos] = -1; 437 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
460 438
461} 439}
462
463#endif 440#endif
464 441
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.S b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
index f5cf3accef37..985f3fc793f6 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
@@ -52,6 +52,7 @@
52#include <linux/linkage.h> 52#include <linux/linkage.h>
53#include <asm/blackfin.h> 53#include <asm/blackfin.h>
54#include <asm/cplb.h> 54#include <asm/cplb.h>
55#include <asm/asm-offsets.h>
55 56
56#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 57#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
57.section .l1.text 58.section .l1.text
@@ -164,10 +165,9 @@ ENTRY(_cplb_mgr)
164.Lifound_victim: 165.Lifound_victim:
165#ifdef CONFIG_CPLB_INFO 166#ifdef CONFIG_CPLB_INFO
166 R7 = [P0 - 0x104]; 167 R7 = [P0 - 0x104];
167 P2.L = _ipdt_table; 168 GET_PDA(P2, R2);
168 P2.H = _ipdt_table; 169 P3 = [P2 + PDA_IPDT_SWAPCOUNT];
169 P3.L = _ipdt_swapcount_table; 170 P2 = [P2 + PDA_IPDT];
170 P3.H = _ipdt_swapcount_table;
171 P3 += -4; 171 P3 += -4;
172.Licount: 172.Licount:
173 R2 = [P2]; /* address from config table */ 173 R2 = [P2]; /* address from config table */
@@ -208,11 +208,10 @@ ENTRY(_cplb_mgr)
208 * range. 208 * range.
209 */ 209 */
210 210
211 P2.L = _ipdt_table; 211 GET_PDA(P3, R0);
212 P2.H = _ipdt_table; 212 P2 = [P3 + PDA_IPDT];
213#ifdef CONFIG_CPLB_INFO 213#ifdef CONFIG_CPLB_INFO
214 P3.L = _ipdt_swapcount_table; 214 P3 = [P3 + PDA_IPDT_SWAPCOUNT];
215 P3.H = _ipdt_swapcount_table;
216 P3 += -8; 215 P3 += -8;
217#endif 216#endif
218 P0.L = _page_size_table; 217 P0.L = _page_size_table;
@@ -469,10 +468,9 @@ ENTRY(_cplb_mgr)
469 468
470#ifdef CONFIG_CPLB_INFO 469#ifdef CONFIG_CPLB_INFO
471 R7 = [P0 - 0x104]; 470 R7 = [P0 - 0x104];
472 P2.L = _dpdt_table; 471 GET_PDA(P2, R2);
473 P2.H = _dpdt_table; 472 P3 = [P2 + PDA_DPDT_SWAPCOUNT];
474 P3.L = _dpdt_swapcount_table; 473 P2 = [P2 + PDA_DPDT];
475 P3.H = _dpdt_swapcount_table;
476 P3 += -4; 474 P3 += -4;
477.Ldicount: 475.Ldicount:
478 R2 = [P2]; 476 R2 = [P2];
@@ -541,11 +539,10 @@ ENTRY(_cplb_mgr)
541 539
542 R0 = I0; /* Our faulting address */ 540 R0 = I0; /* Our faulting address */
543 541
544 P2.L = _dpdt_table; 542 GET_PDA(P3, R1);
545 P2.H = _dpdt_table; 543 P2 = [P3 + PDA_DPDT];
546#ifdef CONFIG_CPLB_INFO 544#ifdef CONFIG_CPLB_INFO
547 P3.L = _dpdt_swapcount_table; 545 P3 = [P3 + PDA_DPDT_SWAPCOUNT];
548 P3.H = _dpdt_swapcount_table;
549 P3 += -8; 546 P3 += -8;
550#endif 547#endif
551 548