svn commit: r199892 - stable/8/sys/powerpc/aim
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Nov 28 20:02:45 UTC 2009
Author: nwhitehorn
Date: Sat Nov 28 20:02:45 2009
New Revision: 199892
URL: http://svn.freebsd.org/changeset/base/199892
Log:
MFC r199226:
Provide a real fix to the too-many-translations problem when booting
from CD on 64-bit hardware to replace existing band-aids. This occurred
when the preloaded mdroot required too many mappings for the static
buffer.
Since we only use the translations buffer once, allocate a dynamic
buffer on the stack. This early in the boot process, the call chain
is quite short and we can be assured of having sufficient stack space.
Modified:
stable/8/sys/powerpc/aim/mmu_oea64.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- stable/8/sys/powerpc/aim/mmu_oea64.c Sat Nov 28 19:37:58 2009 (r199891)
+++ stable/8/sys/powerpc/aim/mmu_oea64.c Sat Nov 28 20:02:45 2009 (r199892)
@@ -264,7 +264,6 @@ static struct mem_region *pregions;
extern u_int phys_avail_count;
extern int regions_sz, pregions_sz;
extern int ofw_real_mode;
-static struct ofw_map translations[96];
extern struct pmap ofw_pmap;
@@ -709,17 +708,73 @@ moea64_bridge_cpu_bootstrap(mmu_t mmup,
}
static void
+moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz)
+{
+ struct ofw_map translations[sz/sizeof(struct ofw_map)];
+ register_t msr;
+ vm_offset_t off;
+ int i, ofw_mappings;
+
+ bzero(translations, sz);
+ if (OF_getprop(mmu, "translations", translations, sz) == -1)
+ panic("moea64_bootstrap: can't get ofw translations");
+
+ CTR0(KTR_PMAP, "moea64_add_ofw_mappings: translations");
+ sz /= sizeof(*translations);
+ qsort(translations, sz, sizeof (*translations), om_cmp);
+
+ for (i = 0, ofw_mappings = 0; i < sz; i++) {
+ CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
+ (uint32_t)(translations[i].om_pa_lo), translations[i].om_va,
+ translations[i].om_len);
+
+ if (translations[i].om_pa_lo % PAGE_SIZE)
+ panic("OFW translation not page-aligned!");
+
+ if (translations[i].om_pa_hi)
+ panic("OFW translations above 32-bit boundary!");
+
+ /* Now enter the pages for this mapping */
+
+ /*
+ * Lock the ofw pmap. pmap_kenter(), which we use for the
+ * pages the kernel also needs, does its own locking.
+ */
+ PMAP_LOCK(&ofw_pmap);
+ DISABLE_TRANS(msr);
+ for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
+ struct vm_page m;
+
+ /* Map low memory mappings into the kernel pmap, too.
+ * These are typically mappings made by the loader,
+ * so we need them if we want to keep executing. */
+
+ if (translations[i].om_va + off < SEGMENT_LENGTH)
+ moea64_kenter(mmup, translations[i].om_va + off,
+ translations[i].om_va + off);
+
+ m.phys_addr = translations[i].om_pa_lo + off;
+ moea64_enter_locked(&ofw_pmap,
+ translations[i].om_va + off, &m, VM_PROT_ALL, 1);
+
+ ofw_mappings++;
+ }
+ ENABLE_TRANS(msr);
+ PMAP_UNLOCK(&ofw_pmap);
+ }
+}
+
+static void
moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
{
ihandle_t mmui;
phandle_t chosen;
phandle_t mmu;
- int sz;
+ size_t sz;
int i, j;
- int ofw_mappings;
vm_size_t size, physsz, hwphyssz;
vm_offset_t pa, va, off;
- uint32_t msr;
+ register_t msr;
void *dpcpu;
/* We don't have a direct map since there is no BAT */
@@ -865,7 +920,6 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
off = (vm_offset_t)(moea64_bpvo_pool);
for (pa = off; pa < off + size; pa += PAGE_SIZE)
moea64_kenter(mmup, pa, pa);
- ENABLE_TRANS(msr);
/*
* Map certain important things, like ourselves.
@@ -876,7 +930,6 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
* address.
*/
- DISABLE_TRANS(msr);
for (pa = kernelstart & ~PAGE_MASK; pa < kernelend; pa += PAGE_SIZE)
moea64_kenter(mmup, pa, pa);
ENABLE_TRANS(msr);
@@ -897,57 +950,10 @@ moea64_bridge_bootstrap(mmu_t mmup, vm_o
panic("moea64_bootstrap: can't get mmu package");
if ((sz = OF_getproplen(mmu, "translations")) == -1)
panic("moea64_bootstrap: can't get ofw translation count");
- if (sz > sizeof(translations))
- panic("moea64_bootstrap: too many ofw translations (%d)",
- sz/sizeof(*translations));
-
- bzero(translations, sz);
- if (OF_getprop(mmu, "translations", translations, sz) == -1)
- panic("moea64_bootstrap: can't get ofw translations");
-
- CTR0(KTR_PMAP, "moea64_bootstrap: translations");
- sz /= sizeof(*translations);
- qsort(translations, sz, sizeof (*translations), om_cmp);
-
- for (i = 0, ofw_mappings = 0; i < sz; i++) {
- CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
- (uint32_t)(translations[i].om_pa_lo), translations[i].om_va,
- translations[i].om_len);
-
- if (translations[i].om_pa_lo % PAGE_SIZE)
- panic("OFW translation not page-aligned!");
-
- if (translations[i].om_pa_hi)
- panic("OFW translations above 32-bit boundary!");
-
- /* Now enter the pages for this mapping */
-
- /*
- * Lock the ofw pmap. pmap_kenter(), which we use for the
- * pages the kernel also needs, does its own locking.
- */
- PMAP_LOCK(&ofw_pmap);
- DISABLE_TRANS(msr);
- for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
- struct vm_page m;
-
- /* Map low memory mappings into the kernel pmap, too.
- * These are typically mappings made by the loader,
- * so we need them if we want to keep executing. */
-
- if (translations[i].om_va + off < SEGMENT_LENGTH)
- moea64_kenter(mmup, translations[i].om_va + off,
- translations[i].om_va + off);
+ if (sz > 6144 /* tmpstksz - 2 KB headroom */)
+ panic("moea64_bootstrap: too many ofw translations");
- m.phys_addr = translations[i].om_pa_lo + off;
- moea64_enter_locked(&ofw_pmap,
- translations[i].om_va + off, &m, VM_PROT_ALL, 1);
-
- ofw_mappings++;
- }
- ENABLE_TRANS(msr);
- PMAP_UNLOCK(&ofw_pmap);
- }
+ moea64_add_ofw_mappings(mmup, mmu, sz);
}
#ifdef SMP
More information about the svn-src-stable-8
mailing list