From 1f433a38eb9f1ffc344adc075b01d4a55d818313 Mon Sep 17 00:00:00 2001 From: mhitch Date: Sat, 12 May 2007 16:51:42 +0000 Subject: [PATCH] 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. --- sys/arch/amiga/amiga/amiga_init.c | 205 +++++++++++++----------------- sys/arch/amiga/amiga/pmap.c | 36 +----- sys/arch/amiga/include/vmparam.h | 4 +- 3 files changed, 93 insertions(+), 152 deletions(-) diff --git a/sys/arch/amiga/amiga/amiga_init.c b/sys/arch/amiga/amiga/amiga_init.c index f1240fae788b..d55b8769f62e 100644 --- a/sys/arch/amiga/amiga/amiga_init.c +++ b/sys/arch/amiga/amiga/amiga_init.c @@ -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 -__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 #include @@ -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 diff --git a/sys/arch/amiga/amiga/pmap.c b/sys/arch/amiga/amiga/pmap.c index 6b2f7b271eca..a371b5650693 100644 --- a/sys/arch/amiga/amiga/pmap.c +++ b/sys/arch/amiga/amiga/pmap.c @@ -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 -__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 #include @@ -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); diff --git a/sys/arch/amiga/include/vmparam.h b/sys/arch/amiga/include/vmparam.h index 4088901c8132..ff916b456f72 100644 --- a/sys/arch/amiga/include/vmparam.h +++ b/sys/arch/amiga/include/vmparam.h @@ -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