4 * Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
6 * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
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.
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.
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,
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
29 #define ASI_BP ASI_PHYS_BYPASS_EC_E
30 #define PROM_ADDR 0x1fff0000000
31 #define SER_ADDR 0x1fe020003f8
32 #define TICK_INT_DIS 0x8000000000000000
33 #define TICK_INTERVAL 1*1000*1000
35 .section ".text.vectors", "ax"
37 /* Sparc64 trap table */
38 .globl trap_table, __divide_error, softint_irq, softint_irq_tl1
39 .register %g2, #scratch
40 .register %g3, #scratch
41 .register %g6, #scratch
42 .register %g7, #scratch
44 #define SPILL_WINDOW \
48 stx %l0, [%sp + STACK_BIAS + 0x00]; \
49 stx %l1, [%sp + STACK_BIAS + 0x08]; \
50 stx %l2, [%sp + STACK_BIAS + 0x10]; \
51 stx %l3, [%sp + STACK_BIAS + 0x18]; \
52 stx %l4, [%sp + STACK_BIAS + 0x20]; \
53 stx %l5, [%sp + STACK_BIAS + 0x28]; \
54 stx %l6, [%sp + STACK_BIAS + 0x30]; \
55 stx %l7, [%sp + STACK_BIAS + 0x38]; \
56 stx %i0, [%sp + STACK_BIAS + 0x40]; \
57 stx %i1, [%sp + STACK_BIAS + 0x48]; \
58 stx %i2, [%sp + STACK_BIAS + 0x50]; \
59 stx %i3, [%sp + STACK_BIAS + 0x58]; \
60 stx %i4, [%sp + STACK_BIAS + 0x60]; \
61 stx %i5, [%sp + STACK_BIAS + 0x68]; \
62 stx %i6, [%sp + STACK_BIAS + 0x70]; \
63 stx %i7, [%sp + STACK_BIAS + 0x78]; \
64 saved; retry; nop; nop; nop; nop; nop; nop; \
65 nop; nop; nop; nop; nop;
71 ldx [%sp + STACK_BIAS + 0x00], %l0; \
72 ldx [%sp + STACK_BIAS + 0x08], %l1; \
73 ldx [%sp + STACK_BIAS + 0x10], %l2; \
74 ldx [%sp + STACK_BIAS + 0x18], %l3; \
75 ldx [%sp + STACK_BIAS + 0x20], %l4; \
76 ldx [%sp + STACK_BIAS + 0x28], %l5; \
77 ldx [%sp + STACK_BIAS + 0x30], %l6; \
78 ldx [%sp + STACK_BIAS + 0x38], %l7; \
79 ldx [%sp + STACK_BIAS + 0x40], %i0; \
80 ldx [%sp + STACK_BIAS + 0x48], %i1; \
81 ldx [%sp + STACK_BIAS + 0x50], %i2; \
82 ldx [%sp + STACK_BIAS + 0x58], %i3; \
83 ldx [%sp + STACK_BIAS + 0x60], %i4; \
84 ldx [%sp + STACK_BIAS + 0x68], %i5; \
85 ldx [%sp + STACK_BIAS + 0x70], %i6; \
86 ldx [%sp + STACK_BIAS + 0x78], %i7; \
87 restored; retry; nop; nop; nop; nop; nop; nop; \
88 nop; nop; nop; nop; nop;
90 #define CLEAN_WINDOW \
91 rdpr %cleanwin, %l0; add %l0, 1, %l0; \
92 wrpr %l0, 0x0, %cleanwin; \
93 clr %o0; clr %o1; clr %o2; clr %o3; \
94 clr %o4; clr %o5; clr %o6; clr %o7; \
95 clr %l0; clr %l1; clr %l2; clr %l3; \
96 clr %l4; clr %l5; clr %l6; clr %l7; \
98 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
100 #define TRAP_IRQ(routine, level) \
101 ba routine; mov level, %g1; nop; nop; nop; nop; nop; nop;
103 ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
104 #define BTRAPTL1(lvl) BTRAP(lvl)
105 #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)
106 #define BTRAPS4(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3)
107 #define TRAP_HANDLER(routine) ba routine; nop; nop; nop; nop; nop; nop; nop;
109 #define STACK_BIAS 2047
110 .globl sparc64_ttable_tl0, sparc64_ttable_tl1
112 ba entry; nop; nop; nop; nop; nop; nop; nop;! XXX remove
113 ba entry; nop; nop; nop; nop; nop; nop; nop;! Power-on reset
114 ba entry; nop; nop; nop; nop; nop; nop; nop;! Watchdog reset
115 ba entry; nop; nop; nop; nop; nop; nop; nop;! External reset
116 ba entry; nop; nop; nop; nop; nop; nop; nop;! Software reset
117 ba entry; nop; nop; nop; nop; nop; nop; nop;! RED state
118 BTRAP(0x06) BTRAP(0x07) BTRAPS(0x08)
119 BTRAPS(0x10) BTRAPS(0x18)
120 BTRAP(0x20) BTRAP(0x21) BTRAP(0x22) BTRAP(0x23)
123 BTRAPS(0x30) BTRAPS(0x38)
124 BTRAP(0x40) BTRAP(0x41) BTRAP(0x42) BTRAP(0x43)
125 tl0_irq4: TRAP_IRQ(handler_irq, 4)
126 tl0_irq5: TRAP_IRQ(handler_irq, 5) TRAP_IRQ(handler_irq, 6)
127 tl0_irq7: TRAP_IRQ(handler_irq, 7) TRAP_IRQ(handler_irq, 8)
128 tl0_irq9: TRAP_IRQ(handler_irq, 9) TRAP_IRQ(handler_irq, 10)
129 tl0_irq11: TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
130 tl0_irq13: TRAP_IRQ(handler_irq, 13)
131 tl0_irq14: TRAP_IRQ(softint_irq, 14)
132 tl0_irq15: TRAP_IRQ(handler_irq, 15)
133 BTRAPS(0x50) BTRAPS(0x58)
135 TRAP_HANDLER(reload_IMMU_tlb) ! 0x64 : instruction_access_MMU_miss
136 TRAP_HANDLER(reload_IMMU_tlb) ! 0x65 : instruction_access_MMU_miss
137 TRAP_HANDLER(reload_IMMU_tlb) ! 0x66 : instruction_access_MMU_miss
138 TRAP_HANDLER(reload_IMMU_tlb) ! 0x67 : instruction_access_MMU_miss
139 TRAP_HANDLER(reload_DMMU_tlb) ! 0x68 : data_access_MMU_miss
140 TRAP_HANDLER(reload_DMMU_tlb) ! 0x69 : data_access_MMU_miss
141 TRAP_HANDLER(reload_DMMU_tlb) ! 0x6A : data_access_MMU_miss
142 TRAP_HANDLER(reload_DMMU_tlb) ! 0x6B : data_access_MMU_miss
143 BTRAPS4(0x6C) ! data_access_protection
144 BTRAPS(0x70) BTRAPS(0x78)
145 tl0_s0n: SPILL_WINDOW
146 tl0_s1n: SPILL_WINDOW
147 tl0_s2n: SPILL_WINDOW
148 tl0_s3n: SPILL_WINDOW
149 tl0_s4n: SPILL_WINDOW
150 tl0_s5n: SPILL_WINDOW
151 tl0_s6n: SPILL_WINDOW
152 tl0_s7n: SPILL_WINDOW
153 tl0_s0o: SPILL_WINDOW
154 tl0_s1o: SPILL_WINDOW
155 tl0_s2o: SPILL_WINDOW
156 tl0_s3o: SPILL_WINDOW
157 tl0_s4o: SPILL_WINDOW
158 tl0_s5o: SPILL_WINDOW
159 tl0_s6o: SPILL_WINDOW
160 tl0_s7o: SPILL_WINDOW
177 tl0_resv100: BTRAPS(0x100) BTRAPS(0x108)
178 tl0_resv110: BTRAPS(0x110) BTRAPS(0x118)
179 tl0_resv120: BTRAPS(0x120) BTRAPS(0x128)
180 tl0_resv130: BTRAPS(0x130) BTRAPS(0x138)
181 tl0_resv140: BTRAPS(0x140) BTRAPS(0x148)
182 tl0_resv150: BTRAPS(0x150) BTRAPS(0x158)
183 tl0_resv160: BTRAPS(0x160) BTRAPS(0x168)
184 tl0_resv170: BTRAPS(0x170) BTRAPS(0x178)
185 tl0_resv180: BTRAPS(0x180) BTRAPS(0x188)
186 tl0_resv190: BTRAPS(0x190) BTRAPS(0x198)
187 tl0_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8)
188 tl0_resv1b0: BTRAPS(0x1b0) BTRAPS(0x1b8)
189 tl0_resv1c0: BTRAPS(0x1c0) BTRAPS(0x1c8)
190 tl0_resv1d0: BTRAPS(0x1d0) BTRAPS(0x1d8)
191 tl0_resv1e0: BTRAPS(0x1e0) BTRAPS(0x1e8)
192 tl0_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8)
195 #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 #define SKIP_IRQ(routine, level) \
198 retry; nop; nop; nop; nop; nop; nop; nop;
201 BTRAPS(0x00) BTRAPS(0x08)
202 BTRAPS(0x10) BTRAPS(0x18)
203 BTRAPTL1(0x20) BTRAPTL1(0x21) BTRAPTL1(0x22) BTRAPTL1(0x23)
206 BTRAPS(0x30) BTRAPS(0x38)
207 BTRAPTL1(0x40) BTRAPTL1(0x41) BTRAPTL1(0x42) BTRAPTL1(0x43)
208 tl1_irq4: TRAP_IRQ(handler_irq, 4)
209 tl1_irq5: TRAP_IRQ(handler_irq, 5) TRAP_IRQ(handler_irq, 6)
210 tl1_irq7: TRAP_IRQ(handler_irq, 7) TRAP_IRQ(handler_irq, 8)
211 tl1_irq9: TRAP_IRQ(handler_irq, 9) TRAP_IRQ(handler_irq, 10)
212 tl1_irq11: TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
213 tl1_irq13: TRAP_IRQ(handler_irq, 13)
214 tl1_irq14: SKIP_IRQ(softint_irq, 14)
215 tl1_irq15: TRAP_IRQ(handler_irq, 15)
216 BTRAPS(0x50) BTRAPS(0x58)
218 TRAP_HANDLER(reload_IMMU_tlb) ! 0x64 : instruction_access_MMU_miss
219 TRAP_HANDLER(reload_IMMU_tlb) ! 0x65 : instruction_access_MMU_miss
220 TRAP_HANDLER(reload_IMMU_tlb) ! 0x66 : instruction_access_MMU_miss
221 TRAP_HANDLER(reload_IMMU_tlb) ! 0x67 : instruction_access_MMU_miss
222 TRAP_HANDLER(reload_DMMU_tlb) ! 0x68 : data_access_MMU_miss
223 TRAP_HANDLER(reload_DMMU_tlb) ! 0x69 : data_access_MMU_miss
224 TRAP_HANDLER(reload_DMMU_tlb) ! 0x6A : data_access_MMU_miss
225 TRAP_HANDLER(reload_DMMU_tlb) ! 0x6B : data_access_MMU_miss
226 BTRAPS4(0x6C) ! data_access_protection
227 BTRAPS(0x70) BTRAPS(0x78)
228 tl1_s0n: SPILL_WINDOW
229 tl1_s1n: SPILL_WINDOW
230 tl1_s2n: SPILL_WINDOW
231 tl1_s3n: SPILL_WINDOW
232 tl1_s4n: SPILL_WINDOW
233 tl1_s5n: SPILL_WINDOW
234 tl1_s6n: SPILL_WINDOW
235 tl1_s7n: SPILL_WINDOW
236 tl1_s0o: SPILL_WINDOW
237 tl1_s1o: SPILL_WINDOW
238 tl1_s2o: SPILL_WINDOW
239 tl1_s3o: SPILL_WINDOW
240 tl1_s4o: SPILL_WINDOW
241 tl1_s5o: SPILL_WINDOW
242 tl1_s6o: SPILL_WINDOW
243 tl1_s7o: SPILL_WINDOW
260 tl1_resv100: BTRAPS(0x100) BTRAPS(0x108)
261 tl1_resv110: BTRAPS(0x110) BTRAPS(0x118)
262 tl1_resv120: BTRAPS(0x120) BTRAPS(0x128)
263 tl1_resv130: BTRAPS(0x130) BTRAPS(0x138)
264 tl1_resv140: BTRAPS(0x140) BTRAPS(0x148)
265 tl1_resv150: BTRAPS(0x150) BTRAPS(0x158)
266 tl1_resv160: BTRAPS(0x160) BTRAPS(0x168)
267 tl1_resv170: BTRAPS(0x170) BTRAPS(0x178)
268 tl1_resv180: BTRAPS(0x180) BTRAPS(0x188)
269 tl1_resv190: BTRAPS(0x190) BTRAPS(0x198)
270 tl1_resv1a0: BTRAPS(0x1a0) BTRAPS(0x1a8)
271 tl1_resv1b0: BTRAPS(0x1b0) BTRAPS(0x1b8)
272 tl1_resv1c0: BTRAPS(0x1c0) BTRAPS(0x1c8)
273 tl1_resv1d0: BTRAPS(0x1d0) BTRAPS(0x1d8)
274 tl1_resv1e0: BTRAPS(0x1e0) BTRAPS(0x1e8)
275 tl1_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8)
279 .globl tlb_handler_stack_top, tlb_handler_stack_pointer, obp_ticks_pointer
281 ! Stack for the tlb MMU trap handlers
282 tlb_handler_stack_bottom:
284 tlb_handler_stack_top:
287 ! MMU trap handler stack pointer
288 tlb_handler_stack_pointer:
289 .xword tlb_handler_stack_top
291 ! Pointer to current tick value
295 .section ".text", "ax"
299 stw %l0, [%sp + 0x00]
300 stw %l1, [%sp + 0x04]
301 stw %l2, [%sp + 0x08]
302 stw %l3, [%sp + 0x0c]
303 stw %l4, [%sp + 0x10]
304 stw %l5, [%sp + 0x14]
305 stw %l6, [%sp + 0x18]
306 stw %l7, [%sp + 0x1c]
307 stw %i0, [%sp + 0x20]
308 stw %i1, [%sp + 0x24]
309 stw %i2, [%sp + 0x28]
310 stw %i3, [%sp + 0x2c]
311 stw %i4, [%sp + 0x30]
312 stw %i5, [%sp + 0x34]
313 stw %i6, [%sp + 0x38]
314 stw %i7, [%sp + 0x3c]
320 lduw [%sp + 0x00], %l0
321 lduw [%sp + 0x04], %l1
322 lduw [%sp + 0x08], %l2
323 lduw [%sp + 0x0c], %l3
324 lduw [%sp + 0x10], %l4
325 lduw [%sp + 0x14], %l5
326 lduw [%sp + 0x18], %l6
327 lduw [%sp + 0x1c], %l7
328 lduw [%sp + 0x20], %i0
329 lduw [%sp + 0x24], %i1
330 lduw [%sp + 0x28], %i2
331 lduw [%sp + 0x2c], %i3
332 lduw [%sp + 0x30], %i4
333 lduw [%sp + 0x34], %i5
334 lduw [%sp + 0x38], %i6
335 lduw [%sp + 0x3c], %i7
340 * SAVE_CPU_STATE and RESTORE_CPU_STATE are macros used to enable a context switch
341 * to C to occur within the MMU I/D TLB miss handlers.
343 * Because these handlers are called on a TLB miss, we cannot use flushw to store
344 * processor window state on the stack, as the memory areas used by each window's
345 * stack pointer may not be in the TLB, causing recursive TLB miss traps.
347 * For this reason, we save window state by manually rotating the window registers
348 * and saving their contents (along with other vital registers) into a special
349 * tlb_handler_stack defined above which is guaranteed to be locked in the TLB, and
350 * so won't cause issues with trap recursion.
352 * Once this process is complete, we remain in a TL=0, CWP=0 state (with IE=1 to allow
353 * window fill/spill traps if required), switch to our safe tlb_handler_stack and
354 * invoke the miss handler.
357 #define SAVE_CPU_STATE(type) \
358 /* Set up our exception stack pointer in %g1 */ \
359 setx tlb_handler_stack_pointer, %g7, %g6; \
361 add %g1, -0x510, %g1; \
363 /* First save the various state registers */ \
366 rdpr %cansave, %g7; \
367 stx %g7, [%g1 + 0x8]; \
368 rdpr %canrestore, %g7; \
369 stx %g7, [%g1 + 0x10]; \
370 rdpr %otherwin, %g7; \
371 stx %g7, [%g1 + 0x18]; \
373 stx %g7, [%g1 + 0x20]; \
374 rdpr %cleanwin, %g7; \
375 stx %g7, [%g1 + 0x28]; \
377 stx %g7, [%g1 + 0x30]; \
380 stx %g7, [%g1 + 0x38]; \
382 stx %g7, [%g1 + 0x40]; \
385 stx %g7, [%g1 + 0x48]; \
388 add %g1, 0x50, %g5; \
391 save_trap_state_##type: \
397 stx %g7, [%g5 + 0x8]; \
399 stx %g7, [%g5 + 0x10]; \
401 stx %g7, [%g5 + 0x18]; \
402 bne save_trap_state_##type; \
403 add %g5, 0x20, %g5; \
405 /* For 4 trap levels with 4 registers, memory required is
406 4*8*4 = 0x80 bytes */ \
408 /* Save the o registers */ \
409 stx %o0, [%g1 + 0xd0]; \
410 stx %o1, [%g1 + 0xd8]; \
411 stx %o2, [%g1 + 0xe0]; \
412 stx %o3, [%g1 + 0xe8]; \
413 stx %o4, [%g1 + 0xf0]; \
414 stx %o5, [%g1 + 0xf8]; \
415 stx %o6, [%g1 + 0x100]; \
416 stx %o7, [%g1 + 0x108]; \
418 /* Now iterate through all of the windows saving all l and i registers */ \
419 add %g1, 0x110, %g5; \
421 /* Get the number of windows in %g6 */ \
426 save_cpu_window_##type: \
430 stx %l1, [%g5 + 0x8]; \
431 stx %l2, [%g5 + 0x10]; \
432 stx %l3, [%g5 + 0x18]; \
433 stx %l4, [%g5 + 0x20]; \
434 stx %l5, [%g5 + 0x28]; \
435 stx %l6, [%g5 + 0x30]; \
436 stx %l7, [%g5 + 0x38]; \
437 stx %i0, [%g5 + 0x40]; \
438 stx %i1, [%g5 + 0x48]; \
439 stx %i2, [%g5 + 0x50]; \
440 stx %i3, [%g5 + 0x58]; \
441 stx %i4, [%g5 + 0x60]; \
442 stx %i5, [%g5 + 0x68]; \
443 stx %i6, [%g5 + 0x70]; \
444 stx %i7, [%g5 + 0x78]; \
445 bne save_cpu_window_##type; \
446 add %g5, 0x80, %g5; \
448 /* For 8 windows with 16 registers to save in the window, memory required
449 is 16*8*8 = 0x400 bytes */ \
451 /* Now we should be in window 0 so update the other window registers */ \
455 wrpr %g6, %cansave; \
457 wrpr %g0, %cleanwin; \
458 wrpr %g0, %canrestore; \
459 wrpr %g0, %otherwin; \
461 /* Update our exception stack pointer */ \
462 setx tlb_handler_stack_pointer, %g7, %g6; \
466 #define RESTORE_CPU_STATE(type) \
467 /* Set up our exception stack pointer in %g1 */ \
468 setx tlb_handler_stack_pointer, %g7, %g6; \
471 /* Get the number of windows in %g6 */ \
476 /* Now iterate through all of the windows restoring all l and i registers */ \
477 add %g1, 0x110, %g5; \
479 restore_cpu_window_##type: \
483 ldx [%g5 + 0x8], %l1; \
484 ldx [%g5 + 0x10], %l2; \
485 ldx [%g5 + 0x18], %l3; \
486 ldx [%g5 + 0x20], %l4; \
487 ldx [%g5 + 0x28], %l5; \
488 ldx [%g5 + 0x30], %l6; \
489 ldx [%g5 + 0x38], %l7; \
490 ldx [%g5 + 0x40], %i0; \
491 ldx [%g5 + 0x48], %i1; \
492 ldx [%g5 + 0x50], %i2; \
493 ldx [%g5 + 0x58], %i3; \
494 ldx [%g5 + 0x60], %i4; \
495 ldx [%g5 + 0x68], %i5; \
496 ldx [%g5 + 0x70], %i6; \
497 ldx [%g5 + 0x78], %i7; \
498 bne restore_cpu_window_##type; \
499 add %g5, 0x80, %g5; \
501 /* Restore the window registers to their original value */ \
504 ldx [%g1 + 0x8], %g7; \
505 wrpr %g7, %cansave; \
506 ldx [%g1 + 0x10], %g7; \
507 wrpr %g7, %canrestore; \
508 ldx [%g1 + 0x18], %g7; \
509 wrpr %g7, %otherwin; \
510 ldx [%g1 + 0x20], %g7; \
512 ldx [%g1 + 0x28], %g7; \
513 wrpr %g7, %cleanwin; \
514 ldx [%g1 + 0x30], %g7; \
517 /* Restore the o registers */ \
518 ldx [%g1 + 0xd0], %o0; \
519 ldx [%g1 + 0xd8], %o1; \
520 ldx [%g1 + 0xe0], %o2; \
521 ldx [%g1 + 0xe8], %o3; \
522 ldx [%g1 + 0xf0], %o4; \
523 ldx [%g1 + 0xf8], %o5; \
524 ldx [%g1 + 0x100], %o6; \
525 ldx [%g1 + 0x108], %o7; \
527 /* Restore the trap state */ \
528 add %g1, 0x50, %g5; \
531 restore_trap_state_##type: \
536 ldx [%g5 + 0x8], %g7; \
538 ldx [%g5 + 0x10], %g7; \
540 ldx [%g5 + 0x18], %g7; \
542 bne restore_trap_state_##type; \
543 add %g5, 0x20, %g5; \
545 ldx [%g1 + 0x38], %g7; \
547 ldx [%g1 + 0x40], %g7; \
549 ldx [%g1 + 0x48], %g7; \
552 /* Restore exception stack pointer to previous value */ \
553 setx tlb_handler_stack_pointer, %g7, %g6; \
554 add %g1, 0x510, %g1; \
558 .globl reload_DMMU_tlb, reload_IMMU_tlb, bug
564 /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
565 gcc to save its arguments when building with -O0) */
566 add %g1, -STACK_BIAS - 192, %sp
568 /* Enable interrupts for window spill/fill traps */
570 or %g7, PSTATE_IE, %g7
573 call dtlb_miss_handler
576 /* Disable interrupts */
578 andn %g7, PSTATE_IE, %g7
581 RESTORE_CPU_STATE(dtlb)
589 /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
590 gcc to save its arguments when building with -O0) */
591 add %g1, -STACK_BIAS - 192, %sp
593 /* Enable interrupts for window spill/fill traps */
595 or %g7, PSTATE_IE, %g7
598 call itlb_miss_handler
601 /* Disable interrupts */
603 andn %g7, PSTATE_IE, %g7
606 RESTORE_CPU_STATE(itlb)
613 /* clear tick interrupt */
614 wr %g2, 0x0, %clear_softint
617 /* clear softint interrupt */
618 wr %g2, 0x0, %clear_softint
620 setx TICK_INT_DIS, %g2, %g1
623 brnz,pn %g1, tick_compare_disabled
626 /* update tick value if pointer set */
627 setx obp_ticks_pointer, %g3, %g1
633 add %g1, 10, %g1 ! 100Hz = 10ms
637 set TICK_INTERVAL, %g1
639 wr %g1, 0, %tick_cmpr
640 tick_compare_disabled:
646 /* Dump the exception and its context */
648 ! Don't change the global register set or we lose %g1 (exception level)
650 or %g2, PSTATE_PRIV, %g2
655 setx _start, %g2, %g3
656 setx highmem, %g2, %g4
658 setx PROM_ADDR, %g2, %g3
661 ! ... while disabling I/D MMUs and caches
662 stxa %g0, [%g0] ASI_LSU_CONTROL
665 ! Extract NWINDOWS from %ver
668 wrpr %g2, 0, %cleanwin
669 wrpr %g2, 0, %cansave
670 wrpr %g0, 0, %canrestore
671 wrpr %g0, 0, %otherwin
678 /* void outstr (unsigned long port, const unsigned char *str);
679 * Writes a string on an IO port.
685 stba %o3, [%o0] ASI_BP
692 /* void outdigit (unsigned long port, uint8_t digit);
693 * Dumps a single digit on serial port.
697 stba %o1, [%o0] ASI_BP
700 /* void outhex (unsigned long port, uint64_t value);
701 * Dumps a 64 bits hex number on serial port
712 2: add %o1, 'a' - 10, %o1
713 3: stba %o1, [%o0] ASI_BP
720 /* void dump_exception ();
722 * Dump a message when catching an exception
725 setx SER_ADDR, %o3, %o0
727 set (_BUG_message_0), %o1
729 setx PROM_ADDR, %g2, %g3
738 add %g3, (_BUG_message_1 - _BUG_message_0), %o1
744 add %g3, (_BUG_message_2 - _BUG_message_0), %o1
750 add %g3, (_BUG_message_3 - _BUG_message_0), %o1
759 .string "Unhandled Exception 0x"
765 .string "\nStopping execution\n"