#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ka49.c,v 1.20 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/clock.h>
#include <machine/scb.h>
#include <machine/mainbus.h>
#define KA49_CPMBX 0x38
#define KA49_HLT_HALT 0xcf
#define KA49_HLT_BOOT 0x8b
static void ka49_conf(void);
static void ka49_memerr(void);
static int ka49_mchk(void *);
static void ka49_halt(void);
static void ka49_reboot(int);
static void ka49_softmem(void *);
static void ka49_hardmem(void *);
static void ka49_steal_pages(void);
static void ka49_cache_enable(void);
static void ka49_halt(void);
static const char * const ka49_devs[] = { "cpu", "sgec", "vsbus", NULL };
const struct cpu_dep ka49_calls = {
.cpu_steal_pages = ka49_steal_pages,
.cpu_mchk = ka49_mchk,
.cpu_memerr = ka49_memerr,
.cpu_conf = ka49_conf,
.cpu_gettime = chip_gettime,
.cpu_settime = chip_settime,
.cpu_vups = 32,
.cpu_scbsz = 2,
.cpu_halt = ka49_halt,
.cpu_reboot = ka49_reboot,
.cpu_devs = ka49_devs,
.cpu_flags = CPU_RAISEIPL,
};
void
ka49_conf(void)
{
curcpu()->ci_cpustr = "KA49, NVAX, 10KB L1 cache, 256KB L2 cache";
{ volatile int *hej = (void *)mfpr(PR_ISP); *hej = *hej; hej[-1] = hej[-1];}
clk_adrshift = 1;
clk_tweak = 2;
clk_page = (short *)vax_map_physmem(0x25400000, 1);
}
void
ka49_hardmem(void *arg)
{
if (cold == 0)
printf("Hard memory error\n");
splhigh();
}
void
ka49_softmem(void *arg)
{
if (cold == 0)
printf("Soft memory error\n");
splhigh();
}
#define PR_CCTL 0xa0
#define CCTL_ENABLE 0x00000001
#define CCTL_SSIZE 0x00000002
#define CCTL_VSIZE 0x00000004
#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
void
ka49_cache_enable(void)
{
int start, slut;
mtpr(0, PR_ICSR);
mtpr(0, PR_PCCTL);
mtpr(mfpr(PR_CCTL) | CCTL_SW_ETM, PR_CCTL);
mtpr(mfpr(PR_CCTL) | 0x10, PR_CCTL);
mtpr(mfpr(PR_BCETSTS), PR_BCETSTS);
mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS);
mtpr(mfpr(PR_NESTS), PR_NESTS);
start = 0x01400000;
slut = 0x01440000;
for (; start < slut; start += 0x20)
mtpr(0, start);
mtpr((mfpr(PR_CCTL) & ~(CCTL_SW_ETM|CCTL_ENABLE)) | CCTL_HW_ETM,
PR_CCTL);
start = 0x01000000;
slut = 0x01040000;
for (; start < slut; start += 0x20)
mtpr(0, start);
mtpr(mfpr(PR_CCTL) | 0x10 | CCTL_ENABLE, PR_CCTL);
start = 0x01800000;
slut = 0x01802000;
for (; start < slut; 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);
start = 0;
slut = 0x800;
for (; start < slut; start += 0x20) {
mtpr(start, PR_VMAR);
mtpr(0, PR_VTAG);
}
mtpr(ICSR_ENABLE, PR_ICSR);
}
void
ka49_memerr(void)
{
printf("Memory err!\n");
}
int
ka49_mchk(void *addr)
{
panic("Machine check");
return 0;
}
void
ka49_steal_pages(void)
{
scb_vecalloc(0x54, ka49_softmem, NULL, 0, NULL);
scb_vecalloc(0x60, ka49_hardmem, NULL, 0, NULL);
ka49_cache_enable();
}
void
ka49_halt(void)
{
((volatile uint8_t *) clk_page)[KA49_CPMBX] = KA49_HLT_HALT;
__asm("halt");
}
void
ka49_reboot(int arg)
{
((volatile uint8_t *) clk_page)[KA49_CPMBX] = KA49_HLT_BOOT;
__asm("halt");
}