Page MenuHomeFreeBSD

D15492.id42755.diff
No OneTemporary

D15492.id42755.diff

Index: head/sys/powerpc/aim/mp_cpudep.c
===================================================================
--- head/sys/powerpc/aim/mp_cpudep.c
+++ head/sys/powerpc/aim/mp_cpudep.c
@@ -96,7 +96,7 @@
mtspr(SPR_LPID, 0);
isync();
- mtspr(SPR_LPCR, LPCR_LPES);
+ mtspr(SPR_LPCR, lpcr);
isync();
}
#endif
@@ -401,7 +401,7 @@
case IBMPOWER9:
#ifdef __powerpc64__
if (mfmsr() & PSL_HV) {
- mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_LPES |
+ mtspr(SPR_LPCR, mfspr(SPR_LPCR) | lpcr |
LPCR_PECE_WAKESET);
isync();
}
Index: head/sys/powerpc/include/cpu.h
===================================================================
--- head/sys/powerpc/include/cpu.h
+++ head/sys/powerpc/include/cpu.h
@@ -135,6 +135,7 @@
#ifdef __powerpc64__
extern void enter_idle_powerx(void);
extern uint64_t can_wakeup;
+extern register_t lpcr;
#endif
void cpu_halt(void);
Index: head/sys/powerpc/include/spr.h
===================================================================
--- head/sys/powerpc/include/spr.h
+++ head/sys/powerpc/include/spr.h
@@ -215,14 +215,6 @@
#define FSL_E300C3 0x8085
#define FSL_E300C4 0x8086
-#define SPR_LPCR 0x13e /* Logical Partitioning Control */
-#define LPCR_LPES 0x008 /* Bit 60 */
-#define LPCR_PECE_DRBL (1ULL << 16) /* Directed Privileged Doorbell */
-#define LPCR_PECE_HDRBL (1ULL << 15) /* Directed Hypervisor Doorbell */
-#define LPCR_PECE_EXT (1ULL << 14) /* External exceptions */
-#define LPCR_PECE_DECR (1ULL << 13) /* Decrementer exceptions */
-#define LPCR_PECE_ME (1ULL << 12) /* Machine Check and Hypervisor */
- /* Maintenance exceptions */
#define LPCR_PECE_WAKESET (LPCR_PECE_EXT | LPCR_PECE_DECR | LPCR_PECE_ME)
#define SPR_EPCR 0x133
@@ -242,7 +234,14 @@
#define SPR_HSRR0 0x13a
#define SPR_HSRR1 0x13b
#define SPR_LPCR 0x13e /* Logical Partitioning Control */
-#define LPCR_LPES 0x008 /* Bit 60 */
+#define LPCR_LPES 0x008 /* Bit 60 */
+#define LPCR_HVICE 0x002 /* Hypervisor Virtualization Interrupt (Arch 3.0) */
+#define LPCR_PECE_DRBL (1ULL << 16) /* Directed Privileged Doorbell */
+#define LPCR_PECE_HDRBL (1ULL << 15) /* Directed Hypervisor Doorbell */
+#define LPCR_PECE_EXT (1ULL << 14) /* External exceptions */
+#define LPCR_PECE_DECR (1ULL << 13) /* Decrementer exceptions */
+#define LPCR_PECE_ME (1ULL << 12) /* Machine Check and Hypervisor */
+ /* Maintenance exceptions */
#define SPR_LPID 0x13f /* Logical Partitioning Control */
#define SPR_PTCR 0x1d0 /* Partition Table Control Register */
Index: head/sys/powerpc/powernv/opal.h
===================================================================
--- head/sys/powerpc/powernv/opal.h
+++ head/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: head/sys/powerpc/powernv/platform_powernv.c
===================================================================
--- head/sys/powerpc/powernv/platform_powernv.c
+++ head/sys/powerpc/powernv/platform_powernv.c
@@ -59,6 +59,7 @@
extern void *ap_pcpu;
#endif
+extern void xicp_smp_cpu_startup(void);
static int powernv_probe(platform_t);
static int powernv_attach(platform_t);
void powernv_mem_regions(platform_t, struct mem_region *phys, int *physsz,
@@ -152,14 +153,14 @@
mtspr(SPR_LPID, 0);
isync();
- mtspr(SPR_LPCR, LPCR_LPES);
+ if (cpu_features2 & PPC_FEATURE2_ARCH_3_00)
+ lpcr |= LPCR_HVICE;
+
+ mtspr(SPR_LPCR, lpcr);
isync();
mtmsr(msr);
- /* Init CPU bits */
- powernv_smp_ap_init(plat);
-
powernv_cpuref_init();
/* Set SLB count from device tree */
@@ -460,6 +461,8 @@
static void
powernv_smp_ap_init(platform_t platform)
{
+
+ xicp_smp_cpu_startup();
}
static void
Index: head/sys/powerpc/powerpc/cpu.c
===================================================================
--- head/sys/powerpc/powerpc/cpu.c
+++ head/sys/powerpc/powerpc/cpu.c
@@ -240,6 +240,10 @@
SYSCTL_OPAQUE(_hw, OID_AUTO, cpu_features2, CTLFLAG_RD,
&cpu_features2, sizeof(cpu_features2), "LX", "PowerPC CPU features 2");
+#ifdef __powerpc64__
+register_t lpcr = LPCR_LPES;
+#endif
+
/* Provide some user-friendly aliases for bits in cpu_features */
SYSCTL_PROC(_hw, OID_AUTO, floatingpoint, CTLTYPE_INT | CTLFLAG_RD,
0, PPC_FEATURE_HAS_FPU, cpu_feature_bit, "I",
Index: head/sys/powerpc/pseries/xics.c
===================================================================
--- head/sys/powerpc/pseries/xics.c
+++ head/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);
@@ -74,6 +77,10 @@
static void xicp_mask(device_t, u_int);
static void xicp_unmask(device_t, u_int);
+#ifdef POWERNV
+void xicp_smp_cpu_startup(void);
+#endif
+
static device_method_t xicp_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, xicp_probe),
@@ -117,6 +124,7 @@
int cpu;
} intvecs[256];
int nintvecs;
+ bool xics_emu;
};
static driver_t xicp_driver = {
@@ -131,6 +139,8 @@
0
};
+static uint32_t cpu_xirr[MAXCPU];
+
static devclass_t xicp_devclass;
static devclass_t xics_devclass;
@@ -161,7 +171,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 +183,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 +217,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 +235,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,19 +345,25 @@
uint64_t xirr, junk;
int i;
+ sc = device_get_softc(dev);
#ifdef POWERNV
- if (mfmsr() & PSL_HV) {
+ if ((mfmsr() & PSL_HV) && !sc->xics_emu) {
regs = xicp_mem_for_cpu(PCPU_GET(hwref));
KASSERT(regs != NULL,
("Can't find regs for CPU %ld", (uintptr_t)PCPU_GET(hwref)));
}
#endif
- sc = device_get_softc(dev);
for (;;) {
/* 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, &cpu_xirr[PCPU_GET(cpuid)],
+ false);
+ xirr = cpu_xirr[PCPU_GET(cpuid)];
+#endif
} else {
/* Return value in R4, use the PFT call */
phyp_pft_hcall(H_XIRR, 0, 0, 0, 0, &xirr, &junk, &junk);
@@ -338,6 +373,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 +387,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 +453,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 +463,13 @@
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)
+ 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 +479,19 @@
{
#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) {
+ 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);
}
@@ -490,3 +549,18 @@
}
}
+#ifdef POWERNV
+/* This is only used on POWER9 systems with the XIVE's XICS emulation. */
+void
+xicp_smp_cpu_startup(void)
+{
+ struct xicp_softc *sc;
+
+ if (mfmsr() & PSL_HV) {
+ sc = device_get_softc(root_pic);
+
+ if (sc->xics_emu)
+ opal_call(OPAL_INT_SET_CPPR, 0xff);
+ }
+}
+#endif

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 21, 10:10 PM (16 h, 49 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25812994
Default Alt Text
D15492.id42755.diff (10 KB)

Event Timeline