1 /* $OpenBSD: locore.h,v 1.7 2022/12/08 02:11:27 guenther Exp $ */ 2 /* $NetBSD: locore.h,v 1.11 2006/01/23 22:32:50 uwe Exp $ */ 3 4 /*- 5 * Copyright (c) 2002 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #if defined(SH3) && defined(SH4) 31 #define MOV(x, r) mov.l .L_##x, r; mov.l @r, r 32 #define REG_SYMBOL(x) .L_##x: .long __sh_##x 33 #define FUNC_SYMBOL(x) .L_##x: .long __sh_##x 34 #elif defined(SH3) 35 #define MOV(x, r) mov.l .L_##x, r 36 #define REG_SYMBOL(x) .L_##x: .long SH3_##x 37 #define FUNC_SYMBOL(x) .L_##x: .long sh3_##x 38 #elif defined(SH4) 39 #define MOV(x, r) mov.l .L_##x, r 40 #define REG_SYMBOL(x) .L_##x: .long SH4_##x 41 #define FUNC_SYMBOL(x) .L_##x: .long sh4_##x 42 #endif /* SH3 && SH4 */ 43 44 /* 45 * BANK1 r7 contains kernel stack top address. 46 * BANK1 r6 contains current frame pointer. (per process) 47 */ 48 /* 49 * __EXCEPTION_ENTRY: 50 * + setup stack pointer 51 * + save all register to frame. (struct trapframe) 52 * + setup kernel stack. 53 * + change bank from 1 to 0 54 * + set BANK0 (r4, r5, r6) = (ssr, spc, ssp) 55 */ 56 #define __EXCEPTION_ENTRY ;\ 57 /* Check kernel/user mode. */ ;\ 58 mov #0x40, r3 ;\ 59 swap.b r3, r3 ;\ 60 stc ssr, r2 ;\ 61 swap.w r3, r3 /* r3 = 0x40000000 */ ;\ 62 mov r2, r0 /* r2 = r0 = SSR */ ;\ 63 and r3, r0 ;\ 64 tst r0, r0 /* if (SSR.MD == 0) T = 1 */ ;\ 65 mov r14, r1 ;\ 66 mov r6, r14 /* frame pointer */ ;\ 67 bf/s 1f /* T==0 ...Exception from kernel mode */;\ 68 mov r15, r0 ;\ 69 /* Exception from user mode */ ;\ 70 mov r7, r15 /* change to kernel stack */ ;\ 71 1: ;\ 72 /* Save registers */ ;\ 73 mov.l r1, @-r14 /* tf_r14 */ ;\ 74 mov.l r0, @-r14 /* tf_r15 */ ;\ 75 stc.l r0_bank,@-r14 /* tf_r0 */ ;\ 76 stc.l r1_bank,@-r14 /* tf_r1 */ ;\ 77 stc.l r2_bank,@-r14 /* tf_r2 */ ;\ 78 stc.l r3_bank,@-r14 /* tf_r3 */ ;\ 79 stc.l r4_bank,@-r14 /* tf_r4 */ ;\ 80 stc.l r5_bank,@-r14 /* tf_r5 */ ;\ 81 stc.l r6_bank,@-r14 /* tf_r6 */ ;\ 82 stc.l r7_bank,@-r14 /* tf_r7 */ ;\ 83 mov.l r8, @-r14 /* tf_r8 */ ;\ 84 mov.l r9, @-r14 /* tf_r9 */ ;\ 85 mov.l r10, @-r14 /* tf_r10 */ ;\ 86 mov.l r11, @-r14 /* tf_r11 */ ;\ 87 mov.l r12, @-r14 /* tf_r12 */ ;\ 88 mov.l r13, @-r14 /* tf_r13 */ ;\ 89 sts.l pr, @-r14 /* tf_pr */ ;\ 90 sts.l mach, @-r14 /* tf_mach*/ ;\ 91 sts.l macl, @-r14 /* tf_macl*/ ;\ 92 stc.l gbr, @-r14 /* tf_gbr */ ;\ 93 mov.l r2, @-r14 /* tf_ssr */ ;\ 94 stc.l spc, @-r14 /* tf_spc */ ;\ 95 add #-TF_SPC, r14 /* skip tf_ubc, tf_expevt */ ;\ 96 mov r14, r6 /* store frame pointer */ ;\ 97 /* Change register bank to 0 */ ;\ 98 shlr r3 /* r3 = 0x20000000 */ ;\ 99 stc sr, r1 /* r1 = SR */ ;\ 100 not r3, r3 ;\ 101 and r1, r3 ;\ 102 ldc r3, sr /* SR.RB = 0 */ ;\ 103 /* Set up argument. r4 = ssr, r5 = spc */ ;\ 104 stc r2_bank,r4 ;\ 105 stc spc, r5 106 107 /* 108 * __EXCEPTION_RETURN: 109 * + block exception 110 * + restore all register from stack. 111 * + rte. 112 */ 113 #define __EXCEPTION_RETURN ;\ 114 mov #0x10, r0 ;\ 115 swap.b r0, r0 ;\ 116 swap.w r0, r0 /* r0 = 0x10000000 */ ;\ 117 stc sr, r1 ;\ 118 or r0, r1 ;\ 119 ldc r1, sr /* SR.BL = 1 */ ;\ 120 stc r6_bank,r0 ;\ 121 mov r0, r14 ;\ 122 add #TF_SIZE, r0 ;\ 123 ldc r0, r6_bank /* roll up frame pointer */ ;\ 124 add #TF_SPC, r14 /* skip tf_expevt, tf_ubc */ ;\ 125 mov.l @r14+, r0 /* tf_spc */ ;\ 126 ldc r0, spc ;\ 127 mov.l @r14+, r0 /* tf_ssr */ ;\ 128 ldc r0, ssr ;\ 129 ldc.l @r14+, gbr /* tf_gbr */ ;\ 130 lds.l @r14+, macl /* tf_macl*/ ;\ 131 lds.l @r14+, mach /* tf_mach*/ ;\ 132 lds.l @r14+, pr /* tf_pr */ ;\ 133 mov.l @r14+, r13 /* tf_r13 */ ;\ 134 mov.l @r14+, r12 /* tf_r12 */ ;\ 135 mov.l @r14+, r11 /* tf_r11 */ ;\ 136 mov.l @r14+, r10 /* tf_r10 */ ;\ 137 mov.l @r14+, r9 /* tf_r9 */ ;\ 138 mov.l @r14+, r8 /* tf_r8 */ ;\ 139 mov.l @r14+, r7 /* tf_r7 */ ;\ 140 mov.l @r14+, r6 /* tf_r6 */ ;\ 141 mov.l @r14+, r5 /* tf_r5 */ ;\ 142 mov.l @r14+, r4 /* tf_r4 */ ;\ 143 mov.l @r14+, r3 /* tf_r3 */ ;\ 144 mov.l @r14+, r2 /* tf_r2 */ ;\ 145 mov.l @r14+, r1 /* tf_r1 */ ;\ 146 mov.l @r14+, r0 /* tf_r0 */ ;\ 147 mov.l @r14+ r15 /* tf_r15 */ ;\ 148 mov.l @r14+, r14 /* tf_r14 */ ;\ 149 rte ;\ 150 nop 151 152 153 /* 154 * Macros to disable and enable exceptions (including interrupts). 155 * This modifies SR.BL 156 */ 157 #define __0x10 #0x10 158 #define __0x78 #0x78 159 160 #define __EXCEPTION_BLOCK(Rn, Rm) ;\ 161 mov __0x10, Rn ;\ 162 swap.b Rn, Rn ;\ 163 swap.w Rn, Rn /* Rn = 0x10000000 */ ;\ 164 stc sr, Rm ;\ 165 or Rn, Rm ;\ 166 ldc Rm, sr /* block exceptions */ 167 168 #define __EXCEPTION_UNBLOCK(Rn, Rm) ;\ 169 mov __0x10, Rn ;\ 170 swap.b Rn, Rn ;\ 171 swap.w Rn, Rn /* Rn = 0x10000000 */ ;\ 172 not Rn, Rn ;\ 173 stc sr, Rm ;\ 174 and Rn, Rm ;\ 175 ldc Rm, sr /* unblock exceptions */ 176 177 /* 178 * Macros to disable and enable interrupts. 179 * This modifies SR.I[0-3] 180 */ 181 #define __INTR_MASK(Rn, Rm) ;\ 182 mov __0x78, Rn ;\ 183 shll Rn /* Rn = 0x000000f0 */ ;\ 184 stc sr, Rm ;\ 185 or Rn, Rm ;\ 186 ldc Rm, sr /* mask all interrupt */ 187 188 #define __INTR_UNMASK(Rn, Rm) ;\ 189 mov __0x78, Rn ;\ 190 shll Rn /* Rn = 0x000000f0 */ ;\ 191 not Rn, Rn ;\ 192 stc sr, Rm ;\ 193 and Rn, Rm ;\ 194 ldc Rm, sr /* unmask all interrupt */ 195 196 #ifndef _LOCORE 197 void sh3_switch_setup(struct proc *); 198 void sh4_switch_setup(struct proc *); 199 void sh3_switch_resume(struct proc *); 200 void sh4_switch_resume(struct proc *); 201 extern void (*__sh_switch_resume)(struct proc *); 202 #endif /* !_LOCORE */ 203