diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-04-12 03:38:06 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-05-07 09:38:13 -0400 |
commit | 7f250a0fa1cc7f8d97560f4ea36eae38c17eb648 (patch) | |
tree | 0e55df98419556bf1184faa287a7f5432edd60f6 /arch/arc/mm | |
parent | 94bad1afeeefbd1b27d7f642de12c04339501a99 (diff) |
ARC: [mm] remove the pessimistic all-alias-invalidate icache helpers
No users of this code anymore - so RIP !
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/mm')
-rw-r--r-- | arch/arc/mm/cache_arc700.c | 201 |
1 files changed, 17 insertions, 184 deletions
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 5aaa955a3aac..da9de401681d 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c | |||
@@ -72,16 +72,6 @@ | |||
72 | #include <asm/cachectl.h> | 72 | #include <asm/cachectl.h> |
73 | #include <asm/setup.h> | 73 | #include <asm/setup.h> |
74 | 74 | ||
75 | |||
76 | #ifdef CONFIG_ARC_HAS_ICACHE | ||
77 | static void __ic_line_inv_no_alias(unsigned long, int); | ||
78 | static void __ic_line_inv_2_alias(unsigned long, int); | ||
79 | static void __ic_line_inv_4_alias(unsigned long, int); | ||
80 | |||
81 | /* Holds the ptr to flush routine, dependign on size due to aliasing issues */ | ||
82 | static void (*___flush_icache_rtn) (unsigned long, int); | ||
83 | #endif | ||
84 | |||
85 | char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) | 75 | char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) |
86 | { | 76 | { |
87 | int n = 0; | 77 | int n = 0; |
@@ -171,30 +161,6 @@ void __cpuinit arc_cache_init(void) | |||
171 | 161 | ||
172 | } | 162 | } |
173 | #endif | 163 | #endif |
174 | |||
175 | /* | ||
176 | * if Cache way size is <= page size then no aliasing exhibited | ||
177 | * otherwise ratio determines num of aliases. | ||
178 | * e.g. 32K I$, 2 way set assoc, 8k pg size | ||
179 | * way-sz = 32k/2 = 16k | ||
180 | * way-pg-ratio = 16k/8k = 2, so 2 aliases possible | ||
181 | * (meaning 1 line could be in 2 possible locations). | ||
182 | */ | ||
183 | way_pg_ratio = ic->sz / ARC_ICACHE_WAYS / PAGE_SIZE; | ||
184 | switch (way_pg_ratio) { | ||
185 | case 0: | ||
186 | case 1: | ||
187 | ___flush_icache_rtn = __ic_line_inv_no_alias; | ||
188 | break; | ||
189 | case 2: | ||
190 | ___flush_icache_rtn = __ic_line_inv_2_alias; | ||
191 | break; | ||
192 | case 4: | ||
193 | ___flush_icache_rtn = __ic_line_inv_4_alias; | ||
194 | break; | ||
195 | default: | ||
196 | panic("Unsupported I-Cache Sz\n"); | ||
197 | } | ||
198 | #endif | 164 | #endif |
199 | 165 | ||
200 | /* Enable/disable I-Cache */ | 166 | /* Enable/disable I-Cache */ |
@@ -391,75 +357,38 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, | |||
391 | /* | 357 | /* |
392 | * I-Cache Aliasing in ARC700 VIPT caches | 358 | * I-Cache Aliasing in ARC700 VIPT caches |
393 | * | 359 | * |
394 | * For fetching code from I$, ARC700 uses vaddr (embedded in program code) | 360 | * ARC VIPT I-cache uses vaddr to index into cache and paddr to match the tag. |
395 | * to "index" into SET of cache-line and paddr from MMU to match the TAG | 361 | * The orig Cache Management Module "CDU" only required paddr to invalidate a |
396 | * in the WAYS of SET. | 362 | * certain line since it sufficed as index in Non-Aliasing VIPT cache-geometry. |
397 | * | 363 | * Infact for distinct V1,V2,P: all of {V1-P},{V2-P},{P-P} would end up fetching |
398 | * However the CDU iterface (to flush/inv) lines from software, only takes | 364 | * the exact same line. |
399 | * paddr (to have simpler hardware interface). For simpler cases, using paddr | ||
400 | * alone suffices. | ||
401 | * e.g. 2-way-set-assoc, 16K I$ (8k MMU pg sz, 32b cache line size): | ||
402 | * way_sz = cache_sz / num_ways = 16k/2 = 8k | ||
403 | * num_sets = way_sz / line_sz = 8k/32 = 256 => 8 bits | ||
404 | * Ignoring the bottom 5 bits corresp to the off within a 32b cacheline, | ||
405 | * bits req for calc set-index = bits 12:5 (0 based). Since this range fits | ||
406 | * inside the bottom 13 bits of paddr, which are same for vaddr and paddr | ||
407 | * (with 8k pg sz), paddr alone can be safely used by CDU to unambigously | ||
408 | * locate a cache-line. | ||
409 | * | 365 | * |
410 | * However for a difft sized cache, say 32k I$, above math yields need | 366 | * However for larger Caches (way-size > page-size) - i.e. in Aliasing config, |
411 | * for 14 bits of vaddr to locate a cache line, which can't be provided by | 367 | * paddr alone could not be used to correctly index the cache. |
412 | * paddr, since the bit 13 (0 based) might differ between the two. | ||
413 | * | ||
414 | * This lack of extra bits needed for correct line addressing, defines the | ||
415 | * classical problem of Cache aliasing with VIPT architectures | ||
416 | * num_aliases = 1 << extra_bits | ||
417 | * e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz => 2 aliases | ||
418 | * 2-way-set-assoc, 64K I$ with 8k MMU pg sz => 4 aliases | ||
419 | * 2-way-set-assoc, 16K I$ with 8k MMU pg sz => NO aliases | ||
420 | * | 368 | * |
421 | * ------------------ | 369 | * ------------------ |
422 | * MMU v1/v2 (Fixed Page Size 8k) | 370 | * MMU v1/v2 (Fixed Page Size 8k) |
423 | * ------------------ | 371 | * ------------------ |
424 | * The solution was to provide CDU with these additonal vaddr bits. These | 372 | * The solution was to provide CDU with these additonal vaddr bits. These |
425 | * would be bits [x:13], x would depend on cache-geom. | 373 | * would be bits [x:13], x would depend on cache-geometry, 13 comes from |
374 | * standard page size of 8k. | ||
426 | * H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits | 375 | * H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits |
427 | * of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the | 376 | * of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the |
428 | * orig 5 bits of paddr were anyways ignored by CDU line ops, as they | 377 | * orig 5 bits of paddr were anyways ignored by CDU line ops, as they |
429 | * represent the offset within cache-line. The adv of using this "clumsy" | 378 | * represent the offset within cache-line. The adv of using this "clumsy" |
430 | * interface for additional info was no new reg was needed in CDU. | 379 | * interface for additional info was no new reg was needed in CDU programming |
380 | * model. | ||
431 | * | 381 | * |
432 | * 17:13 represented the max num of bits passable, actual bits needed were | 382 | * 17:13 represented the max num of bits passable, actual bits needed were |
433 | * fewer, based on the num-of-aliases possible. | 383 | * fewer, based on the num-of-aliases possible. |
434 | * -for 2 alias possibility, only bit 13 needed (32K cache) | 384 | * -for 2 alias possibility, only bit 13 needed (32K cache) |
435 | * -for 4 alias possibility, bits 14:13 needed (64K cache) | 385 | * -for 4 alias possibility, bits 14:13 needed (64K cache) |
436 | * | 386 | * |
437 | * Since vaddr was not available for all instances of I$ flush req by core | ||
438 | * kernel, the only safe way (non-optimal though) was to kill all possible | ||
439 | * lines which could represent an alias (even if they didnt represent one | ||
440 | * in execution). | ||
441 | * e.g. for 64K I$, 4 aliases possible, so we did | ||
442 | * flush start | ||
443 | * flush start | 0x01 | ||
444 | * flush start | 0x2 | ||
445 | * flush start | 0x3 | ||
446 | * | ||
447 | * The penalty was invoking the operation itself, since tag match is anyways | ||
448 | * paddr based, a line which didn't represent an alias would not match the | ||
449 | * paddr, hence wont be killed | ||
450 | * | ||
451 | * Note that aliasing concerns are independent of line-sz for a given cache | ||
452 | * geometry (size + set_assoc) because the extra bits required by line-sz are | ||
453 | * reduced from the set calc. | ||
454 | * e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz and using math above | ||
455 | * 32b line-sz: 9 bits set-index-calc, 5 bits offset-in-line => 1 extra bit | ||
456 | * 64b line-sz: 8 bits set-index-calc, 6 bits offset-in-line => 1 extra bit | ||
457 | * | ||
458 | * ------------------ | 387 | * ------------------ |
459 | * MMU v3 | 388 | * MMU v3 |
460 | * ------------------ | 389 | * ------------------ |
461 | * This ver of MMU supports var page sizes (1k-16k) - Linux will support | 390 | * This ver of MMU supports variable page sizes (1k-16k): although Linux will |
462 | * 8k (default), 16k and 4k. | 391 | * only support 8k (default), 16k and 4k. |
463 | * However from hardware perspective, smaller page sizes aggrevate aliasing | 392 | * However from hardware perspective, smaller page sizes aggrevate aliasing |
464 | * meaning more vaddr bits needed to disambiguate the cache-line-op ; | 393 | * meaning more vaddr bits needed to disambiguate the cache-line-op ; |
465 | * the existing scheme of piggybacking won't work for certain configurations. | 394 | * the existing scheme of piggybacking won't work for certain configurations. |
@@ -468,105 +397,10 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, | |||
468 | */ | 397 | */ |
469 | 398 | ||
470 | /*********************************************************** | 399 | /*********************************************************** |
471 | * Machine specific helpers for per line I-Cache invalidate. | 400 | * Machine specific helper for per line I-Cache invalidate. |
472 | * 3 routines to accpunt for 1, 2, 4 aliases possible | ||
473 | */ | ||
474 | |||
475 | static void __ic_line_inv_no_alias(unsigned long start, int num_lines) | ||
476 | { | ||
477 | while (num_lines-- > 0) { | ||
478 | #if (CONFIG_ARC_MMU_VER > 2) | ||
479 | write_aux_reg(ARC_REG_IC_PTAG, start); | ||
480 | #endif | ||
481 | write_aux_reg(ARC_REG_IC_IVIL, start); | ||
482 | start += ARC_ICACHE_LINE_LEN; | ||
483 | } | ||
484 | } | ||
485 | |||
486 | static void __ic_line_inv_2_alias(unsigned long start, int num_lines) | ||
487 | { | ||
488 | while (num_lines-- > 0) { | ||
489 | |||
490 | #if (CONFIG_ARC_MMU_VER > 2) | ||
491 | /* | ||
492 | * MMU v3, CDU prog model (for line ops) now uses a new IC_PTAG | ||
493 | * reg to pass the "tag" bits and existing IVIL reg only looks | ||
494 | * at bits relevant for "index" (details above) | ||
495 | * Programming Notes: | ||
496 | * -when writing tag to PTAG reg, bit chopping can be avoided, | ||
497 | * CDU ignores non-tag bits. | ||
498 | * -Ideally "index" must be computed from vaddr, but it is not | ||
499 | * avail in these rtns. So to be safe, we kill the lines in all | ||
500 | * possible indexes corresp to num of aliases possible for | ||
501 | * given cache config. | ||
502 | */ | ||
503 | write_aux_reg(ARC_REG_IC_PTAG, start); | ||
504 | write_aux_reg(ARC_REG_IC_IVIL, | ||
505 | start & ~(0x1 << PAGE_SHIFT)); | ||
506 | write_aux_reg(ARC_REG_IC_IVIL, start | (0x1 << PAGE_SHIFT)); | ||
507 | #else | ||
508 | write_aux_reg(ARC_REG_IC_IVIL, start); | ||
509 | write_aux_reg(ARC_REG_IC_IVIL, start | 0x01); | ||
510 | #endif | ||
511 | start += ARC_ICACHE_LINE_LEN; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | static void __ic_line_inv_4_alias(unsigned long start, int num_lines) | ||
516 | { | ||
517 | while (num_lines-- > 0) { | ||
518 | |||
519 | #if (CONFIG_ARC_MMU_VER > 2) | ||
520 | write_aux_reg(ARC_REG_IC_PTAG, start); | ||
521 | |||
522 | write_aux_reg(ARC_REG_IC_IVIL, | ||
523 | start & ~(0x3 << PAGE_SHIFT)); | ||
524 | write_aux_reg(ARC_REG_IC_IVIL, | ||
525 | start & ~(0x2 << PAGE_SHIFT)); | ||
526 | write_aux_reg(ARC_REG_IC_IVIL, | ||
527 | start & ~(0x1 << PAGE_SHIFT)); | ||
528 | write_aux_reg(ARC_REG_IC_IVIL, start | (0x3 << PAGE_SHIFT)); | ||
529 | #else | ||
530 | write_aux_reg(ARC_REG_IC_IVIL, start); | ||
531 | write_aux_reg(ARC_REG_IC_IVIL, start | 0x01); | ||
532 | write_aux_reg(ARC_REG_IC_IVIL, start | 0x02); | ||
533 | write_aux_reg(ARC_REG_IC_IVIL, start | 0x03); | ||
534 | #endif | ||
535 | start += ARC_ICACHE_LINE_LEN; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | static void __ic_line_inv(unsigned long start, unsigned long sz) | ||
540 | { | ||
541 | unsigned long flags; | ||
542 | int num_lines, slack; | ||
543 | |||
544 | /* | ||
545 | * Ensure we properly floor/ceil the non-line aligned/sized requests | ||
546 | * and have @start - aligned to cache line, and integral @num_lines | ||
547 | * However page sized flushes can be compile time optimised. | ||
548 | * -@start will be cache-line aligned already (being page aligned) | ||
549 | * -@sz will be integral multiple of line size (being page sized). | ||
550 | */ | ||
551 | if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { | ||
552 | slack = start & ~ICACHE_LINE_MASK; | ||
553 | sz += slack; | ||
554 | start -= slack; | ||
555 | } | ||
556 | |||
557 | num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN); | ||
558 | |||
559 | local_irq_save(flags); | ||
560 | (*___flush_icache_rtn) (start, num_lines); | ||
561 | local_irq_restore(flags); | ||
562 | } | ||
563 | |||
564 | /* Unlike routines above, having vaddr for flush op (along with paddr), | ||
565 | * prevents the need to speculatively kill the lines in multiple sets | ||
566 | * based on ratio of way_sz : pg_sz | ||
567 | */ | 401 | */ |
568 | static void __ic_line_inv_vaddr(unsigned long phy_start, | 402 | static void __ic_line_inv_vaddr(unsigned long phy_start, unsigned long vaddr, |
569 | unsigned long vaddr, unsigned long sz) | 403 | unsigned long sz) |
570 | { | 404 | { |
571 | unsigned long flags; | 405 | unsigned long flags; |
572 | int num_lines, slack; | 406 | int num_lines, slack; |
@@ -595,7 +429,7 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, | |||
595 | write_aux_reg(ARC_REG_IC_IVIL, vaddr); | 429 | write_aux_reg(ARC_REG_IC_IVIL, vaddr); |
596 | vaddr += ARC_ICACHE_LINE_LEN; | 430 | vaddr += ARC_ICACHE_LINE_LEN; |
597 | #else | 431 | #else |
598 | /* this paddr contains vaddrs bits as needed */ | 432 | /* paddr contains stuffed vaddrs bits */ |
599 | write_aux_reg(ARC_REG_IC_IVIL, addr); | 433 | write_aux_reg(ARC_REG_IC_IVIL, addr); |
600 | #endif | 434 | #endif |
601 | addr += ARC_ICACHE_LINE_LEN; | 435 | addr += ARC_ICACHE_LINE_LEN; |
@@ -605,7 +439,6 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, | |||
605 | 439 | ||
606 | #else | 440 | #else |
607 | 441 | ||
608 | #define __ic_line_inv(start, sz) | ||
609 | #define __ic_line_inv_vaddr(pstart, vstart, sz) | 442 | #define __ic_line_inv_vaddr(pstart, vstart, sz) |
610 | 443 | ||
611 | #endif /* CONFIG_ARC_HAS_ICACHE */ | 444 | #endif /* CONFIG_ARC_HAS_ICACHE */ |