svn commit: r205131 - in projects/ppc64/sys/powerpc: aim include
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Mar 13 21:28:15 UTC 2010
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 <sys/_mutex.h>
#include <machine/sr.h>
#include <machine/pte.h>
-#include <machine/tlb.h>
#include <machine/slb.h>
+#include <machine/tlb.h>
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
More information about the svn-src-projects
mailing list