Module Name: src Committed By: matt Date: Thu Mar 11 08:21:00 UTC 2010
Modified Files: src/sys/arch/sbmips/include [matt-nb5-mips64]: cpu.h systemsw.h src/sys/arch/sbmips/sbmips [matt-nb5-mips64]: cpu.c sb1250_icu.c Log Message: Use a cpu_softc to keep per-cpu things like interrupts, intr masks, etc. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.1.142.1 src/sys/arch/sbmips/include/cpu.h cvs rdiff -u -r1.7.28.4 -r1.7.28.5 src/sys/arch/sbmips/include/systemsw.h cvs rdiff -u -r1.18.16.5 -r1.18.16.6 src/sys/arch/sbmips/sbmips/cpu.c cvs rdiff -u -r1.9.36.6 -r1.9.36.7 src/sys/arch/sbmips/sbmips/sb1250_icu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sbmips/include/cpu.h diff -u src/sys/arch/sbmips/include/cpu.h:1.1 src/sys/arch/sbmips/include/cpu.h:1.1.142.1 --- src/sys/arch/sbmips/include/cpu.h:1.1 Wed Mar 6 02:13:41 2002 +++ src/sys/arch/sbmips/include/cpu.h Thu Mar 11 08:20:59 2010 @@ -1,3 +1,18 @@ -/* $NetBSD: cpu.h,v 1.1 2002/03/06 02:13:41 simonb Exp $ */ +/* $NetBSD: cpu.h,v 1.1.142.1 2010/03/11 08:20:59 matt Exp $ */ + +#ifndef _SBMIPS_CPU_H_ +#define _SBMIPS_CPU_H_ #include <mips/cpu.h> + +#ifndef _LOCORE +struct cpu_softc { + device_t cpu_dev; + struct cpu_info *cpu_ci; + vaddr_t cpu_imr_base; + uint64_t cpu_imr_all; + struct evcnt cpu_intr_evcnts[64]; +}; +#endif /* _LOCORE */ + +#endif /* !_SBMIPS_CPU_H_ */ Index: src/sys/arch/sbmips/include/systemsw.h diff -u src/sys/arch/sbmips/include/systemsw.h:1.7.28.4 src/sys/arch/sbmips/include/systemsw.h:1.7.28.5 --- src/sys/arch/sbmips/include/systemsw.h:1.7.28.4 Mon Mar 1 23:55:49 2010 +++ src/sys/arch/sbmips/include/systemsw.h Thu Mar 11 08:20:59 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: systemsw.h,v 1.7.28.4 2010/03/01 23:55:49 matt Exp $ */ +/* $NetBSD: systemsw.h,v 1.7.28.5 2010/03/11 08:20:59 matt Exp $ */ /* * Copyright 2000, 2001 @@ -56,7 +56,8 @@ bool system_set_clockfns(void *, void (*)(void *)); void sb1250_icu_init(void); -void sb1250_cpu_init(struct cpu_info *); +struct cpu_softc; +void sb1250_cpu_init(struct cpu_softc *); #define cpu_intr_establish(n,s,f,a) ((*systemsw.s_intr_establish)(n,s,f,a)) Index: src/sys/arch/sbmips/sbmips/cpu.c diff -u src/sys/arch/sbmips/sbmips/cpu.c:1.18.16.5 src/sys/arch/sbmips/sbmips/cpu.c:1.18.16.6 --- src/sys/arch/sbmips/sbmips/cpu.c:1.18.16.5 Mon Mar 1 23:55:49 2010 +++ src/sys/arch/sbmips/sbmips/cpu.c Thu Mar 11 08:20:59 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.18.16.5 2010/03/01 23:55:49 matt Exp $ */ +/* $NetBSD: cpu.c,v 1.18.16.6 2010/03/11 08:20:59 matt Exp $ */ /* * Copyright 2000, 2001 @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18.16.5 2010/03/01 23:55:49 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18.16.6 2010/03/11 08:20:59 matt Exp $"); #include "opt_multiprocessor.h" @@ -59,7 +59,7 @@ static int cpu_match(device_t, cfdata_t, void *); static void cpu_attach(device_t, device_t, void *); -CFATTACH_DECL_NEW(cpu, 0, +CFATTACH_DECL_NEW(cpu, sizeof(struct cpu_softc), cpu_match, cpu_attach, NULL, NULL); static u_int found = 0; @@ -85,9 +85,10 @@ cpu_attach(device_t parent, device_t self, void *aux) { struct cpu_info *ci; + struct cpu_softc * const cpu = device_private(self); const char * const xname = device_xname(self); - int plldiv; uint32_t config; + int plldiv; found++; @@ -122,13 +123,24 @@ (ci->ci_cpu_freq % 1000000) / 10000, ci->ci_cycles_per_hz, ci->ci_divisor_delay); + KASSERT(ci->ci_cpuid == 0); + + cpu->cpu_dev = self; + cpu->cpu_ci = ci; + ci->ci_softc = cpu; + + sb1250_cpu_init(cpu); } else { #if defined(MULTIPROCESSOR) int status; - ci = cpu_info_alloc(NULL, found); + ci = cpu_info_alloc(NULL, found - 1); KASSERT(ci); - sb1250_cpu_init(ci); + cpu->cpu_dev = self; + cpu->cpu_ci = ci; + ci->ci_softc = cpu; + + sb1250_cpu_init(cpu); status = cfe_cpu_start(ci->ci_cpuid, cpu_trampoline, (long) ci->ci_data.cpu_idlelwp->l_md.md_utf, 0, Index: src/sys/arch/sbmips/sbmips/sb1250_icu.c diff -u src/sys/arch/sbmips/sbmips/sb1250_icu.c:1.9.36.6 src/sys/arch/sbmips/sbmips/sb1250_icu.c:1.9.36.7 --- src/sys/arch/sbmips/sbmips/sb1250_icu.c:1.9.36.6 Mon Mar 1 23:55:49 2010 +++ src/sys/arch/sbmips/sbmips/sb1250_icu.c Thu Mar 11 08:20:59 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: sb1250_icu.c,v 1.9.36.6 2010/03/01 23:55:49 matt Exp $ */ +/* $NetBSD: sb1250_icu.c,v 1.9.36.7 2010/03/11 08:20:59 matt Exp $ */ /* * Copyright 2000, 2001 @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sb1250_icu.c,v 1.9.36.6 2010/03/01 23:55:49 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sb1250_icu.c,v 1.9.36.7 2010/03/11 08:20:59 matt Exp $"); #define __INTR_PRIVATE @@ -41,6 +41,7 @@ #include <sys/systm.h> #include <sys/device.h> #include <sys/kmem.h> +#include <sys/cpu.h> /* XXX for uvmexp */ #include <uvm/uvm_extern.h> @@ -72,7 +73,6 @@ /* imr values corresponding to each pin */ static uint64_t ints_for_ipl[_IPL_N]; -static uint64_t imr_all; struct sb1250_ihand { void (*ih_fun)(void *, uint32_t, vaddr_t); @@ -84,23 +84,8 @@ #ifdef MULTIPROCESSOR static void sb1250_ipi_intr(void *, uint32_t, vaddr_t); -struct evcnt *sb1250_evcnts; -#define INTR_EVCNTS(ci) (&sb1250_evcnts[(ci)->ci_cpuid]) - -#define SB1250_I_IMR_BASE(ci) MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE \ - + ((ci)->ci_cpuid * IMR_REGISTER_SPACING)) -#else -struct evcnt sb1250_evcnts[K_INT_SOURCES]; -#define INTR_EVCNTS(ci) ((void)ci, sb1250_evcnts) - -#define SB1250_I_IMR_BASE(ci) ((void)ci, MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE)) #endif -#define SB1250_I_IMR_ADDR(base) ((base) + R_IMR_INTERRUPT_MASK) -#define SB1250_I_IMR_SSTATUS(base) ((base) + R_IMR_INTERRUPT_SOURCE_STATUS) -#define SB1250_I_MAP(base, x) ((base) + R_IMR_INTERRUPT_MAP_BASE + (x) * 8) -#define SB1250_I_IMR_MAILBOX(base) ((base) + R_IMR_MAILBOX_CPU) -#define SB1250_I_IMR_MAILBOX_SET(base) ((base) + R_IMR_MAILBOX_SET_CPU) -#define SB1250_I_IMR_MAILBOX_CLR(base) ((base) + R_IMR_MAILBOX_CLR_CPU) +#define SB1250_I_MAP(x) (R_IMR_INTERRUPT_MAP_BASE + (x) * 8) #define READ_REG(rp) (mips3_ld((volatile uint64_t *)(rp))) #define WRITE_REG(rp, val) (mips3_sd((volatile uint64_t *)(rp), (val))) @@ -109,7 +94,7 @@ static void *sb1250_intr_establish(u_int, u_int, void (*fun)(void *, uint32_t, vaddr_t), void *); -static const char * const intr_names[K_INT_SOURCES] = { +static const char sb1250_intr_names[K_INT_SOURCES][16] = { [K_INT_WATCHDOG_TIMER_0] = "wdog0", [K_INT_WATCHDOG_TIMER_1] = "wdog1", [K_INT_TIMER_0] = "timer0", @@ -177,13 +162,22 @@ }; #ifdef MULTIPROCESSOR +static void +sb1250_lsw_cpu_init(struct cpu_info *ci) +{ + struct cpu_softc * const cpu = ci->ci_softc; + + WRITE_REG(cpu->cpu_imr_base + R_IMR_INTERRUPT_MASK, cpu->cpu_imr_all); +} + static int -sb1250_send_ipi(struct cpu_info *ci, int tag) +sb1250_lsw_send_ipi(struct cpu_info *ci, int tag) { - const vaddr_t imr_base = SB1250_I_IMR_BASE(ci); + struct cpu_softc * const cpu = ci->ci_softc; const uint64_t mbox_mask = 1LLU << tag; - WRITE_REG(SB1250_I_IMR_MAILBOX_SET(imr_base), mbox_mask); + if (cpus_running & (1 << cpu_index(ci))) + WRITE_REG(cpu->cpu_imr_base + R_IMR_MAILBOX_SET_CPU, mbox_mask); return 0; } @@ -192,41 +186,49 @@ sb1250_ipi_intr(void *arg, uint32_t status, vaddr_t pc) { struct cpu_info * const ci = curcpu(); - const vaddr_t imr_base = SB1250_I_IMR_BASE(ci); + struct cpu_softc * const cpu = ci->ci_softc; uint64_t mbox_mask; - mbox_mask = READ_REG(SB1250_I_IMR_MAILBOX(imr_base)); - WRITE_REG(SB1250_I_IMR_MAILBOX_CLR(imr_base), mbox_mask); + mbox_mask = READ_REG(cpu->cpu_imr_base + R_IMR_MAILBOX_CPU); + WRITE_REG(cpu->cpu_imr_base + R_IMR_MAILBOX_CLR_CPU, mbox_mask); ipi_process(ci, mbox_mask); } #endif void -sb1250_cpu_init(struct cpu_info *ci) +sb1250_cpu_init(struct cpu_softc *cpu) { - const vaddr_t imr_base = SB1250_I_IMR_BASE(ci); - const char * const xname = ci->ci_dev ? device_xname(ci->ci_dev) : "cpu0"; - struct evcnt * evcnts = INTR_EVCNTS(ci); - const char * const * names = intr_names; + const char * const xname = device_xname(cpu->cpu_ci->ci_dev); + struct evcnt * evcnts = cpu->cpu_intr_evcnts; - WRITE_REG(SB1250_I_IMR_ADDR(imr_base), imr_all); + cpu->cpu_imr_base = + MIPS_PHYS_TO_KSEG1(A_IMR_MAPPER(cpu->cpu_ci->ci_cpuid)); +#ifdef MULTIPROCESSOR + cpu->cpu_imr_all = + ~(M_INT_MBOX_0|M_INT_MBOX_1|M_INT_MBOX_2|M_INT_MBOX_3); +#else + cpu->cpu_imr_all = ~0ULL; +#endif - for (u_int i = 0; i < K_INT_SOURCES; i++, evcnts++, names++) { - WRITE_REG(SB1250_I_MAP(imr_base, i), K_INT_MAP_I0); + for (u_int i = 0; i < K_INT_SOURCES; i++, evcnts++) { + WRITE_REG(cpu->cpu_imr_base + SB1250_I_MAP(i), K_INT_MAP_I0); evcnt_attach_dynamic(evcnts, EVCNT_TYPE_INTR, NULL, - xname, names[i]); + xname, sb1250_intr_names[i]); } + + WRITE_REG(cpu->cpu_imr_base + R_IMR_INTERRUPT_MASK, cpu->cpu_imr_all); } void sb1250_icu_init(void) { + const uint64_t imr_all = 0xffffffffffffffffULL; + ipl_sr_map = sb1250_ipl_sr_map; /* zero out the list of used interrupts/lines */ memset(ints_for_ipl, 0, sizeof ints_for_ipl); - imr_all = 0xffffffffffffffffULL; memset(sb1250_ihands, 0, sizeof sb1250_ihands); systemsw.s_cpu_intr = sb1250_cpu_intr; @@ -243,19 +245,26 @@ * Allocate an evcnt structure for every possible interrupt on * every possible CPU. */ - sb1250_evcnts = kmem_alloc(sizeof(struct evcnt [K_INT_SOURCES*cpus]), - KM_SLEEP); + vaddr_t imr = MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE + R_IMR_INTERRUPT_MASK); + for (u_int i = 1; imr += IMR_REGISTER_SPACING, i < cpus; i++) { + WRITE_REG(imr, imr_all); + } #endif /* MULTIPROCESSOR */ - - sb1250_cpu_init(curcpu()); + WRITE_REG(MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE + R_IMR_INTERRUPT_MASK), + imr_all); #ifdef MULTIPROCESSOR + /* + * For now, deliver all IPIs at IPL_SCHED. Eventually some will be + * at IPL_VM. + */ sb1250_intr_establish(K_INT_MBOX_0, IPL_SCHED, sb1250_ipi_intr, NULL); sb1250_intr_establish(K_INT_MBOX_1, IPL_SCHED, sb1250_ipi_intr, NULL); sb1250_intr_establish(K_INT_MBOX_2, IPL_SCHED, sb1250_ipi_intr, NULL); sb1250_intr_establish(K_INT_MBOX_3, IPL_SCHED, sb1250_ipi_intr, NULL); - mips_locoresw.lsw_send_ipi = sb1250_send_ipi; + mips_locoresw.lsw_send_ipi = sb1250_lsw_send_ipi; + mips_locoresw.lsw_cpu_init = sb1250_lsw_cpu_init; #endif /* MULTIPROCESSOR */ } @@ -263,8 +272,9 @@ sb1250_cpu_intr(int ppl, vaddr_t pc, uint32_t status) { struct cpu_info * const ci = curcpu(); - const vaddr_t imr_base = SB1250_I_IMR_BASE(ci); - struct evcnt * const evcnts = INTR_EVCNTS(ci); + struct cpu_softc * const cpu = ci->ci_softc; + const vaddr_t imr_base = cpu->cpu_imr_base; + struct evcnt * const evcnts = cpu->cpu_intr_evcnts; uint32_t pending; int ipl; @@ -281,10 +291,7 @@ } uint64_t sstatus = ints_for_ipl[ipl]; - if (sstatus == 0) - continue; - - sstatus &= READ_REG(SB1250_I_IMR_SSTATUS(imr_base)); + sstatus &= READ_REG(imr_base + R_IMR_INTERRUPT_SOURCE_STATUS); for (int j = 63; sstatus != 0; j--) { u_int n = __builtin_clz(sstatus); KASSERT((sstatus >> (63-n)) & 1); @@ -302,7 +309,7 @@ sb1250_intr_establish(u_int num, u_int ipl, void (*fun)(void *, uint32_t, vaddr_t), void *arg) { - const vaddr_t imr_base = SB1250_I_IMR_BASE(curcpu()); + struct cpu_softc * const cpu = curcpu()->ci_softc; struct sb1250_ihand * const ih = &sb1250_ihands[num]; const int s = splhigh(); @@ -314,16 +321,16 @@ panic("%s: cannot share sb1250 interrupts", __func__); ints_for_ipl[ipl] |= (1ULL << num); - imr_all &= ~(1ULL << num); + cpu->cpu_imr_all &= ~(1ULL << num); ih->ih_fun = fun; ih->ih_arg = arg; ih->ih_ipl = ipl; if (ipl > IPL_VM) - WRITE_REG(SB1250_I_MAP(imr_base, num), K_INT_MAP_I1); + WRITE_REG(cpu->cpu_imr_base + SB1250_I_MAP(num), K_INT_MAP_I1); - WRITE_REG(SB1250_I_IMR_ADDR(imr_base), imr_all); + WRITE_REG(cpu->cpu_imr_base + R_IMR_INTERRUPT_MASK, cpu->cpu_imr_all); splx(s);