Wed Dec 2 15:51:13 2009 UTC ()
Use common pmap_bootstrap_finalize() to initialize lwp0 uarea etc.
Tested on HP9000/382.


(tsutsui)
diff -r1.147 -r1.148 src/sys/arch/hp300/hp300/locore.s
diff -r1.39 -r1.40 src/sys/arch/hp300/hp300/pmap_bootstrap.c

cvs diff -r1.147 -r1.148 src/sys/arch/hp300/hp300/locore.s (switch to unified diff)

--- src/sys/arch/hp300/hp300/locore.s 2009/11/26 00:19:17 1.147
+++ src/sys/arch/hp300/hp300/locore.s 2009/12/02 15:51:12 1.148
@@ -1,1551 +1,1550 @@ @@ -1,1551 +1,1550 @@
1/* $NetBSD: locore.s,v 1.147 2009/11/26 00:19:17 matt Exp $ */ 1/* $NetBSD: locore.s,v 1.148 2009/12/02 15:51:12 tsutsui Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1980, 1990, 1993 4 * Copyright (c) 1980, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer 8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department. 9 * Science Department.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors 19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 * 34 *
35 * from: Utah $Hdr: locore.s 1.66 92/12/22$ 35 * from: Utah $Hdr: locore.s 1.66 92/12/22$
36 * 36 *
37 * @(#)locore.s 8.6 (Berkeley) 5/27/94 37 * @(#)locore.s 8.6 (Berkeley) 5/27/94
38 */ 38 */
39 39
40/* 40/*
41 * Copyright (c) 1994, 1995 Gordon W. Ross 41 * Copyright (c) 1994, 1995 Gordon W. Ross
42 * Copyright (c) 1988 University of Utah. 42 * Copyright (c) 1988 University of Utah.
43 * 43 *
44 * This code is derived from software contributed to Berkeley by 44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer 45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department. 46 * Science Department.
47 * 47 *
48 * Redistribution and use in source and binary forms, with or without 48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions 49 * modification, are permitted provided that the following conditions
50 * are met: 50 * are met:
51 * 1. Redistributions of source code must retain the above copyright 51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer. 52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright 53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the 54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution. 55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software 56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement: 57 * must display the following acknowledgement:
58 * This product includes software developed by the University of 58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors. 59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors 60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software 61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission. 62 * without specific prior written permission.
63 * 63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE. 74 * SUCH DAMAGE.
75 * 75 *
76 * from: Utah $Hdr: locore.s 1.66 92/12/22$ 76 * from: Utah $Hdr: locore.s 1.66 92/12/22$
77 * 77 *
78 * @(#)locore.s 8.6 (Berkeley) 5/27/94 78 * @(#)locore.s 8.6 (Berkeley) 5/27/94
79 */ 79 */
80 80
81#include "opt_compat_netbsd.h" 81#include "opt_compat_netbsd.h"
82#include "opt_compat_svr4.h" 82#include "opt_compat_svr4.h"
83#include "opt_compat_sunos.h" 83#include "opt_compat_sunos.h"
84#include "opt_ddb.h" 84#include "opt_ddb.h"
85#include "opt_fpsp.h" 85#include "opt_fpsp.h"
86#include "opt_kgdb.h" 86#include "opt_kgdb.h"
87#include "opt_lockdebug.h" 87#include "opt_lockdebug.h"
88#include "opt_fpu_emulate.h" 88#include "opt_fpu_emulate.h"
89 89
90#include "assym.h" 90#include "assym.h"
91#include <machine/asm.h> 91#include <machine/asm.h>
92#include <machine/trap.h> 92#include <machine/trap.h>
93 93
94#include "opt_useleds.h" 94#include "opt_useleds.h"
95#ifdef USELEDS 95#ifdef USELEDS
96#include <hp300/hp300/leds.h> 96#include <hp300/hp300/leds.h>
97#endif 97#endif
98 98
99#include "ksyms.h" 99#include "ksyms.h"
100 100
101#define MMUADDR(ar) movl _C_LABEL(MMUbase),ar 101#define MMUADDR(ar) movl _C_LABEL(MMUbase),ar
102#define CLKADDR(ar) movl _C_LABEL(CLKbase),ar 102#define CLKADDR(ar) movl _C_LABEL(CLKbase),ar
103 103
104/* 104/*
105 * This is for kvm_mkdb, and should be the address of the beginning 105 * This is for kvm_mkdb, and should be the address of the beginning
106 * of the kernel text segment (not necessarily the same as kernbase). 106 * of the kernel text segment (not necessarily the same as kernbase).
107 */ 107 */
108 .text 108 .text
109GLOBAL(kernel_text) 109GLOBAL(kernel_text)
110 110
111/* 111/*
112 * Clear and skip the first page of text; it will not be mapped at 112 * Clear and skip the first page of text; it will not be mapped at
113 * VA 0. 113 * VA 0.
114 * 114 *
115 * The bootloader places the bootinfo in this page, and we allocate 115 * The bootloader places the bootinfo in this page, and we allocate
116 * a VA for it and map it in pmap_bootstrap(). 116 * a VA for it and map it in pmap_bootstrap().
117 */ 117 */
118 .fill PAGE_SIZE/4,4,0 118 .fill PAGE_SIZE/4,4,0
119 119
120/* 120/*
121 * Temporary stack for a variety of purposes. 121 * Temporary stack for a variety of purposes.
122 * Try and make this the first thing is the data segment so it 122 * Try and make this the first thing is the data segment so it
123 * is page aligned. Note that if we overflow here, we run into 123 * is page aligned. Note that if we overflow here, we run into
124 * our text segment. 124 * our text segment.
125 */ 125 */
126 .data 126 .data
127 .space PAGE_SIZE 127 .space PAGE_SIZE
128ASLOCAL(tmpstk) 128ASLOCAL(tmpstk)
129 129
130#include <hp300/hp300/vectors.s> 130#include <hp300/hp300/vectors.s>
131 131
132/* 132/*
133 * Macro to relocate a symbol, used before MMU is enabled. 133 * Macro to relocate a symbol, used before MMU is enabled.
134 */ 134 */
135#ifdef __STDC__ 135#ifdef __STDC__
136#define IMMEDIATE # 136#define IMMEDIATE #
137#define _RELOC(var, ar) \ 137#define _RELOC(var, ar) \
138 movel IMMEDIATE var,ar; \ 138 movel IMMEDIATE var,ar; \
139 addl %a5,ar 139 addl %a5,ar
140#else 140#else
141#define _RELOC(var, ar) \ 141#define _RELOC(var, ar) \
142 movel #var,ar; \ 142 movel #var,ar; \
143 addl %a5,ar 143 addl %a5,ar
144#endif /* __STDC__ */ 144#endif /* __STDC__ */
145 145
146#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) 146#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar)
147#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) 147#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar)
148 148
149/* 149/*
150 * Final bits of grunt work required to reboot the system. The MMU 150 * Final bits of grunt work required to reboot the system. The MMU
151 * must be disabled when this is invoked. 151 * must be disabled when this is invoked.
152 */ 152 */
153#define DOREBOOT \ 153#define DOREBOOT \
154 /* Reset Vector Base Register to what PROM expects. */ \ 154 /* Reset Vector Base Register to what PROM expects. */ \
155 movl #0,%d0; \ 155 movl #0,%d0; \
156 movc %d0,%vbr; \ 156 movc %d0,%vbr; \
157 /* Jump to REQ_REBOOT */ \ 157 /* Jump to REQ_REBOOT */ \
158 jmp 0x1A4; 158 jmp 0x1A4;
159 159
160/* 160/*
161 * Initialization 161 * Initialization
162 * 162 *
163 * A4 contains the address of the end of the symtab 163 * A4 contains the address of the end of the symtab
164 * A5 contains physical load point from boot 164 * A5 contains physical load point from boot
165 * VBR contains zero from ROM. Exceptions will continue to vector 165 * VBR contains zero from ROM. Exceptions will continue to vector
166 * through ROM until MMU is turned on at which time they will vector 166 * through ROM until MMU is turned on at which time they will vector
167 * through our table (vectors.s). 167 * through our table (vectors.s).
168 */ 168 */
169 169
170BSS(lowram,4) 170BSS(lowram,4)
171BSS(esym,4) 171BSS(esym,4)
172 172
173ASENTRY_NOPROFILE(start) 173ASENTRY_NOPROFILE(start)
174 movw #PSL_HIGHIPL,%sr | no interrupts 174 movw #PSL_HIGHIPL,%sr | no interrupts
175 ASRELOC(tmpstk, %a0) 175 ASRELOC(tmpstk, %a0)
176 movl %a0,%sp | give ourselves a temporary stack 176 movl %a0,%sp | give ourselves a temporary stack
177 RELOC(esym, %a0) 177 RELOC(esym, %a0)
178#if 1 178#if 1
179 movl %a4,%a0@ | store end of symbol table 179 movl %a4,%a0@ | store end of symbol table
180#else 180#else
181 clrl %a0@ | no symbol table, yet 181 clrl %a0@ | no symbol table, yet
182#endif 182#endif
183 RELOC(lowram, %a0) 183 RELOC(lowram, %a0)
184 movl %a5,%a0@ | store start of physical memory 184 movl %a5,%a0@ | store start of physical memory
185 movl #CACHE_OFF,%d0 185 movl #CACHE_OFF,%d0
186 movc %d0,%cacr | clear and disable on-chip cache(s) 186 movc %d0,%cacr | clear and disable on-chip cache(s)
187 187
188/* check for internal HP-IB in SYSFLAG */ 188/* check for internal HP-IB in SYSFLAG */
189 btst #5,0xfffffed2 | internal HP-IB? 189 btst #5,0xfffffed2 | internal HP-IB?
190 jeq Lhaveihpib | yes, have HP-IB just continue 190 jeq Lhaveihpib | yes, have HP-IB just continue
191 RELOC(internalhpib, %a0) 191 RELOC(internalhpib, %a0)
192 movl #0,%a0@ | no, clear associated address 192 movl #0,%a0@ | no, clear associated address
193Lhaveihpib: 193Lhaveihpib:
194 194
195 RELOC(boothowto, %a0) | save reboot flags 195 RELOC(boothowto, %a0) | save reboot flags
196 movl %d7,%a0@ 196 movl %d7,%a0@
197 RELOC(bootdev, %a0) | and boot device 197 RELOC(bootdev, %a0) | and boot device
198 movl %d6,%a0@ 198 movl %d6,%a0@
199 199
200 /* 200 /*
201 * All data registers are now free. All address registers 201 * All data registers are now free. All address registers
202 * except %a5 are free. %a5 is used by the RELOC() macro, 202 * except %a5 are free. %a5 is used by the RELOC() macro,
203 * and cannot be used until after the MMU is enabled. 203 * and cannot be used until after the MMU is enabled.
204 */ 204 */
205 205
206/* determine our CPU/MMU combo - check for all regardless of kernel config */ 206/* determine our CPU/MMU combo - check for all regardless of kernel config */
207 movl #INTIOBASE+MMUBASE,%a1 207 movl #INTIOBASE+MMUBASE,%a1
208 movl #0x200,%d0 | data freeze bit 208 movl #0x200,%d0 | data freeze bit
209 movc %d0,%cacr | only exists on 68030 209 movc %d0,%cacr | only exists on 68030
210 movc %cacr,%d0 | read it back 210 movc %cacr,%d0 | read it back
211 tstl %d0 | zero? 211 tstl %d0 | zero?
212 jeq Lnot68030 | yes, we have 68020/68040 212 jeq Lnot68030 | yes, we have 68020/68040
213 213
214 /* 214 /*
215 * 68030 models 215 * 68030 models
216 */ 216 */
217 217
218 RELOC(mmutype, %a0) | no, we have 68030 218 RELOC(mmutype, %a0) | no, we have 68030
219 movl #MMU_68030,%a0@ | set to reflect 68030 PMMU 219 movl #MMU_68030,%a0@ | set to reflect 68030 PMMU
220 RELOC(cputype, %a0) 220 RELOC(cputype, %a0)
221 movl #CPU_68030,%a0@ | and 68030 CPU 221 movl #CPU_68030,%a0@ | and 68030 CPU
222 RELOC(machineid, %a0) 222 RELOC(machineid, %a0)
223 movl #0x80,%a1@(MMUCMD) | set magic cookie 223 movl #0x80,%a1@(MMUCMD) | set magic cookie
224 movl %a1@(MMUCMD),%d0 | read it back 224 movl %a1@(MMUCMD),%d0 | read it back
225 btst #7,%d0 | cookie still on? 225 btst #7,%d0 | cookie still on?
226 jeq Lnot370 | no, 360, 362 or 375 226 jeq Lnot370 | no, 360, 362 or 375
227 movl #0,%a1@(MMUCMD) | clear magic cookie 227 movl #0,%a1@(MMUCMD) | clear magic cookie
228 movl %a1@(MMUCMD),%d0 | read it back 228 movl %a1@(MMUCMD),%d0 | read it back
229 btst #7,%d0 | still on? 229 btst #7,%d0 | still on?
230 jeq Lisa370 | no, must be a 370 230 jeq Lisa370 | no, must be a 370
231 movl #HP_340,%a0@ | yes, must be a 340 231 movl #HP_340,%a0@ | yes, must be a 340
232 jra Lstart1 232 jra Lstart1
233Lnot370: 233Lnot370:
234 movl #HP_360,%a0@ | type is at least a 360 234 movl #HP_360,%a0@ | type is at least a 360
235 movl #0,%a1@(MMUCMD) | clear magic cookie2 235 movl #0,%a1@(MMUCMD) | clear magic cookie2
236 movl %a1@(MMUCMD),%d0 | read it back 236 movl %a1@(MMUCMD),%d0 | read it back
237 btst #16,%d0 | still on? 237 btst #16,%d0 | still on?
238 jeq Lisa36x | no, must be a 360 or a 362 238 jeq Lisa36x | no, must be a 360 or a 362
239 RELOC(mmuid, %a0) | save MMU ID 239 RELOC(mmuid, %a0) | save MMU ID
240 lsrl #MMUID_SHIFT,%d0 240 lsrl #MMUID_SHIFT,%d0
241 andl #MMUID_MASK,%d0 241 andl #MMUID_MASK,%d0
242 movl %d0,%a0@ 242 movl %d0,%a0@
243 RELOC(machineid, %a0) 243 RELOC(machineid, %a0)
244 cmpb #MMUID_345,%d0 | are we a 345? 244 cmpb #MMUID_345,%d0 | are we a 345?
245 beq Lisa345 245 beq Lisa345
246 cmpb #MMUID_375,%d0 | how about a 375? 246 cmpb #MMUID_375,%d0 | how about a 375?
247 beq Lisa375 247 beq Lisa375
248 movl #HP_400,%a0@ | must be a 400 248 movl #HP_400,%a0@ | must be a 400
249 jra Lhaspac 249 jra Lhaspac
250Lisa36x: 250Lisa36x:
251 /* 251 /*
252 * If we found a 360, we need to check for a 362 (neither the 360 252 * If we found a 360, we need to check for a 362 (neither the 360
253 * nor the 362 have a nonzero mmuid). Since the 362 has a frodo 253 * nor the 362 have a nonzero mmuid). Since the 362 has a frodo
254 * utility chip in the DIO hole, check for it. 254 * utility chip in the DIO hole, check for it.
255 */ 255 */
256 movl #(INTIOBASE + FRODO_BASE),%a0 256 movl #(INTIOBASE + FRODO_BASE),%a0
257 ASRELOC(phys_badaddr,%a3) 257 ASRELOC(phys_badaddr,%a3)
258 jbsr %a3@ 258 jbsr %a3@
259 tstl %d0 | found a frodo? 259 tstl %d0 | found a frodo?
260 jne Lstart1 | no, really a 360 260 jne Lstart1 | no, really a 360
261 RELOC(machineid,%a0) 261 RELOC(machineid,%a0)
262 movl #HP_362,%a0@ 262 movl #HP_362,%a0@
263 jra Lstart1 263 jra Lstart1
264Lisa345: 264Lisa345:
265 movl #HP_345,%a0@ 265 movl #HP_345,%a0@
266 jra Lhaspac 266 jra Lhaspac
267Lisa375: 267Lisa375:
268 movl #HP_375,%a0@ 268 movl #HP_375,%a0@
269 jra Lhaspac 269 jra Lhaspac
270Lisa370: 270Lisa370:
271 movl #HP_370,%a0@ | set to 370 271 movl #HP_370,%a0@ | set to 370
272Lhaspac: 272Lhaspac:
273 RELOC(ectype, %a0) 273 RELOC(ectype, %a0)
274 movl #EC_PHYS,%a0@ | also has a physical address cache 274 movl #EC_PHYS,%a0@ | also has a physical address cache
275 jra Lstart1 275 jra Lstart1
276 276
277 /* 277 /*
278 * End of 68030 section 278 * End of 68030 section
279 */ 279 */
280 280
281Lnot68030: 281Lnot68030:
282 bset #31,%d0 | data cache enable bit 282 bset #31,%d0 | data cache enable bit
283 movc %d0,%cacr | only exists on 68040 283 movc %d0,%cacr | only exists on 68040
284 movc %cacr,%d0 | read it back 284 movc %cacr,%d0 | read it back
285 tstl %d0 | zero? 285 tstl %d0 | zero?
286 beq Lis68020 | yes, we have 68020 286 beq Lis68020 | yes, we have 68020
287 moveq #0,%d0 | now turn it back off 287 moveq #0,%d0 | now turn it back off
288 movec %d0,%cacr | before we access any data 288 movec %d0,%cacr | before we access any data
289 289
290 /* 290 /*
291 * 68040 models 291 * 68040 models
292 */ 292 */
293 293
294 RELOC(mmutype, %a0) 294 RELOC(mmutype, %a0)
295 movl #MMU_68040,%a0@ | with a 68040 MMU 295 movl #MMU_68040,%a0@ | with a 68040 MMU
296 RELOC(cputype, %a0) 296 RELOC(cputype, %a0)
297 movl #CPU_68040,%a0@ | and a 68040 CPU 297 movl #CPU_68040,%a0@ | and a 68040 CPU
298 RELOC(fputype, %a0) 298 RELOC(fputype, %a0)
299 movl #FPU_68040,%a0@ | ...and FPU 299 movl #FPU_68040,%a0@ | ...and FPU
300 RELOC(ectype, %a0) 300 RELOC(ectype, %a0)
301 movl #EC_NONE,%a0@ | and no cache (for now XXX) 301 movl #EC_NONE,%a0@ | and no cache (for now XXX)
302 RELOC(mmuid,%a0) | save MMU ID 302 RELOC(mmuid,%a0) | save MMU ID
303 movl %a1@(MMUCMD),%d0 303 movl %a1@(MMUCMD),%d0
304 lsrl #MMUID_SHIFT,%d0 304 lsrl #MMUID_SHIFT,%d0
305 andl #MMUID_MASK,%d0 305 andl #MMUID_MASK,%d0
306 movl %d0,%a0@ 306 movl %d0,%a0@
307 RELOC(machineid, %a0) 307 RELOC(machineid, %a0)
308 cmpb #MMUID_425_T,%d0 | are we a 425t? 308 cmpb #MMUID_425_T,%d0 | are we a 425t?
309 jeq Lisa425 309 jeq Lisa425
310 cmpb #MMUID_425_S,%d0 | how about 425s? 310 cmpb #MMUID_425_S,%d0 | how about 425s?
311 jeq Lisa425 311 jeq Lisa425
312 cmpb #MMUID_425_E,%d0 | or maybe a 425e? 312 cmpb #MMUID_425_E,%d0 | or maybe a 425e?
313 jeq Lisa425 313 jeq Lisa425
314 cmpb #MMUID_433_T,%d0 | or a 433t? 314 cmpb #MMUID_433_T,%d0 | or a 433t?
315 jeq Lisa433 315 jeq Lisa433
316 cmpb #MMUID_433_S,%d0 | or a 433s? 316 cmpb #MMUID_433_S,%d0 | or a 433s?
317 jeq Lisa433 317 jeq Lisa433
318 cmpb #MMUID_385,%d0 | or a 385? 318 cmpb #MMUID_385,%d0 | or a 385?
319 jeq Lisa385 319 jeq Lisa385
320 cmpb #MMUID_382,%d0 | or a 382? 320 cmpb #MMUID_382,%d0 | or a 382?
321 jeq Lisa382 321 jeq Lisa382
322 movl #HP_380,%a0@ | guess we're a 380 322 movl #HP_380,%a0@ | guess we're a 380
323 jra Lstart1 323 jra Lstart1
324Lisa425: 324Lisa425:
325 movl #HP_425,%a0@ 325 movl #HP_425,%a0@
326 jra Lstart1 326 jra Lstart1
327Lisa433: 327Lisa433:
328 movl #HP_433,%a0@ 328 movl #HP_433,%a0@
329 jra Lstart1 329 jra Lstart1
330Lisa385: 330Lisa385:
331 movl #HP_385,%a0@ 331 movl #HP_385,%a0@
332 jra Lstart1 332 jra Lstart1
333Lisa382: 333Lisa382:
334 movl #HP_382,%a0@ 334 movl #HP_382,%a0@
335 jra Lstart1 335 jra Lstart1
336 336
337 /* 337 /*
338 * End of 68040 section 338 * End of 68040 section
339 */ 339 */
340 340
341 /* 341 /*
342 * 68020 models 342 * 68020 models
343 */ 343 */
344 344
345Lis68020: 345Lis68020:
346 RELOC(fputype, %a0) | all of the 68020 systems 346 RELOC(fputype, %a0) | all of the 68020 systems
347 movl #FPU_68881,%a0@ | have a 68881 FPU 347 movl #FPU_68881,%a0@ | have a 68881 FPU
348 movl #1,%a1@(MMUCMD) | a 68020, write HP MMU location 348 movl #1,%a1@(MMUCMD) | a 68020, write HP MMU location
349 movl %a1@(MMUCMD),%d0 | read it back 349 movl %a1@(MMUCMD),%d0 | read it back
350 btst #0,%d0 | non-zero? 350 btst #0,%d0 | non-zero?
351 jne Lishpmmu | yes, we have HP MMU 351 jne Lishpmmu | yes, we have HP MMU
352 RELOC(mmutype, %a0) 352 RELOC(mmutype, %a0)
353 movl #MMU_68851,%a0@ | no, we have PMMU 353 movl #MMU_68851,%a0@ | no, we have PMMU
354 RELOC(machineid, %a0) 354 RELOC(machineid, %a0)
355 movl #HP_330,%a0@ | and 330 CPU 355 movl #HP_330,%a0@ | and 330 CPU
356 jra Lstart1 356 jra Lstart1
357Lishpmmu: 357Lishpmmu:
358 RELOC(ectype, %a0) | 320 or 350 358 RELOC(ectype, %a0) | 320 or 350
359 movl #EC_VIRT,%a0@ | both have a virtual address cache 359 movl #EC_VIRT,%a0@ | both have a virtual address cache
360 movl #0x80,%a1@(MMUCMD) | set magic cookie 360 movl #0x80,%a1@(MMUCMD) | set magic cookie
361 movl %a1@(MMUCMD),%d0 | read it back 361 movl %a1@(MMUCMD),%d0 | read it back
362 btst #7,%d0 | cookie still on? 362 btst #7,%d0 | cookie still on?
363 jeq Lis320 | no, just a 320 363 jeq Lis320 | no, just a 320
364 RELOC(machineid, %a0) 364 RELOC(machineid, %a0)
365 movl #HP_350,%a0@ | yes, a 350 365 movl #HP_350,%a0@ | yes, a 350
366 jra Lstart1 366 jra Lstart1
367Lis320: 367Lis320:
368 RELOC(machineid, %a0) 368 RELOC(machineid, %a0)
369 movl #HP_320,%a0@ 369 movl #HP_320,%a0@
370 370
371 /* 371 /*
372 * End of 68020 section 372 * End of 68020 section
373 */ 373 */
374 374
375Lstart1: 375Lstart1:
376 /* 376 /*
377 * Now that we know what CPU we have, initialize the address error 377 * Now that we know what CPU we have, initialize the address error
378 * and bus error handlers in the vector table: 378 * and bus error handlers in the vector table:
379 * 379 *
380 * vectab+8 bus error 380 * vectab+8 bus error
381 * vectab+12 address error 381 * vectab+12 address error
382 */ 382 */
383 RELOC(cputype, %a0) 383 RELOC(cputype, %a0)
384#if 0 384#if 0
385 /* XXX assembler/linker feature/bug */ 385 /* XXX assembler/linker feature/bug */
386 RELOC(vectab, %a2) 386 RELOC(vectab, %a2)
387#else 387#else
388 movl #_C_LABEL(vectab),%a2 388 movl #_C_LABEL(vectab),%a2
389 addl %a5,%a2 389 addl %a5,%a2
390#endif 390#endif
391#if defined(M68040) 391#if defined(M68040)
392 cmpl #CPU_68040,%a0@ | 68040? 392 cmpl #CPU_68040,%a0@ | 68040?
393 jne 1f | no, skip 393 jne 1f | no, skip
394 movl #_C_LABEL(buserr40),%a2@(8) 394 movl #_C_LABEL(buserr40),%a2@(8)
395 movl #_C_LABEL(addrerr4060),%a2@(12) 395 movl #_C_LABEL(addrerr4060),%a2@(12)
396 jra Lstart2 396 jra Lstart2
3971: 3971:
398#endif 398#endif
399#if defined(M68020) || defined(M68030) 399#if defined(M68020) || defined(M68030)
400 cmpl #CPU_68040,%a0@ | 68040? 400 cmpl #CPU_68040,%a0@ | 68040?
401 jeq 1f | yes, skip 401 jeq 1f | yes, skip
402 movl #_C_LABEL(busaddrerr2030),%a2@(8) 402 movl #_C_LABEL(busaddrerr2030),%a2@(8)
403 movl #_C_LABEL(busaddrerr2030),%a2@(12) 403 movl #_C_LABEL(busaddrerr2030),%a2@(12)
404 jra Lstart2 404 jra Lstart2
4051: 4051:
406#endif 406#endif
407 /* Config botch; no hope. */ 407 /* Config botch; no hope. */
408 DOREBOOT 408 DOREBOOT
409 409
410Lstart2: 410Lstart2:
411 movl #0,%a1@(MMUCMD) | clear out MMU again 411 movl #0,%a1@(MMUCMD) | clear out MMU again
412/* initialize source/destination control registers for movs */ 412/* initialize source/destination control registers for movs */
413 moveq #FC_USERD,%d0 | user space 413 moveq #FC_USERD,%d0 | user space
414 movc %d0,%sfc | as source 414 movc %d0,%sfc | as source
415 movc %d0,%dfc | and destination of transfers 415 movc %d0,%dfc | and destination of transfers
416/* initialize memory sizes (for pmap_bootstrap) */ 416/* initialize memory sizes (for pmap_bootstrap) */
417 movl #MAXADDR,%d1 | last page 417 movl #MAXADDR,%d1 | last page
418 moveq #PGSHIFT,%d2 418 moveq #PGSHIFT,%d2
419 lsrl %d2,%d1 | convert to page (click) number 419 lsrl %d2,%d1 | convert to page (click) number
420 RELOC(maxmem, %a0) 420 RELOC(maxmem, %a0)
421 movl %d1,%a0@ | save as maxmem 421 movl %d1,%a0@ | save as maxmem
422 movl %a5,%d0 | lowram value from ROM via boot 422 movl %a5,%d0 | lowram value from ROM via boot
423 lsrl %d2,%d0 | convert to page number 423 lsrl %d2,%d0 | convert to page number
424 subl %d0,%d1 | compute amount of RAM present 424 subl %d0,%d1 | compute amount of RAM present
425 RELOC(physmem, %a0) 425 RELOC(physmem, %a0)
426 movl %d1,%a0@ | and physmem 426 movl %d1,%a0@ | and physmem
427 427
428/* configure kernel and lwp0 VA space so we can get going */ 428/* configure kernel and lwp0 VA space so we can get going */
429#if NKSYMS || defined(DDB) || defined(LKM) 429#if NKSYMS || defined(DDB) || defined(LKM)
430 RELOC(esym,%a0) | end of static kernel test/data/syms 430 RELOC(esym,%a0) | end of static kernel test/data/syms
431 movl %a0@,%d5 431 movl %a0@,%d5
432 jne Lstart3 432 jne Lstart3
433#endif 433#endif
434 movl #_C_LABEL(end),%d5 | end of static kernel text/data 434 movl #_C_LABEL(end),%d5 | end of static kernel text/data
435Lstart3: 435Lstart3:
436 addl #PAGE_SIZE-1,%d5 436 addl #PAGE_SIZE-1,%d5
437 andl #PG_FRAME,%d5 | round to a page 437 andl #PG_FRAME,%d5 | round to a page
438 movl %d5,%a4 438 movl %d5,%a4
439 addl %a5,%a4 | convert to PA 439 addl %a5,%a4 | convert to PA
440 pea %a5@ | firstpa 440 pea %a5@ | firstpa
441 pea %a4@ | nextpa 441 pea %a4@ | nextpa
442 RELOC(pmap_bootstrap,%a0) 442 RELOC(pmap_bootstrap,%a0)
443 jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) 443 jbsr %a0@ | pmap_bootstrap(firstpa, nextpa)
444 addql #8,%sp 444 addql #8,%sp
445 445
446/* 446/*
447 * Prepare to enable MMU. 447 * Prepare to enable MMU.
448 * Since the kernel is not mapped logical == physical we must insure 448 * Since the kernel is not mapped logical == physical we must insure
449 * that when the MMU is turned on, all prefetched addresses (including 449 * that when the MMU is turned on, all prefetched addresses (including
450 * the PC) are valid. In order guarantee that, we use the last physical 450 * the PC) are valid. In order guarantee that, we use the last physical
451 * page (which is conveniently mapped == VA) and load it up with enough 451 * page (which is conveniently mapped == VA) and load it up with enough
452 * code to defeat the prefetch, then we execute the jump back to here. 452 * code to defeat the prefetch, then we execute the jump back to here.
453 * 453 *
454 * Is this all really necessary, or am I paranoid?? 454 * Is this all really necessary, or am I paranoid??
455 */ 455 */
456 RELOC(Sysseg, %a0) | system segment table addr 456 RELOC(Sysseg, %a0) | system segment table addr
457 movl %a0@,%d1 | read value (a KVA) 457 movl %a0@,%d1 | read value (a KVA)
458 addl %a5,%d1 | convert to PA 458 addl %a5,%d1 | convert to PA
459 RELOC(mmutype, %a0) 459 RELOC(mmutype, %a0)
460 tstl %a0@ | HP MMU? 460 tstl %a0@ | HP MMU?
461 jeq Lhpmmu2 | yes, skip 461 jeq Lhpmmu2 | yes, skip
462 cmpl #MMU_68040,%a0@ | 68040? 462 cmpl #MMU_68040,%a0@ | 68040?
463 jne Lmotommu1 | no, skip 463 jne Lmotommu1 | no, skip
464 .long 0x4e7b1807 | movc %d1,%srp 464 .long 0x4e7b1807 | movc %d1,%srp
465 jra Lstploaddone 465 jra Lstploaddone
466Lmotommu1: 466Lmotommu1:
467 RELOC(protorp, %a0) 467 RELOC(protorp, %a0)
468 movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs 468 movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs
469 movl %d1,%a0@(4) | + segtable address 469 movl %d1,%a0@(4) | + segtable address
470 pmove %a0@,%srp | load the supervisor root pointer 470 pmove %a0@,%srp | load the supervisor root pointer
471 movl #0x80000002,%a0@ | reinit upper half for CRP loads 471 movl #0x80000002,%a0@ | reinit upper half for CRP loads
472 jra Lstploaddone | done 472 jra Lstploaddone | done
473Lhpmmu2: 473Lhpmmu2:
474 moveq #PGSHIFT,%d2 474 moveq #PGSHIFT,%d2
475 lsrl %d2,%d1 | convert to page frame 475 lsrl %d2,%d1 | convert to page frame
476 movl %d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register 476 movl %d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register
477Lstploaddone: 477Lstploaddone:
478 lea MAXADDR,%a2 | PA of last RAM page 478 lea MAXADDR,%a2 | PA of last RAM page
479#if 0 479#if 0
480 ASRELOC(Lhighcode, %a1) | addr of high code 480 ASRELOC(Lhighcode, %a1) | addr of high code
481 ASRELOC(Lehighcode, %a3) | end addr 481 ASRELOC(Lehighcode, %a3) | end addr
482#else 482#else
483 /* don't want pc-relative addressing */ 483 /* don't want pc-relative addressing */
484 .word 0x43f9 | lea Lhighcode, %a1 484 .word 0x43f9 | lea Lhighcode, %a1
485 .long Lhighcode 485 .long Lhighcode
486 addl %a5, %a1 486 addl %a5, %a1
487 .word 0x47f9 | lea Lehighcode, %a3 487 .word 0x47f9 | lea Lehighcode, %a3
488 .long Lehighcode 488 .long Lehighcode
489 addl %a5, %a3 489 addl %a5, %a3
490#endif 490#endif
491Lcodecopy: 491Lcodecopy:
492 movw %a1@+,%a2@+ | copy a word 492 movw %a1@+,%a2@+ | copy a word
493 cmpl %a3,%a1 | done yet? 493 cmpl %a3,%a1 | done yet?
494 jcs Lcodecopy | no, keep going 494 jcs Lcodecopy | no, keep going
495 jmp MAXADDR | go for it! 495 jmp MAXADDR | go for it!
496 496
497 /* 497 /*
498 * BEGIN MMU TRAMPOLINE. This section of code is not 498 * BEGIN MMU TRAMPOLINE. This section of code is not
499 * executed in-place. It's copied to the last page 499 * executed in-place. It's copied to the last page
500 * of RAM (mapped va == pa) and executed there. 500 * of RAM (mapped va == pa) and executed there.
501 */ 501 */
502 502
503Lhighcode: 503Lhighcode:
504 /* 504 /*
505 * Set up the vector table, and race to get the MMU 505 * Set up the vector table, and race to get the MMU
506 * enabled. 506 * enabled.
507 */ 507 */
508 movl #_C_LABEL(vectab),%d0 | set Vector Base Register 508 movl #_C_LABEL(vectab),%d0 | set Vector Base Register
509 movc %d0,%vbr 509 movc %d0,%vbr
510 510
511 RELOC(mmutype, %a0) 511 RELOC(mmutype, %a0)
512 tstl %a0@ | HP MMU? 512 tstl %a0@ | HP MMU?
513 jeq Lhpmmu3 | yes, skip 513 jeq Lhpmmu3 | yes, skip
514 cmpl #MMU_68040,%a0@ | 68040? 514 cmpl #MMU_68040,%a0@ | 68040?
515 jne Lmotommu2 | no, skip 515 jne Lmotommu2 | no, skip
516 movw #0,INTIOBASE+MMUBASE+MMUCMD+2 516 movw #0,INTIOBASE+MMUBASE+MMUCMD+2
517 movw #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2 517 movw #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2
518 | enable FPU and caches 518 | enable FPU and caches
519 moveq #0,%d0 | ensure TT regs are disabled 519 moveq #0,%d0 | ensure TT regs are disabled
520 .long 0x4e7b0004 | movc %d0,%itt0 520 .long 0x4e7b0004 | movc %d0,%itt0
521 .long 0x4e7b0005 | movc %d0,%itt1 521 .long 0x4e7b0005 | movc %d0,%itt1
522 .long 0x4e7b0006 | movc %d0,%dtt0 522 .long 0x4e7b0006 | movc %d0,%dtt0
523 .long 0x4e7b0007 | movc %d0,%dtt1 523 .long 0x4e7b0007 | movc %d0,%dtt1
524 .word 0xf4d8 | cinva bc 524 .word 0xf4d8 | cinva bc
525 .word 0xf518 | pflusha 525 .word 0xf518 | pflusha
526 movl #0x8000,%d0 526 movl #0x8000,%d0
527 .long 0x4e7b0003 | movc %d0,%tc 527 .long 0x4e7b0003 | movc %d0,%tc
528 movl #0x80008000,%d0 528 movl #0x80008000,%d0
529 movc %d0,%cacr | turn on both caches 529 movc %d0,%cacr | turn on both caches
530 jmp Lenab1:l | forced not be pc-relative 530 jmp Lenab1:l | forced not be pc-relative
531Lmotommu2: 531Lmotommu2:
532 movl #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD 532 movl #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD
533 | enable 68881 and i-cache 533 | enable 68881 and i-cache
534 RELOC(prototc, %a2) 534 RELOC(prototc, %a2)
535 movl #0x82c0aa00,%a2@ | value to load TC with 535 movl #0x82c0aa00,%a2@ | value to load TC with
536 pmove %a2@,%tc | load it 536 pmove %a2@,%tc | load it
537 jmp Lenab1:l | forced not be pc-relative 537 jmp Lenab1:l | forced not be pc-relative
538Lhpmmu3: 538Lhpmmu3:
539 movl #0,INTIOBASE+MMUBASE+MMUCMD | clear external cache 539 movl #0,INTIOBASE+MMUBASE+MMUCMD | clear external cache
540 movl #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU 540 movl #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU
541 jmp Lenab1:l | forced not be pc-relative 541 jmp Lenab1:l | forced not be pc-relative
542Lehighcode: 542Lehighcode:
543 543
544 /* 544 /*
545 * END MMU TRAMPOLINE. Address register %a5 is now free. 545 * END MMU TRAMPOLINE. Address register %a5 is now free.
546 */ 546 */
547 547
548/* 548/*
549 * Should be running mapped from this point on 549 * Should be running mapped from this point on
550 */ 550 */
551Lenab1: 551Lenab1:
552/* select the software page size now */ 552/* select the software page size now */
553 lea _ASM_LABEL(tmpstk),%sp | temporary stack 553 lea _ASM_LABEL(tmpstk),%sp | temporary stack
554 jbsr _C_LABEL(uvm_setpagesize) | select software page size 554 jbsr _C_LABEL(uvm_setpagesize) | select software page size
555/* set kernel stack, user SP, and initial pcb */ 555/* call final pmap setup which initialize lwp0, curlwp, and curpcb */
556 lea _C_LABEL(lwp0),%a2 | grab lwp0.l_addr 556 jbsr _C_LABEL(pmap_bootstrap_finalize)
557 movl %a2@(L_ADDR),%a1 | set kernel stack to end of area  557/* set kernel stack, user SP */
558 lea %a1@(USPACE-4),%sp | and curlwp so that we don't 558 movl _C_LABEL(lwp0uarea),%a1 |
559 movl %a2,_C_LABEL(curlwp) | deref NULL in trap() 559 lea %a1@(USPACE-4),%sp | set kernel stack to end of area
560 movl #USRSTACK-4,%a2 560 movl #USRSTACK-4,%a2
561 movl %a2,%usp | init user SP 561 movl %a2,%usp | init user SP
562 movl %a1,_C_LABEL(curpcb) | lwp0 is running 
563 562
564 tstl _C_LABEL(fputype) | Have an FPU? 563 tstl _C_LABEL(fputype) | Have an FPU?
565 jeq Lenab2 | No, skip. 564 jeq Lenab2 | No, skip.
566 clrl %a1@(PCB_FPCTX) | ensure null FP context 565 clrl %a1@(PCB_FPCTX) | ensure null FP context
567 movl %a1,%sp@- 566 movl %a1,%sp@-
568 jbsr _C_LABEL(m68881_restore) | restore it (does not kill %a1) 567 jbsr _C_LABEL(m68881_restore) | restore it (does not kill %a1)
569 addql #4,%sp 568 addql #4,%sp
570Lenab2: 569Lenab2:
571/* flush TLB and turn on caches */ 570/* flush TLB and turn on caches */
572 jbsr _C_LABEL(_TBIA) | invalidate TLB 571 jbsr _C_LABEL(_TBIA) | invalidate TLB
573 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 572 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
574 jeq Lnocache0 | yes, cache already on 573 jeq Lnocache0 | yes, cache already on
575 movl #CACHE_ON,%d0 574 movl #CACHE_ON,%d0
576 movc %d0,%cacr | clear cache(s) 575 movc %d0,%cacr | clear cache(s)
577 tstl _C_LABEL(ectype) 576 tstl _C_LABEL(ectype)
578 jeq Lnocache0 577 jeq Lnocache0
579 MMUADDR(%a0) 578 MMUADDR(%a0)
580 orl #MMU_CEN,%a0@(MMUCMD) | turn on external cache 579 orl #MMU_CEN,%a0@(MMUCMD) | turn on external cache
581Lnocache0: 580Lnocache0:
582/* Final setup for call to main(). */ 581/* Final setup for call to main(). */
583 jbsr _C_LABEL(hp300_init) 582 jbsr _C_LABEL(hp300_init)
584 583
585/* 584/*
586 * Create a fake exception frame so that cpu_fork() can copy it. 585 * Create a fake exception frame so that cpu_fork() can copy it.
587 * main() nevers returns; we exit to user mode from a forked process 586 * main() nevers returns; we exit to user mode from a forked process
588 * later on. 587 * later on.
589 */ 588 */
590 clrw %sp@- | vector offset/frame type 589 clrw %sp@- | vector offset/frame type
591 clrl %sp@- | PC - filled in by "execve" 590 clrl %sp@- | PC - filled in by "execve"
592 movw #PSL_USER,%sp@- | in user mode 591 movw #PSL_USER,%sp@- | in user mode
593 clrl %sp@- | stack adjust count and padding 592 clrl %sp@- | stack adjust count and padding
594 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 593 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7
595 lea _C_LABEL(lwp0),%a0 | save pointer to frame 594 lea _C_LABEL(lwp0),%a0 | save pointer to frame
596 movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs 595 movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs
597 596
598 jra _C_LABEL(main) | main() 597 jra _C_LABEL(main) | main()
599 PANIC("main() returned") 598 PANIC("main() returned")
600 /* NOTREACHED */ 599 /* NOTREACHED */
601 600
602/* 601/*
603 * Trap/interrupt vector routines 602 * Trap/interrupt vector routines
604 */  603 */
605#include <m68k/m68k/trap_subr.s> 604#include <m68k/m68k/trap_subr.s>
606 605
607 .data 606 .data
608GLOBAL(m68k_fault_addr) 607GLOBAL(m68k_fault_addr)
609 .long 0 608 .long 0
610 609
611#if defined(M68040) || defined(M68060) 610#if defined(M68040) || defined(M68060)
612ENTRY_NOPROFILE(addrerr4060) 611ENTRY_NOPROFILE(addrerr4060)
613 clrl %sp@- | stack adjust count 612 clrl %sp@- | stack adjust count
614 moveml #0xFFFF,%sp@- | save user registers 613 moveml #0xFFFF,%sp@- | save user registers
615 movl %usp,%a0 | save the user SP 614 movl %usp,%a0 | save the user SP
616 movl %a0,%sp@(FR_SP) | in the savearea 615 movl %a0,%sp@(FR_SP) | in the savearea
617 movl %sp@(FR_HW+8),%sp@- 616 movl %sp@(FR_HW+8),%sp@-
618 clrl %sp@- | dummy code 617 clrl %sp@- | dummy code
619 movl #T_ADDRERR,%sp@- | mark address error 618 movl #T_ADDRERR,%sp@- | mark address error
620 jra _ASM_LABEL(faultstkadj) | and deal with it 619 jra _ASM_LABEL(faultstkadj) | and deal with it
621#endif 620#endif
622 621
623#if defined(M68060) 622#if defined(M68060)
624ENTRY_NOPROFILE(buserr60) 623ENTRY_NOPROFILE(buserr60)
625 clrl %sp@- | stack adjust count 624 clrl %sp@- | stack adjust count
626 moveml #0xFFFF,%sp@- | save user registers 625 moveml #0xFFFF,%sp@- | save user registers
627 movl %usp,%a0 | save the user SP 626 movl %usp,%a0 | save the user SP
628 movl %a0,%sp@(FR_SP) | in the savearea 627 movl %a0,%sp@(FR_SP) | in the savearea
629 movel %sp@(FR_HW+12),%d0 | FSLW 628 movel %sp@(FR_HW+12),%d0 | FSLW
630 btst #2,%d0 | branch prediction error? 629 btst #2,%d0 | branch prediction error?
631 jeq Lnobpe 630 jeq Lnobpe
632 movc %cacr,%d2 631 movc %cacr,%d2
633 orl #IC60_CABC,%d2 | clear all branch cache entries 632 orl #IC60_CABC,%d2 | clear all branch cache entries
634 movc %d2,%cacr 633 movc %d2,%cacr
635 movl %d0,%d1 634 movl %d0,%d1
636 addql #1,L60bpe 635 addql #1,L60bpe
637 andl #0x7ffd,%d1 636 andl #0x7ffd,%d1
638 jeq _ASM_LABEL(faultstkadjnotrap2) 637 jeq _ASM_LABEL(faultstkadjnotrap2)
639Lnobpe: 638Lnobpe:
640| we need to adjust for misaligned addresses 639| we need to adjust for misaligned addresses
641 movl %sp@(FR_HW+8),%d1 | grab VA 640 movl %sp@(FR_HW+8),%d1 | grab VA
642 btst #27,%d0 | check for mis-aligned access 641 btst #27,%d0 | check for mis-aligned access
643 jeq Lberr3 | no, skip 642 jeq Lberr3 | no, skip
644 addl #28,%d1 | yes, get into next page 643 addl #28,%d1 | yes, get into next page
645 | operand case: 3, 644 | operand case: 3,
646 | instruction case: 4+12+12 645 | instruction case: 4+12+12
647 andl #PG_FRAME,%d1 | and truncate 646 andl #PG_FRAME,%d1 | and truncate
648Lberr3: 647Lberr3:
649 movl %d1,%sp@- 648 movl %d1,%sp@-
650 movl %d0,%sp@- | code is FSLW now. 649 movl %d0,%sp@- | code is FSLW now.
651 andw #0x1f80,%d0  650 andw #0x1f80,%d0
652 jeq Lberr60 | it is a bus error 651 jeq Lberr60 | it is a bus error
653 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 652 movl #T_MMUFLT,%sp@- | show that we are an MMU fault
654 jra _ASM_LABEL(faultstkadj) | and deal with it 653 jra _ASM_LABEL(faultstkadj) | and deal with it
655Lberr60: 654Lberr60:
656 tstl _C_LABEL(nofault) | catch bus error? 655 tstl _C_LABEL(nofault) | catch bus error?
657 jeq Lisberr | no, handle as usual 656 jeq Lisberr | no, handle as usual
658 movl %sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr 657 movl %sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr
659 movl _C_LABEL(nofault),%sp@- | yes, 658 movl _C_LABEL(nofault),%sp@- | yes,
660 jbsr _C_LABEL(longjmp) | longjmp(nofault) 659 jbsr _C_LABEL(longjmp) | longjmp(nofault)
661 /* NOTREACHED */ 660 /* NOTREACHED */
662#endif 661#endif
663#if defined(M68040) 662#if defined(M68040)
664ENTRY_NOPROFILE(buserr40) 663ENTRY_NOPROFILE(buserr40)
665 clrl %sp@- | stack adjust count 664 clrl %sp@- | stack adjust count
666 moveml #0xFFFF,%sp@- | save user registers 665 moveml #0xFFFF,%sp@- | save user registers
667 movl %usp,%a0 | save the user SP 666 movl %usp,%a0 | save the user SP
668 movl %a0,%sp@(FR_SP) | in the savearea 667 movl %a0,%sp@(FR_SP) | in the savearea
669 movl %sp@(FR_HW+20),%d1 | get fault address 668 movl %sp@(FR_HW+20),%d1 | get fault address
670 moveq #0,%d0 669 moveq #0,%d0
671 movw %sp@(FR_HW+12),%d0 | get SSW 670 movw %sp@(FR_HW+12),%d0 | get SSW
672 btst #11,%d0 | check for mis-aligned 671 btst #11,%d0 | check for mis-aligned
673 jeq Lbe1stpg | no skip 672 jeq Lbe1stpg | no skip
674 addl #3,%d1 | get into next page 673 addl #3,%d1 | get into next page
675 andl #PG_FRAME,%d1 | and truncate 674 andl #PG_FRAME,%d1 | and truncate
676Lbe1stpg: 675Lbe1stpg:
677 movl %d1,%sp@- | pass fault address. 676 movl %d1,%sp@- | pass fault address.
678 movl %d0,%sp@- | pass SSW as code 677 movl %d0,%sp@- | pass SSW as code
679 btst #10,%d0 | test ATC 678 btst #10,%d0 | test ATC
680 jeq Lberr40 | it is a bus error 679 jeq Lberr40 | it is a bus error
681 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 680 movl #T_MMUFLT,%sp@- | show that we are an MMU fault
682 jra _ASM_LABEL(faultstkadj) | and deal with it 681 jra _ASM_LABEL(faultstkadj) | and deal with it
683Lberr40: 682Lberr40:
684 tstl _C_LABEL(nofault) | catch bus error? 683 tstl _C_LABEL(nofault) | catch bus error?
685 jeq Lisberr | no, handle as usual 684 jeq Lisberr | no, handle as usual
686 movl %sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr 685 movl %sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr
687 movl _C_LABEL(nofault),%sp@- | yes, 686 movl _C_LABEL(nofault),%sp@- | yes,
688 jbsr _C_LABEL(longjmp) | longjmp(nofault) 687 jbsr _C_LABEL(longjmp) | longjmp(nofault)
689 /* NOTREACHED */ 688 /* NOTREACHED */
690#endif 689#endif
691 690
692#if defined(M68020) || defined(M68030) 691#if defined(M68020) || defined(M68030)
693ENTRY_NOPROFILE(busaddrerr2030) 692ENTRY_NOPROFILE(busaddrerr2030)
694 clrl %sp@- | stack adjust count 693 clrl %sp@- | stack adjust count
695 moveml #0xFFFF,%sp@- | save user registers 694 moveml #0xFFFF,%sp@- | save user registers
696 movl %usp,%a0 | save the user SP 695 movl %usp,%a0 | save the user SP
697 movl %a0,%sp@(FR_SP) | in the savearea 696 movl %a0,%sp@(FR_SP) | in the savearea
698 moveq #0,%d0 697 moveq #0,%d0
699 movw %sp@(FR_HW+10),%d0 | grab SSW for fault processing 698 movw %sp@(FR_HW+10),%d0 | grab SSW for fault processing
700 btst #12,%d0 | RB set? 699 btst #12,%d0 | RB set?
701 jeq LbeX0 | no, test RC 700 jeq LbeX0 | no, test RC
702 bset #14,%d0 | yes, must set FB 701 bset #14,%d0 | yes, must set FB
703 movw %d0,%sp@(FR_HW+10) | for hardware too 702 movw %d0,%sp@(FR_HW+10) | for hardware too
704LbeX0: 703LbeX0:
705 btst #13,%d0 | RC set? 704 btst #13,%d0 | RC set?
706 jeq LbeX1 | no, skip 705 jeq LbeX1 | no, skip
707 bset #15,%d0 | yes, must set FC 706 bset #15,%d0 | yes, must set FC
708 movw %d0,%sp@(FR_HW+10) | for hardware too 707 movw %d0,%sp@(FR_HW+10) | for hardware too
709LbeX1: 708LbeX1:
710 btst #8,%d0 | data fault? 709 btst #8,%d0 | data fault?
711 jeq Lbe0 | no, check for hard cases 710 jeq Lbe0 | no, check for hard cases
712 movl %sp@(FR_HW+16),%d1 | fault address is as given in frame 711 movl %sp@(FR_HW+16),%d1 | fault address is as given in frame
713 jra Lbe10 | thats it 712 jra Lbe10 | thats it
714Lbe0: 713Lbe0:
715 btst #4,%sp@(FR_HW+6) | long (type B) stack frame? 714 btst #4,%sp@(FR_HW+6) | long (type B) stack frame?
716 jne Lbe4 | yes, go handle 715 jne Lbe4 | yes, go handle
717 movl %sp@(FR_HW+2),%d1 | no, can use save PC 716 movl %sp@(FR_HW+2),%d1 | no, can use save PC
718 btst #14,%d0 | FB set? 717 btst #14,%d0 | FB set?
719 jeq Lbe3 | no, try FC 718 jeq Lbe3 | no, try FC
720 addql #4,%d1 | yes, adjust address 719 addql #4,%d1 | yes, adjust address
721 jra Lbe10 | done 720 jra Lbe10 | done
722Lbe3: 721Lbe3:
723 btst #15,%d0 | FC set? 722 btst #15,%d0 | FC set?
724 jeq Lbe10 | no, done 723 jeq Lbe10 | no, done
725 addql #2,%d1 | yes, adjust address 724 addql #2,%d1 | yes, adjust address
726 jra Lbe10 | done 725 jra Lbe10 | done
727Lbe4: 726Lbe4:
728 movl %sp@(FR_HW+36),%d1 | long format, use stage B address 727 movl %sp@(FR_HW+36),%d1 | long format, use stage B address
729 btst #15,%d0 | FC set? 728 btst #15,%d0 | FC set?
730 jeq Lbe10 | no, all done 729 jeq Lbe10 | no, all done
731 subql #2,%d1 | yes, adjust address 730 subql #2,%d1 | yes, adjust address
732Lbe10: 731Lbe10:
733 movl %d1,%sp@- | push fault VA 732 movl %d1,%sp@- | push fault VA
734 movl %d0,%sp@- | and padded SSW 733 movl %d0,%sp@- | and padded SSW
735 movw %sp@(FR_HW+8+6),%d0 | get frame format/vector offset 734 movw %sp@(FR_HW+8+6),%d0 | get frame format/vector offset
736 andw #0x0FFF,%d0 | clear out frame format 735 andw #0x0FFF,%d0 | clear out frame format
737 cmpw #12,%d0 | address error vector? 736 cmpw #12,%d0 | address error vector?
738 jeq Lisaerr | yes, go to it 737 jeq Lisaerr | yes, go to it
739#if defined(M68K_MMU_MOTOROLA) 738#if defined(M68K_MMU_MOTOROLA)
740#if defined(M68K_MMU_HP) 739#if defined(M68K_MMU_HP)
741 tstl _C_LABEL(mmutype) | HP MMU? 740 tstl _C_LABEL(mmutype) | HP MMU?
742 jeq Lbehpmmu | yes, different MMU fault handler 741 jeq Lbehpmmu | yes, different MMU fault handler
743#endif 742#endif
744 movl %d1,%a0 | fault address 743 movl %d1,%a0 | fault address
745 movl %sp@,%d0 | function code from ssw 744 movl %sp@,%d0 | function code from ssw
746 btst #8,%d0 | data fault? 745 btst #8,%d0 | data fault?
747 jne Lbe10a 746 jne Lbe10a
748 movql #1,%d0 | user program access FC 747 movql #1,%d0 | user program access FC
749 | (we dont separate data/program) 748 | (we dont separate data/program)
750 btst #5,%sp@(FR_HW+8) | supervisor mode? 749 btst #5,%sp@(FR_HW+8) | supervisor mode?
751 jeq Lbe10a | if no, done 750 jeq Lbe10a | if no, done
752 movql #5,%d0 | else supervisor program access 751 movql #5,%d0 | else supervisor program access
753Lbe10a: 752Lbe10a:
754 ptestr %d0,%a0@,#7 | do a table search 753 ptestr %d0,%a0@,#7 | do a table search
755 pmove %psr,%sp@ | save result 754 pmove %psr,%sp@ | save result
756 movb %sp@,%d1 755 movb %sp@,%d1
757 btst #2,%d1 | invalid (incl. limit viol. and berr)? 756 btst #2,%d1 | invalid (incl. limit viol. and berr)?
758 jeq Lmightnotbemerr | no -> wp check 757 jeq Lmightnotbemerr | no -> wp check
759 btst #7,%d1 | is it MMU table berr? 758 btst #7,%d1 | is it MMU table berr?
760 jne Lisberr1 | yes, needs not be fast. 759 jne Lisberr1 | yes, needs not be fast.
761#endif /* M68K_MMU_MOTOROLA */ 760#endif /* M68K_MMU_MOTOROLA */
762Lismerr: 761Lismerr:
763 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 762 movl #T_MMUFLT,%sp@- | show that we are an MMU fault
764 jra _ASM_LABEL(faultstkadj) | and deal with it 763 jra _ASM_LABEL(faultstkadj) | and deal with it
765#if defined(M68K_MMU_MOTOROLA) 764#if defined(M68K_MMU_MOTOROLA)
766Lmightnotbemerr: 765Lmightnotbemerr:
767 btst #3,%d1 | write protect bit set? 766 btst #3,%d1 | write protect bit set?
768 jeq Lisberr1 | no: must be bus error 767 jeq Lisberr1 | no: must be bus error
769 movl %sp@,%d0 | ssw into low word of %d0 768 movl %sp@,%d0 | ssw into low word of %d0
770 andw #0xc0,%d0 | Write protect is set on page: 769 andw #0xc0,%d0 | Write protect is set on page:
771 cmpw #0x40,%d0 | was it read cycle? 770 cmpw #0x40,%d0 | was it read cycle?
772 jne Lismerr | no, was not WPE, must be MMU fault 771 jne Lismerr | no, was not WPE, must be MMU fault
773 jra Lisberr1 | real bus err needs not be fast. 772 jra Lisberr1 | real bus err needs not be fast.
774#endif /* M68K_MMU_MOTOROLA */ 773#endif /* M68K_MMU_MOTOROLA */
775#if defined(M68K_MMU_HP) 774#if defined(M68K_MMU_HP)
776Lbehpmmu: 775Lbehpmmu:
777 MMUADDR(%a0) 776 MMUADDR(%a0)
778 movl %a0@(MMUSTAT),%d0 | read MMU status 777 movl %a0@(MMUSTAT),%d0 | read MMU status
779 btst #3,%d0 | MMU fault? 778 btst #3,%d0 | MMU fault?
780 jeq Lisberr1 | no, just a non-MMU bus error 779 jeq Lisberr1 | no, just a non-MMU bus error
781 andl #~MMU_FAULT,%a0@(MMUSTAT)| yes, clear fault bits 780 andl #~MMU_FAULT,%a0@(MMUSTAT)| yes, clear fault bits
782 movw %d0,%sp@ | pass MMU stat in upper half of code 781 movw %d0,%sp@ | pass MMU stat in upper half of code
783 jra Lismerr | and handle it 782 jra Lismerr | and handle it
784#endif 783#endif
785Lisaerr: 784Lisaerr:
786 movl #T_ADDRERR,%sp@- | mark address error 785 movl #T_ADDRERR,%sp@- | mark address error
787 jra _ASM_LABEL(faultstkadj) | and deal with it 786 jra _ASM_LABEL(faultstkadj) | and deal with it
788Lisberr1: 787Lisberr1:
789 clrw %sp@ | re-clear pad word 788 clrw %sp@ | re-clear pad word
790 tstl _C_LABEL(nofault) | catch bus error? 789 tstl _C_LABEL(nofault) | catch bus error?
791 jeq Lisberr | no, handle as usual 790 jeq Lisberr | no, handle as usual
792 movl %sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr 791 movl %sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr
793 movl _C_LABEL(nofault),%sp@- | yes, 792 movl _C_LABEL(nofault),%sp@- | yes,
794 jbsr _C_LABEL(longjmp) | longjmp(nofault) 793 jbsr _C_LABEL(longjmp) | longjmp(nofault)
795 /* NOTREACHED */ 794 /* NOTREACHED */
796#endif /* M68020 || M68030 */ 795#endif /* M68020 || M68030 */
797 796
798Lisberr: | also used by M68040/60 797Lisberr: | also used by M68040/60
799 movl #T_BUSERR,%sp@- | mark bus error 798 movl #T_BUSERR,%sp@- | mark bus error
800 jra _ASM_LABEL(faultstkadj) | and deal with it 799 jra _ASM_LABEL(faultstkadj) | and deal with it
801 800
802/* 801/*
803 * FP exceptions. 802 * FP exceptions.
804 */ 803 */
805ENTRY_NOPROFILE(fpfline) 804ENTRY_NOPROFILE(fpfline)
806#if defined(M68040) 805#if defined(M68040)
807 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 806 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
808 jne Lfp_unimp | no, skip FPSP 807 jne Lfp_unimp | no, skip FPSP
809 cmpw #0x202c,%sp@(6) | format type 2? 808 cmpw #0x202c,%sp@(6) | format type 2?
810 jne _C_LABEL(illinst) | no, not an FP emulation 809 jne _C_LABEL(illinst) | no, not an FP emulation
811Ldofp_unimp: 810Ldofp_unimp:
812#ifdef FPSP 811#ifdef FPSP
813 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it 812 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it
814#endif 813#endif
815Lfp_unimp: 814Lfp_unimp:
816#endif /* M68040 */ 815#endif /* M68040 */
817#ifdef FPU_EMULATE 816#ifdef FPU_EMULATE
818 clrl %sp@- | stack adjust count 817 clrl %sp@- | stack adjust count
819 moveml #0xFFFF,%sp@- | save registers 818 moveml #0xFFFF,%sp@- | save registers
820 moveq #T_FPEMULI,%d0 | denote as FP emulation trap 819 moveq #T_FPEMULI,%d0 | denote as FP emulation trap
821 jra _ASM_LABEL(fault) | do it 820 jra _ASM_LABEL(fault) | do it
822#else 821#else
823 jra _C_LABEL(illinst) 822 jra _C_LABEL(illinst)
824#endif 823#endif
825 824
826ENTRY_NOPROFILE(fpunsupp) 825ENTRY_NOPROFILE(fpunsupp)
827#if defined(M68040) 826#if defined(M68040)
828 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 827 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
829 jne _C_LABEL(illinst) | no, treat as illinst 828 jne _C_LABEL(illinst) | no, treat as illinst
830#ifdef FPSP 829#ifdef FPSP
831 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it 830 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it
832#endif 831#endif
833Lfp_unsupp: 832Lfp_unsupp:
834#endif /* M68040 */ 833#endif /* M68040 */
835#ifdef FPU_EMULATE 834#ifdef FPU_EMULATE
836 clrl %sp@- | stack adjust count 835 clrl %sp@- | stack adjust count
837 moveml #0xFFFF,%sp@- | save registers 836 moveml #0xFFFF,%sp@- | save registers
838 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 837 moveq #T_FPEMULD,%d0 | denote as FP emulation trap
839 jra _ASM_LABEL(fault) | do it 838 jra _ASM_LABEL(fault) | do it
840#else 839#else
841 jra _C_LABEL(illinst) 840 jra _C_LABEL(illinst)
842#endif 841#endif
843 842
844/* 843/*
845 * Handles all other FP coprocessor exceptions. 844 * Handles all other FP coprocessor exceptions.
846 * Note that since some FP exceptions generate mid-instruction frames 845 * Note that since some FP exceptions generate mid-instruction frames
847 * and may cause signal delivery, we need to test for stack adjustment 846 * and may cause signal delivery, we need to test for stack adjustment
848 * after the trap call. 847 * after the trap call.
849 */ 848 */
850ENTRY_NOPROFILE(fpfault) 849ENTRY_NOPROFILE(fpfault)
851 clrl %sp@- | stack adjust count 850 clrl %sp@- | stack adjust count
852 moveml #0xFFFF,%sp@- | save user registers 851 moveml #0xFFFF,%sp@- | save user registers
853 movl %usp,%a0 | and save 852 movl %usp,%a0 | and save
854 movl %a0,%sp@(FR_SP) | the user stack pointer 853 movl %a0,%sp@(FR_SP) | the user stack pointer
855 clrl %sp@- | no VA arg 854 clrl %sp@- | no VA arg
856 movl _C_LABEL(curpcb),%a0 | current pcb 855 movl _C_LABEL(curpcb),%a0 | current pcb
857 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 856 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea
858 fsave %a0@ | save state 857 fsave %a0@ | save state
859#if defined(M68040) || defined(M68060) 858#if defined(M68040) || defined(M68060)
860 /* always null state frame on 68040, 68060 */ 859 /* always null state frame on 68040, 68060 */
861 cmpl #FPU_68040,_C_LABEL(fputype) 860 cmpl #FPU_68040,_C_LABEL(fputype)
862 jge Lfptnull 861 jge Lfptnull
863#endif 862#endif
864 tstb %a0@ | null state frame? 863 tstb %a0@ | null state frame?
865 jeq Lfptnull | yes, safe 864 jeq Lfptnull | yes, safe
866 clrw %d0 | no, need to tweak BIU 865 clrw %d0 | no, need to tweak BIU
867 movb %a0@(1),%d0 | get frame size 866 movb %a0@(1),%d0 | get frame size
868 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 867 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU
869Lfptnull: 868Lfptnull:
870 fmovem %fpsr,%sp@- | push %fpsr as code argument 869 fmovem %fpsr,%sp@- | push %fpsr as code argument
871 frestore %a0@ | restore state 870 frestore %a0@ | restore state
872 movl #T_FPERR,%sp@- | push type arg 871 movl #T_FPERR,%sp@- | push type arg
873 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 872 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
874 873
875/* 874/*
876 * Other exceptions only cause four and six word stack frame and require 875 * Other exceptions only cause four and six word stack frame and require
877 * no post-trap stack adjustment. 876 * no post-trap stack adjustment.
878 */ 877 */
879 878
880ENTRY_NOPROFILE(badtrap) 879ENTRY_NOPROFILE(badtrap)
881 moveml #0xC0C0,%sp@- | save scratch regs 880 moveml #0xC0C0,%sp@- | save scratch regs
882 movw %sp@(22),%sp@- | push exception vector info 881 movw %sp@(22),%sp@- | push exception vector info
883 clrw %sp@- 882 clrw %sp@-
884 movl %sp@(22),%sp@- | and PC 883 movl %sp@(22),%sp@- | and PC
885 jbsr _C_LABEL(straytrap) | report 884 jbsr _C_LABEL(straytrap) | report
886 addql #8,%sp | pop args 885 addql #8,%sp | pop args
887 moveml %sp@+,#0x0303 | restore regs 886 moveml %sp@+,#0x0303 | restore regs
888 jra _ASM_LABEL(rei) | all done 887 jra _ASM_LABEL(rei) | all done
889 888
890ENTRY_NOPROFILE(trap0) 889ENTRY_NOPROFILE(trap0)
891 clrl %sp@- | stack adjust count 890 clrl %sp@- | stack adjust count
892 moveml #0xFFFF,%sp@- | save user registers 891 moveml #0xFFFF,%sp@- | save user registers
893 movl %usp,%a0 | save the user SP 892 movl %usp,%a0 | save the user SP
894 movl %a0,%sp@(FR_SP) | in the savearea 893 movl %a0,%sp@(FR_SP) | in the savearea
895 movl %d0,%sp@- | push syscall number 894 movl %d0,%sp@- | push syscall number
896 jbsr _C_LABEL(syscall) | handle it 895 jbsr _C_LABEL(syscall) | handle it
897 addql #4,%sp | pop syscall arg 896 addql #4,%sp | pop syscall arg
898 tstl _C_LABEL(astpending) | AST pending? 897 tstl _C_LABEL(astpending) | AST pending?
899 jne Lrei | yes, handle it via trap 898 jne Lrei | yes, handle it via trap
900 movl %sp@(FR_SP),%a0 | grab and restore 899 movl %sp@(FR_SP),%a0 | grab and restore
901 movl %a0,%usp | user SP 900 movl %a0,%usp | user SP
902 moveml %sp@+,#0x7FFF | restore most registers 901 moveml %sp@+,#0x7FFF | restore most registers
903 addql #8,%sp | pop SP and stack adjust 902 addql #8,%sp | pop SP and stack adjust
904 rte 903 rte
905 904
906/* 905/*
907 * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) 906 * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
908 * cachectl(command, addr, length) 907 * cachectl(command, addr, length)
909 * command in %d0, addr in %a1, length in %d1 908 * command in %d0, addr in %a1, length in %d1
910 */ 909 */
911ENTRY_NOPROFILE(trap12) 910ENTRY_NOPROFILE(trap12)
912 movl _C_LABEL(curlwp),%a0 911 movl _C_LABEL(curlwp),%a0
913 movl %a0@(L_PROC),%sp@- | push current proc pointer 912 movl %a0@(L_PROC),%sp@- | push current proc pointer
914 movl %d1,%sp@- | push length 913 movl %d1,%sp@- | push length
915 movl %a1,%sp@- | push addr 914 movl %a1,%sp@- | push addr
916 movl %d0,%sp@- | push command 915 movl %d0,%sp@- | push command
917 jbsr _C_LABEL(cachectl1) | do it 916 jbsr _C_LABEL(cachectl1) | do it
918 lea %sp@(16),%sp | pop args 917 lea %sp@(16),%sp | pop args
919 jra _ASM_LABEL(rei) | all done 918 jra _ASM_LABEL(rei) | all done
920 919
921/* 920/*
922 * Trace (single-step) trap. Kernel-mode is special. 921 * Trace (single-step) trap. Kernel-mode is special.
923 * User mode traps are simply passed on to trap(). 922 * User mode traps are simply passed on to trap().
924 */ 923 */
925ENTRY_NOPROFILE(trace) 924ENTRY_NOPROFILE(trace)
926 clrl %sp@- | stack adjust count 925 clrl %sp@- | stack adjust count
927 moveml #0xFFFF,%sp@- 926 moveml #0xFFFF,%sp@-
928 moveq #T_TRACE,%d0 927 moveq #T_TRACE,%d0
929 928
930 | Check PSW and see what happen. 929 | Check PSW and see what happen.
931 | T=0 S=0 (should not happen) 930 | T=0 S=0 (should not happen)
932 | T=1 S=0 trace trap from user mode 931 | T=1 S=0 trace trap from user mode
933 | T=0 S=1 trace trap on a trap instruction 932 | T=0 S=1 trace trap on a trap instruction
934 | T=1 S=1 trace trap from system mode (kernel breakpoint) 933 | T=1 S=1 trace trap from system mode (kernel breakpoint)
935 934
936 movw %sp@(FR_HW),%d1 | get PSW 935 movw %sp@(FR_HW),%d1 | get PSW
937 notw %d1 | XXX no support for T0 on 680[234]0 936 notw %d1 | XXX no support for T0 on 680[234]0
938 andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 937 andw #PSL_TS,%d1 | from system mode (T=1, S=1)?
939 jeq Lkbrkpt | yes, kernel breakpoint 938 jeq Lkbrkpt | yes, kernel breakpoint
940 jra _ASM_LABEL(fault) | no, user-mode fault 939 jra _ASM_LABEL(fault) | no, user-mode fault
941 940
942/* 941/*
943 * Trap 15 is used for: 942 * Trap 15 is used for:
944 * - GDB breakpoints (in user programs) 943 * - GDB breakpoints (in user programs)
945 * - KGDB breakpoints (in the kernel) 944 * - KGDB breakpoints (in the kernel)
946 * - trace traps for SUN binaries (not fully supported yet) 945 * - trace traps for SUN binaries (not fully supported yet)
947 * User mode traps are simply passed to trap(). 946 * User mode traps are simply passed to trap().
948 */ 947 */
949ENTRY_NOPROFILE(trap15) 948ENTRY_NOPROFILE(trap15)
950 clrl %sp@- | stack adjust count 949 clrl %sp@- | stack adjust count
951 moveml #0xFFFF,%sp@- 950 moveml #0xFFFF,%sp@-
952 moveq #T_TRAP15,%d0 951 moveq #T_TRAP15,%d0
953 movw %sp@(FR_HW),%d1 | get PSW 952 movw %sp@(FR_HW),%d1 | get PSW
954 andw #PSL_S,%d1 | from system mode? 953 andw #PSL_S,%d1 | from system mode?
955 jne Lkbrkpt | yes, kernel breakpoint 954 jne Lkbrkpt | yes, kernel breakpoint
956 jra _ASM_LABEL(fault) | no, user-mode fault 955 jra _ASM_LABEL(fault) | no, user-mode fault
957 956
958Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type) 957Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type)
959 | Save the system sp rather than the user sp. 958 | Save the system sp rather than the user sp.
960 movw #PSL_HIGHIPL,%sr | lock out interrupts 959 movw #PSL_HIGHIPL,%sr | lock out interrupts
961 lea %sp@(FR_SIZE),%a6 | Save stack pointer 960 lea %sp@(FR_SIZE),%a6 | Save stack pointer
962 movl %a6,%sp@(FR_SP) | from before trap 961 movl %a6,%sp@(FR_SP) | from before trap
963 962
964 | If were are not on tmpstk switch to it. 963 | If were are not on tmpstk switch to it.
965 | (so debugger can change the stack pointer) 964 | (so debugger can change the stack pointer)
966 movl %a6,%d1 965 movl %a6,%d1
967 cmpl #_ASM_LABEL(tmpstk),%d1 966 cmpl #_ASM_LABEL(tmpstk),%d1
968 jls Lbrkpt2 | already on tmpstk 967 jls Lbrkpt2 | already on tmpstk
969 | Copy frame to the temporary stack 968 | Copy frame to the temporary stack
970 movl %sp,%a0 | %a0=src 969 movl %sp,%a0 | %a0=src
971 lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst 970 lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst
972 movl %a1,%sp | %sp=new frame 971 movl %a1,%sp | %sp=new frame
973 moveq #FR_SIZE,%d1 972 moveq #FR_SIZE,%d1
974Lbrkpt1: 973Lbrkpt1:
975 movl %a0@+,%a1@+ 974 movl %a0@+,%a1@+
976 subql #4,%d1 975 subql #4,%d1
977 bgt Lbrkpt1 976 bgt Lbrkpt1
978 977
979Lbrkpt2: 978Lbrkpt2:
980 | Call the trap handler for the kernel debugger. 979 | Call the trap handler for the kernel debugger.
981 | Do not call trap() to do it, so that we can 980 | Do not call trap() to do it, so that we can
982 | set breakpoints in trap() if we want. We know 981 | set breakpoints in trap() if we want. We know
983 | the trap type is either T_TRACE or T_BREAKPOINT. 982 | the trap type is either T_TRACE or T_BREAKPOINT.
984 | If we have both DDB and KGDB, let KGDB see it first, 983 | If we have both DDB and KGDB, let KGDB see it first,
985 | because KGDB will just return 0 if not connected. 984 | because KGDB will just return 0 if not connected.
986 | Save args in %d2, %a2 985 | Save args in %d2, %a2
987 movl %d0,%d2 | trap type 986 movl %d0,%d2 | trap type
988 movl %sp,%a2 | frame ptr 987 movl %sp,%a2 | frame ptr
989#ifdef KGDB 988#ifdef KGDB
990 | Let KGDB handle it (if connected) 989 | Let KGDB handle it (if connected)
991 movl %a2,%sp@- | push frame ptr 990 movl %a2,%sp@- | push frame ptr
992 movl %d2,%sp@- | push trap type 991 movl %d2,%sp@- | push trap type
993 jbsr _C_LABEL(kgdb_trap) | handle the trap 992 jbsr _C_LABEL(kgdb_trap) | handle the trap
994 addql #8,%sp | pop args 993 addql #8,%sp | pop args
995 cmpl #0,%d0 | did kgdb handle it? 994 cmpl #0,%d0 | did kgdb handle it?
996 jne Lbrkpt3 | yes, done 995 jne Lbrkpt3 | yes, done
997#endif 996#endif
998#ifdef DDB 997#ifdef DDB
999 | Let DDB handle it 998 | Let DDB handle it
1000 movl %a2,%sp@- | push frame ptr 999 movl %a2,%sp@- | push frame ptr
1001 movl %d2,%sp@- | push trap type 1000 movl %d2,%sp@- | push trap type
1002 jbsr _C_LABEL(kdb_trap) | handle the trap 1001 jbsr _C_LABEL(kdb_trap) | handle the trap
1003 addql #8,%sp | pop args 1002 addql #8,%sp | pop args
1004#if 0 /* not needed on hp300 */ 1003#if 0 /* not needed on hp300 */
1005 cmpl #0,%d0 | did ddb handle it? 1004 cmpl #0,%d0 | did ddb handle it?
1006 jne Lbrkpt3 | yes, done 1005 jne Lbrkpt3 | yes, done
1007#endif 1006#endif
1008#endif 1007#endif
1009 /* Sun 3 drops into PROM here. */ 1008 /* Sun 3 drops into PROM here. */
1010Lbrkpt3: 1009Lbrkpt3:
1011 | The stack pointer may have been modified, or 1010 | The stack pointer may have been modified, or
1012 | data below it modified (by kgdb push call), 1011 | data below it modified (by kgdb push call),
1013 | so push the hardware frame at the current sp 1012 | so push the hardware frame at the current sp
1014 | before restoring registers and returning. 1013 | before restoring registers and returning.
1015 1014
1016 movl %sp@(FR_SP),%a0 | modified %sp 1015 movl %sp@(FR_SP),%a0 | modified %sp
1017 lea %sp@(FR_SIZE),%a1 | end of our frame 1016 lea %sp@(FR_SIZE),%a1 | end of our frame
1018 movl %a1@-,%a0@- | copy 2 longs with 1017 movl %a1@-,%a0@- | copy 2 longs with
1019 movl %a1@-,%a0@- | ... predecrement 1018 movl %a1@-,%a0@- | ... predecrement
1020 movl %a0,%sp@(FR_SP) | %sp = h/w frame 1019 movl %a0,%sp@(FR_SP) | %sp = h/w frame
1021 moveml %sp@+,#0x7FFF | restore all but %sp 1020 moveml %sp@+,#0x7FFF | restore all but %sp
1022 movl %sp@,%sp | ... and %sp 1021 movl %sp@,%sp | ... and %sp
1023 rte | all done 1022 rte | all done
1024 1023
1025/* Use common m68k sigreturn */ 1024/* Use common m68k sigreturn */
1026#include <m68k/m68k/sigreturn.s> 1025#include <m68k/m68k/sigreturn.s>
1027 1026
1028/* 1027/*
1029 * Interrupt handlers. 1028 * Interrupt handlers.
1030 * All device interrupts are auto-vectored. The CPU provides 1029 * All device interrupts are auto-vectored. The CPU provides
1031 * the vector 0x18+level. Note we count spurious interrupts, but 1030 * the vector 0x18+level. Note we count spurious interrupts, but
1032 * we don't do anything else with them. 1031 * we don't do anything else with them.
1033 */ 1032 */
1034 1033
1035#define INTERRUPT_SAVEREG moveml #0xC0C0,%sp@- 1034#define INTERRUPT_SAVEREG moveml #0xC0C0,%sp@-
1036#define INTERRUPT_RESTOREREG moveml %sp@+,#0x0303 1035#define INTERRUPT_RESTOREREG moveml %sp@+,#0x0303
1037 1036
1038/* 64-bit evcnt counter increments */ 1037/* 64-bit evcnt counter increments */
1039#define EVCNT_COUNTER(ipl) \ 1038#define EVCNT_COUNTER(ipl) \
1040 _C_LABEL(hp300_intr_list) + (ipl)*SIZEOF_HI + HI_EVCNT 1039 _C_LABEL(hp300_intr_list) + (ipl)*SIZEOF_HI + HI_EVCNT
1041#define EVCNT_INCREMENT(ipl) \ 1040#define EVCNT_INCREMENT(ipl) \
1042 movel %d2,-(%sp); \ 1041 movel %d2,-(%sp); \
1043 clrl %d0; \ 1042 clrl %d0; \
1044 moveql #1,%d1; \ 1043 moveql #1,%d1; \
1045 addl %d1,EVCNT_COUNTER(ipl)+4; \ 1044 addl %d1,EVCNT_COUNTER(ipl)+4; \
1046 movel EVCNT_COUNTER(ipl),%d2; \ 1045 movel EVCNT_COUNTER(ipl),%d2; \
1047 addxl %d0,%d2; \ 1046 addxl %d0,%d2; \
1048 movel %d2,EVCNT_COUNTER(ipl); \ 1047 movel %d2,EVCNT_COUNTER(ipl); \
1049 movel (%sp)+,%d2 1048 movel (%sp)+,%d2
1050 1049
1051ENTRY_NOPROFILE(spurintr) /* level 0 */ 1050ENTRY_NOPROFILE(spurintr) /* level 0 */
1052 EVCNT_INCREMENT(0) 1051 EVCNT_INCREMENT(0)
1053 addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS 1052 addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
1054 jra _ASM_LABEL(rei) 1053 jra _ASM_LABEL(rei)
1055 1054
1056ENTRY_NOPROFILE(intrhand) /* levels 1 through 5 */ 1055ENTRY_NOPROFILE(intrhand) /* levels 1 through 5 */
1057 addql #1,_C_LABEL(idepth) | entering interrupt 1056 addql #1,_C_LABEL(idepth) | entering interrupt
1058 INTERRUPT_SAVEREG 1057 INTERRUPT_SAVEREG
1059 movw %sp@(22),%sp@- | push exception vector info 1058 movw %sp@(22),%sp@- | push exception vector info
1060 clrw %sp@- 1059 clrw %sp@-
1061 jbsr _C_LABEL(intr_dispatch) | call dispatch routine 1060 jbsr _C_LABEL(intr_dispatch) | call dispatch routine
1062 addql #4,%sp 1061 addql #4,%sp
1063 INTERRUPT_RESTOREREG 1062 INTERRUPT_RESTOREREG
1064 subql #1,_C_LABEL(idepth) | exiting from interrupt 1063 subql #1,_C_LABEL(idepth) | exiting from interrupt
1065 jra _ASM_LABEL(rei) | all done 1064 jra _ASM_LABEL(rei) | all done
1066 1065
1067ENTRY_NOPROFILE(lev6intr) /* level 6: clock */ 1066ENTRY_NOPROFILE(lev6intr) /* level 6: clock */
1068 addql #1,_C_LABEL(idepth) | entering interrupt 1067 addql #1,_C_LABEL(idepth) | entering interrupt
1069 INTERRUPT_SAVEREG 1068 INTERRUPT_SAVEREG
1070 CLKADDR(%a0) 1069 CLKADDR(%a0)
1071 movb %a0@(CLKSR),%d0 | read clock status 1070 movb %a0@(CLKSR),%d0 | read clock status
1072Lclkagain: 1071Lclkagain:
1073 btst #0,%d0 | clear timer1 int immediately to 1072 btst #0,%d0 | clear timer1 int immediately to
1074 jeq Lnotim1 | minimize chance of losing another 1073 jeq Lnotim1 | minimize chance of losing another
1075 movpw %a0@(CLKMSB1),%d1 | due to statintr processing delay 1074 movpw %a0@(CLKMSB1),%d1 | due to statintr processing delay
1076 movl _C_LABEL(clkint),%d1 | clkcounter += clkint 1075 movl _C_LABEL(clkint),%d1 | clkcounter += clkint
1077 addl %d1,_C_LABEL(clkcounter) 1076 addl %d1,_C_LABEL(clkcounter)
1078Lnotim1: 1077Lnotim1:
1079 btst #2,%d0 | timer3 interrupt? 1078 btst #2,%d0 | timer3 interrupt?
1080 jeq Lnotim3 | no, skip statclock 1079 jeq Lnotim3 | no, skip statclock
1081 movpw %a0@(CLKMSB3),%d1 | clear timer3 interrupt 1080 movpw %a0@(CLKMSB3),%d1 | clear timer3 interrupt
1082 lea %sp@(16),%a1 | a1 = &clockframe 1081 lea %sp@(16),%a1 | a1 = &clockframe
1083 movl %d0,%sp@- | save status 1082 movl %d0,%sp@- | save status
1084 movl %a1,%sp@- 1083 movl %a1,%sp@-
1085 jbsr _C_LABEL(statintr) | statintr(&frame) 1084 jbsr _C_LABEL(statintr) | statintr(&frame)
1086 addql #4,%sp 1085 addql #4,%sp
1087 movl %sp@+,%d0 | restore pre-statintr status 1086 movl %sp@+,%d0 | restore pre-statintr status
1088 CLKADDR(%a0) 1087 CLKADDR(%a0)
1089Lnotim3: 1088Lnotim3:
1090 btst #0,%d0 | timer1 interrupt? 1089 btst #0,%d0 | timer1 interrupt?
1091 jeq Lrecheck | no, skip hardclock 1090 jeq Lrecheck | no, skip hardclock
1092 EVCNT_INCREMENT(6) 1091 EVCNT_INCREMENT(6)
1093 lea %sp@(16),%a1 | a1 = &clockframe 1092 lea %sp@(16),%a1 | a1 = &clockframe
1094 movl %a1,%sp@- 1093 movl %a1,%sp@-
1095#ifdef USELEDS 1094#ifdef USELEDS
1096 tstl _C_LABEL(ledaddr) | using LEDs? 1095 tstl _C_LABEL(ledaddr) | using LEDs?
1097 jeq Lnoleds0 | no, skip this code 1096 jeq Lnoleds0 | no, skip this code
1098 movl _ASM_LABEL(heartbeat),%d0 | get tick count 1097 movl _ASM_LABEL(heartbeat),%d0 | get tick count
1099 addql #1,%d0 | increment 1098 addql #1,%d0 | increment
1100 movl _C_LABEL(hz),%d1 1099 movl _C_LABEL(hz),%d1
1101 addl #50,%d1 | get the timing a little closer 1100 addl #50,%d1 | get the timing a little closer
1102 tstb _ASM_LABEL(beatstatus) | time to slow down? 1101 tstb _ASM_LABEL(beatstatus) | time to slow down?
1103 jeq Lslowthrob | yes, slow down 1102 jeq Lslowthrob | yes, slow down
1104 lsrl #3,%d1 | no, fast throb 1103 lsrl #3,%d1 | no, fast throb
1105Lslowthrob: 1104Lslowthrob:
1106 lsrl #1,%d1 | slow throb 1105 lsrl #1,%d1 | slow throb
1107 cmpl %d0,%d1 | are we there yet? 1106 cmpl %d0,%d1 | are we there yet?
1108 jne Lnoleds1 | no, nothing to do 1107 jne Lnoleds1 | no, nothing to do
1109 addqb #1,_ASM_LABEL(beatstatus) | incr beat status 1108 addqb #1,_ASM_LABEL(beatstatus) | incr beat status
1110 cmpb #3,_ASM_LABEL(beatstatus) | time to reset? 1109 cmpb #3,_ASM_LABEL(beatstatus) | time to reset?
1111 jle Ltwinkle | no, twinkle the lights 1110 jle Ltwinkle | no, twinkle the lights
1112 movb #0,_ASM_LABEL(beatstatus) | reset the status indicator 1111 movb #0,_ASM_LABEL(beatstatus) | reset the status indicator
1113Ltwinkle: 1112Ltwinkle:
1114 movl #LED_PULSE,%sp@- 1113 movl #LED_PULSE,%sp@-
1115 movl #LED_DISK+LED_LANRCV+LED_LANXMT,%sp@- 1114 movl #LED_DISK+LED_LANRCV+LED_LANXMT,%sp@-
1116 clrl %sp@- 1115 clrl %sp@-
1117 jbsr _C_LABEL(ledcontrol) | toggle pulse, turn all others off 1116 jbsr _C_LABEL(ledcontrol) | toggle pulse, turn all others off
1118 lea %sp@(12),%sp 1117 lea %sp@(12),%sp
1119 movql #0,%d0 1118 movql #0,%d0
1120Lnoleds1: 1119Lnoleds1:
1121 movl %d0,_ASM_LABEL(heartbeat) 1120 movl %d0,_ASM_LABEL(heartbeat)
1122Lnoleds0: 1121Lnoleds0:
1123#endif /* USELEDS */ 1122#endif /* USELEDS */
1124 jbsr _C_LABEL(hardclock) | hardclock(&frame) 1123 jbsr _C_LABEL(hardclock) | hardclock(&frame)
1125 addql #4,%sp 1124 addql #4,%sp
1126 CLKADDR(%a0) 1125 CLKADDR(%a0)
1127Lrecheck: 1126Lrecheck:
1128 addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS | chalk up another interrupt 1127 addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS | chalk up another interrupt
1129 movb %a0@(CLKSR),%d0 | see if anything happened 1128 movb %a0@(CLKSR),%d0 | see if anything happened
1130 jmi Lclkagain | while we were in hardclock/statintr 1129 jmi Lclkagain | while we were in hardclock/statintr
1131 INTERRUPT_RESTOREREG 1130 INTERRUPT_RESTOREREG
1132 subql #1,_C_LABEL(idepth) | exiting from interrupt 1131 subql #1,_C_LABEL(idepth) | exiting from interrupt
1133 jra _ASM_LABEL(rei) | all done 1132 jra _ASM_LABEL(rei) | all done
1134 1133
1135ENTRY_NOPROFILE(lev7intr) /* level 7: parity errors, reset key */ 1134ENTRY_NOPROFILE(lev7intr) /* level 7: parity errors, reset key */
1136 EVCNT_INCREMENT(7) 1135 EVCNT_INCREMENT(7)
1137 clrl %sp@- 1136 clrl %sp@-
1138 moveml #0xFFFF,%sp@- | save registers 1137 moveml #0xFFFF,%sp@- | save registers
1139 movl %usp,%a0 | and save 1138 movl %usp,%a0 | and save
1140 movl %a0,%sp@(FR_SP) | the user stack pointer 1139 movl %a0,%sp@(FR_SP) | the user stack pointer
1141 jbsr _C_LABEL(nmihand) | call handler 1140 jbsr _C_LABEL(nmihand) | call handler
1142 movl %sp@(FR_SP),%a0 | restore 1141 movl %sp@(FR_SP),%a0 | restore
1143 movl %a0,%usp | user SP 1142 movl %a0,%usp | user SP
1144 moveml %sp@+,#0x7FFF | and remaining registers 1143 moveml %sp@+,#0x7FFF | and remaining registers
1145 addql #8,%sp | pop SP and stack adjust 1144 addql #8,%sp | pop SP and stack adjust
1146 jra _ASM_LABEL(rei) | all done 1145 jra _ASM_LABEL(rei) | all done
1147 1146
1148/* 1147/*
1149 * Emulation of VAX REI instruction. 1148 * Emulation of VAX REI instruction.
1150 * 1149 *
1151 * This code deals with checking for and servicing 1150 * This code deals with checking for and servicing
1152 * ASTs (profiling, scheduling). 1151 * ASTs (profiling, scheduling).
1153 * After identifing that we need an AST we drop the IPL 1152 * After identifing that we need an AST we drop the IPL
1154 * to allow device interrupts. 1153 * to allow device interrupts.
1155 * 1154 *
1156 * This code is complicated by the fact that sendsig may have been called 1155 * This code is complicated by the fact that sendsig may have been called
1157 * necessitating a stack cleanup. 1156 * necessitating a stack cleanup.
1158 */ 1157 */
1159 1158
1160ASENTRY_NOPROFILE(rei) 1159ASENTRY_NOPROFILE(rei)
1161 tstl _C_LABEL(astpending) | AST pending? 1160 tstl _C_LABEL(astpending) | AST pending?
1162 jne 1f | no, done 1161 jne 1f | no, done
1163 rte 1162 rte
11641: 11631:
1165 btst #5,%sp@ | yes, are we returning to user mode? 1164 btst #5,%sp@ | yes, are we returning to user mode?
1166 jeq 2f | no, done 1165 jeq 2f | no, done
1167 rte 1166 rte
11682: 11672:
1169 movw #PSL_LOWIPL,%sr | lower SPL 1168 movw #PSL_LOWIPL,%sr | lower SPL
1170 clrl %sp@- | stack adjust 1169 clrl %sp@- | stack adjust
1171 moveml #0xFFFF,%sp@- | save all registers 1170 moveml #0xFFFF,%sp@- | save all registers
1172 movl %usp,%a1 | including 1171 movl %usp,%a1 | including
1173 movl %a1,%sp@(FR_SP) | the users SP 1172 movl %a1,%sp@(FR_SP) | the users SP
1174Lrei: 1173Lrei:
1175 clrl %sp@- | VA == none 1174 clrl %sp@- | VA == none
1176 clrl %sp@- | code == none 1175 clrl %sp@- | code == none
1177 movl #T_ASTFLT,%sp@- | type == async system trap 1176 movl #T_ASTFLT,%sp@- | type == async system trap
1178 pea %sp@(12) | fp == address of trap frame 1177 pea %sp@(12) | fp == address of trap frame
1179 jbsr _C_LABEL(trap) | go handle it 1178 jbsr _C_LABEL(trap) | go handle it
1180 lea %sp@(16),%sp | pop value args 1179 lea %sp@(16),%sp | pop value args
1181 movl %sp@(FR_SP),%a0 | restore user SP 1180 movl %sp@(FR_SP),%a0 | restore user SP
1182 movl %a0,%usp | from save area 1181 movl %a0,%usp | from save area
1183 movw %sp@(FR_ADJ),%d0 | need to adjust stack? 1182 movw %sp@(FR_ADJ),%d0 | need to adjust stack?
1184 jne Laststkadj | yes, go to it 1183 jne Laststkadj | yes, go to it
1185 moveml %sp@+,#0x7FFF | no, restore most user regs 1184 moveml %sp@+,#0x7FFF | no, restore most user regs
1186 addql #8,%sp | toss SP and stack adjust 1185 addql #8,%sp | toss SP and stack adjust
1187 rte | and do real RTE 1186 rte | and do real RTE
1188Laststkadj: 1187Laststkadj:
1189 lea %sp@(FR_HW),%a1 | pointer to HW frame 1188 lea %sp@(FR_HW),%a1 | pointer to HW frame
1190 addql #8,%a1 | source pointer 1189 addql #8,%a1 | source pointer
1191 movl %a1,%a0 | source 1190 movl %a1,%a0 | source
1192 addw %d0,%a0 | + hole size = dest pointer 1191 addw %d0,%a0 | + hole size = dest pointer
1193 movl %a1@-,%a0@- | copy 1192 movl %a1@-,%a0@- | copy
1194 movl %a1@-,%a0@- | 8 bytes 1193 movl %a1@-,%a0@- | 8 bytes
1195 movl %a0,%sp@(FR_SP) | new SSP 1194 movl %a0,%sp@(FR_SP) | new SSP
1196 moveml %sp@+,#0x7FFF | restore user registers 1195 moveml %sp@+,#0x7FFF | restore user registers
1197 movl %sp@,%sp | and our SP 1196 movl %sp@,%sp | and our SP
1198 rte | and do real RTE 1197 rte | and do real RTE
1199 1198
1200/* 1199/*
1201 * Use common m68k sigcode. 1200 * Use common m68k sigcode.
1202 */ 1201 */
1203#include <m68k/m68k/sigcode.s> 1202#include <m68k/m68k/sigcode.s>
1204#ifdef COMPAT_SUNOS 1203#ifdef COMPAT_SUNOS
1205#include <m68k/m68k/sunos_sigcode.s> 1204#include <m68k/m68k/sunos_sigcode.s>
1206#endif 1205#endif
1207#ifdef COMPAT_SVR4 1206#ifdef COMPAT_SVR4
1208#include <m68k/m68k/svr4_sigcode.s> 1207#include <m68k/m68k/svr4_sigcode.s>
1209#endif 1208#endif
1210 1209
1211/* 1210/*
1212 * Primitives 1211 * Primitives
1213 */  1212 */
1214 1213
1215/* 1214/*
1216 * Use common m68k support routines. 1215 * Use common m68k support routines.
1217 */ 1216 */
1218#include <m68k/m68k/support.s> 1217#include <m68k/m68k/support.s>
1219 1218
1220/* 1219/*
1221 * Use common m68k process/lwp switch and context save subroutines. 1220 * Use common m68k process/lwp switch and context save subroutines.
1222 */ 1221 */
1223#define FPCOPROC /* XXX: Temp. reqd. */ 1222#define FPCOPROC /* XXX: Temp. reqd. */
1224#include <m68k/m68k/switch_subr.s> 1223#include <m68k/m68k/switch_subr.s>
1225 1224
1226 1225
1227#if defined(M68040) 1226#if defined(M68040)
1228ENTRY(suline) 1227ENTRY(suline)
1229 movl %sp@(4),%a0 | address to write 1228 movl %sp@(4),%a0 | address to write
1230 movl _C_LABEL(curpcb),%a1 | current pcb 1229 movl _C_LABEL(curpcb),%a1 | current pcb
1231 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault 1230 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault
1232 movl %sp@(8),%a1 | address of line 1231 movl %sp@(8),%a1 | address of line
1233 movl %a1@+,%d0 | get lword 1232 movl %a1@+,%d0 | get lword
1234 movsl %d0,%a0@+ | put lword 1233 movsl %d0,%a0@+ | put lword
1235 nop | sync 1234 nop | sync
1236 movl %a1@+,%d0 | get lword 1235 movl %a1@+,%d0 | get lword
1237 movsl %d0,%a0@+ | put lword 1236 movsl %d0,%a0@+ | put lword
1238 nop | sync 1237 nop | sync
1239 movl %a1@+,%d0 | get lword 1238 movl %a1@+,%d0 | get lword
1240 movsl %d0,%a0@+ | put lword 1239 movsl %d0,%a0@+ | put lword
1241 nop | sync 1240 nop | sync
1242 movl %a1@+,%d0 | get lword 1241 movl %a1@+,%d0 | get lword
1243 movsl %d0,%a0@+ | put lword 1242 movsl %d0,%a0@+ | put lword
1244 nop | sync 1243 nop | sync
1245 moveq #0,%d0 | indicate no fault 1244 moveq #0,%d0 | indicate no fault
1246 jra Lsldone 1245 jra Lsldone
1247Lslerr: 1246Lslerr:
1248 moveq #-1,%d0 1247 moveq #-1,%d0
1249Lsldone: 1248Lsldone:
1250 movl _C_LABEL(curpcb),%a1 | current pcb 1249 movl _C_LABEL(curpcb),%a1 | current pcb
1251 clrl %a1@(PCB_ONFAULT) | clear fault address 1250 clrl %a1@(PCB_ONFAULT) | clear fault address
1252 rts 1251 rts
1253#endif 1252#endif
1254 1253
1255ENTRY(ecacheon) 1254ENTRY(ecacheon)
1256 tstl _C_LABEL(ectype) 1255 tstl _C_LABEL(ectype)
1257 jeq Lnocache7 1256 jeq Lnocache7
1258 MMUADDR(%a0) 1257 MMUADDR(%a0)
1259 orl #MMU_CEN,%a0@(MMUCMD) 1258 orl #MMU_CEN,%a0@(MMUCMD)
1260Lnocache7: 1259Lnocache7:
1261 rts 1260 rts
1262 1261
1263ENTRY(ecacheoff) 1262ENTRY(ecacheoff)
1264 tstl _C_LABEL(ectype) 1263 tstl _C_LABEL(ectype)
1265 jeq Lnocache8 1264 jeq Lnocache8
1266 MMUADDR(%a0) 1265 MMUADDR(%a0)
1267 andl #~MMU_CEN,%a0@(MMUCMD) 1266 andl #~MMU_CEN,%a0@(MMUCMD)
1268Lnocache8: 1267Lnocache8:
1269 rts 1268 rts
1270 1269
1271ENTRY_NOPROFILE(getsfc) 1270ENTRY_NOPROFILE(getsfc)
1272 movc %sfc,%d0 1271 movc %sfc,%d0
1273 rts 1272 rts
1274 1273
1275ENTRY_NOPROFILE(getdfc) 1274ENTRY_NOPROFILE(getdfc)
1276 movc %dfc,%d0 1275 movc %dfc,%d0
1277 rts 1276 rts
1278 1277
1279/* 1278/*
1280 * Load a new user segment table pointer. 1279 * Load a new user segment table pointer.
1281 */ 1280 */
1282ENTRY(loadustp) 1281ENTRY(loadustp)
1283#if defined(M68K_MMU_MOTOROLA) 1282#if defined(M68K_MMU_MOTOROLA)
1284 tstl _C_LABEL(mmutype) | HP MMU? 1283 tstl _C_LABEL(mmutype) | HP MMU?
1285 jeq Lhpmmu9 | yes, skip 1284 jeq Lhpmmu9 | yes, skip
1286 movl %sp@(4),%d0 | new USTP 1285 movl %sp@(4),%d0 | new USTP
1287 moveq #PGSHIFT,%d1 1286 moveq #PGSHIFT,%d1
1288 lsll %d1,%d0 | convert to addr 1287 lsll %d1,%d0 | convert to addr
1289#if defined(M68040) 1288#if defined(M68040)
1290 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1289 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
1291 jne LmotommuC | no, skip 1290 jne LmotommuC | no, skip
1292 .word 0xf518 | yes, pflusha 1291 .word 0xf518 | yes, pflusha
1293 .long 0x4e7b0806 | movc %d0,%urp 1292 .long 0x4e7b0806 | movc %d0,%urp
1294 rts 1293 rts
1295LmotommuC: 1294LmotommuC:
1296#endif 1295#endif
1297 pflusha | flush entire TLB 1296 pflusha | flush entire TLB
1298 lea _C_LABEL(protorp),%a0 | CRP prototype 1297 lea _C_LABEL(protorp),%a0 | CRP prototype
1299 movl %d0,%a0@(4) | stash USTP 1298 movl %d0,%a0@(4) | stash USTP
1300 pmove %a0@,%crp | load root pointer 1299 pmove %a0@,%crp | load root pointer
1301 movl #CACHE_CLR,%d0 1300 movl #CACHE_CLR,%d0
1302 movc %d0,%cacr | invalidate cache(s) 1301 movc %d0,%cacr | invalidate cache(s)
1303 rts 1302 rts
1304Lhpmmu9: 1303Lhpmmu9:
1305#endif 1304#endif
1306#if defined(M68K_MMU_HP) 1305#if defined(M68K_MMU_HP)
1307 movl #CACHE_CLR,%d0 1306 movl #CACHE_CLR,%d0
1308 movc %d0,%cacr | invalidate cache(s) 1307 movc %d0,%cacr | invalidate cache(s)
1309 MMUADDR(%a0) 1308 MMUADDR(%a0)
1310 movl %a0@(MMUTBINVAL),%d1 | invalidate TLB 1309 movl %a0@(MMUTBINVAL),%d1 | invalidate TLB
1311 tstl _C_LABEL(ectype) | have external VAC? 1310 tstl _C_LABEL(ectype) | have external VAC?
1312 jle 1f | no, skip 1311 jle 1f | no, skip
1313 andl #~MMU_CEN,%a0@(MMUCMD) | toggle cache enable 1312 andl #~MMU_CEN,%a0@(MMUCMD) | toggle cache enable
1314 orl #MMU_CEN,%a0@(MMUCMD) | to clear data cache 1313 orl #MMU_CEN,%a0@(MMUCMD) | to clear data cache
13151: 13141:
1316 movl %sp@(4),%a0@(MMUUSTP) | load a new USTP 1315 movl %sp@(4),%a0@(MMUUSTP) | load a new USTP
1317#endif 1316#endif
1318 rts 1317 rts
1319 1318
1320ENTRY(ploadw) 1319ENTRY(ploadw)
1321#if defined(M68K_MMU_MOTOROLA) 1320#if defined(M68K_MMU_MOTOROLA)
1322 movl %sp@(4),%a0 | address to load 1321 movl %sp@(4),%a0 | address to load
1323#if defined(M68K_MMU_HP) 1322#if defined(M68K_MMU_HP)
1324 tstl _C_LABEL(mmutype) | HP MMU? 1323 tstl _C_LABEL(mmutype) | HP MMU?
1325 jeq Lploadwskp | yes, skip 1324 jeq Lploadwskp | yes, skip
1326#endif 1325#endif
1327#if defined(M68040) 1326#if defined(M68040)
1328 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1327 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
1329 jeq Lploadwskp | yes, skip 1328 jeq Lploadwskp | yes, skip
1330#endif 1329#endif
1331 ploadw #1,%a0@ | pre-load translation 1330 ploadw #1,%a0@ | pre-load translation
1332Lploadwskp: 1331Lploadwskp:
1333#endif 1332#endif
1334 rts 1333 rts
1335 1334
1336/* 1335/*
1337 * _delay(u_int N) 1336 * _delay(u_int N)
1338 * 1337 *
1339 * Delay for at least (N/256) microsecends. 1338 * Delay for at least (N/256) microsecends.
1340 * This routine depends on the variable: delay_divisor 1339 * This routine depends on the variable: delay_divisor
1341 * which should be set based on the CPU clock rate. 1340 * which should be set based on the CPU clock rate.
1342 */ 1341 */
1343ENTRY_NOPROFILE(_delay) 1342ENTRY_NOPROFILE(_delay)
1344 | %d0 = arg = (usecs << 8) 1343 | %d0 = arg = (usecs << 8)
1345 movl %sp@(4),%d0 1344 movl %sp@(4),%d0
1346 | %d1 = delay_divisor 1345 | %d1 = delay_divisor
1347 movl _C_LABEL(delay_divisor),%d1 1346 movl _C_LABEL(delay_divisor),%d1
1348 jra L_delay /* Jump into the loop! */ 1347 jra L_delay /* Jump into the loop! */
1349 1348
1350 /* 1349 /*
1351 * Align the branch target of the loop to a half-line (8-byte) 1350 * Align the branch target of the loop to a half-line (8-byte)
1352 * boundary to minimize cache effects. This guarantees both 1351 * boundary to minimize cache effects. This guarantees both
1353 * that there will be no prefetch stalls due to cache line burst 1352 * that there will be no prefetch stalls due to cache line burst
1354 * operations and that the loop will run from a single cache 1353 * operations and that the loop will run from a single cache
1355 * half-line. 1354 * half-line.
1356 */ 1355 */
1357#ifdef __ELF__ 1356#ifdef __ELF__
1358 .align 8 1357 .align 8
1359#else 1358#else
1360 .align 3 1359 .align 3
1361#endif 1360#endif
1362L_delay: 1361L_delay:
1363 subl %d1,%d0 1362 subl %d1,%d0
1364 jgt L_delay 1363 jgt L_delay
1365 rts 1364 rts
1366 1365
1367/* 1366/*
1368 * Save and restore 68881 state. 1367 * Save and restore 68881 state.
1369 */ 1368 */
1370ENTRY(m68881_save) 1369ENTRY(m68881_save)
1371 movl %sp@(4),%a0 | save area pointer 1370 movl %sp@(4),%a0 | save area pointer
1372 fsave %a0@ | save state 1371 fsave %a0@ | save state
1373 tstb %a0@ | null state frame? 1372 tstb %a0@ | null state frame?
1374 jeq Lm68881sdone | yes, all done 1373 jeq Lm68881sdone | yes, all done
1375 fmovem %fp0-%fp7,%a0@(FPF_REGS) | save FP general registers 1374 fmovem %fp0-%fp7,%a0@(FPF_REGS) | save FP general registers
1376 fmovem %fpcr/%fpsr/%fpi,%a0@(FPF_FPCR) | save FP control registers 1375 fmovem %fpcr/%fpsr/%fpi,%a0@(FPF_FPCR) | save FP control registers
1377Lm68881sdone: 1376Lm68881sdone:
1378 rts 1377 rts
1379 1378
1380ENTRY(m68881_restore) 1379ENTRY(m68881_restore)
1381 movl %sp@(4),%a0 | save area pointer 1380 movl %sp@(4),%a0 | save area pointer
1382 tstb %a0@ | null state frame? 1381 tstb %a0@ | null state frame?
1383 jeq Lm68881rdone | yes, easy 1382 jeq Lm68881rdone | yes, easy
1384 fmovem %a0@(FPF_FPCR),%fpcr/%fpsr/%fpi | restore FP control registers 1383 fmovem %a0@(FPF_FPCR),%fpcr/%fpsr/%fpi | restore FP control registers
1385 fmovem %a0@(FPF_REGS),%fp0-%fp7 | restore FP general registers 1384 fmovem %a0@(FPF_REGS),%fp0-%fp7 | restore FP general registers
1386Lm68881rdone: 1385Lm68881rdone:
1387 frestore %a0@ | restore state 1386 frestore %a0@ | restore state
1388 rts 1387 rts
1389 1388
1390/* 1389/*
1391 * Probe a memory address, and see if it causes a bus error. 1390 * Probe a memory address, and see if it causes a bus error.
1392 * This function is only to be used in physical mode, and before our 1391 * This function is only to be used in physical mode, and before our
1393 * trap vectors are initialized. 1392 * trap vectors are initialized.
1394 * Invoke with address to probe in %a0. 1393 * Invoke with address to probe in %a0.
1395 * Alters: %a3 %d0 1394 * Alters: %a3 %d0
1396 */ 1395 */
1397#define BUSERR 0xfffffffc 1396#define BUSERR 0xfffffffc
1398ASLOCAL(phys_badaddr) 1397ASLOCAL(phys_badaddr)
1399 ASRELOC(_bsave,%a3) 1398 ASRELOC(_bsave,%a3)
1400 movl BUSERR,%a3@ | save ROM bus errror handler 1399 movl BUSERR,%a3@ | save ROM bus errror handler
1401 ASRELOC(_ssave,%a3) 1400 ASRELOC(_ssave,%a3)
1402 movl %sp,%a3@ | and current stack pointer 1401 movl %sp,%a3@ | and current stack pointer
1403 ASRELOC(catchbad,%a3) 1402 ASRELOC(catchbad,%a3)
1404 movl %a3,BUSERR | plug in our handler 1403 movl %a3,BUSERR | plug in our handler
1405 movb %a0@,%d0 | access address 1404 movb %a0@,%d0 | access address
1406 ASRELOC(_bsave,%a3) | no fault! 1405 ASRELOC(_bsave,%a3) | no fault!
1407 movl %a3@,BUSERR 1406 movl %a3@,BUSERR
1408 clrl %d0 | return success 1407 clrl %d0 | return success
1409 rts 1408 rts
1410ASLOCAL(catchbad) 1409ASLOCAL(catchbad)
1411 ASRELOC(_bsave,%a3) | got a bus error, so restore handler 1410 ASRELOC(_bsave,%a3) | got a bus error, so restore handler
1412 movl %a3@,BUSERR 1411 movl %a3@,BUSERR
1413 ASRELOC(_ssave,%a3) 1412 ASRELOC(_ssave,%a3)
1414 movl %a3@,%sp | and stack 1413 movl %a3@,%sp | and stack
1415 moveq #1,%d0 | return fault 1414 moveq #1,%d0 | return fault
1416 rts 1415 rts
1417#undef BUSERR 1416#undef BUSERR
1418 1417
1419 .data 1418 .data
1420ASLOCAL(_bsave) 1419ASLOCAL(_bsave)
1421 .long 0 1420 .long 0
1422ASLOCAL(_ssave) 1421ASLOCAL(_ssave)
1423 .long 0 1422 .long 0
1424 .text 1423 .text
1425 1424
1426/* 1425/*
1427 * Handle the nitty-gritty of rebooting the machine. 1426 * Handle the nitty-gritty of rebooting the machine.
1428 * Basically we just turn off the MMU and jump to the appropriate ROM routine. 1427 * Basically we just turn off the MMU and jump to the appropriate ROM routine.
1429 * Note that we must be running in an address range that is mapped one-to-one 1428 * Note that we must be running in an address range that is mapped one-to-one
1430 * logical to physical so that the PC is still valid immediately after the MMU 1429 * logical to physical so that the PC is still valid immediately after the MMU
1431 * is turned off. We have conveniently mapped the last page of physical 1430 * is turned off. We have conveniently mapped the last page of physical
1432 * memory this way. 1431 * memory this way.
1433 */ 1432 */
1434ENTRY_NOPROFILE(doboot) 1433ENTRY_NOPROFILE(doboot)
1435#if defined(M68040) 1434#if defined(M68040)
1436 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1435 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
1437 jeq Lnocache5 | yes, skip 1436 jeq Lnocache5 | yes, skip
1438#endif 1437#endif
1439 movl #CACHE_OFF,%d0 1438 movl #CACHE_OFF,%d0
1440 movc %d0,%cacr | disable on-chip cache(s) 1439 movc %d0,%cacr | disable on-chip cache(s)
1441 tstl _C_LABEL(ectype) | external cache? 1440 tstl _C_LABEL(ectype) | external cache?
1442 jeq Lnocache5 | no, skip 1441 jeq Lnocache5 | no, skip
1443 MMUADDR(%a0) 1442 MMUADDR(%a0)
1444 andl #~MMU_CEN,%a0@(MMUCMD) | disable external cache 1443 andl #~MMU_CEN,%a0@(MMUCMD) | disable external cache
1445Lnocache5: 1444Lnocache5:
1446 lea MAXADDR,%a0 | last page of physical memory 1445 lea MAXADDR,%a0 | last page of physical memory
1447 movl _C_LABEL(boothowto),%a0@+ | store howto 1446 movl _C_LABEL(boothowto),%a0@+ | store howto
1448 movl _C_LABEL(bootdev),%a0@+ | and devtype 1447 movl _C_LABEL(bootdev),%a0@+ | and devtype
1449 lea Lbootcode,%a1 | start of boot code 1448 lea Lbootcode,%a1 | start of boot code
1450 lea Lebootcode,%a3 | end of boot code 1449 lea Lebootcode,%a3 | end of boot code
1451Lbootcopy: 1450Lbootcopy:
1452 movw %a1@+,%a0@+ | copy a word 1451 movw %a1@+,%a0@+ | copy a word
1453 cmpl %a3,%a1 | done yet? 1452 cmpl %a3,%a1 | done yet?
1454 jcs Lbootcopy | no, keep going 1453 jcs Lbootcopy | no, keep going
1455#if defined(M68040) 1454#if defined(M68040)
1456 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1455 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
1457 jne LmotommuE | no, skip 1456 jne LmotommuE | no, skip
1458 .word 0xf4f8 | cpusha bc 1457 .word 0xf4f8 | cpusha bc
1459LmotommuE: 1458LmotommuE:
1460#endif 1459#endif
1461 jmp MAXADDR+8 | jump to last page 1460 jmp MAXADDR+8 | jump to last page
1462 1461
1463Lbootcode: 1462Lbootcode:
1464 lea MAXADDR+0x800,%sp | physical SP in case of NMI 1463 lea MAXADDR+0x800,%sp | physical SP in case of NMI
1465#if defined(M68040) 1464#if defined(M68040)
1466 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1465 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
1467 jne LmotommuF | no, skip 1466 jne LmotommuF | no, skip
1468 movl #0,%d0 1467 movl #0,%d0
1469 movc %d0,%cacr | caches off 1468 movc %d0,%cacr | caches off
1470 .long 0x4e7b0003 | movc %d0,%tc 1469 .long 0x4e7b0003 | movc %d0,%tc
1471 movl %d2,MAXADDR+PAGE_SIZE-4 | restore old high page contents 1470 movl %d2,MAXADDR+PAGE_SIZE-4 | restore old high page contents
1472 DOREBOOT 1471 DOREBOOT
1473LmotommuF: 1472LmotommuF:
1474#endif 1473#endif
1475#if defined(M68K_MMU_MOTOROLA) 1474#if defined(M68K_MMU_MOTOROLA)
1476 tstl _C_LABEL(mmutype) | HP MMU? 1475 tstl _C_LABEL(mmutype) | HP MMU?
1477 jeq LhpmmuB | yes, skip 1476 jeq LhpmmuB | yes, skip
1478 movl #0,%a0@ | value for pmove to TC (turn off MMU) 1477 movl #0,%a0@ | value for pmove to TC (turn off MMU)
1479 pmove %a0@,%tc | disable MMU 1478 pmove %a0@,%tc | disable MMU
1480 DOREBOOT 1479 DOREBOOT
1481LhpmmuB: 1480LhpmmuB:
1482#endif 1481#endif
1483#if defined(M68K_MMU_HP) 1482#if defined(M68K_MMU_HP)
1484 MMUADDR(%a0) 1483 MMUADDR(%a0)
1485 movl #0xFFFF0000,%a0@(MMUCMD) | totally disable MMU 1484 movl #0xFFFF0000,%a0@(MMUCMD) | totally disable MMU
1486 movl %d2,MAXADDR+PAGE_SIZE-4 | restore old high page contents 1485 movl %d2,MAXADDR+PAGE_SIZE-4 | restore old high page contents
1487 DOREBOOT 1486 DOREBOOT
1488#endif 1487#endif
1489Lebootcode: 1488Lebootcode:
1490 1489
1491/* 1490/*
1492 * Misc. global variables. 1491 * Misc. global variables.
1493 */ 1492 */
1494 .data 1493 .data
1495GLOBAL(machineid) 1494GLOBAL(machineid)
1496 .long HP_320 | default to 320 1495 .long HP_320 | default to 320
1497 1496
1498GLOBAL(mmuid) 1497GLOBAL(mmuid)
1499 .long 0 | default to nothing 1498 .long 0 | default to nothing
1500 1499
1501GLOBAL(mmutype) 1500GLOBAL(mmutype)
1502 .long MMU_HP | default to HP MMU 1501 .long MMU_HP | default to HP MMU
1503 1502
1504GLOBAL(cputype) 1503GLOBAL(cputype)
1505 .long CPU_68020 | default to 68020 CPU 1504 .long CPU_68020 | default to 68020 CPU
1506 1505
1507GLOBAL(ectype) 1506GLOBAL(ectype)
1508 .long EC_NONE | external cache type, default to none 1507 .long EC_NONE | external cache type, default to none
1509 1508
1510GLOBAL(fputype) 1509GLOBAL(fputype)
1511 .long FPU_68882 | default to 68882 FPU 1510 .long FPU_68882 | default to 68882 FPU
1512 1511
1513GLOBAL(protorp) 1512GLOBAL(protorp)
1514 .long 0,0 | prototype root pointer 1513 .long 0,0 | prototype root pointer
1515 1514
1516GLOBAL(prototc) 1515GLOBAL(prototc)
1517 .long 0 | prototype translation control 1516 .long 0 | prototype translation control
1518 1517
1519GLOBAL(internalhpib) 1518GLOBAL(internalhpib)
1520 .long 1 | has internal HP-IB, default to yes 1519 .long 1 | has internal HP-IB, default to yes
1521 1520
1522GLOBAL(intiobase) 1521GLOBAL(intiobase)
1523 .long 0 | KVA of base of internal IO space 1522 .long 0 | KVA of base of internal IO space
1524 1523
1525GLOBAL(intiolimit) 1524GLOBAL(intiolimit)
1526 .long 0 | KVA of end of internal IO space 1525 .long 0 | KVA of end of internal IO space
1527 1526
1528GLOBAL(extiobase) 1527GLOBAL(extiobase)
1529 .long 0 | KVA of base of external IO space 1528 .long 0 | KVA of base of external IO space
1530 1529
1531GLOBAL(CLKbase) 1530GLOBAL(CLKbase)
1532 .long 0 | KVA of base of clock registers 1531 .long 0 | KVA of base of clock registers
1533 1532
1534GLOBAL(MMUbase) 1533GLOBAL(MMUbase)
1535 .long 0 | KVA of base of HP MMU registers 1534 .long 0 | KVA of base of HP MMU registers
1536 1535
1537#ifdef USELEDS 1536#ifdef USELEDS
1538ASLOCAL(heartbeat) 1537ASLOCAL(heartbeat)
1539 .long 0 | clock ticks since last heartbeat 1538 .long 0 | clock ticks since last heartbeat
1540 1539
1541ASLOCAL(beatstatus) 1540ASLOCAL(beatstatus)
1542 .long 0 | for determining a fast or slow throb 1541 .long 0 | for determining a fast or slow throb
1543#endif 1542#endif
1544 1543
1545#ifdef DEBUG 1544#ifdef DEBUG
1546ASGLOBAL(fulltflush) 1545ASGLOBAL(fulltflush)
1547 .long 0 1546 .long 0
1548 1547
1549ASGLOBAL(fullcflush) 1548ASGLOBAL(fullcflush)
1550 .long 0 1549 .long 0
1551#endif 1550#endif

cvs diff -r1.39 -r1.40 src/sys/arch/hp300/hp300/pmap_bootstrap.c (switch to unified diff)

--- src/sys/arch/hp300/hp300/pmap_bootstrap.c 2009/11/27 03:23:09 1.39
+++ src/sys/arch/hp300/hp300/pmap_bootstrap.c 2009/12/02 15:51:12 1.40
@@ -1,521 +1,520 @@ @@ -1,521 +1,520 @@
1/* $NetBSD: pmap_bootstrap.c,v 1.39 2009/11/27 03:23:09 rmind Exp $ */ 1/* $NetBSD: pmap_bootstrap.c,v 1.40 2009/12/02 15:51:12 tsutsui Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1991, 1993 4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer 8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department. 9 * Science Department.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors 19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 * 34 *
35 * @(#)pmap_bootstrap.c 8.1 (Berkeley) 6/10/93 35 * @(#)pmap_bootstrap.c 8.1 (Berkeley) 6/10/93
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.39 2009/11/27 03:23:09 rmind Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.40 2009/12/02 15:51:12 tsutsui Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/proc.h> 
43 42
44#include <machine/frame.h> 43#include <machine/frame.h>
45#include <machine/cpu.h> 44#include <machine/cpu.h>
46#include <machine/hp300spu.h> 45#include <machine/hp300spu.h>
47#include <machine/vmparam.h> 46#include <machine/vmparam.h>
48#include <machine/pte.h> 47#include <machine/pte.h>
49 48
50#include <hp300/hp300/clockreg.h> 49#include <hp300/hp300/clockreg.h>
51 50
52#include <uvm/uvm_extern.h> 51#include <uvm/uvm_extern.h>
53 52
54#define RELOC(v, t) *((t*)((uintptr_t)&(v) + firstpa)) 53#define RELOC(v, t) *((t*)((uintptr_t)&(v) + firstpa))
55#define RELOCPTR(v, t) ((t)((uintptr_t)RELOC((v), t) + firstpa)) 54#define RELOCPTR(v, t) ((t)((uintptr_t)RELOC((v), t) + firstpa))
56 55
57extern char *etext; 56extern char *etext;
58extern vaddr_t CLKbase, MMUbase; 57extern vaddr_t CLKbase, MMUbase;
59extern paddr_t bootinfo_pa; 58extern paddr_t bootinfo_pa;
60extern vaddr_t bootinfo_va; 59extern vaddr_t bootinfo_va;
61 60
62extern int maxmem, physmem; 61extern int maxmem, physmem;
63extern paddr_t avail_start, avail_end; 62extern paddr_t avail_start, avail_end;
64#ifdef M68K_MMU_HP 63#ifdef M68K_MMU_HP
65extern int pmap_aliasmask; 64extern int pmap_aliasmask;
66#endif 65#endif
67 66
68void pmap_bootstrap(paddr_t, paddr_t); 67void pmap_bootstrap(paddr_t, paddr_t);
69 68
70/* 69/*
71 * Special purpose kernel virtual addresses, used for mapping 70 * Special purpose kernel virtual addresses, used for mapping
72 * physical pages for a variety of temporary or permanent purposes: 71 * physical pages for a variety of temporary or permanent purposes:
73 * 72 *
74 * CADDR1, CADDR2: pmap zero/copy operations 73 * CADDR1, CADDR2: pmap zero/copy operations
75 * vmmap: /dev/mem, crash dumps, parity error checking 74 * vmmap: /dev/mem, crash dumps, parity error checking
76 * ledbase: SPU LEDs 75 * ledbase: SPU LEDs
77 * msgbufaddr: kernel message buffer 76 * msgbufaddr: kernel message buffer
78 */ 77 */
79void *CADDR1, *CADDR2, *ledbase; 78void *CADDR1, *CADDR2, *ledbase;
80char *vmmap; 79char *vmmap;
81void *msgbufaddr; 80void *msgbufaddr;
82 81
83/* 82/*
84 * Bootstrap the VM system. 83 * Bootstrap the VM system.
85 * 84 *
86 * Called with MMU off so we must relocate all global references by `firstpa' 85 * Called with MMU off so we must relocate all global references by `firstpa'
87 * (don't call any functions here!) `nextpa' is the first available physical 86 * (don't call any functions here!) `nextpa' is the first available physical
88 * memory address. Returns an updated first PA reflecting the memory we 87 * memory address. Returns an updated first PA reflecting the memory we
89 * have allocated. MMU is still off when we return. 88 * have allocated. MMU is still off when we return.
90 * 89 *
91 * XXX assumes sizeof(u_int) == sizeof(pt_entry_t) 90 * XXX assumes sizeof(u_int) == sizeof(pt_entry_t)
92 * XXX a PIC compiler would make this much easier. 91 * XXX a PIC compiler would make this much easier.
93 */ 92 */
94void 93void
95pmap_bootstrap(paddr_t nextpa, paddr_t firstpa) 94pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
96{ 95{
97 paddr_t kstpa, kptpa, kptmpa, lkptpa, p0upa; 96 paddr_t kstpa, kptpa, kptmpa, lkptpa, lwp0upa;
98 u_int nptpages, kstsize; 97 u_int nptpages, kstsize;
99 st_entry_t protoste, *ste; 98 st_entry_t protoste, *ste;
100 pt_entry_t protopte, *pte, *epte; 99 pt_entry_t protopte, *pte, *epte;
101 100
102 /* 101 /*
103 * Calculate important physical addresses: 102 * Calculate important physical addresses:
104 * 103 *
105 * kstpa kernel segment table 1 page (!040) 104 * kstpa kernel segment table 1 page (!040)
106 * N pages (040) 105 * N pages (040)
107 * 106 *
108 * kptpa statically allocated 107 * kptpa statically allocated
109 * kernel PT pages Sysptsize+ pages 108 * kernel PT pages Sysptsize+ pages
110 * 109 *
111 * [ Sysptsize is the number of pages of PT, IIOMAPSIZE and 110 * [ Sysptsize is the number of pages of PT, IIOMAPSIZE and
112 * EIOMAPSIZE are the number of PTEs, hence we need to round 111 * EIOMAPSIZE are the number of PTEs, hence we need to round
113 * the total to a page boundary with IO maps at the end. ] 112 * the total to a page boundary with IO maps at the end. ]
114 * 113 *
115 * kptmpa kernel PT map 1 page 114 * kptmpa kernel PT map 1 page
116 * 115 *
117 * lkptpa last kernel PT page 1 page 116 * lkptpa last kernel PT page 1 page
118 * 117 *
119 * p0upa proc 0 u-area UPAGES pages 118 * lwp0upa lwp 0 u-area UPAGES pages
120 * 119 *
121 * The KVA corresponding to any of these PAs is: 120 * The KVA corresponding to any of these PAs is:
122 * (PA - firstpa + KERNBASE). 121 * (PA - firstpa + KERNBASE).
123 */ 122 */
124 if (RELOC(mmutype, int) == MMU_68040) 123 if (RELOC(mmutype, int) == MMU_68040)
125 kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE); 124 kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
126 else 125 else
127 kstsize = 1; 126 kstsize = 1;
128 kstpa = nextpa; 127 kstpa = nextpa;
129 nextpa += kstsize * PAGE_SIZE; 128 nextpa += kstsize * PAGE_SIZE;
130 kptmpa = nextpa; 129 kptmpa = nextpa;
131 nextpa += PAGE_SIZE; 130 nextpa += PAGE_SIZE;
132 lkptpa = nextpa; 131 lkptpa = nextpa;
133 nextpa += PAGE_SIZE; 132 nextpa += PAGE_SIZE;
134 p0upa = nextpa; 133 lwp0upa = nextpa;
135 nextpa += USPACE; 134 nextpa += USPACE;
136 kptpa = nextpa; 135 kptpa = nextpa;
137 nptpages = RELOC(Sysptsize, int) + 136 nptpages = RELOC(Sysptsize, int) +
138 (IIOMAPSIZE + EIOMAPSIZE + NPTEPG - 1) / NPTEPG; 137 (IIOMAPSIZE + EIOMAPSIZE + NPTEPG - 1) / NPTEPG;
139 nextpa += nptpages * PAGE_SIZE; 138 nextpa += nptpages * PAGE_SIZE;
140 139
141 /* 140 /*
142 * Initialize segment table and kernel page table map. 141 * Initialize segment table and kernel page table map.
143 * 142 *
144 * On 68030s and earlier MMUs the two are identical except for 143 * On 68030s and earlier MMUs the two are identical except for
145 * the valid bits so both are initialized with essentially the 144 * the valid bits so both are initialized with essentially the
146 * same values. On the 68040, which has a mandatory 3-level 145 * same values. On the 68040, which has a mandatory 3-level
147 * structure, the segment table holds the level 1 table and part 146 * structure, the segment table holds the level 1 table and part
148 * (or all) of the level 2 table and hence is considerably 147 * (or all) of the level 2 table and hence is considerably
149 * different. Here the first level consists of 128 descriptors 148 * different. Here the first level consists of 128 descriptors
150 * (512 bytes) each mapping 32mb of address space. Each of these 149 * (512 bytes) each mapping 32mb of address space. Each of these
151 * points to blocks of 128 second level descriptors (512 bytes) 150 * points to blocks of 128 second level descriptors (512 bytes)
152 * each mapping 256kb. Note that there may be additional "segment 151 * each mapping 256kb. Note that there may be additional "segment
153 * table" pages depending on how large MAXKL2SIZE is. 152 * table" pages depending on how large MAXKL2SIZE is.
154 * 153 *
155 * Portions of the last two segment of KVA space (0xFF800000 - 154 * Portions of the last two segment of KVA space (0xFF800000 -
156 * 0xFFFFFFFF) are mapped for a couple of purposes. 155 * 0xFFFFFFFF) are mapped for a couple of purposes.
157 * The first segment (0xFF800000 - 0xFFBFFFFF) is mapped 156 * The first segment (0xFF800000 - 0xFFBFFFFF) is mapped
158 * for the kernel page tables. 157 * for the kernel page tables.
159 * The very last page (0xFFFFF000) in the second segment is mapped 158 * The very last page (0xFFFFF000) in the second segment is mapped
160 * to the last physical page of RAM to give us a region in which 159 * to the last physical page of RAM to give us a region in which
161 * PA == VA. We use the first part of this page for enabling 160 * PA == VA. We use the first part of this page for enabling
162 * and disabling mapping. The last part of this page also contains 161 * and disabling mapping. The last part of this page also contains
163 * info left by the boot ROM. 162 * info left by the boot ROM.
164 * 163 *
165 * XXX cramming two levels of mapping into the single "segment" 164 * XXX cramming two levels of mapping into the single "segment"
166 * table on the 68040 is intended as a temporary hack to get things 165 * table on the 68040 is intended as a temporary hack to get things
167 * working. The 224mb of address space that this allows will most 166 * working. The 224mb of address space that this allows will most
168 * likely be insufficient in the future (at least for the kernel). 167 * likely be insufficient in the future (at least for the kernel).
169 */ 168 */
170 if (RELOC(mmutype, int) == MMU_68040) { 169 if (RELOC(mmutype, int) == MMU_68040) {
171 int num; 170 int num;
172 171
173 /* 172 /*
174 * First invalidate the entire "segment table" pages 173 * First invalidate the entire "segment table" pages
175 * (levels 1 and 2 have the same "invalid" value). 174 * (levels 1 and 2 have the same "invalid" value).
176 */ 175 */
177 pte = (u_int *)kstpa; 176 pte = (u_int *)kstpa;
178 epte = &pte[kstsize * NPTEPG]; 177 epte = &pte[kstsize * NPTEPG];
179 while (pte < epte) 178 while (pte < epte)
180 *pte++ = SG_NV; 179 *pte++ = SG_NV;
181 /* 180 /*
182 * Initialize level 2 descriptors (which immediately 181 * Initialize level 2 descriptors (which immediately
183 * follow the level 1 table). We need: 182 * follow the level 1 table). We need:
184 * NPTEPG / SG4_LEV3SIZE 183 * NPTEPG / SG4_LEV3SIZE
185 * level 2 descriptors to map each of the nptpages 184 * level 2 descriptors to map each of the nptpages
186 * pages of PTEs. Note that we set the "used" bit 185 * pages of PTEs. Note that we set the "used" bit
187 * now to save the HW the expense of doing it. 186 * now to save the HW the expense of doing it.
188 */ 187 */
189 num = nptpages * (NPTEPG / SG4_LEV3SIZE); 188 num = nptpages * (NPTEPG / SG4_LEV3SIZE);
190 pte = &((u_int *)kstpa)[SG4_LEV1SIZE]; 189 pte = &((u_int *)kstpa)[SG4_LEV1SIZE];
191 epte = &pte[num]; 190 epte = &pte[num];
192 protoste = kptpa | SG_U | SG_RW | SG_V; 191 protoste = kptpa | SG_U | SG_RW | SG_V;
193 while (pte < epte) { 192 while (pte < epte) {
194 *pte++ = protoste; 193 *pte++ = protoste;
195 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t)); 194 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
196 } 195 }
197 /* 196 /*
198 * Initialize level 1 descriptors. We need: 197 * Initialize level 1 descriptors. We need:
199 * roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE 198 * roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE
200 * level 1 descriptors to map the `num' level 2's. 199 * level 1 descriptors to map the `num' level 2's.
201 */ 200 */
202 pte = (u_int *)kstpa; 201 pte = (u_int *)kstpa;
203 epte = &pte[roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE]; 202 epte = &pte[roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE];
204 protoste = (u_int)&pte[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V; 203 protoste = (u_int)&pte[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
205 while (pte < epte) { 204 while (pte < epte) {
206 *pte++ = protoste; 205 *pte++ = protoste;
207 protoste += (SG4_LEV2SIZE * sizeof(st_entry_t)); 206 protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
208 } 207 }
209 /* 208 /*
210 * Initialize the final level 1 descriptor to map the last 209 * Initialize the final level 1 descriptor to map the last
211 * block of level 2 descriptors. 210 * block of level 2 descriptors.
212 */ 211 */
213 ste = &((u_int *)kstpa)[SG4_LEV1SIZE-1]; 212 ste = &((u_int *)kstpa)[SG4_LEV1SIZE-1];
214 pte = &((u_int *)kstpa)[kstsize*NPTEPG - SG4_LEV2SIZE]; 213 pte = &((u_int *)kstpa)[kstsize*NPTEPG - SG4_LEV2SIZE];
215 *ste = (u_int)pte | SG_U | SG_RW | SG_V; 214 *ste = (u_int)pte | SG_U | SG_RW | SG_V;
216 /* 215 /*
217 * Now initialize the final portion of that block of 216 * Now initialize the final portion of that block of
218 * descriptors to map kptmpa and the "last PT page". 217 * descriptors to map kptmpa and the "last PT page".
219 */ 218 */
220 pte = &((u_int *)kstpa)[kstsize*NPTEPG - NPTEPG/SG4_LEV3SIZE*2]; 219 pte = &((u_int *)kstpa)[kstsize*NPTEPG - NPTEPG/SG4_LEV3SIZE*2];
221 epte = &pte[NPTEPG/SG4_LEV3SIZE]; 220 epte = &pte[NPTEPG/SG4_LEV3SIZE];
222 protoste = kptmpa | SG_U | SG_RW | SG_V; 221 protoste = kptmpa | SG_U | SG_RW | SG_V;
223 while (pte < epte) { 222 while (pte < epte) {
224 *pte++ = protoste; 223 *pte++ = protoste;
225 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t)); 224 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
226 } 225 }
227 epte = &pte[NPTEPG/SG4_LEV3SIZE]; 226 epte = &pte[NPTEPG/SG4_LEV3SIZE];
228 protoste = lkptpa | SG_U | SG_RW | SG_V; 227 protoste = lkptpa | SG_U | SG_RW | SG_V;
229 while (pte < epte) { 228 while (pte < epte) {
230 *pte++ = protoste; 229 *pte++ = protoste;
231 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t)); 230 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
232 } 231 }
233 /* 232 /*
234 * Initialize Sysptmap 233 * Initialize Sysptmap
235 */ 234 */
236 pte = (u_int *)kptmpa; 235 pte = (u_int *)kptmpa;
237 epte = &pte[nptpages]; 236 epte = &pte[nptpages];
238 protopte = kptpa | PG_RW | PG_CI | PG_V; 237 protopte = kptpa | PG_RW | PG_CI | PG_V;
239 while (pte < epte) { 238 while (pte < epte) {
240 *pte++ = protopte; 239 *pte++ = protopte;
241 protopte += PAGE_SIZE; 240 protopte += PAGE_SIZE;
242 } 241 }
243 /* 242 /*
244 * Invalidate all but the last remaining entry. 243 * Invalidate all but the last remaining entry.
245 */ 244 */
246 epte = &((u_int *)kptmpa)[NPTEPG-2]; 245 epte = &((u_int *)kptmpa)[NPTEPG-2];
247 while (pte < epte) { 246 while (pte < epte) {
248 *pte++ = PG_NV; 247 *pte++ = PG_NV;
249 } 248 }
250 /* 249 /*
251 * Initialize the last ones to point to kptmpa and the page 250 * Initialize the last ones to point to kptmpa and the page
252 * table page allocated earlier. 251 * table page allocated earlier.
253 */ 252 */
254 *pte = kptmpa | PG_RW | PG_CI | PG_V; 253 *pte = kptmpa | PG_RW | PG_CI | PG_V;
255 pte++; 254 pte++;
256 *pte = lkptpa | PG_RW | PG_CI | PG_V; 255 *pte = lkptpa | PG_RW | PG_CI | PG_V;
257 } else { 256 } else {
258 /* 257 /*
259 * Map the page table pages in both the HW segment table 258 * Map the page table pages in both the HW segment table
260 * and the software Sysptmap. 259 * and the software Sysptmap.
261 */ 260 */
262 ste = (u_int *)kstpa; 261 ste = (u_int *)kstpa;
263 pte = (u_int *)kptmpa; 262 pte = (u_int *)kptmpa;
264 epte = &pte[nptpages]; 263 epte = &pte[nptpages];
265 protoste = kptpa | SG_RW | SG_V; 264 protoste = kptpa | SG_RW | SG_V;
266 protopte = kptpa | PG_RW | PG_CI | PG_V; 265 protopte = kptpa | PG_RW | PG_CI | PG_V;
267 while (pte < epte) { 266 while (pte < epte) {
268 *ste++ = protoste; 267 *ste++ = protoste;
269 *pte++ = protopte; 268 *pte++ = protopte;
270 protoste += PAGE_SIZE; 269 protoste += PAGE_SIZE;
271 protopte += PAGE_SIZE; 270 protopte += PAGE_SIZE;
272 } 271 }
273 /* 272 /*
274 * Invalidate all but the last remaining entries in both. 273 * Invalidate all but the last remaining entries in both.
275 */ 274 */
276 epte = &((u_int *)kptmpa)[NPTEPG-2]; 275 epte = &((u_int *)kptmpa)[NPTEPG-2];
277 while (pte < epte) { 276 while (pte < epte) {
278 *ste++ = SG_NV; 277 *ste++ = SG_NV;
279 *pte++ = PG_NV; 278 *pte++ = PG_NV;
280 } 279 }
281 /* 280 /*
282 * Initialize the last ones to point to kptmpa and the page 281 * Initialize the last ones to point to kptmpa and the page
283 * table page allocated earlier. 282 * table page allocated earlier.
284 */ 283 */
285 *ste = kptmpa | SG_RW | SG_V; 284 *ste = kptmpa | SG_RW | SG_V;
286 *pte = kptmpa | PG_RW | PG_CI | PG_V; 285 *pte = kptmpa | PG_RW | PG_CI | PG_V;
287 ste++; 286 ste++;
288 pte++; 287 pte++;
289 *ste = lkptpa | SG_RW | SG_V; 288 *ste = lkptpa | SG_RW | SG_V;
290 *pte = lkptpa | PG_RW | PG_CI | PG_V; 289 *pte = lkptpa | PG_RW | PG_CI | PG_V;
291 } 290 }
292 /* 291 /*
293 * Invalidate all but the final entry in the last kernel PT page 292 * Invalidate all but the final entry in the last kernel PT page
294 * (u-area PTEs will be validated later). The final entry maps 293 * (u-area PTEs will be validated later). The final entry maps
295 * the last page of physical memory. 294 * the last page of physical memory.
296 */ 295 */
297 pte = (u_int *)lkptpa; 296 pte = (u_int *)lkptpa;
298 epte = &pte[NPTEPG-1]; 297 epte = &pte[NPTEPG-1];
299 while (pte < epte) 298 while (pte < epte)
300 *pte++ = PG_NV; 299 *pte++ = PG_NV;
301 *pte = MAXADDR | PG_RW | PG_CI | PG_V; 300 *pte = MAXADDR | PG_RW | PG_CI | PG_V;
302 /* 301 /*
303 * Initialize kernel page table. 302 * Initialize kernel page table.
304 * Start by invalidating the `nptpages' that we have allocated. 303 * Start by invalidating the `nptpages' that we have allocated.
305 */ 304 */
306 pte = (u_int *)kptpa; 305 pte = (u_int *)kptpa;
307 epte = &pte[nptpages * NPTEPG]; 306 epte = &pte[nptpages * NPTEPG];
308 while (pte < epte) 307 while (pte < epte)
309 *pte++ = PG_NV; 308 *pte++ = PG_NV;
310 309
311 /* 310 /*
312 * The page of kernel text is zero-filled in locore.s, 311 * The page of kernel text is zero-filled in locore.s,
313 * and not mapped (at VA 0). The boot loader places the 312 * and not mapped (at VA 0). The boot loader places the
314 * bootinfo here after the kernel is loaded. Remember 313 * bootinfo here after the kernel is loaded. Remember
315 * the physical address; we'll map it to a virtual address 314 * the physical address; we'll map it to a virtual address
316 * later. 315 * later.
317 */ 316 */
318 RELOC(bootinfo_pa, paddr_t) = firstpa; 317 RELOC(bootinfo_pa, paddr_t) = firstpa;
319 318
320 /* 319 /*
321 * Validate PTEs for kernel text (RO). The first page 320 * Validate PTEs for kernel text (RO). The first page
322 * of kernel text remains invalid; see locore.s 321 * of kernel text remains invalid; see locore.s
323 */ 322 */
324 pte = &((u_int *)kptpa)[m68k_btop(KERNBASE + PAGE_SIZE)]; 323 pte = &((u_int *)kptpa)[m68k_btop(KERNBASE + PAGE_SIZE)];
325 epte = &pte[m68k_btop(m68k_trunc_page(&etext))]; 324 epte = &pte[m68k_btop(m68k_trunc_page(&etext))];
326 protopte = (firstpa + PAGE_SIZE) | PG_RO | PG_V; 325 protopte = (firstpa + PAGE_SIZE) | PG_RO | PG_V;
327 while (pte < epte) { 326 while (pte < epte) {
328 *pte++ = protopte; 327 *pte++ = protopte;
329 protopte += PAGE_SIZE; 328 protopte += PAGE_SIZE;
330 } 329 }
331 /* 330 /*
332 * Validate PTEs for kernel data/bss, dynamic data allocated 331 * Validate PTEs for kernel data/bss, dynamic data allocated
333 * by us so far (nextpa - firstpa bytes), and pages for proc0 332 * by us so far (nextpa - firstpa bytes), and pages for lwp0
334 * u-area and page table allocated below (RW). 333 * u-area and page table allocated below (RW).
335 */ 334 */
336 epte = &((u_int *)kptpa)[m68k_btop(nextpa - firstpa)]; 335 epte = &((u_int *)kptpa)[m68k_btop(nextpa - firstpa)];
337 protopte = (protopte & ~PG_PROT) | PG_RW; 336 protopte = (protopte & ~PG_PROT) | PG_RW;
338 /* 337 /*
339 * Enable copy-back caching of data pages 338 * Enable copy-back caching of data pages
340 */ 339 */
341 if (RELOC(mmutype, int) == MMU_68040) 340 if (RELOC(mmutype, int) == MMU_68040)
342 protopte |= PG_CCB; 341 protopte |= PG_CCB;
343 while (pte < epte) { 342 while (pte < epte) {
344 *pte++ = protopte; 343 *pte++ = protopte;
345 protopte += PAGE_SIZE; 344 protopte += PAGE_SIZE;
346 } 345 }
347 /* 346 /*
348 * Finally, validate the internal IO space PTEs (RW+CI). 347 * Finally, validate the internal IO space PTEs (RW+CI).
349 * We do this here since the 320/350 MMU registers (also 348 * We do this here since the 320/350 MMU registers (also
350 * used, but to a lesser extent, on other models) are mapped 349 * used, but to a lesser extent, on other models) are mapped
351 * in this range and it would be nice to be able to access 350 * in this range and it would be nice to be able to access
352 * them after the MMU is turned on. 351 * them after the MMU is turned on.
353 */ 352 */
354 353
355#define PTE2VA(pte) m68k_ptob(pte - ((pt_entry_t *)kptpa)) 354#define PTE2VA(pte) m68k_ptob(pte - ((pt_entry_t *)kptpa))
356 355
357 protopte = INTIOBASE | PG_RW | PG_CI | PG_V; 356 protopte = INTIOBASE | PG_RW | PG_CI | PG_V;
358 epte = &pte[IIOMAPSIZE]; 357 epte = &pte[IIOMAPSIZE];
359 RELOC(intiobase, char *) = (char *)PTE2VA(pte); 358 RELOC(intiobase, char *) = (char *)PTE2VA(pte);
360 RELOC(intiolimit, char *) = (char *)PTE2VA(epte); 359 RELOC(intiolimit, char *) = (char *)PTE2VA(epte);
361 while (pte < epte) { 360 while (pte < epte) {
362 *pte++ = protopte; 361 *pte++ = protopte;
363 protopte += PAGE_SIZE; 362 protopte += PAGE_SIZE;
364 } 363 }
365 RELOC(extiobase, char *) = (char *)PTE2VA(pte); 364 RELOC(extiobase, char *) = (char *)PTE2VA(pte);
366 pte += EIOMAPSIZE; 365 pte += EIOMAPSIZE;
367 RELOC(virtual_avail, vaddr_t) = PTE2VA(pte); 366 RELOC(virtual_avail, vaddr_t) = PTE2VA(pte);
368 367
369 /* 368 /*
370 * Calculate important exported kernel virtual addresses 369 * Calculate important exported kernel virtual addresses
371 */ 370 */
372 /* 371 /*
373 * Sysseg: base of kernel segment table 372 * Sysseg: base of kernel segment table
374 */ 373 */
375 RELOC(Sysseg, st_entry_t *) = 374 RELOC(Sysseg, st_entry_t *) =
376 (st_entry_t *)(kstpa - firstpa); 375 (st_entry_t *)(kstpa - firstpa);
377 /* 376 /*
378 * Sysptmap: base of kernel page table map 377 * Sysptmap: base of kernel page table map
379 */ 378 */
380 RELOC(Sysptmap, pt_entry_t *) = 379 RELOC(Sysptmap, pt_entry_t *) =
381 (pt_entry_t *)(kptmpa - firstpa); 380 (pt_entry_t *)(kptmpa - firstpa);
382 /* 381 /*
383 * Sysmap: kernel page table (as mapped through Sysptmap) 382 * Sysmap: kernel page table (as mapped through Sysptmap)
384 * Allocated at the end of KVA space. 383 * Allocated at the end of KVA space.
385 */ 384 */
386 RELOC(Sysmap, pt_entry_t *) = 385 RELOC(Sysmap, pt_entry_t *) =
387 (pt_entry_t *)m68k_ptob((NPTEPG - 2) * NPTEPG); 386 (pt_entry_t *)m68k_ptob((NPTEPG - 2) * NPTEPG);
388 /* 387 /*
389 * CLKbase, MMUbase: important registers in internal IO space 388 * CLKbase, MMUbase: important registers in internal IO space
390 * accessed from assembly language. 389 * accessed from assembly language.
391 */ 390 */
392 RELOC(CLKbase, vaddr_t) = 391 RELOC(CLKbase, vaddr_t) =
393 (vaddr_t)RELOC(intiobase, char *) + CLKBASE; 392 (vaddr_t)RELOC(intiobase, char *) + CLKBASE;
394 RELOC(MMUbase, vaddr_t) = 393 RELOC(MMUbase, vaddr_t) =
395 (vaddr_t)RELOC(intiobase, char *) + MMUBASE; 394 (vaddr_t)RELOC(intiobase, char *) + MMUBASE;
396 395
397 /* 396 /*
398 * Setup u-area for process 0. 397 * Setup u-area for lwp 0.
399 */ 398 */
400 /* 399 /*
401 * Zero the u-area. 400 * Zero the u-area.
402 * NOTE: `pte' and `epte' aren't PTEs here. 401 * NOTE: `pte' and `epte' aren't PTEs here.
403 */ 402 */
404 pte = (u_int *)p0upa; 403 pte = (u_int *)lwp0upa;
405 epte = (u_int *)(p0upa + USPACE); 404 epte = (u_int *)(lwp0upa + USPACE);
406 while (pte < epte) 405 while (pte < epte)
407 *pte++ = 0; 406 *pte++ = 0;
408 /* 407 /*
409 * Remember the u-area address so it can be loaded in the 408 * Remember the u-area address so it can be loaded in the lwp0
410 * proc struct p_addr field later. 409 * via uvm_lwp_setuarea() later in pmap_bootstrap_finalize().
411 */ 410 */
412 RELOC(lwp0.l_addr, struct user *) = (struct user *)(p0upa - firstpa); 411 RELOC(lwp0uarea, vaddr_t) = lwp0upa - firstpa;
413 412
414 /* 413 /*
415 * VM data structures are now initialized, set up data for 414 * VM data structures are now initialized, set up data for
416 * the pmap module. 415 * the pmap module.
417 * 416 *
418 * Note about avail_end: msgbuf is initialized just after 417 * Note about avail_end: msgbuf is initialized just after
419 * avail_end in machdep.c. Since the last page is used 418 * avail_end in machdep.c. Since the last page is used
420 * for rebooting the system (code is copied there and 419 * for rebooting the system (code is copied there and
421 * excution continues from copied code before the MMU 420 * excution continues from copied code before the MMU
422 * is disabled), the msgbuf will get trounced between 421 * is disabled), the msgbuf will get trounced between
423 * reboots if it's placed in the last physical page. 422 * reboots if it's placed in the last physical page.
424 * To work around this, we move avail_end back one more 423 * To work around this, we move avail_end back one more
425 * page so the msgbuf can be preserved. 424 * page so the msgbuf can be preserved.
426 */ 425 */
427 RELOC(avail_start, paddr_t) = nextpa; 426 RELOC(avail_start, paddr_t) = nextpa;
428 RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int)) - 427 RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int)) -
429 (m68k_round_page(MSGBUFSIZE) + m68k_ptob(1)); 428 (m68k_round_page(MSGBUFSIZE) + m68k_ptob(1));
430 RELOC(mem_size, vsize_t) = m68k_ptob(RELOC(physmem, int)); 429 RELOC(mem_size, vsize_t) = m68k_ptob(RELOC(physmem, int));
431 RELOC(virtual_end, vaddr_t) = VM_MAX_KERNEL_ADDRESS; 430 RELOC(virtual_end, vaddr_t) = VM_MAX_KERNEL_ADDRESS;
432 431
433#ifdef M68K_MMU_HP 432#ifdef M68K_MMU_HP
434 /* 433 /*
435 * Determine VA aliasing distance if any 434 * Determine VA aliasing distance if any
436 */ 435 */
437 if (RELOC(ectype, int) == EC_VIRT) { 436 if (RELOC(ectype, int) == EC_VIRT) {
438 if (RELOC(machineid, int) == HP_320) 437 if (RELOC(machineid, int) == HP_320)
439 RELOC(pmap_aliasmask, int) = 0x3fff; /* 16k */ 438 RELOC(pmap_aliasmask, int) = 0x3fff; /* 16k */
440 else if (RELOC(machineid, int) == HP_350) 439 else if (RELOC(machineid, int) == HP_350)
441 RELOC(pmap_aliasmask, int) = 0x7fff; /* 32k */ 440 RELOC(pmap_aliasmask, int) = 0x7fff; /* 32k */
442 } 441 }
443#endif 442#endif
444 443
445 /* 444 /*
446 * Initialize protection array. 445 * Initialize protection array.
447 * XXX don't use a switch statement, it might produce an 446 * XXX don't use a switch statement, it might produce an
448 * absolute "jmp" table. 447 * absolute "jmp" table.
449 */ 448 */
450 { 449 {
451 u_int *kp; 450 u_int *kp;
452 451
453 kp = &RELOC(protection_codes, u_int); 452 kp = &RELOC(protection_codes, u_int);
454 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_NONE] = 0; 453 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_NONE] = 0;
455 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_NONE] = PG_RO; 454 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_NONE] = PG_RO;
456 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO; 455 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
457 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO; 456 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
458 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW; 457 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
459 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW; 458 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
460 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW; 459 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
461 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW; 460 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
462 } 461 }
463 462
464 /* 463 /*
465 * Kernel page/segment table allocated above, 464 * Kernel page/segment table allocated above,
466 * just initialize pointers. 465 * just initialize pointers.
467 */ 466 */
468 { 467 {
469 struct pmap *kpm; 468 struct pmap *kpm;
470 469
471 kpm = RELOCPTR(kernel_pmap_ptr, struct pmap *); 470 kpm = RELOCPTR(kernel_pmap_ptr, struct pmap *);
472 471
473 kpm->pm_stab = RELOC(Sysseg, st_entry_t *); 472 kpm->pm_stab = RELOC(Sysseg, st_entry_t *);
474 kpm->pm_ptab = RELOC(Sysmap, pt_entry_t *); 473 kpm->pm_ptab = RELOC(Sysmap, pt_entry_t *);
475 simple_lock_init(&kpm->pm_lock); 474 simple_lock_init(&kpm->pm_lock);
476 kpm->pm_count = 1; 475 kpm->pm_count = 1;
477 kpm->pm_stpa = (st_entry_t *)kstpa; 476 kpm->pm_stpa = (st_entry_t *)kstpa;
478 /* 477 /*
479 * For the 040 we also initialize the free level 2 478 * For the 040 we also initialize the free level 2
480 * descriptor mask noting that we have used: 479 * descriptor mask noting that we have used:
481 * 0: level 1 table 480 * 0: level 1 table
482 * 1 to `num': map page tables 481 * 1 to `num': map page tables
483 * MAXKL2SIZE-1: maps kptmpa and last-page page table 482 * MAXKL2SIZE-1: maps kptmpa and last-page page table
484 */ 483 */
485 if (RELOC(mmutype, int) == MMU_68040) { 484 if (RELOC(mmutype, int) == MMU_68040) {
486 int num; 485 int num;
487 486
488 kpm->pm_stfree = ~l2tobm(0); 487 kpm->pm_stfree = ~l2tobm(0);
489 num = roundup(nptpages * (NPTEPG / SG4_LEV3SIZE), 488 num = roundup(nptpages * (NPTEPG / SG4_LEV3SIZE),
490 SG4_LEV2SIZE) / SG4_LEV2SIZE; 489 SG4_LEV2SIZE) / SG4_LEV2SIZE;
491 while (num) 490 while (num)
492 kpm->pm_stfree &= ~l2tobm(num--); 491 kpm->pm_stfree &= ~l2tobm(num--);
493 kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1); 492 kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
494 for (num = MAXKL2SIZE; 493 for (num = MAXKL2SIZE;
495 num < sizeof(kpm->pm_stfree)*NBBY; 494 num < sizeof(kpm->pm_stfree)*NBBY;
496 num++) 495 num++)
497 kpm->pm_stfree &= ~l2tobm(num); 496 kpm->pm_stfree &= ~l2tobm(num);
498 } 497 }
499 } 498 }
500 499
501 /* 500 /*
502 * Allocate some fixed, special purpose kernel virtual addresses 501 * Allocate some fixed, special purpose kernel virtual addresses
503 */ 502 */
504 { 503 {
505 vaddr_t va = RELOC(virtual_avail, vaddr_t); 504 vaddr_t va = RELOC(virtual_avail, vaddr_t);
506 505
507 RELOC(bootinfo_va, vaddr_t) = (vaddr_t)va; 506 RELOC(bootinfo_va, vaddr_t) = (vaddr_t)va;
508 va += PAGE_SIZE; 507 va += PAGE_SIZE;
509 RELOC(CADDR1, void *) = (void *)va; 508 RELOC(CADDR1, void *) = (void *)va;
510 va += PAGE_SIZE; 509 va += PAGE_SIZE;
511 RELOC(CADDR2, void *) = (void *)va; 510 RELOC(CADDR2, void *) = (void *)va;
512 va += PAGE_SIZE; 511 va += PAGE_SIZE;
513 RELOC(vmmap, void *) = (void *)va; 512 RELOC(vmmap, void *) = (void *)va;
514 va += PAGE_SIZE; 513 va += PAGE_SIZE;
515 RELOC(ledbase, void *) = (void *)va; 514 RELOC(ledbase, void *) = (void *)va;
516 va += PAGE_SIZE; 515 va += PAGE_SIZE;
517 RELOC(msgbufaddr, void *) = (void *)va; 516 RELOC(msgbufaddr, void *) = (void *)va;
518 va += m68k_round_page(MSGBUFSIZE); 517 va += m68k_round_page(MSGBUFSIZE);
519 RELOC(virtual_avail, vaddr_t) = va; 518 RELOC(virtual_avail, vaddr_t) = va;
520 } 519 }
521} 520}