1 /* $NetBSD: pmap_bootstrap.c,v 1.14 2026/11/08 08:39:10 tsutsui Exp $ */ 2 /*- 3 * Copyright (c) 1999 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Jason R. Thorpe. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * Copyright (c) 1991 Regents of the University of California. 33 * All rights reserved. 34 * 35 * This code is derived from software contributed to Berkeley by 36 * the Systems Programming Group of the University of Utah Computer 37 * Science Department. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. Neither the name of the University nor the names of its contributors 48 * may be used to endorse or promote products derived from this software 49 * without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 * 63 * @(#)pmap.c 7.5 (Berkeley) 5/10/91 64 */ 65 66 /* 67 * Copyright (c) 1995 Leo Weppelman 68 * Copyright (c) 1994 Michael L. Hitch 69 * Copyright (c) 1993 Markus Wild 70 * All rights reserved. 71 * 72 * Redistribution and use in source and binary forms, with or without 73 * modification, are permitted provided that the following conditions 74 * are met: 75 * 1. Redistributions of source code must retain the above copyright 76 * notice, this list of conditions and the following disclaimer. 77 * 2. Redistributions in binary form must reproduce the above copyright 78 * notice, this list of conditions and the following disclaimer in the 79 * documentation and/or other materials provided with the distribution. 80 * 3. All advertising materials mentioning features or use of this software 81 * must display the following acknowledgement: 82 * This product includes software developed by Markus Wild. 83 * 4. The name of the author may not be used to endorse or promote products 84 * derived from this software without specific prior written permission 85 * 86 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 87 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 88 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 89 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 90 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 91 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 92 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 93 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 94 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 95 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 96 */ 97 98 #include <sys/cdefs.h> 99 100 #include "opt_m68k_arch.h" 101 #include "opt_mbtype.h" 102 103 #include <sys/param.h> 104 #include <sys/systm.h> 105 #include <sys/proc.h> 106 107 #include <uvm/uvm.h> 108 109 #include <machine/pte.h> 110 #include <machine/cpu.h> 111 #include <machine/vmparam.h> 112 113 #include <m68k/cacheops.h> 114 #include <machine/iomap.h> 115 #include <sys/bus.h> 116 117 static vaddr_t bootstrap_vstart; 118 119 /* 120 * Keep these declarations here during preparation for NEW_PMAP. 121 * They may become unnecessary after the transition, so defer moving 122 * them to a header. 123 */ 124 extern psize_t st_pool_size; 125 extern paddr_t st_pool_phys; 126 extern vaddr_t st_pool_virt; 127 extern vaddr_t page_zero; 128 129 #define RELOC_PA(base, pa) ((base) + (pa)) /* used to set up PTE etc. */ 130 int kernel_copyback = 1; 131 132 static void mmu030_setup(paddr_t, u_int, paddr_t, psize_t, paddr_t, paddr_t); 133 static void map_io_areas(paddr_t, psize_t, u_int); 134 #if defined(M68040) || defined(M68060) 135 static void mmu040_setup(paddr_t, u_int, paddr_t, psize_t, paddr_t, paddr_t); 136 #endif 137 138 extern paddr_t avail_start; 139 extern paddr_t avail_end; 140 141 extern paddr_t msgbufpa; 142 143 /* 144 * All those kernel PT submaps that BSD is so fond of 145 */ 146 void *CADDR1, *CADDR2; 147 char *vmmap; 148 149 paddr_t __attribute__((no_instrument_function)) 150 pmap_bootstrap1(paddr_t nextpa, paddr_t reloff) 151 { 152 extern void etext(void); 153 paddr_t pstart, ptpa, Sysptmap_pa; 154 vaddr_t vstart; /* Next available virtual address */ 155 vaddr_t kva; 156 vsize_t avail; 157 psize_t ptsize; 158 u_int ptextra, kstsize; 159 pt_entry_t *pg, *epg, pg_proto; 160 161 /* 162 * We run the kernel from ST memory at the moment. 163 * The kernel segment table is put just behind the loaded image. 164 * pstart: start of usable ST memory 165 * avail : size of ST memory available. 166 */ 167 vstart = (vaddr_t)nextpa; 168 vstart = m68k_round_page(vstart); 169 pstart = (paddr_t)vstart; /* pre-reloc PA == kernel VA here */ 170 avail = st_pool_phys - pstart; 171 172 /* 173 * Save KVA of lwp0 uarea and allocate it. 174 */ 175 lwp0uarea = vstart; 176 pstart += USPACE; 177 vstart += USPACE; 178 avail -= USPACE; 179 180 /* 181 * Calculate the number of pages needed for Sysseg. 182 * For the 68030, we need 256 descriptors (segment-table-entries). 183 * This easily fits into one page. 184 * For the 68040, both the level-1 and level-2 descriptors are 185 * stored into Sysseg. We currently handle a maximum sum of MAXKL2SIZE 186 * level-1 & level-2 tables. 187 */ 188 #if defined(M68040) || defined(M68060) 189 if (mmutype == MMU_68040) 190 kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE); 191 else 192 #endif 193 kstsize = 1; 194 /* 195 * allocate the kernel segment table 196 */ 197 Sysseg_pa = pstart; /* pre-reloc PA to init STEs */ 198 Sysseg = (st_entry_t *)vstart; 199 pstart += kstsize * PAGE_SIZE; 200 vstart += kstsize * PAGE_SIZE; 201 avail -= kstsize * PAGE_SIZE; 202 203 /* 204 * allocate kernel page table map 205 */ 206 Sysptmap_pa = pstart; /* pre-reloc PA to init PTEs */ 207 Sysptmap = (pt_entry_t *)vstart; 208 pstart += PAGE_SIZE; 209 vstart += PAGE_SIZE; 210 avail -= PAGE_SIZE; 211 212 /* 213 * Determine the number of pte's we need for extra's like 214 * ST I/O map's. 215 */ 216 ptextra = btoc(STIO_SIZE); 217 218 /* 219 * If present, add pci areas 220 */ 221 if (machineid & ATARI_HADES) 222 ptextra += btoc(PCI_CONFIG_SIZE + PCI_IO_SIZE + PCI_MEM_SIZE); 223 if (machineid & ATARI_MILAN) 224 ptextra += btoc(PCI_IO_SIZE + PCI_MEM_SIZE); 225 ptextra += btoc(BOOTM_VA_POOL); 226 /* 227 * now need to account for the kmem area, which is allocated 228 * before pmap_init() is called. It is roughly the size of physical 229 * memory. 230 */ 231 ptextra += physmem; 232 233 /* 234 * The 'pt' (the initial kernel pagetable) has to map the kernel and 235 * the I/O areas. The various I/O areas are mapped (virtually) at 236 * the top of the address space mapped by 'pt' (ie. just below Sysmap). 237 */ 238 ptpa = pstart; /* pre-reloc PA to init PTEs */ 239 ptsize = (Sysptsize + howmany(ptextra, NPTEPG)) << PGSHIFT; 240 pstart += ptsize; 241 vstart += ptsize; 242 avail -= ptsize; 243 244 /* 245 * Sysmap is now placed at the end of Supervisor virtual address space. 246 */ 247 Sysmap = (pt_entry_t *)SYSMAP_VA; 248 249 /* 250 * Initialize segment tables 251 */ 252 #if defined(M68040) || defined(M68060) 253 if (mmutype == MMU_68040) 254 mmu040_setup(Sysseg_pa, kstsize, ptpa, ptsize, Sysptmap_pa, 255 reloff); 256 else 257 #endif /* defined(M68040) || defined(M68060) */ 258 mmu030_setup(Sysseg_pa, kstsize, ptpa, ptsize, Sysptmap_pa, 259 reloff); 260 261 /* 262 * initialize kernel page table page(s). 263 * Assume load at VA 0. 264 * - Text pages are RO 265 * - Page zero is invalid 266 */ 267 pg_proto = RELOC_PA(reloff, 0) | PG_RO | PG_V; 268 pg = (pt_entry_t *)ptpa; 269 *pg++ = PG_NV; 270 271 pg_proto += PAGE_SIZE; 272 for (kva = PAGE_SIZE; kva < (vaddr_t)etext; kva += PAGE_SIZE) { 273 *pg++ = pg_proto; 274 pg_proto += PAGE_SIZE; 275 } 276 277 /* 278 * data, bss and dynamic tables are read/write 279 */ 280 pg_proto = (pg_proto & PG_FRAME) | PG_RW | PG_V; 281 282 #if defined(M68040) || defined(M68060) 283 /* 284 * Map the kernel segment table cache invalidated for 68040/68060. 285 * (for the 68040 not strictly necessary, but recommended by Motorola; 286 * for the 68060 mandatory) 287 */ 288 if (mmutype == MMU_68040) { 289 290 if (kernel_copyback) 291 pg_proto |= PG_CCB; 292 293 for (; kva < (vaddr_t)Sysseg; kva += PAGE_SIZE) { 294 *pg++ = pg_proto; 295 pg_proto += PAGE_SIZE; 296 } 297 298 pg_proto = (pg_proto & ~PG_CCB) | PG_CI; 299 for (; kva < (vaddr_t)Sysptmap; kva += PAGE_SIZE) { 300 *pg++ = pg_proto; 301 pg_proto += PAGE_SIZE; 302 } 303 304 pg_proto = (pg_proto & ~PG_CI); 305 if (kernel_copyback) 306 pg_proto |= PG_CCB; 307 } 308 #endif /* defined(M68040) || defined(M68060) */ 309 310 /* 311 * go till end of data allocated so far 312 * plus lwp0 u-area (to be allocated) 313 */ 314 for (; kva < vstart; kva += PAGE_SIZE) { 315 *pg++ = pg_proto; 316 pg_proto += PAGE_SIZE; 317 } 318 319 /* 320 * invalidate remainder of kernel PT 321 */ 322 epg = (pt_entry_t *)ptpa; 323 epg = &epg[ptsize / sizeof(pt_entry_t)]; 324 while (pg < epg) 325 *pg++ = PG_NV; 326 327 /* 328 * Map various I/O areas 329 */ 330 map_io_areas(ptpa, ptsize, ptextra); 331 332 /* 333 * Map the allocated space in ST-ram now. In the contig-case, there 334 * is no need to make a distinction between virtual and physical 335 * addresses. But I make it anyway to be prepared. 336 * Physical space is already reserved! 337 */ 338 st_pool_virt = vstart; 339 pg = (pt_entry_t *)ptpa; 340 pg = &pg[vstart / PAGE_SIZE]; 341 pg_proto = st_pool_phys | PG_RW | PG_CI | PG_V; 342 vstart += st_pool_size; 343 while (pg_proto < (st_pool_phys + st_pool_size)) { 344 *pg++ = pg_proto; 345 pg_proto += PAGE_SIZE; 346 } 347 348 /* 349 * Map physical page_zero and page-zero+1 (First ST-ram page). We need 350 * to reference it in the reboot code. Two pages are mapped, because 351 * we must make sure 'doboot()' is contained in it (see the tricky 352 * copying there....). 353 */ 354 page_zero = vstart; 355 pg = (pt_entry_t *)ptpa; 356 pg = &pg[vstart / PAGE_SIZE]; 357 *pg++ = PG_RW | PG_CI | PG_V; 358 vstart += PAGE_SIZE; 359 *pg = PG_RW | PG_CI | PG_V | PAGE_SIZE; 360 vstart += PAGE_SIZE; 361 362 /* 363 * All necessary STEs and PTEs have been initialized. 364 * Update Sysseg_pa and Sysptmap_pa to point relocated PA. 365 */ 366 if (reloff) { 367 Sysseg_pa += reloff; 368 Sysptmap_pa += reloff; 369 } 370 371 bootstrap_vstart = vstart; 372 return pstart; 373 } 374 375 /* 376 * Do the dull work of mapping the various I/O areas. They MUST be Cache 377 * inhibited! 378 * All I/O areas are virtually mapped at the end of the pt-table. 379 */ 380 static void __attribute__((no_instrument_function)) 381 map_io_areas(paddr_t ptpa, psize_t ptsize, u_int ptextra) 382 /* ptsize: Size of 'pt' in bytes */ 383 /* ptextra: #of additional I/O pte's */ 384 { 385 vaddr_t ioaddr; 386 pt_entry_t *pt, *pg, *epg; 387 pt_entry_t pg_proto; 388 u_long mask; 389 390 pt = (pt_entry_t *)ptpa; 391 ioaddr = ((ptsize / sizeof(pt_entry_t)) - ptextra) * PAGE_SIZE; 392 393 /* 394 * Map ST-IO area 395 */ 396 stio_addr = ioaddr; 397 ioaddr += STIO_SIZE; 398 pg = &pt[stio_addr / PAGE_SIZE]; 399 epg = &pg[btoc(STIO_SIZE)]; 400 #ifdef _MILANHW_ 401 /* 402 * Turn on byte swaps in the ST I/O area. On the Milan, the 403 * U0 signal of the MMU controls the BigEndian signal 404 * of the PLX9080. We use this setting so we can read/write the 405 * PLX registers (and PCI-config space) in big-endian mode. 406 */ 407 pg_proto = STIO_PHYS | PG_RW | PG_CI | PG_V | PTE40_U0; 408 #else 409 pg_proto = STIO_PHYS | PG_RW | PG_CI | PG_V; 410 #endif 411 while (pg < epg) { 412 *pg++ = pg_proto; 413 pg_proto += PAGE_SIZE; 414 } 415 416 /* 417 * Map PCI areas 418 */ 419 if (machineid & ATARI_HADES) { 420 /* 421 * Only Hades maps the PCI-config space! 422 */ 423 pci_conf_addr = ioaddr; 424 ioaddr += PCI_CONFIG_SIZE; 425 pg = &pt[pci_conf_addr / PAGE_SIZE]; 426 epg = &pg[btoc(PCI_CONFIG_SIZE)]; 427 mask = PCI_CONFM_PHYS; 428 pg_proto = PCI_CONFB_PHYS | PG_RW | PG_CI | PG_V; 429 for (; pg < epg; mask <<= 1) 430 *pg++ = pg_proto | mask; 431 } else 432 pci_conf_addr = 0; /* XXX: should crash */ 433 434 if (machineid & (ATARI_HADES|ATARI_MILAN)) { 435 pci_io_addr = ioaddr; 436 ioaddr += PCI_IO_SIZE; 437 pg = &pt[pci_io_addr / PAGE_SIZE]; 438 epg = &pg[btoc(PCI_IO_SIZE)]; 439 pg_proto = PCI_IO_PHYS | PG_RW | PG_CI | PG_V; 440 while (pg < epg) { 441 *pg++ = pg_proto; 442 pg_proto += PAGE_SIZE; 443 } 444 445 pci_mem_addr = ioaddr; 446 /* Provide an uncached PCI address for the MILAN */ 447 pci_mem_uncached = ioaddr; 448 ioaddr += PCI_MEM_SIZE; 449 epg = &pg[btoc(PCI_MEM_SIZE)]; 450 pg_proto = PCI_VGA_PHYS | PG_RW | PG_CI | PG_V; 451 while (pg < epg) { 452 *pg++ = pg_proto; 453 pg_proto += PAGE_SIZE; 454 } 455 } 456 457 bootm_init(ioaddr, pg, BOOTM_VA_POOL); 458 /* 459 * ioaddr += BOOTM_VA_POOL; 460 * pg = &pg[btoc(BOOTM_VA_POOL)]; 461 */ 462 } 463 464 void __attribute__((no_instrument_function)) 465 mmu030_setup(paddr_t sysseg_pa, u_int kstsize, paddr_t ptpa, psize_t ptsize, 466 paddr_t sysptmap_pa, paddr_t kbase) 467 /* sysseg_pa: System segment table */ 468 /* kstsize: size of 'sysseg' in pages */ 469 /* ptpa: Kernel page table */ 470 /* ptsize: size of 'pt' in bytes */ 471 /* sysptmap_pa: System page table */ 472 { 473 st_entry_t sg_proto, *sg, *esg; 474 pt_entry_t pg_proto, *pg, *epg; 475 476 /* 477 * Map the page table pages in both the HW segment table 478 * and the software Sysptmap. 479 */ 480 sg = (st_entry_t *)sysseg_pa; 481 pg = (pt_entry_t *)sysptmap_pa; 482 epg = &pg[ptsize >> PGSHIFT]; 483 sg_proto = RELOC_PA(kbase, ptpa) | SG_RW | SG_V; 484 pg_proto = RELOC_PA(kbase, ptpa) | PG_RW | PG_CI | PG_V; 485 while (pg < epg) { 486 *sg++ = sg_proto; 487 *pg++ = pg_proto; 488 sg_proto += PAGE_SIZE; 489 pg_proto += PAGE_SIZE; 490 } 491 492 /* 493 * Invalidate the remainder of the tables. 494 */ 495 esg = (st_entry_t *)sysseg_pa; 496 esg = &esg[TIA_SIZE]; 497 while (sg < esg) 498 *sg++ = SG_NV; 499 epg = (pt_entry_t *)sysptmap_pa; 500 epg = &epg[TIB_SIZE]; 501 while (pg < epg) 502 *pg++ = PG_NV; 503 504 /* 505 * Initialize the PTE for the last one to point Sysptmap. 506 */ 507 sg = (st_entry_t *)sysseg_pa; 508 sg = &sg[SYSMAP_VA >> SEGSHIFT]; 509 pg = (pt_entry_t *)sysptmap_pa; 510 pg = &pg[SYSMAP_VA >> SEGSHIFT]; 511 *sg = RELOC_PA(kbase, sysptmap_pa) | SG_RW | SG_V; 512 *pg = RELOC_PA(kbase, sysptmap_pa) | PG_RW | PG_CI | PG_V; 513 } 514 515 #if defined(M68040) || defined(M68060) 516 void __attribute__((no_instrument_function)) 517 mmu040_setup(paddr_t sysseg_pa, u_int kstsize, paddr_t ptpa, psize_t ptsize, 518 paddr_t sysptmap_pa, paddr_t kbase) 519 /* sysseg_pa: System segment table */ 520 /* kstsize: size of 'sysseg' in pages */ 521 /* ptpa: Kernel page table */ 522 /* ptsize: size of 'pt' in bytes */ 523 /* sysptmap_pa: System page table */ 524 { 525 int nl1desc, nl2desc, i; 526 st_entry_t sg_proto, *sg, *esg; 527 pt_entry_t pg_proto, *pg, *epg; 528 529 /* 530 * First invalidate the entire "segment table" pages 531 * (levels 1 and 2 have the same "invalid" values). 532 */ 533 sg = (st_entry_t *)sysseg_pa; 534 esg = &sg[kstsize * NPTEPG]; 535 while (sg < esg) 536 *sg++ = SG_NV; 537 538 /* 539 * Initialize level 2 descriptors (which immediately 540 * follow the level 1 table). 541 * We need: 542 * NPTEPG / SG4_LEV3SIZE 543 * level 2 descriptors to map each of the nptpages 544 * pages of PTEs. Note that we set the "used" bit 545 * now to save the HW the expense of doing it. 546 */ 547 nl2desc = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE); 548 sg = (st_entry_t *)sysseg_pa; 549 sg = &sg[SG4_LEV1SIZE]; 550 esg = &sg[nl2desc]; 551 sg_proto = RELOC_PA(kbase, ptpa) | SG_U | SG_RW | SG_V; 552 while (sg < esg) { 553 *sg++ = sg_proto; 554 sg_proto += (SG4_LEV3SIZE * sizeof(st_entry_t)); 555 } 556 557 /* 558 * Initialize level 1 descriptors. We need: 559 * howmany(nl2desc, SG4_LEV2SIZE) 560 * level 1 descriptors to map the 'nl2desc' level 2's. 561 */ 562 nl1desc = howmany(nl2desc, SG4_LEV2SIZE); 563 sg = (st_entry_t *)sysseg_pa; 564 esg = &sg[nl1desc]; 565 sg_proto = RELOC_PA(kbase, (paddr_t)&sg[SG4_LEV1SIZE]) 566 | SG_U | SG_RW | SG_V; 567 while (sg < esg) { 568 *sg++ = sg_proto; 569 sg_proto += (SG4_LEV2SIZE * sizeof(st_entry_t)); 570 } 571 572 /* Sysmap is last entry in level 1 */ 573 sg = (st_entry_t *)sysseg_pa; 574 sg = &sg[SG4_LEV1SIZE - 1]; 575 *sg = sg_proto; 576 577 /* 578 * Kernel segment table at end of next level 2 table 579 */ 580 i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE); 581 sg = (st_entry_t *)sysseg_pa; 582 sg = &sg[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)]; 583 esg = &sg[NPTEPG / SG4_LEV3SIZE]; 584 sg_proto = RELOC_PA(kbase, sysptmap_pa) | SG_U | SG_RW | SG_V; 585 while (sg < esg) { 586 *sg++ = sg_proto; 587 sg_proto += (SG4_LEV3SIZE * sizeof(st_entry_t)); 588 } 589 590 /* Include additional level 2 table for Sysmap in protostfree */ 591 protostfree = (~0U << (1 + nl1desc + 1)) /* & ~(~0U << MAXKL2SIZE) */; 592 593 /* 594 * Initialize Sysptmap 595 */ 596 pg = (pt_entry_t *)sysptmap_pa; 597 epg = &pg[ptsize >> PGSHIFT]; 598 pg_proto = RELOC_PA(kbase, ptpa) | PG_RW | PG_CI | PG_V; 599 while (pg < epg) { 600 *pg++ = pg_proto; 601 pg_proto += PAGE_SIZE; 602 } 603 604 /* 605 * Invalidate rest of Sysptmap page. 606 */ 607 epg = (pt_entry_t *)sysptmap_pa; 608 epg = &epg[TIB_SIZE]; 609 while (pg < epg) 610 *pg++ = PG_NV; 611 612 /* 613 * Initialize the PTE for the last one to point Sysptmap. 614 */ 615 pg = (pt_entry_t *)sysptmap_pa; 616 pg = &pg[SYSMAP_VA >> SEGSHIFT]; 617 *pg = RELOC_PA(kbase, sysptmap_pa) | PG_RW | PG_CI | PG_V; 618 } 619 #endif /* M68040 */ 620 621 #ifdef DEBUG 622 void dump_segtable(u_int *); 623 void dump_pagetable(u_int *, u_int, u_int); 624 625 void 626 dump_segtable(u_int *stp) 627 { 628 u_int *s, *es; 629 int shift, i; 630 631 s = stp; 632 { 633 es = s + (M68K_STSIZE >> 2); 634 shift = SG_ISHIFT; 635 } 636 637 /* 638 * XXX need changes for 68040 639 */ 640 for (i = 0; s < es; s++, i++) 641 if (*s & SG_V) 642 printf("$%08x: $%08x\t", i << shift, *s & SG_FRAME); 643 printf("\n"); 644 } 645 646 void 647 dump_pagetable(u_int *ptp, u_int i, u_int n) 648 { 649 u_int *p, *ep; 650 651 p = ptp + i; 652 ep = p + n; 653 for (; p < ep; p++, i++) 654 if (*p & PG_V) 655 printf("$%08x -> $%08x\t", i, *p & PG_FRAME); 656 printf("\n"); 657 } 658 659 #endif 660 661 /* 662 * Bootstrap the system enough to run with virtual memory. 663 * 664 * This is called after mapping has already been enabled 665 * and just syncs the pmap module with what has already been done. 666 */ 667 void __attribute__((no_instrument_function)) 668 pmap_bootstrap(void) 669 { 670 vaddr_t va; 671 vaddr_t vstart = bootstrap_vstart; 672 int i; 673 674 /* 675 * Announce page-size to the VM-system 676 */ 677 uvmexp.pagesize = NBPG; 678 uvm_md_init(); 679 680 /* 681 * Setup physical address ranges 682 */ 683 for (i = 0; i < NMEM_SEGS && usable_segs[i].start; i++) 684 continue; 685 /* XXX: allow for msgbuf */ 686 usable_segs[i - 1].end -= m68k_round_page(MSGBUFSIZE); 687 msgbufpa = usable_segs[i - 1].end; 688 689 /* 690 * Count physical memory 691 */ 692 extern vsize_t mem_size; 693 mem_size = 0; 694 for (i = 0; i < NMEM_SEGS; i++) { 695 if (boot_segs[i].start == boot_segs[i].end) 696 break; 697 mem_size += boot_segs[i].end - boot_segs[i].start; 698 } 699 700 /* 701 * Announce available memory to the VM-system 702 */ 703 for (i = 0; i < NMEM_SEGS && usable_segs[i].start; i++) 704 uvm_page_physload(atop(usable_segs[i].start), 705 atop(usable_segs[i].end), 706 atop(usable_segs[i].start), 707 atop(usable_segs[i].end), 708 usable_segs[i].free_list); 709 710 avail_start = usable_segs[0].start; 711 avail_end = usable_segs[i - 1].end; 712 713 virtual_avail = vstart; 714 virtual_end = VM_MAX_KERNEL_ADDRESS; 715 716 /* 717 * Allocate all the submaps we need 718 */ 719 #define SYSMAP(c, v, n) \ 720 v = (c)va; va += ((n)*PAGE_SIZE); 721 722 va = virtual_avail; 723 724 SYSMAP(void * ,CADDR1 ,1 ) 725 SYSMAP(void * ,CADDR2 ,1 ) 726 SYSMAP(void * ,vmmap ,1 ) 727 SYSMAP(void * ,msgbufaddr ,btoc(MSGBUFSIZE) ) 728 729 DCIS(); 730 731 virtual_avail = reserve_dumppages(va); 732 } 733