1 /*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the Systems Programming Group of the University of Utah Computer
7 * Science Department.
8 *
9 * %sccs.include.redist.c%
10 *
11 * @(#)pmap_bootstrap.c 8.1 (Berkeley) 06/10/93
12 */
13
14 #include <sys/param.h>
15 #include <sys/msgbuf.h>
16 #include <hp300/hp300/pte.h>
17 #include <hp300/hp300/clockreg.h>
18 #include <machine/vmparam.h>
19 #include <machine/cpu.h>
20
21 #include <vm/vm.h>
22
23 #define RELOC(v, t) *((t*)((u_int)&(v) + firstpa))
24
25 extern char *etext;
26 extern int Sysptsize;
27 extern char *extiobase, *proc0paddr;
28 extern struct ste *Sysseg;
29 extern struct pte *Sysptmap, *Sysmap;
30 extern vm_offset_t Umap, CLKbase, MMUbase;
31
32 extern int maxmem, physmem;
33 extern vm_offset_t avail_start, avail_end, virtual_avail, virtual_end;
34 extern vm_size_t mem_size;
35 extern int protection_codes[];
36 #ifdef HAVEVAC
37 extern int pmap_aliasmask;
38 #endif
39
40 /*
41 * Special purpose kernel virtual addresses, used for mapping
42 * physical pages for a variety of temporary or permanent purposes:
43 *
44 * CADDR1, CADDR2: pmap zero/copy operations
45 * vmmap: /dev/mem, crash dumps, parity error checking
46 * ledbase: SPU LEDs
47 * msgbufp: kernel message buffer
48 */
49 caddr_t CADDR1, CADDR2, vmmap, ledbase;
50 struct msgbuf *msgbufp;
51
52 /*
53 * Bootstrap the VM system.
54 *
55 * Called with MMU off so we must relocate all global references by `firstpa'
56 * (don't call any functions here!) `nextpa' is the first available physical
57 * memory address. Returns an updated first PA reflecting the memory we
58 * have allocated. MMU is still off when we return.
59 *
60 * XXX assumes sizeof(u_int) == sizeof(struct pte)
61 * XXX a PIC compiler would make this much easier.
62 */
63 void
pmap_bootstrap(nextpa,firstpa)64 pmap_bootstrap(nextpa, firstpa)
65 vm_offset_t nextpa;
66 register vm_offset_t firstpa;
67 {
68 vm_offset_t kstpa, kptpa, iiopa, eiopa, kptmpa, lkptpa, p0upa;
69 u_int nptpages, kstsize;
70 register u_int protoste, protopte, *ste, *pte, *epte;
71
72 /*
73 * Calculate important physical addresses:
74 *
75 * kstpa kernel segment table 1 page (!040)
76 * N pages (040)
77 *
78 * kptpa statically allocated
79 * kernel PT pages Sysptsize+ pages
80 *
81 * iiopa internal IO space
82 * PT pages IIOMAPSIZE pages
83 *
84 * eiopa external IO space
85 * PT pages EIOMAPSIZE pages
86 *
87 * [ Sysptsize is the number of pages of PT, IIOMAPSIZE and
88 * EIOMAPSIZE are the number of PTEs, hence we need to round
89 * the total to a page boundary with IO maps at the end. ]
90 *
91 * kptmpa kernel PT map 1 page
92 *
93 * lkptpa last kernel PT page 1 page
94 *
95 * p0upa proc 0 u-area UPAGES pages
96 *
97 * The KVA corresponding to any of these PAs is:
98 * (PA - firstpa + KERNBASE).
99 */
100 if (RELOC(mmutype, int) == MMU_68040)
101 kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
102 else
103 kstsize = 1;
104 kstpa = nextpa;
105 nextpa += kstsize * NBPG;
106 kptpa = nextpa;
107 nptpages = RELOC(Sysptsize, int) +
108 (IIOMAPSIZE + EIOMAPSIZE + NPTEPG - 1) / NPTEPG;
109 nextpa += nptpages * NBPG;
110 eiopa = nextpa - EIOMAPSIZE * sizeof(struct pte);
111 iiopa = eiopa - IIOMAPSIZE * sizeof(struct pte);
112 kptmpa = nextpa;
113 nextpa += NBPG;
114 lkptpa = nextpa;
115 nextpa += NBPG;
116 p0upa = nextpa;
117 nextpa += UPAGES * NBPG;
118
119 /*
120 * Initialize segment table and kernel page table map.
121 *
122 * On 68030s and earlier MMUs the two are identical except for
123 * the valid bits so both are initialized with essentially the
124 * same values. On the 68040, which has a mandatory 3-level
125 * structure, the segment table holds the level 1 table and part
126 * (or all) of the level 2 table and hence is considerably
127 * different. Here the first level consists of 128 descriptors
128 * (512 bytes) each mapping 32mb of address space. Each of these
129 * points to blocks of 128 second level descriptors (512 bytes)
130 * each mapping 256kb. Note that there may be additional "segment
131 * table" pages depending on how large MAXKL2SIZE is.
132 *
133 * Portions of the last segment of KVA space (0xFFF00000 -
134 * 0xFFFFFFFF) are mapped for a couple of purposes. 0xFFF00000
135 * for UPAGES is used for mapping the current process u-area
136 * (u + kernel stack). The very last page (0xFFFFF000) is mapped
137 * to the last physical page of RAM to give us a region in which
138 * PA == VA. We use the first part of this page for enabling
139 * and disabling mapping. The last part of this page also contains
140 * info left by the boot ROM.
141 *
142 * XXX cramming two levels of mapping into the single "segment"
143 * table on the 68040 is intended as a temporary hack to get things
144 * working. The 224mb of address space that this allows will most
145 * likely be insufficient in the future (at least for the kernel).
146 */
147 if (RELOC(mmutype, int) == MMU_68040) {
148 register int num;
149
150 /*
151 * First invalidate the entire "segment table" pages
152 * (levels 1 and 2 have the same "invalid" value).
153 */
154 pte = (u_int *)kstpa;
155 epte = &pte[kstsize * NPTEPG];
156 while (pte < epte)
157 *pte++ = SG_NV;
158 /*
159 * Initialize level 2 descriptors (which immediately
160 * follow the level 1 table). We need:
161 * NPTEPG / SG4_LEV3SIZE
162 * level 2 descriptors to map each of the nptpages+1
163 * pages of PTEs. Note that we set the "used" bit
164 * now to save the HW the expense of doing it.
165 */
166 num = (nptpages + 1) * (NPTEPG / SG4_LEV3SIZE);
167 pte = &((u_int *)kstpa)[SG4_LEV1SIZE];
168 epte = &pte[num];
169 protoste = kptpa | SG_U | SG_RW | SG_V;
170 while (pte < epte) {
171 *pte++ = protoste;
172 protoste += (SG4_LEV3SIZE * sizeof(struct ste));
173 }
174 /*
175 * Initialize level 1 descriptors. We need:
176 * roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE
177 * level 1 descriptors to map the `num' level 2's.
178 */
179 pte = (u_int *)kstpa;
180 epte = &pte[roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE];
181 protoste = (u_int)&pte[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
182 while (pte < epte) {
183 *pte++ = protoste;
184 protoste += (SG4_LEV2SIZE * sizeof(struct ste));
185 }
186 /*
187 * Initialize the final level 1 descriptor to map the last
188 * block of level 2 descriptors.
189 */
190 ste = &((u_int *)kstpa)[SG4_LEV1SIZE-1];
191 pte = &((u_int *)kstpa)[kstsize*NPTEPG - SG4_LEV2SIZE];
192 *ste = (u_int)pte | SG_U | SG_RW | SG_V;
193 /*
194 * Now initialize the final portion of that block of
195 * descriptors to map the "last PT page".
196 */
197 pte = &((u_int *)kstpa)[kstsize*NPTEPG - NPTEPG/SG4_LEV3SIZE];
198 epte = &pte[NPTEPG/SG4_LEV3SIZE];
199 protoste = lkptpa | SG_U | SG_RW | SG_V;
200 while (pte < epte) {
201 *pte++ = protoste;
202 protoste += (SG4_LEV3SIZE * sizeof(struct ste));
203 }
204 /*
205 * Initialize Sysptmap
206 */
207 pte = (u_int *)kptmpa;
208 epte = &pte[nptpages+1];
209 protopte = kptpa | PG_RW | PG_CI | PG_V;
210 while (pte < epte) {
211 *pte++ = protopte;
212 protopte += NBPG;
213 }
214 pte = &((u_int *)kptmpa)[NPTEPG-1];
215 *pte = lkptpa | PG_RW | PG_CI | PG_V;
216 } else {
217 /*
218 * Map the page table pages in both the HW segment table
219 * and the software Sysptmap. Note that Sysptmap is also
220 * considered a PT page hence the +1.
221 */
222 ste = (u_int *)kstpa;
223 pte = (u_int *)kptmpa;
224 epte = &pte[nptpages+1];
225 protoste = kptpa | SG_RW | SG_V;
226 protopte = kptpa | PG_RW | PG_CI | PG_V;
227 while (pte < epte) {
228 *ste++ = protoste;
229 *pte++ = protopte;
230 protoste += NBPG;
231 protopte += NBPG;
232 }
233 /*
234 * Invalidate all but the last remaining entries in both.
235 */
236 epte = &((u_int *)kptmpa)[NPTEPG-1];
237 while (pte < epte) {
238 *ste++ = SG_NV;
239 *pte++ = PG_NV;
240 }
241 /*
242 * Initialize the last to point to point to the page
243 * table page allocated earlier.
244 */
245 *ste = lkptpa | SG_RW | SG_V;
246 *pte = lkptpa | PG_RW | PG_CI | PG_V;
247 }
248 /*
249 * Invalidate all but the final entry in the last kernel PT page
250 * (u-area PTEs will be validated later). The final entry maps
251 * the last page of physical memory.
252 */
253 pte = (u_int *)lkptpa;
254 epte = &pte[NPTEPG-1];
255 while (pte < epte)
256 *pte++ = PG_NV;
257 *pte = MAXADDR | PG_RW | PG_CI | PG_V;
258 /*
259 * Initialize kernel page table.
260 * Start by invalidating the `nptpages' that we have allocated.
261 */
262 pte = (u_int *)kptpa;
263 epte = &pte[nptpages * NPTEPG];
264 while (pte < epte)
265 *pte++ = PG_NV;
266 /*
267 * Validate PTEs for kernel text (RO)
268 */
269 pte = &((u_int *)kptpa)[hp300_btop(KERNBASE)];
270 epte = &pte[hp300_btop(hp300_trunc_page(&etext))];
271 #ifdef KGDB
272 protopte = firstpa | PG_RW | PG_V; /* XXX RW for now */
273 #else
274 protopte = firstpa | PG_RO | PG_V;
275 #endif
276 while (pte < epte) {
277 *pte++ = protopte;
278 protopte += NBPG;
279 }
280 /*
281 * Validate PTEs for kernel data/bss, dynamic data allocated
282 * by us so far (nextpa - firstpa bytes), and pages for proc0
283 * u-area and page table allocated below (RW).
284 */
285 epte = &((u_int *)kptpa)[hp300_btop(nextpa - firstpa)];
286 protopte = (protopte & ~PG_PROT) | PG_RW;
287 /*
288 * Enable copy-back caching of data pages
289 */
290 if (RELOC(mmutype, int) == MMU_68040)
291 protopte |= PG_CCB;
292 while (pte < epte) {
293 *pte++ = protopte;
294 protopte += NBPG;
295 }
296 /*
297 * Finally, validate the internal IO space PTEs (RW+CI).
298 * We do this here since the 320/350 MMU registers (also
299 * used, but to a lesser extent, on other models) are mapped
300 * in this range and it would be nice to be able to access
301 * them after the MMU is turned on.
302 */
303 pte = (u_int *)iiopa;
304 epte = (u_int *)eiopa;
305 protopte = INTIOBASE | PG_RW | PG_CI | PG_V;
306 while (pte < epte) {
307 *pte++ = protopte;
308 protopte += NBPG;
309 }
310
311 /*
312 * Calculate important exported kernel virtual addresses
313 */
314 /*
315 * Sysseg: base of kernel segment table
316 */
317 RELOC(Sysseg, struct ste *) =
318 (struct ste *)(kstpa - firstpa);
319 /*
320 * Sysptmap: base of kernel page table map
321 */
322 RELOC(Sysptmap, struct pte *) =
323 (struct pte *)(kptmpa - firstpa);
324 /*
325 * Sysmap: kernel page table (as mapped through Sysptmap)
326 * Immediately follows `nptpages' of static kernel page table.
327 */
328 RELOC(Sysmap, struct pte *) =
329 (struct pte *)hp300_ptob(nptpages * NPTEPG);
330 /*
331 * Umap: first of UPAGES PTEs (in Sysmap) for fixed-address u-area.
332 * HIGHPAGES PTEs from the end of Sysmap.
333 */
334 RELOC(Umap, vm_offset_t) =
335 (vm_offset_t)RELOC(Sysmap, struct pte *) +
336 (HP_MAX_PTSIZE - HIGHPAGES * sizeof(struct pte));
337 /*
338 * intiobase, intiolimit: base and end of internal (DIO) IO space.
339 * IIOMAPSIZE pages prior to external IO space at end of static
340 * kernel page table.
341 */
342 RELOC(intiobase, char *) =
343 (char *)hp300_ptob(nptpages*NPTEPG - (IIOMAPSIZE+EIOMAPSIZE));
344 RELOC(intiolimit, char *) =
345 (char *)hp300_ptob(nptpages*NPTEPG - EIOMAPSIZE);
346 /*
347 * extiobase: base of external (DIO-II) IO space.
348 * EIOMAPSIZE pages at the end of the static kernel page table.
349 */
350 RELOC(extiobase, char *) =
351 (char *)hp300_ptob(nptpages*NPTEPG - EIOMAPSIZE);
352 /*
353 * CLKbase, MMUbase: important registers in internal IO space
354 * accessed from assembly language.
355 */
356 RELOC(CLKbase, vm_offset_t) =
357 (vm_offset_t)RELOC(intiobase, char *) + CLKBASE;
358 RELOC(MMUbase, vm_offset_t) =
359 (vm_offset_t)RELOC(intiobase, char *) + MMUBASE;
360
361 /*
362 * Setup u-area for process 0.
363 */
364 /*
365 * Validate PTEs in Sysmap corresponding to the u-area (Umap)
366 * which are HIGHPAGES from the end of the last kernel PT page
367 * allocated earlier.
368 */
369 pte = &((u_int *)lkptpa)[NPTEPG - HIGHPAGES];
370 epte = &pte[UPAGES];
371 protopte = p0upa | PG_RW | PG_V;
372 while (pte < epte) {
373 *pte++ = protopte;
374 protopte += NBPG;
375 }
376 /*
377 * Zero the u-area.
378 * NOTE: `pte' and `epte' aren't PTEs here.
379 */
380 pte = (u_int *)p0upa;
381 epte = (u_int *)(p0upa + UPAGES*NBPG);
382 while (pte < epte)
383 *pte++ = 0;
384 /*
385 * Remember the u-area address so it can be loaded in the
386 * proc struct p_addr field later.
387 */
388 RELOC(proc0paddr, char *) = (char *)(p0upa - firstpa);
389
390 /*
391 * VM data structures are now initialized, set up data for
392 * the pmap module.
393 */
394 RELOC(avail_start, vm_offset_t) = nextpa;
395 RELOC(avail_end, vm_offset_t) =
396 hp300_ptob(RELOC(maxmem, int))
397 /* XXX allow for msgbuf */
398 - hp300_round_page(sizeof(struct msgbuf));
399 RELOC(mem_size, vm_size_t) = hp300_ptob(RELOC(physmem, int));
400 RELOC(virtual_avail, vm_offset_t) =
401 VM_MIN_KERNEL_ADDRESS + (nextpa - firstpa);
402 RELOC(virtual_end, vm_offset_t) = VM_MAX_KERNEL_ADDRESS;
403
404 #ifdef HAVEVAC
405 /*
406 * Determine VA aliasing distance if any
407 */
408 if (RELOC(ectype, int) == EC_VIRT)
409 if (RELOC(machineid, int) == HP_320)
410 RELOC(pmap_aliasmask, int) = 0x3fff; /* 16k */
411 else if (RELOC(machineid, int) == HP_350)
412 RELOC(pmap_aliasmask, int) = 0x7fff; /* 32k */
413 #endif
414
415 /*
416 * Initialize protection array.
417 * XXX don't use a switch statement, it might produce an
418 * absolute "jmp" table.
419 */
420 {
421 register int *kp;
422
423 kp = &RELOC(protection_codes, int);
424 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_NONE] = 0;
425 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_NONE] = PG_RO;
426 kp[VM_PROT_READ|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
427 kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_EXECUTE] = PG_RO;
428 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
429 kp[VM_PROT_NONE|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
430 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_NONE] = PG_RW;
431 kp[VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;
432 }
433
434 /*
435 * Kernel page/segment table allocated in locore,
436 * just initialize pointers.
437 */
438 {
439 struct pmap *kpm = &RELOC(kernel_pmap_store, struct pmap);
440
441 kpm->pm_stab = RELOC(Sysseg, struct ste *);
442 kpm->pm_ptab = RELOC(Sysmap, struct pte *);
443 simple_lock_init(&kpm->pm_lock);
444 kpm->pm_count = 1;
445 kpm->pm_stpa = (struct ste *)kstpa;
446 /*
447 * For the 040 we also initialize the free level 2
448 * descriptor mask noting that we have used:
449 * 0: level 1 table
450 * 1 to `num': map page tables
451 * MAXKL2SIZE-1: maps last-page page table
452 */
453 if (RELOC(mmutype, int) == MMU_68040) {
454 register int num;
455
456 kpm->pm_stfree = ~l2tobm(0);
457 num = roundup((nptpages + 1) * (NPTEPG / SG4_LEV3SIZE),
458 SG4_LEV2SIZE) / SG4_LEV2SIZE;
459 while (num)
460 kpm->pm_stfree &= ~l2tobm(num--);
461 kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
462 for (num = MAXKL2SIZE;
463 num < sizeof(kpm->pm_stfree)*NBBY;
464 num++)
465 kpm->pm_stfree &= ~l2tobm(num);
466 }
467 }
468
469 /*
470 * Allocate some fixed, special purpose kernel virtual addresses
471 */
472 {
473 vm_offset_t va = RELOC(virtual_avail, vm_offset_t);
474
475 RELOC(CADDR1, caddr_t) = (caddr_t)va;
476 va += HP_PAGE_SIZE;
477 RELOC(CADDR2, caddr_t) = (caddr_t)va;
478 va += HP_PAGE_SIZE;
479 RELOC(vmmap, caddr_t) = (caddr_t)va;
480 va += HP_PAGE_SIZE;
481 RELOC(ledbase, caddr_t) = (caddr_t)va;
482 va += HP_PAGE_SIZE;
483 RELOC(msgbufp, struct msgbuf *) = (struct msgbuf *)va;
484 va += HP_PAGE_SIZE;
485 RELOC(virtual_avail, vm_offset_t) = va;
486 }
487 }
488