#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ka680.c,v 1.18 2017/05/22 16:46:15 ragge Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <machine/sid.h>
#include <machine/nexus.h>
#include <machine/ka680.h>
#include <machine/clock.h>
#include <machine/scb.h>
static void ka680_conf(void);
static void ka680_attach_cpu(device_t);
static void ka680_cache_enable(void);
static void ka680_softmem(void *);
static void ka680_hardmem(void *);
static void ka680_steal_pages(void);
static void ka680_memerr(void);
static int ka680_mchk(void *);
#define PR_CCTL 0xa0
#define CCTL_ENABLE 0x00000001
#define CCTL_SW_ETM 0x40000000
#define CCTL_HW_ETM 0x80000000
#define PR_BCETSTS 0xa3
#define PR_BCEDSTS 0xa6
#define PR_NESTS 0xae
#define PR_VMAR 0xd0
#define PR_VTAG 0xd1
#define PR_ICSR 0xd3
#define ICSR_ENABLE 0x01
#define PR_PCCTL 0xf8
#define PCCTL_P_EN 0x10
#define PCCTL_I_EN 0x02
#define PCCTL_D_EN 0x01
static const char * const ka680_devs[] = { "cpu", "sgec", "shac", "uba", NULL };
const struct cpu_dep ka680_calls = {
.cpu_steal_pages = ka680_steal_pages,
.cpu_mchk = ka680_mchk,
.cpu_memerr = ka680_memerr,
.cpu_conf = ka680_conf,
.cpu_gettime = generic_gettime,
.cpu_settime = generic_settime,
.cpu_vups = 24,
.cpu_scbsz = 2,
.cpu_halt = generic_halt,
.cpu_reboot = generic_reboot,
.cpu_flags = CPU_RAISEIPL,
.cpu_devs = ka680_devs,
.cpu_attach_cpu = ka680_attach_cpu,
};
void
ka680_conf(void)
{
volatile int *hej = (void *)mfpr(PR_ISP);
*hej = *hej;
hej[-1] = hej[-1];
cpmbx = (struct cpmbx *)vax_map_physmem(0x20140400, 1);
}
void
ka680_attach_cpu(device_t self)
{
const char *cpuname;
switch (vax_boardtype) {
case VAX_BTYP_680:
switch((vax_siedata & 0xff00) >> 8) {
case VAX_STYP_675: cpuname = "KA675"; break;
case VAX_STYP_680: cpuname = "KA680"; break;
case VAX_STYP_690: cpuname = "KA690"; break;
default: cpuname = "unknown KA680-class";
}
break;
case VAX_BTYP_681:
switch ((vax_siedata & 0xff00) >> 8) {
case VAX_STYP_681: cpuname = "KA681"; break;
case VAX_STYP_691: cpuname = "KA691"; break;
case VAX_STYP_694: cpuname = (vax_cpudata & 0x1000) ?
"KA694" : "KA692"; break;
default: cpuname = "unknown KA681-class";
}
break;
default: cpuname = "unknown class"; break;
}
aprint_normal("%s, NVAX (ucode rev %d)\n", cpuname, vax_cpudata & 0xff);
}
void
ka680_cache_enable(void)
{
int start, pslut, fslut, cslut, havevic;
mtpr(0, PR_ICSR);
mtpr(0, PR_PCCTL);
mtpr(mfpr(PR_CCTL) | CCTL_SW_ETM, PR_CCTL);
mtpr(mfpr(PR_CCTL) | 6, PR_CCTL);
mtpr(mfpr(PR_BCETSTS), PR_BCETSTS);
mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS);
mtpr(mfpr(PR_NESTS), PR_NESTS);
start = 0x01400000;
fslut = 0x01420000;
cslut = 0x01020000;
havevic = 0;
switch(vax_boardtype) {
case VAX_BTYP_680:
switch((vax_siedata & 0xff00) >> 8) {
case VAX_STYP_675:
fslut = 0x01420000;
cslut = 0x01020000;
havevic = 0;
break;
case VAX_STYP_680:
fslut = 0x01420000;
cslut = 0x01020000;
havevic = 1;
break;
case VAX_STYP_690:
fslut = 0x01440000;
cslut = 0x01040000;
havevic = 1;
break;
}
case VAX_BTYP_681:
switch((vax_siedata & 0xff00) >> 8) {
case VAX_STYP_681:
fslut = 0x01420000;
cslut = 0x01020000;
havevic = 1;
break;
case VAX_STYP_691:
fslut = 0x01420000;
cslut = 0x01020000;
havevic = 1;
break;
case VAX_STYP_694:
fslut = 0x01440000;
cslut = 0x01040000;
havevic = 1;
break;
}
}
for (; start < fslut; start += 0x20)
mtpr(0, start);
mtpr((mfpr(PR_CCTL) & ~(CCTL_SW_ETM|CCTL_ENABLE)) | CCTL_HW_ETM,
PR_CCTL);
start = 0x01000000;
for (; start < cslut; start += 0x20)
mtpr(0, start);
mtpr(mfpr(PR_CCTL) | 6 | CCTL_ENABLE, PR_CCTL);
start = 0x01800000;
pslut = 0x01802000;
for (; start < pslut; start += 0x20)
mtpr(0, start);
__asm("movpsl -(%sp); movab 1f,-(%sp); rei; 1:;");
mtpr(PCCTL_P_EN|PCCTL_I_EN|PCCTL_D_EN, PR_PCCTL);
if (havevic) {
int slut;
start = 0;
slut = 0x800;
for (; start < slut; start += 0x20) {
mtpr(start, PR_VMAR);
mtpr(0, PR_VTAG);
}
mtpr(ICSR_ENABLE, PR_ICSR);
}
}
void
ka680_hardmem(void *arg)
{
if (cold == 0)
printf("Hard memory error\n");
splhigh();
}
void
ka680_softmem(void *arg)
{
if (cold == 0)
printf("Soft memory error\n");
splhigh();
}
void
ka680_steal_pages(void)
{
scb_vecalloc(0x54, ka680_softmem, NULL, 0, NULL);
scb_vecalloc(0x60, ka680_hardmem, NULL, 0, NULL);
ka680_cache_enable();
}
void
ka680_memerr(void)
{
printf("Memory err!\n");
}
int
ka680_mchk(void *addr)
{
panic("Machine check");
return 0;
}