Merge branch 'acpica'
[deliverable/linux.git] / arch / metag / tbx / tbidefr.S
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 */
This page took 0.035782 seconds and 5 git commands to generate.