/* $NetBSD: autoconf.c,v 1.101 2023/12/20 15:34:45 thorpej Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.101 2023/12/20 15:34:45 thorpej Exp $"); #include "opt_compat_netbsd.h" #include "opt_cputype.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "locators.h" #include "ioconf.h" void gencnslask(void); const struct cpu_dep *dep_call; #define MAINBUS 0 void cpu_configure(void) { if (config_rootfound("mainbus", NULL) == NULL) panic("mainbus not configured"); /* * We're ready to start up. Clear CPU cold start flag. * Soft cold-start flag will be cleared in configure(). */ if (dep_call->cpu_clrf) (*dep_call->cpu_clrf)(); } void cpu_rootconf(void) { /* * The device we booted from are looked for during autoconfig. * If there has been a match, it's already been done. */ #ifdef DEBUG printf("booted from type %d unit %d csr 0x%lx adapter %lx slave %d\n", rpb.devtyp, rpb.unit, rpb.csrphy, rpb.adpphy, rpb.slave); #endif printf("boot device: %s\n", booted_device ? device_xname(booted_device) : ""); rootconf(); } static int mainbus_print(void *, const char *); static int mainbus_match(device_t, cfdata_t, void *); static void mainbus_attach(device_t, device_t, void *); extern struct vax_bus_space vax_mem_bus_space; extern struct vax_bus_dma_tag vax_bus_dma_tag; int mainbus_print(void *aux, const char *name) { struct mainbus_attach_args * const ma = aux; if (name) { aprint_naive("%s at %s", ma->ma_type, name); aprint_normal("%s at %s", ma->ma_type, name); } return UNCONF; } int mainbus_match(device_t parent, cfdata_t cf, void *aux) { return 1; /* First (and only) mainbus */ } void mainbus_attach(device_t parent, device_t self, void *aux) { struct mainbus_attach_args ma; const char * const * devp; aprint_naive("\n"); aprint_normal("\n"); for (devp = dep_call->cpu_devs; *devp != NULL; devp++) { ma.ma_type = *devp; ma.ma_iot = &vax_mem_bus_space; ma.ma_dmat = &vax_bus_dma_tag; config_found(self, &ma, mainbus_print, CFARGS_NONE); } /* * Hopefully there a master bus? * Maybe should have this as master instead of mainbus. */ #if defined(COMPAT_14) if (rpb.rpb_base == (void *)-1) printf("\nWARNING: you must update your boot blocks.\n\n"); #endif } CFATTACH_DECL_NEW(mainbus, 0, mainbus_match, mainbus_attach, NULL, NULL); static int cpu_mainbus_match(device_t, cfdata_t, void *); static void cpu_mainbus_attach(device_t, device_t, void *); int cpu_mainbus_match(device_t self, cfdata_t cf, void *aux) { struct mainbus_attach_args *ma = aux; return strcmp(cpu_cd.cd_name, ma->ma_type) == 0; } void cpu_mainbus_attach(device_t parent, device_t self, void *aux) { struct cpu_info *ci; KASSERT(device_private(self) == NULL); ci = curcpu(); device_set_private(self, ci); ci->ci_dev = self; ci->ci_cpuid = device_unit(self); if (dep_call->cpu_attach_cpu != NULL) (*dep_call->cpu_attach_cpu)(self); else if (ci->ci_cpustr) { aprint_naive(": %s\n", ci->ci_cpustr); aprint_normal(": %s\n", ci->ci_cpustr); } else { aprint_naive("\n"); aprint_normal("\n"); } } CFATTACH_DECL_NEW(cpu_mainbus, 0, cpu_mainbus_match, cpu_mainbus_attach, NULL, NULL); #include "sd.h" #include "cd.h" #include "rl.h" #include "ra.h" #include "hp.h" #include "ry.h" static int ubtest(void *); static int jmfr(const char *, device_t, int); static int booted_qe(device_t, void *); static int booted_qt(device_t, void *); static int booted_le(device_t, void *); static int booted_ze(device_t, void *); static int booted_de(device_t, void *); static int booted_ni(device_t, void *); #if NSD > 0 || NCD > 0 static int booted_sd(device_t, void *); #endif #if NRL > 0 static int booted_rl(device_t, void *); #endif #if NRA > 0 || NRACD > 0 static int booted_ra(device_t, void *); #endif #if NHP static int booted_hp(device_t, void *); #endif #if NRD static int booted_rd(device_t, void *); #endif int (* const devreg[])(device_t, void *) = { booted_qe, booted_qt, booted_le, booted_ze, booted_de, booted_ni, #if NSD > 0 || NCD > 0 booted_sd, #endif #if NRL > 0 booted_rl, #endif #if NRA booted_ra, #endif #if NHP booted_hp, #endif #if NRD booted_rd, #endif 0, }; #define ubreg(x) ((x) & 017777) void device_register(device_t dev, void *aux) { int (* const * dp)(device_t, void *) = devreg; /* If there's a synthetic RPB, we can't trust it */ if (rpb.rpb_base == (void *)-1) return; while (*dp) { if ((**dp)(dev, aux)) { booted_device = dev; break; } dp++; } } /* * Simple checks. Return 1 on fail. */ int jmfr(const char *n, device_t dev, int nr) { if (rpb.devtyp != nr) return 1; return !device_is_a(dev, n); } #include int ubtest(void *aux) { paddr_t p; p = kvtophys(((struct uba_attach_args *)aux)->ua_ioh); if (rpb.csrphy != p) return 1; return 0; } #if 1 /* NNI */ #include int booted_ni(device_t dev, void *aux) { struct bi_attach_args *ba = aux; if (jmfr("ni", dev, BDEV_NI) || (kvtophys(ba->ba_ioh) != rpb.csrphy)) return 0; return 1; } #endif /* NNI */ #if 1 /* NDE */ int booted_de(device_t dev, void *aux) { if (jmfr("de", dev, BDEV_DE) || ubtest(aux)) return 0; return 1; } #endif /* NDE */ int booted_le(device_t dev, void *aux) { if (jmfr("le", dev, BDEV_LE)) return 0; return 1; } int booted_ze(device_t dev, void *aux) { if (jmfr("ze", dev, BDEV_ZE)) return 0; return 1; } int booted_qt(device_t dev, void *aux) { if (jmfr("qt", dev, BDEV_QE) || ubtest(aux)) return 0; return 1; } #if 1 /* NQE */ int booted_qe(device_t dev, void *aux) { if (jmfr("qe", dev, BDEV_QE) || ubtest(aux)) return 0; return 1; } #endif /* NQE */ #if NSD > 0 || NCD > 0 #include #include int booted_sd(device_t dev, void *aux) { struct scsipibus_attach_args *sa = aux; device_t ppdev; /* Is this a SCSI device? */ if (jmfr("sd", dev, BDEV_SD) && jmfr("sd", dev, BDEV_SDN) && jmfr("cd", dev, BDEV_SD) && jmfr("cd", dev, BDEV_SDN)) return 0; if (sa->sa_periph->periph_channel->chan_bustype->bustype_type != SCSIPI_BUSTYPE_SCSI) return 0; /* ``Cannot happen'' */ if (sa->sa_periph->periph_target != (rpb.unit/100) || sa->sa_periph->periph_lun != (rpb.unit % 100)) return 0; /* Wrong unit */ ppdev = device_parent(device_parent(dev)); /* VS3100 NCR 53C80 (si) & VS4000 NCR 53C94 (asc) */ if ((jmfr("si", ppdev, BDEV_SD) == 0 || /* new name */ jmfr("asc", ppdev, BDEV_SD) == 0 || jmfr("asc", ppdev, BDEV_SDN) == 0) && (device_cfdata(ppdev)->cf_loc[VSBUSCF_CSR] == rpb.csrphy)) return 1; return 0; /* Where did we come from??? */ } #endif #if NRL > 0 #include int booted_rl(device_t dev, void *aux) { struct rlc_attach_args *raa = aux; static int ub; if (jmfr("rlc", dev, BDEV_RL) == 0) ub = ubtest(aux); if (ub) return 0; if (jmfr("rl", dev, BDEV_RL)) return 0; if (raa->hwid != rpb.unit) return 0; /* Wrong unit number */ return 1; } #endif #if NRA > 0 || NRACD > 0 #include #include #include int booted_ra(device_t dev, void *aux) { struct drive_attach_args *da = aux; struct mscp_softc *pdev = device_private(device_parent(dev)); paddr_t ioaddr; if (jmfr("ra", dev, BDEV_UDA) && jmfr("racd", dev, BDEV_UDA)) return 0; if (da->da_mp->mscp_unit != rpb.unit) return 0; /* Wrong unit number */ ioaddr = kvtophys(pdev->mi_iph); /* Get phys addr of CSR */ if (rpb.devtyp == BDEV_UDA && rpb.csrphy == ioaddr) return 1; /* Did match CSR */ return 0; } #endif #if NHP #include int booted_hp(device_t dev, void *aux) { static int mbaaddr; /* Save last adapter address */ if (jmfr("mba", dev, BDEV_HP) == 0) { struct sbi_attach_args *sa = aux; mbaaddr = kvtophys(sa->sa_ioh); return 0; } if (jmfr("hp", dev, BDEV_HP)) return 0; if (((struct mba_attach_args *)aux)->ma_unit != rpb.unit) return 0; if (mbaaddr != rpb.adpphy) return 0; return 1; } #endif #if NRD int booted_rd(device_t dev, void *aux) { int *nr = aux; /* XXX - use the correct attach struct */ if (jmfr("rd", dev, BDEV_RD)) return 0; if (*nr != rpb.unit) return 0; return 1; } #endif