Finish moving code between ip2x.c and ip3x.c to imc.c and crime.c.
This commit is contained in:
parent
90ed8dc85b
commit
23020fc3cf
@ -1,6 +1,7 @@
|
||||
/* $NetBSD: crime.c,v 1.16 2004/01/13 14:31:37 sekiya Exp $ */
|
||||
/* $NetBSD: crime.c,v 1.17 2004/01/18 00:54:55 sekiya Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Christopher SEKIYA
|
||||
* Copyright (c) 2000 Soren S. Jorvang
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -37,11 +38,12 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: crime.c,v 1.16 2004/01/13 14:31:37 sekiya Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: crime.c,v 1.17 2004/01/18 00:54:55 sekiya Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/locore.h>
|
||||
@ -58,9 +60,15 @@ __KERNEL_RCSID(0, "$NetBSD: crime.c,v 1.16 2004/01/13 14:31:37 sekiya Exp $");
|
||||
|
||||
static int crime_match(struct device *, struct cfdata *, void *);
|
||||
static void crime_attach(struct device *, struct device *, void *);
|
||||
void crime_watchdog_tickle(void);
|
||||
void crime_bus_reset(void);
|
||||
void crime_watchdog_reset(void);
|
||||
void crime_watchdog_disable(void);
|
||||
void crime_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
void *crime_intr_establish(int, int, int (*)(void *), void *);
|
||||
extern void mace_intr(int); /* XXX */
|
||||
|
||||
struct crime_softc *crime_sc; /* only one per machine, okay to be global */
|
||||
static bus_space_tag_t crm_iot;
|
||||
static bus_space_handle_t crm_ioh;
|
||||
|
||||
CFATTACH_DECL(crime, sizeof(struct crime_softc),
|
||||
crime_match, crime_attach, NULL, NULL);
|
||||
@ -73,10 +81,7 @@ struct {
|
||||
} crime[CRIME_NINTR];
|
||||
|
||||
static int
|
||||
crime_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *match;
|
||||
void *aux;
|
||||
crime_match(struct device *parent, struct cfdata *match, void *aux)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -89,24 +94,20 @@ crime_match(parent, match, aux)
|
||||
}
|
||||
|
||||
static void
|
||||
crime_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
crime_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct crime_softc *sc = (struct crime_softc *)self;
|
||||
struct mainbus_attach_args *ma = aux;
|
||||
u_int64_t crm_id;
|
||||
u_int64_t baseline;
|
||||
u_int32_t cps;
|
||||
|
||||
crime_sc = sc;
|
||||
crm_iot = SGIMIPS_BUS_SPACE_CRIME;
|
||||
|
||||
sc->iot = SGIMIPS_BUS_SPACE_CRIME;
|
||||
|
||||
if (bus_space_map(sc->iot, ma->ma_addr, 0 /* XXX */,
|
||||
BUS_SPACE_MAP_LINEAR, &sc->ioh))
|
||||
if (bus_space_map(crm_iot, ma->ma_addr, 0 /* XXX */,
|
||||
BUS_SPACE_MAP_LINEAR, &crm_ioh))
|
||||
panic("crime_attach: can't map I/O space");
|
||||
|
||||
crm_id = bus_space_read_8(sc->iot, sc->ioh, CRIME_REV);
|
||||
crm_id = bus_space_read_8(crm_iot, crm_ioh, CRIME_REV);
|
||||
|
||||
aprint_naive(": system ASIC");
|
||||
|
||||
@ -135,20 +136,43 @@ crime_attach(parent, self, aux)
|
||||
|
||||
aprint_normal(" (CRIME_ID: %llx)\n", crm_id);
|
||||
|
||||
/* reset CRIME CPU & memory error registers */
|
||||
crime_bus_reset();
|
||||
|
||||
baseline = bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME) & CRIME_TIME_MASK;
|
||||
cps = mips3_cp0_count_read();
|
||||
|
||||
while (((bus_space_read_8(crm_iot, crm_ioh, CRIME_TIME) & CRIME_TIME_MASK)
|
||||
- baseline) < 50 * 1000000 / 15)
|
||||
continue;
|
||||
cps = mips3_cp0_count_read() - cps;
|
||||
cps = cps / 5;
|
||||
|
||||
/* Counter on R4k/R4400/R4600/R5k counts at half the CPU frequency */
|
||||
curcpu()->ci_cpu_freq = cps * 2 * hz;
|
||||
curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz);
|
||||
curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000);
|
||||
MIPS_SET_CI_RECIPRICAL(curcpu());
|
||||
|
||||
/* Turn on memory error and crime error interrupts.
|
||||
All others turned on as devices are registered. */
|
||||
bus_space_write_8(sc->iot, sc->ioh, CRIME_INTMASK,
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_INTMASK,
|
||||
CRIME_INT_MEMERR |
|
||||
CRIME_INT_CRMERR |
|
||||
CRIME_INT_VICE |
|
||||
CRIME_INT_VID_OUT |
|
||||
CRIME_INT_VID_IN2 |
|
||||
CRIME_INT_VID_IN1);
|
||||
bus_space_write_8(sc->iot, sc->ioh, CRIME_INTSTAT, 0);
|
||||
bus_space_write_8(sc->iot, sc->ioh, CRIME_SOFTINT, 0);
|
||||
bus_space_write_8(sc->iot, sc->ioh, CRIME_HARDINT, 0);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_INTSTAT, 0);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_SOFTINT, 0);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_HARDINT, 0);
|
||||
|
||||
platform.watchdog_reset = crime_watchdog_tickle;
|
||||
platform.bus_reset = crime_bus_reset;
|
||||
platform.watchdog_reset = crime_watchdog_reset;
|
||||
platform.watchdog_disable = crime_watchdog_disable;
|
||||
platform.watchdog_enable = crime_watchdog_reset;
|
||||
platform.intr_establish = crime_intr_establish;
|
||||
platform.intr0 = crime_intr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -156,12 +180,7 @@ crime_attach(parent, self, aux)
|
||||
*/
|
||||
|
||||
void *
|
||||
crime_intr_establish(irq, type, level, func, arg)
|
||||
int irq;
|
||||
int type;
|
||||
int level;
|
||||
int (*func)(void *);
|
||||
void *arg;
|
||||
crime_intr_establish(int irq, int level, int (*func)(void *), void *arg)
|
||||
{
|
||||
if (crime[irq].func != NULL)
|
||||
return NULL; /* panic("Cannot share CRIME interrupts!"); */
|
||||
@ -175,15 +194,51 @@ crime_intr_establish(irq, type, level, func, arg)
|
||||
}
|
||||
|
||||
void
|
||||
crime_intr(pendmask)
|
||||
u_int pendmask;
|
||||
crime_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending)
|
||||
{
|
||||
u_int64_t crime_intmask;
|
||||
u_int64_t crime_intstat;
|
||||
u_int64_t crime_ipending;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CRIME_NINTR; i++) {
|
||||
if ((pendmask & (1 << i)) && crime[i].func != NULL)
|
||||
(*crime[i].func)(crime[i].arg);
|
||||
crime_intmask = bus_space_read_8(crm_iot, crm_ioh, CRIME_INTMASK);
|
||||
crime_intstat = bus_space_read_8(crm_iot, crm_ioh, CRIME_INTSTAT);
|
||||
crime_ipending = (crime_intstat & crime_intmask);
|
||||
|
||||
if (crime_ipending & 0xff)
|
||||
mace_intr(crime_ipending & 0xff);
|
||||
|
||||
if (crime_ipending & 0xffff0000) {
|
||||
/*
|
||||
* CRIME interrupts for CPU and memory errors
|
||||
*/
|
||||
if (crime_ipending & CRIME_INT_MEMERR) {
|
||||
u_int64_t address =
|
||||
bus_space_read_8(crm_iot, crm_ioh, CRIME_MEM_ERROR_ADDR);
|
||||
u_int64_t status =
|
||||
bus_space_read_8(crm_iot, crm_ioh, CRIME_MEM_ERROR_STAT);
|
||||
printf("crime: memory error address %llx"
|
||||
" status %llx\n", address << 2, status);
|
||||
crime_bus_reset();
|
||||
}
|
||||
|
||||
if (crime_ipending & CRIME_INT_CRMERR) {
|
||||
u_int64_t stat =
|
||||
bus_space_read_8(crm_iot, crm_ioh, CRIME_CPU_ERROR_STAT);
|
||||
printf("crime: cpu error %llx at"
|
||||
" address %llx\n", stat,
|
||||
bus_space_read_8(crm_iot, crm_ioh, CRIME_CPU_ERROR_ADDR));
|
||||
crime_bus_reset();
|
||||
}
|
||||
}
|
||||
|
||||
crime_ipending &= 0xff00;
|
||||
|
||||
if (crime_ipending)
|
||||
for (i = 0; i < CRIME_NINTR; i++) {
|
||||
if ((crime_ipending & (1 << i)) && crime[i].func != NULL)
|
||||
(*crime[i].func)(crime[i].arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -191,17 +246,34 @@ crime_intr_mask(unsigned int intr)
|
||||
{
|
||||
u_int64_t mask;
|
||||
|
||||
mask = bus_space_read_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK);
|
||||
mask = bus_space_read_8(crm_iot, crm_ioh, CRIME_INTMASK);
|
||||
mask |= (1 << intr);
|
||||
bus_space_write_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK, mask);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_INTMASK, mask);
|
||||
}
|
||||
|
||||
void
|
||||
crime_watchdog_tickle(void)
|
||||
crime_bus_reset(void)
|
||||
{
|
||||
/* enable watchdog timer, clear it */
|
||||
bus_space_write_8(crime_sc->iot, crime_sc->ioh,
|
||||
CRIME_CONTROL, CRIME_CONTROL_DOG_ENABLE);
|
||||
bus_space_write_8(crime_sc->iot, crime_sc->ioh, CRIME_WATCHDOG, 0);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_CPU_ERROR_STAT, 0);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_MEM_ERROR_STAT, 0);
|
||||
}
|
||||
|
||||
void
|
||||
crime_watchdog_reset(void)
|
||||
{
|
||||
/* enable watchdog timer, clear it */
|
||||
bus_space_write_8(crm_iot, crm_ioh,
|
||||
CRIME_CONTROL, CRIME_CONTROL_DOG_ENABLE);
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_WATCHDOG, 0);
|
||||
}
|
||||
|
||||
void
|
||||
crime_watchdog_disable(void)
|
||||
{
|
||||
u_int64_t reg;
|
||||
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_WATCHDOG, 0);
|
||||
reg = bus_space_read_8(crm_iot, crm_ioh, CRIME_CONTROL)
|
||||
& ~CRIME_CONTROL_DOG_ENABLE;
|
||||
bus_space_write_8(crm_iot, crm_ioh, CRIME_CONTROL, reg);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: crimevar.h,v 1.2 2003/11/17 10:07:58 keihan Exp $ */
|
||||
/* $NetBSD: crimevar.h,v 1.3 2004/01/18 00:54:55 sekiya Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Christopher SEKIYA
|
||||
@ -36,13 +36,6 @@
|
||||
|
||||
struct crime_softc {
|
||||
struct device sc_dev;
|
||||
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
};
|
||||
|
||||
extern struct crime_softc *crime_sc;
|
||||
|
||||
void *crime_intr_establish(int, int, int, int (*)(void *), void *);
|
||||
void crime_intr(u_int);
|
||||
void crime_intr_mask(unsigned int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: imc.c,v 1.13 2004/01/13 14:31:37 sekiya Exp $ */
|
||||
/* $NetBSD: imc.c,v 1.14 2004/01/18 00:54:55 sekiya Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Rafal K. Boni
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: imc.c,v 1.13 2004/01/13 14:31:37 sekiya Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: imc.c,v 1.14 2004/01/18 00:54:55 sekiya Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
@ -59,7 +59,9 @@ static void imc_attach(struct device *, struct device *, void *);
|
||||
static int imc_print(void *, const char *);
|
||||
void imc_bus_reset(void);
|
||||
void imc_bus_error(void);
|
||||
void imc_watchdog_tickle(void);
|
||||
void imc_watchdog_reset(void);
|
||||
void imc_watchdog_disable(void);
|
||||
void imc_watchdog_enable(void);
|
||||
|
||||
CFATTACH_DECL(imc, sizeof(struct imc_softc),
|
||||
imc_match, imc_attach, NULL, NULL);
|
||||
@ -110,7 +112,9 @@ imc_attach(parent, self, aux)
|
||||
panic("imc_attach: could not allocate memory\n");
|
||||
|
||||
platform.bus_reset = imc_bus_reset;
|
||||
platform.watchdog_reset = imc_watchdog_tickle;
|
||||
platform.watchdog_reset = imc_watchdog_reset;
|
||||
platform.watchdog_disable = imc_watchdog_disable;
|
||||
platform.watchdog_enable = imc_watchdog_enable;
|
||||
|
||||
sysid = bus_space_read_4(isc.iot, isc.ioh, IMC_SYSID);
|
||||
|
||||
@ -220,11 +224,7 @@ imc_attach(parent, self, aux)
|
||||
iaa.iaa_name = "gio";
|
||||
(void)config_found(self, (void*)&iaa, imc_print);
|
||||
|
||||
/* enable watchdog and clear it */
|
||||
reg = bus_space_read_4(isc.iot, isc.ioh, IMC_CPUCTRL0);
|
||||
reg |= IMC_CPUCTRL0_WDOG;
|
||||
bus_space_write_4(isc.iot, isc.ioh, IMC_CPUCTRL0, reg);
|
||||
imc_watchdog_tickle();
|
||||
imc_watchdog_enable();
|
||||
}
|
||||
|
||||
|
||||
@ -260,7 +260,29 @@ imc_bus_error(void)
|
||||
}
|
||||
|
||||
void
|
||||
imc_watchdog_tickle(void)
|
||||
imc_watchdog_reset(void)
|
||||
{
|
||||
bus_space_write_4(isc.iot, isc.ioh, IMC_WDOG, 0);
|
||||
}
|
||||
void
|
||||
imc_watchdog_disable(void)
|
||||
{
|
||||
u_int32_t reg;
|
||||
|
||||
bus_space_write_4(isc.iot, isc.ioh, IMC_WDOG, 0);
|
||||
reg = bus_space_read_4(isc.iot, isc.ioh, IMC_CPUCTRL0);
|
||||
reg &= IMC_CPUCTRL0_WDOG;
|
||||
bus_space_write_4(isc.iot, isc.ioh, IMC_CPUCTRL0, reg);
|
||||
}
|
||||
|
||||
void
|
||||
imc_watchdog_enable(void)
|
||||
{
|
||||
u_int32_t reg;
|
||||
|
||||
/* enable watchdog and clear it */
|
||||
reg = bus_space_read_4(isc.iot, isc.ioh, IMC_CPUCTRL0);
|
||||
reg |= IMC_CPUCTRL0_WDOG;
|
||||
bus_space_write_4(isc.iot, isc.ioh, IMC_CPUCTRL0, reg);
|
||||
imc_watchdog_reset();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: int2reg.h,v 1.1 2004/01/10 05:16:57 sekiya Exp $ */
|
||||
/* $NetBSD: int2reg.h,v 1.2 2004/01/18 00:54:55 sekiya Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Christopher SEKIYA
|
||||
@ -30,6 +30,12 @@
|
||||
#if !defined(_ARCH_SGIMIPS_DEV_INT2_H_)
|
||||
#define _ARCH_SGIMIPS_DEV_INT2_H_
|
||||
|
||||
/* The INT has known locations on all SGI machines */
|
||||
#define INT_IP12 0x1fb801c0
|
||||
#define INT_IP20 0x1fb801c0
|
||||
#define INT_IP22 0x1fbd9000
|
||||
#define INT_IP24 0x1fbd9880
|
||||
|
||||
#define INT2_LOCAL0_STATUS 0x00
|
||||
#define INT2_LOCAL0_MASK 0x04
|
||||
#define INT2_LOCAL1_STATUS 0x08
|
||||
|
Loading…
Reference in New Issue
Block a user