Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136984489
D15492.id42755.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D15492.id42755.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D15492: Add support for the XIVE XICS emulation mode for POWER9 systems
Attached
Detach File
Event Timeline
Log In to Comment