diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-08-23 08:07:18 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-08-30 12:12:18 -0400 |
commit | 5bd87adf9b2ae5fa1bb469c68029b4eec06d6e03 (patch) | |
tree | 25b80c5717ae313fa52d4153caa6fef3100055bb | |
parent | ade922f8e269115252d199bf6c524a10379cf716 (diff) |
ARC: [ASID] Refactor the TLB paranoid debug code
-Asm code already has values of SW and HW ASID values, so they can be
passed to the printing routine.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/mmu.h | 2 | ||||
-rw-r--r-- | arch/arc/mm/tlb.c | 24 | ||||
-rw-r--r-- | arch/arc/mm/tlbex.S | 16 |
3 files changed, 21 insertions, 21 deletions
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h index 7165f25c0910..1639f25e47b1 100644 --- a/arch/arc/include/asm/mmu.h +++ b/arch/arc/include/asm/mmu.h | |||
@@ -52,7 +52,7 @@ typedef struct { | |||
52 | } mm_context_t; | 52 | } mm_context_t; |
53 | 53 | ||
54 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA | 54 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA |
55 | void tlb_paranoid_check(unsigned int pid_sw, unsigned long address); | 55 | void tlb_paranoid_check(unsigned int mm_asid, unsigned long address); |
56 | #else | 56 | #else |
57 | #define tlb_paranoid_check(a, b) | 57 | #define tlb_paranoid_check(a, b) |
58 | #endif | 58 | #endif |
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 7646a96f3155..a4ad68c4b50d 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c | |||
@@ -688,25 +688,27 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, | |||
688 | * Low Level ASM TLB handler calls this if it finds that HW and SW ASIDS | 688 | * Low Level ASM TLB handler calls this if it finds that HW and SW ASIDS |
689 | * don't match | 689 | * don't match |
690 | */ | 690 | */ |
691 | void print_asid_mismatch(int is_fast_path) | 691 | void print_asid_mismatch(int mm_asid, int mmu_asid, int is_fast_path) |
692 | { | 692 | { |
693 | int pid_sw, pid_hw; | ||
694 | pid_sw = current->active_mm->context.asid; | ||
695 | pid_hw = read_aux_reg(ARC_REG_PID) & 0xff; | ||
696 | |||
697 | pr_emerg("ASID Mismatch in %s Path Handler: sw-pid=0x%x hw-pid=0x%x\n", | 693 | pr_emerg("ASID Mismatch in %s Path Handler: sw-pid=0x%x hw-pid=0x%x\n", |
698 | is_fast_path ? "Fast" : "Slow", pid_sw, pid_hw); | 694 | is_fast_path ? "Fast" : "Slow", mm_asid, mmu_asid); |
699 | 695 | ||
700 | __asm__ __volatile__("flag 1"); | 696 | __asm__ __volatile__("flag 1"); |
701 | } | 697 | } |
702 | 698 | ||
703 | void tlb_paranoid_check(unsigned int pid_sw, unsigned long addr) | 699 | void tlb_paranoid_check(unsigned int mm_asid, unsigned long addr) |
704 | { | 700 | { |
705 | unsigned int pid_hw; | 701 | unsigned int mmu_asid; |
706 | 702 | ||
707 | pid_hw = read_aux_reg(ARC_REG_PID) & 0xff; | 703 | mmu_asid = read_aux_reg(ARC_REG_PID) & 0xff; |
708 | 704 | ||
709 | if (addr < 0x70000000 && ((pid_hw != pid_sw) || (pid_sw == NO_ASID))) | 705 | /* |
710 | print_asid_mismatch(0); | 706 | * At the time of a TLB miss/installation |
707 | * - HW version needs to match SW version | ||
708 | * - SW needs to have a valid ASID | ||
709 | */ | ||
710 | if (addr < 0x70000000 && | ||
711 | ((mmu_asid != mm_asid) || (mm_asid == NO_ASID))) | ||
712 | print_asid_mismatch(mm_asid, mmu_asid, 0); | ||
711 | } | 713 | } |
712 | #endif | 714 | #endif |
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index 50e83ca96b96..88897a112d55 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S | |||
@@ -102,7 +102,7 @@ ex_saved_reg1: | |||
102 | ; VERIFY if the ASID in MMU-PID Reg is same as | 102 | ; VERIFY if the ASID in MMU-PID Reg is same as |
103 | ; one in Linux data structures | 103 | ; one in Linux data structures |
104 | 104 | ||
105 | DBG_ASID_MISMATCH | 105 | tlb_paranoid_check_asm |
106 | .endm | 106 | .endm |
107 | 107 | ||
108 | .macro TLBMISS_RESTORE_REGS | 108 | .macro TLBMISS_RESTORE_REGS |
@@ -133,34 +133,32 @@ ex_saved_reg1: | |||
133 | ; In bizzare scenrios SW and HW ASID can get out-of-sync which is trouble. | 133 | ; In bizzare scenrios SW and HW ASID can get out-of-sync which is trouble. |
134 | ; So we try to detect this in TLB Mis shandler | 134 | ; So we try to detect this in TLB Mis shandler |
135 | 135 | ||
136 | 136 | .macro tlb_paranoid_check_asm | |
137 | .macro DBG_ASID_MISMATCH | ||
138 | 137 | ||
139 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA | 138 | #ifdef CONFIG_ARC_DBG_TLB_PARANOIA |
140 | 139 | ||
141 | ; make sure h/w ASID is same as s/w ASID | ||
142 | |||
143 | GET_CURR_TASK_ON_CPU r3 | 140 | GET_CURR_TASK_ON_CPU r3 |
144 | ld r0, [r3, TASK_ACT_MM] | 141 | ld r0, [r3, TASK_ACT_MM] |
145 | ld r0, [r0, MM_CTXT+MM_CTXT_ASID] | 142 | ld r0, [r0, MM_CTXT+MM_CTXT_ASID] |
146 | 143 | ||
147 | lr r1, [ARC_REG_PID] | 144 | lr r1, [ARC_REG_PID] |
148 | and r1, r1, 0xFF | 145 | and r1, r1, 0xFF |
146 | |||
149 | breq r1, r0, 5f | 147 | breq r1, r0, 5f |
150 | 148 | ||
151 | ; Error if H/w and S/w ASID don't match, but NOT if in kernel mode | 149 | ; Error if H/w and S/w ASID don't match, but NOT if in kernel mode |
152 | lr r0, [erstatus] | 150 | lr r2, [erstatus] |
153 | bbit0 r0, STATUS_U_BIT, 5f | 151 | bbit0 r2, STATUS_U_BIT, 5f |
154 | 152 | ||
155 | ; We sure are in troubled waters, Flag the error, but to do so | 153 | ; We sure are in troubled waters, Flag the error, but to do so |
156 | ; need to switch to kernel mode stack to call error routine | 154 | ; need to switch to kernel mode stack to call error routine |
157 | GET_TSK_STACK_BASE r3, sp | 155 | GET_TSK_STACK_BASE r3, sp |
158 | 156 | ||
159 | ; Call printk to shoutout aloud | 157 | ; Call printk to shoutout aloud |
160 | mov r0, 1 | 158 | mov r2, 1 |
161 | j print_asid_mismatch | 159 | j print_asid_mismatch |
162 | 160 | ||
163 | 5: ; ASIDs match so proceed normally | 161 | 5: ; ASIDs match so proceed normally |
164 | nop | 162 | nop |
165 | 163 | ||
166 | #endif | 164 | #endif |