Home | History | Annotate | Line # | Download | only in atari
      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