#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.28 2022/03/03 06:27:03 riastradh Exp $");
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/cpu.h>
#include <uvm/uvm_extern.h>
#include <machine/locore.h>
#include <machine/psl.h>
#include <machine/autoconf.h>
#include <machine/machtype.h>
#include <machine/sysconf.h>
#include <dev/arcbios/arcbios.h>
#include <dev/arcbios/arcbiosvar.h>
static int cpu_match(device_t, cfdata_t, void *);
static void cpu_attach(device_t, device_t, void *);
void cpu_intr(int, vaddr_t, uint32_t);
void *cpu_intr_establish(int, int, int (*func)(void *), void *);
static struct evcnt mips_int0_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 0");
static struct evcnt mips_int1_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 1");
static struct evcnt mips_int2_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 2");
static struct evcnt mips_int3_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 3");
static struct evcnt mips_int4_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 4");
static struct evcnt mips_int5_evcnt =
EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 5");
CFATTACH_DECL_NEW(cpu, 0,
cpu_match, cpu_attach, NULL, NULL);
static int
cpu_match(device_t parent, cfdata_t cf, void *aux)
{
return 1;
}
static void
cpu_attach(device_t parent, device_t self, void *aux)
{
struct cpu_info * const ci = curcpu();
ci->ci_dev = self;
device_set_private(self, ci);
aprint_normal(": ");
cpu_identify(self);
}
void
cpu_intr(int ppl, vaddr_t pc, uint32_t status)
{
uint32_t pending;
int ipl;
curcpu()->ci_data.cpu_nintr++;
#if !defined(__mips_o32)
KASSERTMSG(mips_cp0_status_read() & MIPS_SR_KX,
"pc %"PRIxVADDR ", status %x\n", pc, status);
#endif
(void)(*platform.watchdog_reset)();
while (ppl < (ipl = splintr(&pending))) {
splx(ipl);
if (pending & MIPS_INT_MASK_5) {
(void)(*platform.intr5)(pc, status, pending);
mips_int5_evcnt.ev_count++;
}
if (pending & MIPS_INT_MASK_4) {
(void)(*platform.intr4)(pc, status, pending);
mips_int4_evcnt.ev_count++;
}
if (pending & MIPS_INT_MASK_3) {
(void)(*platform.intr3)(pc, status, pending);
mips_int3_evcnt.ev_count++;
}
if (pending & MIPS_INT_MASK_2) {
(void)(*platform.intr2)(pc, status, pending);
mips_int2_evcnt.ev_count++;
}
if (pending & MIPS_INT_MASK_1) {
(void)(*platform.intr1)(pc, status, pending);
mips_int1_evcnt.ev_count++;
}
if (pending & MIPS_INT_MASK_0) {
(void)(*platform.intr0)(pc, status, pending);
mips_int0_evcnt.ev_count++;
}
(void)splhigh();
}
}
void *
cpu_intr_establish(int level, int ipl, int (*func)(void *), void *arg)
{
(*platform.intr_establish)(level, ipl, func, arg);
return (void *) -1;
}
#ifdef MIPS1
void
mips1_fpu_intr(vaddr_t pc, uint32_t status, uint32_t pending)
{
if (!USERMODE(status))
panic("kernel used FPU: PC 0x%08x, SR 0x%08x",
pc, status);
#if !defined(NOFPU) && !defined(FPEMUL)
mips_fpu_intr(pc, curlwp->l_md.md_utf);
#endif
}
#endif