1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 2a88b5ba8SSam Ravnborg /* We need to carefully read the error status, ACK the errors, 3a88b5ba8SSam Ravnborg * prevent recursive traps, and pass the information on to C 4a88b5ba8SSam Ravnborg * code for logging. 5a88b5ba8SSam Ravnborg * 6a88b5ba8SSam Ravnborg * We pass the AFAR in as-is, and we encode the status 7a88b5ba8SSam Ravnborg * information as described in asm-sparc64/sfafsr.h 8a88b5ba8SSam Ravnborg */ 9a88b5ba8SSam Ravnborg .type __spitfire_access_error,#function 10a88b5ba8SSam Ravnborg__spitfire_access_error: 11a88b5ba8SSam Ravnborg /* Disable ESTATE error reporting so that we do not take 12a88b5ba8SSam Ravnborg * recursive traps and RED state the processor. 13a88b5ba8SSam Ravnborg */ 14a88b5ba8SSam Ravnborg stxa %g0, [%g0] ASI_ESTATE_ERROR_EN 15a88b5ba8SSam Ravnborg membar #Sync 16a88b5ba8SSam Ravnborg 17a88b5ba8SSam Ravnborg mov UDBE_UE, %g1 18a88b5ba8SSam Ravnborg ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR 19a88b5ba8SSam Ravnborg 20a88b5ba8SSam Ravnborg /* __spitfire_cee_trap branches here with AFSR in %g4 and 21a88b5ba8SSam Ravnborg * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the ESTATE 22a88b5ba8SSam Ravnborg * Error Enable register. 23a88b5ba8SSam Ravnborg */ 24a88b5ba8SSam Ravnborg__spitfire_cee_trap_continue: 25a88b5ba8SSam Ravnborg ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR 26a88b5ba8SSam Ravnborg 27a88b5ba8SSam Ravnborg rdpr %tt, %g3 28a88b5ba8SSam Ravnborg and %g3, 0x1ff, %g3 ! Paranoia 29a88b5ba8SSam Ravnborg sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3 30a88b5ba8SSam Ravnborg or %g4, %g3, %g4 31a88b5ba8SSam Ravnborg rdpr %tl, %g3 32a88b5ba8SSam Ravnborg cmp %g3, 1 33a88b5ba8SSam Ravnborg mov 1, %g3 34a88b5ba8SSam Ravnborg bleu %xcc, 1f 35a88b5ba8SSam Ravnborg sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3 36a88b5ba8SSam Ravnborg 37a88b5ba8SSam Ravnborg or %g4, %g3, %g4 38a88b5ba8SSam Ravnborg 39a88b5ba8SSam Ravnborg /* Read in the UDB error register state, clearing the sticky 40a88b5ba8SSam Ravnborg * error bits as-needed. We only clear them if the UE bit is 41a88b5ba8SSam Ravnborg * set. Likewise, __spitfire_cee_trap below will only do so 42a88b5ba8SSam Ravnborg * if the CE bit is set. 43a88b5ba8SSam Ravnborg * 44a88b5ba8SSam Ravnborg * NOTE: UltraSparc-I/II have high and low UDB error 45a88b5ba8SSam Ravnborg * registers, corresponding to the two UDB units 46a88b5ba8SSam Ravnborg * present on those chips. UltraSparc-IIi only 47a88b5ba8SSam Ravnborg * has a single UDB, called "SDB" in the manual. 48a88b5ba8SSam Ravnborg * For IIi the upper UDB register always reads 49a88b5ba8SSam Ravnborg * as zero so for our purposes things will just 50a88b5ba8SSam Ravnborg * work with the checks below. 51a88b5ba8SSam Ravnborg */ 52a88b5ba8SSam Ravnborg1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3 53a88b5ba8SSam Ravnborg and %g3, 0x3ff, %g7 ! Paranoia 54a88b5ba8SSam Ravnborg sllx %g7, SFSTAT_UDBH_SHIFT, %g7 55a88b5ba8SSam Ravnborg or %g4, %g7, %g4 56a88b5ba8SSam Ravnborg andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE 57a88b5ba8SSam Ravnborg be,pn %xcc, 1f 58a88b5ba8SSam Ravnborg nop 59a88b5ba8SSam Ravnborg stxa %g3, [%g0] ASI_UDB_ERROR_W 60a88b5ba8SSam Ravnborg membar #Sync 61a88b5ba8SSam Ravnborg 62a88b5ba8SSam Ravnborg1: mov 0x18, %g3 63a88b5ba8SSam Ravnborg ldxa [%g3] ASI_UDBL_ERROR_R, %g3 64a88b5ba8SSam Ravnborg and %g3, 0x3ff, %g7 ! Paranoia 65a88b5ba8SSam Ravnborg sllx %g7, SFSTAT_UDBL_SHIFT, %g7 66a88b5ba8SSam Ravnborg or %g4, %g7, %g4 67a88b5ba8SSam Ravnborg andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE 68a88b5ba8SSam Ravnborg be,pn %xcc, 1f 69a88b5ba8SSam Ravnborg nop 70a88b5ba8SSam Ravnborg mov 0x18, %g7 71a88b5ba8SSam Ravnborg stxa %g3, [%g7] ASI_UDB_ERROR_W 72a88b5ba8SSam Ravnborg membar #Sync 73a88b5ba8SSam Ravnborg 74a88b5ba8SSam Ravnborg1: /* Ok, now that we've latched the error state, clear the 75a88b5ba8SSam Ravnborg * sticky bits in the AFSR. 76a88b5ba8SSam Ravnborg */ 77a88b5ba8SSam Ravnborg stxa %g4, [%g0] ASI_AFSR 78a88b5ba8SSam Ravnborg membar #Sync 79a88b5ba8SSam Ravnborg 80a88b5ba8SSam Ravnborg rdpr %tl, %g2 81a88b5ba8SSam Ravnborg cmp %g2, 1 82a88b5ba8SSam Ravnborg rdpr %pil, %g2 83a88b5ba8SSam Ravnborg bleu,pt %xcc, 1f 84a88b5ba8SSam Ravnborg wrpr %g0, PIL_NORMAL_MAX, %pil 85a88b5ba8SSam Ravnborg 86a88b5ba8SSam Ravnborg ba,pt %xcc, etraptl1 87a88b5ba8SSam Ravnborg rd %pc, %g7 88a88b5ba8SSam Ravnborg 8949fa5230SDavid S. Miller ba,a,pt %xcc, 2f 900ae2d26fSBabu Moger nop 91a88b5ba8SSam Ravnborg 92a88b5ba8SSam Ravnborg1: ba,pt %xcc, etrap_irq 93a88b5ba8SSam Ravnborg rd %pc, %g7 94a88b5ba8SSam Ravnborg 95a88b5ba8SSam Ravnborg2: 96a88b5ba8SSam Ravnborg#ifdef CONFIG_TRACE_IRQFLAGS 97a88b5ba8SSam Ravnborg call trace_hardirqs_off 98a88b5ba8SSam Ravnborg nop 99a88b5ba8SSam Ravnborg#endif 100a88b5ba8SSam Ravnborg mov %l4, %o1 101a88b5ba8SSam Ravnborg mov %l5, %o2 102a88b5ba8SSam Ravnborg call spitfire_access_error 103a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 10449fa5230SDavid S. Miller ba,a,pt %xcc, rtrap 105a88b5ba8SSam Ravnborg .size __spitfire_access_error,.-__spitfire_access_error 106a88b5ba8SSam Ravnborg 107a88b5ba8SSam Ravnborg /* This is the trap handler entry point for ECC correctable 108a88b5ba8SSam Ravnborg * errors. They are corrected, but we listen for the trap so 109a88b5ba8SSam Ravnborg * that the event can be logged. 110a88b5ba8SSam Ravnborg * 111a88b5ba8SSam Ravnborg * Disrupting errors are either: 112a88b5ba8SSam Ravnborg * 1) single-bit ECC errors during UDB reads to system 113a88b5ba8SSam Ravnborg * memory 114a88b5ba8SSam Ravnborg * 2) data parity errors during write-back events 115a88b5ba8SSam Ravnborg * 116a88b5ba8SSam Ravnborg * As far as I can make out from the manual, the CEE trap is 117a88b5ba8SSam Ravnborg * only for correctable errors during memory read accesses by 118a88b5ba8SSam Ravnborg * the front-end of the processor. 119a88b5ba8SSam Ravnborg * 120a88b5ba8SSam Ravnborg * The code below is only for trap level 1 CEE events, as it 121a88b5ba8SSam Ravnborg * is the only situation where we can safely record and log. 122a88b5ba8SSam Ravnborg * For trap level >1 we just clear the CE bit in the AFSR and 123a88b5ba8SSam Ravnborg * return. 124a88b5ba8SSam Ravnborg * 125a88b5ba8SSam Ravnborg * This is just like __spiftire_access_error above, but it 126a88b5ba8SSam Ravnborg * specifically handles correctable errors. If an 127a88b5ba8SSam Ravnborg * uncorrectable error is indicated in the AFSR we will branch 128a88b5ba8SSam Ravnborg * directly above to __spitfire_access_error to handle it 129a88b5ba8SSam Ravnborg * instead. Uncorrectable therefore takes priority over 130a88b5ba8SSam Ravnborg * correctable, and the error logging C code will notice this 131a88b5ba8SSam Ravnborg * case by inspecting the trap type. 132a88b5ba8SSam Ravnborg */ 133a88b5ba8SSam Ravnborg .type __spitfire_cee_trap,#function 134a88b5ba8SSam Ravnborg__spitfire_cee_trap: 135a88b5ba8SSam Ravnborg ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR 136a88b5ba8SSam Ravnborg mov 1, %g3 137a88b5ba8SSam Ravnborg sllx %g3, SFAFSR_UE_SHIFT, %g3 138a88b5ba8SSam Ravnborg andcc %g4, %g3, %g0 ! Check for UE 139a88b5ba8SSam Ravnborg bne,pn %xcc, __spitfire_access_error 140a88b5ba8SSam Ravnborg nop 141a88b5ba8SSam Ravnborg 142a88b5ba8SSam Ravnborg /* Ok, in this case we only have a correctable error. 143a88b5ba8SSam Ravnborg * Indicate we only wish to capture that state in register 144a88b5ba8SSam Ravnborg * %g1, and we only disable CE error reporting unlike UE 145a88b5ba8SSam Ravnborg * handling which disables all errors. 146a88b5ba8SSam Ravnborg */ 147a88b5ba8SSam Ravnborg ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3 148a88b5ba8SSam Ravnborg andn %g3, ESTATE_ERR_CE, %g3 149a88b5ba8SSam Ravnborg stxa %g3, [%g0] ASI_ESTATE_ERROR_EN 150a88b5ba8SSam Ravnborg membar #Sync 151a88b5ba8SSam Ravnborg 152a88b5ba8SSam Ravnborg /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */ 153a88b5ba8SSam Ravnborg ba,pt %xcc, __spitfire_cee_trap_continue 154a88b5ba8SSam Ravnborg mov UDBE_CE, %g1 155a88b5ba8SSam Ravnborg .size __spitfire_cee_trap,.-__spitfire_cee_trap 156a88b5ba8SSam Ravnborg 157a88b5ba8SSam Ravnborg .type __spitfire_data_access_exception_tl1,#function 158a88b5ba8SSam Ravnborg__spitfire_data_access_exception_tl1: 159a88b5ba8SSam Ravnborg rdpr %pstate, %g4 160a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 161a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 162a88b5ba8SSam Ravnborg mov DMMU_SFAR, %g5 163a88b5ba8SSam Ravnborg ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR 164a88b5ba8SSam Ravnborg ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR 165a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit 166a88b5ba8SSam Ravnborg membar #Sync 167a88b5ba8SSam Ravnborg rdpr %tt, %g3 168a88b5ba8SSam Ravnborg cmp %g3, 0x80 ! first win spill/fill trap 169a88b5ba8SSam Ravnborg blu,pn %xcc, 1f 170a88b5ba8SSam Ravnborg cmp %g3, 0xff ! last win spill/fill trap 171a88b5ba8SSam Ravnborg bgu,pn %xcc, 1f 172a88b5ba8SSam Ravnborg nop 173a88b5ba8SSam Ravnborg ba,pt %xcc, winfix_dax 174a88b5ba8SSam Ravnborg rdpr %tpc, %g3 175a88b5ba8SSam Ravnborg1: sethi %hi(109f), %g7 176a88b5ba8SSam Ravnborg ba,pt %xcc, etraptl1 177a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 178a88b5ba8SSam Ravnborg mov %l4, %o1 179a88b5ba8SSam Ravnborg mov %l5, %o2 180a88b5ba8SSam Ravnborg call spitfire_data_access_exception_tl1 181a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 18249fa5230SDavid S. Miller ba,a,pt %xcc, rtrap 183a88b5ba8SSam Ravnborg .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 184a88b5ba8SSam Ravnborg 185a88b5ba8SSam Ravnborg .type __spitfire_data_access_exception,#function 186a88b5ba8SSam Ravnborg__spitfire_data_access_exception: 187a88b5ba8SSam Ravnborg rdpr %pstate, %g4 188a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 189a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 190a88b5ba8SSam Ravnborg mov DMMU_SFAR, %g5 191a88b5ba8SSam Ravnborg ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR 192a88b5ba8SSam Ravnborg ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR 193a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit 194a88b5ba8SSam Ravnborg membar #Sync 195a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 196a88b5ba8SSam Ravnborg ba,pt %xcc, etrap 197a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 198a88b5ba8SSam Ravnborg mov %l4, %o1 199a88b5ba8SSam Ravnborg mov %l5, %o2 200a88b5ba8SSam Ravnborg call spitfire_data_access_exception 201a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 20249fa5230SDavid S. Miller ba,a,pt %xcc, rtrap 203a88b5ba8SSam Ravnborg .size __spitfire_data_access_exception,.-__spitfire_data_access_exception 204a88b5ba8SSam Ravnborg 205a88b5ba8SSam Ravnborg .type __spitfire_insn_access_exception_tl1,#function 206a88b5ba8SSam Ravnborg__spitfire_insn_access_exception_tl1: 207a88b5ba8SSam Ravnborg rdpr %pstate, %g4 208a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 209a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 210a88b5ba8SSam Ravnborg ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR 211a88b5ba8SSam Ravnborg rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC 212a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit 213a88b5ba8SSam Ravnborg membar #Sync 214a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 215a88b5ba8SSam Ravnborg ba,pt %xcc, etraptl1 216a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 217a88b5ba8SSam Ravnborg mov %l4, %o1 218a88b5ba8SSam Ravnborg mov %l5, %o2 219a88b5ba8SSam Ravnborg call spitfire_insn_access_exception_tl1 220a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 22149fa5230SDavid S. Miller ba,a,pt %xcc, rtrap 222a88b5ba8SSam Ravnborg .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 223a88b5ba8SSam Ravnborg 224a88b5ba8SSam Ravnborg .type __spitfire_insn_access_exception,#function 225a88b5ba8SSam Ravnborg__spitfire_insn_access_exception: 226a88b5ba8SSam Ravnborg rdpr %pstate, %g4 227a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 228a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 229a88b5ba8SSam Ravnborg ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR 230a88b5ba8SSam Ravnborg rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC 231a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit 232a88b5ba8SSam Ravnborg membar #Sync 233a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 234a88b5ba8SSam Ravnborg ba,pt %xcc, etrap 235a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 236a88b5ba8SSam Ravnborg mov %l4, %o1 237a88b5ba8SSam Ravnborg mov %l5, %o2 238a88b5ba8SSam Ravnborg call spitfire_insn_access_exception 239a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 24049fa5230SDavid S. Miller ba,a,pt %xcc, rtrap 241a88b5ba8SSam Ravnborg .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception 242