#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/reboot.h>
#include <machine/autoconf.h>
#define DUID_SIZE 8
extern void dumpconf(void);
int parseduid(const char *, u_char *);
void parsepmonbp(void);
int cold = 1;
struct device *bootdv = NULL;
char bootdev[16];
enum devclass bootdev_class = DV_DULL;
extern char pmon_bootp[];
void
cpu_configure(void)
{
(void)splhigh();
softintr_init();
(void)config_rootfound("mainbus", NULL);
unmap_startup();
splinit();
cold = 0;
}
void
parsepmonbp(void)
{
char *p = NULL;
char *q;
size_t len = 0;
if (strncmp(pmon_bootp, "tftp://", 7) == 0) {
bootdev_class = DV_IFNET;
strlcpy(bootdev, "netboot", sizeof bootdev);
return;
}
strlcpy(bootdev, "unknown", sizeof bootdev);
if (strncmp(pmon_bootp, "/dev/disk/", 10) == 0) {
p = pmon_bootp + 10;
len = strlen(p);
} else if (strncmp(pmon_bootp, "bootduid=", 9) == 0) {
if (parseduid(pmon_bootp + 9, bootduid) != 0)
return;
} else {
p = strchr(pmon_bootp, '@');
if (p == NULL)
return;
p++;
q = strchr(p, '/');
if (q == NULL)
return;
len = q - p;
}
if (len <= 2 || len >= sizeof bootdev - 1)
return;
memcpy(bootdev, p, len);
bootdev[len] = '\0';
bootdev_class = DV_DISK;
}
static unsigned int
parsehex(int c)
{
if (c >= 'a')
return c - 'a' + 10;
else
return c - '0';
}
int
parseduid(const char *str, u_char *duid)
{
int i;
for (i = 0; i < DUID_SIZE * 2; i++) {
if (!(str[i] >= '0' && str[i] <= '9') &&
!(str[i] >= 'a' && str[i] <= 'f'))
return -1;
}
if (str[DUID_SIZE * 2] != '\0')
return -1;
for (i = 0; i < DUID_SIZE; i++) {
duid[i] = parsehex(str[i * 2]) * 0x10 +
parsehex(str[i * 2 + 1]);
}
return 0;
}
void
diskconf(void)
{
if (*pmon_bootp != '\0')
printf("pmon bootpath: %s\n", pmon_bootp);
if (bootdv != NULL)
printf("boot device: %s\n", bootdv->dv_xname);
setroot(bootdv, 0, RB_USERREQ);
dumpconf();
}
void
device_register(struct device *dev, void *aux)
{
if (bootdv != NULL)
return;
(*sys_platform->device_register)(dev, aux);
}
const struct nam2blk nam2blk[] = {
{ "sd", 0 },
{ "vnd", 2 },
{ "cd", 3 },
{ "wd", 4 },
{ "rd", 8 },
{ NULL, -1 }
};