These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / openbios / arch / sparc64 / vectors.S
1 /*
2  * <vectors.S>
3  *
4  * Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
5  *
6  *   Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
7  *
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License
10  *   version 2 as published by the Free Software Foundation.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20  *   MA  02110-1301, USA.
21  *   This program is free software; you can redistribute it and/or
22  *   modify it under the terms of the GNU General Public License V2
23  *   as published by the Free Software Foundation
24  */
25
26 #define __ASSEMBLY__
27 #include "cpustate.h"
28 #include "pstate.h"
29 #include <asm/asi.h>
30 #define ASI_BP ASI_PHYS_BYPASS_EC_E
31 #define PROM_ADDR 0x1fff0000000
32 #define SER_ADDR 0x1fe020003f8
33 #define TICK_INT_DIS 0x8000000000000000
34 #define TICK_INTERVAL 1*1000*1000
35
36         .section ".text.vectors", "ax"
37         .align 16384
38 /* Sparc64 trap table */
39         .globl trap_table, __divide_error, softint_irq, softint_irq_tl1
40         .register %g2, #scratch
41         .register %g3, #scratch
42         .register %g6, #scratch
43         .register %g7, #scratch
44 trap_table:
45 #define SPILL_WINDOW                                    \
46         btst    1, %sp;                                 \
47         be      spill_32bit;                            \
48          nop;                                           \
49         stx     %l0, [%sp + STACK_BIAS + 0x00];         \
50         stx     %l1, [%sp + STACK_BIAS + 0x08];         \
51         stx     %l2, [%sp + STACK_BIAS + 0x10];         \
52         stx     %l3, [%sp + STACK_BIAS + 0x18];         \
53         stx     %l4, [%sp + STACK_BIAS + 0x20];         \
54         stx     %l5, [%sp + STACK_BIAS + 0x28];         \
55         stx     %l6, [%sp + STACK_BIAS + 0x30];         \
56         stx     %l7, [%sp + STACK_BIAS + 0x38];         \
57         stx     %i0, [%sp + STACK_BIAS + 0x40];         \
58         stx     %i1, [%sp + STACK_BIAS + 0x48];         \
59         stx     %i2, [%sp + STACK_BIAS + 0x50];         \
60         stx     %i3, [%sp + STACK_BIAS + 0x58];         \
61         stx     %i4, [%sp + STACK_BIAS + 0x60];         \
62         stx     %i5, [%sp + STACK_BIAS + 0x68];         \
63         stx     %i6, [%sp + STACK_BIAS + 0x70];         \
64         stx     %i7, [%sp + STACK_BIAS + 0x78];         \
65         saved; retry; nop; nop; nop; nop; nop; nop;     \
66         nop; nop; nop; nop; nop;
67
68 #define FILL_WINDOW                                     \
69         btst    1, %sp;                                 \
70         be      fill_32bit;                             \
71          nop;                                           \
72         ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
73         ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
74         ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
75         ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
76         ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
77         ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
78         ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
79         ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
80         ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
81         ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
82         ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
83         ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
84         ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
85         ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
86         ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
87         ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
88         restored; retry; nop; nop; nop; nop; nop; nop;  \
89         nop; nop; nop; nop; nop;
90
91 #define CLEAN_WINDOW                                                    \
92         rdpr    %cleanwin, %l0;         add     %l0, 1, %l0;            \
93         wrpr    %l0, 0x0, %cleanwin;                                    \
94         clr     %o0;    clr     %o1;    clr     %o2;    clr     %o3;    \
95         clr     %o4;    clr     %o5;    clr     %o6;    clr     %o7;    \
96         clr     %l0;    clr     %l1;    clr     %l2;    clr     %l3;    \
97         clr     %l4;    clr     %l5;    clr     %l6;    clr     %l7;    \
98         retry;                                                          \
99         nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
100
101 #define TRAP_IRQ(routine, level)                        \
102                 ba routine;  mov level, %g1; nop; nop; nop; nop; nop; nop;
103 #define BTRAP(lvl)                                      \
104                  ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
105 #define BTRAPTL1(lvl) BTRAP(lvl)
106 #define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7)
107 #define BTRAPS4(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3)
108 #define TRAP_HANDLER(routine) ba routine; nop; nop; nop; nop; nop; nop; nop;
109
110 #define STACK_BIAS              2047
111         .globl  sparc64_ttable_tl0, sparc64_ttable_tl1
112 sparc64_ttable_tl0:
113                 ba entry; nop; nop; nop; nop; nop; nop; nop;! XXX remove
114                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Power-on reset
115                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Watchdog reset
116                 ba entry; nop; nop; nop; nop; nop; nop; nop;! External reset
117                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Software reset
118                 ba entry; nop; nop; nop; nop; nop; nop; nop;! RED state
119                 BTRAP(0x06) BTRAP(0x07) BTRAPS(0x08)
120                 BTRAPS(0x10) BTRAPS(0x18)
121                 BTRAP(0x20) BTRAP(0x21) BTRAP(0x22) BTRAP(0x23)
122                 CLEAN_WINDOW ! 24-27
123                 BTRAPS(0x28)
124                 BTRAPS(0x30) BTRAPS(0x38)
125                 BTRAP(0x40) BTRAP(0x41) BTRAP(0x42) BTRAP(0x43)
126 tl0_irq4:       TRAP_IRQ(handler_irq, 4)
127 tl0_irq5:       TRAP_IRQ(handler_irq, 5)  TRAP_IRQ(handler_irq, 6)
128 tl0_irq7:       TRAP_IRQ(handler_irq, 7)  TRAP_IRQ(handler_irq, 8)
129 tl0_irq9:       TRAP_IRQ(handler_irq, 9)  TRAP_IRQ(handler_irq, 10)
130 tl0_irq11:      TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
131 tl0_irq13:      TRAP_IRQ(handler_irq, 13)
132 tl0_irq14:      TRAP_IRQ(softint_irq, 14)
133 tl0_irq15:      TRAP_IRQ(handler_irq, 15)
134                 BTRAPS(0x50) BTRAPS(0x58)
135                 BTRAPS4(0x60)
136                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
137                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
138                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
139                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
140                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
141                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
142                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
143                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
144                 BTRAPS4(0x6C)    ! data_access_protection
145                 BTRAPS(0x70) BTRAPS(0x78)
146 tl0_s0n:        SPILL_WINDOW
147 tl0_s1n:        SPILL_WINDOW
148 tl0_s2n:        SPILL_WINDOW
149 tl0_s3n:        SPILL_WINDOW
150 tl0_s4n:        SPILL_WINDOW
151 tl0_s5n:        SPILL_WINDOW
152 tl0_s6n:        SPILL_WINDOW
153 tl0_s7n:        SPILL_WINDOW
154 tl0_s0o:        SPILL_WINDOW
155 tl0_s1o:        SPILL_WINDOW
156 tl0_s2o:        SPILL_WINDOW
157 tl0_s3o:        SPILL_WINDOW
158 tl0_s4o:        SPILL_WINDOW
159 tl0_s5o:        SPILL_WINDOW
160 tl0_s6o:        SPILL_WINDOW
161 tl0_s7o:        SPILL_WINDOW
162 tl0_f0n:        FILL_WINDOW
163 tl0_f1n:        FILL_WINDOW
164 tl0_f2n:        FILL_WINDOW
165 tl0_f3n:        FILL_WINDOW
166 tl0_f4n:        FILL_WINDOW
167 tl0_f5n:        FILL_WINDOW
168 tl0_f6n:        FILL_WINDOW
169 tl0_f7n:        FILL_WINDOW
170 tl0_f0o:        FILL_WINDOW
171 tl0_f1o:        FILL_WINDOW
172 tl0_f2o:        FILL_WINDOW
173 tl0_f3o:        FILL_WINDOW
174 tl0_f4o:        FILL_WINDOW
175 tl0_f5o:        FILL_WINDOW
176 tl0_f6o:        FILL_WINDOW
177 tl0_f7o:        FILL_WINDOW
178 tl0_resv100:    BTRAPS(0x100) BTRAPS(0x108)
179 tl0_resv110:    BTRAPS(0x110) BTRAPS(0x118)
180 tl0_resv120:    BTRAPS(0x120) BTRAPS(0x128)
181 tl0_resv130:    BTRAPS(0x130) BTRAPS(0x138)
182 tl0_resv140:    BTRAPS(0x140) BTRAPS(0x148)
183 tl0_resv150:    BTRAPS(0x150) BTRAPS(0x158)
184 tl0_resv160:    BTRAPS(0x160) BTRAPS(0x168)
185 tl0_resv170:    BTRAPS(0x170) BTRAPS(0x178)
186 tl0_resv180:    BTRAPS(0x180) BTRAPS(0x188)
187 tl0_resv190:    BTRAPS(0x190) BTRAPS(0x198)
188 tl0_resv1a0:    BTRAPS(0x1a0) BTRAPS(0x1a8)
189 tl0_resv1b0:    BTRAPS(0x1b0) BTRAPS(0x1b8)
190 tl0_resv1c0:    BTRAPS(0x1c0) BTRAPS(0x1c8)
191 tl0_resv1d0:    BTRAPS(0x1d0) BTRAPS(0x1d8)
192 tl0_resv1e0:    BTRAPS(0x1e0) BTRAPS(0x1e8)
193 tl0_resv1f0:    BTRAPS(0x1f0) BTRAPS(0x1f8)
194
195 #undef BTRAPS
196 #define BTRAPS(x) BTRAPTL1(x) BTRAPTL1(x+1) BTRAPTL1(x+2) BTRAPTL1(x+3) BTRAPTL1(x+4) BTRAPTL1(x+5) BTRAPTL1(x+6) BTRAPTL1(x+7)
197
198 #define SKIP_IRQ(routine, level) \
199                 retry;  nop; nop; nop; nop; nop; nop; nop;
200
201 sparc64_ttable_tl1:
202                 BTRAPS(0x00) BTRAPS(0x08)
203                 BTRAPS(0x10) BTRAPS(0x18)
204                 BTRAPTL1(0x20) BTRAPTL1(0x21) BTRAPTL1(0x22) BTRAPTL1(0x23)
205                 CLEAN_WINDOW ! 24-27
206                 BTRAPS(0x28)
207                 BTRAPS(0x30) BTRAPS(0x38)
208                 BTRAPTL1(0x40) BTRAPTL1(0x41) BTRAPTL1(0x42) BTRAPTL1(0x43)
209 tl1_irq4:       TRAP_IRQ(handler_irq, 4)
210 tl1_irq5:       TRAP_IRQ(handler_irq, 5)  TRAP_IRQ(handler_irq, 6)
211 tl1_irq7:       TRAP_IRQ(handler_irq, 7)  TRAP_IRQ(handler_irq, 8)
212 tl1_irq9:       TRAP_IRQ(handler_irq, 9)  TRAP_IRQ(handler_irq, 10)
213 tl1_irq11:      TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
214 tl1_irq13:      TRAP_IRQ(handler_irq, 13)
215 tl1_irq14:      SKIP_IRQ(softint_irq, 14)
216 tl1_irq15:      TRAP_IRQ(handler_irq, 15)
217                 BTRAPS(0x50) BTRAPS(0x58)
218                 BTRAPS4(0x60)
219                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
220                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
221                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
222                 TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
223                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
224                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
225                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
226                 TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
227                 BTRAPS4(0x6C)    ! data_access_protection
228                 BTRAPS(0x70) BTRAPS(0x78)
229 tl1_s0n:        SPILL_WINDOW
230 tl1_s1n:        SPILL_WINDOW
231 tl1_s2n:        SPILL_WINDOW
232 tl1_s3n:        SPILL_WINDOW
233 tl1_s4n:        SPILL_WINDOW
234 tl1_s5n:        SPILL_WINDOW
235 tl1_s6n:        SPILL_WINDOW
236 tl1_s7n:        SPILL_WINDOW
237 tl1_s0o:        SPILL_WINDOW
238 tl1_s1o:        SPILL_WINDOW
239 tl1_s2o:        SPILL_WINDOW
240 tl1_s3o:        SPILL_WINDOW
241 tl1_s4o:        SPILL_WINDOW
242 tl1_s5o:        SPILL_WINDOW
243 tl1_s6o:        SPILL_WINDOW
244 tl1_s7o:        SPILL_WINDOW
245 tl1_f0n:        FILL_WINDOW
246 tl1_f1n:        FILL_WINDOW
247 tl1_f2n:        FILL_WINDOW
248 tl1_f3n:        FILL_WINDOW
249 tl1_f4n:        FILL_WINDOW
250 tl1_f5n:        FILL_WINDOW
251 tl1_f6n:        FILL_WINDOW
252 tl1_f7n:        FILL_WINDOW
253 tl1_f0o:        FILL_WINDOW
254 tl1_f1o:        FILL_WINDOW
255 tl1_f2o:        FILL_WINDOW
256 tl1_f3o:        FILL_WINDOW
257 tl1_f4o:        FILL_WINDOW
258 tl1_f5o:        FILL_WINDOW
259 tl1_f6o:        FILL_WINDOW
260 tl1_f7o:        FILL_WINDOW
261 tl1_resv100:    BTRAPS(0x100) BTRAPS(0x108)
262 tl1_resv110:    BTRAPS(0x110) BTRAPS(0x118)
263 tl1_resv120:    BTRAPS(0x120) BTRAPS(0x128)
264 tl1_resv130:    BTRAPS(0x130) BTRAPS(0x138)
265 tl1_resv140:    BTRAPS(0x140) BTRAPS(0x148)
266 tl1_resv150:    BTRAPS(0x150) BTRAPS(0x158)
267 tl1_resv160:    BTRAPS(0x160) BTRAPS(0x168)
268 tl1_resv170:    BTRAPS(0x170) BTRAPS(0x178)
269 tl1_resv180:    BTRAPS(0x180) BTRAPS(0x188)
270 tl1_resv190:    BTRAPS(0x190) BTRAPS(0x198)
271 tl1_resv1a0:    BTRAPS(0x1a0) BTRAPS(0x1a8)
272 tl1_resv1b0:    BTRAPS(0x1b0) BTRAPS(0x1b8)
273 tl1_resv1c0:    BTRAPS(0x1c0) BTRAPS(0x1c8)
274 tl1_resv1d0:    BTRAPS(0x1d0) BTRAPS(0x1d8)
275 tl1_resv1e0:    BTRAPS(0x1e0) BTRAPS(0x1e8)
276 tl1_resv1f0:    BTRAPS(0x1f0) BTRAPS(0x1f8)
277
278         .section ".data"
279         .align 8
280         .globl obp_ticks_pointer
281
282
283         ! Pointer to current tick value
284 obp_ticks_pointer:
285         .xword 0
286
287         .section ".text", "ax"
288
289 spill_32bit:
290         srl     %sp, 0, %sp
291         stw     %l0, [%sp + 0x00]
292         stw     %l1, [%sp + 0x04]
293         stw     %l2, [%sp + 0x08]
294         stw     %l3, [%sp + 0x0c]
295         stw     %l4, [%sp + 0x10]
296         stw     %l5, [%sp + 0x14]
297         stw     %l6, [%sp + 0x18]
298         stw     %l7, [%sp + 0x1c]
299         stw     %i0, [%sp + 0x20]
300         stw     %i1, [%sp + 0x24]
301         stw     %i2, [%sp + 0x28]
302         stw     %i3, [%sp + 0x2c]
303         stw     %i4, [%sp + 0x30]
304         stw     %i5, [%sp + 0x34]
305         stw     %i6, [%sp + 0x38]
306         stw     %i7, [%sp + 0x3c]
307         saved
308         retry
309
310 fill_32bit:
311         srl     %sp, 0, %sp
312         lduw    [%sp + 0x00], %l0
313         lduw    [%sp + 0x04], %l1
314         lduw    [%sp + 0x08], %l2
315         lduw    [%sp + 0x0c], %l3
316         lduw    [%sp + 0x10], %l4
317         lduw    [%sp + 0x14], %l5
318         lduw    [%sp + 0x18], %l6
319         lduw    [%sp + 0x1c], %l7
320         lduw    [%sp + 0x20], %i0
321         lduw    [%sp + 0x24], %i1
322         lduw    [%sp + 0x28], %i2
323         lduw    [%sp + 0x2c], %i3
324         lduw    [%sp + 0x30], %i4
325         lduw    [%sp + 0x34], %i5
326         lduw    [%sp + 0x38], %i6
327         lduw    [%sp + 0x3c], %i7
328         restored
329         retry
330
331
332         .globl reload_DMMU_tlb, reload_IMMU_tlb, bug
333
334 reload_DMMU_tlb:
335         
336         /* Save CPU state to stack */
337         setx    _fcstack_ptr, %g6, %g7
338         ldx     [%g7], %g1
339         add     %g1, -CONTEXT_STATE_SIZE, %g1
340         stx     %g1, [%g7]
341         
342         SAVE_CPU_STATE(dtlb)
343
344         /* Switch to 8K TLB locked OpenBIOS stack (note we add an additional 192 bytes required for
345            gcc to save its arguments when building with -O0) */
346         setx    _fcstack_ptr, %g6, %g7
347         ldx     [%g7], %g6
348         setx    CONTEXT_STACK_SIZE, %g4, %g5
349         sub     %g6, %g5, %g6
350         stx     %g6, [%g7]
351         
352         setx    - 2047 - 192, %g6, %g7
353         add     %g1, %g7, %g7
354         mov     %g7, %sp
355
356         /* Enable interrupts for window spill/fill traps */
357         rdpr    %pstate, %g7
358         or      %g7, PSTATE_IE, %g7
359         wrpr    %g7, %pstate    
360
361         call    dtlb_miss_handler
362          nop
363
364         /* Disable interrupts */
365         rdpr    %pstate, %g7
366         andn    %g7, PSTATE_IE, %g7
367         wrpr    %g7, %pstate
368         
369         /* Restore CPU state from stack */
370         setx    _fcstack_ptr, %g6, %g7
371         ldx     [%g7], %g1
372         setx    CONTEXT_STACK_SIZE, %g4, %g5
373         add     %g1, %g5, %g1
374         stx     %g1, [%g7]
375         
376         RESTORE_CPU_STATE(dtlb)
377         
378         setx    _fcstack_ptr, %g6, %g7
379         ldx     [%g7], %g1
380         add     %g1, CONTEXT_STATE_SIZE, %g1
381         stx     %g1, [%g7]
382         
383         retry
384
385 reload_IMMU_tlb:
386         
387         /* Save CPU state to stack */
388         setx    _fcstack_ptr, %g6, %g7
389         ldx     [%g7], %g1
390         add     %g1, -CONTEXT_STATE_SIZE, %g1
391         stx     %g1, [%g7]
392         
393         SAVE_CPU_STATE(itlb)
394
395         /* Switch to 8K TLB locked OpenBIOS stack (note we add an additional 192 bytes required for
396            gcc to save its arguments when building with -O0) */
397         setx    _fcstack_ptr, %g6, %g7
398         ldx     [%g7], %g6
399         setx    CONTEXT_STACK_SIZE, %g4, %g5
400         sub     %g6, %g5, %g6
401         stx     %g6, [%g7]
402         
403         setx    - 2047 - 192, %g6, %g7
404         add     %g1, %g7, %g7
405         mov     %g7, %sp
406
407         /* Enable interrupts for window spill/fill traps */
408         rdpr    %pstate, %g7
409         or      %g7, PSTATE_IE, %g7
410         wrpr    %g7, %pstate    
411
412         call    itlb_miss_handler
413          nop
414
415         /* Disable interrupts */
416         rdpr    %pstate, %g7
417         andn    %g7, PSTATE_IE, %g7
418         wrpr    %g7, %pstate
419         
420         /* Restore CPU state from stack */
421         setx    _fcstack_ptr, %g6, %g7
422         ldx     [%g7], %g1
423         setx    CONTEXT_STACK_SIZE, %g4, %g5
424         add     %g1, %g5, %g1
425         stx     %g1, [%g7]
426         
427         RESTORE_CPU_STATE(itlb)
428         
429         setx    _fcstack_ptr, %g6, %g7
430         ldx     [%g7], %g1
431         add     %g1, CONTEXT_STATE_SIZE, %g1
432         stx     %g1, [%g7]
433
434         retry
435
436 softint_irq_tl1:
437 softint_irq:
438         mov     1, %g2
439         /* clear tick interrupt */
440         wr      %g2, 0x0, %clear_softint
441         sll     %g2, %g1, %g2
442         sra     %g2, 0, %g2
443         /* clear softint interrupt */
444         wr      %g2, 0x0, %clear_softint
445
446         setx    TICK_INT_DIS, %g2, %g1
447         rd      %tick, %g2
448         and     %g1, %g2, %g1
449         brnz,pn %g1, tick_compare_disabled
450          nop
451
452         /* update tick value if pointer set */
453         setx    obp_ticks_pointer, %g3, %g1
454         ldx     [%g1], %g3
455         brz     %g3, tick_rearm
456          nop
457
458         ldx     [%g3], %g1
459         add     %g1, 10, %g1    ! 100Hz = 10ms
460         stx     %g1, [%g3]
461          
462 tick_rearm:         
463         set     TICK_INTERVAL, %g1
464         add     %g1, %g2, %g1
465         wr      %g1, 0, %tick_cmpr
466 tick_compare_disabled:
467         retry
468
469 handler_irq:
470 __divide_error:
471 bug:
472         /* Dump the exception and its context */
473         ! Set up CPU state
474         ! Don't change the global register set or we lose %g1 (exception level)
475         rdpr    %pstate, %g2
476         or      %g2, PSTATE_PRIV, %g2
477         wrpr    %g2, %pstate
478         wr      %g0, 0, %fprs
479
480         ! Jump to ROM ...
481         setx    _start, %g2, %g3
482         setx    highmem, %g2, %g4
483         sub     %g4, %g3, %g4
484         setx    PROM_ADDR, %g2, %g3
485         add     %g4, %g3, %g3
486         jmp     %g3
487         ! ... while disabling I/D MMUs and caches
488          stxa    %g0, [%g0] ASI_LSU_CONTROL
489
490 highmem:
491         ! Extract NWINDOWS from %ver
492         rdpr    %ver, %g2
493         and     %g2, 0xf, %g2
494         wrpr    %g2, 0, %cleanwin
495         wrpr    %g2, 0, %cansave
496         wrpr    %g0, 0, %canrestore
497         wrpr    %g0, 0, %otherwin
498         wrpr    %g0, 0, %wstate
499
500         b       dump_exception
501          nop
502
503 outstr:
504         /* void outstr (unsigned long port, const unsigned char *str);
505          * Writes a string on an IO port.
506          */
507 1:      ldub    [%o1], %o3
508         cmp     %o3, 0
509         be      2f
510          nop
511         stba    %o3, [%o0] ASI_BP
512         b       1b
513          inc    %o1
514 2:      retl
515          nop
516
517 outdigit:
518         /* void outdigit (unsigned long port, uint8_t digit);
519          * Dumps a single digit on serial port.
520          */
521         add     %o1, '0', %o1
522         retl
523          stba   %o1, [%o0] ASI_BP
524
525 outhex:
526         /* void outhex (unsigned long port, uint64_t value);
527          * Dumps a 64 bits hex number on serial port
528          */
529         mov     %o1, %o2
530         set     60, %o3
531         srlx    %o2, %o3, %o1
532 1:      and     %o1, 0xf, %o1
533         cmp     %o1, 9
534         bgt     2f
535          nop
536         b       3f
537          add    %o1, '0', %o1
538 2:      add     %o1, 'a' - 10, %o1
539 3:      stba    %o1, [%o0] ASI_BP
540         subcc   %o3, 4, %o3
541         bge     1b
542          srlx   %o2, %o3, %o1
543         retl
544          nop
545
546         /* void dump_exception ();
547          *
548          * Dump a message when catching an exception
549          */
550 dump_exception:
551         setx    SER_ADDR, %o3, %o0
552         set     _start, %g3
553         set     (_BUG_message_0), %o1
554         sub     %o1, %g3, %g4
555         setx    PROM_ADDR, %g2, %g3
556         add     %g4, %g3, %g3
557         call    outstr
558          mov    %g3, %o1
559
560         call    outhex
561          mov    %g1, %o1
562
563         call    outstr
564          add    %g3, (_BUG_message_1 -  _BUG_message_0), %o1
565
566         call    outhex
567          rdpr   %tpc, %o1
568
569         call    outstr
570          add    %g3, (_BUG_message_2 -  _BUG_message_0), %o1
571
572         call    outhex
573          rdpr   %tnpc, %o1
574
575         call    outstr
576          add    %g3, (_BUG_message_3 -  _BUG_message_0), %o1
577
578 _forever:
579         /* Loop forever */
580         b       _forever                                  ;
581          nop
582
583         .section .rodata
584 _BUG_message_0:
585         .string "Unhandled Exception 0x"
586 _BUG_message_1:
587         .string "\nPC = 0x"
588 _BUG_message_2:
589         .string " NPC = 0x"
590 _BUG_message_3:
591         .string "\nStopping execution\n"