aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-01-18 04:42:25 -0500
committerVineet Gupta <vgupta@synopsys.com>2013-02-15 12:46:10 -0500
commit8b5850f8ac8d9b809db4588b80b568faca5aaaaf (patch)
tree9cb026d610787ba2177e3543d44c7f94fdfd6bfe /arch/arc/kernel
parent9c57564e26c5392ac7f0e08cc0ad8d29e225a3a3 (diff)
ARC: Support for single cycle Close Coupled Mem (CCM)
* Includes mapping of CCMs in address space * Annotations to move arbitrary code/data into CCM * Moving some of the critical code/data into CCM * Runtime detection/reporting Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/entry.S4
-rw-r--r--arch/arc/kernel/setup.c53
-rw-r--r--arch/arc/kernel/vmlinux.lds.S21
3 files changed, 75 insertions, 3 deletions
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index f8efade15368..3f628ca9b71a 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -149,7 +149,7 @@ VECTOR reserved ; Reserved Exceptions
149 149
150;##################### Scratch Mem for IRQ stack switching ############# 150;##################### Scratch Mem for IRQ stack switching #############
151 151
152 .section .data ; NOT .global 152ARCFP_DATA int1_saved_reg
153 .align 32 153 .align 32
154 .type int1_saved_reg, @object 154 .type int1_saved_reg, @object
155 .size int1_saved_reg, 4 155 .size int1_saved_reg, 4
@@ -159,7 +159,7 @@ int1_saved_reg:
159/* Each Interrupt level needs it's own scratch */ 159/* Each Interrupt level needs it's own scratch */
160#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS 160#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
161 161
162 .section .data ; NOT .global 162ARCFP_DATA int2_saved_reg
163 .type int2_saved_reg, @object 163 .type int2_saved_reg, @object
164 .size int2_saved_reg, 4 164 .size int2_saved_reg, 4
165int2_saved_reg: 165int2_saved_reg:
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index e25538e29fe7..6cc361c6751a 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -64,6 +64,33 @@ void __init read_arc_build_cfg_regs(void)
64 cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR); 64 cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR);
65 cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR); 65 cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR);
66 66
67 /* Note that we read the CCM BCRs independent of kernel config
68 * This is to catch the cases where user doesn't know that
69 * CCMs are present in hardware build
70 */
71 {
72 struct bcr_iccm iccm;
73 struct bcr_dccm dccm;
74 struct bcr_dccm_base dccm_base;
75 unsigned int bcr_32bit_val;
76
77 bcr_32bit_val = read_aux_reg(ARC_REG_ICCM_BCR);
78 if (bcr_32bit_val) {
79 iccm = *((struct bcr_iccm *)&bcr_32bit_val);
80 cpu->iccm.base_addr = iccm.base << 16;
81 cpu->iccm.sz = 0x2000 << (iccm.sz - 1);
82 }
83
84 bcr_32bit_val = read_aux_reg(ARC_REG_DCCM_BCR);
85 if (bcr_32bit_val) {
86 dccm = *((struct bcr_dccm *)&bcr_32bit_val);
87 cpu->dccm.sz = 0x800 << (dccm.sz);
88
89 READ_BCR(ARC_REG_DCCMBASE_BCR, dccm_base);
90 cpu->dccm.base_addr = dccm_base.addr << 8;
91 }
92 }
93
67 READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem); 94 READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem);
68 95
69 read_decode_mmu_bcr(); 96 read_decode_mmu_bcr();
@@ -211,6 +238,30 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
211 return buf; 238 return buf;
212} 239}
213 240
241void __init arc_chk_ccms(void)
242{
243#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
244 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
245
246#ifdef CONFIG_ARC_HAS_DCCM
247 /*
248 * DCCM can be arbit placed in hardware.
249 * Make sure it's placement/sz matches what Linux is built with
250 */
251 if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr)
252 panic("Linux built with incorrect DCCM Base address\n");
253
254 if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz)
255 panic("Linux built with incorrect DCCM Size\n");
256#endif
257
258#ifdef CONFIG_ARC_HAS_ICCM
259 if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
260 panic("Linux built with incorrect ICCM Size\n");
261#endif
262#endif
263}
264
214/* 265/*
215 * Ensure that FP hardware and kernel config match 266 * Ensure that FP hardware and kernel config match
216 * -If hardware contains DPFP, kernel needs to save/restore FPU state 267 * -If hardware contains DPFP, kernel needs to save/restore FPU state
@@ -255,7 +306,7 @@ void __init setup_processor(void)
255 306
256 arc_mmu_init(); 307 arc_mmu_init();
257 arc_cache_init(); 308 arc_cache_init();
258 309 arc_chk_ccms();
259 310
260 printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); 311 printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str)));
261 312
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 303ea01c85c8..8d3b0d447498 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -23,6 +23,12 @@ jiffies = jiffies_64;
23 23
24SECTIONS 24SECTIONS
25{ 25{
26 /*
27 * ICCM starts at 0x8000_0000. So if kernel is relocated to some other
28 * address, make sure peripheral at 0x8z doesn't clash with ICCM
29 * Essentially vector is also in ICCM.
30 */
31
26 . = CONFIG_LINUX_LINK_BASE; 32 . = CONFIG_LINUX_LINK_BASE;
27 33
28 _int_vec_base_lds = .; 34 _int_vec_base_lds = .;
@@ -31,6 +37,13 @@ SECTIONS
31 . = ALIGN(PAGE_SIZE); 37 . = ALIGN(PAGE_SIZE);
32 } 38 }
33 39
40#ifdef CONFIG_ARC_HAS_ICCM
41 .text.arcfp : {
42 *(.text.arcfp)
43 . = ALIGN(CONFIG_ARC_ICCM_SZ * 1024);
44 }
45#endif
46
34 /* 47 /*
35 * The reason for having a seperate subsection .init.ramfs is to 48 * The reason for having a seperate subsection .init.ramfs is to
36 * prevent objump from including it in kernel dumps 49 * prevent objump from including it in kernel dumps
@@ -134,4 +147,12 @@ SECTIONS
134 .debug_loc 0 : { *(.debug_loc) } 147 .debug_loc 0 : { *(.debug_loc) }
135 .debug_macinfo 0 : { *(.debug_macinfo) } 148 .debug_macinfo 0 : { *(.debug_macinfo) }
136 149
150#ifdef CONFIG_ARC_HAS_DCCM
151 . = CONFIG_ARC_DCCM_BASE;
152 __arc_dccm_base = .;
153 .data.arcfp : {
154 *(.data.arcfp)
155 }
156 . = ALIGN(CONFIG_ARC_DCCM_SZ * 1024);
157#endif
137} 158}