diff options
Diffstat (limited to 'libgloss/sparc/traps.S')
-rw-r--r-- | libgloss/sparc/traps.S | 651 |
1 files changed, 0 insertions, 651 deletions
diff --git a/libgloss/sparc/traps.S b/libgloss/sparc/traps.S deleted file mode 100644 index b3cc966..0000000 --- a/libgloss/sparc/traps.S +++ /dev/null @@ -1,651 +0,0 @@ -/* - * 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 - - |