From owner-p4-projects@FreeBSD.ORG Wed Dec 12 19:19:37 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 65AC016A468; Wed, 12 Dec 2007 19:19:37 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2AB8616A41A for ; Wed, 12 Dec 2007 19:19:37 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2015113C442 for ; Wed, 12 Dec 2007 19:19:37 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id lBCJJaKp034768 for ; Wed, 12 Dec 2007 19:19:36 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id lBCJJauC034765 for perforce@freebsd.org; Wed, 12 Dec 2007 19:19:36 GMT (envelope-from marcel@freebsd.org) Date: Wed, 12 Dec 2007 19:19:36 GMT Message-Id: <200712121919.lBCJJauC034765@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 130726 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Dec 2007 19:19:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=130726 Change 130726 by marcel@marcel_cluster on 2007/12/12 19:19:01 Add rudimentary support for IPIs. Since there are only 4 IPI "channels" and we typically have more than 4 IPI messages, we use a bitmap approach where each IPI message corresponds to a bit in pcpu->pc_ipimask and we always raise the IPI using a single channel (channel 0). This way we support up to 32 IPI messages and don't care that IPIs are not queued to the processor. This changes the OpenPIC driver to always use the private per-processor register bank instead of the global one. The PIC I/F also grows a new method, called ipi(). Affected files ... .. //depot/projects/powerpc/sys/powerpc/include/openpicreg.h#4 edit .. //depot/projects/powerpc/sys/powerpc/include/openpicvar.h#4 edit .. //depot/projects/powerpc/sys/powerpc/include/pcpu.h#8 edit .. //depot/projects/powerpc/sys/powerpc/powermac/openpic_macio.c#3 edit .. //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#11 edit .. //depot/projects/powerpc/sys/powerpc/powerpc/openpic.c#4 edit .. //depot/projects/powerpc/sys/powerpc/powerpc/pic_if.m#4 edit .. //depot/projects/powerpc/sys/powerpc/psim/openpic_iobus.c#3 edit Differences ... ==== //depot/projects/powerpc/sys/powerpc/include/openpicreg.h#4 (text+ko) ==== @@ -33,16 +33,35 @@ #define OPENPIC_SIZE 0x40000 /* - * GLOBAL/TIMER register (IDU base + 0x1000) + * Per Processor Registers [private access] (0x00000 - 0x00fff) + */ + +/* IPI dispatch command reg */ +#define OPENPIC_IPI_DISPATCH(ipi) (0x40 + (ipi) * 0x10) + +/* current task priority reg */ +#define OPENPIC_PRIORITY 0x80 +#define OPENPIC_PRIORITY_MASK 0x0000000f + +#define OPENPIC_WHOAMI 0x90 + +/* interrupt acknowledge reg */ +#define OPENPIC_IACK 0xa0 + +/* end of interrupt reg */ +#define OPENPIC_EOI 0xb0 + +/* + * Global registers (0x01000-0x0ffff) */ /* feature reporting reg 0 */ #define OPENPIC_FEATURE 0x1000 -#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff -#define OPENPIC_FEATURE_LAST_CPU_MASK 0x00001f00 -#define OPENPIC_FEATURE_LAST_CPU_SHIFT 8 -#define OPENPIC_FEATURE_LAST_IRQ_MASK 0x07ff0000 -#define OPENPIC_FEATURE_LAST_IRQ_SHIFT 16 +#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff +#define OPENPIC_FEATURE_LAST_CPU_MASK 0x00001f00 +#define OPENPIC_FEATURE_LAST_CPU_SHIFT 8 +#define OPENPIC_FEATURE_LAST_IRQ_MASK 0x07ff0000 +#define OPENPIC_FEATURE_LAST_IRQ_SHIFT 16 /* global config reg 0 */ #define OPENPIC_CONFIG 0x1020 @@ -51,9 +70,9 @@ /* interrupt configuration mode (direct or serial) */ #define OPENPIC_ICR 0x1030 -#define OPENPIC_ICR_SERIAL_MODE (1 << 27) -#define OPENPIC_ICR_SERIAL_RATIO_MASK (0x7 << 28) -#define OPENPIC_ICR_SERIAL_RATIO_SHIFT 28 +#define OPENPIC_ICR_SERIAL_MODE (1 << 27) +#define OPENPIC_ICR_SERIAL_RATIO_MASK (0x7 << 28) +#define OPENPIC_ICR_SERIAL_RATIO_SHIFT 28 /* vendor ID */ #define OPENPIC_VENDOR_ID 0x1080 @@ -67,9 +86,16 @@ /* spurious intr. vector */ #define OPENPIC_SPURIOUS_VECTOR 0x10e0 +/* Timer registers */ +#define OPENPIC_TIMERS 4 +#define OPENPIC_TFREQ 0x10f0 +#define OPENPIC_TCNT(t) (0x1100 + (t) * 0x40) +#define OPENPIC_TBASE(t) (0x1110 + (t) * 0x40) +#define OPENPIC_TVEC(t) (0x1120 + (t) * 0x40) +#define OPENPIC_TDST(t) (0x1130 + (t) * 0x40) /* - * INTERRUPT SOURCE register (IDU base + 0x10000) + * Interrupt Source Configuration Registers (0x10000 - 0x1ffff) */ /* interrupt vector/priority reg */ @@ -92,18 +118,20 @@ #endif /* - * PROCESSOR register (IDU base + 0x20000) + * Per Processor Registers [global access] (0x20000 - 0x3ffff) */ -/* IPI command reg */ -#define OPENPIC_IPI(cpu, ipi) (0x20040 + (cpu) * 0x1000 + (ipi)) +#define OPENPIC_PCPU_BASE(cpu) (0x20000 + (cpu) * 0x1000) + +#define OPENPIC_PCPU_IPI_DISPATCH(cpu, ipi) \ + (OPENPIC_PCPU_BASE(cpu) + OPENPIC_IPI_DISPATCH(ipi)) + +#define OPENPIC_PCPU_PRIORITY(cpu) \ + (OPENPIC_PCPU_BASE(cpu) + OPENPIC_PRIORITY) -/* current task priority reg */ -#define OPENPIC_CPU_PRIORITY(cpu) (0x20080 + (cpu) * 0x1000) -#define OPENPIC_CPU_PRIORITY_MASK 0x0000000f +#define OPENPIC_PCPU_IACK(cpu) \ + (OPENPIC_PCPU_BASE(cpu) + OPENPIC_IACK) -/* interrupt acknowledge reg */ -#define OPENPIC_IACK(cpu) (0x200a0 + (cpu) * 0x1000) +#define OPENPIC_PCPU_EOI(cpu) \ + (OPENPIC_PCPU_BASE(cpu) + OPENPIC_EOI) -/* end of interrupt reg */ -#define OPENPIC_EOI(cpu) (0x200b0 + (cpu) * 0x1000) ==== //depot/projects/powerpc/sys/powerpc/include/openpicvar.h#4 (text+ko) ==== @@ -57,6 +57,7 @@ void openpic_dispatch(device_t, struct trapframe *); void openpic_enable(device_t, u_int, u_int); void openpic_eoi(device_t, u_int); +void openpic_ipi(device_t, u_int); void openpic_mask(device_t, u_int); void openpic_unmask(device_t, u_int); ==== //depot/projects/powerpc/sys/powerpc/include/pcpu.h#8 (text+ko) ==== @@ -42,6 +42,7 @@ struct thread *pc_fputhread; /* current fpu user */ \ int pc_bsp:1; \ int pc_awake:1; \ + uint32_t pc_ipimask; \ register_t pc_tempsave[CPUSAVE_LEN]; \ register_t pc_disisave[CPUSAVE_LEN]; \ register_t pc_dbsave[CPUSAVE_LEN]; ==== //depot/projects/powerpc/sys/powerpc/powermac/openpic_macio.c#3 (text+ko) ==== @@ -70,6 +70,7 @@ DEVMETHOD(pic_dispatch, openpic_dispatch), DEVMETHOD(pic_enable, openpic_enable), DEVMETHOD(pic_eoi, openpic_eoi), + DEVMETHOD(pic_ipi, openpic_ipi), DEVMETHOD(pic_mask, openpic_mask), DEVMETHOD(pic_unmask, openpic_unmask), ==== //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#11 (text+ko) ==== @@ -34,11 +34,14 @@ #include #include +#include #include #include #include +#include "pic_if.h" + extern void __start_ap(void *); MALLOC_DEFINE(M_SMP, "smp", "SMP specific datastructures"); @@ -211,9 +214,9 @@ static void ipi_send(struct pcpu *pc, int ipi) { - /* - * - */ + + atomic_set_32(&pc->pc_ipimask, (1 << ipi)); + PIC_IPI(pic, pc->pc_cpuid); } /* Send an IPI to a set of cpus. */ ==== //depot/projects/powerpc/sys/powerpc/powerpc/openpic.c#4 (text+ko) ==== @@ -66,14 +66,14 @@ } static __inline void -openpic_set_priority(struct openpic_softc *sc, int cpu, int pri) +openpic_set_priority(struct openpic_softc *sc, int pri) { uint32_t x; - x = openpic_read(sc, OPENPIC_CPU_PRIORITY(cpu)); - x &= ~OPENPIC_CPU_PRIORITY_MASK; + x = openpic_read(sc, OPENPIC_PRIORITY); + x &= ~OPENPIC_PRIORITY_MASK; x |= pri; - openpic_write(sc, OPENPIC_CPU_PRIORITY(cpu), x); + openpic_write(sc, OPENPIC_PRIORITY, x); } int @@ -134,7 +134,7 @@ for (irq = 0; irq < sc->sc_nirq; irq++) openpic_write(sc, OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK); - openpic_set_priority(sc, 0, 15); + openpic_set_priority(sc, 15); /* we don't need 8259 passthrough mode */ x = openpic_read(sc, OPENPIC_CONFIG); @@ -157,12 +157,12 @@ /* XXX IPI */ /* XXX set spurious intr vector */ - openpic_set_priority(sc, 0, 0); + openpic_set_priority(sc, 0); /* clear all pending interrupts */ for (irq = 0; irq < sc->sc_nirq; irq++) { - (void)openpic_read(sc, OPENPIC_IACK(0)); - openpic_write(sc, OPENPIC_EOI(0), 0); + (void)openpic_read(sc, OPENPIC_IACK); + openpic_write(sc, OPENPIC_EOI, 0); } powerpc_register_pic(dev); @@ -182,7 +182,7 @@ sc = device_get_softc(dev); while (1) { - vector = openpic_read(sc, OPENPIC_IACK(0)); + vector = openpic_read(sc, OPENPIC_IACK); vector &= OPENPIC_VECTOR_MASK; if (vector == 255) break; @@ -209,7 +209,16 @@ struct openpic_softc *sc; sc = device_get_softc(dev); - openpic_write(sc, OPENPIC_EOI(0), 0); + openpic_write(sc, OPENPIC_EOI, 0); +} + +void +openpic_ipi(device_t dev, u_int cpu) +{ + struct openpic_softc *sc; + + sc = device_get_softc(dev); + openpic_write(sc, OPENPIC_IPI_DISPATCH(0), 1u << cpu); } void @@ -222,7 +231,7 @@ x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq)); x |= OPENPIC_IMASK; openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x); - openpic_write(sc, OPENPIC_EOI(0), 0); + openpic_write(sc, OPENPIC_EOI, 0); } void ==== //depot/projects/powerpc/sys/powerpc/powerpc/pic_if.m#4 (text+ko) ==== @@ -48,6 +48,11 @@ u_int irq; }; +METHOD void ipi { + device_t dev; + u_int cpu; +}; + METHOD void mask { device_t dev; u_int irq; ==== //depot/projects/powerpc/sys/powerpc/psim/openpic_iobus.c#3 (text+ko) ==== @@ -74,6 +74,7 @@ DEVMETHOD(pic_dispatch, openpic_dispatch), DEVMETHOD(pic_enable, openpic_enable), DEVMETHOD(pic_eoi, openpic_eoi), + DEVMETHOD(pic_ipi, openpic_ipi), DEVMETHOD(pic_mask, openpic_mask), DEVMETHOD(pic_unmask, openpic_unmask),