Date: Thu, 30 Apr 2026 00:18:10 +0000 From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 40bcad56f1b8 - main - powerpc/pic: Add a PIC_AP_INIT() to set up AP PIC info Message-ID: <69f29fc2.317a4.ef71453@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by jhibbits: URL: https://cgit.FreeBSD.org/src/commit/?id=40bcad56f1b8b3a0eed9af68de5535a784c004d9 commit 40bcad56f1b8b3a0eed9af68de5535a784c004d9 Author: Justin Hibbits <jhibbits@FreeBSD.org> AuthorDate: 2026-04-30 00:12:18 +0000 Commit: Justin Hibbits <jhibbits@FreeBSD.org> CommitDate: 2026-04-30 00:13:48 +0000 powerpc/pic: Add a PIC_AP_INIT() to set up AP PIC info pc_cpuid may not match the PIC's idea of a given CPU. Since openpic has a WHOAMI register, we can use that to get the PIC's idea of the CPU. This needs to be done on each AP, so add a PIC_AP_INIT device method so the PIC can perform any AP-specific initialization at AP bootstrap time. This fixes SMP on e6500, which is still lacking SMT support. Differential Revision: https://reviews.freebsd.org/D56421 --- sys/powerpc/include/pcpu.h | 1 + sys/powerpc/powerpc/mp_machdep.c | 1 + sys/powerpc/powerpc/openpic.c | 28 +++++++++++++++++++++------- sys/powerpc/powerpc/pic_if.m | 3 +++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h index 924b3d893acd..f2a9bd0080b5 100644 --- a/sys/powerpc/include/pcpu.h +++ b/sys/powerpc/include/pcpu.h @@ -45,6 +45,7 @@ struct pvo_entry; struct thread *pc_vecthread; /* current vec user */ \ struct thread *pc_htmthread; /* current htm user */ \ uintptr_t pc_hwref; \ + uintptr_t pc_pic; \ int pc_bsp; \ volatile int pc_awake; \ uint32_t pc_ipimask; \ diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index d6d140aa0ea2..114990a97cdb 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -87,6 +87,7 @@ machdep_ap_bootstrap(void) /* Give platform code a chance to do anything else necessary */ platform_smp_ap_init(); + PIC_AP_INIT(root_pic); /* Initialize decrementer */ decr_ap_init(); diff --git a/sys/powerpc/powerpc/openpic.c b/sys/powerpc/powerpc/openpic.c index aa28f63cb6f5..bdd59407e3d4 100644 --- a/sys/powerpc/powerpc/openpic.c +++ b/sys/powerpc/powerpc/openpic.c @@ -254,7 +254,7 @@ openpic_bind(device_t dev, u_int irq, cpuset_t cpumask, void **priv __unused) break; ncpu++; } - mask &= (1 << cpu); + mask = (1 << __pcpu[cpu].pc_pic); } openpic_write(sc, OPENPIC_IDEST(irq), mask); @@ -288,9 +288,10 @@ openpic_dispatch(device_t dev, struct trapframe *tf) CTR1(KTR_INTR, "%s: got interrupt", __func__); - cpuid = (dev == root_pic) ? PCPU_GET(cpuid) : 0; - sc = device_get_softc(dev); + + cpuid = (dev == root_pic) ? PCPU_GET(pic) : 0; + while (1) { vector = openpic_read(sc, OPENPIC_PCPU_IACK(cpuid)); vector &= OPENPIC_VECTOR_MASK; @@ -337,9 +338,9 @@ openpic_eoi(device_t dev, u_int irq __unused, void *priv __unused) struct openpic_softc *sc; u_int cpuid; - cpuid = (dev == root_pic) ? PCPU_GET(cpuid) : 0; - sc = device_get_softc(dev); + cpuid = (dev == root_pic) ? PCPU_GET(pic) : 0; + openpic_write(sc, OPENPIC_PCPU_EOI(cpuid), 0); } @@ -352,8 +353,8 @@ openpic_ipi(device_t dev, u_int cpu) sc = device_get_softc(dev); sched_pin(); - openpic_write(sc, OPENPIC_PCPU_IPI_DISPATCH(PCPU_GET(cpuid), 0), - 1u << cpu); + openpic_write(sc, OPENPIC_PCPU_IPI_DISPATCH(PCPU_GET(pic), 0), + 1u << pcpu_find(cpu)->pc_pic); sched_unpin(); } @@ -454,6 +455,18 @@ openpic_resume(device_t dev) return (0); } +static void +openpic_ap_init(device_t dev) +{ + struct openpic_softc *sc; + + if (dev != root_pic) + return; + + sc = device_get_softc(dev); + PCPU_SET(pic, bus_read_4(sc->sc_memr, OPENPIC_WHOAMI)); +} + static device_method_t openpic_methods[] = { /* Device interface */ DEVMETHOD(device_suspend, openpic_suspend), @@ -468,6 +481,7 @@ static device_method_t openpic_methods[] = { DEVMETHOD(pic_ipi, openpic_ipi), DEVMETHOD(pic_mask, openpic_mask), DEVMETHOD(pic_unmask, openpic_unmask), + DEVMETHOD(pic_ap_init, openpic_ap_init), DEVMETHOD_END }; diff --git a/sys/powerpc/powerpc/pic_if.m b/sys/powerpc/powerpc/pic_if.m index 59187be9d935..dbbcc93f6241 100644 --- a/sys/powerpc/powerpc/pic_if.m +++ b/sys/powerpc/powerpc/pic_if.m @@ -100,3 +100,6 @@ METHOD void unmask { void *priv; }; +METHOD void ap_init { + device_t dev; +};home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f29fc2.317a4.ef71453>
