1/* 2 * tbidefr.S 3 * 4 * Copyright (C) 2009, 2012 Imagination Technologies. 5 * 6 * This program is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License version 2 as published by the 8 * Free Software Foundation. 9 * 10 * Routing deferred exceptions 11 */ 12 13#include <asm/metag_regs.h> 14#include <asm/tbx.h> 15 16 .text 17 .balign 4 18 .global ___TBIHandleDFR 19 .type ___TBIHandleDFR,function 20/* D1Ar1:D0Ar2 -- State 21 * D0Ar3 -- SigNum 22 * D0Ar4 -- Triggers 23 * D1Ar5 -- Inst 24 * D0Ar6 -- pTBI (volatile) 25 */ 26___TBIHandleDFR: 27#ifdef META_BUG_MBN100212 28 MSETL [A0StP++], D0FrT, D0.5 29 30 /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved 31 * D0Ar4 -- The deferred exceptions 32 * D1Ar3 -- As per D0Ar4 but just the trigger bits 33 * D0.5 -- The bgnd deferred exceptions 34 * D1.5 -- TXDEFR with bgnd re-added 35 */ 36 37 /* - Collect the pending deferred exceptions using TXSTAT, 38 * (ack's the bgnd exceptions as a side-effect) 39 * - Manually collect remaining (interrupt) deferred exceptions 40 * using TXDEFR 41 * - Replace the triggers (from TXSTATI) with the int deferred 42 * exceptions DEFR ..., TXSTATI would have returned if it was valid 43 * from bgnd code 44 * - Reconstruct TXDEFR by or'ing bgnd deferred exceptions (except 45 * the DEFER bit) and the int deferred exceptions. This will be 46 * restored later 47 */ 48 DEFR D0.5, TXSTAT 49 MOV D1.5, TXDEFR 50 ANDT D0.5, D0.5, #HI(0xFFFF0000) 51 MOV D1Ar3, D1.5 52 ANDT D1Ar3, D1Ar3, #HI(0xFFFF0000) 53 OR D0Ar4, D1Ar3, #TXSTAT_DEFER_BIT 54 OR D1.5, D1.5, D0.5 55 56 /* Mask off anything unrelated to the deferred exception triggers */ 57 ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS) 58 59 /* Can assume that at least one exception happened since this 60 * handler wouldnt have been called otherwise. 61 * 62 * Replace the signal number and at the same time, prepare 63 * the mask to acknowledge the exception 64 * 65 * D1Re0 -- The bits to acknowledge 66 * D1Ar3 -- The signal number 67 * D1RtP -- Scratch to deal with non-conditional insns 68 */ 69 MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT) 70 MOV D1RtP, #TXSTAT_FPE_INVALID_S 71 FFB D1Ar3, D1Ar3 72 CMP D1Ar3, #TXSTAT_FPE_INVALID_S 73 MOVLE D1Ar3, D1RtP /* Collapse FPE triggers to a single signal */ 74 MOV D1RtP, #1 75 LSLGT D1Re0, D1RtP, D1Ar3 76 77 /* Get the handler using the signal number 78 * 79 * D1Ar3 -- The signal number 80 * D0Re0 -- Offset into TBI struct containing handler address 81 * D1Re0 -- Mask of triggers to keep 82 * D1RtP -- Address of handler 83 */ 84 SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE) 85 LSL D0Re0, D1Ar3, #2 86 XOR D1Re0, D1Re0, #-1 /* Prepare mask for acknowledge (avoids stall) */ 87 ADD D0Re0,D0Re0,#TBI_fnSigs 88 GETD D1RtP, [D0Ar6+D0Re0] 89 90 /* Acknowledge triggers */ 91 AND D1.5, D1.5, D1Re0 92 93 /* Restore remaining exceptions 94 * Do this here in case the handler enables nested interrupts 95 * 96 * D1.5 -- TXDEFR with this exception ack'd 97 */ 98 MOV TXDEFR, D1.5 99 100 /* Call the handler */ 101 SWAP D1RtP, PC 102 103 GETL D0.5, D1.5, [--A0StP] 104 GETL D0FrT, D1RtP, [--A0StP] 105 MOV PC,D1RtP 106#else /* META_BUG_MBN100212 */ 107 108 /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved 109 * D0Ar4 -- The deferred exceptions 110 * D1Ar3 -- As per D0Ar4 but just the trigger bits 111 */ 112 113 /* - Collect the pending deferred exceptions using TXSTAT, 114 * (ack's the interrupt exceptions as a side-effect) 115 */ 116 DEFR D0Ar4, TXSTATI 117 118 /* Mask off anything unrelated to the deferred exception triggers */ 119 MOV D1Ar3, D0Ar4 120 ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS) 121 122 /* Can assume that at least one exception happened since this 123 * handler wouldnt have been called otherwise. 124 * 125 * Replace the signal number and at the same time, prepare 126 * the mask to acknowledge the exception 127 * 128 * The unusual code for 1<<D1Ar3 may need explanation. 129 * Normally this would be done using 'MOV rs,#1' and 'LSL rd,rs,D1Ar3' 130 * but only D1Re0 is available in D1 and no crossunit insns are available 131 * Even worse, there is no conditional 'MOV r,#uimm8'. 132 * Since the CMP proves that D1Ar3 >= 20, we can reuse the bottom 12-bits 133 * of D1Re0 (using 'ORGT r,#1') in the knowledge that the top 20-bits will 134 * be discarded without affecting the result. 135 * 136 * D1Re0 -- The bits to acknowledge 137 * D1Ar3 -- The signal number 138 */ 139 MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT) 140 MOV D0Re0, #TXSTAT_FPE_INVALID_S 141 FFB D1Ar3, D1Ar3 142 CMP D1Ar3, #TXSTAT_FPE_INVALID_S 143 MOVLE D1Ar3, D0Re0 /* Collapse FPE triggers to a single signal */ 144 ORGT D1Re0, D1Re0, #1 145 LSLGT D1Re0, D1Re0, D1Ar3 146 147 SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE) 148 149 /* Acknowledge triggers and restore remaining exceptions 150 * Do this here in case the handler enables nested interrupts 151 * 152 * (x | y) ^ y == x & ~y. It avoids the restrictive XOR ...,#-1 insn 153 * and is the same length 154 */ 155 MOV D0Re0, TXDEFR 156 OR D0Re0, D0Re0, D1Re0 157 XOR TXDEFR, D0Re0, D1Re0 158 159 /* Get the handler using the signal number 160 * 161 * D1Ar3 -- The signal number 162 * D0Re0 -- Address of handler 163 */ 164 LSL D0Re0, D1Ar3, #2 165 ADD D0Re0,D0Re0,#TBI_fnSigs 166 GETD D0Re0, [D0Ar6+D0Re0] 167 168 /* Tailcall the handler */ 169 MOV PC,D0Re0 170 171#endif /* META_BUG_MBN100212 */ 172 .size ___TBIHandleDFR,.-___TBIHandleDFR 173/* 174 * End of tbidefr.S 175 */ 176