Page MenuHomeFreeBSD

D17933.id56150.diff
No OneTemporary

D17933.id56150.diff

Index: head/sys/powerpc/aim/mmu_oea64.c
===================================================================
--- head/sys/powerpc/aim/mmu_oea64.c
+++ head/sys/powerpc/aim/mmu_oea64.c
@@ -146,8 +146,9 @@
*/
static struct mem_region *regions;
static struct mem_region *pregions;
+static struct numa_mem_region *numa_pregions;
static u_int phys_avail_count;
-static int regions_sz, pregions_sz;
+static int regions_sz, pregions_sz, numapregions_sz;
extern void bs_remap_earlyboot(void);
@@ -1048,6 +1049,8 @@
PMAP_UNLOCK(kernel_pmap);
}
}
+
+ numa_mem_regions(&numa_pregions, &numapregions_sz);
}
static void
Index: head/sys/powerpc/conf/GENERIC64
===================================================================
--- head/sys/powerpc/conf/GENERIC64
+++ head/sys/powerpc/conf/GENERIC64
@@ -35,6 +35,7 @@
options FDT #Flattened Device Tree
options SCHED_ULE #ULE scheduler
+options NUMA #Non-Uniform Memory Architecture support
options PREEMPTION #Enable kernel thread preemption
options VIMAGE # Subsystem virtualization, e.g. VNET
options INET #InterNETworking
Index: head/sys/powerpc/include/intr_machdep.h
===================================================================
--- head/sys/powerpc/include/intr_machdep.h
+++ head/sys/powerpc/include/intr_machdep.h
@@ -54,7 +54,7 @@
void powerpc_dispatch_intr(u_int, struct trapframe *);
int powerpc_enable_intr(void);
int powerpc_setup_intr(const char *, u_int, driver_filter_t, driver_intr_t,
- void *, enum intr_type, void **);
+ void *, enum intr_type, void **, int);
int powerpc_teardown_intr(void *);
int powerpc_bind_intr(u_int irq, u_char cpu);
int powerpc_config_intr(int, enum intr_trigger, enum intr_polarity);
Index: head/sys/powerpc/include/ofw_machdep.h
===================================================================
--- head/sys/powerpc/include/ofw_machdep.h
+++ head/sys/powerpc/include/ofw_machdep.h
@@ -47,7 +47,11 @@
void OF_reboot(void);
void ofw_mem_regions(struct mem_region *, int *, struct mem_region *, int *);
+void ofw_numa_mem_regions(struct numa_mem_region *, int *);
void ofw_quiesce(void); /* Must be called before VM is up! */
void ofw_save_trap_vec(char *);
+int ofw_pcibus_get_domain(device_t dev, device_t child, int *domain);
+int ofw_pcibus_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+ size_t setsize, cpuset_t *cpuset);
#endif /* _MACHINE_OFW_MACHDEP_H_ */
Index: head/sys/powerpc/include/param.h
===================================================================
--- head/sys/powerpc/include/param.h
+++ head/sys/powerpc/include/param.h
@@ -82,7 +82,7 @@
#endif /* SMP || KLD_MODULE */
#ifndef MAXMEMDOM
-#define MAXMEMDOM 1
+#define MAXMEMDOM 8
#endif
#define ALIGNBYTES _ALIGNBYTES
Index: head/sys/powerpc/include/platform.h
===================================================================
--- head/sys/powerpc/include/platform.h
+++ head/sys/powerpc/include/platform.h
@@ -45,9 +45,16 @@
uint64_t mr_size;
};
+struct numa_mem_region {
+ uint64_t mr_start;
+ uint64_t mr_size;
+ uint64_t mr_domain;
+};
+
/* Documentation for these functions is in platform_if.m */
void mem_regions(struct mem_region **, int *, struct mem_region **, int *);
+void numa_mem_regions(struct numa_mem_region **, int *);
vm_offset_t platform_real_maxaddr(void);
u_long platform_timebase_freq(struct cpuref *);
Index: head/sys/powerpc/include/smp.h
===================================================================
--- head/sys/powerpc/include/smp.h
+++ head/sys/powerpc/include/smp.h
@@ -52,6 +52,7 @@
struct cpuref {
uintptr_t cr_hwref;
u_int cr_cpuid;
+ u_int cr_domain;
};
void pmap_cpu_bootstrap(int);
Index: head/sys/powerpc/ofw/ofw_machdep.c
===================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c
+++ head/sys/powerpc/ofw/ofw_machdep.c
@@ -59,6 +59,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_page.h>
+#include <vm/vm_phys.h>
#include <machine/bus.h>
#include <machine/cpu.h>
@@ -222,11 +223,59 @@
j++;
}
- sz = j*sizeof(output[0]);
- return (sz);
+ return (j);
}
+static int
+parse_numa_ofw_memory(phandle_t node, const char *prop,
+ struct numa_mem_region *output)
+{
+ cell_t address_cells, size_cells;
+ cell_t OFmem[4 * PHYS_AVAIL_SZ];
+ int sz, i, j;
+ phandle_t phandle;
+
+ sz = 0;
+
+ /*
+ * Get #address-cells from root node, defaulting to 1 if it cannot
+ * be found.
+ */
+ phandle = OF_finddevice("/");
+ if (OF_getencprop(phandle, "#address-cells", &address_cells,
+ sizeof(address_cells)) < (ssize_t)sizeof(address_cells))
+ address_cells = 1;
+ if (OF_getencprop(phandle, "#size-cells", &size_cells,
+ sizeof(size_cells)) < (ssize_t)sizeof(size_cells))
+ size_cells = 1;
+
+ /*
+ * Get memory.
+ */
+ if (node == -1 || (sz = OF_getencprop(node, prop,
+ OFmem, sizeof(OFmem))) <= 0)
+ panic("Physical memory map not found");
+
+ i = 0;
+ j = 0;
+ while (i < sz/sizeof(cell_t)) {
+ output[j].mr_start = OFmem[i++];
+ if (address_cells == 2) {
+ output[j].mr_start <<= 32;
+ output[j].mr_start += OFmem[i++];
+ }
+ output[j].mr_size = OFmem[i++];
+ if (size_cells == 2) {
+ output[j].mr_size <<= 32;
+ output[j].mr_size += OFmem[i++];
+ }
+ j++;
+ }
+
+ return (j);
+}
+
#ifdef FDT
static int
excise_reserved_regions(struct mem_region *avail, int asz,
@@ -408,6 +457,51 @@
* The available regions need not take the kernel into account.
*/
void
+ofw_numa_mem_regions(struct numa_mem_region *memp, int *memsz)
+{
+ phandle_t phandle;
+ int res, count, msz;
+ char name[31];
+ cell_t associativity[5];
+ struct numa_mem_region *curmemp;
+
+ msz = 0;
+ /*
+ * Get memory from all the /memory nodes.
+ */
+ for (phandle = OF_child(OF_peer(0)); phandle != 0;
+ phandle = OF_peer(phandle)) {
+ if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0)
+ continue;
+ if (strncmp(name, "memory@", strlen("memory@")) != 0)
+ continue;
+
+ count = parse_numa_ofw_memory(phandle, "reg", &memp[msz]);
+ if (count == 0)
+ continue;
+ curmemp = &memp[msz];
+ res = OF_getproplen(phandle, "ibm,associativity");
+ if (res <= 0)
+ continue;
+ MPASS(count == 1);
+ OF_getencprop(phandle, "ibm,associativity",
+ associativity, res);
+ curmemp->mr_domain = associativity[3] - 1;
+ if (bootverbose)
+ printf("%s %#jx-%#jx domain(%ju)\n",
+ name, (uintmax_t)curmemp->mr_start,
+ (uintmax_t)curmemp->mr_start + curmemp->mr_size,
+ (uintmax_t)curmemp->mr_domain);
+ msz += count;
+ }
+ *memsz = msz;
+}
+/*
+ * This is called during powerpc_init, before the system is really initialized.
+ * It shall provide the total and the available regions of RAM.
+ * The available regions need not take the kernel into account.
+ */
+void
ofw_mem_regions(struct mem_region *memp, int *memsz,
struct mem_region *availp, int *availsz)
{
@@ -430,7 +524,7 @@
continue;
res = parse_ofw_memory(phandle, "reg", &memp[msz]);
- msz += res/sizeof(struct mem_region);
+ msz += res;
/*
* On POWER9 Systems we might have both linux,usable-memory and
@@ -446,7 +540,7 @@
&availp[asz]);
else
res = parse_ofw_memory(phandle, "reg", &availp[asz]);
- asz += res/sizeof(struct mem_region);
+ asz += res;
}
#ifdef FDT
Index: head/sys/powerpc/ofw/ofw_pcibus.c
===================================================================
--- head/sys/powerpc/ofw/ofw_pcibus.c
+++ head/sys/powerpc/ofw/ofw_pcibus.c
@@ -38,6 +38,7 @@
#include <sys/libkern.h>
#include <sys/module.h>
#include <sys/pciio.h>
+#include <sys/smp.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -80,6 +81,8 @@
DEVMETHOD(bus_child_deleted, ofw_pcibus_child_deleted),
DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_child_pnpinfo_str_method),
DEVMETHOD(bus_rescan, bus_null_rescan),
+ DEVMETHOD(bus_get_cpus, ofw_pcibus_get_cpus),
+ DEVMETHOD(bus_get_domain, ofw_pcibus_get_domain),
/* PCI interface */
DEVMETHOD(pci_alloc_devinfo, ofw_pcibus_alloc_devinfo),
@@ -382,3 +385,76 @@
return (&dinfo->opd_obdinfo);
}
+static int
+ofw_pcibus_parse_associativity(device_t dev, int *domain)
+{
+ phandle_t node;
+ cell_t associativity[5];
+ int res;
+
+ if ((node = ofw_bus_get_node(dev)) == -1) {
+ device_printf(dev, "no ofw node found\n");
+ return (ENXIO);
+ }
+ res = OF_getproplen(node, "ibm,associativity");
+ if (res <= 0)
+ return (ENXIO);
+ OF_getencprop(node, "ibm,associativity",
+ associativity, res);
+
+ *domain = associativity[3] - 1;
+ if (bootverbose)
+ device_printf(dev, "domain(%d)\n", *domain);
+ return (0);
+}
+
+int
+ofw_pcibus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize,
+ cpuset_t *cpuset)
+{
+ int d, error;
+
+ error = ofw_pcibus_parse_associativity(child, &d);
+ if (error)
+ return (bus_generic_get_cpus(dev, child, op, setsize, cpuset));
+
+ switch (op) {
+ case LOCAL_CPUS:
+ if (setsize != sizeof(cpuset_t))
+ return (EINVAL);
+ *cpuset = cpuset_domain[d];
+ return (0);
+ case INTR_CPUS:
+ error = bus_generic_get_cpus(dev, child, op, setsize, cpuset);
+ if (error != 0)
+ return (error);
+ if (setsize != sizeof(cpuset_t))
+ return (EINVAL);
+ CPU_AND(cpuset, &cpuset_domain[d]);
+ return (0);
+ default:
+ return (bus_generic_get_cpus(dev, child, op, setsize, cpuset));
+ }
+ return (0);
+}
+
+/*
+ * Fetch the NUMA domain for the given device 'dev'.
+ *
+ * If a device has a _PXM method, map that to a NUMA domain.
+ * Otherwise, pass the request up to the parent.
+ * If there's no matching domain or the domain cannot be
+ * determined, return ENOENT.
+ */
+int
+ofw_pcibus_get_domain(device_t dev, device_t child, int *domain)
+{
+ int d, error;
+
+ error = ofw_pcibus_parse_associativity(child, &d);
+ /* No ofw node; go up a level */
+ if (error)
+ return (bus_generic_get_domain(dev, child, domain));
+ *domain = d;
+ return (0);
+}
Index: head/sys/powerpc/powernv/opal_pci.c
===================================================================
--- head/sys/powerpc/powernv/opal_pci.c
+++ head/sys/powerpc/powernv/opal_pci.c
@@ -149,6 +149,8 @@
/* Bus interface */
DEVMETHOD(bus_get_dma_tag, opalpci_get_dma_tag),
+ DEVMETHOD(bus_get_cpus, ofw_pcibus_get_cpus),
+ DEVMETHOD(bus_get_domain, ofw_pcibus_get_domain),
DEVMETHOD_END
};
@@ -367,7 +369,7 @@
tce_size = max_tce_size(dev);
maxmem = roundup2(powerpc_ptob(Maxmem), tce_size);
entries = round_pow2(maxmem / tce_size);
- tce_tbl_size = max(entries * sizeof(uint64_t), 4096);
+ tce_tbl_size = MAX(entries * sizeof(uint64_t), 4096);
if (entries > OPAL_PCI_TCE_MAX_ENTRIES)
panic("POWERNV supports only %jdGB of memory space\n",
(uintmax_t)((OPAL_PCI_TCE_MAX_ENTRIES * tce_size) >> 30));
Index: head/sys/powerpc/powernv/platform_powernv.c
===================================================================
--- head/sys/powerpc/powernv/platform_powernv.c
+++ head/sys/powerpc/powernv/platform_powernv.c
@@ -65,6 +65,7 @@
static int powernv_attach(platform_t);
void powernv_mem_regions(platform_t, struct mem_region *phys, int *physsz,
struct mem_region *avail, int *availsz);
+static void powernv_numa_mem_regions(platform_t plat, struct numa_mem_region *phys, int *physsz);
static u_long powernv_timebase_freq(platform_t, struct cpuref *cpuref);
static int powernv_smp_first_cpu(platform_t, struct cpuref *cpuref);
static int powernv_smp_next_cpu(platform_t, struct cpuref *cpuref);
@@ -83,6 +84,7 @@
PLATFORMMETHOD(platform_probe, powernv_probe),
PLATFORMMETHOD(platform_attach, powernv_attach),
PLATFORMMETHOD(platform_mem_regions, powernv_mem_regions),
+ PLATFORMMETHOD(platform_numa_mem_regions, powernv_numa_mem_regions),
PLATFORMMETHOD(platform_timebase_freq, powernv_timebase_freq),
PLATFORMMETHOD(platform_smp_ap_init, powernv_smp_ap_init),
@@ -250,6 +252,13 @@
ofw_mem_regions(phys, physsz, avail, availsz);
}
+static void
+powernv_numa_mem_regions(platform_t plat, struct numa_mem_region *phys, int *physsz)
+{
+
+ ofw_numa_mem_regions(phys, physsz);
+}
+
static u_long
powernv_timebase_freq(platform_t plat, struct cpuref *cpuref)
{
@@ -313,15 +322,13 @@
if (res > 0 && strcmp(buf, "cpu") == 0) {
res = OF_getproplen(cpu, "ibm,ppc-interrupt-server#s");
if (res > 0) {
-
-
OF_getencprop(cpu, "ibm,ppc-interrupt-server#s",
interrupt_servers, res);
for (a = 0; a < res/sizeof(cell_t); a++) {
tmp_cpuref[tmp_cpuref_cnt].cr_hwref = interrupt_servers[a];
tmp_cpuref[tmp_cpuref_cnt].cr_cpuid = tmp_cpuref_cnt;
-
+ tmp_cpuref[tmp_cpuref_cnt].cr_domain = interrupt_servers[a] >> 11;
if (interrupt_servers[a] == (uint32_t)powernv_boot_pir)
bsp = tmp_cpuref_cnt;
@@ -335,11 +342,13 @@
for (a = bsp; a < tmp_cpuref_cnt; a++) {
platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref;
platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt;
+ platform_cpuref[platform_cpuref_cnt].cr_domain = tmp_cpuref[a].cr_domain;
platform_cpuref_cnt++;
}
for (a = 0; a < bsp; a++) {
platform_cpuref[platform_cpuref_cnt].cr_hwref = tmp_cpuref[a].cr_hwref;
platform_cpuref[platform_cpuref_cnt].cr_cpuid = platform_cpuref_cnt;
+ platform_cpuref[platform_cpuref_cnt].cr_domain = tmp_cpuref[a].cr_domain;
platform_cpuref_cnt++;
}
@@ -356,6 +365,7 @@
cpuref->cr_cpuid = 0;
cpuref->cr_hwref = platform_cpuref[0].cr_hwref;
+ cpuref->cr_domain = platform_cpuref[0].cr_domain;
return (0);
}
@@ -374,6 +384,7 @@
cpuref->cr_cpuid = platform_cpuref[id].cr_cpuid;
cpuref->cr_hwref = platform_cpuref[id].cr_hwref;
+ cpuref->cr_domain = platform_cpuref[id].cr_domain;
return (0);
}
@@ -384,6 +395,7 @@
cpuref->cr_cpuid = platform_cpuref[0].cr_cpuid;
cpuref->cr_hwref = platform_cpuref[0].cr_hwref;
+ cpuref->cr_domain = platform_cpuref[0].cr_domain;
return (0);
}
Index: head/sys/powerpc/powerpc/intr_machdep.c
===================================================================
--- head/sys/powerpc/powerpc/intr_machdep.c
+++ head/sys/powerpc/powerpc/intr_machdep.c
@@ -97,16 +97,17 @@
struct intr_event *event;
long *cntp;
void *priv; /* PIC-private data */
- u_int irq;
device_t pic;
+ u_int irq;
u_int intline;
u_int vector;
u_int cntindex;
- cpuset_t cpu;
- enum intr_trigger trig;
- enum intr_polarity pol;
int fwcode;
int ipi;
+ int pi_domain;
+ enum intr_trigger trig;
+ enum intr_polarity pol;
+ cpuset_t pi_cpuset;
};
struct pic {
@@ -203,7 +204,7 @@
for (vector = 0; vector < nvectors; vector++) {
i = powerpc_intrs[vector];
if (i != NULL && i->event != NULL && i->pic == root_pic)
- PIC_BIND(i->pic, i->intline, i->cpu, &i->priv);
+ PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv);
}
}
SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL);
@@ -256,9 +257,9 @@
i->ipi = 0;
#ifdef SMP
- i->cpu = all_cpus;
+ i->pi_cpuset = all_cpus;
#else
- CPU_SETOF(0, &i->cpu);
+ CPU_SETOF(0, &i->pi_cpuset);
#endif
for (vector = 0; vector < num_io_irqs && vector <= nvectors;
@@ -347,12 +348,12 @@
struct powerpc_intr *i = arg;
if (cpu == NOCPU)
- i->cpu = all_cpus;
+ i->pi_cpuset = all_cpus;
else
- CPU_SETOF(cpu, &i->cpu);
+ CPU_SETOF(cpu, &i->pi_cpuset);
if (!cold && i->pic != NULL && i->pic == root_pic)
- PIC_BIND(i->pic, i->intline, i->cpu, &i->priv);
+ PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv);
return (0);
#else
@@ -469,7 +470,8 @@
error = powerpc_setup_intr("IPI",
MAP_IRQ(piclist[n].node, piclist[n].irqs),
powerpc_ipi_handler, NULL, NULL,
- INTR_TYPE_MISC | INTR_EXCL, &ipi_cookie);
+ INTR_TYPE_MISC | INTR_EXCL, &ipi_cookie,
+ 0 /* domain XXX */);
if (error) {
printf("unable to setup IPI handler\n");
return (error);
@@ -512,7 +514,8 @@
int
powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
- driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)
+ driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep,
+ int domain)
{
struct powerpc_intr *i;
int error, enable = 0;
@@ -533,7 +536,13 @@
error = intr_event_add_handler(i->event, name, filter, handler, arg,
intr_priority(flags), flags, cookiep);
-
+ if (error)
+ return (error);
+ i->pi_domain = domain;
+ if (strcmp(name, "IPI") != 0) {
+ CPU_ZERO(&i->pi_cpuset);
+ CPU_COPY(&cpuset_domain[domain], &i->pi_cpuset);
+ }
mtx_lock(&intr_table_lock);
intrcnt_setname(i->event->ie_fullname, i->cntindex);
mtx_unlock(&intr_table_lock);
@@ -551,7 +560,7 @@
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
if (i->pic == root_pic)
- PIC_BIND(i->pic, i->intline, i->cpu, &i->priv);
+ PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv);
if (enable)
PIC_ENABLE(i->pic, i->intline, i->vector,
Index: head/sys/powerpc/powerpc/mp_machdep.c
===================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c
+++ head/sys/powerpc/powerpc/mp_machdep.c
@@ -182,6 +182,15 @@
pc->pc_bsp = 1;
}
pc->pc_hwref = cpu.cr_hwref;
+
+ if (vm_ndomains > 1)
+ pc->pc_domain = cpu.cr_domain;
+ else
+ pc->pc_domain = 0;
+
+ CPU_SET(pc->pc_cpuid, &cpuset_domain[pc->pc_domain]);
+ KASSERT(pc->pc_domain < MAXMEMDOM, ("bad domain value %d\n",
+ pc->pc_domain));
CPU_SET(pc->pc_cpuid, &all_cpus);
next:
error = platform_smp_next_cpu(&cpu);
@@ -205,7 +214,7 @@
pc = pcpu_find(i);
if (pc == NULL)
continue;
- printf("cpu%d: dev=%x", i, (int)pc->pc_hwref);
+ printf("cpu%d: dev=%x domain=%d ", i, (int)pc->pc_hwref, pc->pc_domain);
if (pc->pc_bsp)
printf(" (BSP)");
printf("\n");
Index: head/sys/powerpc/powerpc/nexus.c
===================================================================
--- head/sys/powerpc/powerpc/nexus.c
+++ head/sys/powerpc/powerpc/nexus.c
@@ -38,11 +38,13 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/pcpu.h>
#include <sys/rman.h>
+#include <sys/smp.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -67,6 +69,8 @@
static bus_activate_resource_t nexus_activate_resource;
static bus_deactivate_resource_t nexus_deactivate_resource;
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t);
+static int nexus_get_cpus(device_t, device_t, enum cpu_sets, size_t,
+ cpuset_t *);
#ifdef SMP
static bus_bind_intr_t nexus_bind_intr;
#endif
@@ -89,6 +93,7 @@
#endif
DEVMETHOD(bus_config_intr, nexus_config_intr),
DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag),
+ DEVMETHOD(bus_get_cpus, nexus_get_cpus),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
@@ -127,11 +132,13 @@
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
void **cookiep)
{
- int error;
+ int error, domain;
if (r == NULL)
panic("%s: NULL interrupt resource!", __func__);
+ if (cookiep != NULL)
+ *cookiep = NULL;
if ((rman_get_flags(r) & RF_SHAREABLE) == 0)
flags |= INTR_EXCL;
@@ -140,8 +147,13 @@
if (error)
return (error);
+ if (bus_get_domain(child, &domain) != 0) {
+ if(bootverbose)
+ device_printf(child, "no domain found\n");
+ domain = 0;
+ }
error = powerpc_setup_intr(device_get_nameunit(child),
- rman_get_start(r), filt, intr, arg, flags, cookiep);
+ rman_get_start(r), filt, intr, arg, flags, cookiep, domain);
return (error);
}
@@ -162,6 +174,24 @@
{
return(&bs_be_tag);
+}
+
+static int
+nexus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize,
+ cpuset_t *cpuset)
+{
+
+ switch (op) {
+#ifdef SMP
+ case INTR_CPUS:
+ if (setsize != sizeof(cpuset_t))
+ return (EINVAL);
+ *cpuset = all_cpus;
+ return (0);
+#endif
+ default:
+ return (bus_generic_get_cpus(dev, child, op, setsize, cpuset));
+ }
}
#ifdef SMP
Index: head/sys/powerpc/powerpc/platform.c
===================================================================
--- head/sys/powerpc/powerpc/platform.c
+++ head/sys/powerpc/powerpc/platform.c
@@ -48,13 +48,16 @@
#include <sys/types.h>
#include <vm/vm.h>
+#include <vm/vm_param.h>
#include <vm/vm_page.h>
+#include <vm/vm_phys.h>
#include <machine/cpu.h>
#include <machine/md_var.h>
#include <machine/platform.h>
#include <machine/platformvar.h>
#include <machine/smp.h>
+#include <machine/vmparam.h>
#include "platform_if.h"
@@ -67,9 +70,12 @@
SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RD | CTLFLAG_TUN,
plat_name, 0, "Platform currently in use");
+static struct mem_affinity mem_info[VM_PHYSSEG_MAX + 1];
+static int vm_locality_table[MAXMEMDOM * MAXMEMDOM];
static struct mem_region pregions[PHYS_AVAIL_SZ];
+static struct numa_mem_region numa_pregions[PHYS_AVAIL_SZ];
static struct mem_region aregions[PHYS_AVAIL_SZ];
-static int npregions, naregions;
+static int nnumapregions, npregions, naregions;
/*
* Memory region utilities: determine if two regions overlap,
@@ -113,6 +119,54 @@
}
void
+numa_mem_regions(struct numa_mem_region **phys, int *physsz)
+{
+ struct mem_affinity *mi;
+ int i, j, maxdom, ndomain, offset;
+
+ nnumapregions = 0;
+ PLATFORM_NUMA_MEM_REGIONS(plat_obj, numa_pregions, &nnumapregions);
+
+ if (physsz != NULL)
+ *physsz = nnumapregions;
+ if (phys != NULL)
+ *phys = numa_pregions;
+ if (physsz == NULL || phys == NULL) {
+ printf("unset value\n");
+ return;
+ }
+ maxdom = 0;
+ for (i = 0; i < nnumapregions; i++)
+ if (numa_pregions[i].mr_domain > maxdom)
+ maxdom = numa_pregions[i].mr_domain;
+
+ mi = mem_info;
+ for (i = 0; i < nnumapregions; i++, mi++) {
+ mi->start = numa_pregions[i].mr_start;
+ mi->end = numa_pregions[i].mr_start + numa_pregions[i].mr_size;
+ mi->domain = numa_pregions[i].mr_domain;
+ }
+ offset = 0;
+ vm_locality_table[offset] = 10;
+ ndomain = maxdom + 1;
+ if (ndomain > 1) {
+ for (i = 0; i < ndomain; i++) {
+ for (j = 0; j < ndomain; j++) {
+ /*
+ * Not sure what these values should actually be
+ */
+ if (i == j)
+ vm_locality_table[offset] = 10;
+ else
+ vm_locality_table[offset] = 21;
+ offset++;
+ }
+ }
+ }
+ vm_phys_register_domains(ndomain, mem_info, vm_locality_table);
+}
+
+void
mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail,
int *availsz)
{
@@ -252,7 +306,7 @@
struct cpu_group *
cpu_topo(void)
{
- return (PLATFORM_SMP_TOPO(plat_obj));
+ return (PLATFORM_SMP_TOPO(plat_obj));
}
#endif
Index: head/sys/powerpc/powerpc/platform_if.m
===================================================================
--- head/sys/powerpc/powerpc/platform_if.m
+++ head/sys/powerpc/powerpc/platform_if.m
@@ -130,6 +130,22 @@
int *_availsz;
};
+
+/**
+ * @brief Return the system's physical memory map.
+ *
+ * It shall provide the total RAM with the corresponding domains.
+ *
+ * @param _memp Array of physical memory chunks
+ * @param _memsz Number of physical memory chunks
+ */
+
+METHOD void numa_mem_regions {
+ platform_t _plat;
+ struct numa_mem_region *_memp;
+ int *_memsz;
+};
+
/**
* @brief Return the maximum address accessible in real mode
* (for use with hypervisors)

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 8:08 PM (10 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14931023
Default Alt Text
D17933.id56150.diff (22 KB)

Event Timeline