1 /* $NetBSD: pmap_bootstrap.c,v 1.43 2024/01/18 04:07:38 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
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
21 * without specific prior written permission.
22 *
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
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
33 * SUCH DAMAGE.
34 *
35 * @(#)pmap_bootstrap.c 8.1 (Berkeley) 6/10/93
36 */
37 /*
38 * news68k/pmap_bootstrap.c - from hp300 and mvme68k
39 */
40
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.43 2024/01/18 04:07:38 thorpej Exp $");
43
44 #include "opt_m68k_arch.h"
45 #include "opt_newsconf.h"
46
47 #include <sys/param.h>
48 #include <uvm/uvm_extern.h>
49
50 #include <machine/cpu.h>
51 #include <machine/pte.h>
52 #include <machine/vmparam.h>
53
54 #define RELOC(v, t) *((t*)((uintptr_t)&(v) + firstpa))
55
56 extern char *etext;
57 extern char *extiobase;
58 extern char *cache_ctl, *cache_clr;
59
60 extern int maxmem;
61 extern paddr_t avail_start, avail_end;
62
63 /*
64 * Special purpose kernel virtual addresses, used for mapping
65 * physical pages for a variety of temporary or permanent purposes:
66 *
67 * CADDR1, CADDR2: pmap zero/copy operations
68 * vmmap: /dev/mem, crash dumps, parity error checking
69 * msgbufaddr: kernel message buffer
70 */
71 void *CADDR1, *CADDR2;
72 char *vmmap;
73 void *msgbufaddr;
74
75 void pmap_bootstrap(paddr_t, paddr_t);
76
77 /*
78 * Bootstrap the VM system.
79 *
80 * Called with MMU off so we must relocate all global references by `firstpa'
81 * (don't call any functions here!) `nextpa' is the first available physical
82 * memory address. Returns an updated first PA reflecting the memory we
83 * have allocated. MMU is still off when we return.
84 *
85 * XXX assumes sizeof(u_int) == sizeof(pt_entry_t)
86 * XXX a PIC compiler would make this much easier.
87 */
88 void
pmap_bootstrap(paddr_t nextpa,paddr_t firstpa)89 pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
90 {
91 paddr_t lwp0upa, kstpa, kptmpa, kptpa;
92 u_int nptpages, kstsize;
93 st_entry_t protoste, *ste, *este;
94 pt_entry_t protopte, *pte, *epte;
95 u_int iiomapsize, eiomapsize;
96 #ifdef M68040
97 u_int stfree = 0; /* XXX: gcc -Wuninitialized */
98 #endif
99
100 /*
101 * Calculate important physical addresses:
102 *
103 * lwp0upa lwp0 u-area UPAGES pages
104 *
105 * kstpa kernel segment table 1 page (!040)
106 * N pages (040)
107 *
108 * kptmpa kernel PT map 1 page
109 *
110 * kptpa statically allocated
111 * kernel PT pages Sysptsize+ pages
112 *
113 * [ Sysptsize is the number of pages of PT, and IIOMAPSIZE and
114 * EIOMAPSIZE are the number of PTEs, hence we need to round
115 * the total to a page boundary with IO maps at the end. ]
116 *
117 * The KVA corresponding to any of these PAs is:
118 * (PA - firstpa + KERNBASE).
119 */
120
121 /*
122 * XXX now we are using tt0 register to map IIO.
123 */
124 iiomapsize = m68k_btop(RELOC(intiotop_phys, u_int) -
125 RELOC(intiobase_phys, u_int));
126 eiomapsize = m68k_btop(RELOC(extiotop_phys, u_int) -
127 RELOC(extiobase_phys, u_int));
128
129 lwp0upa = nextpa;
130 nextpa += USPACE;
131 #ifdef M68040
132 if (RELOC(mmutype, int) == MMU_68040)
133 kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
134 else
135 #endif
136 kstsize = 1;
137 kstpa = nextpa;
138 nextpa += kstsize * PAGE_SIZE;
139 kptmpa = nextpa;
140 nextpa += PAGE_SIZE;
141 kptpa = nextpa;
142 nptpages = RELOC(Sysptsize, int) + howmany(RELOC(physmem, int), NPTEPG) +
143 (iiomapsize + eiomapsize + NPTEPG - 1) / NPTEPG;
144 nextpa += nptpages * PAGE_SIZE;
145
146 /*
147 * Clear all PTEs to zero
148 */
149 for (pte = (pt_entry_t *)kstpa; pte < (pt_entry_t *)nextpa; pte++)
150 *pte = 0;
151
152 /*
153 * Initialize segment table and kernel page table map.
154 *
155 * On 68030s and earlier MMUs the two are identical except for
156 * the valid bits so both are initialized with essentially the
157 * same values. On the 68040, which has a mandatory 3-level
158 * structure, the segment table holds the level 1 table and part
159 * (or all) of the level 2 table and hence is considerably
160 * different. Here the first level consists of 128 descriptors
161 * (512 bytes) each mapping 32mb of address space. Each of these
162 * points to blocks of 128 second level descriptors (512 bytes)
163 * each mapping 256kb. Note that there may be additional "segment
164 * table" pages depending on how large MAXKL2SIZE is.
165 *
166 * Portions of the last segment of KVA space (0xBFC00000 -
167 * 0xBFFFFFFF) are mapped for the kernel page tables.
168 *
169 * The region 0xC0000000 - 0xCFFFFFFF is mapped via the %tt1 register
170 * for RAM accesses for PROM.
171 * The region 0xE0000000 - 0xFFFFFFFF is mapped via the %tt0 register
172 * for I/O accesses.
173 *
174 * XXX cramming two levels of mapping into the single "segment"
175 * table on the 68040 is intended as a temporary hack to get things
176 * working. The 224mb of address space that this allows will most
177 * likely be insufficient in the future (at least for the kernel).
178 */
179 #ifdef M68040
180 if (RELOC(mmutype, int) == MMU_68040) {
181 int nl1desc, nl2desc, i;
182
183 /*
184 * First invalidate the entire "segment table" pages
185 * (levels 1 and 2 have the same "invalid" value).
186 */
187 ste = (st_entry_t *)kstpa;
188 este = &ste[kstsize * NPTEPG];
189 while (ste < este)
190 *ste++ = SG_NV;
191 /*
192 * Initialize level 2 descriptors (which immediately
193 * follow the level 1 table). We need:
194 * NPTEPG / SG4_LEV3SIZE
195 * level 2 descriptors to map each of the nptpages
196 * pages of PTEs. Note that we set the "used" bit
197 * now to save the HW the expense of doing it.
198 */
199 nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
200 ste = (st_entry_t *)kstpa;
201 ste = &ste[SG4_LEV1SIZE];
202 este = &ste[nl2desc];
203 protoste = kptpa | SG_U | SG_RW | SG_V;
204 while (ste < este) {
205 *ste++ = protoste;
206 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
207 }
208 /*
209 * Initialize level 1 descriptors. We need:
210 * howmany(nl2desc, SG4_LEV2SIZE)
211 * level 1 descriptors to map the `nl2desc' level 2's.
212 */
213 nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
214 ste = (st_entry_t *)kstpa;
215 este = &ste[nl1desc];
216 protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
217 while (ste < este) {
218 *ste++ = protoste;
219 protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
220 }
221 /*
222 * Initialize the level 1 descriptor correspond to
223 * SYSMAP_VA to map the last block of level 2 descriptors
224 * for Sysptmap.
225 */
226 ste = (st_entry_t *)kstpa;
227 ste = &ste[SYSMAP_VA >> SG4_SHIFT1];
228 *ste = protoste;
229 /*
230 * Now initialize the portion of that block of
231 * descriptors to map Sysptmap.
232 */
233 i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
234 ste = (st_entry_t *)kstpa;
235 ste = &ste[i + ((SYSMAP_VA & SG4_MASK2) >> SG4_SHIFT2)];
236 este = &ste[NPTEPG / SG4_LEV3SIZE];
237 protoste = kptmpa | SG_U | SG_RW | SG_V;
238 while (ste < este) {
239 *ste++ = protoste;
240 protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
241 }
242 /*
243 * Calculate the free level 2 descriptor mask
244 * noting that we have used:
245 * 0: level 1 table
246 * 1 to nl1desc: map page tables
247 * nl1desc + 1: maps kptmpa and last-page page table
248 */
249 /* mark an entry for level 1 table */
250 stfree = ~l2tobm(0);
251 /* mark entries for map page tables */
252 for (i = 1; i <= nl1desc; i++)
253 stfree &= ~l2tobm(i);
254 /* mark an entry for kptmpa and lkptpa */
255 stfree &= ~l2tobm(i);
256 /* mark entries not available */
257 for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
258 stfree &= ~l2tobm(i);
259
260 /*
261 * Initialize Sysptmap
262 */
263 pte = (pt_entry_t *)kptmpa;
264 epte = &pte[nptpages];
265 protopte = kptpa | PG_RW | PG_CI | PG_V;
266 while (pte < epte) {
267 *pte++ = protopte;
268 protopte += PAGE_SIZE;
269 }
270 /*
271 * Invalidate all remaining entries.
272 */
273 epte = (pt_entry_t *)kptmpa;
274 epte = &epte[TIB_SIZE];
275 while (pte < epte) {
276 *pte++ = PG_NV;
277 }
278 /*
279 * Initialize the one corresponding to SYSMAP_VA
280 * to point to Sysptmap.
281 */
282 pte = (pt_entry_t *)kptmpa;
283 pte = &pte[SYSMAP_VA >> SEGSHIFT];
284 *pte = kptmpa | PG_RW | PG_CI | PG_V;
285 } else
286 #endif
287 {
288 /*
289 * Map the page table pages in both the HW segment table
290 * and the software Sysptmap.
291 */
292 ste = (st_entry_t *)kstpa;
293 pte = (pt_entry_t *)kptmpa;
294 epte = &pte[nptpages];
295 protoste = kptpa | SG_RW | SG_V;
296 protopte = kptpa | PG_RW | PG_CI | PG_V;
297 while (pte < epte) {
298 *ste++ = protoste;
299 *pte++ = protopte;
300 protoste += PAGE_SIZE;
301 protopte += PAGE_SIZE;
302 }
303 /*
304 * Invalidate all remaining entries in both.
305 */
306 este = (st_entry_t *)kstpa;
307 este = &este[TIA_SIZE];
308 while (ste < este)
309 *ste++ = SG_NV;
310 epte = (pt_entry_t *)kptmpa;
311 epte = &epte[TIB_SIZE];
312 while (pte < epte)
313 *pte++ = PG_NV;
314 /*
315 * Initialize the last one to point to Sysptmap.
316 */
317 ste = (st_entry_t *)kstpa;
318 ste = &ste[SYSMAP_VA >> SEGSHIFT];
319 pte = (pt_entry_t *)kptmpa;
320 pte = &pte[SYSMAP_VA >> SEGSHIFT];
321 *ste = kptmpa | SG_RW | SG_V;
322 *pte = kptmpa | PG_RW | PG_CI | PG_V;
323 }
324
325 /*
326 * Initialize kernel page table.
327 * Start by invalidating the `nptpages' that we have allocated.
328 */
329 pte = (pt_entry_t *)kptpa;
330 epte = &pte[nptpages * NPTEPG];
331 while (pte < epte)
332 *pte++ = PG_NV;
333 /*
334 * Validate PTEs for kernel text (RO).
335 */
336 pte = (pt_entry_t *)kptpa;
337 pte = &pte[m68k_btop(KERNBASE)];
338 epte = &pte[m68k_btop(m68k_trunc_page(&etext))];
339 protopte = firstpa | PG_RO | PG_V;
340 while (pte < epte) {
341 *pte++ = protopte;
342 protopte += PAGE_SIZE;
343 }
344 /*
345 * Validate PTEs for kernel data/bss, dynamic data allocated
346 * by us so far (kstpa - firstpa bytes), and pages for lwp0
347 * u-area and page table allocated below (RW).
348 */
349 epte = (pt_entry_t *)kptpa;
350 epte = &epte[m68k_btop(kstpa - firstpa)];
351 protopte = (protopte & ~PG_PROT) | PG_RW;
352 /*
353 * Enable copy-back caching of data pages
354 */
355 #ifdef M68040
356 if (RELOC(mmutype, int) == MMU_68040)
357 protopte |= PG_CCB;
358 #endif
359 while (pte < epte) {
360 *pte++ = protopte;
361 protopte += PAGE_SIZE;
362 }
363 /*
364 * Map the kernel segment table cache invalidated for 68040/68060.
365 * (for the 68040 not strictly necessary, but recommended by Motorola;
366 * for the 68060 mandatory)
367 */
368 epte = (pt_entry_t *)kptpa;
369 epte = &epte[m68k_btop(nextpa - firstpa)];
370 protopte = (protopte & ~PG_PROT) | PG_RW;
371 #ifdef M68040
372 if (RELOC(mmutype, int) == MMU_68040) {
373 protopte &= ~PG_CCB;
374 protopte |= PG_CIN;
375 }
376 #endif
377 while (pte < epte) {
378 *pte++ = protopte;
379 protopte += PAGE_SIZE;
380 }
381
382 /*
383 * Finally, validate the internal IO space PTEs (RW+CI).
384 */
385
386 #define PTE2VA(pte) m68k_ptob(pte - ((pt_entry_t *)kptpa))
387
388 protopte = RELOC(intiobase_phys, u_int) | PG_RW | PG_CI | PG_V;
389 epte = &pte[iiomapsize];
390 RELOC(intiobase, uint8_t *) = (uint8_t *)PTE2VA(pte);
391 RELOC(intiolimit, uint8_t *) = (uint8_t *)PTE2VA(epte);
392 while (pte < epte) {
393 *pte++ = protopte;
394 protopte += PAGE_SIZE;
395 }
396 RELOC(extiobase, uint8_t *) = (uint8_t *)PTE2VA(pte);
397 pte += eiomapsize;
398 RELOC(virtual_avail, vaddr_t) = PTE2VA(pte);
399
400 /*
401 * Calculate important exported kernel addresses and related values.
402 */
403 /*
404 * Sysseg: base of kernel segment table
405 */
406 RELOC(Sysseg, st_entry_t *) = (st_entry_t *)(kstpa - firstpa);
407 RELOC(Sysseg_pa, paddr_t) = kstpa;
408 #ifdef M68040
409 if (RELOC(mmutype, int) == MMU_68040)
410 RELOC(protostfree, u_int) = stfree;
411 #endif
412 /*
413 * Sysptmap: base of kernel page table map
414 */
415 RELOC(Sysptmap, pt_entry_t *) = (pt_entry_t *)(kptmpa - firstpa);
416 /*
417 * Sysmap: kernel page table (as mapped through Sysptmap)
418 * Allocated at the end of KVA space.
419 */
420 RELOC(Sysmap, pt_entry_t *) = (pt_entry_t *)SYSMAP_VA;
421
422 /*
423 * Remember the u-area address so it can be loaded in the lwp0
424 * via uvm_lwp_setuarea() later in pmap_bootstrap_finalize().
425 */
426 RELOC(lwp0uarea, vaddr_t) = lwp0upa - firstpa;
427
428 /*
429 * VM data structures are now initialized, set up data for
430 * the pmap module.
431 *
432 * Note about avail_end: msgbuf is initialized just after
433 * avail_end in machdep.c.
434 */
435 RELOC(avail_start, paddr_t) = nextpa;
436 RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int)) -
437 m68k_round_page(MSGBUFSIZE);
438 RELOC(mem_size, vsize_t) = m68k_ptob(RELOC(physmem, int));
439
440 RELOC(virtual_end, vaddr_t) = VM_MAX_KERNEL_ADDRESS;
441
442 #ifdef news1700
443 if (RELOC(systype, int) == NEWS1700) {
444 RELOC(cache_ctl, uint8_t *) = 0xe1300000 - INTIOBASE1700 +
445 RELOC(intiobase, uint8_t *);
446 RELOC(cache_clr, uint8_t *) = 0xe1900000 - INTIOBASE1700 +
447 RELOC(intiobase, uint8_t *);
448 }
449 #endif
450
451 /*
452 * Allocate some fixed, special purpose kernel virtual addresses
453 */
454 {
455 vaddr_t va = RELOC(virtual_avail, vaddr_t);
456
457 RELOC(CADDR1, void *) = (void *)va;
458 va += PAGE_SIZE;
459 RELOC(CADDR2, void *) = (void *)va;
460 va += PAGE_SIZE;
461 RELOC(vmmap, void *) = (void *)va;
462 va += PAGE_SIZE;
463 RELOC(msgbufaddr, void *) = (void *)va;
464 va += m68k_round_page(MSGBUFSIZE);
465 RELOC(virtual_avail, vaddr_t) = va;
466 }
467 }
468