1 /* $OpenBSD: mainbus.c,v 1.59 2019/01/18 01:34:50 pd Exp $ */ 2 /* $NetBSD: mainbus.c,v 1.21 1997/06/06 23:14:20 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Christopher G. Demetriou 18 * for the NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/device.h> 37 38 #include <machine/bus.h> 39 #include <machine/specialreg.h> 40 41 #include <dev/isa/isavar.h> 42 #include <dev/eisa/eisavar.h> 43 #include <dev/pci/pcivar.h> 44 45 #include <dev/isa/isareg.h> /* for IOM_BEGIN */ 46 #include <i386/isa/isa_machdep.h> 47 48 #include "pci.h" 49 #include "eisa.h" 50 #include "isa.h" 51 #include "apm.h" 52 #include "bios.h" 53 #include "acpi.h" 54 #include "ipmi.h" 55 #include "esm.h" 56 #include "amdmsr.h" 57 #include "pvbus.h" 58 59 #include <machine/cpuvar.h> 60 #include <machine/i82093var.h> 61 62 #if NBIOS > 0 63 #include <machine/biosvar.h> 64 #endif 65 66 #include <dev/acpi/acpivar.h> 67 68 #if NIPMI > 0 69 #include <dev/ipmivar.h> 70 #endif 71 72 #if NPVBUS > 0 73 #include <dev/pv/pvvar.h> 74 #endif 75 76 #if NAMDMSR > 0 77 #include <machine/amdmsr.h> 78 #endif 79 80 #if NESM > 0 81 #include <arch/i386/i386/esmvar.h> 82 #endif 83 84 int mainbus_match(struct device *, void *, void *); 85 void mainbus_attach(struct device *, struct device *, void *); 86 87 struct cfattach mainbus_ca = { 88 sizeof(struct device), mainbus_match, mainbus_attach, NULL, 89 config_activate_children 90 }; 91 92 struct cfdriver mainbus_cd = { 93 NULL, "mainbus", DV_DULL 94 }; 95 96 int mainbus_print(void *, const char *); 97 98 union mainbus_attach_args { 99 const char *mba_busname; /* first elem of all */ 100 struct pcibus_attach_args mba_pba; 101 struct eisabus_attach_args mba_eba; 102 struct isabus_attach_args mba_iba; 103 #if NBIOS > 0 104 struct bios_attach_args mba_bios; 105 #endif 106 struct cpu_attach_args mba_caa; 107 struct apic_attach_args aaa_caa; 108 #if NIPMI > 0 109 struct ipmi_attach_args mba_iaa; 110 #endif 111 #if NESM > 0 112 struct esm_attach_args mba_eaa; 113 #endif 114 #if NPVBUS > 0 115 struct pvbus_attach_args mba_pvba; 116 #endif 117 }; 118 119 /* 120 * This is set when the ISA bus is attached. If it's not set by the 121 * time it's checked below, then mainbus attempts to attach an ISA. 122 */ 123 int isa_has_been_seen; 124 125 /* 126 * Probe for the mainbus; always succeeds. 127 */ 128 int 129 mainbus_match(struct device *parent, void *match, void *aux) 130 { 131 return (1); 132 } 133 134 /* 135 * Attach the mainbus. 136 */ 137 void 138 mainbus_attach(struct device *parent, struct device *self, void *aux) 139 { 140 union mainbus_attach_args mba; 141 extern void (*setperf_setup)(struct cpu_info *); 142 extern void (*cpusensors_setup)(struct cpu_info *); 143 144 printf("\n"); 145 146 #if NPVBUS > 0 147 /* Detect hypervisors early, attach the paravirtual bus later */ 148 if (cpu_ecxfeature & CPUIDECX_HV) 149 pvbus_identify(); 150 #endif 151 152 #if NBIOS > 0 153 { 154 mba.mba_bios.ba_name = "bios"; 155 mba.mba_bios.ba_iot = I386_BUS_SPACE_IO; 156 mba.mba_bios.ba_memt = I386_BUS_SPACE_MEM; 157 config_found(self, &mba.mba_bios, mainbus_print); 158 } 159 #endif 160 161 #if NIPMI > 0 162 { 163 memset(&mba.mba_iaa, 0, sizeof(mba.mba_iaa)); 164 mba.mba_iaa.iaa_name = "ipmi"; 165 mba.mba_iaa.iaa_iot = I386_BUS_SPACE_IO; 166 mba.mba_iaa.iaa_memt = I386_BUS_SPACE_MEM; 167 if (ipmi_probe(&mba.mba_iaa)) 168 config_found(self, &mba.mba_iaa, mainbus_print); 169 } 170 #endif 171 172 if ((cpu_info_primary.ci_flags & CPUF_PRESENT) == 0) { 173 struct cpu_attach_args caa; 174 175 memset(&caa, 0, sizeof(caa)); 176 caa.caa_name = "cpu"; 177 caa.cpu_apicid = 0; 178 caa.cpu_role = CPU_ROLE_SP; 179 caa.cpu_func = 0; 180 caa.cpu_signature = cpu_id; 181 caa.feature_flags = cpu_feature; 182 183 config_found(self, &caa, mainbus_print); 184 } 185 #if NAMDMSR > 0 186 if (amdmsr_probe()) { 187 mba.mba_busname = "amdmsr"; 188 config_found(self, &mba.mba_busname, mainbus_print); 189 } 190 #endif 191 192 #if NACPI > 0 193 if (!acpi_hasprocfvs) 194 #endif 195 { 196 if (setperf_setup != NULL) 197 setperf_setup(&cpu_info_primary); 198 } 199 200 #ifdef MULTIPROCESSOR 201 mp_setperf_init(); 202 #endif 203 204 if (cpusensors_setup != NULL) 205 cpusensors_setup(&cpu_info_primary); 206 207 #if NESM > 0 208 { 209 memset(&mba.mba_eaa, 0, sizeof(mba.mba_eaa)); 210 mba.mba_eaa.eaa_name = "esm"; 211 mba.mba_eaa.eaa_iot = I386_BUS_SPACE_IO; 212 mba.mba_eaa.eaa_memt = I386_BUS_SPACE_MEM; 213 if (esm_probe(&mba.mba_eaa)) 214 config_found(self, &mba.mba_eaa, mainbus_print); 215 } 216 #endif 217 218 #if NPVBUS > 0 219 /* Probe first to hide the "not configured" message */ 220 if (pvbus_probe()) { 221 mba.mba_pvba.pvba_busname = "pvbus"; 222 config_found(self, &mba.mba_pvba.pvba_busname, mainbus_print); 223 } 224 #endif 225 226 /* 227 * XXX Note also that the presence of a PCI bus should 228 * XXX _always_ be checked, and if present the bus should be 229 * XXX 'found'. However, because of the structure of the code, 230 * XXX that's not currently possible. 231 */ 232 #if NPCI > 0 233 if (pci_mode_detect() != 0) { 234 pci_init_extents(); 235 236 bzero(&mba.mba_pba, sizeof(mba.mba_pba)); 237 mba.mba_pba.pba_busname = "pci"; 238 mba.mba_pba.pba_iot = I386_BUS_SPACE_IO; 239 mba.mba_pba.pba_memt = I386_BUS_SPACE_MEM; 240 mba.mba_pba.pba_dmat = &pci_bus_dma_tag; 241 mba.mba_pba.pba_ioex = pciio_ex; 242 mba.mba_pba.pba_memex = pcimem_ex; 243 mba.mba_pba.pba_busex = pcibus_ex; 244 mba.mba_pba.pba_domain = pci_ndomains++; 245 mba.mba_pba.pba_bus = 0; 246 config_found(self, &mba.mba_pba, mainbus_print); 247 #if NACPI > 0 248 acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print); 249 #endif 250 } 251 #endif 252 253 if (!bcmp(ISA_HOLE_VADDR(EISA_ID_PADDR), EISA_ID, EISA_ID_LEN)) { 254 mba.mba_eba.eba_busname = "eisa"; 255 mba.mba_eba.eba_iot = I386_BUS_SPACE_IO; 256 mba.mba_eba.eba_memt = I386_BUS_SPACE_MEM; 257 #if NEISA > 0 258 mba.mba_eba.eba_dmat = &eisa_bus_dma_tag; 259 #endif 260 config_found(self, &mba.mba_eba, mainbus_print); 261 } 262 263 if (isa_has_been_seen == 0) { 264 mba.mba_iba.iba_busname = "isa"; 265 mba.mba_iba.iba_iot = I386_BUS_SPACE_IO; 266 mba.mba_iba.iba_memt = I386_BUS_SPACE_MEM; 267 #if NISADMA > 0 268 mba.mba_iba.iba_dmat = &isa_bus_dma_tag; 269 #endif 270 config_found(self, &mba.mba_iba, mainbus_print); 271 } 272 } 273 274 int 275 mainbus_print(void *aux, const char *pnp) 276 { 277 union mainbus_attach_args *mba = aux; 278 279 if (pnp) 280 printf("%s at %s", mba->mba_busname, pnp); 281 if (!strcmp(mba->mba_busname, "pci")) 282 printf(" bus %d", mba->mba_pba.pba_bus); 283 284 return (UNCONF); 285 } 286