xref: /netbsd-src/sys/arch/xen/x86/autoconf.c (revision 4a96dd4fc2b02adf9af17780aaa72447a29ac609)
1*4a96dd4fSbouyer /*	$NetBSD: autoconf.c,v 1.26 2023/10/17 12:07:42 bouyer Exp $	*/
24e541343Sbouyer /*	NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp 	*/
34e541343Sbouyer 
44e541343Sbouyer /*-
54e541343Sbouyer  * Copyright (c) 1990 The Regents of the University of California.
64e541343Sbouyer  * All rights reserved.
74e541343Sbouyer  *
84e541343Sbouyer  * This code is derived from software contributed to Berkeley by
94e541343Sbouyer  * William Jolitz.
104e541343Sbouyer  *
114e541343Sbouyer  * Redistribution and use in source and binary forms, with or without
124e541343Sbouyer  * modification, are permitted provided that the following conditions
134e541343Sbouyer  * are met:
144e541343Sbouyer  * 1. Redistributions of source code must retain the above copyright
154e541343Sbouyer  *    notice, this list of conditions and the following disclaimer.
164e541343Sbouyer  * 2. Redistributions in binary form must reproduce the above copyright
174e541343Sbouyer  *    notice, this list of conditions and the following disclaimer in the
184e541343Sbouyer  *    documentation and/or other materials provided with the distribution.
194e541343Sbouyer  * 3. Neither the name of the University nor the names of its contributors
204e541343Sbouyer  *    may be used to endorse or promote products derived from this software
214e541343Sbouyer  *    without specific prior written permission.
224e541343Sbouyer  *
234e541343Sbouyer  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
244e541343Sbouyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
254e541343Sbouyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
264e541343Sbouyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
274e541343Sbouyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
284e541343Sbouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
294e541343Sbouyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
304e541343Sbouyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
314e541343Sbouyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
324e541343Sbouyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
334e541343Sbouyer  * SUCH DAMAGE.
344e541343Sbouyer  *
354e541343Sbouyer  *	@(#)autoconf.c	7.1 (Berkeley) 5/9/91
364e541343Sbouyer  */
374e541343Sbouyer 
384e541343Sbouyer /*
394e541343Sbouyer  * Setup the system to run on the current machine.
404e541343Sbouyer  *
414e541343Sbouyer  * Configure() is called at boot time and initializes the vba
424e541343Sbouyer  * device tables and the memory controller monitoring.  Available
434e541343Sbouyer  * devices are determined (from possibilities mentioned in ioconf.c),
444e541343Sbouyer  * and the drivers are initialized.
454e541343Sbouyer  */
464e541343Sbouyer 
474e541343Sbouyer #include <sys/cdefs.h>
48*4a96dd4fSbouyer __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.26 2023/10/17 12:07:42 bouyer Exp $");
494e541343Sbouyer 
504e541343Sbouyer #include "opt_xen.h"
514e541343Sbouyer #include "opt_multiprocessor.h"
524e541343Sbouyer #include "opt_nfs_boot.h"
534e541343Sbouyer 
544e541343Sbouyer #include <sys/param.h>
554e541343Sbouyer #include <sys/systm.h>
564e541343Sbouyer #include <sys/buf.h>
574e541343Sbouyer #include <sys/disklabel.h>
584e541343Sbouyer #include <sys/disk.h>
594e541343Sbouyer #include <sys/conf.h>
604e541343Sbouyer #include <sys/device.h>
614e541343Sbouyer #include <sys/vnode.h>
624e541343Sbouyer #include <sys/fcntl.h>
634e541343Sbouyer #include <sys/dkio.h>
644e541343Sbouyer #include <sys/proc.h>
654e541343Sbouyer #include <sys/kauth.h>
664e541343Sbouyer 
674e541343Sbouyer #ifdef NFS_BOOT_BOOTSTATIC
684e541343Sbouyer #include <net/if.h>
694e541343Sbouyer #include <net/if_ether.h>
704e541343Sbouyer #include <netinet/in.h>
714e541343Sbouyer #include <nfs/rpcv2.h>
724e541343Sbouyer #include <nfs/nfsproto.h>
734e541343Sbouyer #include <nfs/nfs.h>
744e541343Sbouyer #include <nfs/nfsmount.h>
754e541343Sbouyer #include <nfs/nfsdiskless.h>
764e541343Sbouyer #include <xen/if_xennetvar.h>
774e541343Sbouyer #endif
784e541343Sbouyer 
794e541343Sbouyer #include <machine/pte.h>
804e541343Sbouyer #include <machine/cpu.h>
814e541343Sbouyer #include <machine/gdt.h>
824e541343Sbouyer #include <machine/pcb.h>
834e541343Sbouyer #include <machine/bootinfo.h>
844e541343Sbouyer 
85*4a96dd4fSbouyer #include <x86/autoconf.h>
86*4a96dd4fSbouyer 
874e541343Sbouyer struct disklist *x86_alldisks;
884e541343Sbouyer int x86_ndisks;
8913deebddSnonaka int x86_found_console;
904e541343Sbouyer 
914e541343Sbouyer #include "bios32.h"
924e541343Sbouyer #if NBIOS32 > 0
934e541343Sbouyer #include <machine/bios32.h>
94b38f39aeSnonaka /* XXX */
95b38f39aeSnonaka extern void platform_init(void);
964e541343Sbouyer #endif
974e541343Sbouyer 
984e541343Sbouyer #include "opt_pcibios.h"
994e541343Sbouyer #ifdef PCIBIOS
1004e541343Sbouyer #include <dev/pci/pcireg.h>
1014e541343Sbouyer #include <dev/pci/pcivar.h>
1024e541343Sbouyer #include <i386/pci/pcibios.h>
1034e541343Sbouyer #endif
1044e541343Sbouyer 
1054e209382Sbad #ifdef DEBUG_GEOM
1064e209382Sbad #define DPRINTF(a) printf a
1074e209382Sbad #else
1084e209382Sbad #define DPRINTF(a)
1094e209382Sbad #endif
1104e209382Sbad 
1114e541343Sbouyer /*
1124e541343Sbouyer  * Determine i/o configuration for a machine.
1134e541343Sbouyer  */
1144e541343Sbouyer void
cpu_configure(void)1154e541343Sbouyer cpu_configure(void)
1164e541343Sbouyer {
117448807faSrmind 	struct pcb *pcb;
1184e541343Sbouyer 
119d5c9d50fSbouyer 	xen_startrtclock();
1204e541343Sbouyer 
121b38f39aeSnonaka #if defined(DOM0OPS)
122b38f39aeSnonaka 	if (xendomain_is_dom0()) {
123b38f39aeSnonaka #if NBIOS32 > 0
1244e541343Sbouyer 		bios32_init();
125b38f39aeSnonaka 		platform_init();
126b38f39aeSnonaka 		/* identify hypervisor type from SMBIOS */
127b38f39aeSnonaka 		identify_hypervisor();
128b38f39aeSnonaka #endif /* NBIOS32 > 0 */
129c24c993fSbouyer 	}
130b38f39aeSnonaka #endif /* DOM0OPS */
1314e541343Sbouyer #ifdef PCIBIOS
1324e541343Sbouyer 	pcibios_init();
1334e541343Sbouyer #endif
1344e541343Sbouyer 
1354e541343Sbouyer 	if (config_rootfound("mainbus", NULL) == NULL)
1364e541343Sbouyer 		panic("configure: mainbus not configured");
1374e541343Sbouyer 
1384e541343Sbouyer #ifdef INTRDEBUG
1394e541343Sbouyer 	intr_printconfig();
1404e541343Sbouyer #endif
1414e541343Sbouyer 
1423355a42fScherry #if NIOAPIC > 0
1433355a42fScherry 	ioapic_enable();
1443355a42fScherry #endif
1454e541343Sbouyer 	/* resync cr0 after FPU configuration */
146448807faSrmind 	pcb = lwp_getpcb(&lwp0);
147448807faSrmind 	pcb->pcb_cr0 = rcr0();
1484e541343Sbouyer #ifdef MULTIPROCESSOR
1494e541343Sbouyer 	/* propagate this to the idle pcb's. */
1504e541343Sbouyer 	cpu_init_idle_lwps();
1514e541343Sbouyer #endif
1524e541343Sbouyer 
1534e541343Sbouyer 	spl0();
1544e541343Sbouyer }
1554e541343Sbouyer 
1564e541343Sbouyer void
cpu_rootconf(void)1574e541343Sbouyer cpu_rootconf(void)
1584e541343Sbouyer {
1599c96bd6bSchristos 	cpu_bootconf();
1604e541343Sbouyer 
1614e541343Sbouyer 	printf("boot device: %s\n",
162138fd134Smlelstv 	    booted_device ? device_xname(booted_device) :
163138fd134Smlelstv 	    bootspec ? bootspec : "<unknown>");
1648ce44338Smlelstv 	rootconf();
1654e541343Sbouyer }
1664e541343Sbouyer 
1674e541343Sbouyer 
1684e541343Sbouyer /*
1694e541343Sbouyer  * Attempt to find the device from which we were booted.
1704e541343Sbouyer  */
1714e541343Sbouyer void
cpu_bootconf(void)1729c96bd6bSchristos cpu_bootconf(void)
1734e541343Sbouyer {
174d5c9d50fSbouyer 	xen_bootconf();
1754e209382Sbad }
1764e541343Sbouyer #include "pci.h"
1774e541343Sbouyer 
1784e541343Sbouyer #include <dev/isa/isavar.h>
1794e541343Sbouyer #if NPCI > 0
1804e541343Sbouyer #include <dev/pci/pcivar.h>
1814e541343Sbouyer #endif
1824e541343Sbouyer 
1834e541343Sbouyer 
1844e541343Sbouyer #if defined(NFS_BOOT_BOOTSTATIC) && defined(DOM0OPS)
1854e541343Sbouyer static int
dom0_bootstatic_callback(struct nfs_diskless * nd)1864e541343Sbouyer dom0_bootstatic_callback(struct nfs_diskless *nd)
1874e541343Sbouyer {
1884e541343Sbouyer #if 0
1894e541343Sbouyer 	struct ifnet *ifp = nd->nd_ifp;
1904e541343Sbouyer #endif
191c4798840Scegger 	int flags = 0;
1924e541343Sbouyer 	union xen_cmdline_parseinfo xcp;
1934e541343Sbouyer 	struct sockaddr_in *sin;
1944e541343Sbouyer 
1954e541343Sbouyer 	memset(&xcp, 0, sizeof(xcp.xcp_netinfo));
1964e541343Sbouyer 	xcp.xcp_netinfo.xi_ifno = 0; /* XXX first interface hardcoded */
1974e541343Sbouyer 	xcp.xcp_netinfo.xi_root = nd->nd_root.ndm_host;
1984e541343Sbouyer 	xen_parse_cmdline(XEN_PARSE_NETINFO, &xcp);
1994e541343Sbouyer 
200c4798840Scegger 	if (xcp.xcp_netinfo.xi_root[0] != '\0') {
201c4798840Scegger 		flags |= NFS_BOOT_HAS_SERVER;
202c4798840Scegger 		if (strchr(xcp.xcp_netinfo.xi_root, ':') != NULL)
203c4798840Scegger 			flags |= NFS_BOOT_HAS_ROOTPATH;
204c4798840Scegger 	}
205c4798840Scegger 
2064e541343Sbouyer 	nd->nd_myip.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[0]);
2074e541343Sbouyer 	nd->nd_gwip.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[2]);
2084e541343Sbouyer 	nd->nd_mask.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[3]);
2094e541343Sbouyer 
2104e541343Sbouyer 	sin = (struct sockaddr_in *) &nd->nd_root.ndm_saddr;
2114e541343Sbouyer 	memset((void *)sin, 0, sizeof(*sin));
2124e541343Sbouyer 	sin->sin_len = sizeof(*sin);
2134e541343Sbouyer 	sin->sin_family = AF_INET;
2144e541343Sbouyer 	sin->sin_addr.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[1]);
2154e541343Sbouyer 
216c4798840Scegger 	if (nd->nd_myip.s_addr)
217c4798840Scegger 		flags |= NFS_BOOT_HAS_MYIP;
218c4798840Scegger 	if (nd->nd_gwip.s_addr)
219c4798840Scegger 		flags |= NFS_BOOT_HAS_GWIP;
220c4798840Scegger 	if (nd->nd_mask.s_addr)
221c4798840Scegger 		flags |= NFS_BOOT_HAS_MASK;
222c4798840Scegger 	if (sin->sin_addr.s_addr)
223c4798840Scegger 		flags |= NFS_BOOT_HAS_SERVADDR;
224c4798840Scegger 
225c4798840Scegger 	return flags;
2264e541343Sbouyer }
2274e541343Sbouyer #endif
2284e541343Sbouyer 
2294e541343Sbouyer void
device_register(device_t dev,void * aux)2307f01a821Scegger device_register(device_t dev, void *aux)
2314e541343Sbouyer {
232*4a96dd4fSbouyer 	device_t isaboot, pciboot;
233*4a96dd4fSbouyer 	device_t found = NULL;
234*4a96dd4fSbouyer 
235*4a96dd4fSbouyer 	isaboot = device_isa_register(dev, aux);
236*4a96dd4fSbouyer 	pciboot = device_pci_register(dev, aux);
237*4a96dd4fSbouyer 
2384e541343Sbouyer 	/*
2394e541343Sbouyer 	 * Handle network interfaces here, the attachment information is
2404e541343Sbouyer 	 * not available driver independently later.
2414e541343Sbouyer 	 * For disks, there is nothing useful available at attach time.
2424e541343Sbouyer 	 */
2434e541343Sbouyer #if NXENNET_HYPERVISOR > 0 || NXENNET_XENBUS > 0 || defined(DOM0OPS)
2444e541343Sbouyer 	if (device_class(dev) == DV_IFNET) {
2454e541343Sbouyer 		union xen_cmdline_parseinfo xcp;
2464e541343Sbouyer 
2474e541343Sbouyer #ifdef NFS_BOOT_BOOTSTATIC
2484e541343Sbouyer #ifdef DOM0OPS
2492de31871Scegger 		if (xendomain_is_privileged()) {
2504e541343Sbouyer 			nfs_bootstatic_callback = dom0_bootstatic_callback;
2514e541343Sbouyer 		} else
2524e541343Sbouyer #endif
2534e541343Sbouyer #if NXENNET_HYPERVISOR > 0 || NXENNET_XENBUS > 0
2544e541343Sbouyer 		nfs_bootstatic_callback = xennet_bootstatic_callback;
2554e541343Sbouyer #endif
2564e541343Sbouyer #endif
25717fa4af4Scegger 		xen_parse_cmdline(XEN_PARSE_BOOTDEV, &xcp);
25817fa4af4Scegger 		if (strncmp(xcp.xcp_bootdev, device_xname(dev),
25917fa4af4Scegger 		    sizeof(xcp.xcp_bootdev)) == 0)
26017fa4af4Scegger 		{
261*4a96dd4fSbouyer 			found = dev;
2624e541343Sbouyer 		}
2634e541343Sbouyer 	}
2644e541343Sbouyer #endif
265*4a96dd4fSbouyer 	if (found == NULL) {
266*4a96dd4fSbouyer 		if (isaboot != NULL)
267*4a96dd4fSbouyer 			found = isaboot;
268*4a96dd4fSbouyer 		else if (pciboot != NULL)
269*4a96dd4fSbouyer 			found = pciboot;
2704e541343Sbouyer 	}
2714e541343Sbouyer 
272*4a96dd4fSbouyer 	if (found) {
2734e541343Sbouyer 		if (booted_device) {
2744e541343Sbouyer 			/* XXX should be a "panic()" */
2754e541343Sbouyer 			printf("warning: double match for boot device (%s, %s)\n",
276f5bd7c21Scegger 			    device_xname(booted_device), device_xname(dev));
2774e541343Sbouyer 			return;
2784e541343Sbouyer 		}
279*4a96dd4fSbouyer 		booted_device = found;
280*4a96dd4fSbouyer 		booted_method = "device/register";
281*4a96dd4fSbouyer 	}
2824e541343Sbouyer }
283