summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/powerpc/aim/mmu_oea64.c3
-rw-r--r--sys/powerpc/aim/ofw_machdep.c13
-rw-r--r--sys/powerpc/aim/slb.c55
-rw-r--r--sys/powerpc/booke/machdep.c9
-rw-r--r--sys/powerpc/include/platform.h1
-rw-r--r--sys/powerpc/powerpc/mp_machdep.c7
-rw-r--r--sys/powerpc/powerpc/platform.c51
-rw-r--r--sys/powerpc/powerpc/platform_if.m30
-rw-r--r--sys/sys/smp.h5
9 files changed, 140 insertions, 34 deletions
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 002754d..af57834 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -2385,6 +2385,9 @@ moea64_bootstrap_alloc(vm_size_t size, u_int align)
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]) {
diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c
index 1ebcd0c..84f9cf0 100644
--- a/sys/powerpc/aim/ofw_machdep.c
+++ b/sys/powerpc/aim/ofw_machdep.c
@@ -692,16 +692,3 @@ OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
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);
-}
-
diff --git a/sys/powerpc/aim/slb.c b/sys/powerpc/aim/slb.c
index 9d8828a..d5fb12e 100644
--- a/sys/powerpc/aim/slb.c
+++ b/sys/powerpc/aim/slb.c
@@ -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 *slb)
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 **
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 860c271..921dfbf 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -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);
-}
diff --git a/sys/powerpc/include/platform.h b/sys/powerpc/include/platform.h
index cfa7a0d..48ea0e6 100644
--- a/sys/powerpc/include/platform.h
+++ b/sys/powerpc/include/platform.h
@@ -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 *);
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index 9086db5..ee95f86 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -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)
{
diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c
index 2b5c607..02d89ee 100644
--- a/sys/powerpc/powerpc/platform.c
+++ b/sys/powerpc/powerpc/platform.c
@@ -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)
diff --git a/sys/powerpc/powerpc/platform_if.m b/sys/powerpc/powerpc/platform_if.m
index 07e49bc..94383c3 100644
--- a/sys/powerpc/powerpc/platform_if.m
+++ b/sys/powerpc/powerpc/platform_if.m
@@ -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 {
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index 619eba8..6104d3e 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -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);
OpenPOWER on IntegriCloud