diff options
author | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
---|---|---|
committer | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
commit | 03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch) | |
tree | 7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/sparc/traps.S | |
parent | fae4c299f14fc23e2829c8656992eba21f79242a (diff) | |
download | cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2 cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip |
20000317 sourceware import
Diffstat (limited to 'libgloss/sparc/traps.S')
-rw-r--r-- | libgloss/sparc/traps.S | 651 |
1 files changed, 651 insertions, 0 deletions
diff --git a/libgloss/sparc/traps.S b/libgloss/sparc/traps.S new file mode 100644 index 000000000..b3cc96692 --- /dev/null +++ b/libgloss/sparc/traps.S @@ -0,0 +1,651 @@ +/* + * Copyright (c) 1995, 1996, 1998 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "asm.h" +#include "slite.h" + + .text + .align 4 + +/* + * The trap table has to be the first code in a boot PROM. But because + * the Memory Configuration comes up thinking we only have 4K of PROM, we + * cannot have a full trap table and still have room left over to + * reprogram the Memory Configuration register correctly. This file + * uses an abbreviated trap which has every entry which might be used + * before RTEMS installs its own trap table. + */ + .globl _trap_table +_trap_table: + TRAP(SYM(ercinit)); ! 00 reset trap + BAD_TRAP; ! 01 instruction access exception + TRAP(SYM(no_fpu)); ! 02 illegal instruction + BAD_TRAP; ! 03 privileged instruction + BAD_TRAP; ! 04 fp disabled + TRAP(SYM(win_overflow)); ! 05 window overflow + TRAP(SYM(win_underflow)); ! 06 window underflow + BAD_TRAP; ! 07 memory address not aligned + BAD_TRAP; ! 08 fp exception + BAD_TRAP; ! 09 data access exception + BAD_TRAP; ! 0A tag overflow + + /* Trap levels from 0B to 0x10 are not defined (used for MEC init) */ + +SYM(ercinit): + sethi %hi(_ERC32_MEC), %g1 ! 0B + sethi %hi(0x001C1000), %g2 + or %g1,%lo(0x001C1000),%g1 + st %g2, [%g1 + 0x10] + st %g0, [%g1 + 0x18] ! 0C + nop + nop + nop + + TRAP(SYM(hard_reset)); ! 0D undefined + BAD_TRAP; ! 0E undefined + BAD_TRAP; ! 0F undefined + BAD_TRAP; ! 10 undefined + + /* + * ERC32 defined traps + */ + + BAD_TRAP; ! 11 masked errors + BAD_TRAP; ! 12 external 1 + BAD_TRAP; ! 13 external 2 + BAD_TRAP; ! 14 UART A RX/TX + BAD_TRAP; ! 15 UART B RX/TX + BAD_TRAP; ! 16 correctable memory error + BAD_TRAP; ! 17 UART error + BAD_TRAP; ! 18 DMA access error + BAD_TRAP; ! 19 DMA timeout + BAD_TRAP; ! 1A external 3 + BAD_TRAP; ! 1B external 4 + BAD_TRAP; ! 1C general purpose timer + BAD_TRAP; ! 1D real time clock + BAD_TRAP; ! 1E external 5 + BAD_TRAP; ! 1F watchdog timeout + + + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined + BAD_TRAP; ! 24 cp_disabled + BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined + BAD_TRAP; ! 28 cp_exception + BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 2B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined + + /* + * Software traps + * + * NOTE: At the risk of being redundant... this is not a full + * table. The setjmp on the SPARC requires a window flush trap + * handler and RTEMS will preserve the entries that were + * installed before. + */ + + SOFT_TRAP; ! 80 +#if 0 + SOFT_TRAP; ! 81 +#else + TRAP(SYM(trap_low)) ! 81 +#endif + SOFT_TRAP; ! 82 + TRAP(SYM(win_flush)); ! 83 flush windows SW trap + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF + +/* + * Startup code for standalone system. Wash IU and FPU (if present) + * registers. The registers have to be written to initiate the parity + * bits. + */ + .globl SYM(hard_reset) +SYM(hard_reset): + + sethi %hi(0x01FE0),%o0 + or %o0,%lo(0x01FE0),%o0 + mov %o0, %psr ! Set valid PSR + nop + + mov %g0, %wim ! Set window invalid mask register + mov %g0, %y ! Init Y-register + nop + sethi %hi(SYM(hard_reset)), %g1 + + mov %g1, %tbr ! Set TBR + sethi %hi(SP_INIT),%sp + or %g0, 1, %o0 + ld [%g0], %f0 ! Check if FPU is present + + tst %o0 + bz fixiu + nop + ba fixfpu + +! FPU disabled trap address + + clr %i0 + jmpl %l2, %g0 + rett %l2 + 4 + nop + + +! Wash register files (fix for 90C601E & 90C602E) + +fixfpu: + + ld [%g0], %f0 + ld [%g0], %f1 + ld [%g0], %f2 + ld [%g0], %f3 + ld [%g0], %f4 + ld [%g0], %f5 + ld [%g0], %f6 + ld [%g0], %f7 + ld [%g0], %f8 + ld [%g0], %f9 + ld [%g0], %f10 + ld [%g0], %f11 + ld [%g0], %f12 + ld [%g0], %f13 + ld [%g0], %f14 + ld [%g0], %f15 + ld [%g0], %f16 + ld [%g0], %f17 + ld [%g0], %f18 + ld [%g0], %f19 + ld [%g0], %f20 + ld [%g0], %f21 + ld [%g0], %f22 + ld [%g0], %f23 + ld [%g0], %f24 + ld [%g0], %f25 + ld [%g0], %f26 + ld [%g0], %f27 + ld [%g0], %f28 + ld [%g0], %f29 + ld [%g0], %f30 + ld [%g0], %f31 + +fixiu: + clr %g1 + clr %g2 + clr %g3 + clr %g4 + clr %g5 + clr %g6 + clr %g7 + set 8,%g1 +wl0: + clr %i0 + clr %i1 + clr %i2 + clr %i3 + clr %i4 + clr %i5 + clr %i6 + clr %i7 + clr %l0 + clr %l1 + clr %l2 + clr %l3 + clr %l4 + clr %l5 + clr %l6 + clr %l7 + save + subcc %g1, 1, %g1 + bne wl0 + nop + +! +! Start the real-time clock with a tick of 150 clocks +! + +rtc: + + set 0x1f80000, %l0 ! MEC register base + set 149, %l1 + st %l1, [%l0 + 0x84] ! RTC scaler = 149 + set 0x0d00, %l1 + st %l1, [%l0 + 0x98] ! Start RTC + + st %g0, [%l0 + 0x64] ! Disable watchdog for now + ld [%l0], %g1 + or %g1, 1, %g1 + st %g1, [%l0] ! Enable power-down mode + +_init: + set PSR_INIT, %g1 ! Initialize psr + mov %g1, %psr + set WIM_INIT, %g1 ! Initialize WIM + mov %g1, %wim + set _trap_table, %g1 ! Initialize TBR + mov %g1, %tbr + nop;nop;nop + + set PSR_INIT, %g1 + wr %g1, 0x20, %psr ! enable traps + nop; nop; nop; + + call SYM(start) + nop + +/* + * Register window overflow handler. Come here when save would move us + * into the invalid window. This routine runs with traps disabled, and + * must be careful not to touch the condition codes, as PSR is never + * restored. + * + * We are called with %l0 = wim, %l1 = pc, %l2 = npc + */ + .globl SYM(win_overflow) +SYM(win_overflow): + mov %g1, %l3 ! Save g1, we use it to hold the wim + srl %l0, 1, %g1 ! Rotate wim right + sll %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0 + or %l0, %g1, %g1 + + save %g0, %g0, %g0 ! Slip into next window + mov %g1, %wim ! Install the new wim + nop + nop + nop + + std %l0, [%sp + 0 * 4] ! save L & I registers + std %l2, [%sp + 2 * 4] + std %l4, [%sp + 4 * 4] + std %l6, [%sp + 6 * 4] + + std %i0, [%sp + 8 * 4] + std %i2, [%sp + 10 * 4] + std %i4, [%sp + 12 * 4] + std %i6, [%sp + 14 * 4] + + restore ! Go back to trap window. + mov %l3, %g1 ! Restore %g1 + + jmpl %l1, %g0 + rett %l2 + +/* + * Register window underflow handler. Come here when restore would move us + * into the invalid window. This routine runs with traps disabled, and + * must be careful not to touch the condition codes, as PSR is never + * restored. + * + * We are called with %l0 = wim, %l1 = pc, %l2 = npc + */ + .globl SYM(win_underflow) +SYM(win_underflow): + sll %l0, 1, %l3 ! Rotate wim left + srl %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0 + or %l0, %l3, %l0 + + mov %l0, %wim ! Install the new wim + + restore ! Users window + restore ! His callers window + + ldd [%sp + 0 * 4], %l0 ! restore L & I registers + ldd [%sp + 2 * 4], %l2 + ldd [%sp + 4 * 4], %l4 + ldd [%sp + 6 * 4], %l6 + + ldd [%sp + 8 * 4], %i0 + ldd [%sp + 10 * 4], %i2 + ldd [%sp + 12 * 4], %i4 + ldd [%sp + 14 * 4], %i6 + + save %g0, %g0, %g0 ! Back to trap window + save %g0, %g0, %g0 + + jmpl %l1, %g0 + rett %l2 + +/* + * Register window flush handler, triggered by a "ta 3" instruction. + * We are called with %l0 = wim, %l1 = pc, %l2 = npc + */ + .globl SYM(win_flush) +SYM(win_flush): + mov %psr, %l0 + or %l0,0xf00,%l3 ! Disable interrupts + mov %l3,%psr + nop + nop + nop + mov %wim, %l3 + + srl %l3, %l0, %l4 ! wim >> cwp + cmp %l4, 1 + bne flush_window_fine ! Branch if not in the invalid window + nop + +/* Handle window overflow. We can't trap here. */ + + mov %g1, %l4 ! Save g1, we use it to hold the wim + srl %l3, 1, %g1 ! Rotate wim right + sll %l3, NUMBER_OF_REGISTER_WINDOWS - 1, %l3 + or %l3, %g1, %g1 + mov %g0, %wim ! Clear wim so that subsequent save + nop ! wont trap + nop + nop + save %g0, %g0, %g0 ! Slip into next window + mov %g1, %wim ! Install the new wim + + std %l0, [%sp + 0 * 4] ! save L & I registers + std %l2, [%sp + 2 * 4] + std %l4, [%sp + 4 * 4] + std %l6, [%sp + 6 * 4] + + std %i0, [%sp + 8 * 4] + std %i2, [%sp + 10 * 4] + std %i4, [%sp + 12 * 4] + std %i6, [%sp + 14 * 4] + + restore ! Go back to trap window. + mov %l4, %g1 ! Restore %g1 + +flush_window_fine: + mov %psr,%l5 ! enable traps + or %l5,0x20,%l5 + mov %l5, %psr + nop + nop + nop + + set save_buf,%l5 + st %l2,[%l5] + + ! The stack pointer currently contains a bogus value [when a trap + ! occurs CWP is decremented and points to an unused window]. + ! Give it something useful before we flush every window. + ! This does what a "save %sp,-64,$sp" would, except that CWP has + ! already been decremented. + add %fp, -64, %sp + + save %sp, -64, %sp ! Flush user register window to stack + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + restore + restore + restore + restore + restore + restore + restore + restore + + restore ! Make sure we have a valid window + save %g0, %g0, %g0 + + set save_buf, %l2 ! Get our return address back + ld [%l2],%l2 + + mov %psr,%l5 ! disable traps for rett + andn %l5,0x20,%l5 + mov %l5,%psr + nop + nop + nop + + jmpl %l2, %g0 + rett %l2+4 + +/* + * Read the TBR. + */ + .globl SYM(rdtbr) +SYM(rdtbr): + mov %tbr, %o0 + nop + retl + nop + +/* + * Read the psr + */ + .globl SYM(read_psr) +SYM(read_psr): + mov %psr, %o0 + nop + retl + nop + +/* + * Write the PSR. + */ + + .globl SYM(write_psr) +SYM(write_psr): + mov %i0, %psr + nop + nop + nop + retl + nop +/* + * Come here when no fpu exists. This just skips the offending + * instruction. + */ + .globl SYM(no_fpu) +SYM(no_fpu): + jmpl %l2, %g0 + rett %l2+4 + + .globl SYM(fltr_proto) + .align 4 +SYM(fltr_proto): ! First level trap routine prototype + sethi 0, %l0 + jmpl 0+%l0, %g0 + nop + nop + +/* + * Trap handler for memory errors. This just sets mem_err to be + * non-zero. It assumes that l1 is non-zero. This should be safe, + * as it is doubtful that 0 would ever contain code that could mem + * fault. This routine will skip past the faulting instruction after + * setting mem_err. + */ + .globl SYM(fltr_set_mem_err) +SYM(fltr_set_mem_err): + sethi %hi(SYM(mem_err)), %l0 + st %l1, [%l0 + %lo(SYM(mem_err))] + jmpl %l2, %g0 + rett %l2+4 + + .data + .align 4 + .ascii "DaTa" + .long SYM(sdata) +in_trap_handler: + .word 0 +save_buf: + .word 0 /* place to save %g1 */ + .word 0 /* place to save %g2 */ + + .text + .align 4 + +/* + * This function is called when any SPARC trap (except window overflow + * or underflow) occurs. It makes sure that the invalid register + * window is still available before jumping into C code. It will also + * restore the world if you return from handle_exception. + */ + .globl SYM(trap_low) +SYM(trap_low): + mov %psr, %l0 + mov %wim, %l3 + + srl %l3, %l0, %l4 ! wim >> cwp + cmp %l4, 1 + bne window_fine ! Branch if not in the invalid window + nop + + mov %g1, %l4 ! Save g1, we use it to hold the wim + srl %l3, 1, %g1 ! Rotate wim right + sll %l3, 8-1, %l5 + or %l5, %g1, %g1 + + save %g0, %g0, %g0 ! Slip into next window + mov %g1, %wim ! Install the new wim + + std %l0, [%sp + 0 * 4] ! save L & I registers + std %l2, [%sp + 2 * 4] + std %l4, [%sp + 4 * 4] + std %l6, [%sp + 6 * 4] + + std %i0, [%sp + 8 * 4] + std %i2, [%sp + 10 * 4] + std %i4, [%sp + 12 * 4] + std %i6, [%sp + 14 * 4] + + restore ! Go back to trap window. + mov %l4, %g1 ! Restore g1 + +window_fine: + sethi %hi(in_trap_handler), %l4 + ld [%lo(in_trap_handler) + %l4], %l5 + tst %l5 + bg recursive_trap + inc %l5 + + /* use the stack we set in the linker script */ + sethi %hi(__trap_stack), %l6 + or %l6,%lo(__trap_stack),%l6 + mov %l6, %sp ! set the stack pointer + +recursive_trap: + st %l5, [%lo(in_trap_handler) + %l4] + + sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals + ! + hidden arg + arg spill + ! + doubleword alignment + ! + registers[72] local var + + std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] + std %g2, [%sp + (24 + 2) * 4] + std %g4, [%sp + (24 + 4) * 4] + std %g6, [%sp + (24 + 6) * 4] + + std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] + std %i2, [%sp + (24 + 10) * 4] + std %i4, [%sp + (24 + 12) * 4] + std %i6, [%sp + (24 + 14) * 4] + ! F0->F31 not implemented + mov %y, %l4 + mov %tbr, %l5 + st %l4, [%sp + (24 + 64) * 4] ! Y + st %l0, [%sp + (24 + 65) * 4] ! PSR + st %l3, [%sp + (24 + 66) * 4] ! WIM + st %l5, [%sp + (24 + 67) * 4] ! TBR + st %l1, [%sp + (24 + 68) * 4] ! PC + st %l2, [%sp + (24 + 69) * 4] ! NPC + ! CPSR and FPSR not implemented + + or %l0, 0xf20, %l4 + mov %l4, %psr ! Turn on traps, disable interrupts + + call SYM(handle_exception) + add %sp, 24 * 4, %o0 ! Pass address of registers + +/* Reload all of the registers that aren't on the stack */ + + ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] + ldd [%sp + (24 + 2) * 4], %g2 + ldd [%sp + (24 + 4) * 4], %g4 + ldd [%sp + (24 + 6) * 4], %g6 + + ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] + ldd [%sp + (24 + 10) * 4], %i2 + ldd [%sp + (24 + 12) * 4], %i4 + ldd [%sp + (24 + 14) * 4], %i6 + + ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR + ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC + + restore ! Ensure that previous window is valid + save %g0, %g0, %g0 ! by causing a window_underflow trap + + mov %l0, %y + mov %l1, %psr ! Make sure that traps are disabled + ! for rett + + sethi %hi(in_trap_handler), %l4 + ld [%lo(in_trap_handler) + %l4], %l5 + dec %l5 + st %l5, [%lo(in_trap_handler) + %l4] + + jmpl %l2, %g0 ! Restore old PC + rett %l3 ! Restore old nPC + + |