Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+137 -6
+27
arch/arc/Kconfig
··· 198 198 199 199 endif #ARC_CACHE 200 200 201 + config ARC_HAS_ICCM 202 + bool "Use ICCM" 203 + help 204 + Single Cycle RAMS to store Fast Path Code 205 + default n 206 + 207 + config ARC_ICCM_SZ 208 + int "ICCM Size in KB" 209 + default "64" 210 + depends on ARC_HAS_ICCM 211 + 212 + config ARC_HAS_DCCM 213 + bool "Use DCCM" 214 + help 215 + Single Cycle RAMS to store Fast Path Data 216 + default n 217 + 218 + config ARC_DCCM_SZ 219 + int "DCCM Size in KB" 220 + default "64" 221 + depends on ARC_HAS_DCCM 222 + 223 + config ARC_DCCM_BASE 224 + hex "DCCM map address" 225 + default "0xA0000000" 226 + depends on ARC_HAS_DCCM 227 + 201 228 config ARC_HAS_HW_MPY 202 229 bool "Use Hardware Multiplier (Normal or Faster XMAC)" 203 230 default y
+33
arch/arc/include/asm/linkage.h
··· 25 25 .size \ name, ASM_PREV_SYM_ADDR(\name) 26 26 .endm 27 27 28 + /* annotation for data we want in DCCM - if enabled in .config */ 29 + .macro ARCFP_DATA nm 30 + #ifdef CONFIG_ARC_HAS_DCCM 31 + .section .data.arcfp 32 + #else 33 + .section .data 34 + #endif 35 + .global \nm 36 + .endm 37 + 38 + /* annotation for data we want in DCCM - if enabled in .config */ 39 + .macro ARCFP_CODE 40 + #ifdef CONFIG_ARC_HAS_ICCM 41 + .section .text.arcfp, "ax",@progbits 42 + #else 43 + .section .text, "ax",@progbits 44 + #endif 45 + .endm 46 + 47 + #else /* !__ASSEMBLY__ */ 48 + 49 + #ifdef CONFIG_ARC_HAS_ICCM 50 + #define __arcfp_code __attribute__((__section__(".text.arcfp"))) 51 + #else 52 + #define __arcfp_code __attribute__((__section__(".text"))) 53 + #endif 54 + 55 + #ifdef CONFIG_ARC_HAS_DCCM 56 + #define __arcfp_data __attribute__((__section__(".data.arcfp"))) 57 + #else 58 + #define __arcfp_data __attribute__((__section__(".data"))) 59 + #endif 60 + 28 61 #endif /* __ASSEMBLY__ */ 29 62 30 63 #endif
+2 -2
arch/arc/kernel/entry.S
··· 149 149 150 150 ;##################### Scratch Mem for IRQ stack switching ############# 151 151 152 - .section .data ; NOT .global 152 + ARCFP_DATA int1_saved_reg 153 153 .align 32 154 154 .type int1_saved_reg, @object 155 155 .size int1_saved_reg, 4 ··· 159 159 /* Each Interrupt level needs it's own scratch */ 160 160 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS 161 161 162 - .section .data ; NOT .global 162 + ARCFP_DATA int2_saved_reg 163 163 .type int2_saved_reg, @object 164 164 .size int2_saved_reg, 4 165 165 int2_saved_reg:
+52 -1
arch/arc/kernel/setup.c
··· 64 64 cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR); 65 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 94 READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem); 68 95 69 96 read_decode_mmu_bcr(); ··· 238 211 return buf; 239 212 } 240 213 214 + void __init arc_chk_ccms(void) 215 + { 216 + #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) 217 + struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 218 + 219 + #ifdef CONFIG_ARC_HAS_DCCM 220 + /* 221 + * DCCM can be arbit placed in hardware. 222 + * Make sure it's placement/sz matches what Linux is built with 223 + */ 224 + if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) 225 + panic("Linux built with incorrect DCCM Base address\n"); 226 + 227 + if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz) 228 + panic("Linux built with incorrect DCCM Size\n"); 229 + #endif 230 + 231 + #ifdef CONFIG_ARC_HAS_ICCM 232 + if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz) 233 + panic("Linux built with incorrect ICCM Size\n"); 234 + #endif 235 + #endif 236 + } 237 + 241 238 /* 242 239 * Ensure that FP hardware and kernel config match 243 240 * -If hardware contains DPFP, kernel needs to save/restore FPU state ··· 306 255 307 256 arc_mmu_init(); 308 257 arc_cache_init(); 309 - 258 + arc_chk_ccms(); 310 259 311 260 printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); 312 261
+21
arch/arc/kernel/vmlinux.lds.S
··· 23 23 24 24 SECTIONS 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 32 . = CONFIG_LINUX_LINK_BASE; 27 33 28 34 _int_vec_base_lds = .; ··· 36 30 *(.vector) 37 31 . = ALIGN(PAGE_SIZE); 38 32 } 33 + 34 + #ifdef CONFIG_ARC_HAS_ICCM 35 + .text.arcfp : { 36 + *(.text.arcfp) 37 + . = ALIGN(CONFIG_ARC_ICCM_SZ * 1024); 38 + } 39 + #endif 39 40 40 41 /* 41 42 * The reason for having a seperate subsection .init.ramfs is to ··· 147 134 .debug_loc 0 : { *(.debug_loc) } 148 135 .debug_macinfo 0 : { *(.debug_macinfo) } 149 136 137 + #ifdef CONFIG_ARC_HAS_DCCM 138 + . = CONFIG_ARC_DCCM_BASE; 139 + __arc_dccm_base = .; 140 + .data.arcfp : { 141 + *(.data.arcfp) 142 + } 143 + . = ALIGN(CONFIG_ARC_DCCM_SZ * 1024); 144 + #endif 150 145 }
+2 -3
arch/arc/mm/tlbex.S
··· 53 53 ; For details refer to comments before TLBMISS_FREEUP_REGS below 54 54 ;-------------------------------------------------------------------------- 55 55 56 - .section .data 57 - .global ex_saved_reg1 56 + ARCFP_DATA ex_saved_reg1 58 57 .align 1 << L1_CACHE_SHIFT ; IMP: Must be Cache Line aligned 59 58 .type ex_saved_reg1, @object 60 59 #ifdef CONFIG_SMP ··· 254 255 #endif 255 256 .endm 256 257 257 - .section .text, "ax",@progbits ;Fast Path Code, candidate for ICCM 258 + ARCFP_CODE ;Fast Path Code, candidate for ICCM 258 259 259 260 ;----------------------------------------------------------------------------- 260 261 ; I-TLB Miss Exception Handler