From owner-svn-src-all@FreeBSD.ORG Thu Nov 12 15:19:09 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5D073106566B; Thu, 12 Nov 2009 15:19:09 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4B7188FC27; Thu, 12 Nov 2009 15:19:09 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nACFJ9BQ034390; Thu, 12 Nov 2009 15:19:09 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nACFJ9K0034388; Thu, 12 Nov 2009 15:19:09 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <200911121519.nACFJ9K0034388@svn.freebsd.org> From: Nathan Whitehorn Date: Thu, 12 Nov 2009 15:19:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199226 - head/sys/powerpc/aim X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Nov 2009 15:19:09 -0000 Author: nwhitehorn Date: Thu Nov 12 15:19:09 2009 New Revision: 199226 URL: http://svn.freebsd.org/changeset/base/199226 Log: 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. Reviewed by: grehan Modified: head/sys/powerpc/aim/mmu_oea64.c Modified: head/sys/powerpc/aim/mmu_oea64.c ============================================================================== --- head/sys/powerpc/aim/mmu_oea64.c Thu Nov 12 14:48:36 2009 (r199225) +++ head/sys/powerpc/aim/mmu_oea64.c Thu Nov 12 15:19:09 2009 (r199226) @@ -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