1 1.31 thorpej /* $NetBSD: mainbus.c,v 1.31 2023/12/20 06:36:01 thorpej Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe. 9 1.1 thorpej * 10 1.1 thorpej * Redistribution and use in source and binary forms, with or without 11 1.1 thorpej * modification, are permitted provided that the following conditions 12 1.1 thorpej * are met: 13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.1 thorpej * notice, this list of conditions and the following disclaimer. 15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.1 thorpej * documentation and/or other materials provided with the distribution. 18 1.1 thorpej * 19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.1 thorpej */ 31 1.14 lukem 32 1.14 lukem #include <sys/cdefs.h> 33 1.31 thorpej __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.31 2023/12/20 06:36:01 thorpej Exp $"); 34 1.1 thorpej 35 1.1 thorpej #include "opt_algor_p4032.h" 36 1.1 thorpej #include "opt_algor_p5064.h" 37 1.1 thorpej #include "opt_algor_p6032.h" 38 1.1 thorpej 39 1.1 thorpej #include "opt_pci.h" 40 1.1 thorpej 41 1.1 thorpej #include <sys/param.h> 42 1.25 matt #include <sys/bus.h> 43 1.1 thorpej #include <sys/conf.h> 44 1.1 thorpej #include <sys/device.h> 45 1.25 matt #include <sys/reboot.h> 46 1.25 matt #include <sys/systm.h> 47 1.1 thorpej 48 1.25 matt #include <algor/autoconf.h> 49 1.1 thorpej 50 1.7 thorpej #include <mips/cache.h> 51 1.7 thorpej 52 1.1 thorpej #include <dev/pci/pcivar.h> 53 1.1 thorpej #include <dev/pci/pciconf.h> 54 1.1 thorpej 55 1.4 thorpej #if defined(PCI_NETBSD_CONFIGURE) && defined(PCI_NETBSD_ENABLE_IDE) 56 1.4 thorpej #if defined(ALGOR_P5064) || defined(ALGOR_P6032) 57 1.4 thorpej #include <dev/pci/pciide_piix_reg.h> 58 1.4 thorpej #endif /* ALGOR_P5064 || ALGOR_P6032 */ 59 1.4 thorpej #endif /* PCI_NETBSD_CONFIGURE && PCI_NETBSD_ENABLE_IDE */ 60 1.4 thorpej 61 1.1 thorpej #include "locators.h" 62 1.1 thorpej #include "pci.h" 63 1.1 thorpej 64 1.22 matt int mainbus_match(device_t, cfdata_t, void *); 65 1.22 matt void mainbus_attach(device_t, device_t, void *); 66 1.1 thorpej 67 1.22 matt CFATTACH_DECL_NEW(mainbus, 0, 68 1.12 thorpej mainbus_match, mainbus_attach, NULL, NULL); 69 1.1 thorpej 70 1.1 thorpej int mainbus_print(void *, const char *); 71 1.22 matt int mainbus_submatch(device_t, cfdata_t, 72 1.18 drochner const int *, void *); 73 1.1 thorpej 74 1.1 thorpej /* There can be only one. */ 75 1.1 thorpej int mainbus_found; 76 1.1 thorpej 77 1.2 thorpej struct mainbusdev { 78 1.2 thorpej const char *md_name; 79 1.2 thorpej bus_addr_t md_addr; 80 1.2 thorpej int md_irq; 81 1.2 thorpej }; 82 1.2 thorpej 83 1.2 thorpej #if defined(ALGOR_P4032) 84 1.2 thorpej #include <algor/algor/algor_p4032reg.h> 85 1.2 thorpej #include <algor/algor/algor_p4032var.h> 86 1.2 thorpej 87 1.2 thorpej struct mainbusdev mainbusdevs[] = { 88 1.2 thorpej { "cpu", -1, -1 }, 89 1.2 thorpej { "mcclock", P4032_RTC, P4032_IRQ_RTC }, 90 1.2 thorpej { "com", P4032_COM1, P4032_IRQ_COM1 }, 91 1.2 thorpej { "com", P4032_COM2, P4032_IRQ_COM2 }, 92 1.2 thorpej { "lpt", P4032_LPT, P4032_IRQ_LPT }, 93 1.2 thorpej { "pckbc", P4032_PCKBC, P4032_IRQ_PCKBC }, 94 1.2 thorpej { "fdc", P4032_FDC, P4032_IRQ_FLOPPY }, 95 1.2 thorpej { "vtpbc", P4032_V962PBC, -1 }, 96 1.2 thorpej 97 1.2 thorpej { NULL, 0, 0 }, 98 1.2 thorpej }; 99 1.28 thorpej 100 1.28 thorpej /* Reserve the bottom 64K of the I/O space for ISA devices. */ 101 1.28 thorpej #define PCI_IO_START 0x00010000 102 1.28 thorpej #define PCI_IO_END 0x000effff 103 1.28 thorpej #define PCI_MEM_START 0x01000000 104 1.28 thorpej #define PCI_MEM_END 0x07ffffff 105 1.28 thorpej #define PCI_CHIPSET &p4032_configuration.ac_pc 106 1.2 thorpej #endif /* ALGOR_P4032 */ 107 1.2 thorpej 108 1.1 thorpej #if defined(ALGOR_P5064) 109 1.1 thorpej #include <algor/algor/algor_p5064reg.h> 110 1.1 thorpej #include <algor/algor/algor_p5064var.h> 111 1.1 thorpej 112 1.2 thorpej struct mainbusdev mainbusdevs[] = { 113 1.2 thorpej { "cpu", -1, -1 }, 114 1.2 thorpej { "vtpbc", P5064_V360EPC, -1 }, 115 1.1 thorpej 116 1.2 thorpej { NULL, 0, 0 }, 117 1.1 thorpej }; 118 1.28 thorpej 119 1.28 thorpej /* 120 1.28 thorpej * Reserve the bottom 512K of the I/O space for ISA devices. 121 1.28 thorpej * According to the PMON sources, this is a work-around for 122 1.28 thorpej * a bug in the ISA bridge. 123 1.28 thorpej */ 124 1.28 thorpej #define PCI_IO_START 0x00080000 125 1.28 thorpej #define PCI_IO_END 0x00ffffff 126 1.28 thorpej #define PCI_MEM_START 0x01000000 127 1.28 thorpej #define PCI_MEM_END 0x07ffffff 128 1.28 thorpej #define PCI_IDE_DEV 2 129 1.28 thorpej #define PCI_IDE_FUNC 1 130 1.28 thorpej #define PCI_CHIPSET &p5064_configuration.ac_pc 131 1.1 thorpej #endif /* ALGOR_P5064 */ 132 1.1 thorpej 133 1.3 thorpej #if defined(ALGOR_P6032) 134 1.3 thorpej #include <algor/algor/algor_p6032reg.h> 135 1.3 thorpej #include <algor/algor/algor_p6032var.h> 136 1.3 thorpej 137 1.3 thorpej struct mainbusdev mainbusdevs[] = { 138 1.3 thorpej { "cpu", -1, -1 }, 139 1.3 thorpej { "bonito", BONITO_REG_BASE, -1 }, 140 1.3 thorpej 141 1.3 thorpej { NULL, 0, 0 }, 142 1.3 thorpej }; 143 1.28 thorpej 144 1.28 thorpej /* Reserve the bottom 64K of the I/O space for ISA devices. */ 145 1.28 thorpej #define PCI_IO_START 0x00010000 146 1.28 thorpej #define PCI_IO_END 0x000effff 147 1.28 thorpej #define PCI_MEM_START 0x01000000 148 1.28 thorpej #define PCI_MEM_END 0x0affffff 149 1.28 thorpej #define PCI_IDE_DEV 17 150 1.28 thorpej #define PCI_IDE_FUNC 1 151 1.28 thorpej #define PCI_CHIPSET &p6032_configuration.ac_pc 152 1.3 thorpej #endif /* ALGOR_P6032 */ 153 1.3 thorpej 154 1.28 thorpej #define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1) 155 1.28 thorpej #define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1) 156 1.28 thorpej 157 1.1 thorpej int 158 1.22 matt mainbus_match(device_t parent, cfdata_t cf, void *aux) 159 1.1 thorpej { 160 1.1 thorpej 161 1.1 thorpej if (mainbus_found) 162 1.1 thorpej return (0); 163 1.1 thorpej 164 1.1 thorpej return (1); 165 1.1 thorpej } 166 1.1 thorpej 167 1.1 thorpej void 168 1.22 matt mainbus_attach(device_t parent, device_t self, void *aux) 169 1.1 thorpej { 170 1.2 thorpej struct mainbus_attach_args ma; 171 1.2 thorpej struct mainbusdev *md; 172 1.2 thorpej bus_space_tag_t st; 173 1.1 thorpej 174 1.1 thorpej mainbus_found = 1; 175 1.1 thorpej 176 1.1 thorpej printf("\n"); 177 1.1 thorpej 178 1.1 thorpej #if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE) 179 1.28 thorpej struct pciconf_resources *pcires = pciconf_resource_init(); 180 1.1 thorpej 181 1.28 thorpej pciconf_resource_add(pcires, PCICONF_RESOURCE_IO, 182 1.28 thorpej PCI_IO_START, PCI_IO_SIZE); 183 1.28 thorpej pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM, 184 1.28 thorpej PCI_MEM_START, PCI_MEM_SIZE); 185 1.28 thorpej 186 1.28 thorpej pci_configure_bus(PCI_CHIPSET, pcires, 0, 187 1.28 thorpej mips_cache_info.mci_dcache_align); 188 1.28 thorpej pciconf_resource_fini(pcires); 189 1.4 thorpej 190 1.4 thorpej #if defined(PCI_NETBSD_ENABLE_IDE) 191 1.4 thorpej /* 192 1.4 thorpej * Perhaps PMON has not enabled the IDE controller. Easy to 193 1.4 thorpej * fix -- just set the ENABLE bits for each channel in the 194 1.4 thorpej * IDETIM register. Just clear all the bits for the channel 195 1.4 thorpej * except for the ENABLE bits -- the `pciide' driver will 196 1.4 thorpej * properly configure it later. 197 1.4 thorpej */ 198 1.28 thorpej pcitag_t idetag = pci_make_tag(PCI_CHIPSET, 0, PCI_IDE_DEV, 199 1.28 thorpej PCI_IDE_FUNC); 200 1.28 thorpej pcireg_t idetim = 0; 201 1.4 thorpej if (PCI_NETBSD_ENABLE_IDE & 0x01) 202 1.4 thorpej idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 0); 203 1.4 thorpej if (PCI_NETBSD_ENABLE_IDE & 0x02) 204 1.4 thorpej idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 1); 205 1.28 thorpej pci_conf_write(PCI_CHIPSET, idetag, PIIX_IDETIM, idetim); 206 1.4 thorpej #endif 207 1.1 thorpej #endif /* NPCI > 0 && defined(PCI_NETBSD_CONFIGURE) */ 208 1.1 thorpej 209 1.2 thorpej #if defined(ALGOR_P4032) 210 1.2 thorpej st = &p4032_configuration.ac_lociot; 211 1.2 thorpej #elif defined(ALGOR_P5064) 212 1.3 thorpej st = NULL; 213 1.3 thorpej #elif defined(ALGOR_P6032) 214 1.2 thorpej st = NULL; 215 1.2 thorpej #endif 216 1.2 thorpej 217 1.2 thorpej for (md = mainbusdevs; md->md_name != NULL; md++) { 218 1.2 thorpej ma.ma_name = md->md_name; 219 1.2 thorpej ma.ma_st = st; 220 1.2 thorpej ma.ma_addr = md->md_addr; 221 1.2 thorpej ma.ma_irq = md->md_irq; 222 1.29 thorpej config_found(self, &ma, mainbus_print, 223 1.30 thorpej CFARGS(.submatch = mainbus_submatch)); 224 1.2 thorpej } 225 1.1 thorpej } 226 1.1 thorpej 227 1.1 thorpej int 228 1.1 thorpej mainbus_print(void *aux, const char *pnp) 229 1.1 thorpej { 230 1.1 thorpej struct mainbus_attach_args *ma = aux; 231 1.1 thorpej 232 1.1 thorpej if (pnp) 233 1.13 thorpej aprint_normal("%s at %s", ma->ma_name, pnp); 234 1.1 thorpej if (ma->ma_addr != (bus_addr_t) -1) 235 1.24 matt aprint_normal(" addr %#" PRIxBUSADDR, ma->ma_addr); 236 1.1 thorpej 237 1.1 thorpej return (UNCONF); 238 1.1 thorpej } 239 1.1 thorpej 240 1.1 thorpej int 241 1.22 matt mainbus_submatch(device_t parent, cfdata_t cf, 242 1.18 drochner const int *ldesc, void *aux) 243 1.1 thorpej { 244 1.1 thorpej struct mainbus_attach_args *ma = aux; 245 1.1 thorpej 246 1.1 thorpej if (cf->cf_loc[MAINBUSCF_ADDR] != MAINBUSCF_ADDR_DEFAULT && 247 1.1 thorpej cf->cf_loc[MAINBUSCF_ADDR] != ma->ma_addr) 248 1.1 thorpej return (0); 249 1.1 thorpej 250 1.9 thorpej return (config_match(parent, cf, aux)); 251 1.1 thorpej } 252