1 /* $NetBSD: tcasic.c,v 1.52 2021/08/07 16:18:41 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 5 * All rights reserved. 6 * 7 * Author: Chris G. Demetriou 8 * 9 * Permission to use, copy, modify and distribute this software and 10 * its documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie the 27 * rights to redistribute these changes. 28 */ 29 30 #include "opt_dec_3000_300.h" 31 #include "opt_dec_3000_500.h" 32 33 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 34 35 __KERNEL_RCSID(0, "$NetBSD: tcasic.c,v 1.52 2021/08/07 16:18:41 thorpej Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/cpu.h> 40 #include <sys/device.h> 41 42 #include <machine/autoconf.h> 43 #include <machine/rpb.h> 44 #include <machine/alpha.h> 45 46 #include <dev/tc/tcvar.h> 47 #include <alpha/tc/tc_conf.h> 48 49 /* Definition of the driver for autoconfig. */ 50 static int tcasicmatch(device_t, cfdata_t, void *); 51 static void tcasicattach(device_t, device_t, void *); 52 53 CFATTACH_DECL_NEW(tcasic, 0, 54 tcasicmatch, tcasicattach, NULL, NULL); 55 56 extern struct cfdriver tcasic_cd; 57 58 static int tcasicprint(void *, const char *); 59 60 /* There can be only one. */ 61 static int tcasicfound; 62 63 static int 64 tcasicmatch(device_t parent, cfdata_t cf, void *aux) 65 { 66 struct mainbus_attach_args *ma = aux; 67 68 /* Make sure that we're looking for a TURBOchannel ASIC. */ 69 if (strcmp(ma->ma_name, tcasic_cd.cd_name)) 70 return (0); 71 72 /* Make sure that the system supports a TURBOchannel ASIC. */ 73 if ((cputype != ST_DEC_3000_500) && (cputype != ST_DEC_3000_300)) 74 return (0); 75 76 if (tcasicfound) 77 return (0); 78 79 return (1); 80 } 81 82 static void 83 tcasicattach(device_t parent, device_t self, void *aux) 84 { 85 struct tcbus_attach_args tba; 86 void (*intr_setup)(void); 87 void (*iointr)(void *, unsigned long); 88 89 printf("\n"); 90 tcasicfound = 1; 91 92 switch (cputype) { 93 #ifdef DEC_3000_500 94 case ST_DEC_3000_500: 95 96 intr_setup = tc_3000_500_intr_setup; 97 iointr = tc_3000_500_iointr; 98 99 tba.tba_speed = TC_SPEED_25_MHZ; 100 tba.tba_nslots = tc_3000_500_nslots; 101 tba.tba_slots = tc_3000_500_slots; 102 if (hwrpb->rpb_variation & SV_GRAPHICS) { 103 tba.tba_nbuiltins = tc_3000_500_graphics_nbuiltins; 104 tba.tba_builtins = tc_3000_500_graphics_builtins; 105 } else { 106 tba.tba_nbuiltins = tc_3000_500_nographics_nbuiltins; 107 tba.tba_builtins = tc_3000_500_nographics_builtins; 108 } 109 tba.tba_intr_evcnt = tc_3000_500_intr_evcnt; 110 tba.tba_intr_establish = tc_3000_500_intr_establish; 111 tba.tba_intr_disestablish = tc_3000_500_intr_disestablish; 112 tba.tba_get_dma_tag = tc_dma_get_tag_3000_500; 113 114 /* Do 3000/500-specific DMA setup now. */ 115 tc_dma_init_3000_500(tc_3000_500_nslots); 116 break; 117 #endif /* DEC_3000_500 */ 118 119 #ifdef DEC_3000_300 120 case ST_DEC_3000_300: 121 122 intr_setup = tc_3000_300_intr_setup; 123 iointr = tc_3000_300_iointr; 124 125 tba.tba_speed = TC_SPEED_12_5_MHZ; 126 tba.tba_nslots = tc_3000_300_nslots; 127 tba.tba_slots = tc_3000_300_slots; 128 tba.tba_nbuiltins = tc_3000_300_nbuiltins; 129 tba.tba_builtins = tc_3000_300_builtins; 130 tba.tba_intr_evcnt = tc_3000_300_intr_evcnt; 131 tba.tba_intr_establish = tc_3000_300_intr_establish; 132 tba.tba_intr_disestablish = tc_3000_300_intr_disestablish; 133 tba.tba_get_dma_tag = tc_dma_get_tag_3000_300; 134 break; 135 #endif /* DEC_3000_300 */ 136 137 default: 138 panic("tcasicattach: bad cputype"); 139 } 140 141 tba.tba_busname = "tc"; 142 tba.tba_memt = tc_bus_mem_init(NULL); 143 144 tc_dma_init(); 145 146 (*intr_setup)(); 147 148 /* They all come in at 0x800. */ 149 mutex_enter(&cpu_lock); 150 scb_set(0x800, iointr, NULL); 151 mutex_exit(&cpu_lock); 152 153 config_found(self, &tba, tcasicprint, CFARGS_NONE); 154 } 155 156 static int 157 tcasicprint(void *aux, const char *pnp) 158 { 159 160 /* only TCs can attach to tcasics; easy. */ 161 if (pnp) 162 aprint_normal("tc at %s", pnp); 163 return (UNCONF); 164 } 165 166 #include "wsdisplay.h" 167 168 #if NWSDISPLAY > 0 169 170 #include "sfb.h" 171 #include "sfbp.h" 172 #include "cfb.h" 173 #include "mfb.h" 174 #include "tfb.h" 175 #include "px.h" 176 #include "pxg.h" 177 178 extern void sfb_cnattach(tc_addr_t); 179 extern void sfbp_cnattach(tc_addr_t); 180 extern void cfb_cnattach(tc_addr_t); 181 extern void mfb_cnattach(tc_addr_t); 182 extern void tfb_cnattach(tc_addr_t); 183 extern void px_cnattach(tc_addr_t); 184 extern void pxg_cnattach(tc_addr_t); 185 186 struct cnboards { 187 const char *cb_tcname; 188 void (*cb_cnattach)(tc_addr_t); 189 } static const cnboards[] = { 190 #if NSFB > 0 191 { "PMAGB-BA", sfb_cnattach }, 192 #endif 193 #if NSFBP > 0 194 { "PMAGD ", sfbp_cnattach }, 195 #endif 196 #if NCFB > 0 197 { "PMAG-BA ", cfb_cnattach }, 198 #endif 199 #if NMFB > 0 200 { "PMAG-AA ", mfb_cnattach }, 201 #endif 202 #if NTFB > 0 203 { "PMAG-JA ", tfb_cnattach }, 204 #endif 205 #if NPX > 0 206 { "PMAG-CA ", px_cnattach }, 207 #endif 208 #if NPXG > 0 209 { "PMAG-DA ", pxg_cnattach }, 210 { "PMAG-FA ", pxg_cnattach }, 211 { "PMAG-FB ", pxg_cnattach }, 212 { "PMAGB-FA", pxg_cnattach }, 213 { "PMAGB-FB", pxg_cnattach }, 214 #endif 215 }; 216 217 /* 218 * tc_fb_cnattach -- 219 * Attempt to attach the appropriate display driver to the 220 * output console. 221 */ 222 int 223 tc_fb_cnattach(tc_addr_t tcaddr) 224 { 225 char tcname[TC_ROM_LLEN]; 226 int i; 227 228 if (tc_badaddr(tcaddr) || (tc_checkslot(tcaddr, tcname, NULL) == 0)) 229 return (EINVAL); 230 231 for (i = 0; i < sizeof(cnboards) / sizeof(cnboards[0]); i++) 232 if (strncmp(tcname, cnboards[i].cb_tcname, TC_ROM_LLEN) == 0) 233 break; 234 235 if (i == sizeof(cnboards) / sizeof(cnboards[0])) 236 return (ENXIO); 237 238 (cnboards[i].cb_cnattach)(tcaddr); 239 return (0); 240 } 241 #endif /* if NWSDISPLAY > 0 */ 242