From owner-svn-src-projects@FreeBSD.ORG Sat Mar 13 21:28:14 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EE28F106564A; Sat, 13 Mar 2010 21:28:14 +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 DC7F28FC18; Sat, 13 Mar 2010 21:28:14 +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 o2DLSEWD038200; Sat, 13 Mar 2010 21:28:14 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2DLSEiv038196; Sat, 13 Mar 2010 21:28:14 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201003132128.o2DLSEiv038196@svn.freebsd.org> From: Nathan Whitehorn Date: Sat, 13 Mar 2010 21:28:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205131 - in projects/ppc64/sys/powerpc: aim include X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Mar 2010 21:28:15 -0000 Author: nwhitehorn Date: Sat Mar 13 21:28:14 2010 New Revision: 205131 URL: http://svn.freebsd.org/changeset/base/205131 Log: Provide a mechanism for handling kernel SLB spills that does not fill me with terror to imagine. Modified: projects/ppc64/sys/powerpc/aim/machdep.c projects/ppc64/sys/powerpc/aim/trap.c projects/ppc64/sys/powerpc/include/pmap.h projects/ppc64/sys/powerpc/include/vmparam.h Modified: projects/ppc64/sys/powerpc/aim/machdep.c ============================================================================== --- projects/ppc64/sys/powerpc/aim/machdep.c Sat Mar 13 20:43:11 2010 (r205130) +++ projects/ppc64/sys/powerpc/aim/machdep.c Sat Mar 13 21:28:14 2010 (r205131) @@ -822,56 +822,7 @@ db_trap_glue(struct trapframe *frame) return (0); } -#ifdef __powerpc64__ -uintptr_t moea64_get_unique_vsid(void); - -uint64_t -va_to_vsid(pmap_t pm, vm_offset_t va) -{ - uint64_t slbe, slbv, i; - - slbe = (uintptr_t)va >> ADDR_SR_SHFT; - slbe = (slbe << SLBE_ESID_SHIFT) | SLBE_VALID; - slbv = 0; - - for (i = 0; i < sizeof(pm->pm_slb)/sizeof(pm->pm_slb[0]); i++) { - if (pm->pm_slb[i].slbe == (slbe | i)) { - slbv = pm->pm_slb[i].slbv; - break; - } - } - - /* XXX: Have a long list for processes mapping more than 16 GB */ - - /* - * If there is no vsid for this VA, we need to add a new entry - * to the PMAP's segment table. - */ - - if (slbv == 0) { - slbv = moea64_get_unique_vsid() << SLBV_VSID_SHIFT; - for (i = 0; i < sizeof(pm->pm_slb)/sizeof(pm->pm_slb[0]); i++) { - if (pm == kernel_pmap && i == USER_SR) - continue; - - if (!(pm->pm_slb[i].slbe & SLBE_VALID)) { - pm->pm_slb[i].slbv = slbv; - pm->pm_slb[i].slbe = slbe | i; - - if (pm == kernel_pmap && pmap_bootstrapped) { - __asm __volatile ("slbmte %0, %1" :: - "r"(kernel_pmap->pm_slb[i].slbv), - "r"(kernel_pmap->pm_slb[i].slbe)); - } - break; - } - } - } - - return ((slbv & SLBV_VSID_MASK) >> SLBV_VSID_SHIFT); -} - -#else +#ifndef __powerpc64__ uint64_t va_to_vsid(pmap_t pm, vm_offset_t va) Modified: projects/ppc64/sys/powerpc/aim/trap.c ============================================================================== --- projects/ppc64/sys/powerpc/aim/trap.c Sat Mar 13 20:43:11 2010 (r205130) +++ projects/ppc64/sys/powerpc/aim/trap.c Sat Mar 13 21:28:14 2010 (r205131) @@ -87,6 +87,11 @@ static int ppc_instr_emulate(struct trap static int handle_onfault(struct trapframe *frame); static void syscall(struct trapframe *frame); +#ifdef __powerpc64__ +static void handle_slb_spill(pmap_t pm, vm_offset_t addr); +static uint64_t slb_esid_lookup(pmap_t pm, uint64_t vsid); +#endif + int setfault(faultbuf); /* defined in locore.S */ /* Why are these not defined in a header? */ @@ -182,22 +187,9 @@ trap(struct trapframe *frame) #ifdef __powerpc64__ case EXC_ISE: case EXC_DSE: - /* - * Once we support more segments per process - * than the SLB size, we should reload the SLB - * cache here from the longer segment list. - * - * For now, we assume a miss, and call va_to_vsid() - * to allocate a new segment. This will then likely - * trigger a page fault immediately after. - */ - - PMAP_LOCK(&p->p_vmspace->vm_pmap); - (void)va_to_vsid(&p->p_vmspace->vm_pmap, + handle_slb_spill(&p->p_vmspace->vm_pmap, (type == EXC_ISE) ? frame->srr0 : frame->cpu.aim.dar); - PMAP_UNLOCK(&p->p_vmspace->vm_pmap); - break; #endif case EXC_DSI: @@ -259,11 +251,9 @@ trap(struct trapframe *frame) #ifdef __powerpc64__ case EXC_ISE: case EXC_DSE: - PMAP_LOCK(kernel_pmap); - (void)va_to_vsid(kernel_pmap, + handle_slb_spill(kernel_pmap, (type == EXC_ISE) ? frame->srr0 : frame->cpu.aim.dar); - PMAP_UNLOCK(kernel_pmap); return; #endif case EXC_MCHK: @@ -531,6 +521,21 @@ slb_esid_lookup(pmap_t pm, uint64_t vsid return (0); } + +static void +handle_slb_spill(pmap_t pm, vm_offset_t addr) +{ + uint64_t vsid, esid; + + PMAP_LOCK(pm); + esid = addr >> ADDR_SR_SHFT; + vsid = va_to_vsid_noalloc(pm, addr); + if (vsid == 0) + (void)va_to_vsid(pm, addr); + else + slb_spill(pm, esid, vsid); + PMAP_UNLOCK(pm); +} #endif static int Modified: projects/ppc64/sys/powerpc/include/pmap.h ============================================================================== --- projects/ppc64/sys/powerpc/include/pmap.h Sat Mar 13 20:43:11 2010 (r205130) +++ projects/ppc64/sys/powerpc/include/pmap.h Sat Mar 13 21:28:14 2010 (r205131) @@ -69,8 +69,8 @@ #include #include #include -#include #include +#include struct pmap_md { u_int md_index; @@ -124,12 +124,16 @@ struct md_page { /* * Return the VSID corresponding to a given virtual address. - * If no VSID is currently defined, it will allocate one, and add it to - * a free SLB slot if available. + * If no VSID is currently defined, it will allocate one, and add + * it to a free slot if available. * * NB: The PMAP MUST be locked already. */ uint64_t va_to_vsid(pmap_t pm, vm_offset_t va); +uint64_t va_to_vsid_noalloc(pmap_t pm, vm_offset_t va); + +uint64_t allocate_vsid(pmap_t pm, uint64_t esid); +void slb_spill(pmap_t pm, uint64_t esid, uint64_t vsid); #else Modified: projects/ppc64/sys/powerpc/include/vmparam.h ============================================================================== --- projects/ppc64/sys/powerpc/include/vmparam.h Sat Mar 13 20:43:11 2010 (r205130) +++ projects/ppc64/sys/powerpc/include/vmparam.h Sat Mar 13 21:28:14 2010 (r205131) @@ -79,28 +79,26 @@ * Would like to have MAX addresses = 0, but this doesn't (currently) work */ #if !defined(LOCORE) -#define VM_MIN_ADDRESS ((vm_offset_t)0) #ifdef __powerpc64__ -#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x4fffff000) +#define VM_MIN_ADDRESS (0x0000000000000000UL) +#define VM_MAXUSER_ADDRESS (0x00000004fffff000UL) +#define VM_MAX_ADDRESS (0xffffffffffffffffUL) #else +#define VM_MIN_ADDRESS ((vm_offset_t)0) #define VM_MAXUSER_ADDRESS ((vm_offset_t)0x7ffff000) +#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS #endif -#else -#define VM_MIN_ADDRESS 0 -#define VM_MAXUSER_ADDRESS 0x7ffff000 #endif /* LOCORE */ -#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS #define FREEBSD32_USRSTACK 0x7ffff000 -#if defined(AIM) /* AIM */ - +#ifdef AIM #define KERNBASE 0x00100000UL /* start of kernel virtual */ #ifdef __powerpc64__ #define VM_MIN_KERNEL_ADDRESS 0xc000000000000000UL -#define VM_MAX_KERNEL_ADDRESS 0xcfffffffefffffffUL +#define VM_MAX_KERNEL_ADDRESS 0xc0000001c8000000UL #define VM_MAX_SAFE_KERNEL_ADDRESS VM_MAX_KERNEL_ADDRESS #else #define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)KERNEL_SR << ADDR_SR_SHFT) @@ -114,7 +112,7 @@ */ #define UMA_MD_SMALL_ALLOC -#else +#else /* Book-E */ /* * Kernel CCSRBAR location. We make this the reset location. @@ -195,7 +193,7 @@ struct pmap_physseg { #endif #ifndef VM_KMEM_SIZE_MAX -#define VM_KMEM_SIZE_MAX 0x200000000 /* XXX: 8 GB until SLB long list */ +#define VM_KMEM_SIZE_MAX 0x1c0000000 /* 7 GB */ #endif #endif