1/* 2 * Copyright (c) 2019-2020 Cobham Gaisler AB 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/* 8 * This file contains standard handlers for the SPARC V8 window overflow and 9 * underflow traps. It also implements the handler for SPARC-ABI 10 * "Flush windows" which is used for example by longjmp() and C++ exceptions. 11 */ 12 13#include <toolchain.h> 14#include <linker/sections.h> 15#include <arch/sparc/sparc.h> 16 17GTEXT(__sparc_trap_window_overflow) 18GTEXT(__sparc_trap_window_underflow) 19GTEXT(__sparc_trap_flush_windows) 20 21SECTION_FUNC(TEXT, __sparc_trap_window_overflow) 22 /* Enter the window to be stored. */ 23 save 24 /* Save local register set. */ 25 std %l0, [%sp + 0x00] 26 std %l2, [%sp + 0x08] 27 std %l4, [%sp + 0x10] 28 rd %wim, %l3 29 std %l6, [%sp + 0x18] 30 /* l2 := WIM << (NWIN-1) */ 31 sll %l3, (CONFIG_SPARC_NWIN-1), %l2 32 /* Save input register set. */ 33 std %i0, [%sp + 0x20] 34 /* l3 := WIM >> 1 */ 35 srl %l3, 1, %l3 36 std %i2, [%sp + 0x28] 37 /* WIM := (WIM >> 1) ^ (WIM << (NWIN-1)) */ 38 wr %l3, %l2, %wim 39 /* NOTE: 3 instruction before restore (delayed write instruction) */ 40 std %i4, [%sp + 0x30] 41 nop 42 std %i6, [%sp + 0x38] 43 /* Go back to trap window. */ 44 restore 45 /* Re-execute save. */ 46 jmp %l1 47 rett %l2 48 49SECTION_FUNC(TEXT, __sparc_trap_window_underflow) 50 rd %wim, %l3 51 /* l4 := WIM << 1 */ 52 sll %l3, 1, %l4 53 /* l5 := WIM >> (NWIN-1) */ 54 srl %l3, (CONFIG_SPARC_NWIN-1), %l5 55 /* WIM := (WIM << 1) ^ (WIM >> (NWIN-1)) */ 56 wr %l4, %l5, %wim 57 /* WIM is implicitly read so nops are needed. */ 58 nop 59 nop 60 nop 61 62 /* Enter the window to restore requires two restore instructions. */ 63 restore 64 restore 65 ldd [%sp + 0x00], %l0 66 ldd [%sp + 0x08], %l2 67 ldd [%sp + 0x10], %l4 68 ldd [%sp + 0x18], %l6 69 ldd [%sp + 0x20], %i0 70 ldd [%sp + 0x28], %i2 71 ldd [%sp + 0x30], %i4 72 ldd [%sp + 0x38], %i6 73 /* Go back to the trap window. */ 74 save 75 save 76 /* Re-execute restore. */ 77 jmp %l1 78 rett %l2 79 80/* 81 * Handler for SPARC trap 0x83: trap_instruction, defined as "Flush windows" by 82 * SPARC-ABI: 83 * "By executing a type 3 trap, a process asks the system to flush all its 84 * register windows to the stack." 85 * 86 * This implementation uses the window overflow trap handler to perform the 87 * actual window flush. 88 * 89 * On entry: 90 * %l0: psr 91 * %l1: pc 92 * %l2: npc 93 */ 94SECTION_FUNC(TEXT, __sparc_trap_flush_windows) 95 /* push a few registers which are needed later to the stack */ 96 sub %sp, 0x10, %sp 97 std %l0, [%sp + 0x40 + 0x00] 98 st %l2, [%sp + 0x40 + 0x08] 99 st %g2, [%sp + 0x40 + 0x0c] 100 101 restore 102 /* In window where we trapped from. This window will not be flushed. */ 103 104 /* Set highest processor interrupt level and enable traps. */ 105 rd %psr, %g2 106 or %g2, PSR_PIL, %g2 107 wr %g2, PSR_ET, %psr 108 nop 109 nop 110 111 /* Execute "save" NWINDOWS-1 times. */ 112 set CONFIG_SPARC_NWIN-2, %g2 1131: 114 save 115 cmp %g2, %g0 116 bne 1b 117 sub %g2, 1, %g2 118 119 /* Execute "restore" NWINDOWS-1 times. */ 120 set CONFIG_SPARC_NWIN-2, %g2 1212: 122 restore 123 cmp %g2, %g0 124 bne 2b 125 sub %g2, 1, %g2 126 127 save 128 129 /* pop registers from stack which are used for the trap return */ 130 ldd [%sp + 0x40 + 0x00], %l0 131 ld [%sp + 0x40 + 0x08], %l2 132 ld [%sp + 0x40 + 0x0c], %g2 133 add %sp, 0x10, %sp 134 135 /* Restore %psr as it was on trap entry. */ 136 wr %l0, %psr 137 nop 138 nop 139 nop 140 141 jmp %l2 142 rett %l2 + 4 143