Home | History | Annotate | Line # | Download | only in bebox
      1 /*	$NetBSD: autoconf.c,v 1.30 2025/10/04 04:16:39 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1990 The Regents of the University of California.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * William Jolitz.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  *
     34  *	@(#)autoconf.c	7.1 (Berkeley) 5/9/91
     35  */
     36 
     37 /*
     38  * Setup the system to run on the current machine.
     39  *
     40  * Configure() is called at boot time and initializes the vba
     41  * device tables and the memory controller monitoring.  Available
     42  * devices are determined (from possibilities mentioned in ioconf.c),
     43  * and the drivers are initialized.
     44  */
     45 
     46 #include <sys/cdefs.h>
     47 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.30 2025/10/04 04:16:39 thorpej Exp $");
     48 
     49 #include <sys/param.h>
     50 #include <sys/systm.h>
     51 #include <sys/buf.h>
     52 #include <sys/disk.h>
     53 #include <sys/disklabel.h>
     54 #include <sys/conf.h>
     55 #include <sys/reboot.h>
     56 #include <sys/device.h>
     57 #include <sys/queue.h>
     58 
     59 #include "pci.h"
     60 #if NPCI > 0
     61 #include <dev/pci/pcireg.h>
     62 #include <dev/pci/pcivar.h>
     63 #endif
     64 #include <dev/ata/atareg.h>
     65 #include <dev/ata/atavar.h>
     66 #include <dev/ata/wdvar.h>
     67 #include <dev/scsipi/sdvar.h>
     68 
     69 #include <machine/bootinfo.h>
     70 #include <machine/pte.h>
     71 #include <machine/intr.h>
     72 
     73 void genppc_cpu_configure(void);
     74 static void findroot(void);
     75 
     76 static int bus, target, lun, drive;
     77 static const char *name = NULL;
     78 
     79 /*
     80  * Determine i/o configuration for a machine.
     81  */
     82 
     83 void
     84 cpu_configure(void)
     85 {
     86 
     87 	findroot();
     88 
     89 	if (config_rootfound("mainbus", NULL) == NULL)
     90 		panic("configure: mainbus not configured");
     91 
     92 	genppc_cpu_configure();
     93 }
     94 
     95 void
     96 cpu_rootconf(void)
     97 {
     98 
     99 	aprint_normal("boot device: %s\n",
    100 	    booted_device ? device_xname(booted_device) : "<unknown>");
    101 
    102 	rootconf();
    103 }
    104 
    105 /*
    106  * Attempt to find the device from which we were booted.
    107  * If we can do so, and not instructed not to do so,
    108  * change rootdev to correspond to the load device.
    109  */
    110 static void
    111 findroot(void)
    112 {
    113 	struct btinfo_rootdevice *rdev;
    114 	int part;
    115 	char *p;
    116 
    117 	target = lun = drive = -1;
    118 
    119 	rdev = (struct btinfo_rootdevice *)lookup_bootinfo(BTINFO_ROOTDEVICE);
    120 	if (rdev == NULL)
    121 		return;
    122 	p = rdev->rootdevice;
    123 	if (strncmp(p, "/dev/disk/", 10) != 0)
    124 		/* unknown device... */
    125 		return;
    126 	p += 10;
    127 	if (strncmp(p, "scsi/", 5) == 0) {
    128 		name = "sd";
    129 		p += 5;
    130 
    131 		if (!isdigit(*(p + 0)) ||
    132 		    !isdigit(*(p + 1)) ||
    133 		    !isdigit(*(p + 2)) ||
    134 		    *(p + 3) != '/')
    135 			return;
    136 		bus = (*p++) - '0';
    137 		target = (*p++) - '0';
    138 		lun = (*p++) - '0';
    139 	} else if (strncmp(p, "ide/", 4) == 0) {
    140 		name = "wd";
    141 		p += 4;
    142 
    143 		bus = (*p++) - '0';
    144 		if (*p++ != '/')
    145 			return;
    146 		if (strncmp(p, "master/", 7) == 0) {
    147 			drive = 0;
    148 			p += 8;
    149 		} else if (strncmp(p, "slave/", 6) == 0) {
    150 			drive = 1;
    151 			p += 7;
    152 		} else
    153 			return;
    154 	} else if (strcmp(p, "floppy") == 0)
    155 		return;
    156 	else
    157 		/* unknown disk... */
    158 		return;
    159 
    160 	if (*(p + 0) != '0' || *(p + 1) != '_' || !isdigit(*(p + 2)))
    161 		return;
    162 	p += 2;
    163 	part = (*p++) - '0';
    164 	if (*p != '\0')
    165 		return;
    166 
    167 	booted_partition = part;
    168 }
    169 
    170 void
    171 device_register(device_t dev, void *aux)
    172 {
    173 	device_t bdev, cdev;
    174 
    175 #if NPCI > 0
    176 	if (device_is_a(dev, "genfb") &&
    177 	    device_is_a(device_parent(dev), "pci")) {
    178 		prop_dictionary_t dict = device_properties(dev);
    179 		struct pci_attach_args *pa = aux;
    180 		pcireg_t bar0;
    181 		uint32_t fbaddr;
    182 
    183 		bar0 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
    184 		fbaddr = PCI_MAPREG_MEM_ADDR(bar0);
    185 
    186 		prop_dictionary_set_bool(dict, "is_console", 1);
    187 		prop_dictionary_set_uint32(dict, "width", 640);
    188 		prop_dictionary_set_uint32(dict, "height", 480);
    189 		prop_dictionary_set_uint32(dict, "depth", 8);
    190 		prop_dictionary_set_uint32(dict, "address", fbaddr);
    191 	}
    192 
    193 	if (device_is_a(dev, "siop") &&
    194 	    device_is_a(device_parent(dev), "pci")) {
    195 		struct pci_attach_args *pa = aux;
    196 		int pbus, device;
    197 
    198 		pci_decompose_tag(pa->pa_pc, pa->pa_tag, &pbus, &device, NULL);
    199 		if (pbus == 0 && device == 12) {
    200 			/* Internal SCSI uses PCI clock as SCSI clock */
    201 			device_setprop_bool(dev, "use_pciclock", true);
    202 		}
    203 	}
    204 #endif
    205 
    206 	if (booted_device != NULL)
    207 		return;
    208 	/*
    209 	 * Check boot device.
    210 	 * It is sd/wd connected by the onboard controller to be supported.
    211 	 */
    212 	if (device_is_a(dev, "sd") && strcmp(name, "sd") == 0) {
    213 		struct scsipibus_attach_args *sa = aux;
    214 
    215 		bdev = device_parent(dev);
    216 		if (!device_is_a(bdev, "scsibus"))
    217 			return;
    218 		cdev = device_parent(bdev);
    219 		if (!device_is_a(cdev, "siop"))
    220 			return;
    221 
    222 		if (sa->sa_periph->periph_target == target &&
    223 		    sa->sa_periph->periph_lun == lun)
    224 			booted_device = dev;
    225 	} else if (device_is_a(dev, "wd") && strcmp(name, "wd") == 0) {
    226 		struct ata_device *adev = aux;
    227 
    228 		bdev = device_parent(dev);
    229 		if (!device_is_a(bdev, "atabus"))
    230 			return;
    231 		cdev = device_parent(bdev);
    232 		if (!device_is_a(cdev, "wdc"))
    233 			return;
    234 		if (!device_is_a(device_parent(cdev), "isa"))
    235 			return;
    236 
    237 		if (adev->adev_drv_data->drive == drive)
    238 			booted_device = dev;
    239 	}
    240 }
    241 
    242