Finish moving code between ip2x.c and ip3x.c to imc.c and crime.c.

This commit is contained in:
sekiya 2004-01-18 00:54:55 +00:00
parent 90ed8dc85b
commit 23020fc3cf
4 changed files with 154 additions and 61 deletions

View File

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

View File

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

View File

@ -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();
}

View File

@ -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