| @@ -1,990 +1,990 @@ | | | @@ -1,990 +1,990 @@ |
1 | /* $NetBSD: locore.s,v 1.118 2014/07/31 14:41:19 isaki Exp $ */ | | 1 | /* $NetBSD: locore.s,v 1.119 2015/07/25 06:24:53 isaki Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988 University of Utah. | | 4 | * Copyright (c) 1988 University of Utah. |
5 | * Copyright (c) 1980, 1990, 1993 | | 5 | * Copyright (c) 1980, 1990, 1993 |
6 | * The Regents of the University of California. All rights reserved. | | 6 | * The Regents of the University of California. All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to Berkeley by | | 8 | * This code is derived from software contributed to Berkeley by |
9 | * the Systems Programming Group of the University of Utah Computer | | 9 | * the Systems Programming Group of the University of Utah Computer |
10 | * Science Department. | | 10 | * Science Department. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright | | 15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions and the following disclaimer. | | 16 | * notice, this list of conditions and the following disclaimer. |
17 | * 2. Redistributions in binary form must reproduce the above copyright | | 17 | * 2. Redistributions in binary form must reproduce the above copyright |
18 | * notice, this list of conditions and the following disclaimer in the | | 18 | * notice, this list of conditions and the following disclaimer in the |
19 | * documentation and/or other materials provided with the distribution. | | 19 | * documentation and/or other materials provided with the distribution. |
20 | * 3. Neither the name of the University nor the names of its contributors | | 20 | * 3. Neither the name of the University nor the names of its contributors |
21 | * may be used to endorse or promote products derived from this software | | 21 | * may be used to endorse or promote products derived from this software |
22 | * without specific prior written permission. | | 22 | * without specific prior written permission. |
23 | * | | 23 | * |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 | * SUCH DAMAGE. | | 34 | * SUCH DAMAGE. |
35 | * | | 35 | * |
36 | * from: Utah $Hdr: locore.s 1.66 92/12/22$ | | 36 | * from: Utah $Hdr: locore.s 1.66 92/12/22$ |
37 | * | | 37 | * |
38 | * @(#)locore.s 8.6 (Berkeley) 5/27/94 | | 38 | * @(#)locore.s 8.6 (Berkeley) 5/27/94 |
39 | */ | | 39 | */ |
40 | | | 40 | |
41 | #include "opt_compat_netbsd.h" | | 41 | #include "opt_compat_netbsd.h" |
42 | #include "opt_compat_svr4.h" | | 42 | #include "opt_compat_svr4.h" |
43 | #include "opt_compat_sunos.h" | | 43 | #include "opt_compat_sunos.h" |
44 | #include "opt_ddb.h" | | 44 | #include "opt_ddb.h" |
45 | #include "opt_fpsp.h" | | 45 | #include "opt_fpsp.h" |
46 | #include "opt_kgdb.h" | | 46 | #include "opt_kgdb.h" |
47 | #include "opt_lockdebug.h" | | 47 | #include "opt_lockdebug.h" |
48 | #include "opt_fpu_emulate.h" | | 48 | #include "opt_fpu_emulate.h" |
49 | #include "opt_m68k_arch.h" | | 49 | #include "opt_m68k_arch.h" |
50 | | | 50 | |
51 | #include "ite.h" | | 51 | #include "ite.h" |
52 | #include "fd.h" | | 52 | #include "fd.h" |
53 | #include "par.h" | | 53 | #include "par.h" |
54 | #include "assym.h" | | 54 | #include "assym.h" |
55 | #include "ksyms.h" | | 55 | #include "ksyms.h" |
56 | | | 56 | |
57 | #include <machine/asm.h> | | 57 | #include <machine/asm.h> |
58 | | | 58 | |
59 | /* | | 59 | /* |
60 | * This is for kvm_mkdb, and should be the address of the beginning | | 60 | * This is for kvm_mkdb, and should be the address of the beginning |
61 | * of the kernel text segment (not necessarily the same as kernbase). | | 61 | * of the kernel text segment (not necessarily the same as kernbase). |
62 | */ | | 62 | */ |
63 | .text | | 63 | .text |
64 | GLOBAL(kernel_text) | | 64 | GLOBAL(kernel_text) |
65 | | | 65 | |
66 | /* | | 66 | /* |
67 | * Temporary stack for a variety of purposes. | | 67 | * Temporary stack for a variety of purposes. |
68 | * Try and make this the first thing is the data segment so it | | 68 | * Try and make this the first thing is the data segment so it |
69 | * is page aligned. Note that if we overflow here, we run into | | 69 | * is page aligned. Note that if we overflow here, we run into |
70 | * our text segment. | | 70 | * our text segment. |
71 | */ | | 71 | */ |
72 | .data | | 72 | .data |
73 | .space PAGE_SIZE | | 73 | .space PAGE_SIZE |
74 | ASLOCAL(tmpstk) | | 74 | ASLOCAL(tmpstk) |
75 | | | 75 | |
76 | #include <x68k/x68k/vectors.s> | | 76 | #include <x68k/x68k/vectors.s> |
77 | | | 77 | |
78 | .text | | 78 | .text |
79 | /* | | 79 | /* |
80 | * This is where we wind up if the kernel jumps to location 0. | | 80 | * This is where we wind up if the kernel jumps to location 0. |
81 | * (i.e. a bogus PC) This is known to immediately follow the vector | | 81 | * (i.e. a bogus PC) This is known to immediately follow the vector |
82 | * table and is hence at 0x400 (see reset vector in vectors.s). | | 82 | * table and is hence at 0x400 (see reset vector in vectors.s). |
83 | */ | | 83 | */ |
84 | PANIC("kernel jump to zero") | | 84 | PANIC("kernel jump to zero") |
85 | /* NOTREACHED */ | | 85 | /* NOTREACHED */ |
86 | | | 86 | |
87 | /* | | 87 | /* |
88 | * Macro to relocate a symbol, used before MMU is enabled. | | 88 | * Macro to relocate a symbol, used before MMU is enabled. |
89 | */ | | 89 | */ |
90 | #define _RELOC(var, ar) \ | | 90 | #define _RELOC(var, ar) \ |
91 | lea var,ar; \ | | 91 | lea var,ar; \ |
92 | addl %a5,ar | | 92 | addl %a5,ar |
93 | | | 93 | |
94 | #define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) | | 94 | #define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) |
95 | #define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) | | 95 | #define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) |
96 | | | 96 | |
97 | /* | | 97 | /* |
98 | * Initialization | | 98 | * Initialization |
99 | * | | 99 | * |
100 | * A4 contains the address of the end of the symtab | | 100 | * A4 contains the address of the end of the symtab |
101 | * A5 contains physical load point from boot | | 101 | * A5 contains physical load point from boot |
102 | * VBR contains zero from ROM. Exceptions will continue to vector | | 102 | * VBR contains zero from ROM. Exceptions will continue to vector |
103 | * through ROM until MMU is turned on at which time they will vector | | 103 | * through ROM until MMU is turned on at which time they will vector |
104 | * through our table (vectors.s). | | 104 | * through our table (vectors.s). |
105 | */ | | 105 | */ |
106 | | | 106 | |
107 | BSS(lowram,4) | | 107 | BSS(lowram,4) |
108 | BSS(esym,4) | | 108 | BSS(esym,4) |
109 | | | 109 | |
110 | GLOBAL(_verspad) | | 110 | GLOBAL(_verspad) |
111 | .word 0 | | 111 | .word 0 |
112 | GLOBAL(boot_version) | | 112 | GLOBAL(boot_version) |
113 | .word X68K_BOOTIF_VERS | | 113 | .word X68K_BOOTIF_VERS |
114 | | | 114 | |
115 | ASENTRY_NOPROFILE(start) | | 115 | ASENTRY_NOPROFILE(start) |
116 | movw #PSL_HIGHIPL,%sr | no interrupts | | 116 | movw #PSL_HIGHIPL,%sr | no interrupts |
117 | | | 117 | |
118 | addql #4,%sp | | 118 | addql #4,%sp |
119 | movel %sp@+,%a5 | firstpa | | 119 | movel %sp@+,%a5 | firstpa |
120 | movel %sp@+,%d5 | fphysize -- last page | | 120 | movel %sp@+,%d5 | fphysize -- last page |
121 | movel %sp@,%a4 | esym | | 121 | movel %sp@,%a4 | esym |
122 | | | 122 | |
123 | RELOC(vectab,%a0) | set Vector Base Register temporaly | | 123 | RELOC(vectab,%a0) | set Vector Base Register temporaly |
124 | movc %a0,%vbr | | 124 | movc %a0,%vbr |
125 | | | 125 | |
126 | #if 0 /* XXX this should be done by the boot loader */ | | 126 | #if 0 /* XXX this should be done by the boot loader */ |
127 | RELOC(edata, %a0) | clear out BSS | | 127 | RELOC(edata, %a0) | clear out BSS |
128 | movl #_C_LABEL(end)-4,%d0 | (must be <= 256 kB) | | 128 | movl #_C_LABEL(end)-4,%d0 | (must be <= 256 kB) |
129 | subl #_C_LABEL(edata),%d0 | | 129 | subl #_C_LABEL(edata),%d0 |
130 | lsrl #2,%d0 | | 130 | lsrl #2,%d0 |
131 | 1: clrl %a0@+ | | 131 | 1: clrl %a0@+ |
132 | dbra %d0,1b | | 132 | dbra %d0,1b |
133 | #endif | | 133 | #endif |
134 | | | 134 | |
135 | ASRELOC(tmpstk, %a0) | | 135 | ASRELOC(tmpstk, %a0) |
136 | movl %a0,%sp | give ourselves a temporary stack | | 136 | movl %a0,%sp | give ourselves a temporary stack |
137 | RELOC(esym, %a0) | | 137 | RELOC(esym, %a0) |
138 | #if 1 | | 138 | #if 1 |
139 | movl %a4,%a0@ | store end of symbol table | | 139 | movl %a4,%a0@ | store end of symbol table |
140 | #else | | 140 | #else |
141 | clrl %a0@ | no symbol table, yet | | 141 | clrl %a0@ | no symbol table, yet |
142 | #endif | | 142 | #endif |
143 | RELOC(lowram, %a0) | | 143 | RELOC(lowram, %a0) |
144 | movl %a5,%a0@ | store start of physical memory | | 144 | movl %a5,%a0@ | store start of physical memory |
145 | | | 145 | |
146 | movl #CACHE_OFF,%d0 | | 146 | movl #CACHE_OFF,%d0 |
147 | movc %d0,%cacr | clear and disable on-chip cache(s) | | 147 | movc %d0,%cacr | clear and disable on-chip cache(s) |
148 | | | 148 | |
149 | /* determine our CPU/MMU combo - check for all regardless of kernel config */ | | 149 | /* determine our CPU/MMU combo - check for all regardless of kernel config */ |
150 | movl #DC_FREEZE,%d0 | data freeze bit | | 150 | movl #DC_FREEZE,%d0 | data freeze bit |
151 | movc %d0,%cacr | only exists on 68030 | | 151 | movc %d0,%cacr | only exists on 68030 |
152 | movc %cacr,%d0 | read it back | | 152 | movc %cacr,%d0 | read it back |
153 | tstl %d0 | zero? | | 153 | tstl %d0 | zero? |
154 | jeq Lnot68030 | yes, we have 68020/68040/68060 | | 154 | jeq Lnot68030 | yes, we have 68020/68040/68060 |
155 | jra Lstart1 | no, we have 68030 | | 155 | jra Lstart1 | no, we have 68030 |
156 | Lnot68030: | | 156 | Lnot68030: |
157 | bset #31,%d0 | data cache enable bit | | 157 | bset #31,%d0 | data cache enable bit |
158 | movc %d0,%cacr | only exists on 68040/68060 | | 158 | movc %d0,%cacr | only exists on 68040/68060 |
159 | movc %cacr,%d0 | read it back | | 159 | movc %cacr,%d0 | read it back |
160 | tstl %d0 | zero? | | 160 | tstl %d0 | zero? |
161 | jeq Lis68020 | yes, we have 68020 | | 161 | jeq Lis68020 | yes, we have 68020 |
162 | moveq #0,%d0 | now turn it back off | | 162 | moveq #0,%d0 | now turn it back off |
163 | movec %d0,%cacr | before we access any data | | 163 | movec %d0,%cacr | before we access any data |
164 | .word 0xf4d8 | cinva bc - invalidate caches XXX | | 164 | .word 0xf4d8 | cinva bc - invalidate caches XXX |
165 | bset #30,%d0 | data cache no allocate mode bit | | 165 | bset #30,%d0 | data cache no allocate mode bit |
166 | movc %d0,%cacr | only exists on 68060 | | 166 | movc %d0,%cacr | only exists on 68060 |
167 | movc %cacr,%d0 | read it back | | 167 | movc %cacr,%d0 | read it back |
168 | tstl %d0 | zero? | | 168 | tstl %d0 | zero? |
169 | jeq Lis68040 | yes, we have 68040 | | 169 | jeq Lis68040 | yes, we have 68040 |
170 | RELOC(mmutype, %a0) | no, we have 68060 | | 170 | RELOC(mmutype, %a0) | no, we have 68060 |
171 | movl #MMU_68040,%a0@ | with a 68040 compatible MMU | | 171 | movl #MMU_68040,%a0@ | with a 68040 compatible MMU |
172 | RELOC(cputype, %a0) | | 172 | RELOC(cputype, %a0) |
173 | movl #CPU_68060,%a0@ | and a 68060 CPU | | 173 | movl #CPU_68060,%a0@ | and a 68060 CPU |
174 | jra Lstart1 | | 174 | jra Lstart1 |
175 | Lis68040: | | 175 | Lis68040: |
176 | RELOC(mmutype, %a0) | | 176 | RELOC(mmutype, %a0) |
177 | movl #MMU_68040,%a0@ | with a 68040 MMU | | 177 | movl #MMU_68040,%a0@ | with a 68040 MMU |
178 | RELOC(cputype, %a0) | | 178 | RELOC(cputype, %a0) |
179 | movl #CPU_68040,%a0@ | and a 68040 CPU | | 179 | movl #CPU_68040,%a0@ | and a 68040 CPU |
180 | jra Lstart1 | | 180 | jra Lstart1 |
181 | Lis68020: | | 181 | Lis68020: |
182 | RELOC(mmutype, %a0) | | 182 | RELOC(mmutype, %a0) |
183 | movl #MMU_68851,%a0@ | we have PMMU | | 183 | movl #MMU_68851,%a0@ | we have PMMU |
184 | RELOC(cputype, %a0) | | 184 | RELOC(cputype, %a0) |
185 | movl #CPU_68020,%a0@ | and a 68020 CPU | | 185 | movl #CPU_68020,%a0@ | and a 68020 CPU |
186 | | | 186 | |
187 | Lstart1: | | 187 | Lstart1: |
188 | /* | | 188 | /* |
189 | * Now that we know what CPU we have, initialize the address error | | 189 | * Now that we know what CPU we have, initialize the address error |
190 | * and bus error handlers in the vector table: | | 190 | * and bus error handlers in the vector table: |
191 | * | | 191 | * |
192 | * vectab+8 bus error | | 192 | * vectab+8 bus error |
193 | * vectab+12 address error | | 193 | * vectab+12 address error |
194 | */ | | 194 | */ |
195 | RELOC(cputype,%a0) | | 195 | RELOC(cputype,%a0) |
196 | RELOC(vectab,%a2) | | 196 | RELOC(vectab,%a2) |
197 | #if defined(M68060) | | 197 | #if defined(M68060) |
198 | cmpl #CPU_68060,%a0@ | 68060? | | 198 | cmpl #CPU_68060,%a0@ | 68060? |
199 | jne 1f | | 199 | jne 1f |
200 | movl #_C_LABEL(buserr60),%a2@(8) | | 200 | movl #_C_LABEL(buserr60),%a2@(8) |
201 | movl #_C_LABEL(addrerr4060),%a2@(12) | | 201 | movl #_C_LABEL(addrerr4060),%a2@(12) |
202 | jra Lstart2 | | 202 | jra Lstart2 |
203 | 1: | | 203 | 1: |
204 | #endif | | 204 | #endif |
205 | #if defined(M68040) | | 205 | #if defined(M68040) |
206 | cmpl #CPU_68040,%a0@ | 68040? | | 206 | cmpl #CPU_68040,%a0@ | 68040? |
207 | jne 1f | | 207 | jne 1f |
208 | movl #_C_LABEL(buserr40),%a2@(8) | | 208 | movl #_C_LABEL(buserr40),%a2@(8) |
209 | movl #_C_LABEL(addrerr4060),%a2@(12) | | 209 | movl #_C_LABEL(addrerr4060),%a2@(12) |
210 | jra Lstart2 | | 210 | jra Lstart2 |
211 | 1: | | 211 | 1: |
212 | #endif | | 212 | #endif |
213 | movl #_C_LABEL(busaddrerr2030),%a2@(8) | | 213 | movl #_C_LABEL(busaddrerr2030),%a2@(8) |
214 | movl #_C_LABEL(busaddrerr2030),%a2@(12) | | 214 | movl #_C_LABEL(busaddrerr2030),%a2@(12) |
215 | | | 215 | |
216 | Lstart2: | | 216 | Lstart2: |
217 | /* initialize source/destination control registers for movs */ | | 217 | /* initialize source/destination control registers for movs */ |
218 | moveq #FC_USERD,%d0 | user space | | 218 | moveq #FC_USERD,%d0 | user space |
219 | movc %d0,%sfc | as source | | 219 | movc %d0,%sfc | as source |
220 | movc %d0,%dfc | and destination of transfers | | 220 | movc %d0,%dfc | and destination of transfers |
221 | /* initialize memory sizes (for pmap_bootstrap) */ | | 221 | /* initialize memory sizes (for pmap_bootstrap) */ |
222 | movl %d5,%d1 | last page | | 222 | movl %d5,%d1 | last page |
223 | moveq #PGSHIFT,%d2 | | 223 | moveq #PGSHIFT,%d2 |
224 | lsrl %d2,%d1 | convert to page (click) number | | 224 | lsrl %d2,%d1 | convert to page (click) number |
225 | RELOC(maxmem, %a0) | | 225 | RELOC(maxmem, %a0) |
226 | movl %d1,%a0@ | save as maxmem | | 226 | movl %d1,%a0@ | save as maxmem |
227 | movl %a5,%d0 | lowram value from ROM via boot | | 227 | movl %a5,%d0 | lowram value from ROM via boot |
228 | lsrl %d2,%d0 | convert to page number | | 228 | lsrl %d2,%d0 | convert to page number |
229 | subl %d0,%d1 | compute amount of RAM present | | 229 | subl %d0,%d1 | compute amount of RAM present |
230 | RELOC(physmem, %a0) | | 230 | RELOC(physmem, %a0) |
231 | movl %d1,%a0@ | and physmem | | 231 | movl %d1,%a0@ | and physmem |
232 | | | 232 | |
233 | /* configure kernel and lwp0 VA space so we can get going */ | | 233 | /* configure kernel and lwp0 VA space so we can get going */ |
234 | #if NKSYMS || defined(DDB) || defined(MODULAR) | | 234 | #if NKSYMS || defined(DDB) || defined(MODULAR) |
235 | RELOC(esym,%a0) | end of static kernel test/data/syms | | 235 | RELOC(esym,%a0) | end of static kernel test/data/syms |
236 | movl %a0@,%d5 | | 236 | movl %a0@,%d5 |
237 | jne Lstart3 | | 237 | jne Lstart3 |
238 | #endif | | 238 | #endif |
239 | movl #_C_LABEL(end),%d5 | end of static kernel text/data | | 239 | movl #_C_LABEL(end),%d5 | end of static kernel text/data |
240 | Lstart3: | | 240 | Lstart3: |
241 | RELOC(setmemrange,%a0) | call setmemrange() | | 241 | RELOC(setmemrange,%a0) | call setmemrange() |
242 | jbsr %a0@ | to probe all memory regions | | 242 | jbsr %a0@ | to probe all memory regions |
243 | addl #PAGE_SIZE-1,%d5 | | 243 | addl #PAGE_SIZE-1,%d5 |
244 | andl #PG_FRAME,%d5 | round to a page | | 244 | andl #PG_FRAME,%d5 | round to a page |
245 | movl %d5,%a4 | | 245 | movl %d5,%a4 |
246 | addl %a5,%a4 | convert to PA | | 246 | addl %a5,%a4 | convert to PA |
247 | pea %a5@ | firstpa | | 247 | pea %a5@ | firstpa |
248 | pea %a4@ | nextpa | | 248 | pea %a4@ | nextpa |
249 | RELOC(pmap_bootstrap,%a0) | | 249 | RELOC(pmap_bootstrap,%a0) |
250 | jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) | | 250 | jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) |
251 | addql #8,%sp | | 251 | addql #8,%sp |
252 | | | 252 | |
253 | /* | | 253 | /* |
254 | * Prepare to enable MMU. | | 254 | * Prepare to enable MMU. |
255 | * Since the kernel is mapped logical == physical, we just turn it on. | | 255 | * Since the kernel is mapped logical == physical, we just turn it on. |
256 | */ | | 256 | */ |
257 | RELOC(Sysseg_pa, %a0) | system segment table addr | | 257 | RELOC(Sysseg_pa, %a0) | system segment table addr |
258 | movl %a0@,%d1 | read value (a PA) | | 258 | movl %a0@,%d1 | read value (a PA) |
259 | RELOC(mmutype, %a0) | | 259 | RELOC(mmutype, %a0) |
260 | cmpl #MMU_68040,%a0@ | 68040? | | 260 | cmpl #MMU_68040,%a0@ | 68040? |
261 | jne Lmotommu1 | no, skip | | 261 | jne Lmotommu1 | no, skip |
262 | .long 0x4e7b1807 | movc %d1,%srp | | 262 | .long 0x4e7b1807 | movc %d1,%srp |
263 | jra Lstploaddone | | 263 | jra Lstploaddone |
264 | Lmotommu1: | | 264 | Lmotommu1: |
265 | RELOC(protorp, %a0) | | 265 | RELOC(protorp, %a0) |
266 | movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs | | 266 | movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs |
267 | movl %d1,%a0@(4) | + segtable address | | 267 | movl %d1,%a0@(4) | + segtable address |
268 | pmove %a0@,%srp | load the supervisor root pointer | | 268 | pmove %a0@,%srp | load the supervisor root pointer |
269 | movl #0x80000002,%a0@ | reinit upper half for CRP loads | | 269 | movl #0x80000002,%a0@ | reinit upper half for CRP loads |
270 | Lstploaddone: | | 270 | Lstploaddone: |
271 | RELOC(mmutype, %a0) | | 271 | RELOC(mmutype, %a0) |
272 | cmpl #MMU_68040,%a0@ | 68040? | | 272 | cmpl #MMU_68040,%a0@ | 68040? |
273 | jne Lmotommu2 | no, skip | | 273 | jne Lmotommu2 | no, skip |
274 | #include "opt_jupiter.h" | | 274 | #include "opt_jupiter.h" |
275 | #ifdef JUPITER | | 275 | #ifdef JUPITER |
276 | /* JUPITER-X: set system register "SUPER" bit */ | | 276 | /* JUPITER-X: set system register "SUPER" bit */ |
277 | movl #0x0200a240,%d0 | translate DRAM area transparently | | 277 | movl #0x0200a240,%d0 | translate DRAM area transparently |
278 | .long 0x4e7b0006 | movc d0,dtt0 | | 278 | .long 0x4e7b0006 | movc d0,dtt0 |
279 | lea 0x00c00000,%a0 | %a0: graphic VRAM | | 279 | lea 0x00c00000,%a0 | %a0: graphic VRAM |
280 | lea 0x02c00000,%a1 | %a1: graphic VRAM ( not JUPITER-X ) | | 280 | lea 0x02c00000,%a1 | %a1: graphic VRAM ( not JUPITER-X ) |
281 | | DRAM ( JUPITER-X ) | | 281 | | DRAM ( JUPITER-X ) |
282 | movw %a0@,%d0 | | 282 | movw %a0@,%d0 |
283 | movw %d0,%d1 | | 283 | movw %d0,%d1 |
284 | notw %d1 | | 284 | notw %d1 |
285 | movw %d1,%a1@ | | 285 | movw %d1,%a1@ |
286 | movw %d0,%a0@ | | 286 | movw %d0,%a0@ |
287 | cmpw %a1@,%d1 | JUPITER-X? | | 287 | cmpw %a1@,%d1 | JUPITER-X? |
288 | jne Ljupiterdone | no, skip | | 288 | jne Ljupiterdone | no, skip |
289 | movl #0x0100a240,%d0 | to access system register | | 289 | movl #0x0100a240,%d0 | to access system register |
290 | .long 0x4e7b0006 | movc %d0,%dtt0 | | 290 | .long 0x4e7b0006 | movc %d0,%dtt0 |
291 | movb #0x01,0x01800003 | set "SUPER" bit | | 291 | movb #0x01,0x01800003 | set "SUPER" bit |
292 | Ljupiterdone: | | 292 | Ljupiterdone: |
293 | #endif /* JUPITER */ | | 293 | #endif /* JUPITER */ |
294 | moveq #0,%d0 | ensure TT regs are disabled | | 294 | moveq #0,%d0 | ensure TT regs are disabled |
295 | .long 0x4e7b0004 | movc %d0,%itt0 | | 295 | .long 0x4e7b0004 | movc %d0,%itt0 |
296 | .long 0x4e7b0005 | movc %d0,%itt1 | | 296 | .long 0x4e7b0005 | movc %d0,%itt1 |
297 | .long 0x4e7b0006 | movc %d0,%dtt0 | | 297 | .long 0x4e7b0006 | movc %d0,%dtt0 |
298 | .long 0x4e7b0007 | movc %d0,%dtt1 | | 298 | .long 0x4e7b0007 | movc %d0,%dtt1 |
299 | .word 0xf4d8 | cinva bc | | 299 | .word 0xf4d8 | cinva bc |
300 | .word 0xf518 | pflusha | | 300 | .word 0xf518 | pflusha |
301 | #if PGSHIFT == 13 | | 301 | #if PGSHIFT == 13 |
302 | movl #0xc000,%d0 | | 302 | movl #0xc000,%d0 |
303 | #else | | 303 | #else |
304 | movl #0x8000,%d0 | | 304 | movl #0x8000,%d0 |
305 | #endif | | 305 | #endif |
306 | .long 0x4e7b0003 | movc %d0,%tc | | 306 | .long 0x4e7b0003 | movc %d0,%tc |
307 | #ifdef M68060 | | 307 | #ifdef M68060 |
308 | RELOC(cputype, %a0) | | 308 | RELOC(cputype, %a0) |
309 | cmpl #CPU_68060,%a0@ | 68060? | | 309 | cmpl #CPU_68060,%a0@ | 68060? |
310 | jne Lnot060cache | | 310 | jne Lnot060cache |
311 | movl #1,%d0 | | 311 | movl #1,%d0 |
312 | .long 0x4e7b0808 | movcl %d0,%pcr | | 312 | .long 0x4e7b0808 | movcl %d0,%pcr |
313 | movl #0xa0808000,%d0 | | 313 | movl #0xa0808000,%d0 |
314 | movc %d0,%cacr | enable store buffer, both caches | | 314 | movc %d0,%cacr | enable store buffer, both caches |
315 | jmp Lenab1 | | 315 | jmp Lenab1 |
316 | Lnot060cache: | | 316 | Lnot060cache: |
317 | #endif | | 317 | #endif |
318 | movl #CACHE40_ON,%d0 | | 318 | movl #CACHE40_ON,%d0 |
319 | movc %d0,%cacr | turn on both caches | | 319 | movc %d0,%cacr | turn on both caches |
320 | jmp Lenab1 | | 320 | jmp Lenab1 |
321 | Lmotommu2: | | 321 | Lmotommu2: |
322 | pflusha | | 322 | pflusha |
323 | #if PGSHIFT == 13 | | 323 | #if PGSHIFT == 13 |
324 | movl #0x82d08b00,%sp@- | value to load TC with | | 324 | movl #0x82d08b00,%sp@- | value to load TC with |
325 | #else | | 325 | #else |
326 | movl #0x82c0aa00,%sp@- | value to load TC with | | 326 | movl #0x82c0aa00,%sp@- | value to load TC with |
327 | #endif | | 327 | #endif |
328 | pmove %sp@,%tc | load it | | 328 | pmove %sp@,%tc | load it |
329 | | | 329 | |
330 | /* | | 330 | /* |
331 | * Should be running mapped from this point on | | 331 | * Should be running mapped from this point on |
332 | */ | | 332 | */ |
333 | Lenab1: | | 333 | Lenab1: |
334 | /* set vector base in virtual address */ | | 334 | /* set vector base in virtual address */ |
335 | movl #_C_LABEL(vectab),%d0 | set Vector Base Register | | 335 | movl #_C_LABEL(vectab),%d0 | set Vector Base Register |
336 | movc %d0,%vbr | | 336 | movc %d0,%vbr |
337 | lea _ASM_LABEL(tmpstk),%sp | temporary stack | | 337 | lea _ASM_LABEL(tmpstk),%sp | temporary stack |
338 | /* call final pmap setup */ | | 338 | /* call final pmap setup */ |
339 | jbsr _C_LABEL(pmap_bootstrap_finalize) | | 339 | jbsr _C_LABEL(pmap_bootstrap_finalize) |
340 | /* set kernel stack, user SP */ | | 340 | /* set kernel stack, user SP */ |
341 | movl _C_LABEL(lwp0uarea),%a1 | get lwp0 uarea | | 341 | movl _C_LABEL(lwp0uarea),%a1 | get lwp0 uarea |
342 | lea %a1@(USPACE-4),%sp | set kernel stack to end of area | | 342 | lea %a1@(USPACE-4),%sp | set kernel stack to end of area |
343 | movl #USRSTACK-4,%a2 | | 343 | movl #USRSTACK-4,%a2 |
344 | movl %a2,%usp | init user SP | | 344 | movl %a2,%usp | init user SP |
345 | | | 345 | |
346 | /* detect FPU type */ | | 346 | /* detect FPU type */ |
347 | jbsr _C_LABEL(fpu_probe) | | 347 | jbsr _C_LABEL(fpu_probe) |
348 | movl %d0,_C_LABEL(fputype) | | 348 | movl %d0,_C_LABEL(fputype) |
349 | tstl _C_LABEL(fputype) | Have an FPU? | | 349 | tstl _C_LABEL(fputype) | Have an FPU? |
350 | jeq Lenab2 | No, skip. | | 350 | jeq Lenab2 | No, skip. |
351 | clrl %a1@(PCB_FPCTX) | ensure null FP context | | 351 | clrl %a1@(PCB_FPCTX) | ensure null FP context |
352 | movl %a1,%sp@- | | 352 | movl %a1,%sp@- |
353 | jbsr _C_LABEL(m68881_restore) | restore it (does not kill %a1) | | 353 | jbsr _C_LABEL(m68881_restore) | restore it (does not kill %a1) |
354 | addql #4,%sp | | 354 | addql #4,%sp |
355 | Lenab2: | | 355 | Lenab2: |
356 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? | | 356 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? |
357 | jeq Ltbia040 | yes, cache already on | | 357 | jeq Ltbia040 | yes, cache already on |
358 | pflusha | | 358 | pflusha |
359 | tstl _C_LABEL(mmutype) | | 359 | tstl _C_LABEL(mmutype) |
360 | jpl Lenab3 | 68851 implies no d-cache | | 360 | jpl Lenab3 | 68851 implies no d-cache |
361 | movl #CACHE_ON,%d0 | | 361 | movl #CACHE_ON,%d0 |
362 | movc %d0,%cacr | clear cache(s) | | 362 | movc %d0,%cacr | clear cache(s) |
363 | jra Lenab3 | | 363 | jra Lenab3 |
364 | Ltbia040: | | 364 | Ltbia040: |
365 | .word 0xf518 | | 365 | .word 0xf518 | pflusha |
366 | Lenab3: | | 366 | Lenab3: |
367 | /* final setup for C code */ | | 367 | /* final setup for C code */ |
368 | movl %d7,_C_LABEL(boothowto) | save reboot flags | | 368 | movl %d7,_C_LABEL(boothowto) | save reboot flags |
369 | movl %d6,_C_LABEL(bootdev) | and boot device | | 369 | movl %d6,_C_LABEL(bootdev) | and boot device |
370 | jbsr _C_LABEL(x68k_init) | additional pre-main initialization | | 370 | jbsr _C_LABEL(x68k_init) | additional pre-main initialization |
371 | | | 371 | |
372 | /* | | 372 | /* |
373 | * Create a fake exception frame so that cpu_lwp_fork() can copy it. | | 373 | * Create a fake exception frame so that cpu_lwp_fork() can copy it. |
374 | * main() nevers returns; we exit to user mode from a forked process | | 374 | * main() nevers returns; we exit to user mode from a forked process |
375 | * later on. | | 375 | * later on. |
376 | */ | | 376 | */ |
377 | clrw %sp@- | vector offset/frame type | | 377 | clrw %sp@- | vector offset/frame type |
378 | clrl %sp@- | PC - filled in by "execve" | | 378 | clrl %sp@- | PC - filled in by "execve" |
379 | movw #PSL_USER,%sp@- | in user mode | | 379 | movw #PSL_USER,%sp@- | in user mode |
380 | clrl %sp@- | stack adjust count and padding | | 380 | clrl %sp@- | stack adjust count and padding |
381 | lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 | | 381 | lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 |
382 | lea _C_LABEL(lwp0),%a0 | save pointer to frame | | 382 | lea _C_LABEL(lwp0),%a0 | save pointer to frame |
383 | movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs | | 383 | movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs |
384 | | | 384 | |
385 | jra _C_LABEL(main) | main() | | 385 | jra _C_LABEL(main) | main() |
386 | | | 386 | |
387 | PANIC("main() returned") | Yow! Main returned! | | 387 | PANIC("main() returned") | Yow! Main returned! |
388 | /* NOTREACHED */ | | 388 | /* NOTREACHED */ |
389 | | | 389 | |
390 | /* | | 390 | /* |
391 | * Trap/interrupt vector routines | | 391 | * Trap/interrupt vector routines |
392 | */ | | 392 | */ |
393 | #include <m68k/m68k/trap_subr.s> | | 393 | #include <m68k/m68k/trap_subr.s> |
394 | | | 394 | |
395 | /* | | 395 | /* |
396 | * Use common m68k bus error and address error handlers. | | 396 | * Use common m68k bus error and address error handlers. |
397 | */ | | 397 | */ |
398 | #include <m68k/m68k/busaddrerr.s> | | 398 | #include <m68k/m68k/busaddrerr.s> |
399 | | | 399 | |
400 | /* | | 400 | /* |
401 | * FP exceptions. | | 401 | * FP exceptions. |
402 | */ | | 402 | */ |
403 | ENTRY_NOPROFILE(fpfline) | | 403 | ENTRY_NOPROFILE(fpfline) |
404 | #if defined(M68040) | | 404 | #if defined(M68040) |
405 | cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? | | 405 | cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? |
406 | jne Lfp_unimp | no, skip FPSP | | 406 | jne Lfp_unimp | no, skip FPSP |
407 | cmpw #0x202c,%sp@(6) | format type 2? | | 407 | cmpw #0x202c,%sp@(6) | format type 2? |
408 | jne _C_LABEL(illinst) | no, not an FP emulation | | 408 | jne _C_LABEL(illinst) | no, not an FP emulation |
409 | #ifdef FPSP | | 409 | #ifdef FPSP |
410 | jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it | | 410 | jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it |
411 | #else | | 411 | #else |
412 | clrl %sp@- | stack adjust count | | 412 | clrl %sp@- | stack adjust count |
413 | moveml #0xFFFF,%sp@- | save registers | | 413 | moveml #0xFFFF,%sp@- | save registers |
414 | moveq #T_FPEMULI,%d0 | denote as FP emulation trap | | 414 | moveq #T_FPEMULI,%d0 | denote as FP emulation trap |
415 | jra _ASM_LABEL(fault) | do it | | 415 | jra _ASM_LABEL(fault) | do it |
416 | #endif | | 416 | #endif |
417 | Lfp_unimp: | | 417 | Lfp_unimp: |
418 | #endif /* M68040 */ | | 418 | #endif /* M68040 */ |
419 | #ifdef FPU_EMULATE | | 419 | #ifdef FPU_EMULATE |
420 | clrl %sp@- | stack adjust count | | 420 | clrl %sp@- | stack adjust count |
421 | moveml #0xFFFF,%sp@- | save registers | | 421 | moveml #0xFFFF,%sp@- | save registers |
422 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap | | 422 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap |
423 | jra _ASM_LABEL(fault) | do it | | 423 | jra _ASM_LABEL(fault) | do it |
424 | #else | | 424 | #else |
425 | jra _C_LABEL(illinst) | | 425 | jra _C_LABEL(illinst) |
426 | #endif | | 426 | #endif |
427 | | | 427 | |
428 | ENTRY_NOPROFILE(fpunsupp) | | 428 | ENTRY_NOPROFILE(fpunsupp) |
429 | #if defined(M68040) | | 429 | #if defined(M68040) |
430 | cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? | | 430 | cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? |
431 | jne Lfp_unsupp | no, skip FPSP | | 431 | jne Lfp_unsupp | no, skip FPSP |
432 | #ifdef FPSP | | 432 | #ifdef FPSP |
433 | jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it | | 433 | jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it |
434 | #else | | 434 | #else |
435 | clrl %sp@- | stack adjust count | | 435 | clrl %sp@- | stack adjust count |
436 | moveml #0xFFFF,%sp@- | save registers | | 436 | moveml #0xFFFF,%sp@- | save registers |
437 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap | | 437 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap |
438 | jra _ASM_LABEL(fault) | do it | | 438 | jra _ASM_LABEL(fault) | do it |
439 | #endif /* M68040 */ | | 439 | #endif /* M68040 */ |
440 | Lfp_unsupp: | | 440 | Lfp_unsupp: |
441 | #endif | | 441 | #endif |
442 | #ifdef FPU_EMULATE | | 442 | #ifdef FPU_EMULATE |
443 | clrl %sp@- | stack adjust count | | 443 | clrl %sp@- | stack adjust count |
444 | moveml #0xFFFF,%sp@- | save registers | | 444 | moveml #0xFFFF,%sp@- | save registers |
445 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap | | 445 | moveq #T_FPEMULD,%d0 | denote as FP emulation trap |
446 | jra _ASM_LABEL(fault) | do it | | 446 | jra _ASM_LABEL(fault) | do it |
447 | #else | | 447 | #else |
448 | jra _C_LABEL(illinst) | | 448 | jra _C_LABEL(illinst) |
449 | #endif | | 449 | #endif |
450 | | | 450 | |
451 | /* | | 451 | /* |
452 | * Handles all other FP coprocessor exceptions. | | 452 | * Handles all other FP coprocessor exceptions. |
453 | * Note that since some FP exceptions generate mid-instruction frames | | 453 | * Note that since some FP exceptions generate mid-instruction frames |
454 | * and may cause signal delivery, we need to test for stack adjustment | | 454 | * and may cause signal delivery, we need to test for stack adjustment |
455 | * after the trap call. | | 455 | * after the trap call. |
456 | */ | | 456 | */ |
457 | ENTRY_NOPROFILE(fpfault) | | 457 | ENTRY_NOPROFILE(fpfault) |
458 | clrl %sp@- | stack adjust count | | 458 | clrl %sp@- | stack adjust count |
459 | moveml #0xFFFF,%sp@- | save user registers | | 459 | moveml #0xFFFF,%sp@- | save user registers |
460 | movl %usp,%a0 | and save | | 460 | movl %usp,%a0 | and save |
461 | movl %a0,%sp@(FR_SP) | the user stack pointer | | 461 | movl %a0,%sp@(FR_SP) | the user stack pointer |
462 | clrl %sp@- | no VA arg | | 462 | clrl %sp@- | no VA arg |
463 | movl _C_LABEL(curpcb),%a0 | current pcb | | 463 | movl _C_LABEL(curpcb),%a0 | current pcb |
464 | lea %a0@(PCB_FPCTX),%a0 | address of FP savearea | | 464 | lea %a0@(PCB_FPCTX),%a0 | address of FP savearea |
465 | fsave %a0@ | save state | | 465 | fsave %a0@ | save state |
466 | #if defined(M68040) || defined(M68060) | | 466 | #if defined(M68040) || defined(M68060) |
467 | /* always null state frame on 68040, 68060 */ | | 467 | /* always null state frame on 68040, 68060 */ |
468 | cmpl #FPU_68040,_C_LABEL(fputype) | | 468 | cmpl #FPU_68040,_C_LABEL(fputype) |
469 | jge Lfptnull | | 469 | jge Lfptnull |
470 | #endif | | 470 | #endif |
471 | tstb %a0@ | null state frame? | | 471 | tstb %a0@ | null state frame? |
472 | jeq Lfptnull | yes, safe | | 472 | jeq Lfptnull | yes, safe |
473 | clrw %d0 | no, need to tweak BIU | | 473 | clrw %d0 | no, need to tweak BIU |
474 | movb %a0@(1),%d0 | get frame size | | 474 | movb %a0@(1),%d0 | get frame size |
475 | bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU | | 475 | bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU |
476 | Lfptnull: | | 476 | Lfptnull: |
477 | fmovem %fpsr,%sp@- | push fpsr as code argument | | 477 | fmovem %fpsr,%sp@- | push fpsr as code argument |
478 | frestore %a0@ | restore state | | 478 | frestore %a0@ | restore state |
479 | movl #T_FPERR,%sp@- | push type arg | | 479 | movl #T_FPERR,%sp@- | push type arg |
480 | jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup | | 480 | jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup |
481 | | | 481 | |
482 | /* | | 482 | /* |
483 | * Other exceptions only cause four and six word stack frame and require | | 483 | * Other exceptions only cause four and six word stack frame and require |
484 | * no post-trap stack adjustment. | | 484 | * no post-trap stack adjustment. |
485 | */ | | 485 | */ |
486 | | | 486 | |
487 | ENTRY_NOPROFILE(badtrap) | | 487 | ENTRY_NOPROFILE(badtrap) |
488 | moveml #0xC0C0,%sp@- | save scratch regs | | 488 | moveml #0xC0C0,%sp@- | save scratch regs |
489 | movw %sp@(22),%sp@- | push exception vector info | | 489 | movw %sp@(22),%sp@- | push exception vector info |
490 | clrw %sp@- | | 490 | clrw %sp@- |
491 | movl %sp@(22),%sp@- | and PC | | 491 | movl %sp@(22),%sp@- | and PC |
492 | jbsr _C_LABEL(straytrap) | report | | 492 | jbsr _C_LABEL(straytrap) | report |
493 | addql #8,%sp | pop args | | 493 | addql #8,%sp | pop args |
494 | moveml %sp@+,#0x0303 | restore regs | | 494 | moveml %sp@+,#0x0303 | restore regs |
495 | jra _ASM_LABEL(rei) | all done | | 495 | jra _ASM_LABEL(rei) | all done |
496 | | | 496 | |
497 | ENTRY_NOPROFILE(trap0) | | 497 | ENTRY_NOPROFILE(trap0) |
498 | clrl %sp@- | stack adjust count | | 498 | clrl %sp@- | stack adjust count |
499 | moveml #0xFFFF,%sp@- | save user registers | | 499 | moveml #0xFFFF,%sp@- | save user registers |
500 | movl %usp,%a0 | save the user SP | | 500 | movl %usp,%a0 | save the user SP |
501 | movl %a0,%sp@(FR_SP) | in the savearea | | 501 | movl %a0,%sp@(FR_SP) | in the savearea |
502 | movl %d0,%sp@- | push syscall number | | 502 | movl %d0,%sp@- | push syscall number |
503 | jbsr _C_LABEL(syscall) | handle it | | 503 | jbsr _C_LABEL(syscall) | handle it |
504 | addql #4,%sp | pop syscall arg | | 504 | addql #4,%sp | pop syscall arg |
505 | tstl _C_LABEL(astpending) | AST pending? | | 505 | tstl _C_LABEL(astpending) | AST pending? |
506 | jne Lrei | yes, handle it via trap | | 506 | jne Lrei | yes, handle it via trap |
507 | movl %sp@(FR_SP),%a0 | grab and restore | | 507 | movl %sp@(FR_SP),%a0 | grab and restore |
508 | movl %a0,%usp | user SP | | 508 | movl %a0,%usp | user SP |
509 | moveml %sp@+,#0x7FFF | restore most registers | | 509 | moveml %sp@+,#0x7FFF | restore most registers |
510 | addql #8,%sp | pop SP and stack adjust | | 510 | addql #8,%sp | pop SP and stack adjust |
511 | rte | | 511 | rte |
512 | | | 512 | |
513 | /* | | 513 | /* |
514 | * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) | | 514 | * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) |
515 | * cachectl(command, addr, length) | | 515 | * cachectl(command, addr, length) |
516 | * command in %d0, addr in %a1, length in %d1 | | 516 | * command in %d0, addr in %a1, length in %d1 |
517 | */ | | 517 | */ |
518 | ENTRY_NOPROFILE(trap12) | | 518 | ENTRY_NOPROFILE(trap12) |
519 | movl _C_LABEL(curlwp),%a0 | | 519 | movl _C_LABEL(curlwp),%a0 |
520 | movl %a0@(L_PROC),%sp@- | push current proc pointer | | 520 | movl %a0@(L_PROC),%sp@- | push current proc pointer |
521 | movl %d1,%sp@- | push length | | 521 | movl %d1,%sp@- | push length |
522 | movl %a1,%sp@- | push addr | | 522 | movl %a1,%sp@- | push addr |
523 | movl %d0,%sp@- | push command | | 523 | movl %d0,%sp@- | push command |
524 | jbsr _C_LABEL(cachectl1) | do it | | 524 | jbsr _C_LABEL(cachectl1) | do it |
525 | lea %sp@(16),%sp | pop args | | 525 | lea %sp@(16),%sp | pop args |
526 | jra _ASM_LABEL(rei) | all done | | 526 | jra _ASM_LABEL(rei) | all done |
527 | | | 527 | |
528 | /* | | 528 | /* |
529 | * Trace (single-step) trap. Kernel-mode is special. | | 529 | * Trace (single-step) trap. Kernel-mode is special. |
530 | * User mode traps are simply passed on to trap(). | | 530 | * User mode traps are simply passed on to trap(). |
531 | */ | | 531 | */ |
532 | ENTRY_NOPROFILE(trace) | | 532 | ENTRY_NOPROFILE(trace) |
533 | clrl %sp@- | stack adjust count | | 533 | clrl %sp@- | stack adjust count |
534 | moveml #0xFFFF,%sp@- | | 534 | moveml #0xFFFF,%sp@- |
535 | moveq #T_TRACE,%d0 | | 535 | moveq #T_TRACE,%d0 |
536 | | | 536 | |
537 | | Check PSW and see what happen. | | 537 | | Check PSW and see what happen. |
538 | | T=0 S=0 (should not happen) | | 538 | | T=0 S=0 (should not happen) |
539 | | T=1 S=0 trace trap from user mode | | 539 | | T=1 S=0 trace trap from user mode |
540 | | T=0 S=1 trace trap on a trap instruction | | 540 | | T=0 S=1 trace trap on a trap instruction |
541 | | T=1 S=1 trace trap from system mode (kernel breakpoint) | | 541 | | T=1 S=1 trace trap from system mode (kernel breakpoint) |
542 | | | 542 | |
543 | movw %sp@(FR_HW),%d1 | get PSW | | 543 | movw %sp@(FR_HW),%d1 | get PSW |
544 | notw %d1 | XXX no support for T0 on 680[234]0 | | 544 | notw %d1 | XXX no support for T0 on 680[234]0 |
545 | andw #PSL_TS,%d1 | from system mode (T=1, S=1)? | | 545 | andw #PSL_TS,%d1 | from system mode (T=1, S=1)? |
546 | jeq Lkbrkpt | yes, kernel breakpoint | | 546 | jeq Lkbrkpt | yes, kernel breakpoint |
547 | jra _ASM_LABEL(fault) | no, user-mode fault | | 547 | jra _ASM_LABEL(fault) | no, user-mode fault |
548 | | | 548 | |
549 | /* | | 549 | /* |
550 | * Trap 15 is used for: | | 550 | * Trap 15 is used for: |
551 | * - GDB breakpoints (in user programs) | | 551 | * - GDB breakpoints (in user programs) |
552 | * - KGDB breakpoints (in the kernel) | | 552 | * - KGDB breakpoints (in the kernel) |
553 | * - trace traps for SUN binaries (not fully supported yet) | | 553 | * - trace traps for SUN binaries (not fully supported yet) |
554 | * User mode traps are simply passed to trap(). | | 554 | * User mode traps are simply passed to trap(). |
555 | */ | | 555 | */ |
556 | ENTRY_NOPROFILE(trap15) | | 556 | ENTRY_NOPROFILE(trap15) |
557 | clrl %sp@- | stack adjust count | | 557 | clrl %sp@- | stack adjust count |
558 | moveml #0xFFFF,%sp@- | | 558 | moveml #0xFFFF,%sp@- |
559 | moveq #T_TRAP15,%d0 | | 559 | moveq #T_TRAP15,%d0 |
560 | movw %sp@(FR_HW),%d1 | get PSW | | 560 | movw %sp@(FR_HW),%d1 | get PSW |
561 | andw #PSL_S,%d1 | from system mode? | | 561 | andw #PSL_S,%d1 | from system mode? |
562 | jne Lkbrkpt | yes, kernel breakpoint | | 562 | jne Lkbrkpt | yes, kernel breakpoint |
563 | jra _ASM_LABEL(fault) | no, user-mode fault | | 563 | jra _ASM_LABEL(fault) | no, user-mode fault |
564 | | | 564 | |
565 | Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type) | | 565 | Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type) |
566 | | Save the system sp rather than the user sp. | | 566 | | Save the system sp rather than the user sp. |
567 | movw #PSL_HIGHIPL,%sr | lock out interrupts | | 567 | movw #PSL_HIGHIPL,%sr | lock out interrupts |
568 | lea %sp@(FR_SIZE),%a6 | Save stack pointer | | 568 | lea %sp@(FR_SIZE),%a6 | Save stack pointer |
569 | movl %a6,%sp@(FR_SP) | from before trap | | 569 | movl %a6,%sp@(FR_SP) | from before trap |
570 | | | 570 | |
571 | | If were are not on tmpstk switch to it. | | 571 | | If were are not on tmpstk switch to it. |
572 | | (so debugger can change the stack pointer) | | 572 | | (so debugger can change the stack pointer) |
573 | movl %a6,%d1 | | 573 | movl %a6,%d1 |
574 | cmpl #_ASM_LABEL(tmpstk),%d1 | | 574 | cmpl #_ASM_LABEL(tmpstk),%d1 |
575 | jls Lbrkpt2 | already on tmpstk | | 575 | jls Lbrkpt2 | already on tmpstk |
576 | | Copy frame to the temporary stack | | 576 | | Copy frame to the temporary stack |
577 | movl %sp,%a0 | %a0=src | | 577 | movl %sp,%a0 | %a0=src |
578 | lea _ASM_LABEL(tmpstk)-96,%a1 | %a1=dst | | 578 | lea _ASM_LABEL(tmpstk)-96,%a1 | %a1=dst |
579 | movl %a1,%sp | %sp=new frame | | 579 | movl %a1,%sp | %sp=new frame |
580 | moveq #FR_SIZE,%d1 | | 580 | moveq #FR_SIZE,%d1 |
581 | Lbrkpt1: | | 581 | Lbrkpt1: |
582 | movl %a0@+,%a1@+ | | 582 | movl %a0@+,%a1@+ |
583 | subql #4,%d1 | | 583 | subql #4,%d1 |
584 | jgt Lbrkpt1 | | 584 | jgt Lbrkpt1 |
585 | | | 585 | |
586 | Lbrkpt2: | | 586 | Lbrkpt2: |
587 | | Call the trap handler for the kernel debugger. | | 587 | | Call the trap handler for the kernel debugger. |
588 | | Do not call trap() to do it, so that we can | | 588 | | Do not call trap() to do it, so that we can |
589 | | set breakpoints in trap() if we want. We know | | 589 | | set breakpoints in trap() if we want. We know |
590 | | the trap type is either T_TRACE or T_BREAKPOINT. | | 590 | | the trap type is either T_TRACE or T_BREAKPOINT. |
591 | | If we have both DDB and KGDB, let KGDB see it first, | | 591 | | If we have both DDB and KGDB, let KGDB see it first, |
592 | | because KGDB will just return 0 if not connected. | | 592 | | because KGDB will just return 0 if not connected. |
593 | | Save args in %d2, %a2 | | 593 | | Save args in %d2, %a2 |
594 | movl %d0,%d2 | trap type | | 594 | movl %d0,%d2 | trap type |
595 | movl %sp,%a2 | frame ptr | | 595 | movl %sp,%a2 | frame ptr |
596 | #ifdef KGDB | | 596 | #ifdef KGDB |
597 | | Let KGDB handle it (if connected) | | 597 | | Let KGDB handle it (if connected) |
598 | movl %a2,%sp@- | push frame ptr | | 598 | movl %a2,%sp@- | push frame ptr |
599 | movl %d2,%sp@- | push trap type | | 599 | movl %d2,%sp@- | push trap type |
600 | jbsr _C_LABEL(kgdb_trap) | handle the trap | | 600 | jbsr _C_LABEL(kgdb_trap) | handle the trap |
601 | addql #8,%sp | pop args | | 601 | addql #8,%sp | pop args |
602 | cmpl #0,%d0 | did kgdb handle it? | | 602 | cmpl #0,%d0 | did kgdb handle it? |
603 | jne Lbrkpt3 | yes, done | | 603 | jne Lbrkpt3 | yes, done |
604 | #endif | | 604 | #endif |
605 | #ifdef DDB | | 605 | #ifdef DDB |
606 | | Let DDB handle it | | 606 | | Let DDB handle it |
607 | movl %a2,%sp@- | push frame ptr | | 607 | movl %a2,%sp@- | push frame ptr |
608 | movl %d2,%sp@- | push trap type | | 608 | movl %d2,%sp@- | push trap type |
609 | jbsr _C_LABEL(kdb_trap) | handle the trap | | 609 | jbsr _C_LABEL(kdb_trap) | handle the trap |
610 | addql #8,%sp | pop args | | 610 | addql #8,%sp | pop args |
611 | #if 0 /* not needed on hp300 */ | | 611 | #if 0 /* not needed on hp300 */ |
612 | cmpl #0,%d0 | did ddb handle it? | | 612 | cmpl #0,%d0 | did ddb handle it? |
613 | jne Lbrkpt3 | yes, done | | 613 | jne Lbrkpt3 | yes, done |
614 | #endif | | 614 | #endif |
615 | #endif | | 615 | #endif |
616 | /* Sun 3 drops into PROM here. */ | | 616 | /* Sun 3 drops into PROM here. */ |
617 | Lbrkpt3: | | 617 | Lbrkpt3: |
618 | | The stack pointer may have been modified, or | | 618 | | The stack pointer may have been modified, or |
619 | | data below it modified (by kgdb push call), | | 619 | | data below it modified (by kgdb push call), |
620 | | so push the hardware frame at the current sp | | 620 | | so push the hardware frame at the current sp |
621 | | before restoring registers and returning. | | 621 | | before restoring registers and returning. |
622 | | | 622 | |
623 | movl %sp@(FR_SP),%a0 | modified %sp | | 623 | movl %sp@(FR_SP),%a0 | modified %sp |
624 | lea %sp@(FR_SIZE),%a1 | end of our frame | | 624 | lea %sp@(FR_SIZE),%a1 | end of our frame |
625 | movl %a1@-,%a0@- | copy 2 longs with | | 625 | movl %a1@-,%a0@- | copy 2 longs with |
626 | movl %a1@-,%a0@- | ... predecrement | | 626 | movl %a1@-,%a0@- | ... predecrement |
627 | movl %a0,%sp@(FR_SP) | %sp = h/w frame | | 627 | movl %a0,%sp@(FR_SP) | %sp = h/w frame |
628 | moveml %sp@+,#0x7FFF | restore all but %sp | | 628 | moveml %sp@+,#0x7FFF | restore all but %sp |
629 | movl %sp@,%sp | ... and %sp | | 629 | movl %sp@,%sp | ... and %sp |
630 | rte | all done | | 630 | rte | all done |
631 | | | 631 | |
632 | /* Use common m68k sigreturn */ | | 632 | /* Use common m68k sigreturn */ |
633 | #include <m68k/m68k/sigreturn.s> | | 633 | #include <m68k/m68k/sigreturn.s> |
634 | | | 634 | |
635 | /* | | 635 | /* |
636 | * Provide a generic interrupt dispatcher, only handle hardclock (int6) | | 636 | * Provide a generic interrupt dispatcher, only handle hardclock (int6) |
637 | * specially, to improve performance | | 637 | * specially, to improve performance |
638 | */ | | 638 | */ |
639 | | | 639 | |
640 | ENTRY_NOPROFILE(spurintr) /* level 0 */ | | 640 | ENTRY_NOPROFILE(spurintr) /* level 0 */ |
641 | addql #1,_C_LABEL(intrcnt)+0 | | 641 | addql #1,_C_LABEL(intrcnt)+0 |
642 | INTERRUPT_SAVEREG | | 642 | INTERRUPT_SAVEREG |
643 | CPUINFO_INCREMENT(CI_NINTR) | | 643 | CPUINFO_INCREMENT(CI_NINTR) |
644 | INTERRUPT_RESTOREREG | | 644 | INTERRUPT_RESTOREREG |
645 | rte | XXX mfpcure (x680x0 hardware bug) | | 645 | rte | XXX mfpcure (x680x0 hardware bug) |
646 | | | 646 | |
647 | ENTRY_NOPROFILE(kbdtimer) | | 647 | ENTRY_NOPROFILE(kbdtimer) |
648 | rte | | 648 | rte |
649 | | | 649 | |
650 | ENTRY_NOPROFILE(intiotrap) | | 650 | ENTRY_NOPROFILE(intiotrap) |
651 | addql #1,_C_LABEL(idepth) | | 651 | addql #1,_C_LABEL(idepth) |
652 | INTERRUPT_SAVEREG | | 652 | INTERRUPT_SAVEREG |
653 | pea %sp@(16-(FR_HW)) | XXX | | 653 | pea %sp@(16-(FR_HW)) | XXX |
654 | jbsr _C_LABEL(intio_intr) | | 654 | jbsr _C_LABEL(intio_intr) |
655 | addql #4,%sp | | 655 | addql #4,%sp |
656 | CPUINFO_INCREMENT(CI_NINTR) | | 656 | CPUINFO_INCREMENT(CI_NINTR) |
657 | INTERRUPT_RESTOREREG | | 657 | INTERRUPT_RESTOREREG |
658 | subql #1,_C_LABEL(idepth) | | 658 | subql #1,_C_LABEL(idepth) |
659 | jra rei | | 659 | jra rei |
660 | | | 660 | |
661 | ENTRY_NOPROFILE(lev1intr) | | 661 | ENTRY_NOPROFILE(lev1intr) |
662 | ENTRY_NOPROFILE(lev2intr) | | 662 | ENTRY_NOPROFILE(lev2intr) |
663 | ENTRY_NOPROFILE(lev3intr) | | 663 | ENTRY_NOPROFILE(lev3intr) |
664 | ENTRY_NOPROFILE(lev4intr) | | 664 | ENTRY_NOPROFILE(lev4intr) |
665 | ENTRY_NOPROFILE(lev5intr) | | 665 | ENTRY_NOPROFILE(lev5intr) |
666 | ENTRY_NOPROFILE(lev6intr) | | 666 | ENTRY_NOPROFILE(lev6intr) |
667 | addql #1,_C_LABEL(idepth) | | 667 | addql #1,_C_LABEL(idepth) |
668 | INTERRUPT_SAVEREG | | 668 | INTERRUPT_SAVEREG |
669 | Lnotdma: | | 669 | Lnotdma: |
670 | lea _C_LABEL(intrcnt),%a0 | | 670 | lea _C_LABEL(intrcnt),%a0 |
671 | movw %sp@(22),%d0 | use vector offset | | 671 | movw %sp@(22),%d0 | use vector offset |
672 | andw #0xfff,%d0 | sans frame type | | 672 | andw #0xfff,%d0 | sans frame type |
673 | addql #1,%a0@(-0x60,%d0:w) | to increment apropos counter | | 673 | addql #1,%a0@(-0x60,%d0:w) | to increment apropos counter |
674 | movw %sr,%sp@- | push current SR value | | 674 | movw %sr,%sp@- | push current SR value |
675 | clrw %sp@- | padded to longword | | 675 | clrw %sp@- | padded to longword |
676 | jbsr _C_LABEL(intrhand) | handle interrupt | | 676 | jbsr _C_LABEL(intrhand) | handle interrupt |
677 | addql #4,%sp | pop SR | | 677 | addql #4,%sp | pop SR |
678 | CPUINFO_INCREMENT(CI_NINTR) | | 678 | CPUINFO_INCREMENT(CI_NINTR) |
679 | INTERRUPT_RESTOREREG | | 679 | INTERRUPT_RESTOREREG |
680 | subql #1,_C_LABEL(idepth) | | 680 | subql #1,_C_LABEL(idepth) |
681 | jra _ASM_LABEL(rei) | | 681 | jra _ASM_LABEL(rei) |
682 | | | 682 | |
683 | ENTRY_NOPROFILE(timertrap) | | 683 | ENTRY_NOPROFILE(timertrap) |
684 | addql #1,_C_LABEL(idepth) | | 684 | addql #1,_C_LABEL(idepth) |
685 | INTERRUPT_SAVEREG | save scratch registers | | 685 | INTERRUPT_SAVEREG | save scratch registers |
686 | addql #1,_C_LABEL(intrcnt)+32 | count hardclock interrupts | | 686 | addql #1,_C_LABEL(intrcnt)+32 | count hardclock interrupts |
687 | lea %sp@(16),%a1 | a1 = &clockframe | | 687 | lea %sp@(16),%a1 | a1 = &clockframe |
688 | movl %a1,%sp@- | | 688 | movl %a1,%sp@- |
689 | jbsr _C_LABEL(hardclock) | hardclock(&frame) | | 689 | jbsr _C_LABEL(hardclock) | hardclock(&frame) |
690 | addql #4,%sp | | 690 | addql #4,%sp |
691 | CPUINFO_INCREMENT(CI_NINTR) | chalk up another interrupt | | 691 | CPUINFO_INCREMENT(CI_NINTR) | chalk up another interrupt |
692 | INTERRUPT_RESTOREREG | restore scratch registers | | 692 | INTERRUPT_RESTOREREG | restore scratch registers |
693 | subql #1,_C_LABEL(idepth) | | 693 | subql #1,_C_LABEL(idepth) |
694 | jra _ASM_LABEL(rei) | all done | | 694 | jra _ASM_LABEL(rei) | all done |
695 | | | 695 | |
696 | ENTRY_NOPROFILE(lev7intr) | | 696 | ENTRY_NOPROFILE(lev7intr) |
697 | addql #1,_C_LABEL(idepth) | | 697 | addql #1,_C_LABEL(idepth) |
698 | addql #1,_C_LABEL(intrcnt)+28 | | 698 | addql #1,_C_LABEL(intrcnt)+28 |
699 | clrl %sp@- | | 699 | clrl %sp@- |
700 | moveml #0xFFFF,%sp@- | save registers | | 700 | moveml #0xFFFF,%sp@- | save registers |
701 | movl %usp,%a0 | and save | | 701 | movl %usp,%a0 | and save |
702 | movl %a0,%sp@(FR_SP) | the user stack pointer | | 702 | movl %a0,%sp@(FR_SP) | the user stack pointer |
703 | jbsr _C_LABEL(nmihand) | call handler | | 703 | jbsr _C_LABEL(nmihand) | call handler |
704 | movl %sp@(FR_SP),%a0 | restore | | 704 | movl %sp@(FR_SP),%a0 | restore |
705 | movl %a0,%usp | user SP | | 705 | movl %a0,%usp | user SP |
706 | moveml %sp@+,#0x7FFF | and remaining registers | | 706 | moveml %sp@+,#0x7FFF | and remaining registers |
707 | addql #8,%sp | pop SP and stack adjust | | 707 | addql #8,%sp | pop SP and stack adjust |
708 | subql #1,_C_LABEL(idepth) | | 708 | subql #1,_C_LABEL(idepth) |
709 | jra _ASM_LABEL(rei) | all done | | 709 | jra _ASM_LABEL(rei) | all done |
710 | | | 710 | |
711 | /* | | 711 | /* |
712 | * floppy ejection trap | | 712 | * floppy ejection trap |
713 | */ | | 713 | */ |
714 | | | 714 | |
715 | ENTRY_NOPROFILE(fdeject) | | 715 | ENTRY_NOPROFILE(fdeject) |
716 | jra _ASM_LABEL(rei) | | 716 | jra _ASM_LABEL(rei) |
717 | | | 717 | |
718 | /* | | 718 | /* |
719 | * Emulation of VAX REI instruction. | | 719 | * Emulation of VAX REI instruction. |
720 | * | | 720 | * |
721 | * This code deals with checking for and servicing ASTs | | 721 | * This code deals with checking for and servicing ASTs |
722 | * (profiling, scheduling) and software interrupts (network, softclock). | | 722 | * (profiling, scheduling) and software interrupts (network, softclock). |
723 | * We check for ASTs first, just like the VAX. To avoid excess overhead | | 723 | * We check for ASTs first, just like the VAX. To avoid excess overhead |
724 | * the T_ASTFLT handling code will also check for software interrupts so we | | 724 | * the T_ASTFLT handling code will also check for software interrupts so we |
725 | * do not have to do it here. After identifing that we need an AST we | | 725 | * do not have to do it here. After identifing that we need an AST we |
726 | * drop the IPL to allow device interrupts. | | 726 | * drop the IPL to allow device interrupts. |
727 | * | | 727 | * |
728 | * This code is complicated by the fact that sendsig may have been called | | 728 | * This code is complicated by the fact that sendsig may have been called |
729 | * necessitating a stack cleanup. | | 729 | * necessitating a stack cleanup. |
730 | */ | | 730 | */ |
731 | | | 731 | |
732 | ASENTRY_NOPROFILE(rei) | | 732 | ASENTRY_NOPROFILE(rei) |
733 | tstl _C_LABEL(astpending) | AST pending? | | 733 | tstl _C_LABEL(astpending) | AST pending? |
734 | jne 1f | no, done | | 734 | jne 1f | no, done |
735 | rte | | 735 | rte |
736 | 1: | | 736 | 1: |
737 | btst #5,%sp@ | yes, are we returning to user mode? | | 737 | btst #5,%sp@ | yes, are we returning to user mode? |
738 | beq 2f | no, done | | 738 | beq 2f | no, done |
739 | rte | | 739 | rte |
740 | 2: | | 740 | 2: |
741 | movw #PSL_LOWIPL,%sr | lower SPL | | 741 | movw #PSL_LOWIPL,%sr | lower SPL |
742 | clrl %sp@- | stack adjust | | 742 | clrl %sp@- | stack adjust |
743 | moveml #0xFFFF,%sp@- | save all registers | | 743 | moveml #0xFFFF,%sp@- | save all registers |
744 | movl %usp,%a1 | including | | 744 | movl %usp,%a1 | including |
745 | movl %a1,%sp@(FR_SP) | the users SP | | 745 | movl %a1,%sp@(FR_SP) | the users SP |
746 | Lrei: | | 746 | Lrei: |
747 | clrl %sp@- | VA == none | | 747 | clrl %sp@- | VA == none |
748 | clrl %sp@- | code == none | | 748 | clrl %sp@- | code == none |
749 | movl #T_ASTFLT,%sp@- | type == async system trap | | 749 | movl #T_ASTFLT,%sp@- | type == async system trap |
750 | pea %sp@(12) | fp == trap frame address | | 750 | pea %sp@(12) | fp == trap frame address |
751 | jbsr _C_LABEL(trap) | go handle it | | 751 | jbsr _C_LABEL(trap) | go handle it |
752 | lea %sp@(16),%sp | pop value args | | 752 | lea %sp@(16),%sp | pop value args |
753 | movl %sp@(FR_SP),%a0 | restore user SP | | 753 | movl %sp@(FR_SP),%a0 | restore user SP |
754 | movl %a0,%usp | from save area | | 754 | movl %a0,%usp | from save area |
755 | movw %sp@(FR_ADJ),%d0 | need to adjust stack? | | 755 | movw %sp@(FR_ADJ),%d0 | need to adjust stack? |
756 | jne Laststkadj | yes, go to it | | 756 | jne Laststkadj | yes, go to it |
757 | moveml %sp@+,#0x7FFF | no, restore most user regs | | 757 | moveml %sp@+,#0x7FFF | no, restore most user regs |
758 | addql #8,%sp | toss SP and stack adjust | | 758 | addql #8,%sp | toss SP and stack adjust |
759 | rte | and do real RTE | | 759 | rte | and do real RTE |
760 | Laststkadj: | | 760 | Laststkadj: |
761 | lea %sp@(FR_HW),%a1 | pointer to HW frame | | 761 | lea %sp@(FR_HW),%a1 | pointer to HW frame |
762 | addql #8,%a1 | source pointer | | 762 | addql #8,%a1 | source pointer |
763 | movl %a1,%a0 | source | | 763 | movl %a1,%a0 | source |
764 | addw %d0,%a0 | + hole size = dest pointer | | 764 | addw %d0,%a0 | + hole size = dest pointer |
765 | movl %a1@-,%a0@- | copy | | 765 | movl %a1@-,%a0@- | copy |
766 | movl %a1@-,%a0@- | 8 bytes | | 766 | movl %a1@-,%a0@- | 8 bytes |
767 | movl %a0,%sp@(FR_SP) | new SSP | | 767 | movl %a0,%sp@(FR_SP) | new SSP |
768 | moveml %sp@+,#0x7FFF | restore user registers | | 768 | moveml %sp@+,#0x7FFF | restore user registers |
769 | movl %sp@,%sp | and our SP | | 769 | movl %sp@,%sp | and our SP |
770 | rte | and do real RTE | | 770 | rte | and do real RTE |
771 | | | 771 | |
772 | /* | | 772 | /* |
773 | * Use common m68k sigcode. | | 773 | * Use common m68k sigcode. |
774 | */ | | 774 | */ |
775 | #include <m68k/m68k/sigcode.s> | | 775 | #include <m68k/m68k/sigcode.s> |
776 | #ifdef COMPAT_SUNOS | | 776 | #ifdef COMPAT_SUNOS |
777 | #include <m68k/m68k/sunos_sigcode.s> | | 777 | #include <m68k/m68k/sunos_sigcode.s> |
778 | #endif | | 778 | #endif |
779 | #ifdef COMPAT_SVR4 | | 779 | #ifdef COMPAT_SVR4 |
780 | #include <m68k/m68k/svr4_sigcode.s> | | 780 | #include <m68k/m68k/svr4_sigcode.s> |
781 | #endif | | 781 | #endif |
782 | | | 782 | |
783 | /* | | 783 | /* |
784 | * Primitives | | 784 | * Primitives |
785 | */ | | 785 | */ |
786 | | | 786 | |
787 | /* | | 787 | /* |
788 | * Use common m68k support routines. | | 788 | * Use common m68k support routines. |
789 | */ | | 789 | */ |
790 | #include <m68k/m68k/support.s> | | 790 | #include <m68k/m68k/support.s> |
791 | | | 791 | |
792 | /* | | 792 | /* |
793 | * Use common m68k process/lwp switch and context save subroutines. | | 793 | * Use common m68k process/lwp switch and context save subroutines. |
794 | */ | | 794 | */ |
795 | #define FPCOPROC /* XXX: Temp. reqd. */ | | 795 | #define FPCOPROC /* XXX: Temp. reqd. */ |
796 | #include <m68k/m68k/switch_subr.s> | | 796 | #include <m68k/m68k/switch_subr.s> |
797 | | | 797 | |
798 | | | 798 | |
799 | #if defined(M68040) || defined(M68060) | | 799 | #if defined(M68040) || defined(M68060) |
800 | ENTRY(suline) | | 800 | ENTRY(suline) |
801 | movl %sp@(4),%a0 | address to write | | 801 | movl %sp@(4),%a0 | address to write |
802 | movl _C_LABEL(curpcb),%a1 | current pcb | | 802 | movl _C_LABEL(curpcb),%a1 | current pcb |
803 | movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault | | 803 | movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault |
804 | movl %sp@(8),%a1 | address of line | | 804 | movl %sp@(8),%a1 | address of line |
805 | movl %a1@+,%d0 | get lword | | 805 | movl %a1@+,%d0 | get lword |
806 | movsl %d0,%a0@+ | put lword | | 806 | movsl %d0,%a0@+ | put lword |
807 | nop | sync | | 807 | nop | sync |
808 | movl %a1@+,%d0 | get lword | | 808 | movl %a1@+,%d0 | get lword |
809 | movsl %d0,%a0@+ | put lword | | 809 | movsl %d0,%a0@+ | put lword |
810 | nop | sync | | 810 | nop | sync |
811 | movl %a1@+,%d0 | get lword | | 811 | movl %a1@+,%d0 | get lword |
812 | movsl %d0,%a0@+ | put lword | | 812 | movsl %d0,%a0@+ | put lword |
813 | nop | sync | | 813 | nop | sync |
814 | movl %a1@+,%d0 | get lword | | 814 | movl %a1@+,%d0 | get lword |
815 | movsl %d0,%a0@+ | put lword | | 815 | movsl %d0,%a0@+ | put lword |
816 | nop | sync | | 816 | nop | sync |
817 | moveq #0,%d0 | indicate no fault | | 817 | moveq #0,%d0 | indicate no fault |
818 | jra Lsldone | | 818 | jra Lsldone |
819 | Lslerr: | | 819 | Lslerr: |
820 | moveq #-1,%d0 | | 820 | moveq #-1,%d0 |
821 | Lsldone: | | 821 | Lsldone: |
822 | movl _C_LABEL(curpcb),%a1 | current pcb | | 822 | movl _C_LABEL(curpcb),%a1 | current pcb |
823 | clrl %a1@(PCB_ONFAULT) | clear fault address | | 823 | clrl %a1@(PCB_ONFAULT) | clear fault address |
824 | rts | | 824 | rts |
825 | #endif | | 825 | #endif |
826 | | | 826 | |
827 | ENTRY(ecacheon) | | 827 | ENTRY(ecacheon) |
828 | rts | | 828 | rts |
829 | | | 829 | |
830 | ENTRY(ecacheoff) | | 830 | ENTRY(ecacheoff) |
831 | rts | | 831 | rts |
832 | | | 832 | |
833 | /* | | 833 | /* |
834 | * Load a new user segment table pointer. | | 834 | * Load a new user segment table pointer. |
835 | */ | | 835 | */ |
836 | ENTRY(loadustp) | | 836 | ENTRY(loadustp) |
837 | movl %sp@(4),%d0 | new USTP | | 837 | movl %sp@(4),%d0 | new USTP |
838 | moveq #PGSHIFT,%d1 | | 838 | moveq #PGSHIFT,%d1 |
839 | lsll %d1,%d0 | convert to addr | | 839 | lsll %d1,%d0 | convert to addr |
840 | #if defined(M68040) || defined(M68060) | | 840 | #if defined(M68040) || defined(M68060) |
841 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? | | 841 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? |
842 | jne LmotommuC | no, skip | | 842 | jne LmotommuC | no, skip |
843 | .word 0xf518 | yes, pflusha | | 843 | .word 0xf518 | yes, pflusha |
844 | .long 0x4e7b0806 | movc %d0,%urp | | 844 | .long 0x4e7b0806 | movc %d0,%urp |
845 | #ifdef M68060 | | 845 | #ifdef M68060 |
846 | cmpl #CPU_68060,_C_LABEL(cputype) | | 846 | cmpl #CPU_68060,_C_LABEL(cputype) |
847 | jne Lldno60 | | 847 | jne Lldno60 |
848 | movc %cacr,%d0 | | 848 | movc %cacr,%d0 |
849 | orl #IC60_CUBC,%d0 | clear user branch cache entries | | 849 | orl #IC60_CUBC,%d0 | clear user branch cache entries |
850 | movc %d0,%cacr | | 850 | movc %d0,%cacr |
851 | Lldno60: | | 851 | Lldno60: |
852 | #endif | | 852 | #endif |
853 | rts | | 853 | rts |
854 | LmotommuC: | | 854 | LmotommuC: |
855 | #endif | | 855 | #endif |
856 | pflusha | flush entire TLB | | 856 | pflusha | flush entire TLB |
857 | lea _C_LABEL(protorp),%a0 | CRP prototype | | 857 | lea _C_LABEL(protorp),%a0 | CRP prototype |
858 | movl %d0,%a0@(4) | stash USTP | | 858 | movl %d0,%a0@(4) | stash USTP |
859 | pmove %a0@,%crp | load root pointer | | 859 | pmove %a0@,%crp | load root pointer |
860 | movl #CACHE_CLR,%d0 | | 860 | movl #CACHE_CLR,%d0 |
861 | movc %d0,%cacr | invalidate cache(s) | | 861 | movc %d0,%cacr | invalidate cache(s) |
862 | rts | | 862 | rts |
863 | | | 863 | |
864 | ENTRY(ploadw) | | 864 | ENTRY(ploadw) |
865 | #if defined(M68030) | | 865 | #if defined(M68030) |
866 | movl %sp@(4),%a0 | address to load | | 866 | movl %sp@(4),%a0 | address to load |
867 | #if defined(M68040) || defined(M68060) | | 867 | #if defined(M68040) || defined(M68060) |
868 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? | | 868 | cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? |
869 | jeq Lploadwskp | yes, skip | | 869 | jeq Lploadwskp | yes, skip |
870 | #endif | | 870 | #endif |
871 | ploadw #1,%a0@ | pre-load translation | | 871 | ploadw #1,%a0@ | pre-load translation |
872 | Lploadwskp: | | 872 | Lploadwskp: |
873 | #endif | | 873 | #endif |
874 | rts | | 874 | rts |
875 | | | 875 | |
876 | /* | | 876 | /* |
877 | * _delay(u_int N) | | 877 | * _delay(u_int N) |
878 | * | | 878 | * |
879 | * Delay for at least (N/256) microseconds. | | 879 | * Delay for at least (N/256) microseconds. |
880 | * This routine depends on the variable: delay_divisor | | 880 | * This routine depends on the variable: delay_divisor |
881 | * which should be set based on the CPU clock rate. | | 881 | * which should be set based on the CPU clock rate. |
882 | */ | | 882 | */ |
883 | ENTRY_NOPROFILE(_delay) | | 883 | ENTRY_NOPROFILE(_delay) |
884 | | %d0 = arg = (usecs << 8) | | 884 | | %d0 = arg = (usecs << 8) |
885 | movl %sp@(4),%d0 | | 885 | movl %sp@(4),%d0 |
886 | | %d1 = delay_divisor | | 886 | | %d1 = delay_divisor |
887 | movl _C_LABEL(delay_divisor),%d1 | | 887 | movl _C_LABEL(delay_divisor),%d1 |
888 | L_delay: | | 888 | L_delay: |
889 | subl %d1,%d0 | | 889 | subl %d1,%d0 |
890 | jgt L_delay | | 890 | jgt L_delay |
891 | rts | | 891 | rts |
892 | | | 892 | |
893 | /* | | 893 | /* |
894 | * Handle the nitty-gritty of rebooting the machine. | | 894 | * Handle the nitty-gritty of rebooting the machine. |
895 | * Basically we just turn off the MMU and jump to the appropriate ROM routine. | | 895 | * Basically we just turn off the MMU and jump to the appropriate ROM routine. |
896 | * Note that we must be running in an address range that is mapped one-to-one | | 896 | * Note that we must be running in an address range that is mapped one-to-one |
897 | * logical to physical so that the PC is still valid immediately after the MMU | | 897 | * logical to physical so that the PC is still valid immediately after the MMU |
898 | * is turned off. We have conveniently mapped the last page of physical | | 898 | * is turned off. We have conveniently mapped the last page of physical |
899 | * memory this way. | | 899 | * memory this way. |
900 | */ | | 900 | */ |
901 | ENTRY_NOPROFILE(doboot) | | 901 | ENTRY_NOPROFILE(doboot) |
902 | movw #PSL_HIGHIPL,%sr | cut off any interrupts | | 902 | movw #PSL_HIGHIPL,%sr | cut off any interrupts |
903 | subal %a1,%a1 | a1 = 0 | | 903 | subal %a1,%a1 | a1 = 0 |
904 | | | 904 | |
905 | movl #CACHE_OFF,%d0 | | 905 | movl #CACHE_OFF,%d0 |
906 | #if defined(M68040) || defined(M68060) | | 906 | #if defined(M68040) || defined(M68060) |
907 | movl _C_LABEL(mmutype),%d2 | d2 = mmutype | | 907 | movl _C_LABEL(mmutype),%d2 | d2 = mmutype |
908 | addl #(-1 * MMU_68040),%d2 | 68040? | | 908 | addl #(-1 * MMU_68040),%d2 | 68040? |
909 | jne Ldoboot0 | no, skip | | 909 | jne Ldoboot0 | no, skip |
910 | .word 0xf4f8 | cpusha bc - push and invalidate caches | | 910 | .word 0xf4f8 | cpusha bc - push and invalidate caches |
911 | nop | | 911 | nop |
912 | movl #CACHE40_OFF,%d0 | | 912 | movl #CACHE40_OFF,%d0 |
913 | Ldoboot0: | | 913 | Ldoboot0: |
914 | #endif | | 914 | #endif |
915 | movc %d0,%cacr | disable on-chip cache(s) | | 915 | movc %d0,%cacr | disable on-chip cache(s) |
916 | | | 916 | |
917 | | ok, turn off MMU.. | | 917 | | ok, turn off MMU.. |
918 | Ldoreboot: | | 918 | Ldoreboot: |
919 | #if defined(M68040) || defined(M68060) | | 919 | #if defined(M68040) || defined(M68060) |
920 | tstl %d2 | 68040? | | 920 | tstl %d2 | 68040? |
921 | jne LmotommuF | no, skip | | 921 | jne LmotommuF | no, skip |
922 | movc %a1,%cacr | caches off | | 922 | movc %a1,%cacr | caches off |
923 | .long 0x4e7b9003 | movc a1(=0),tc ; disable MMU | | 923 | .long 0x4e7b9003 | movc a1(=0),tc ; disable MMU |
924 | jra Ldoreboot1 | | 924 | jra Ldoreboot1 |
925 | LmotommuF: | | 925 | LmotommuF: |
926 | #endif | | 926 | #endif |
927 | clrl %sp@ | | 927 | clrl %sp@ |
928 | pmove %sp@,%tc | disable MMU | | 928 | pmove %sp@,%tc | disable MMU |
929 | Ldoreboot1: | | 929 | Ldoreboot1: |
930 | moveml 0x00ff0000,#0x0101 | get RESET vectors in ROM | | 930 | moveml 0x00ff0000,#0x0101 | get RESET vectors in ROM |
931 | | (d0: ssp, a0: pc) | | 931 | | (d0: ssp, a0: pc) |
932 | moveml #0x0101,%a1@ | put them at 0x0000 (for Xellent30) | | 932 | moveml #0x0101,%a1@ | put them at 0x0000 (for Xellent30) |
933 | movc %a1,%vbr | reset Vector Base Register | | 933 | movc %a1,%vbr | reset Vector Base Register |
934 | jmp %a0@ | reboot X680x0 | | 934 | jmp %a0@ | reboot X680x0 |
935 | Lebootcode: | | 935 | Lebootcode: |
936 | | | 936 | |
937 | /* | | 937 | /* |
938 | * Misc. global variables. | | 938 | * Misc. global variables. |
939 | */ | | 939 | */ |
940 | .data | | 940 | .data |
941 | GLOBAL(mmutype) | | 941 | GLOBAL(mmutype) |
942 | .long MMU_68030 | default to 030 internal MMU | | 942 | .long MMU_68030 | default to 030 internal MMU |
943 | | | 943 | |
944 | GLOBAL(cputype) | | 944 | GLOBAL(cputype) |
945 | .long CPU_68030 | default to 68030 CPU | | 945 | .long CPU_68030 | default to 68030 CPU |
946 | | | 946 | |
947 | #ifdef M68K_MMU_HP | | 947 | #ifdef M68K_MMU_HP |
948 | GLOBAL(ectype) | | 948 | GLOBAL(ectype) |
949 | .long EC_NONE | external cache type, default to none | | 949 | .long EC_NONE | external cache type, default to none |
950 | #endif | | 950 | #endif |
951 | | | 951 | |
952 | GLOBAL(fputype) | | 952 | GLOBAL(fputype) |
953 | .long FPU_NONE | | 953 | .long FPU_NONE |
954 | | | 954 | |
955 | GLOBAL(protorp) | | 955 | GLOBAL(protorp) |
956 | .long 0,0 | prototype root pointer | | 956 | .long 0,0 | prototype root pointer |
957 | | | 957 | |
958 | GLOBAL(intiobase) | | 958 | GLOBAL(intiobase) |
959 | .long 0 | KVA of base of internal IO space | | 959 | .long 0 | KVA of base of internal IO space |
960 | | | 960 | |
961 | GLOBAL(intiolimit) | | 961 | GLOBAL(intiolimit) |
962 | .long 0 | KVA of end of internal IO space | | 962 | .long 0 | KVA of end of internal IO space |
963 | | | 963 | |
964 | #ifdef DEBUG | | 964 | #ifdef DEBUG |
965 | ASGLOBAL(fulltflush) | | 965 | ASGLOBAL(fulltflush) |
966 | .long 0 | | 966 | .long 0 |
967 | | | 967 | |
968 | ASGLOBAL(fullcflush) | | 968 | ASGLOBAL(fullcflush) |
969 | .long 0 | | 969 | .long 0 |
970 | #endif | | 970 | #endif |
971 | | | 971 | |
972 | /* interrupt counters */ | | 972 | /* interrupt counters */ |
973 | | | 973 | |
974 | GLOBAL(intrnames) | | 974 | GLOBAL(intrnames) |
975 | .asciz "spur" | | 975 | .asciz "spur" |
976 | .asciz "lev1" | | 976 | .asciz "lev1" |
977 | .asciz "lev2" | | 977 | .asciz "lev2" |
978 | .asciz "lev3" | | 978 | .asciz "lev3" |
979 | .asciz "lev4" | | 979 | .asciz "lev4" |
980 | .asciz "lev5" | | 980 | .asciz "lev5" |
981 | .asciz "lev6" | | 981 | .asciz "lev6" |
982 | .asciz "nmi" | | 982 | .asciz "nmi" |
983 | .asciz "clock" | | 983 | .asciz "clock" |
984 | .asciz "com" | | 984 | .asciz "com" |
985 | GLOBAL(eintrnames) | | 985 | GLOBAL(eintrnames) |
986 | .even | | 986 | .even |
987 | | | 987 | |
988 | GLOBAL(intrcnt) | | 988 | GLOBAL(intrcnt) |
989 | .long 0,0,0,0,0,0,0,0,0,0 | | 989 | .long 0,0,0,0,0,0,0,0,0,0 |
990 | GLOBAL(eintrcnt) | | 990 | GLOBAL(eintrcnt) |