1 /* $OpenBSD: autoconf.c,v 1.109 2023/01/30 10:49:04 jsg Exp $ */ 2 /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * William Jolitz. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)autoconf.c 7.1 (Berkeley) 5/9/91 36 */ 37 38 /* 39 * Setup the system to run on the current machine. 40 * 41 * cpu_configure() is called at boot time and initializes the vba 42 * device tables and the memory controller monitoring. Available 43 * devices are determined (from possibilities mentioned in ioconf.c), 44 * and the drivers are initialized. 45 */ 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/proc.h> 49 #include <sys/user.h> 50 #include <sys/reboot.h> 51 #include <sys/device.h> 52 #include <sys/hibernate.h> 53 54 #include <net/if.h> 55 #include <net/if_types.h> 56 #include <netinet/in.h> 57 #include <netinet/if_ether.h> 58 59 #include <uvm/uvm_extern.h> 60 61 #include <machine/gdt.h> 62 #include <machine/biosvar.h> 63 64 #include "ioapic.h" 65 66 #include "acpi.h" 67 68 #if NIOAPIC > 0 69 #include <machine/i82093var.h> 70 #endif 71 72 #ifdef MULTIPROCESSOR 73 #include <machine/mpbiosvar.h> 74 #endif 75 76 /* 77 * The following several variables are related to 78 * the configuration process, and are used in initializing 79 * the machine. 80 */ 81 extern dev_t bootdev; 82 83 /* Support for VIA C3 RNG */ 84 extern struct timeout viac3_rnd_tmo; 85 extern int viac3_rnd_present; 86 void viac3_rnd(void *); 87 88 extern struct timeout rdrand_tmo; 89 extern int has_rdrand; 90 extern int has_rdseed; 91 void rdrand(void *); 92 93 #ifdef CRYPTO 94 void viac3_crypto_setup(void); 95 extern int i386_has_xcrypt; 96 #endif 97 98 void 99 unmap_startup(void) 100 { 101 extern int kernel_text[], endboot[]; 102 vaddr_t p = (vaddr_t)kernel_text; 103 104 do { 105 pmap_kremove(p, PAGE_SIZE); 106 p += PAGE_SIZE; 107 } while (p < (vaddr_t)endboot); 108 } 109 110 /* 111 * Determine i/o configuration for a machine. 112 */ 113 void 114 cpu_configure(void) 115 { 116 /* 117 * Note, on i386, configure is not running under splhigh unlike other 118 * architectures. This fact is used by the pcmcia irq line probing. 119 */ 120 121 gdt_init(); /* XXX - pcibios uses gdt stuff */ 122 123 /* Set up proc0's TSS */ 124 i386_proc0_tss_init(); 125 126 pmap_bootstrap_pae(); 127 128 #if defined(MULTIPROCESSOR) || \ 129 (NACPI > 0 && !defined(SMALL_KERNEL)) 130 /* install the lowmem ptp after boot args for 1:1 mappings */ 131 pmap_prealloc_lowmem_ptp(); 132 #endif 133 134 #ifdef MULTIPROCESSOR 135 pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE, /* virtual */ 136 (paddr_t)MP_TRAMPOLINE, /* physical */ 137 PROT_READ | PROT_WRITE | PROT_EXEC); /* protection */ 138 pmap_kenter_pa((vaddr_t)MP_TRAMP_DATA, /* virtual */ 139 (paddr_t)MP_TRAMP_DATA, /* physical */ 140 PROT_READ | PROT_WRITE); /* protection */ 141 #endif 142 143 if (config_rootfound("mainbus", NULL) == NULL) 144 panic("cpu_configure: mainbus not configured"); 145 146 #if NIOAPIC > 0 147 ioapic_enable(); 148 #endif 149 150 proc0.p_addr->u_pcb.pcb_cr0 = rcr0(); 151 152 unmap_startup(); 153 154 #ifdef MULTIPROCESSOR 155 /* propagate TSS configuration to the idle pcb's. */ 156 cpu_init_idle_pcbs(); 157 #endif 158 spl0(); 159 160 /* 161 * We can not know which is our root disk, defer 162 * until we can checksum blocks to figure it out. 163 */ 164 cold = 0; 165 166 167 /* 168 * At this point the RNG is running, and if FSXR is set we can 169 * use it. Here we setup a periodic timeout to collect the data. 170 */ 171 if (viac3_rnd_present) { 172 timeout_set(&viac3_rnd_tmo, viac3_rnd, &viac3_rnd_tmo); 173 viac3_rnd(&viac3_rnd_tmo); 174 } 175 if (has_rdrand || has_rdseed) { 176 timeout_set(&rdrand_tmo, rdrand, &rdrand_tmo); 177 rdrand(&rdrand_tmo); 178 } 179 180 #ifdef CRYPTO 181 /* 182 * Also, if the chip has crypto available, enable it. 183 */ 184 if (i386_has_xcrypt) 185 viac3_crypto_setup(); 186 #endif 187 } 188 189 void 190 device_register(struct device *dev, void *aux) 191 { 192 } 193 194 /* 195 * Now that we are fully operational, we can checksum the 196 * disks, and using some heuristics, hopefully are able to 197 * always determine the correct root disk. 198 */ 199 void 200 diskconf(void) 201 { 202 int majdev, unit, part = 0; 203 struct device *bootdv = NULL; 204 dev_t tmpdev; 205 char buf[128]; 206 extern bios_bootmac_t *bios_bootmac; 207 208 dkcsumattach(); 209 210 if ((bootdev & B_MAGICMASK) == (u_int)B_DEVMAGIC) { 211 majdev = B_TYPE(bootdev); 212 unit = B_UNIT(bootdev); 213 part = B_PARTITION(bootdev); 214 snprintf(buf, sizeof buf, "%s%d%c", findblkname(majdev), 215 unit, part + 'a'); 216 bootdv = parsedisk(buf, strlen(buf), part, &tmpdev); 217 } 218 219 if (bios_bootmac) { 220 struct ifnet *ifp; 221 222 TAILQ_FOREACH(ifp, &ifnetlist, if_list) { 223 if (ifp->if_type == IFT_ETHER && 224 memcmp(bios_bootmac->mac, 225 ((struct arpcom *)ifp)->ac_enaddr, 226 ETHER_ADDR_LEN) == 0) 227 break; 228 } 229 if (ifp) { 230 printf("PXE boot MAC address %s, interface %s\n", 231 ether_sprintf(bios_bootmac->mac), ifp->if_xname); 232 #if defined(NFSCLIENT) 233 bootdv = parsedisk(ifp->if_xname, strlen(ifp->if_xname), 234 0, &tmpdev); 235 part = 0; 236 #endif 237 } else 238 printf("PXE boot MAC address %s, interface %s\n", 239 ether_sprintf(bios_bootmac->mac), "unknown"); 240 } 241 242 setroot(bootdv, part, RB_USERREQ); 243 dumpconf(); 244 245 #ifdef HIBERNATE 246 hibernate_resume(); 247 #endif /* HIBERNATE */ 248 } 249 250 const struct nam2blk nam2blk[] = { 251 { "wd", 0 }, 252 { "fd", 2 }, 253 { "sd", 4 }, 254 { "cd", 6 }, 255 { "vnd", 14 }, 256 { "rd", 17 }, 257 { NULL, -1 } 258 }; 259