Commit | Line | Data |
---|---|---|
027f891f JH |
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 | |
95281171 | 23 | * D1Ar5 -- Inst |
027f891f JH |
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 | */ |