1 /* $NetBSD: tsc.c,v 1.30 2023/12/04 00:32:10 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 by Ross Harvey. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Ross Harvey. 17 * 4. The name of Ross Harvey may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ROSS HARVEY ``AS IS'' AND ANY EXPRESS 21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE 23 * ARE DISCLAIMED. IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 #include <sys/cdefs.h> 35 36 __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.30 2023/12/04 00:32:10 thorpej Exp $"); 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/device.h> 41 42 #include <machine/autoconf.h> 43 #include <machine/rpb.h> 44 #include <machine/sysarch.h> 45 46 #include <dev/isa/isareg.h> 47 #include <dev/isa/isavar.h> 48 #include <dev/pci/pcireg.h> 49 #include <dev/pci/pcivar.h> 50 #include <alpha/pci/tsreg.h> 51 #include <alpha/pci/tsvar.h> 52 53 #include "tsciic.h" 54 55 #define tsc() { Generate ctags(1) key. } 56 57 static int tscmatch(device_t, cfdata_t, void *); 58 static void tscattach(device_t, device_t, void *); 59 60 CFATTACH_DECL_NEW(tsc, 0, tscmatch, tscattach, NULL, NULL); 61 62 extern struct cfdriver tsc_cd; 63 64 struct tsp_config tsp_configuration[4]; 65 66 static int tscprint(void *, const char *pnp); 67 68 static int tspmatch(device_t, cfdata_t, void *); 69 static void tspattach(device_t, device_t, void *); 70 71 CFATTACH_DECL_NEW(tsp, 0, tspmatch, tspattach, NULL, NULL); 72 73 extern struct cfdriver tsp_cd; 74 75 static int tsp_bus_get_window(int, int, 76 struct alpha_bus_space_translation *); 77 78 static int tsciicprint(void *, const char *pnp); 79 80 static int tsciicmatch(device_t, cfdata_t, void *); 81 static void tsciicattach(device_t, device_t, void *); 82 83 CFATTACH_DECL_NEW(tsciic, sizeof(struct tsciic_softc), tsciicmatch, 84 tsciicattach, NULL, NULL); 85 86 #if NTSCIIC 87 extern struct cfdriver tsciic_cd; 88 #endif 89 90 /* There can be only one */ 91 static int tscfound; 92 93 /* Which hose is the display console connected to? */ 94 int tsp_console_hose; 95 96 static int 97 tscmatch(device_t parent, cfdata_t match, void *aux) 98 { 99 struct mainbus_attach_args *ma = aux; 100 101 switch (cputype) { 102 case ST_DEC_6600: 103 case ST_DEC_TITAN: 104 return strcmp(ma->ma_name, tsc_cd.cd_name) == 0 && !tscfound; 105 default: 106 return 0; 107 } 108 } 109 110 static void 111 tscattach(device_t parent, device_t self, void * aux) 112 { 113 int i; 114 int nbus; 115 uint64_t csc, aar; 116 struct tsp_attach_args tsp; 117 struct tsciic_attach_args tsciic; 118 struct mainbus_attach_args *ma = aux; 119 int titan = cputype == ST_DEC_TITAN; 120 121 tscfound = 1; 122 123 csc = LDQP(TS_C_CSC); 124 125 nbus = 1 + (CSC_BC(csc) >= 2); 126 printf(": 2127%c Core Logic Chipset, Cchip rev %d\n" 127 "%s%d: %c Dchips, %d memory bus%s of %d bytes\n", 128 titan ? '4' : '2', (int)MISC_REV(LDQP(TS_C_MISC)), 129 ma->ma_name, ma->ma_slot, "2448"[CSC_BC(csc)], 130 nbus, nbus > 1 ? "es" : "", 16 + 16 * ((csc & CSC_AW) != 0)); 131 printf("%s%d: arrays present: ", ma->ma_name, ma->ma_slot); 132 for (i = 0; i < 4; ++i) { 133 aar = LDQP(TS_C_AAR0 + i * TS_STEP); 134 printf("%s%dMB%s", i ? ", " : "", (8 << AAR_ASIZ(aar)) & ~0xf, 135 aar & AAR_SPLIT ? " (split)" : ""); 136 } 137 printf(", Dchip 0 rev %d\n", (int)LDQP(TS_D_DREV) & 0xf); 138 139 memset(&tsp, 0, sizeof tsp); 140 tsp.tsp_name = "tsp"; 141 tsp.tsp_slot = 0; 142 143 config_found(self, &tsp, tscprint, CFARGS_NONE); 144 if (titan) { 145 tsp.tsp_slot += 2; 146 config_found(self, &tsp, tscprint, CFARGS_NONE); 147 } 148 149 if (csc & CSC_P1P) { 150 tsp.tsp_slot = 1; 151 config_found(self, &tsp, tscprint, CFARGS_NONE); 152 if (titan) { 153 tsp.tsp_slot += 2; 154 config_found(self, &tsp, tscprint, CFARGS_NONE); 155 } 156 } 157 158 memset(&tsciic, 0, sizeof tsciic); 159 tsciic.tsciic_name = "tsciic"; 160 161 config_found(self, &tsciic, tsciicprint, CFARGS_NONE); 162 } 163 164 static int 165 tscprint(void *aux, const char *p) 166 { 167 struct tsp_attach_args *tsp = aux; 168 169 if (p) 170 aprint_normal("%s%d at %s", tsp->tsp_name, tsp->tsp_slot, p); 171 return UNCONF; 172 } 173 174 static int 175 tsciicprint(void *aux, const char *p) 176 { 177 struct tsciic_attach_args *tsciic = aux; 178 179 if (p) 180 aprint_normal("%s at %s\n", tsciic->tsciic_name, p); 181 else 182 aprint_normal("\n"); 183 return UNCONF; 184 } 185 186 #define tsp() { Generate ctags(1) key. } 187 188 static int 189 tspmatch(device_t parent, cfdata_t match, void *aux) 190 { 191 struct tsp_attach_args *t = aux; 192 193 switch (cputype) { 194 case ST_DEC_6600: 195 case ST_DEC_TITAN: 196 return strcmp(t->tsp_name, tsp_cd.cd_name) == 0; 197 default: 198 return 0; 199 } 200 } 201 202 static void 203 tspattach(device_t parent, device_t self, void *aux) 204 { 205 struct pcibus_attach_args pba; 206 struct tsp_attach_args *t = aux; 207 struct tsp_config *pcp; 208 209 printf("\n"); 210 pcp = tsp_init(t->tsp_slot); 211 212 tsp_dma_init(pcp); 213 214 /* 215 * Do PCI memory initialization that needs to be deferred until 216 * malloc is safe. On the Tsunami, we need to do this after 217 * DMA is initialized, as well. 218 */ 219 tsp_bus_mem_init2(&pcp->pc_memt, pcp); 220 221 alpha_pci_intr_init(pcp, &pcp->pc_iot, &pcp->pc_memt, &pcp->pc_pc); 222 223 pba.pba_iot = &pcp->pc_iot; 224 pba.pba_memt = &pcp->pc_memt; 225 pba.pba_dmat = 226 alphabus_dma_get_tag(&pcp->pc_dmat_direct, ALPHA_BUS_PCI); 227 pba.pba_dmat64 = &pcp->pc_dmat64_direct; 228 pba.pba_pc = &pcp->pc_pc; 229 pba.pba_bus = 0; 230 pba.pba_bridgetag = NULL; 231 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 232 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 233 config_found(self, &pba, pcibusprint, CFARGS_NONE); 234 } 235 236 struct tsp_config * 237 tsp_init(int n) 238 /* n: Pchip number */ 239 { 240 struct tsp_config *pcp; 241 int titan = cputype == ST_DEC_TITAN; 242 243 KASSERT(n >= 0 && n < __arraycount(tsp_configuration)); 244 pcp = &tsp_configuration[n]; 245 pcp->pc_pslot = n; 246 pcp->pc_iobase = TS_Pn(n, 0); 247 pcp->pc_csr = S_PAGE(TS_Pn(n & 1, P_CSRBASE)); 248 if (n & 2) { 249 /* `A' port of PA Chip */ 250 pcp->pc_csr++; 251 } 252 if (titan) { 253 /* same address on G and A ports */ 254 pcp->pc_tlbia = &pcp->pc_csr->port.g.tsp_tlbia.tsg_r; 255 } else { 256 pcp->pc_tlbia = &pcp->pc_csr->port.p.tsp_tlbia.tsg_r; 257 } 258 259 if (!pcp->pc_initted) { 260 tsp_bus_io_init(&pcp->pc_iot, pcp); 261 tsp_bus_mem_init(&pcp->pc_memt, pcp); 262 263 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 1; 264 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 1; 265 266 alpha_bus_get_window = tsp_bus_get_window; 267 } 268 tsp_pci_init(&pcp->pc_pc, pcp); 269 pcp->pc_initted = 1; 270 return pcp; 271 } 272 273 static int 274 tsp_bus_get_window(int type, int window, 275 struct alpha_bus_space_translation *abst) 276 { 277 struct tsp_config *tsp = &tsp_configuration[tsp_console_hose]; 278 bus_space_tag_t st; 279 int error; 280 281 switch (type) { 282 case ALPHA_BUS_TYPE_PCI_IO: 283 st = &tsp->pc_iot; 284 break; 285 286 case ALPHA_BUS_TYPE_PCI_MEM: 287 st = &tsp->pc_memt; 288 break; 289 290 default: 291 panic("tsp_bus_get_window"); 292 } 293 294 error = alpha_bus_space_get_window(st, window, abst); 295 if (error) 296 return error; 297 298 abst->abst_sys_start = TS_PHYSADDR(abst->abst_sys_start); 299 abst->abst_sys_end = TS_PHYSADDR(abst->abst_sys_end); 300 301 return 0; 302 } 303 304 #define tsciic() { Generate ctags(1) key. } 305 306 static int 307 tsciicmatch(device_t parent, cfdata_t match, void *aux) 308 { 309 #if NTSCIIC 310 struct tsciic_attach_args *t = aux; 311 #endif 312 313 switch (cputype) { 314 case ST_DEC_6600: 315 case ST_DEC_TITAN: 316 #if NTSCIIC 317 return strcmp(t->tsciic_name, tsciic_cd.cd_name) == 0; 318 #endif 319 default: 320 return 0; 321 } 322 } 323 324 static void 325 tsciicattach(device_t parent, device_t self, void *aux) 326 { 327 #if NTSCIIC 328 tsciic_init(self); 329 #endif 330 } 331 332 void 333 tsc_print_dir(unsigned int indent, unsigned long dir) 334 { 335 char buf[60]; 336 337 snprintb(buf, 60, 338 "\177\20" 339 "b\77Internal Cchip asynchronous error\0" 340 "b\76Pchip 0 error\0" 341 "b\75Pchip 1 error\0" 342 "b\74Pchip 2 error\0" 343 "b\73Pchip 3 error\0", 344 dir); 345 IPRINTF(indent, "DIR = %s\n", buf); 346 } 347 348 void 349 tsc_print_misc(unsigned int indent, unsigned long misc) 350 { 351 unsigned long tmp = MISC_NXM_SRC(misc); 352 353 if (!MISC_NXM(misc)) 354 return; 355 356 IPRINTF(indent, "NXM address detected\n"); 357 IPRINTF(indent, "NXM source = %s %lu\n", 358 tmp <= 3 ? "CPU" : "Pchip", tmp <= 3 ? tmp : tmp - 4); 359 } 360