Final changes to amiga kernel address space layout to match almost all the

other m68k ports (initially from the yamt-km branch a long time ago).

- move Sysmap to the end of address space.
- move Amiga hardware mapping to immediately after Sysptmap.
- tweak virtual_avail/end accordingly.

A DEBUG kernel should now boot without panicing.  Also, kernel address space
layout is now compatible with m68k/m68k/pmap_motorola.c.
This commit is contained in:
mhitch 2007-05-12 16:51:42 +00:00
parent 201c1005be
commit 1f433a38eb
3 changed files with 93 additions and 152 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: amiga_init.c,v 1.94 2007/03/04 05:59:15 christos Exp $ */
/* $NetBSD: amiga_init.c,v 1.95 2007/05/12 16:51:42 mhitch Exp $ */
/*
* Copyright (c) 1994 Michael L. Hitch
@ -36,7 +36,7 @@
#include "opt_devreload.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: amiga_init.c,v 1.94 2007/03/04 05:59:15 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: amiga_init.c,v 1.95 2007/05/12 16:51:42 mhitch Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -99,12 +99,6 @@ vaddr_t INTREQWaddr;
*/
volatile unsigned short *amiga_intena_read, *amiga_intena_write;
/*
* the number of pages in our hw mapping and the start address
*/
vaddr_t amigahwaddr;
u_int namigahwpg;
vaddr_t CHIPMEMADDR;
vaddr_t chipmem_start;
vaddr_t chipmem_end;
@ -350,6 +344,14 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
pend = vend + fphystart;
avail -= vstart;
/*
* save KVA of proc0 u-area and allocate it.
*/
RELOC(proc0paddr, u_int) = vstart;
pstart += USPACE;
vstart += USPACE;
avail -= USPACE;
#if defined(M68040) || defined(M68060)
if (RELOC(mmutype, int) == MMU_68040)
kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
@ -366,6 +368,15 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
pstart += PAGE_SIZE * kstsize;
avail -= PAGE_SIZE * kstsize;
/*
* allocate kernel page table map
*/
RELOC(Sysptmap, u_int) = vstart;
Sysptmap_pa = pstart;
vstart += PAGE_SIZE;
pstart += PAGE_SIZE;
avail -= PAGE_SIZE;
/*
* allocate initial page table pages
*/
@ -388,30 +399,16 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
pstart += ptsize;
avail -= ptsize;
/*
* allocate kernel page table map
*/
RELOC(Sysptmap, u_int) = vstart;
Sysptmap_pa = pstart;
vstart += PAGE_SIZE;
pstart += PAGE_SIZE;
avail -= PAGE_SIZE;
/*
* pt maps the first N megs of ram Sysptmap comes directly
* after pt (ptpa) and so it must map >= N meg + Its one
* page and so it must map 8M of space. Specifically
* Sysptmap holds the pte's that map the kerne page tables.
* Sysptmap holds the pte's that map the kernel page tables.
*
* We want Sysmap to be the first address mapped by Sysptmap.
* this will be the address just above what pt,pt+ptsize maps.
* pt[0] maps address 0 so:
*
* ptsize
* Sysmap = ------ * PAGE_SIZE
* 4
* Sysmap is now placed at the end of Supervisor virtual address space.
*/
RELOC(Sysmap, u_int *) = (u_int *)(ptsize * (PAGE_SIZE / 4));
RELOC(Sysmap, u_int *) = (u_int *)-(NPTEPG * PAGE_SIZE);
/*
* initialize segment table and page table map
@ -430,11 +427,11 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
* Initialize level 2 descriptors (which immediately
* follow the level 1 table). We need:
* NPTEPG / SG4_LEV3SIZE
* level 2 descriptors to map each of the nptpages + 1
* level 2 descriptors to map each of the nptpages
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
i = ((ptsize >> PGSHIFT) + 1) * (NPTEPG / SG4_LEV3SIZE);
i = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
sg = &((u_int *)(RELOC(Sysseg_pa, u_int)))[SG4_LEV1SIZE];
esg = &sg[i];
sg_proto = ptpa | SG_U | SG_RW | SG_V;
@ -442,14 +439,16 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
*sg++ = sg_proto;
sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
}
/*
* Initialize level 1 descriptors. We need:
* roundup(num, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
* level 1 descriptors to map the 'num' level 2's.
*/
i = roundup(i, SG4_LEV2SIZE) / SG4_LEV2SIZE;
/* Include additional level 2 table for Sysmap in protostfree */
RELOC(protostfree, u_int) =
(-1 << (i + 1)) /* & ~(-1 << MAXKL2SIZE) */;
(-1 << (i + 2)) /* & ~(-1 << MAXKL2SIZE) */;
sg = (u_int *) RELOC(Sysseg_pa, u_int);
esg = &sg[i];
sg_proto = (u_int)&sg[SG4_LEV1SIZE] | SG_U | SG_RW |SG_V;
@ -457,11 +456,30 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
*sg++ = sg_proto;
sg_proto += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/* Sysmap is last entry in level 1 */
sg = (u_int *) RELOC(Sysseg_pa, u_int);
sg = &sg[SG4_LEV1SIZE - 1];
*sg = sg_proto;
/*
* Kernel segment table at end of next level 2 table
*/
/* XXX fix calculations XXX */
i = ((((ptsize >> PGSHIFT) + 3) & -2) - 1) * (NPTEPG / SG4_LEV3SIZE);
sg = &((u_int *)(RELOC(Sysseg_pa, u_int)))[SG4_LEV1SIZE + i];
esg = &sg[NPTEPG / SG4_LEV3SIZE];
sg_proto = Sysptmap_pa | SG_U | SG_RW | SG_V;
while (sg < esg) {
*sg++ = sg_proto;
sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
}
/*
* Initialize Sysptmap
*/
sg = (u_int *) Sysptmap_pa;
esg = &sg[(ptsize >> PGSHIFT) + 1];
esg = &sg[ptsize >> PGSHIFT];
pg_proto = ptpa | PG_RW | PG_CI | PG_V;
while (sg < esg) {
*sg++ = pg_proto;
@ -470,20 +488,22 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
/*
* Invalidate rest of Sysptmap page
*/
esg = (u_int *)(Sysptmap_pa + PAGE_SIZE);
esg = (u_int *)(Sysptmap_pa + PAGE_SIZE - sizeof(st_entry_t));
while (sg < esg)
*sg++ = SG_NV;
sg = (u_int *) Sysptmap_pa;
sg = &sg[256 - 1]; /* XXX */
*sg = Sysptmap_pa | PG_RW | PG_CI | PG_V;
} else
#endif /* M68040 */
{
/*
* Map the page table pages in both the HW segment table
* and the software Sysptmap. Note that Sysptmap is also
* considered a PT page, hence the +1.
* and the software Sysptmap.
*/
sg = (u_int *)RELOC(Sysseg_pa, u_int);
pg = (u_int *)Sysptmap_pa;
esg = &pg[(ptsize >> PGSHIFT) + 1];
esg = &pg[ptsize >> PGSHIFT];
sg_proto = ptpa | SG_RW | SG_V;
pg_proto = ptpa | PG_RW | PG_CI | PG_V;
while (pg < esg) {
@ -495,11 +515,15 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
/*
* invalidate the remainder of each table
*/
esg = (u_int *)(Sysptmap_pa + PAGE_SIZE);
/* XXX PAGE_SIZE dependent constant: 256 or 1024 */
esg = (u_int *)(Sysptmap_pa + (256 - 1) * sizeof(st_entry_t));
while (pg < esg) {
*sg++ = SG_NV;
*pg++ = PG_NV;
}
*sg = Sysptmap_pa | SG_RW | SG_V;
*pg = Sysptmap_pa | PG_RW | SG_V;
/* XXX zero out rest of page? */
}
/*
@ -551,7 +575,7 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
* go till end of data allocated so far
* plus proc0 u-area (to be allocated)
*/
for (; i < vstart + USPACE; i += PAGE_SIZE, pg_proto += PAGE_SIZE)
for (; i < vstart; i += PAGE_SIZE, pg_proto += PAGE_SIZE)
*pg++ = pg_proto;
/*
* invalidate remainder of kernel PT
@ -560,20 +584,27 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
*pg++ = PG_NV;
/*
* go back and validate internal IO PTEs
* at end of allocated PT space
* validate internal IO PTEs following current vstart
*/
pg -= ptextra;
pg = &((u_int *)ptpa)[vstart >> PGSHIFT];
#ifdef DRACO
if ((id >> 24) == 0x7D) {
RELOC(DRCCADDR, u_int) = vstart;
RELOC(CIAADDR, vaddr_t) =
RELOC(DRCCADDR, u_int) + DRCIAPG * PAGE_SIZE;
if (RELOC(z2mem_end, vaddr_t) == 0)
RELOC(ZBUSADDR, vaddr_t) =
RELOC(DRCCADDR, u_int) + NDRCCPG * PAGE_SIZE;
pg_proto = DRCCBASE | PG_RW | PG_CI | PG_V;
while (pg_proto < DRZ2BASE) {
*pg++ = pg_proto;
pg_proto += DRCCSTRIDE;
vstart += PAGE_SIZE;
}
/* NCR 53C710 chip */
*pg++ = DRSCSIBASE | PG_RW | PG_CI | PG_V;
vstart += PAGE_SIZE;
#ifdef DEBUG_KERNEL_START
/*
@ -581,56 +612,62 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
* XXX (only works if in slot 0)
*/
*pg++ = 0x20000000 | PG_RW | PG_CI | PG_V;
vstart += PAGE_SIZE;
#endif
} else
#endif
{
RELOC(CHIPMEMADDR, vaddr_t) = vstart;
pg_proto = CHIPMEMBASE | PG_RW | PG_CI | PG_V;
/* CI needed here?? */
while (pg_proto < CHIPMEMTOP) {
*pg++ = pg_proto;
pg_proto += PAGE_SIZE;
vstart += PAGE_SIZE;
}
}
if (RELOC(z2mem_end, paddr_t)) { /* XXX */
RELOC(ZTWOMEMADDR, vaddr_t) = vstart;
RELOC(ZBUSADDR, vaddr_t) = RELOC(ZTWOMEMADDR, vaddr_t) +
RELOC(NZTWOMEMPG, u_int) * PAGE_SIZE;
pg_proto = RELOC(z2mem_start, paddr_t) | /* XXX */
PG_RW | PG_V; /* XXX */
while (pg_proto < RELOC(z2mem_end, paddr_t)) { /* XXX */
*pg++ = pg_proto; /* XXX */
pg_proto += PAGE_SIZE; /* XXX */
vstart += PAGE_SIZE;
} /* XXX */
} /* XXX */
#ifdef DRACO
if ((id >> 24) != 0x7D)
#endif
{
RELOC(CIAADDR, vaddr_t) = vstart;
pg_proto = CIABASE | PG_RW | PG_CI | PG_V;
while (pg_proto < CIATOP) {
*pg++ = pg_proto;
pg_proto += PAGE_SIZE;
vstart += PAGE_SIZE;
}
RELOC(ZTWOROMADDR, vaddr_t) = vstart;
pg_proto = ZTWOROMBASE | PG_RW | PG_CI | PG_V;
while (pg_proto < ZTWOROMTOP) {
*pg++ = pg_proto;
pg_proto += PAGE_SIZE;
vstart += PAGE_SIZE;
}
RELOC(ZBUSADDR, vaddr_t) = vstart;
/* not on 8k boundary :-( */
RELOC(CIAADDR, vaddr_t) += PAGE_SIZE/2;
RELOC(CUSTOMADDR, vaddr_t) =
RELOC(ZTWOROMADDR, vaddr_t) - ZTWOROMBASE + CUSTOMBASE;
}
/*
*[ following page tables MAY be allocated to ZORRO3 space,
* but they're then later mapped in autoconf.c ]
*/
/* zero out proc0 user area */
/* bzero ((u_char *)pstart, USPACE);*/ /* XXXXXXXXXXXXXXXXXXXXX */
/*
* save KVA of proc0 u-area and allocate it.
*/
RELOC(proc0paddr, u_int) = vstart;
pstart += USPACE;
vstart += USPACE;
avail -= USPACE;
vstart += RELOC(ZBUSAVAIL, u_int);
/*
* init mem sizes
@ -639,80 +676,16 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags, inh_sync,
RELOC(lowram, u_int) = fphystart;
RELOC(physmem, u_int) = fphysize >> PGSHIFT;
RELOC(virtual_avail, u_int) = vstart;
/*
* Put user page tables starting at next 16MB boundary, to make kernel
* dumps more readable, with guaranteed 16MB of.
* XXX depends on Sysmap being last.
* XXX 16 MB instead of 256 MB should be enough, but...
* we need to fix the fastmem loading first. (see comment at line 375)
*/
RELOC(amiga_uptbase, vaddr_t) =
roundup(RELOC(Sysmap, u_int) + 0x10000000, 0x10000000);
/*
* get the pmap module in sync with reality.
*/
/* pmap_bootstrap(pstart, fphystart);*/ /* XXXXXXXXXXXXXXXXXXXXXXx*/
/*
* record base KVA of IO spaces which are just before Sysmap
*/
#ifdef DRACO
if ((id >> 24) == 0x7D) {
RELOC(DRCCADDR, u_int) =
(u_int)RELOC(Sysmap, u_int) - ptextra * PAGE_SIZE;
RELOC(CIAADDR, vaddr_t) =
RELOC(DRCCADDR, u_int) + DRCIAPG * PAGE_SIZE;
if (RELOC(z2mem_end, vaddr_t)) { /* XXX */
RELOC(ZTWOMEMADDR, vaddr_t) =
RELOC(DRCCADDR, u_int) + NDRCCPG * PAGE_SIZE;
RELOC(ZBUSADDR, vaddr_t) =
RELOC(ZTWOMEMADDR, vaddr_t) +
RELOC(NZTWOMEMPG, u_int)*PAGE_SIZE;
} else {
RELOC(ZBUSADDR, vaddr_t) =
RELOC(DRCCADDR, u_int) + NDRCCPG * PAGE_SIZE;
}
/*
* some nice variables for pmap to use
*/
RELOC(amigahwaddr, vaddr_t) = RELOC(DRCCADDR, u_int);
} else
#endif
{
RELOC(CHIPMEMADDR, vaddr_t) =
(u_int)RELOC(Sysmap, u_int) - ptextra * PAGE_SIZE;
if (RELOC(z2mem_end, u_int) == 0)
RELOC(CIAADDR, vaddr_t) =
RELOC(CHIPMEMADDR, vaddr_t) +
NCHIPMEMPG * PAGE_SIZE;
else {
RELOC(ZTWOMEMADDR, vaddr_t) =
RELOC(CHIPMEMADDR, vaddr_t) +
NCHIPMEMPG * PAGE_SIZE;
RELOC(CIAADDR, vaddr_t) = RELOC(ZTWOMEMADDR, vaddr_t) +
RELOC(NZTWOMEMPG, u_int) * PAGE_SIZE;
}
RELOC(ZTWOROMADDR, vaddr_t) =
RELOC(CIAADDR, vaddr_t) + NCIAPG * PAGE_SIZE;
RELOC(ZBUSADDR, vaddr_t) =
RELOC(ZTWOROMADDR, vaddr_t) + NZTWOROMPG * PAGE_SIZE;
/* not on 8k boundary :-( */
RELOC(CIAADDR, vaddr_t) += PAGE_SIZE/2;
RELOC(CUSTOMADDR, vaddr_t) =
RELOC(ZTWOROMADDR, vaddr_t) - ZTWOROMBASE + CUSTOMBASE;
/*
* some nice variables for pmap to use
*/
RELOC(amigahwaddr, vaddr_t) = RELOC(CHIPMEMADDR, vaddr_t);
}
/* Set number of pages to reserve for mapping Amiga hardware pages */
RELOC(namigahwpg, u_int) = ptextra;
roundup(vstart + 0x10000000, 0x10000000);
/*
* set this before copying the kernel, so the variable is updated in

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.122 2007/03/05 20:34:51 he Exp $ */
/* $NetBSD: pmap.c,v 1.123 2007/05/12 16:51:43 mhitch Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -107,7 +107,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.122 2007/03/05 20:34:51 he Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.123 2007/05/12 16:51:43 mhitch Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -442,7 +442,6 @@ pmap_bootstrap(firstaddr, loadaddr)
}
mem_size = physmem << PGSHIFT;
virtual_avail = VM_MIN_KERNEL_ADDRESS + (firstaddr - loadaddr);
virtual_end = VM_MAX_KERNEL_ADDRESS;
/*
@ -495,8 +494,6 @@ pmap_bootstrap(firstaddr, loadaddr)
void
pmap_init()
{
extern vaddr_t amigahwaddr;
extern u_int namigahwpg;
vaddr_t addr, addr2;
vsize_t s;
u_int npg;
@ -511,35 +508,6 @@ pmap_init()
#ifdef DEBUG
if (pmapdebug & PDB_FOLLOW)
printf("pmap_init()\n");
#endif
/*
* Now that kernel map has been allocated, we can mark as
* unavailable regions which we have mapped in locore.
* XXX in pmap_bootstrap() ???
*/
addr = (vaddr_t) amigahwaddr;
if (uvm_map(kernel_map, &addr,
ptoa(namigahwpg),
NULL, UVM_UNKNOWN_OFFSET, 0,
UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE,
UVM_INH_NONE, UVM_ADV_RANDOM,
UVM_FLAG_FIXED)) != 0)
goto bogons;
addr = (vaddr_t) Sysmap;
if (uvm_map(kernel_map, &addr, AMIGA_KPTSIZE,
NULL, UVM_UNKNOWN_OFFSET, 0,
UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE,
UVM_INH_NONE, UVM_ADV_RANDOM,
UVM_FLAG_FIXED)) != 0) {
/*
* If this fails, it is probably because the static
* portion of the kernel page table isn't big enough
* and we overran the page table map.
*/
bogons:
panic("pmap_init: bogons in the VM system!");
}
#ifdef DEBUG
if (pmapdebug & PDB_INIT) {
printf("pmap_init: Sysseg %p, Sysmap %p, Sysptmap %p\n",
Sysseg, Sysmap, Sysptmap);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vmparam.h,v 1.34 2005/12/11 12:16:36 christos Exp $ */
/* $NetBSD: vmparam.h,v 1.35 2007/05/12 16:51:43 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@ -153,7 +153,7 @@
#define VM_MAX_ADDRESS ((vaddr_t)(USRSTACK)) /* user max */
#define VM_MAXUSER_ADDRESS ((vaddr_t)(VM_MAX_ADDRESS)) /* same */
#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0)
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(0-PAGE_SIZE))
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)-(NPTEPG * PAGE_SIZE))
/*
* virtual sizes (bytes) for various kernel submaps