Changeset bad1f53 in mainline
- Timestamp:
- 2013-01-19T16:35:17Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 827aae5
- Parents:
- 5fcd537
- Location:
- kernel/arch/arm32
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/cp15.h
r5fcd537 rbad1f53 104 104 CONTROL_REG_GEN_READ(ID_ISAR5, c0, 0, c2, 5); 105 105 106 enum { 107 CCSIDR_WT_FLAG = 1 << 31, 108 CCSIDR_WB_FLAG = 1 << 30, 109 CCSIDR_RA_FLAG = 1 << 29, 110 CCSIDR_WA_FLAG = 1 << 28, 111 CCSIDR_NUMSETS_MASK = 0x7fff, 112 CCSIDR_NUMSETS_SHIFT = 13, 113 CCSIDR_ASSOC_MASK = 0x3ff, 114 CCSIDR_ASSOC_SHIFT = 3, 115 CCSIDR_LINESIZE_MASK = 0x7, 116 CCSIDR_LINESIZE_SHIFT = 0, 117 }; 106 118 CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0); 119 120 enum { 121 CLIDR_LOUU_MASK = 0x7, 122 CLIDR_LOUU_SHIFT = 27, 123 CLIDR_LOC_MASK = 0x7, 124 CLIDR_LOC_SHIFT = 24, 125 CLIDR_LOUIS_MASK = 0x7, 126 CLIDR_LOUIS_SHIFT = 21, 127 CLIDR_NOCACHE = 0x0, 128 CLIDR_ICACHE_ONLY = 0x1, 129 CLIDR_DCACHE_ONLY = 0x2, 130 CLIDR_SEP_CACHE = 0x3, 131 CLIDR_UNI_CACHE = 0x4, 132 CLIDR_CACHE_MASK = 0x7, 133 #define CLIDR_CACHE(level, val) ((val >> (level - 1) * 3) & CLIDR_CACHE_MASK) 134 }; 107 135 CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1); 108 136 CONTROL_REG_GEN_READ(AIDR, c0, 1, c0, 7); /* Implementation defined or MIDR */ 109 137 138 enum { 139 CCSELR_LEVEL_MASK = 0x7, 140 CCSELR_LEVEL_SHIFT = 1, 141 CCSELR_INSTRUCTION_FLAG = 1 << 0, 142 }; 110 143 CONTROL_REG_GEN_READ(CSSELR, c0, 2, c0, 0); 111 144 CONTROL_REG_GEN_WRITE(CSSELR, c0, 2, c0, 0); -
kernel/arch/arm32/include/cpu.h
r5fcd537 rbad1f53 40 40 #include <arch/asm.h> 41 41 42 enum { 43 ARM_MAX_CACHE_LEVELS = 7, 44 }; 42 45 43 46 /** Struct representing ARM CPU identification. */ … … 57 60 /** Revision number. */ 58 61 uint32_t rev_num; 62 63 struct { 64 unsigned ways; 65 unsigned sets; 66 unsigned line_size; 67 unsigned way_shift; 68 unsigned set_shift; 69 } dcache[ARM_MAX_CACHE_LEVELS]; 70 unsigned dcache_levels; 59 71 } cpu_arch_t; 60 72 -
kernel/arch/arm32/src/cpu/cpu.c
r5fcd537 rbad1f53 34 34 */ 35 35 36 #include <arch/cache.h> 36 37 #include <arch/cpu.h> 38 #include <arch/cp15.h> 37 39 #include <cpu.h> 38 40 #include <arch.h> 39 41 #include <print.h> 42 43 static inline unsigned log2(unsigned val) 44 { 45 unsigned log = 0; 46 --val; 47 while (val) { 48 ++log; 49 val >>= 1; 50 } 51 return log; 52 } 53 54 static unsigned dcache_ways(unsigned level); 55 static unsigned dcache_sets(unsigned level); 56 static unsigned dcache_linesize_log(unsigned level); 57 40 58 41 59 /** Implementers (vendor) names */ … … 93 111 cpu->rev_num = (ident << 28) >> 28; 94 112 // TODO CPUs with arch_num == 0xf use CPUID scheme for identification 113 cpu->dcache_levels = dcache_levels(); 114 115 for (unsigned i = 0; i < cpu->dcache_levels; ++i) { 116 cpu->dcache[i].ways = dcache_ways(i); 117 cpu->dcache[i].sets = dcache_sets(i); 118 cpu->dcache[i].way_shift = 31 - log2(cpu->dcache[i].ways); 119 cpu->dcache[i].set_shift = dcache_linesize_log(i); 120 cpu->dcache[i].line_size = 1 << dcache_linesize_log(i); 121 printf("Found DCache L%u: %u-way, %u sets, %u byte lines " 122 "(shifts: w%u, s%u)\n", i + 1, cpu->dcache[i].ways, 123 cpu->dcache[i].sets, cpu->dcache[i].line_size, 124 cpu->dcache[i].way_shift, cpu->dcache[i].set_shift); 125 } 95 126 } 96 127 … … 170 201 } 171 202 203 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 204 static unsigned dcache_linesize_log(unsigned level) 205 { 206 #ifdef PROCESSOR_ARCH_armv7_a 207 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 208 const unsigned ls_log = 2 + 209 ((CCSIDR_read() >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK); 210 return ls_log + 2; //return log2(bytes) 211 #endif 212 return 0; 213 214 } 215 216 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 217 static unsigned dcache_ways(unsigned level) 218 { 219 #ifdef PROCESSOR_ARCH_armv7_a 220 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 221 const unsigned ways = 1 + 222 ((CCSIDR_read() >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK); 223 return ways; 224 #endif 225 return 0; 226 } 227 228 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 229 static unsigned dcache_sets(unsigned level) 230 { 231 #ifdef PROCESSOR_ARCH_armv7_a 232 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 233 const unsigned sets = 1 + 234 ((CCSIDR_read() >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK); 235 return sets; 236 #endif 237 return 0; 238 } 239 240 unsigned dcache_levels(void) 241 { 242 const uint32_t val = CLIDR_read(); 243 unsigned levels = 0; 244 for (unsigned i = 1; i <= 7; ++i) { 245 const unsigned ctype = CLIDR_CACHE(i, val); 246 switch (ctype) { 247 case CLIDR_DCACHE_ONLY: 248 case CLIDR_SEP_CACHE: 249 case CLIDR_UNI_CACHE: 250 ++levels; 251 default: 252 (void)0; 253 } 254 } 255 return levels; 256 } 257 258 static void dcache_clean_manual(unsigned level, bool invalidate, 259 unsigned ways, unsigned sets, unsigned way_shift, unsigned set_shift) 260 { 261 262 for (unsigned i = 0; i < ways; ++i) { 263 for (unsigned j = 0; j < sets; ++j) { 264 const uint32_t val = 265 ((level & 0x7) << 1) | 266 (j << set_shift) | (i << way_shift); 267 if (invalidate) 268 DCCISW_write(val); 269 else 270 DCCSW_write(val); 271 } 272 } 273 } 274 275 void dcache_flush(void) 276 { 277 /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */ 278 const unsigned levels = dcache_levels(); 279 for (unsigned i = 0; i < levels; ++i) { 280 const unsigned ways = dcache_ways(i); 281 const unsigned sets = dcache_sets(i); 282 const unsigned way_shift = 31 - log2(ways); 283 const unsigned set_shift = dcache_linesize_log(i); 284 dcache_clean_manual(i, false, ways, sets, way_shift, set_shift); 285 } 286 } 287 288 void dcache_flush_invalidate(void) 289 { 290 /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */ 291 const unsigned levels = dcache_levels(); 292 for (unsigned i = 0; i < levels; ++i) { 293 const unsigned ways = dcache_ways(i); 294 const unsigned sets = dcache_sets(i); 295 const unsigned way_shift = 31 - log2(ways); 296 const unsigned set_shift = dcache_linesize_log(i); 297 dcache_clean_manual(i, true, ways, sets, way_shift, set_shift); 298 } 299 } 300 301 302 void cpu_dcache_flush(void) 303 { 304 for (unsigned i = 0; i < CPU->arch.dcache_levels; ++i) 305 dcache_clean_manual(i, false, 306 CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets, 307 CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift); 308 } 309 310 void cpu_dcache_flush_invalidate(void) 311 { 312 const unsigned levels = dcache_levels(); 313 for (unsigned i = 0; i < levels; ++i) 314 dcache_clean_manual(i, true, 315 CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets, 316 CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift); 317 } 318 319 void icache_invalidate(void) 320 { 321 ICIALLU_write(0); 322 } 323 172 324 /** @} 173 325 */
Note:
See TracChangeset
for help on using the changeset viewer.