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