#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.80 2012/10/13 06:51:22 tsutsui Exp $");
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/reboot.h>
#include <sys/systm.h>
#include <pmax/autoconf.h>
#include <pmax/sysconf.h>
#include <pmax/pmax/pmaxtype.h>
#include <dev/tc/tcvar.h>
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsipi_all.h>
#include <dev/scsipi/scsiconf.h>
#include "opt_dec_3100.h"
#include "opt_dec_5100.h"
struct intrhand intrtab[MAX_DEV_NCOOKIES];
static device_t booted_controller;
static int booted_slot, booted_unit;
static const char *booted_protocol;
void
cpu_configure(void)
{
(void)splhigh();
intr_init();
if (config_rootfound("mainbus", NULL) == NULL)
panic("no mainbus found");
(*platform.bus_reset)();
spl0();
}
void
makebootdev(char *cp)
{
booted_device = NULL;
booted_slot = booted_unit = booted_partition = 0;
booted_protocol = NULL;
#if defined(DEC_3100) || defined(DEC_5100)
if (cp[0] == 'r' && cp[1] == 'z' && cp[2] == '(') {
cp += 3;
if (*cp >= '0' && *cp <= '9')
booted_slot = *cp++ - '0';
if (*cp == ',')
cp += 1;
if (*cp >= '0' && *cp <= '9')
booted_unit = *cp++ - '0';
if (*cp == ',')
cp += 1;
if (*cp >= '0' && *cp <= '9')
booted_partition = *cp - '0';
booted_protocol = "SCSI";
return;
}
if (strncmp(cp, "tftp(", 5) == 0) {
booted_protocol = "BOOTP";
return;
}
if (strncmp(cp, "mop(", 4) == 0) {
booted_protocol = "MOP";
return;
}
#endif
if (cp[0] >= '0' && cp[0] <= '9' && cp[1] == '/') {
booted_slot = cp[0] - '0';
if (cp[2] == 'r' && cp[3] == 'z'
&& cp[4] >= '0' && cp[4] <= '9') {
booted_protocol = "SCSI";
booted_unit = cp[4] - '0';
}
else if (strncmp(cp+2, "tftp", 4) == 0)
booted_protocol = "BOOTP";
else if (strncmp(cp+2, "mop", 3) == 0)
booted_protocol = "MOP";
}
}
void
cpu_rootconf(void)
{
printf("boot device: %s\n",
booted_device ? device_xname(booted_device) : "<unknown>");
rootconf();
}
void
device_register(device_t dev, void *aux)
{
static int found, initted, scsiboot, netboot;
static device_t ioasicdev;
device_t parent = device_parent(dev);
if (found)
return;
if (!initted) {
scsiboot = strcmp(booted_protocol, "SCSI") == 0;
netboot = (strcmp(booted_protocol, "BOOTP") == 0) ||
(strcmp(booted_protocol, "MOP") == 0);
initted = 1;
}
if (device_is_a(dev, "ioasic")) {
struct tc_attach_args *ta = aux;
if (ta->ta_slot == booted_slot)
ioasicdev = dev;
return;
}
if (scsiboot && device_is_a(dev, "asc")) {
struct tc_attach_args *ta = aux;
if (parent == ioasicdev ||
ta->ta_slot == booted_slot) {
booted_controller = dev;
return;
}
}
if (scsiboot && device_is_a(dev, "sii")) {
booted_controller = dev;
return;
}
if (booted_controller &&
(device_is_a(dev, "sd") ||
device_is_a(dev, "st") ||
device_is_a(dev, "cd"))) {
struct scsipibus_attach_args *sa = aux;
if (device_parent(parent) != booted_controller)
return;
if (booted_unit != sa->sa_periph->periph_target)
return;
booted_device = dev;
found = 1;
return;
}
if (netboot) {
struct tc_attach_args *ta = aux;
if ((
#if defined(DEC_3100) || defined(DEC_5100)
systype == DS_PMAX || systype == DS_MIPSMATE ||
#endif
parent == ioasicdev)
&& device_is_a(dev, "le")) {
booted_device = dev;
found = 1;
return;
}
if (device_class(dev) == DV_IFNET &&
device_is_a(parent, "tc") &&
ta->ta_slot == booted_slot) {
booted_device = dev;
found = 1;
return;
}
}
}