#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ka630.c,v 1.30 2010/12/14 23:44:49 matt Exp $");
#include "opt_cputype.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/time.h>
#include <machine/ka630.h>
#include <machine/clock.h>
#include <machine/vsbus.h>
static struct uvaxIIcpu *uvaxIIcpu_ptr;
static void ka630_conf(void);
static void ka630_memerr(void);
static int ka630_mchk(void *);
static void ka630_halt(void);
static void ka630_reboot(int);
static void ka630_clrf(void);
static const char * const ka630_devs[] = { "cpu", "uba", NULL };
const struct cpu_dep ka630_calls = {
.cpu_mchk = ka630_mchk,
.cpu_memerr = ka630_memerr,
.cpu_conf = ka630_conf,
.cpu_gettime = chip_gettime,
.cpu_settime = chip_settime,
.cpu_vups = 1,
.cpu_scbsz = 2,
.cpu_halt = ka630_halt,
.cpu_reboot = ka630_reboot,
.cpu_clrf = ka630_clrf,
.cpu_devs = ka630_devs
};
void
ka630_conf(void)
{
curcpu()->ci_cpustr = "KA630, UV2";
clk_adrshift = 0;
clk_tweak = 0;
clk_page = (short *)vax_map_physmem((paddr_t)KA630CLK, 1);
uvaxIIcpu_ptr = (void *)vax_map_physmem(VS_REGS, 1);
uvaxIIcpu_ptr->uvaxII_mser = (UVAXIIMSER_PEN | UVAXIIMSER_MERR |
UVAXIIMSER_LEB);
}
void
ka630_memerr(void)
{
printf("memory err!\n");
}
#define NMC78032 10
const char * const mc78032[] = {
0, "immcr (fsd)", "immcr (ssd)", "fpu err 0",
"fpu err 7", "mmu st(tb)", "mmu st(m=0)", "pte in p0",
"pte in p1", "un intr id",
};
struct mc78032frame {
int mc63_bcnt;
int mc63_summary;
int mc63_mrvaddr;
int mc63_istate;
int mc63_pc;
int mc63_psl;
};
int
ka630_mchk(void *cmcf)
{
struct mc78032frame * const mcf = (struct mc78032frame *)cmcf;
u_int type = mcf->mc63_summary;
printf("machine check %x", type);
if (type < NMC78032 && mc78032[type])
printf(": %s", mc78032[type]);
printf("\n\tvap %x istate %x pc %x psl %x\n",
mcf->mc63_mrvaddr, mcf->mc63_istate,
mcf->mc63_pc, mcf->mc63_psl);
if (uvaxIIcpu_ptr && uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_MERR) {
printf("\tmser=0x%lx ", uvaxIIcpu_ptr->uvaxII_mser);
if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_CPUE)
printf("page=%ld", uvaxIIcpu_ptr->uvaxII_cear);
if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_DQPE)
printf("page=%ld", uvaxIIcpu_ptr->uvaxII_dear);
printf("\n");
}
return (-1);
}
void
ka630_halt(void)
{
((volatile struct ka630clock *)clk_page)->cpmbx = KA630CLK_DOTHIS|KA630CLK_HALT;
__asm("halt");
}
void
ka630_reboot(int arg)
{
((volatile struct ka630clock *)clk_page)->cpmbx =
KA630CLK_DOTHIS | KA630CLK_REBOOT;
}
void
ka630_clrf(void)
{
short i = ((volatile struct ka630clock *)clk_page)->cpmbx;
((volatile struct ka630clock *)clk_page)->cpmbx = i & KA630CLK_LANG;
}