1/* $NetBSD: asp.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $ */ 2 3/* $OpenBSD: asp.c,v 1.5 2000/02/09 05:04:22 mickey Exp $ */ 4 5/* 6 * Copyright (c) 1998-2003 Michael Shalayeff 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* 32 * References: 33 * 34 * 1. Cobra/Coral I/O Subsystem External Reference Specification 35 * Hewlett-Packard 36 * 37 */ 38 39#include <sys/cdefs.h> 40__KERNEL_RCSID(0, "$NetBSD: asp.c,v 1.4 2021/08/07 16:18:55 thorpej Exp $"); 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/device.h> 45#include <sys/reboot.h> 46 47#include <sys/bus.h> 48#include <machine/iomod.h> 49#include <machine/autoconf.h> 50#include <machine/cpufunc.h> 51 52#include <hppa/hppa/machdep.h> 53#include <hppa/dev/cpudevs.h> 54#include <hppa/dev/viper.h> 55 56#include <hppa/gsc/gscbusvar.h> 57 58struct asp_hwr { 59 uint8_t asp_reset; 60 uint8_t asp_resv[31]; 61 uint8_t asp_version; 62 uint8_t asp_resv1[15]; 63 uint8_t asp_scsidsync; 64 uint8_t asp_resv2[15]; 65 uint8_t asp_error; 66}; 67 68struct asp_trs { 69 uint32_t asp_irr; 70 uint32_t asp_imr; 71 uint32_t asp_ipr; 72 uint32_t asp_icr; 73 uint32_t asp_iar; 74 uint32_t asp_resv[3]; 75 uint8_t asp_cled; 76 uint8_t asp_resv1[3]; 77 struct { 78 u_int :20, 79 asp_spu : 3, /* SPU ID board jumper */ 80#define ASP_SPUCOBRA 0 81#define ASP_SPUCORAL 1 82#define ASP_SPUBUSH 2 83#define ASP_SPUHARDBALL 3 84#define ASP_SPUSCORPIO 4 85#define ASP_SPUCORAL2 5 86 asp_sw : 1, /* front switch is normal */ 87 asp_clk : 1, /* SCSI clock is doubled */ 88 asp_lan : 2, /* LAN iface selector */ 89#define ASP_LANINVAL 0 90#define ASP_LANAUI 1 91#define ASP_LANTHIN 2 92#define ASP_LANMISS 3 93 asp_lanf: 1, /* LAN AUI fuse is ok */ 94 asp_spwr: 1, /* SCSI power ok */ 95 asp_scsi: 3; /* SCSI ctrl ID */ 96 } _asp_ios; 97#define asp_spu _asp_ios.asp_spu 98#define asp_sw _asp_ios.asp_sw 99#define asp_clk _asp_ios.asp_clk 100#define asp_lan _asp_ios.asp_lan 101#define asp_lanf _asp_ios.asp_lanf 102#define asp_spwr _asp_ios.asp_spwr 103#define asp_scsi _asp_ios.asp_scsi 104}; 105 106#define ASP_BANK_SZ 0x02000000 107#define ASP_REG_INT 0x00800000 108#define ASP_ETHER_ADDR 0x00810000 109#define ASP_REG_MISC 0x0082f000 110 111const struct asp_spus_tag { 112 char name[12]; 113 int ledword; 114} asp_spus[] = { 115 { "Cobra", 0 }, 116 { "Coral", 0 }, 117 { "Bushmaster", 0 }, 118 { "Hardball", 1 }, 119 { "Scorpio", 0 }, 120 { "Coral II", 1 }, 121 { "#6", 0 }, 122 { "#7", 0 } 123}; 124 125struct asp_softc { 126 device_t sc_dev; 127 128 struct hppa_interrupt_register sc_ir; 129 130 volatile struct asp_hwr *sc_hw; 131 volatile struct asp_trs *sc_trs; 132}; 133 134int aspmatch(device_t, cfdata_t, void *); 135void aspattach(device_t, device_t, void *); 136 137CFATTACH_DECL_NEW(asp, sizeof(struct asp_softc), 138 aspmatch, aspattach, NULL, NULL); 139 140/* 141 * Before a module is matched, this fixes up its gsc_attach_args. 142 */ 143static void asp_fix_args(void *, struct gsc_attach_args *); 144static void 145asp_fix_args(void *_sc, struct gsc_attach_args *ga) 146{ 147 hppa_hpa_t module_offset; 148 struct asp_softc *sc = _sc; 149 150 /* 151 * Determine this module's interrupt bit. 152 */ 153 module_offset = ga->ga_hpa - (hppa_hpa_t) sc->sc_trs; 154 ga->ga_irq = HPPACF_IRQ_UNDEF; 155#define ASP_IRQ(off, irq) if (module_offset == off) ga->ga_irq = irq 156 ASP_IRQ(0x22000, 6); /* com1 */ 157 ASP_IRQ(0x23000, 5); /* com0 */ 158 ASP_IRQ(0x24000, 7); /* lpt */ 159 ASP_IRQ(0x25000, 9); /* osiop */ 160 ASP_IRQ(0x26000, 8); /* ie */ 161 ASP_IRQ(0x30000, 3); /* siop */ 162 ASP_IRQ(0x800000, 13); /* harmony */ 163#undef ASP_IRQ 164} 165 166int 167aspmatch(device_t parent, cfdata_t cf, void *aux) 168{ 169 struct confargs *ca = aux; 170 171 if (ca->ca_type.iodc_type != HPPA_TYPE_BHA || 172 ca->ca_type.iodc_sv_model != HPPA_BHA_ASP) 173 return 0; 174 175 /* 176 * Forcibly mask the HPA down to the start of the ASP 177 * chip address space. 178 */ 179 ca->ca_hpa &= ~(ASP_BANK_SZ - 1); 180 181 return 1; 182} 183 184void 185aspattach(device_t parent, device_t self, void *aux) 186{ 187 struct confargs *ca = aux; 188 struct asp_softc *sc = device_private(self); 189 struct gsc_attach_args ga; 190 struct cpu_info *ci = &cpus[0]; 191 bus_space_handle_t ioh; 192 int s; 193 194 sc->sc_dev = self; 195 196 ca->ca_irq = hppa_intr_allocate_bit(&ci->ci_ir, ca->ca_irq); 197 if (ca->ca_irq == HPPACF_IRQ_UNDEF) { 198 aprint_error_dev(self, ": can't allocate interrupt"); 199 return; 200 } 201 202 /* 203 * Map the ASP interrupt registers. 204 */ 205 if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_INT, 206 sizeof(struct asp_trs), 0, &ioh)) { 207 aprint_error(": can't map interrupt registers.\n"); 208 return; 209 } 210 sc->sc_trs = (struct asp_trs *)ioh; 211 212 /* 213 * Map the ASP miscellaneous registers. 214 */ 215 if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_REG_MISC, 216 sizeof(struct asp_hwr), 0, &ioh)) { 217 aprint_error(": can't map miscellaneous registers.\n"); 218 return; 219 } 220 sc->sc_hw = (struct asp_hwr *)ioh; 221 222 /* 223 * Map the Ethernet address and read it out. 224 */ 225 if (bus_space_map(ca->ca_iot, ca->ca_hpa + ASP_ETHER_ADDR, 226 sizeof(ga.ga_ether_address), 0, &ioh)) { 227 aprint_error(": can't map EEPROM.\n"); 228 return; 229 } 230 bus_space_read_region_1(ca->ca_iot, ioh, 0, 231 ga.ga_ether_address, sizeof(ga.ga_ether_address)); 232 bus_space_unmap(ca->ca_iot, ioh, sizeof(ga.ga_ether_address)); 233 234#ifdef USELEDS 235 machine_ledaddr = &sc->sc_trs->asp_cled; 236 machine_ledword = asp_spus[sc->sc_trs->asp_spu].ledword; 237#endif 238 239 /* reset ASP */ 240 /* sc->sc_hw->asp_reset = 1; */ 241 /* delay(400000); */ 242 243 s = splhigh(); 244 viper_setintrwnd(1 << ca->ca_irq); 245 246 sc->sc_trs->asp_imr = 0; 247 (void)sc->sc_trs->asp_irr; 248 249 /* Establish the interrupt register. */ 250 hppa_interrupt_register_establish(ci, &sc->sc_ir); 251 sc->sc_ir.ir_name = device_xname(self); 252 sc->sc_ir.ir_mask = &sc->sc_trs->asp_imr; 253 sc->sc_ir.ir_req = &sc->sc_trs->asp_irr; 254 255 splx(s); 256 257 aprint_normal(": %s rev %d, lan %d scsi %d\n", 258 asp_spus[sc->sc_trs->asp_spu].name, sc->sc_hw->asp_version, 259 sc->sc_trs->asp_lan, sc->sc_trs->asp_scsi); 260 261 /* Attach the GSC bus. */ 262 ga.ga_ca = *ca; /* clone from us */ 263 if (strcmp(device_xname(parent), "mainbus0") == 0) { 264 ga.ga_dp.dp_bc[0] = ga.ga_dp.dp_bc[1]; 265 ga.ga_dp.dp_bc[1] = ga.ga_dp.dp_bc[2]; 266 ga.ga_dp.dp_bc[2] = ga.ga_dp.dp_bc[3]; 267 ga.ga_dp.dp_bc[3] = ga.ga_dp.dp_bc[4]; 268 ga.ga_dp.dp_bc[4] = ga.ga_dp.dp_bc[5]; 269 ga.ga_dp.dp_bc[5] = ga.ga_dp.dp_mod; 270 ga.ga_dp.dp_mod = 0; 271 } 272 273 ga.ga_name = "gsc"; 274 ga.ga_ir = &sc->sc_ir; 275 ga.ga_fix_args = asp_fix_args; 276 ga.ga_fix_args_cookie = sc; 277 ga.ga_scsi_target = sc->sc_trs->asp_scsi; 278 config_found(self, &ga, gscprint, CFARGS_NONE); 279} 280