#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.28 2023/02/03 23:13:01 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/reboot.h>
#include <sys/device.h>
#include <machine/vmparam.h>
#include <machine/autoconf.h>
#include <machine/disklabel.h>
#include <machine/cpu.h>
#include <machine/pte.h>
#include <next68k/next68k/isr.h>
#include <next68k/next68k/nextrom.h>
#include <next68k/dev/intiovar.h>
volatile u_long *intrstat;
volatile u_long *intrmask;
static device_t getdevunit(const char *, int);
static int devidentparse(const char *, int *, int *, int *);
static int atoi(const char *);
struct device_equiv {
const char *alias;
const char *real;
};
static struct device_equiv device_equiv[] = {
{ "en", "xe" },
{ "tp", "xe" },
};
static int ndevice_equivs = (sizeof(device_equiv)/sizeof(device_equiv[0]));
void
cpu_configure(void)
{
extern u_int rom_intrmask;
extern u_int rom_intrstat;
booted_device = NULL;
isrinit();
#if 0
dma_rev = ((volatile u_char *)IIOV(NEXT_P_SCR1))[1];
switch (dma_rev) {
case 0:
intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK_0);
intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT_0);
break;
case 1:
intrmask = (volatile u_long *)IIOV(NEXT_P_INTRMASK);
intrstat = (volatile u_long *)IIOV(NEXT_P_INTRSTAT);
break;
default:
panic("unknown DMA chip revision");
}
#else
intrmask = (volatile u_long *)IIOV(rom_intrmask);
intrstat = (volatile u_long *)IIOV(rom_intrstat);
printf ("intrmask: %p\n", intrmask);
printf ("intrstat: %p\n", intrstat);
#endif
INTR_SETMASK(0);
if (config_rootfound("mainbus", NULL) == NULL)
panic("autoconfig failed, no root");
spl0();
}
void
cpu_rootconf(void)
{
int count, lun, part;
count = lun = part = 0;
devidentparse (rom_boot_info, &count, &lun, &part);
booted_device = getdevunit (rom_boot_dev, count);
printf("boot device: %s\n",
(booted_device) ? device_xname(booted_device) : "<unknown>");
rootconf();
}
static device_t
getdevunit(const char *name, int unit)
{
int i;
for (i = 0; i < ndevice_equivs; i++)
if (device_equiv->alias &&
strcmp(name, device_equiv->alias) == 0)
name = device_equiv->real;
return device_find_by_driver_unit(name, unit);
}
static int
devidentparse(const char *spec, int *count, int *lun, int *part)
{
int i;
const char *args[3];
if (*spec == '(') {
args[0] = ++spec;
for (i = 1; *spec && *spec != ')' && i < 3; spec++) {
if (*spec == ',')
args[i++] = ++spec;
}
if (*spec != ')')
goto baddev;
switch(i) {
case 3:
*count = atoi(args[0]);
*lun = atoi(args[1]);
*part = atoi(args[2]);
break;
case 2:
*lun = atoi(args[0]);
*part = atoi(args[1]);
break;
case 1:
*part = atoi(args[0]);
break;
case 0:
break;
}
} else
goto baddev;
return 0;
baddev:
return ENXIO;
}
static int
atoi(const char *s)
{
int val = 0;
while (isdigit(*s))
val = val * 10 + (*s++ - '0');
return val;
}