svn commit: r215159 - in head/sys: powerpc/aim powerpc/booke
powerpc/include powerpc/powerpc sys
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Fri Nov 12 04:18:20 UTC 2010
Author: nwhitehorn
Date: Fri Nov 12 04:18:19 2010
New Revision: 215159
URL: http://svn.freebsd.org/changeset/base/215159
Log:
Add some platform KOBJ extensions and continue integrating PowerPC
hypervisor infrastructure support:
- Fix coexistence of multiple platform modules in the same kernel
- Allow platform modules to provide an SMP topology
- PowerPC hypervisors limit the amount of memory accessible in real mode.
Allow the platform modules to specify the maximum real-mode address,
and modify the bits of the kernel that need to allocate
real-mode-accessible buffers to respect this limits.
Modified:
head/sys/powerpc/aim/mmu_oea64.c
head/sys/powerpc/aim/ofw_machdep.c
head/sys/powerpc/aim/slb.c
head/sys/powerpc/booke/machdep.c
head/sys/powerpc/include/platform.h
head/sys/powerpc/powerpc/mp_machdep.c
head/sys/powerpc/powerpc/platform.c
head/sys/powerpc/powerpc/platform_if.m
head/sys/sys/smp.h
Modified: head/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- head/sys/powerpc/aim/mmu_oea64.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/aim/mmu_oea64.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -2385,6 +2385,9 @@ moea64_bootstrap_alloc(vm_size_t size, u
if (s < phys_avail[i] || e > phys_avail[i + 1])
continue;
+ if (s + size > platform_real_maxaddr())
+ continue;
+
if (s == phys_avail[i]) {
phys_avail[i] += size;
} else if (e == phys_avail[i + 1]) {
Modified: head/sys/powerpc/aim/ofw_machdep.c
==============================================================================
--- head/sys/powerpc/aim/ofw_machdep.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/aim/ofw_machdep.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -692,16 +692,3 @@ OF_decode_addr(phandle_t dev, int regno,
return (bus_space_map(*tag, addr, size, 0, handle));
}
-int
-mem_valid(vm_offset_t addr, int len)
-{
- int i;
-
- for (i = 0; i < nOFmem; i++)
- if ((addr >= OFmem[i].mr_start)
- && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size))
- return (0);
-
- return (EFAULT);
-}
-
Modified: head/sys/powerpc/aim/slb.c
==============================================================================
--- head/sys/powerpc/aim/slb.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/aim/slb.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -36,9 +36,14 @@
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/uma.h>
+#include <vm/vm.h>
#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
#include <machine/md_var.h>
+#include <machine/platform.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
@@ -474,6 +479,51 @@ slb_insert_user(pmap_t pm, struct slb *s
pm->pm_slb[i] = slb;
}
+static void *
+slb_uma_real_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
+{
+ static vm_offset_t realmax = 0;
+ void *va;
+ vm_page_t m;
+ int pflags;
+
+ if (realmax == 0)
+ realmax = platform_real_maxaddr();
+
+ *flags = UMA_SLAB_PRIV;
+ if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
+ pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED;
+ else
+ pflags = VM_ALLOC_SYSTEM | VM_ALLOC_WIRED;
+ if (wait & M_ZERO)
+ pflags |= VM_ALLOC_ZERO;
+
+ for (;;) {
+ m = vm_phys_alloc_contig(1, 0, realmax, PAGE_SIZE,
+ PAGE_SIZE);
+ if (m == NULL) {
+ if (wait & M_NOWAIT)
+ return (NULL);
+ VM_WAIT;
+ } else
+ break;
+ }
+
+ va = (void *) VM_PAGE_TO_PHYS(m);
+
+ if (!hw_direct_map)
+ pmap_kenter((vm_offset_t)va, VM_PAGE_TO_PHYS(m));
+
+ if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ bzero(va, PAGE_SIZE);
+
+ /* vm_phys_alloc_contig does not track wiring */
+ atomic_add_int(&cnt.v_wire_count, 1);
+ m->wire_count = 1;
+
+ return (va);
+}
+
static void
slb_zone_init(void *dummy)
{
@@ -482,6 +532,11 @@ slb_zone_init(void *dummy)
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
slb_cache_zone = uma_zcreate("SLB cache", 64*sizeof(struct slb *),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
+
+ if (platform_real_maxaddr() != VM_MAX_ADDRESS) {
+ uma_zone_set_allocf(slb_cache_zone, slb_uma_real_alloc);
+ uma_zone_set_allocf(slbt_zone, slb_uma_real_alloc);
+ }
}
struct slb **
Modified: head/sys/powerpc/booke/machdep.c
==============================================================================
--- head/sys/powerpc/booke/machdep.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/booke/machdep.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -597,12 +597,3 @@ bzero(void *buf, size_t len)
}
}
-/*
- * XXX what is the better/proper place for this routine?
- */
-int
-mem_valid(vm_offset_t addr, int len)
-{
-
- return (1);
-}
Modified: head/sys/powerpc/include/platform.h
==============================================================================
--- head/sys/powerpc/include/platform.h Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/include/platform.h Fri Nov 12 04:18:19 2010 (r215159)
@@ -44,6 +44,7 @@ struct mem_region {
};
void mem_regions(struct mem_region **, int *, struct mem_region **, int *);
+vm_offset_t platform_real_maxaddr(void);
u_long platform_timebase_freq(struct cpuref *);
Modified: head/sys/powerpc/powerpc/mp_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/powerpc/mp_machdep.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -98,13 +98,6 @@ machdep_ap_bootstrap(void)
sched_throw(NULL);
}
-struct cpu_group *
-cpu_topo(void)
-{
-
- return (smp_topo_none());
-}
-
void
cpu_mp_setmaxid(void)
{
Modified: head/sys/powerpc/powerpc/platform.c
==============================================================================
--- head/sys/powerpc/powerpc/platform.c Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/powerpc/platform.c Fri Nov 12 04:18:19 2010 (r215159)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/types.h>
@@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <machine/cpu.h>
+#include <machine/md_var.h>
#include <machine/platform.h>
#include <machine/platformvar.h>
#include <machine/smp.h>
@@ -62,11 +64,45 @@ static char plat_name[64] = "";
SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RD | CTLFLAG_TUN,
plat_name, 0, "Platform currently in use");
+static struct mem_region *pregions = NULL;
+static struct mem_region *aregions = NULL;
+static int npregions, naregions;
+
void
mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail,
int *availsz)
{
- PLATFORM_MEM_REGIONS(plat_obj, phys, physsz, avail, availsz);
+ if (pregions == NULL)
+ PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions,
+ &aregions, &naregions);
+
+ *phys = pregions;
+ *avail = aregions;
+ *physsz = npregions;
+ *availsz = naregions;
+}
+
+int
+mem_valid(vm_offset_t addr, int len)
+{
+ int i;
+
+ if (pregions == NULL)
+ PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions,
+ &aregions, &naregions);
+
+ for (i = 0; i < npregions; i++)
+ if ((addr >= pregions[i].mr_start)
+ && (addr + len < pregions[i].mr_start + pregions[i].mr_size))
+ return (0);
+
+ return (EFAULT);
+}
+
+vm_offset_t
+platform_real_maxaddr(void)
+{
+ return (PLATFORM_REAL_MAXADDR(plat_obj));
}
const char *
@@ -105,6 +141,14 @@ platform_smp_start_cpu(struct pcpu *cpu)
return (PLATFORM_SMP_START_CPU(plat_obj, cpu));
}
+#ifdef SMP
+struct cpu_group *
+cpu_topo(void)
+{
+ return (PLATFORM_SMP_TOPO(plat_obj));
+}
+#endif
+
/*
* Reset back to firmware.
*/
@@ -164,9 +208,10 @@ platform_probe_and_attach()
}
/*
- * We can't free the KOBJ, since it is static. Luckily,
- * this has no ill effects since it gets reset every time.
+ * We can't free the KOBJ, since it is static. Reset the ops
+ * member of this class so that we can come back later.
*/
+ platp->ops = NULL;
}
if (plat_def_impl == NULL)
Modified: head/sys/powerpc/powerpc/platform_if.m
==============================================================================
--- head/sys/powerpc/powerpc/platform_if.m Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/powerpc/powerpc/platform_if.m Fri Nov 12 04:18:19 2010 (r215159)
@@ -30,10 +30,12 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/smp.h>
#include <machine/platform.h>
#include <machine/platformvar.h>
#include <machine/smp.h>
+#include <machine/vmparam.h>
/**
* @defgroup PLATFORM platform - KObj methods for PowerPC platform
@@ -66,6 +68,18 @@ CODE {
{
return (ENOENT);
}
+ static struct cpu_group *platform_null_smp_topo(platform_t plat)
+ {
+#ifdef SMP
+ return (smp_topo_none());
+#else
+ return (NULL);
+#endif
+ }
+ static vm_offset_t platform_null_real_maxaddr(platform_t plat)
+ {
+ return (VM_MAX_ADDRESS);
+ }
};
/**
@@ -109,6 +123,15 @@ METHOD void mem_regions {
};
/**
+ * @brief Return the maximum address accessible in real mode
+ * (for use with hypervisors)
+ */
+METHOD vm_offset_t real_maxaddr {
+ platform_t _plat;
+} DEFAULT platform_null_real_maxaddr;
+
+
+/**
* @brief Get the CPU's timebase frequency, in ticks per second.
*
* @param _cpu CPU whose timebase to query
@@ -162,6 +185,13 @@ METHOD int smp_start_cpu {
};
/**
+ * @brief Return SMP topology
+ */
+METHOD cpu_group_t smp_topo {
+ platform_t _plat;
+} DEFAULT platform_null_smp_topo;
+
+/**
* @brief Reset system
*/
METHOD void reset {
Modified: head/sys/sys/smp.h
==============================================================================
--- head/sys/sys/smp.h Fri Nov 12 04:13:48 2010 (r215158)
+++ head/sys/sys/smp.h Fri Nov 12 04:18:19 2010 (r215159)
@@ -16,8 +16,6 @@
#ifndef LOCORE
-#ifdef SMP
-
/*
* Topology of a NUMA or HTT system.
*
@@ -41,6 +39,8 @@ struct cpu_group {
int8_t cg_flags; /* Traversal modifiers. */
};
+typedef struct cpu_group *cpu_group_t;
+
/*
* Defines common resources for CPUs in the group. The highest level
* resource should be used when multiple are shared.
@@ -60,6 +60,7 @@ struct cpu_group {
/*
* Convenience routines for building topologies.
*/
+#ifdef SMP
struct cpu_group *smp_topo(void);
struct cpu_group *smp_topo_none(void);
struct cpu_group *smp_topo_1level(int l1share, int l1count, int l1flags);
More information about the svn-src-head
mailing list