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);