Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103743426
D17933.id56150.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D17933.id56150.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D17933: add NUMA support to powerpc
Attached
Detach File
Event Timeline
Log In to Comment