Sync MMU table initialization with amiga and atari a bit:

- for 040/060, move L2 descs for Sysptmap from the last L2 block in segment
  table pages to the contiguous block with ones for segment table mappings

- for 020/030, invalidate ste and pte entries separately since
  ste size (TIA_SIZE) and pte size (TIB_SIZE) could be different
  on 8KB/page systems

Tested on hp300 (040), mac68k (LC040), and news68k (030)
(and untested on others).

XXX: some more stuff in pmap_bootstrap.c could be moved into
XXX: common pmap_bootstrap_finalize()?
This commit is contained in:
tsutsui 2009-12-06 02:42:34 +00:00
parent 38859c1df9
commit 378ad8db55
8 changed files with 413 additions and 352 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.23 2009/12/05 23:16:57 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.24 2009/12/06 02:42:34 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.23 2009/12/05 23:16:57 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.24 2009/12/06 02:42:34 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -87,6 +87,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
u_int nptpages, kstsize;
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
/*
* Calculate important physical addresses:
@ -159,7 +160,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* likely be insufficient in the future (at least for the kernel).
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc, i;
/*
* First invalidate the entire "segment table" pages
@ -169,7 +170,6 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
este = &ste[kstsize * NPTEPG];
while (ste < este)
*ste++ = SG_NV;
/*
* Initialize level 2 descriptors (which immediately
* follow the level 1 table). We need:
@ -178,10 +178,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -190,11 +190,12 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -202,20 +203,19 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map kptmpa and the "last PT page".
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE * 2];
ste = &ste[i + SG4_LEV2SIZE - NPTEPG / SG4_LEV3SIZE * 2];
epte = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
@ -228,6 +228,23 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
@ -241,10 +258,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
@ -252,6 +269,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* Initialize the last to point to kptmpa and the page
* table page allocated earlier.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
pte++;
*pte = lkptpa | PG_RW | PG_CI | PG_V;
@ -272,18 +291,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &epte[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last to point to kptmpa and the page
* table page allocated earlier.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
*pte = kptmpa | PG_RW | PG_CI | PG_V;
ste++;
@ -424,27 +449,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
simple_lock_init(&kpm->pm_lock);
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa and last-page page table
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = roundup(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE) / SG4_LEV2SIZE;
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.43 2009/12/05 23:16:57 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.44 2009/12/06 02:42:34 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.43 2009/12/05 23:16:57 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.44 2009/12/06 02:42:34 tsutsui Exp $");
#include <sys/param.h>
@ -97,6 +97,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
u_int nptpages, kstsize;
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
/*
* Calculate important physical addresses:
@ -167,7 +168,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* likely be insufficient in the future (at least for the kernel).
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc, i;
/*
* First invalidate the entire "segment table" pages
@ -185,10 +186,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -196,31 +197,31 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map kptmpa and the "last PT page".
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE * 2];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE) * 2];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
@ -233,6 +234,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -244,10 +263,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
@ -255,6 +274,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* Initialize the last ones to point to kptmpa and the page
* table page allocated earlier.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
pte++;
*pte = lkptpa | PG_RW | PG_CI | PG_V;
@ -275,18 +296,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &epte[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last ones to point to kptmpa and the page
* table page allocated earlier.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
*pte = kptmpa | PG_RW | PG_CI | PG_V;
ste++;
@ -469,27 +496,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
simple_lock_init(&kpm->pm_lock);
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa and last-page page table
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.23 2009/12/05 23:16:57 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.24 2009/12/06 02:42:34 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.23 2009/12/05 23:16:57 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.24 2009/12/06 02:42:34 tsutsui Exp $");
#include <sys/param.h>
@ -85,12 +85,12 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
{
paddr_t kstpa, kptpa, kptmpa, lwp0upa;
u_int nptpages, kstsize;
st_entry_t protoste, *ste;
#if defined(M68040)
st_entry_t *este;
#endif
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
u_int iiomapsize;
#if defined(M68040)
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
#endif
/*
* Calculate important physical addresses:
@ -151,7 +151,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
#if defined(M68040)
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc, i;
/*
* First invalidate the entire "segment table" pages
@ -169,10 +169,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -180,11 +180,12 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&pte[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -196,20 +197,38 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SYSMAP_VA >> SG4_SHIFT1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the portion of that block of
* descriptors to map Sysptmap.
*/
ste = &este[((SYSMAP_VA & SG4_MASK2) >> SG4_SHIFT2)];
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[i + ((SYSMAP_VA & SG4_MASK2) >> SG4_SHIFT2)];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -233,6 +252,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* to point to Sysptmap.
*/
pte = (pt_entry_t *)kptmpa;
/* XXX should be (TIA_SIZE * PAGE_SIZE) */
pte[SYSMAP_VA / (NPTEPG * PAGE_SIZE)] =
kptmpa | PG_RW | PG_CI | PG_V;
} else
@ -256,20 +276,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
/*
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &este[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the one corresponding to SYSMAP_VA
* to point to Sysptmap.
*/
ste = (st_entry_t *)kstpa;
pte = (pt_entry_t *)kptmpa;
/* XXX should be (TIA_SIZE * PAGE_SIZE) */
pte[SYSMAP_VA / (NPTEPG * PAGE_SIZE)] =
kptmpa | SG_RW | SG_V;
/* XXX should be (TIA_SIZE * PAGE_SIZE) */
ste[SYSMAP_VA / (NPTEPG * PAGE_SIZE)] =
kptmpa | PG_RW | PG_CI | PG_V;
}
@ -392,27 +416,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
simple_lock_init(&kpm->pm_lock);
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptama
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
#if defined(M68040)
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
#endif
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.84 2009/12/05 23:16:57 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.85 2009/12/06 02:42:34 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.84 2009/12/05 23:16:57 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.85 2009/12/06 02:42:34 tsutsui Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -118,6 +118,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
int i;
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
extern char start[];
vidlen = m68k_round_page(mac68k_video.mv_height *
@ -196,7 +197,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* likely be insufficient in the future (at least for the kernel).
*/
if (mmutype == MMU_68040) {
int num;
int nl1desc, nl2desc;
/*
* First invalidate the entire "segment table" pages
@ -214,10 +215,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = PA2VA(kstpa, st_entry_t *);
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -225,37 +226,55 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = PA2VA(kstpa, u_int *);
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = PA2VA(kstpa, st_entry_t *);
ste = &ste[SG4_LEV1SIZE - 1];
este = PA2VA(kstpa, st_entry_t *);
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map Sysmap.
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = PA2VA(kstpa, st_entry_t *);
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -267,16 +286,18 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = PA2VA(kptmpa, pt_entry_t *);
epte = &epte[NPTEPG - 1];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
pte = PA2VA(kptmpa, pt_entry_t *);
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
} else {
/*
@ -295,18 +316,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = PA2VA(kptmpa, pt_entry_t *);
epte = &epte[NPTEPG - 1];
while (pte < epte) {
este = PA2VA(kstpa, st_entry_t *);
este = &este[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = PA2VA(kptmpa, pt_entry_t *);
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
ste = PA2VA(kstpa, st_entry_t *);
ste = &ste[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
pte = PA2VA(kptmpa, pt_entry_t *);
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
}
@ -474,27 +501,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
simple_lock_init(&kpm->pm_lock);
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa
*/
if (mmutype == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (mmutype == MMU_68040)
kpm->pm_stfree = stfree;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.37 2009/12/05 23:16:57 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.38 2009/12/06 02:42:34 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.37 2009/12/05 23:16:57 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.38 2009/12/06 02:42:34 tsutsui Exp $");
#include <sys/param.h>
#include <sys/kcore.h>
@ -90,14 +90,14 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
{
paddr_t kstpa, kptpa, kptmpa, lkptpa, lwp0upa;
u_int nptpages, kstsize;
st_entry_t protoste, *ste;
#if defined(M68040) || defined(M68060)
st_entry_t *este;
#endif
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
psize_t size;
u_int iiomappages;
int i;
#if defined(M68040) || defined(M68060)
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
#endif
/*
* Calculate important physical addresses:
@ -182,7 +182,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
#if defined(M68040) || defined(M68060)
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc;
/*
* First invalidate the entire "segment table" pages
@ -200,10 +200,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -211,31 +211,31 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* roundup(num, SG4_LEV2SIZE) / SG4_LEV2SIZE
* level 1 descriptors to map the `num' level 2's.
* roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEV2SIZE
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map kptmpa and the "last PT page".
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE * 2];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE) * 2];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
@ -248,6 +248,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -259,13 +277,19 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
/*
* Initialize the last ones to point to kptmpa and the page
* table page allocated earlier.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
pte++;
*pte = lkptpa | PG_RW | PG_CI | PG_U | PG_V;
@ -288,18 +312,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last two remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (st_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &epte[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (st_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last ones to point to Sysptmap and the page
* table page allocated earlier.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
*pte = kptmpa | PG_RW | PG_CI | PG_V;
ste++;
@ -525,27 +555,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
#if defined(M68040) || defined(M68060)
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa and last-page page table
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.27 2009/12/05 23:16:58 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.28 2009/12/06 02:42:35 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.27 2009/12/05 23:16:58 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.28 2009/12/06 02:42:35 tsutsui Exp $");
#include <sys/param.h>
@ -91,12 +91,12 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
{
paddr_t kstpa, kptpa, kptmpa, lwp0upa;
u_int nptpages, kstsize;
st_entry_t protoste, *ste;
#ifdef M68040
st_entry_t *este;
#endif
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
u_int iiomapsize, eiomapsize;
#ifdef M68040
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
#endif
/*
* Calculate important physical addresses:
@ -178,7 +178,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
#ifdef M68040
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc, i;
/*
* First invalidate the entire "segment table" pages
@ -196,10 +196,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -207,37 +207,55 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)epte | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map Sysmap.
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -249,16 +267,18 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 1];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
} else
#endif
@ -279,18 +299,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 1];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &este[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
}
@ -441,28 +467,9 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
simple_lock_init(&kpm->pm_lock);
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa
*/
#ifdef M68040
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.32 2009/12/05 23:16:58 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.33 2009/12/06 02:42:35 tsutsui Exp $ */
/*
* This file was taken from mvme68k/mvme68k/pmap_bootstrap.c
@ -45,7 +45,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.32 2009/12/05 23:16:58 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.33 2009/12/06 02:42:35 tsutsui Exp $");
#include <sys/param.h>
#include <sys/kcore.h>
@ -103,13 +103,13 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
{
paddr_t kstpa, kptpa, kptmpa, lkptpa, lwp0upa;
u_int nptpages, kstsize;
st_entry_t protoste, *ste;
#if defined(M68040) || defined(M68060)
st_entry_t *este;
#endif
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
psize_t size;
int i;
#if defined(M68040) || defined(M68060)
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
#endif
/*
* Calculate important physical addresses:
@ -192,7 +192,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
#if defined(M68040) || defined(M68060)
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc;
/*
* First invalidate the entire "segment table" pages
@ -210,10 +210,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -221,31 +221,31 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)&ste[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map the "last PT page".
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE * 2];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE) * 2];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
@ -258,6 +258,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -269,10 +287,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last two remaining entries.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
@ -280,6 +298,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* Initialize the last ones to point to Sysptmap and the page
* table page allocated earlier.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
pte++;
*pte = lkptpa | PG_RW | PG_CI | PG_U | PG_V;
@ -302,18 +322,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last two remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 2];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &epte[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last ones to point to Sysptmap and the page
* table page allocated earlier.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 2]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
*pte = kptmpa | PG_RW | PG_CI | PG_V;
ste++;
@ -566,27 +592,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
#if defined(M68040) || defined(M68060)
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa and last-page page table
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap_bootstrap.c,v 1.46 2009/12/05 23:16:58 tsutsui Exp $ */
/* $NetBSD: pmap_bootstrap.c,v 1.47 2009/12/06 02:42:35 tsutsui Exp $ */
/*
* Copyright (c) 1991, 1993
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.46 2009/12/05 23:16:58 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.47 2009/12/06 02:42:35 tsutsui Exp $");
#include "opt_m680x0.h"
@ -86,11 +86,11 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
{
paddr_t kstpa, kptpa, kptmpa, lwp0upa;
u_int nptpages, kstsize;
st_entry_t protoste, *ste;
#if defined(M68040) || defined(M68060)
st_entry_t *este;
#endif
st_entry_t protoste, *ste, *este;
pt_entry_t protopte, *pte, *epte;
#if defined(M68040) || defined(M68060)
u_int stfree = 0; /* XXX: gcc -Wuninitialized */
#endif
/*
* Calculate important physical addresses:
@ -154,7 +154,7 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
*/
#if defined(M68040) || defined(M68060)
if (RELOC(mmutype, int) == MMU_68040) {
int num;
int nl1desc, nl2desc, i;
/*
* First invalidate the entire "segment table" pages
@ -172,10 +172,10 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
num = nptpages * (NPTEPG / SG4_LEV3SIZE);
nl2desc = nptpages * (NPTEPG / SG4_LEV3SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE];
este = &ste[num];
este = &ste[nl2desc];
protoste = kptpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
@ -183,37 +183,55 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
}
/*
* Initialize level 1 descriptors. We need:
* howmany(num, SG4_LEV2SIZE)
* level 1 descriptors to map the `num' level 2's.
* howmany(nl2desc, SG4_LEV2SIZE)
* level 1 descriptors to map the `nl2desc' level 2's.
*/
nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
este = &ste[howmany(num, SG4_LEV2SIZE)];
este = &ste[nl1desc];
protoste = (paddr_t)este[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV2SIZE * sizeof(st_entry_t));
}
/*
* Initialize the final level 1 descriptor to map the last
* block of level 2 descriptors.
* Initialize the final level 1 descriptor to map the next
* block of level 2 descriptors for Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[SG4_LEV1SIZE - 1];
este = (st_entry_t *)kstpa;
este = &este[kstsize * NPTEPG - SG4_LEV2SIZE];
*ste = (paddr_t)este | SG_U | SG_RW | SG_V;
*ste = protoste;
/*
* Now initialize the final portion of that block of
* descriptors to map kptmpa.
*/
i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
ste = (st_entry_t *)kstpa;
ste = &ste[kstsize * NPTEPG - NPTEPG / SG4_LEV3SIZE];
ste = &ste[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
este = &ste[NPTEPG / SG4_LEV3SIZE];
protoste = kptmpa | SG_U | SG_RW | SG_V;
while (ste < este) {
*ste++ = protoste;
protoste += (SG4_LEV3SIZE * sizeof(st_entry_t));
}
/*
* Calculate the free level 2 descriptor mask
* noting that we have used:
* 0: level 1 table
* 1 to nl1desc: map page tables
* nl1desc + 1: maps kptmpa and last-page page table
*/
/* mark an entry for level 1 table */
stfree = ~l2tobm(0);
/* mark entries for map page tables */
for (i = 1; i <= nl1desc; i++)
stfree &= ~l2tobm(i);
/* mark an entry for kptmpa and lkptpa */
stfree &= ~l2tobm(i);
/* mark entries not available */
for (i = MAXKL2SIZE; i < sizeof(stfree) * NBBY; i++)
stfree &= ~l2tobm(i);
/*
* Initialize Sysptmap
*/
@ -225,16 +243,18 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entry.
* Invalidate all remaining entries.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 1];
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte) {
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
} else
#endif /* M68040 || M68060 */
@ -255,18 +275,24 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
protopte += PAGE_SIZE;
}
/*
* Invalidate all but the last remaining entries in both.
* Invalidate all remaining entries in both.
*/
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG - 1];
while (pte < epte) {
este = (st_entry_t *)kstpa;
este = &este[NPTEPG]; /* XXX: should be TIA_SIZE */
while (ste < este)
*ste++ = SG_NV;
epte = (pt_entry_t *)kptmpa;
epte = &epte[NPTEPG]; /* XXX: should be TIB_SIZE */
while (pte < epte)
*pte++ = PG_NV;
}
/*
* Initialize the last one to point to Sysptmap.
*/
ste = (st_entry_t *)kstpa;
ste = &ste[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*ste = kptmpa | SG_RW | SG_V;
pte = (pt_entry_t *)kptmpa;
pte = &pte[NPTEPG - 1]; /* XXX: should be TIA_SIZE */
*pte = kptmpa | PG_RW | PG_CI | PG_V;
}
@ -411,27 +437,8 @@ pmap_bootstrap(paddr_t nextpa, paddr_t firstpa)
kpm->pm_count = 1;
kpm->pm_stpa = (st_entry_t *)kstpa;
#if defined(M68040) || defined(M68060)
/*
* For the 040 we also initialize the free level 2
* descriptor mask noting that we have used:
* 0: level 1 table
* 1 to `num': map page tables
* MAXKL2SIZE-1: maps kptmpa and last-page page table
*/
if (RELOC(mmutype, int) == MMU_68040) {
int num;
kpm->pm_stfree = ~l2tobm(0);
num = howmany(nptpages * (NPTEPG / SG4_LEV3SIZE),
SG4_LEV2SIZE);
while (num)
kpm->pm_stfree &= ~l2tobm(num--);
kpm->pm_stfree &= ~l2tobm(MAXKL2SIZE-1);
for (num = MAXKL2SIZE;
num < sizeof(kpm->pm_stfree)*NBBY;
num++)
kpm->pm_stfree &= ~l2tobm(num);
}
if (RELOC(mmutype, int) == MMU_68040)
kpm->pm_stfree = stfree;
#endif
}