1 1.12 thorpej /* $NetBSD: pchb.c,v 1.12 2021/08/07 16:19:03 thorpej Exp $ */ 2 1.2 garbled 3 1.2 garbled /*- 4 1.2 garbled * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 1.2 garbled * All rights reserved. 6 1.2 garbled * 7 1.2 garbled * This code is derived from software contributed to The NetBSD Foundation 8 1.2 garbled * by Tim Rightnour 9 1.2 garbled * 10 1.2 garbled * Redistribution and use in source and binary forms, with or without 11 1.2 garbled * modification, are permitted provided that the following conditions 12 1.2 garbled * are met: 13 1.2 garbled * 1. Redistributions of source code must retain the above copyright 14 1.2 garbled * notice, this list of conditions and the following disclaimer. 15 1.2 garbled * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 garbled * notice, this list of conditions and the following disclaimer in the 17 1.2 garbled * documentation and/or other materials provided with the distribution. 18 1.2 garbled * 19 1.2 garbled * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 garbled * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 garbled * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 garbled * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 garbled * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 garbled * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 garbled * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 garbled * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 garbled * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 garbled * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 garbled * POSSIBILITY OF SUCH DAMAGE. 30 1.2 garbled */ 31 1.2 garbled 32 1.2 garbled #include <sys/cdefs.h> 33 1.12 thorpej __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.12 2021/08/07 16:19:03 thorpej Exp $"); 34 1.10 rin 35 1.10 rin #include "agp.h" 36 1.2 garbled 37 1.2 garbled #include <sys/types.h> 38 1.2 garbled #include <sys/param.h> 39 1.2 garbled #include <sys/systm.h> 40 1.2 garbled #include <sys/device.h> 41 1.2 garbled 42 1.8 dyoung #include <sys/bus.h> 43 1.2 garbled #include <machine/pio.h> 44 1.2 garbled 45 1.2 garbled #include <dev/pci/pcivar.h> 46 1.2 garbled #include <dev/pci/pcireg.h> 47 1.2 garbled #include <dev/pci/pcidevs.h> 48 1.2 garbled #include <dev/pci/agpreg.h> 49 1.2 garbled #include <dev/pci/agpvar.h> 50 1.2 garbled 51 1.2 garbled #include <dev/ic/mpc105reg.h> 52 1.2 garbled #include <dev/ic/mpc106reg.h> 53 1.2 garbled #include <dev/ic/ibm82660reg.h> 54 1.2 garbled 55 1.5 matt int pchbmatch(device_t, cfdata_t, void *); 56 1.5 matt void pchbattach(device_t, device_t, void *); 57 1.2 garbled 58 1.5 matt CFATTACH_DECL_NEW(pchb, 0, 59 1.2 garbled pchbmatch, pchbattach, NULL, NULL); 60 1.2 garbled 61 1.2 garbled int 62 1.5 matt pchbmatch(device_t parent, cfdata_t cf, void *aux) 63 1.2 garbled { 64 1.2 garbled struct pci_attach_args *pa = aux; 65 1.2 garbled 66 1.2 garbled /* 67 1.2 garbled * Match all known PCI host chipsets. 68 1.2 garbled */ 69 1.2 garbled if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 70 1.2 garbled PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) { 71 1.2 garbled return (1); 72 1.2 garbled } 73 1.2 garbled 74 1.2 garbled return (0); 75 1.2 garbled } 76 1.2 garbled 77 1.2 garbled static void 78 1.5 matt mpc105_print(struct pci_attach_args *pa, device_t self) 79 1.2 garbled { 80 1.2 garbled pcireg_t reg1, reg2; 81 1.2 garbled const char *s1; 82 1.2 garbled 83 1.2 garbled reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC105_PICR1); 84 1.2 garbled reg2 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC105_PICR2); 85 1.6 matt aprint_normal_dev(self, "L2 cache: "); 86 1.2 garbled 87 1.2 garbled switch (reg2 & MPC105_PICR2_L2_SIZE) { 88 1.2 garbled case MPC105_PICR2_L2_SIZE_256K: 89 1.2 garbled s1 = "256K"; 90 1.2 garbled break; 91 1.2 garbled case MPC105_PICR2_L2_SIZE_512K: 92 1.2 garbled s1 = "512K"; 93 1.2 garbled break; 94 1.2 garbled case MPC105_PICR2_L2_SIZE_1M: 95 1.2 garbled s1 = "1M"; 96 1.2 garbled break; 97 1.2 garbled default: 98 1.2 garbled s1 = "reserved size"; 99 1.2 garbled break; 100 1.2 garbled } 101 1.2 garbled 102 1.2 garbled aprint_normal("%s, ", s1); 103 1.2 garbled switch (reg1 & MPC105_PICR1_L2_MP) { 104 1.2 garbled case MPC105_PICR1_L2_MP_NONE: 105 1.2 garbled s1 = "uniprocessor/none"; 106 1.2 garbled break; 107 1.2 garbled case MPC105_PICR1_L2_MP_WT: 108 1.2 garbled s1 = "write-through"; 109 1.2 garbled break; 110 1.2 garbled case MPC105_PICR1_L2_MP_WB: 111 1.2 garbled s1 = "write-back"; 112 1.2 garbled break; 113 1.2 garbled case MPC105_PICR1_L2_MP_MP: 114 1.2 garbled s1 = "multiprocessor"; 115 1.2 garbled break; 116 1.2 garbled } 117 1.2 garbled aprint_normal("%s mode\n", s1); 118 1.2 garbled } 119 1.2 garbled 120 1.2 garbled static void 121 1.5 matt mpc106_print(struct pci_attach_args *pa, device_t self) 122 1.2 garbled { 123 1.2 garbled pcireg_t reg1, reg2; 124 1.2 garbled const char *s1; 125 1.2 garbled 126 1.2 garbled reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC106_PICR1); 127 1.2 garbled reg2 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC106_PICR2); 128 1.6 matt aprint_normal_dev(self, "L2 cache: "); 129 1.2 garbled 130 1.2 garbled switch (reg2 & MPC106_PICR2_L2_SIZE) { 131 1.2 garbled case MPC106_PICR2_L2_SIZE_256K: 132 1.2 garbled s1 = "256K"; 133 1.2 garbled break; 134 1.2 garbled case MPC106_PICR2_L2_SIZE_512K: 135 1.2 garbled s1 = "512K"; 136 1.2 garbled break; 137 1.2 garbled case MPC106_PICR2_L2_SIZE_1M: 138 1.2 garbled s1 = "1M"; 139 1.2 garbled break; 140 1.2 garbled default: 141 1.2 garbled s1 = "reserved size"; 142 1.2 garbled break; 143 1.2 garbled } 144 1.2 garbled 145 1.2 garbled aprint_normal("%s, ", s1); 146 1.2 garbled switch (reg1 & MPC106_PICR1_EXT_L2_EN) { 147 1.2 garbled case 0: 148 1.2 garbled switch (reg1 & MPC106_PICR1_L2_MP) { 149 1.2 garbled case MPC106_PICR1_L2_MP_NONE: 150 1.2 garbled s1 = "uniprocessor/none"; 151 1.2 garbled break; 152 1.2 garbled case MPC106_PICR1_L2_MP_WT: 153 1.2 garbled s1 = "internally controlled write-through"; 154 1.2 garbled break; 155 1.2 garbled case MPC106_PICR1_L2_MP_WB: 156 1.2 garbled s1 = "internally controlled write-back"; 157 1.2 garbled break; 158 1.2 garbled case MPC106_PICR1_L2_MP_MP: 159 1.2 garbled s1 = "multiprocessor/none"; 160 1.2 garbled break; 161 1.2 garbled } 162 1.2 garbled break; 163 1.2 garbled case 1: 164 1.2 garbled switch (reg1 & MPC106_PICR1_L2_MP) { 165 1.2 garbled case MPC106_PICR1_L2_MP_NONE: 166 1.2 garbled s1 = "uniprocessor/external"; 167 1.2 garbled break; 168 1.2 garbled case MPC106_PICR1_L2_MP_MP: 169 1.2 garbled s1 = "multiprocessors/external"; 170 1.2 garbled break; 171 1.2 garbled default: 172 1.2 garbled s1 = "reserved"; 173 1.2 garbled break; 174 1.2 garbled } 175 1.2 garbled } 176 1.2 garbled aprint_normal("%s mode\n", s1); 177 1.2 garbled } 178 1.2 garbled 179 1.2 garbled static void 180 1.5 matt ibm82660_print(struct pci_attach_args *pa, device_t self) 181 1.2 garbled { 182 1.2 garbled pcireg_t reg1; 183 1.2 garbled #ifdef PREP_BUS_SPACE_IO 184 1.2 garbled pcireg_t reg2; 185 1.2 garbled #endif 186 1.2 garbled const char *s1, *s2; 187 1.2 garbled 188 1.2 garbled reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, 189 1.2 garbled IBM_82660_CACHE_STATUS); 190 1.2 garbled #ifdef PREP_BUS_SPACE_IO 191 1.2 garbled reg2 = in32rb(PREP_BUS_SPACE_IO+IBM_82660_SYSTEM_CTRL); 192 1.2 garbled if (reg2 & IBM_82660_SYSTEM_CTRL_L2_EN) { 193 1.2 garbled if (reg1 & IBM_82660_CACHE_STATUS_L2_EN) 194 1.2 garbled s1 = "internal enabled"; 195 1.2 garbled else 196 1.2 garbled s1 = "enabled"; 197 1.2 garbled if (reg2 & IBM_82660_SYSTEM_CTRL_L2_MI) 198 1.6 matt s2 = " (normal operation)"; 199 1.2 garbled else 200 1.6 matt s2 = " (miss updates inhibited)"; 201 1.2 garbled } else { 202 1.2 garbled s1 = "disabled"; 203 1.2 garbled s2 = ""; 204 1.2 garbled } 205 1.2 garbled #else 206 1.2 garbled if (reg1 & IBM_82660_CACHE_STATUS_L2_EN) 207 1.2 garbled s1 = "enabled"; 208 1.2 garbled else 209 1.2 garbled s1 = "disabled"; 210 1.2 garbled s2 = ""; 211 1.2 garbled #endif 212 1.6 matt aprint_normal_dev(self, "L1 %s L2 %s%s\n", 213 1.2 garbled (reg1 & IBM_82660_CACHE_STATUS_L1_EN) ? "enabled" : "disabled", 214 1.2 garbled s1, s2); 215 1.2 garbled 216 1.2 garbled reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, IBM_82660_OPTIONS_1); 217 1.6 matt aprint_verbose_dev(self, "MCP# assertion %s " 218 1.6 matt "TEA# assertion %s\n", 219 1.2 garbled (reg1 & IBM_82660_OPTIONS_1_MCP) ? "enabled" : "disabled", 220 1.2 garbled (reg1 & IBM_82660_OPTIONS_1_TEA) ? "enabled" : "disabled"); 221 1.6 matt aprint_verbose_dev(self, "PCI/ISA I/O mapping %s\n", 222 1.2 garbled (reg1 & IBM_82660_OPTIONS_1_ISA) ? "contiguous" : "non-contiguous"); 223 1.2 garbled 224 1.2 garbled reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, IBM_82660_OPTIONS_3); 225 1.6 matt aprint_normal_dev(self, "DRAM %s (%s) SRAM %s\n", 226 1.2 garbled (reg1 & IBM_82660_OPTIONS_3_DRAM) ? "EDO" : "standard", 227 1.2 garbled (reg1 & IBM_82660_OPTIONS_3_ECC) ? "ECC" : "parity", 228 1.2 garbled (reg1 & IBM_82660_OPTIONS_3_SRAM) ? "sync" : "async"); 229 1.6 matt aprint_verbose_dev(self, "Snoop mode %s\n", 230 1.2 garbled (reg1 & IBM_82660_OPTIONS_3_SNOOP) ? "603" : "601/604"); 231 1.2 garbled } 232 1.2 garbled 233 1.2 garbled void 234 1.5 matt pchbattach(device_t parent, device_t self, void *aux) 235 1.2 garbled { 236 1.2 garbled struct pci_attach_args *pa = aux; 237 1.2 garbled char devinfo[256]; 238 1.2 garbled #if NAGP > 0 239 1.2 garbled struct agpbus_attach_args apa; 240 1.2 garbled #endif 241 1.3 garbled volatile unsigned char *python; 242 1.3 garbled uint32_t v; 243 1.3 garbled 244 1.9 phx aprint_naive("\n"); 245 1.3 garbled aprint_normal("\n"); 246 1.2 garbled 247 1.2 garbled /* 248 1.2 garbled * All we do is print out a description. Eventually, we 249 1.2 garbled * might want to add code that does something that's 250 1.2 garbled * possibly chipset-specific. 251 1.2 garbled */ 252 1.2 garbled 253 1.2 garbled pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 254 1.6 matt aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo, 255 1.2 garbled PCI_REVISION(pa->pa_class)); 256 1.2 garbled 257 1.2 garbled switch (PCI_VENDOR(pa->pa_id)) { 258 1.2 garbled case PCI_VENDOR_IBM: 259 1.2 garbled switch (PCI_PRODUCT(pa->pa_id)) { 260 1.2 garbled case PCI_PRODUCT_IBM_82660: 261 1.2 garbled ibm82660_print(pa, self); 262 1.2 garbled break; 263 1.3 garbled case PCI_PRODUCT_IBM_PYTHON: 264 1.7 matt python = mapiodev(0xfeff6000, 0x60, false); 265 1.3 garbled v = 0x88b78e01; /* taken from linux */ 266 1.3 garbled out32rb(python+0x30, v); 267 1.3 garbled v = in32rb(python+0x30); 268 1.3 garbled aprint_debug("Reset python reg 30 to 0x%x\n", v); 269 1.3 garbled break; 270 1.2 garbled } 271 1.2 garbled break; 272 1.2 garbled case PCI_VENDOR_MOT: 273 1.2 garbled switch (PCI_PRODUCT(pa->pa_id)) { 274 1.2 garbled case PCI_PRODUCT_MOT_MPC105: 275 1.2 garbled mpc105_print(pa, self); 276 1.2 garbled break; 277 1.2 garbled case PCI_PRODUCT_MOT_MPC106: 278 1.2 garbled mpc106_print(pa, self); 279 1.2 garbled break; 280 1.2 garbled } 281 1.2 garbled break; 282 1.2 garbled } 283 1.2 garbled 284 1.2 garbled #if NAGP > 0 285 1.2 garbled if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, 286 1.2 garbled NULL, NULL) != 0) { 287 1.2 garbled apa.apa_pci_args = *pa; 288 1.11 thorpej config_found(self, &apa, agpbusprint, 289 1.12 thorpej CFARGS(.iattr = "agpbus")); 290 1.2 garbled } 291 1.2 garbled #endif /* NAGP */ 292 1.2 garbled } 293