aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/traps.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-09-26 03:32:17 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-09-26 03:32:17 -0400
commit80dc0d6b44ce0f01df58d8899e46612690ed7d81 (patch)
tree570b8e834c0fae0793bdf75dd2fd2516b0fabf4f /arch/sparc64/kernel/traps.c
parent56425306517ef28a9b480161cdb96d182172bc1d (diff)
[SPARC64]: Probe D/I/E-cache config and use.
At boot time, determine the D-cache, I-cache and E-cache size and line-size. Use them in cache flushes when appropriate. This change was motivated by discovering that the D-cache on UltraSparc-IIIi and later are 64K not 32K, and the flushes done by the Cheetah error handlers were assuming a 32K size. There are still some pieces of code that are hard coding things and will need to be fixed up at some point. While we're here, fix the D-cache and I-cache parity error handlers to run with interrupts disabled, and when the trap occurs at trap level > 1 log the event via a counter displayed in /proc/cpuinfo. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r--arch/sparc64/kernel/traps.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index b280b2ef674f..f8e7005fede9 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -869,14 +869,19 @@ static void cheetah_flush_ecache_line(unsigned long physaddr)
869 */ 869 */
870static void __cheetah_flush_icache(void) 870static void __cheetah_flush_icache(void)
871{ 871{
872 unsigned long i; 872 unsigned int icache_size, icache_line_size;
873 unsigned long addr;
874
875 icache_size = local_cpu_data().icache_size;
876 icache_line_size = local_cpu_data().icache_line_size;
873 877
874 /* Clear the valid bits in all the tags. */ 878 /* Clear the valid bits in all the tags. */
875 for (i = 0; i < (1 << 15); i += (1 << 5)) { 879 for (addr = 0; addr < icache_size; addr += icache_line_size) {
876 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 880 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
877 "membar #Sync" 881 "membar #Sync"
878 : /* no outputs */ 882 : /* no outputs */
879 : "r" (i | (2 << 3)), "i" (ASI_IC_TAG)); 883 : "r" (addr | (2 << 3)),
884 "i" (ASI_IC_TAG));
880 } 885 }
881} 886}
882 887
@@ -904,13 +909,17 @@ static void cheetah_flush_icache(void)
904 909
905static void cheetah_flush_dcache(void) 910static void cheetah_flush_dcache(void)
906{ 911{
907 unsigned long i; 912 unsigned int dcache_size, dcache_line_size;
913 unsigned long addr;
914
915 dcache_size = local_cpu_data().dcache_size;
916 dcache_line_size = local_cpu_data().dcache_line_size;
908 917
909 for (i = 0; i < (1 << 16); i += (1 << 5)) { 918 for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
910 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 919 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
911 "membar #Sync" 920 "membar #Sync"
912 : /* no outputs */ 921 : /* no outputs */
913 : "r" (i), "i" (ASI_DCACHE_TAG)); 922 : "r" (addr), "i" (ASI_DCACHE_TAG));
914 } 923 }
915} 924}
916 925
@@ -921,24 +930,29 @@ static void cheetah_flush_dcache(void)
921 */ 930 */
922static void cheetah_plus_zap_dcache_parity(void) 931static void cheetah_plus_zap_dcache_parity(void)
923{ 932{
924 unsigned long i; 933 unsigned int dcache_size, dcache_line_size;
934 unsigned long addr;
935
936 dcache_size = local_cpu_data().dcache_size;
937 dcache_line_size = local_cpu_data().dcache_line_size;
925 938
926 for (i = 0; i < (1 << 16); i += (1 << 5)) { 939 for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
927 unsigned long tag = (i >> 14); 940 unsigned long tag = (addr >> 14);
928 unsigned long j; 941 unsigned long line;
929 942
930 __asm__ __volatile__("membar #Sync\n\t" 943 __asm__ __volatile__("membar #Sync\n\t"
931 "stxa %0, [%1] %2\n\t" 944 "stxa %0, [%1] %2\n\t"
932 "membar #Sync" 945 "membar #Sync"
933 : /* no outputs */ 946 : /* no outputs */
934 : "r" (tag), "r" (i), 947 : "r" (tag), "r" (addr),
935 "i" (ASI_DCACHE_UTAG)); 948 "i" (ASI_DCACHE_UTAG));
936 for (j = i; j < i + (1 << 5); j += (1 << 3)) 949 for (line = addr; line < addr + dcache_line_size; line += 8)
937 __asm__ __volatile__("membar #Sync\n\t" 950 __asm__ __volatile__("membar #Sync\n\t"
938 "stxa %%g0, [%0] %1\n\t" 951 "stxa %%g0, [%0] %1\n\t"
939 "membar #Sync" 952 "membar #Sync"
940 : /* no outputs */ 953 : /* no outputs */
941 : "r" (j), "i" (ASI_DCACHE_DATA)); 954 : "r" (line),
955 "i" (ASI_DCACHE_DATA));
942 } 956 }
943} 957}
944 958