Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154907121
D15331.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D15331.diff
View Options
Index: sys/powerpc/powernv/opal.h
===================================================================
--- sys/powerpc/powernv/opal.h
+++ sys/powerpc/powernv/opal.h
@@ -73,7 +73,12 @@
#define OPAL_REINIT_CPUS 70
#define OPAL_CHECK_ASYNC_COMPLETION 86
#define OPAL_I2C_REQUEST 109
+#define OPAL_INT_GET_XIRR 122
+#define OPAL_INT_SET_CPPR 123
+#define OPAL_INT_EOI 124
+#define OPAL_INT_SET_MFRR 125
#define OPAL_PCI_TCE_KILL 126
+#define OPAL_XIVE_RESET 128
/* For OPAL_PCI_SET_PE */
#define OPAL_UNMAP_PE 0
Index: sys/powerpc/pseries/xics.c
===================================================================
--- sys/powerpc/pseries/xics.c
+++ sys/powerpc/pseries/xics.c
@@ -61,6 +61,9 @@
#define XICP_IPI 2
#define MAX_XICP_IRQS (1<<24) /* 24-bit XIRR field */
+#define XIVE_XICS_MODE_EMU 0
+#define XIVE_XICS_MODE_EXP 1
+
static int xicp_probe(device_t);
static int xicp_attach(device_t);
static int xics_probe(device_t);
@@ -117,6 +120,7 @@
int cpu;
} intvecs[256];
int nintvecs;
+ bool xics_emu;
};
static driver_t xicp_driver = {
@@ -161,7 +165,8 @@
xicp_probe(device_t dev)
{
- if (!ofw_bus_is_compatible(dev, "ibm,ppc-xicp"))
+ if (!ofw_bus_is_compatible(dev, "ibm,ppc-xicp") &&
+ !ofw_bus_is_compatible(dev, "ibm,opal-intc"))
return (ENXIO);
device_set_desc(dev, "External Interrupt Presentation Controller");
@@ -172,7 +177,8 @@
xics_probe(device_t dev)
{
- if (!ofw_bus_is_compatible(dev, "ibm,ppc-xics"))
+ if (!ofw_bus_is_compatible(dev, "ibm,ppc-xics") &&
+ !ofw_bus_is_compatible(dev, "IBM,opal-xics"))
return (ENXIO);
device_set_desc(dev, "External Interrupt Source Controller");
@@ -205,6 +211,15 @@
sc->cpu_range[1] += sc->cpu_range[0];
device_printf(dev, "Handling CPUs %d-%d\n", sc->cpu_range[0],
sc->cpu_range[1]-1);
+#ifdef POWERNV
+ } else if (ofw_bus_is_compatible(dev, "ibm,opal-intc")) {
+ /*
+ * For now run POWER9 XIVE interrupt controller in XICS
+ * compatibility mode.
+ */
+ sc->xics_emu = true;
+ opal_call(OPAL_XIVE_RESET, XIVE_XICS_MODE_EMU);
+#endif
} else {
sc->cpu_range[0] = 0;
sc->cpu_range[1] = mp_ncpus;
@@ -214,18 +229,26 @@
if (mfmsr() & PSL_HV) {
int i;
- for (i = 0; i < sc->cpu_range[1] - sc->cpu_range[0]; i++) {
- sc->mem[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &i, RF_ACTIVE);
- if (sc->mem[i] == NULL) {
- device_printf(dev, "Could not alloc mem "
- "resource %d\n", i);
- return (ENXIO);
+ if (sc->xics_emu) {
+ opal_call(OPAL_INT_SET_CPPR, 0xff);
+ for (i = 0; i < mp_ncpus; i++) {
+ opal_call(OPAL_INT_SET_MFRR,
+ pcpu_find(i)->pc_hwref, 0xff);
}
+ } else {
+ for (i = 0; i < sc->cpu_range[1] - sc->cpu_range[0]; i++) {
+ sc->mem[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &i, RF_ACTIVE);
+ if (sc->mem[i] == NULL) {
+ device_printf(dev, "Could not alloc mem "
+ "resource %d\n", i);
+ return (ENXIO);
+ }
- /* Unmask interrupts on all cores */
- bus_write_1(sc->mem[i], 4, 0xff);
- bus_write_1(sc->mem[i], 12, 0xff);
+ /* Unmask interrupts on all cores */
+ bus_write_1(sc->mem[i], 4, 0xff);
+ bus_write_1(sc->mem[i], 12, 0xff);
+ }
}
}
#endif
@@ -316,6 +339,7 @@
uint64_t xirr, junk;
int i;
+ printf("Dispatch!\n");
#ifdef POWERNV
if (mfmsr() & PSL_HV) {
regs = xicp_mem_for_cpu(PCPU_GET(hwref));
@@ -329,6 +353,10 @@
/* Return value in R4, use the PFT call */
if (regs) {
xirr = bus_read_4(regs, 4);
+#ifdef POWERNV
+ } else if (sc->xics_emu) {
+ opal_call(OPAL_INT_GET_XIRR, vtophys(&xirr), false);
+#endif
} else {
/* Return value in R4, use the PFT call */
phyp_pft_hcall(H_XIRR, 0, 0, 0, 0, &xirr, &junk, &junk);
@@ -338,6 +366,10 @@
if (xirr == 0) { /* No more pending interrupts? */
if (regs)
bus_write_1(regs, 4, 0xff);
+#ifdef POWERNV
+ else if (sc->xics_emu)
+ opal_call(OPAL_INT_SET_CPPR, 0xff);
+#endif
else
phyp_hcall(H_CPPR, (uint64_t)0xff);
break;
@@ -348,6 +380,11 @@
/* Clear IPI */
if (regs)
bus_write_1(regs, 12, 0xff);
+#ifdef POWERNV
+ else if (sc->xics_emu)
+ opal_call(OPAL_INT_SET_MFRR,
+ PCPU_GET(hwref), 0xff);
+#endif
else
phyp_hcall(H_IPI, (uint64_t)(PCPU_GET(hwref)),
0xff);
@@ -409,6 +446,9 @@
static void
xicp_eoi(device_t dev, u_int irq)
{
+#ifdef POWERNV
+ struct xicp_softc *sc;
+#endif
uint64_t xirr;
if (irq == MAX_XICP_IRQS) /* Remap IPI interrupt to internal value */
@@ -416,9 +456,15 @@
xirr = irq | (XICP_PRIORITY << 24);
#ifdef POWERNV
- if (mfmsr() & PSL_HV)
- bus_write_4(xicp_mem_for_cpu(PCPU_GET(hwref)), 4, xirr);
- else
+ if (mfmsr() & PSL_HV) {
+ sc = device_get_softc(dev);
+ if (sc->xics_emu)
+ device_printf(dev, "Setting EOI for IRQ %u\n", irq);
+ if (sc->xics_emu)
+ opal_call(OPAL_INT_EOI, xirr);
+ else
+ bus_write_4(xicp_mem_for_cpu(PCPU_GET(hwref)), 4, xirr);
+ } else
#endif
phyp_hcall(H_EOI, xirr);
}
@@ -428,11 +474,21 @@
{
#ifdef POWERNV
+ struct xicp_softc *sc;
cpu = pcpu_find(cpu)->pc_hwref;
- if (mfmsr() & PSL_HV)
- bus_write_1(xicp_mem_for_cpu(cpu), 12, XICP_PRIORITY);
- else
+ if (mfmsr() & PSL_HV) {
+ sc = device_get_softc(dev);
+ if (sc->xics_emu)
+ device_printf(dev, "Sending IPI to %d\n", cpu);
+ if (sc->xics_emu) {
+ int64_t rv;
+ rv = opal_call(OPAL_INT_SET_MFRR, cpu, XICP_PRIORITY);
+ if (rv != 0)
+ device_printf(dev, "IPI SET_MFRR result: %ld\n", rv);
+ } else
+ bus_write_1(xicp_mem_for_cpu(cpu), 12, XICP_PRIORITY);
+ } else
#endif
phyp_hcall(H_IPI, (uint64_t)cpu, XICP_PRIORITY);
}
@@ -478,6 +534,7 @@
} else {
int i;
+ printf("Unmask %u\n", irq);
for (i = 0; i < sc->nintvecs; i++) {
if (sc->intvecs[i].irq == irq) {
break;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 30, 11:04 PM (20 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32544317
Default Alt Text
D15331.diff (5 KB)
Attached To
Mode
D15331: Enable XIVE XICS emulation mode for POWER9 interrupt controller
Attached
Detach File
Event Timeline
Log In to Comment