1a88b5ba8SSam Ravnborg /* We need to carefully read the error status, ACK the errors, 2a88b5ba8SSam Ravnborg * prevent recursive traps, and pass the information on to C 3a88b5ba8SSam Ravnborg * code for logging. 4a88b5ba8SSam Ravnborg * 5a88b5ba8SSam Ravnborg * We pass the AFAR in as-is, and we encode the status 6a88b5ba8SSam Ravnborg * information as described in asm-sparc64/sfafsr.h 7a88b5ba8SSam Ravnborg */ 8a88b5ba8SSam Ravnborg .type __spitfire_access_error,#function 9a88b5ba8SSam Ravnborg__spitfire_access_error: 10a88b5ba8SSam Ravnborg /* Disable ESTATE error reporting so that we do not take 11a88b5ba8SSam Ravnborg * recursive traps and RED state the processor. 12a88b5ba8SSam Ravnborg */ 13a88b5ba8SSam Ravnborg stxa %g0, [%g0] ASI_ESTATE_ERROR_EN 14a88b5ba8SSam Ravnborg membar #Sync 15a88b5ba8SSam Ravnborg 16a88b5ba8SSam Ravnborg mov UDBE_UE, %g1 17a88b5ba8SSam Ravnborg ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR 18a88b5ba8SSam Ravnborg 19a88b5ba8SSam Ravnborg /* __spitfire_cee_trap branches here with AFSR in %g4 and 20a88b5ba8SSam Ravnborg * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the ESTATE 21a88b5ba8SSam Ravnborg * Error Enable register. 22a88b5ba8SSam Ravnborg */ 23a88b5ba8SSam Ravnborg__spitfire_cee_trap_continue: 24a88b5ba8SSam Ravnborg ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR 25a88b5ba8SSam Ravnborg 26a88b5ba8SSam Ravnborg rdpr %tt, %g3 27a88b5ba8SSam Ravnborg and %g3, 0x1ff, %g3 ! Paranoia 28a88b5ba8SSam Ravnborg sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3 29a88b5ba8SSam Ravnborg or %g4, %g3, %g4 30a88b5ba8SSam Ravnborg rdpr %tl, %g3 31a88b5ba8SSam Ravnborg cmp %g3, 1 32a88b5ba8SSam Ravnborg mov 1, %g3 33a88b5ba8SSam Ravnborg bleu %xcc, 1f 34a88b5ba8SSam Ravnborg sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3 35a88b5ba8SSam Ravnborg 36a88b5ba8SSam Ravnborg or %g4, %g3, %g4 37a88b5ba8SSam Ravnborg 38a88b5ba8SSam Ravnborg /* Read in the UDB error register state, clearing the sticky 39a88b5ba8SSam Ravnborg * error bits as-needed. We only clear them if the UE bit is 40a88b5ba8SSam Ravnborg * set. Likewise, __spitfire_cee_trap below will only do so 41a88b5ba8SSam Ravnborg * if the CE bit is set. 42a88b5ba8SSam Ravnborg * 43a88b5ba8SSam Ravnborg * NOTE: UltraSparc-I/II have high and low UDB error 44a88b5ba8SSam Ravnborg * registers, corresponding to the two UDB units 45a88b5ba8SSam Ravnborg * present on those chips. UltraSparc-IIi only 46a88b5ba8SSam Ravnborg * has a single UDB, called "SDB" in the manual. 47a88b5ba8SSam Ravnborg * For IIi the upper UDB register always reads 48a88b5ba8SSam Ravnborg * as zero so for our purposes things will just 49a88b5ba8SSam Ravnborg * work with the checks below. 50a88b5ba8SSam Ravnborg */ 51a88b5ba8SSam Ravnborg1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3 52a88b5ba8SSam Ravnborg and %g3, 0x3ff, %g7 ! Paranoia 53a88b5ba8SSam Ravnborg sllx %g7, SFSTAT_UDBH_SHIFT, %g7 54a88b5ba8SSam Ravnborg or %g4, %g7, %g4 55a88b5ba8SSam Ravnborg andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE 56a88b5ba8SSam Ravnborg be,pn %xcc, 1f 57a88b5ba8SSam Ravnborg nop 58a88b5ba8SSam Ravnborg stxa %g3, [%g0] ASI_UDB_ERROR_W 59a88b5ba8SSam Ravnborg membar #Sync 60a88b5ba8SSam Ravnborg 61a88b5ba8SSam Ravnborg1: mov 0x18, %g3 62a88b5ba8SSam Ravnborg ldxa [%g3] ASI_UDBL_ERROR_R, %g3 63a88b5ba8SSam Ravnborg and %g3, 0x3ff, %g7 ! Paranoia 64a88b5ba8SSam Ravnborg sllx %g7, SFSTAT_UDBL_SHIFT, %g7 65a88b5ba8SSam Ravnborg or %g4, %g7, %g4 66a88b5ba8SSam Ravnborg andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE 67a88b5ba8SSam Ravnborg be,pn %xcc, 1f 68a88b5ba8SSam Ravnborg nop 69a88b5ba8SSam Ravnborg mov 0x18, %g7 70a88b5ba8SSam Ravnborg stxa %g3, [%g7] ASI_UDB_ERROR_W 71a88b5ba8SSam Ravnborg membar #Sync 72a88b5ba8SSam Ravnborg 73a88b5ba8SSam Ravnborg1: /* Ok, now that we've latched the error state, clear the 74a88b5ba8SSam Ravnborg * sticky bits in the AFSR. 75a88b5ba8SSam Ravnborg */ 76a88b5ba8SSam Ravnborg stxa %g4, [%g0] ASI_AFSR 77a88b5ba8SSam Ravnborg membar #Sync 78a88b5ba8SSam Ravnborg 79a88b5ba8SSam Ravnborg rdpr %tl, %g2 80a88b5ba8SSam Ravnborg cmp %g2, 1 81a88b5ba8SSam Ravnborg rdpr %pil, %g2 82a88b5ba8SSam Ravnborg bleu,pt %xcc, 1f 83a88b5ba8SSam Ravnborg wrpr %g0, PIL_NORMAL_MAX, %pil 84a88b5ba8SSam Ravnborg 85a88b5ba8SSam Ravnborg ba,pt %xcc, etraptl1 86a88b5ba8SSam Ravnborg rd %pc, %g7 87a88b5ba8SSam Ravnborg 88a88b5ba8SSam Ravnborg ba,pt %xcc, 2f 89a88b5ba8SSam Ravnborg nop 90a88b5ba8SSam Ravnborg 91a88b5ba8SSam Ravnborg1: ba,pt %xcc, etrap_irq 92a88b5ba8SSam Ravnborg rd %pc, %g7 93a88b5ba8SSam Ravnborg 94a88b5ba8SSam Ravnborg2: 95a88b5ba8SSam Ravnborg#ifdef CONFIG_TRACE_IRQFLAGS 96a88b5ba8SSam Ravnborg call trace_hardirqs_off 97a88b5ba8SSam Ravnborg nop 98a88b5ba8SSam Ravnborg#endif 99a88b5ba8SSam Ravnborg mov %l4, %o1 100a88b5ba8SSam Ravnborg mov %l5, %o2 101a88b5ba8SSam Ravnborg call spitfire_access_error 102a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 103a88b5ba8SSam Ravnborg ba,pt %xcc, rtrap 104a88b5ba8SSam Ravnborg nop 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 182a88b5ba8SSam Ravnborg ba,pt %xcc, rtrap 183a88b5ba8SSam Ravnborg nop 184a88b5ba8SSam Ravnborg .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 185a88b5ba8SSam Ravnborg 186a88b5ba8SSam Ravnborg .type __spitfire_data_access_exception,#function 187a88b5ba8SSam Ravnborg__spitfire_data_access_exception: 188a88b5ba8SSam Ravnborg rdpr %pstate, %g4 189a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 190a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 191a88b5ba8SSam Ravnborg mov DMMU_SFAR, %g5 192a88b5ba8SSam Ravnborg ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR 193a88b5ba8SSam Ravnborg ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR 194a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit 195a88b5ba8SSam Ravnborg membar #Sync 196a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 197a88b5ba8SSam Ravnborg ba,pt %xcc, etrap 198a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 199a88b5ba8SSam Ravnborg mov %l4, %o1 200a88b5ba8SSam Ravnborg mov %l5, %o2 201a88b5ba8SSam Ravnborg call spitfire_data_access_exception 202a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 203a88b5ba8SSam Ravnborg ba,pt %xcc, rtrap 204a88b5ba8SSam Ravnborg nop 205a88b5ba8SSam Ravnborg .size __spitfire_data_access_exception,.-__spitfire_data_access_exception 206a88b5ba8SSam Ravnborg 207a88b5ba8SSam Ravnborg .type __spitfire_insn_access_exception_tl1,#function 208a88b5ba8SSam Ravnborg__spitfire_insn_access_exception_tl1: 209a88b5ba8SSam Ravnborg rdpr %pstate, %g4 210a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 211a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 212a88b5ba8SSam Ravnborg ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR 213a88b5ba8SSam Ravnborg rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC 214a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit 215a88b5ba8SSam Ravnborg membar #Sync 216a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 217a88b5ba8SSam Ravnborg ba,pt %xcc, etraptl1 218a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 219a88b5ba8SSam Ravnborg mov %l4, %o1 220a88b5ba8SSam Ravnborg mov %l5, %o2 221a88b5ba8SSam Ravnborg call spitfire_insn_access_exception_tl1 222a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 223a88b5ba8SSam Ravnborg ba,pt %xcc, rtrap 224a88b5ba8SSam Ravnborg nop 225a88b5ba8SSam Ravnborg .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 226a88b5ba8SSam Ravnborg 227a88b5ba8SSam Ravnborg .type __spitfire_insn_access_exception,#function 228a88b5ba8SSam Ravnborg__spitfire_insn_access_exception: 229a88b5ba8SSam Ravnborg rdpr %pstate, %g4 230a88b5ba8SSam Ravnborg wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate 231a88b5ba8SSam Ravnborg mov TLB_SFSR, %g3 232a88b5ba8SSam Ravnborg ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR 233a88b5ba8SSam Ravnborg rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC 234a88b5ba8SSam Ravnborg stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit 235a88b5ba8SSam Ravnborg membar #Sync 236a88b5ba8SSam Ravnborg sethi %hi(109f), %g7 237a88b5ba8SSam Ravnborg ba,pt %xcc, etrap 238a88b5ba8SSam Ravnborg109: or %g7, %lo(109b), %g7 239a88b5ba8SSam Ravnborg mov %l4, %o1 240a88b5ba8SSam Ravnborg mov %l5, %o2 241a88b5ba8SSam Ravnborg call spitfire_insn_access_exception 242a88b5ba8SSam Ravnborg add %sp, PTREGS_OFF, %o0 243a88b5ba8SSam Ravnborg ba,pt %xcc, rtrap 244a88b5ba8SSam Ravnborg nop 245a88b5ba8SSam Ravnborg .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception 246