From owner-svn-src-all@FreeBSD.ORG Wed Mar 18 23:50:25 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 5FDDD106564A; Wed, 18 Mar 2009 23:50:25 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4BA018FC19; Wed, 18 Mar 2009 23:50:25 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2INoPlm041691; Wed, 18 Mar 2009 23:50:25 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2INoPhF041690; Wed, 18 Mar 2009 23:50:25 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <200903182350.n2INoPhF041690@svn.freebsd.org> From: Marius Strobl Date: Wed, 18 Mar 2009 23:50:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r190002 - in stable/7/sys: . boot/sparc64/loader contrib/pf dev/ath/ath_hal dev/cxgb 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: Wed, 18 Mar 2009 23:50:26 -0000 Author: marius Date: Wed Mar 18 23:50:25 2009 New Revision: 190002 URL: http://svn.freebsd.org/changeset/base/190002 Log: MFC: r182478, r182766 - Read ASI_{D,I}TLB_DATA_ACCESS_REG twice in order to work around errata of USIII and beyond (USIII erratum #19, USIII+ erratum #1, USIIIi erratum #1). - Use the cheetah PA mask in {d,i}tlb_va_to_pa_sun4u() for USIII and beyond. This is done so that these functions will still mask the debug bits of spitfire-class CPUs once we increase TD_PA_BITS to match the number of bits used for the PA by cheetah-class CPUs. - Change {d,i}tlb_enter_sun4u() to also set TLB_CTX_KERNEL as the context of the mappings entered. This is more or less cosmetic as TLB_CTX_KERNEL is 0. - Now that we have to distinguish between different sun4u CPUs in the loader anyway, no longer do trial and error when reading the portid property. Modified: stable/7/sys/ (props changed) stable/7/sys/boot/sparc64/loader/main.c stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) Modified: stable/7/sys/boot/sparc64/loader/main.c ============================================================================== --- stable/7/sys/boot/sparc64/loader/main.c Wed Mar 18 23:35:40 2009 (r190001) +++ stable/7/sys/boot/sparc64/loader/main.c Wed Mar 18 23:50:25 2009 (r190002) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "bootstrap.h" #include "libofw.h" @@ -57,8 +58,10 @@ static struct mmu_ops { typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); +static inline u_long dtlb_get_data_sun4u(int slot); static void dtlb_enter_sun4u(u_long vpn, u_long data); static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); +static inline u_long itlb_get_data_sun4u(int slot); static void itlb_enter_sun4u(u_long vpn, u_long data); static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); extern vm_offset_t md_load(char *, vm_offset_t *); @@ -92,6 +95,7 @@ struct tlb_entry *dtlb_store; struct tlb_entry *itlb_store; int dtlb_slot; int itlb_slot; +int cpu_impl; static int dtlb_slot_max; static int itlb_slot_max; @@ -365,60 +369,98 @@ __elfN(exec)(struct preloaded_file *fp) panic("%s: exec returned", __func__); } +static inline u_long +dtlb_get_data_sun4u(int slot) +{ + + /* + * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * around errata of USIII and beyond. + */ + (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); + return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); +} + +static inline u_long +itlb_get_data_sun4u(int slot) +{ + + /* + * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work + * around errata of USIII and beyond. + */ + (void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG); + return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG)); +} + static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t va) { - u_long reg; + u_long pstate, reg; int i; + pstate = rdpr(pstate); + wrpr(pstate, pstate & ~PSTATE_IE, 0); for (i = 0; i < dtlb_slot_max; i++) { reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); if (TLB_TAR_VA(reg) != va) continue; - reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); + reg = dtlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); + if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) + return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); } + wrpr(pstate, pstate, 0); return (-1); } static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t va) { - u_long reg; + u_long pstate, reg; int i; + pstate = rdpr(pstate); + wrpr(pstate, pstate & ~PSTATE_IE, 0); for (i = 0; i < itlb_slot_max; i++) { reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); if (TLB_TAR_VA(reg) != va) continue; - reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + reg = itlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); + if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) + return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); } + wrpr(pstate, pstate, 0); return (-1); } static void -itlb_enter_sun4u(u_long vpn, u_long data) +dtlb_enter_sun4u(u_long vpn, u_long data) { u_long reg; reg = rdpr(pstate); wrpr(pstate, reg & ~PSTATE_IE, 0); - stxa(AA_IMMU_TAR, ASI_IMMU, vpn); - stxa(0, ASI_ITLB_DATA_IN_REG, data); + stxa(AA_DMMU_TAR, ASI_DMMU, + TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); + stxa(0, ASI_DTLB_DATA_IN_REG, data); membar(Sync); wrpr(pstate, reg, 0); } static void -dtlb_enter_sun4u(u_long vpn, u_long data) +itlb_enter_sun4u(u_long vpn, u_long data) { u_long reg; reg = rdpr(pstate); wrpr(pstate, reg & ~PSTATE_IE, 0); - stxa(AA_DMMU_TAR, ASI_DMMU, vpn); - stxa(0, ASI_DTLB_DATA_IN_REG, data); + stxa(AA_IMMU_TAR, ASI_IMMU, + TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); + stxa(0, ASI_ITLB_DATA_IN_REG, data); membar(Sync); wrpr(pstate, reg, 0); } @@ -539,19 +581,18 @@ tlb_init_sun4u(void) u_int bootcpu; u_int cpu; + cpu_impl = VER_IMPL(rdpr(ver)); bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); for (child = OF_child(root); child != 0; child = OF_peer(child)) { - if (child == -1) - panic("%s: can't get child phandle", __func__); - if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 && - strcmp(buf, "cpu") == 0) { - if (OF_getprop(child, "upa-portid", &cpu, - sizeof(cpu)) == -1 && OF_getprop(child, "portid", - &cpu, sizeof(cpu)) == -1) - panic("%s: can't get portid", __func__); - if (cpu == bootcpu) - break; - } + if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0) + continue; + if (strcmp(buf, "cpu") != 0) + continue; + if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? + "upa-portid" : "portid", &cpu, sizeof(cpu)) <= 0) + continue; + if (cpu == bootcpu) + break; } if (cpu != bootcpu) panic("%s: no node for bootcpu?!?!", __func__); @@ -712,10 +753,14 @@ static void pmap_print_tlb_sun4u(void) { tte_t tag, tte; + u_long pstate; int i; + pstate = rdpr(pstate); for (i = 0; i < itlb_slot_max; i++) { - tte = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + wrpr(pstate, pstate & ~PSTATE_IE, 0); + tte = itlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); if (!(tte & TD_V)) continue; tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); @@ -723,7 +768,9 @@ pmap_print_tlb_sun4u(void) pmap_print_tte_sun4u(tag, tte); } for (i = 0; i < dtlb_slot_max; i++) { - tte = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); + wrpr(pstate, pstate & ~PSTATE_IE, 0); + tte = dtlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); if (!(tte & TD_V)) continue; tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG);