#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.30 2025/10/04 04:16:39 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/conf.h>
#include <sys/reboot.h>
#include <sys/device.h>
#include <sys/queue.h>
#include "pci.h"
#if NPCI > 0
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#endif
#include <dev/ata/atareg.h>
#include <dev/ata/atavar.h>
#include <dev/ata/wdvar.h>
#include <dev/scsipi/sdvar.h>
#include <machine/bootinfo.h>
#include <machine/pte.h>
#include <machine/intr.h>
void genppc_cpu_configure(void);
static void findroot(void);
static int bus, target, lun, drive;
static const char *name = NULL;
void
cpu_configure(void)
{
findroot();
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");
genppc_cpu_configure();
}
void
cpu_rootconf(void)
{
aprint_normal("boot device: %s\n",
booted_device ? device_xname(booted_device) : "<unknown>");
rootconf();
}
static void
findroot(void)
{
struct btinfo_rootdevice *rdev;
int part;
char *p;
target = lun = drive = -1;
rdev = (struct btinfo_rootdevice *)lookup_bootinfo(BTINFO_ROOTDEVICE);
if (rdev == NULL)
return;
p = rdev->rootdevice;
if (strncmp(p, "/dev/disk/", 10) != 0)
return;
p += 10;
if (strncmp(p, "scsi/", 5) == 0) {
name = "sd";
p += 5;
if (!isdigit(*(p + 0)) ||
!isdigit(*(p + 1)) ||
!isdigit(*(p + 2)) ||
*(p + 3) != '/')
return;
bus = (*p++) - '0';
target = (*p++) - '0';
lun = (*p++) - '0';
} else if (strncmp(p, "ide/", 4) == 0) {
name = "wd";
p += 4;
bus = (*p++) - '0';
if (*p++ != '/')
return;
if (strncmp(p, "master/", 7) == 0) {
drive = 0;
p += 8;
} else if (strncmp(p, "slave/", 6) == 0) {
drive = 1;
p += 7;
} else
return;
} else if (strcmp(p, "floppy") == 0)
return;
else
return;
if (*(p + 0) != '0' || *(p + 1) != '_' || !isdigit(*(p + 2)))
return;
p += 2;
part = (*p++) - '0';
if (*p != '\0')
return;
booted_partition = part;
}
void
device_register(device_t dev, void *aux)
{
device_t bdev, cdev;
#if NPCI > 0
if (device_is_a(dev, "genfb") &&
device_is_a(device_parent(dev), "pci")) {
prop_dictionary_t dict = device_properties(dev);
struct pci_attach_args *pa = aux;
pcireg_t bar0;
uint32_t fbaddr;
bar0 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
fbaddr = PCI_MAPREG_MEM_ADDR(bar0);
prop_dictionary_set_bool(dict, "is_console", 1);
prop_dictionary_set_uint32(dict, "width", 640);
prop_dictionary_set_uint32(dict, "height", 480);
prop_dictionary_set_uint32(dict, "depth", 8);
prop_dictionary_set_uint32(dict, "address", fbaddr);
}
if (device_is_a(dev, "siop") &&
device_is_a(device_parent(dev), "pci")) {
struct pci_attach_args *pa = aux;
int pbus, device;
pci_decompose_tag(pa->pa_pc, pa->pa_tag, &pbus, &device, NULL);
if (pbus == 0 && device == 12) {
device_setprop_bool(dev, "use_pciclock", true);
}
}
#endif
if (booted_device != NULL)
return;
if (device_is_a(dev, "sd") && strcmp(name, "sd") == 0) {
struct scsipibus_attach_args *sa = aux;
bdev = device_parent(dev);
if (!device_is_a(bdev, "scsibus"))
return;
cdev = device_parent(bdev);
if (!device_is_a(cdev, "siop"))
return;
if (sa->sa_periph->periph_target == target &&
sa->sa_periph->periph_lun == lun)
booted_device = dev;
} else if (device_is_a(dev, "wd") && strcmp(name, "wd") == 0) {
struct ata_device *adev = aux;
bdev = device_parent(dev);
if (!device_is_a(bdev, "atabus"))
return;
cdev = device_parent(bdev);
if (!device_is_a(cdev, "wdc"))
return;
if (!device_is_a(device_parent(cdev), "isa"))
return;
if (adev->adev_drv_data->drive == drive)
booted_device = dev;
}
}