diff options
author | Graf Yang <graf.yang@analog.com> | 2008-11-18 09:48:22 (GMT) |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-11-18 09:48:22 (GMT) |
commit | b8a989893cbdeb6c97a7b5af5f38fb0e480235f9 (patch) | |
tree | 658cf6df93dac687f0d6b94111d0f53b3dd0177c /arch/blackfin/kernel/cplb-nompu | |
parent | 6b3087c64a92a36ae20d33479b4df6d7afc910d4 (diff) | |
download | linux-fsl-qoriq-b8a989893cbdeb6c97a7b5af5f38fb0e480235f9.tar.xz |
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.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinfo.c | 55 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinit.c | 89 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbmgr.S | 29 |
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 bd08315..3a385ae 100644 --- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c @@ -25,9 +25,9 @@ #include <asm/cplbinit.h> #if defined(CONFIG_BFIN_ICACHE) -void __init bfin_icache_init(void) +void __cpuinit bfin_icache_init(u_long icplb[]) { - unsigned long *table = icplb_table; + unsigned long *table = icplb; unsigned long ctrl; int i; @@ -47,9 +47,9 @@ void __init bfin_icache_init(void) #endif #if defined(CONFIG_BFIN_DCACHE) -void __init bfin_dcache_init(void) +void __cpuinit bfin_dcache_init(u_long dcplb[]) { - unsigned long *table = dcplb_table; + unsigned long *table = dcplb; unsigned long ctrl; int i; @@ -64,6 +64,7 @@ void __init bfin_dcache_init(void) ctrl = bfin_read_DMEM_CONTROL(); ctrl |= DMEM_CNTR; bfin_write_DMEM_CONTROL(ctrl); + SSYNC(); } #endif diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinfo.c b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c index 1e74f0b..3f00809 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, return -1; } -static char *cplb_print_entry(char *buf, int type) +static char *cplb_print_entry(char *buf, int type, unsigned int cpu) { - unsigned long *p_addr = dpdt_table; - unsigned long *p_data = dpdt_table + 1; - unsigned long *p_icount = dpdt_swapcount_table; - unsigned long *p_ocount = dpdt_swapcount_table + 1; + unsigned long *p_addr = dpdt_tables[cpu]; + unsigned long *p_data = dpdt_tables[cpu] + 1; + unsigned long *p_icount = dpdt_swapcount_tables[cpu]; + unsigned long *p_ocount = dpdt_swapcount_tables[cpu] + 1; unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0; unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0; int entry = 0, used_cplb = 0; if (type == CPLB_I) { buf += sprintf(buf, "Instruction CPLB entry:\n"); - p_addr = ipdt_table; - p_data = ipdt_table + 1; - p_icount = ipdt_swapcount_table; - p_ocount = ipdt_swapcount_table + 1; + p_addr = ipdt_tables[cpu]; + p_data = ipdt_tables[cpu] + 1; + p_icount = ipdt_swapcount_tables[cpu]; + p_ocount = ipdt_swapcount_tables[cpu] + 1; cplb_addr = (unsigned long *)ICPLB_ADDR0; cplb_data = (unsigned long *)ICPLB_DATA0; } else @@ -134,24 +134,24 @@ static char *cplb_print_entry(char *buf, int type) return buf; } -static int cplbinfo_proc_output(char *buf) +static int cplbinfo_proc_output(char *buf, void *data) { + unsigned int cpu = (unsigned int)data; char *p; p = buf; - p += sprintf(p, "------------------ CPLB Information ------------------\n\n"); + p += sprintf(p, "------------- CPLB Information on CPU%u--------------\n\n", cpu); if (bfin_read_IMEM_CONTROL() & ENICPLB) - p = cplb_print_entry(p, CPLB_I); + p = cplb_print_entry(p, CPLB_I, cpu); else p += sprintf(p, "Instruction CPLB is disabled.\n\n"); if (bfin_read_DMEM_CONTROL() & ENDCPLB) - p = cplb_print_entry(p, CPLB_D); + p = cplb_print_entry(p, CPLB_D, cpu); else p += sprintf(p, "Data CPLB is disabled.\n"); - return p - buf; } @@ -160,7 +160,7 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off, { int len; - len = cplbinfo_proc_output(page); + len = cplbinfo_proc_output(page, data); if (len <= off + count) *eof = 1; *start = page + off; @@ -174,20 +174,33 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off, static int __init cplbinfo_init(void) { - struct proc_dir_entry *entry; + struct proc_dir_entry *parent, *entry; + unsigned int cpu; + unsigned char str[10]; + + parent = proc_mkdir("cplbinfo", NULL); - entry = create_proc_entry("cplbinfo", 0, NULL); - if (!entry) - return -ENOMEM; + for_each_online_cpu(cpu) { + sprintf(str, "cpu%u", cpu); + entry = create_proc_entry(str, 0, parent); + if (!entry) + return -ENOMEM; - entry->read_proc = cplbinfo_read_proc; - entry->data = NULL; + entry->read_proc = cplbinfo_read_proc; + entry->data = (void *)cpu; + } return 0; } static void __exit cplbinfo_exit(void) { + unsigned int cpu; + unsigned char str[20]; + for_each_online_cpu(cpu) { + sprintf(str, "cplbinfo/cpu%u", cpu); + remove_proc_entry(str, NULL); + } remove_proc_entry("cplbinfo", NULL); } diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 2debc90..8966c70 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -27,46 +27,20 @@ #include <asm/cplb.h> #include <asm/cplbinit.h> -#define CPLB_MEM CONFIG_MAX_MEM_SIZE - -/* -* Number of required data CPLB switchtable entries -* MEMSIZE / 4 (we mostly install 4M page size CPLBs -* approx 16 for smaller 1MB page size CPLBs for allignment purposes -* 1 for L1 Data Memory -* possibly 1 for L2 Data Memory -* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO -* 1 for ASYNC Memory -*/ -#define MAX_SWITCH_D_CPLBS (((CPLB_MEM / 4) + 16 + 1 + 1 + 1 \ - + ASYNC_MEMORY_CPLB_COVERAGE) * 2) - -/* -* Number of required instruction CPLB switchtable entries -* MEMSIZE / 4 (we mostly install 4M page size CPLBs -* approx 12 for smaller 1MB page size CPLBs for allignment purposes -* 1 for L1 Instruction Memory -* possibly 1 for L2 Instruction Memory -* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO -*/ -#define MAX_SWITCH_I_CPLBS (((CPLB_MEM / 4) + 12 + 1 + 1 + 1) * 2) - - -u_long icplb_table[MAX_CPLBS + 1]; -u_long dcplb_table[MAX_CPLBS + 1]; +u_long icplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1]; +u_long dcplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1]; #ifdef CONFIG_CPLB_SWITCH_TAB_L1 -# define PDT_ATTR __attribute__((l1_data)) +#define PDT_ATTR __attribute__((l1_data)) #else -# define PDT_ATTR +#define PDT_ATTR #endif -u_long ipdt_table[MAX_SWITCH_I_CPLBS + 1] PDT_ATTR; -u_long dpdt_table[MAX_SWITCH_D_CPLBS + 1] PDT_ATTR; - +u_long ipdt_tables[NR_CPUS][MAX_SWITCH_I_CPLBS+1] PDT_ATTR; +u_long dpdt_tables[NR_CPUS][MAX_SWITCH_D_CPLBS+1] PDT_ATTR; #ifdef CONFIG_CPLB_INFO -u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS] PDT_ATTR; -u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS] PDT_ATTR; +u_long ipdt_swapcount_tables[NR_CPUS][MAX_SWITCH_I_CPLBS] PDT_ATTR; +u_long dpdt_swapcount_tables[NR_CPUS][MAX_SWITCH_D_CPLBS] PDT_ATTR; #endif struct s_cplb { @@ -93,8 +67,8 @@ static struct cplb_desc cplb_data[] = { .name = "Zero Pointer Guard Page", }, { - .start = L1_CODE_START, - .end = L1_CODE_START + L1_CODE_LENGTH, + .start = 0, /* dyanmic */ + .end = 0, /* dynamic */ .psize = SIZE_4M, .attr = INITIAL_T | SWITCH_T | I_CPLB, .i_conf = L1_IMEMORY, @@ -103,8 +77,8 @@ static struct cplb_desc cplb_data[] = { .name = "L1 I-Memory", }, { - .start = L1_DATA_A_START, - .end = L1_DATA_B_START + L1_DATA_B_LENGTH, + .start = 0, /* dynamic */ + .end = 0, /* dynamic */ .psize = SIZE_4M, .attr = INITIAL_T | SWITCH_T | D_CPLB, .i_conf = 0, @@ -117,6 +91,16 @@ static struct cplb_desc cplb_data[] = { .name = "L1 D-Memory", }, { + .start = L2_START, + .end = L2_START + L2_LENGTH, + .psize = SIZE_1M, + .attr = L2_ATTR, + .i_conf = L2_IMEMORY, + .d_conf = L2_DMEMORY, + .valid = (L2_LENGTH > 0), + .name = "L2 Memory", + }, + { .start = 0, .end = 0, /* dynamic */ .psize = 0, @@ -165,16 +149,6 @@ static struct cplb_desc cplb_data[] = { .name = "Asynchronous Memory Banks", }, { - .start = L2_START, - .end = L2_START + L2_LENGTH, - .psize = SIZE_1M, - .attr = SWITCH_T | I_CPLB | D_CPLB, - .i_conf = L2_IMEMORY, - .d_conf = L2_DMEMORY, - .valid = (L2_LENGTH > 0), - .name = "L2 Memory", - }, - { .start = BOOT_ROM_START, .end = BOOT_ROM_START + BOOT_ROM_LENGTH, .psize = SIZE_1M, @@ -310,7 +284,7 @@ __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) } } -void __init generate_cplb_tables(void) +void __init generate_cplb_tables_cpu(unsigned int cpu) { u16 i, j, process; @@ -322,8 +296,8 @@ void __init generate_cplb_tables(void) printk(KERN_INFO "NOMPU: setting up cplb tables for global access\n"); - cplb.init_i.size = MAX_CPLBS; - cplb.init_d.size = MAX_CPLBS; + cplb.init_i.size = CPLB_TBL_ENTRIES; + cplb.init_d.size = CPLB_TBL_ENTRIES; cplb.switch_i.size = MAX_SWITCH_I_CPLBS; cplb.switch_d.size = MAX_SWITCH_D_CPLBS; @@ -332,11 +306,15 @@ void __init generate_cplb_tables(void) cplb.switch_i.pos = 0; cplb.switch_d.pos = 0; - cplb.init_i.tab = icplb_table; - cplb.init_d.tab = dcplb_table; - cplb.switch_i.tab = ipdt_table; - cplb.switch_d.tab = dpdt_table; + cplb.init_i.tab = icplb_tables[cpu]; + cplb.init_d.tab = dcplb_tables[cpu]; + cplb.switch_i.tab = ipdt_tables[cpu]; + cplb.switch_d.tab = dpdt_tables[cpu]; + cplb_data[L1I_MEM].start = get_l1_code_start_cpu(cpu); + cplb_data[L1I_MEM].end = cplb_data[L1I_MEM].start + L1_CODE_LENGTH; + cplb_data[L1D_MEM].start = get_l1_data_a_start_cpu(cpu); + cplb_data[L1D_MEM].end = get_l1_data_b_start_cpu(cpu) + L1_DATA_B_LENGTH; cplb_data[SDRAM_KERN].end = memory_end; #ifdef CONFIG_MTD_UCLINUX @@ -459,6 +437,5 @@ void __init generate_cplb_tables(void) cplb.switch_d.tab[cplb.switch_d.pos] = -1; } - #endif diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.S b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S index f5cf3ac..985f3fc 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.S +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S @@ -52,6 +52,7 @@ #include <linux/linkage.h> #include <asm/blackfin.h> #include <asm/cplb.h> +#include <asm/asm-offsets.h> #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 .section .l1.text @@ -164,10 +165,9 @@ ENTRY(_cplb_mgr) .Lifound_victim: #ifdef CONFIG_CPLB_INFO R7 = [P0 - 0x104]; - P2.L = _ipdt_table; - P2.H = _ipdt_table; - P3.L = _ipdt_swapcount_table; - P3.H = _ipdt_swapcount_table; + GET_PDA(P2, R2); + P3 = [P2 + PDA_IPDT_SWAPCOUNT]; + P2 = [P2 + PDA_IPDT]; P3 += -4; .Licount: R2 = [P2]; /* address from config table */ @@ -208,11 +208,10 @@ ENTRY(_cplb_mgr) * range. */ - P2.L = _ipdt_table; - P2.H = _ipdt_table; + GET_PDA(P3, R0); + P2 = [P3 + PDA_IPDT]; #ifdef CONFIG_CPLB_INFO - P3.L = _ipdt_swapcount_table; - P3.H = _ipdt_swapcount_table; + P3 = [P3 + PDA_IPDT_SWAPCOUNT]; P3 += -8; #endif P0.L = _page_size_table; @@ -469,10 +468,9 @@ ENTRY(_cplb_mgr) #ifdef CONFIG_CPLB_INFO R7 = [P0 - 0x104]; - P2.L = _dpdt_table; - P2.H = _dpdt_table; - P3.L = _dpdt_swapcount_table; - P3.H = _dpdt_swapcount_table; + GET_PDA(P2, R2); + P3 = [P2 + PDA_DPDT_SWAPCOUNT]; + P2 = [P2 + PDA_DPDT]; P3 += -4; .Ldicount: R2 = [P2]; @@ -541,11 +539,10 @@ ENTRY(_cplb_mgr) R0 = I0; /* Our faulting address */ - P2.L = _dpdt_table; - P2.H = _dpdt_table; + GET_PDA(P3, R1); + P2 = [P3 + PDA_DPDT]; #ifdef CONFIG_CPLB_INFO - P3.L = _dpdt_swapcount_table; - P3.H = _dpdt_swapcount_table; + P3 = [P3 + PDA_DPDT_SWAPCOUNT]; P3 += -8; #endif |