1183371Simp/*- 2183371Simp * Copyright (c) 2007 Bruce M. Simpson. 3183371Simp * All rights reserved. 4183371Simp * 5183371Simp * Redistribution and use in source and binary forms, with or without 6183371Simp * modification, are permitted provided that the following conditions 7183371Simp * are met: 8183371Simp * 1. Redistributions of source code must retain the above copyright 9183371Simp * notice, this list of conditions and the following disclaimer. 10183371Simp * 2. Redistributions in binary form must reproduce the above copyright 11183371Simp * notice, this list of conditions and the following disclaimer in the 12183371Simp * documentation and/or other materials provided with the distribution. 13183371Simp * 14183371Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15183371Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16183371Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17183371Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18183371Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19183371Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20183371Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21183371Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22183371Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23183371Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24183371Simp * SUCH DAMAGE. 25183371Simp */ 26183371Simp 27183371Simp#include <sys/cdefs.h> 28183371Simp__FBSDID("$FreeBSD: releng/10.3/sys/dev/siba/siba.c 227848 2011-11-22 21:55:40Z marius $"); 29183371Simp 30183371Simp#include <sys/param.h> 31183371Simp#include <sys/systm.h> 32183371Simp#include <sys/bus.h> 33183371Simp#include <sys/kernel.h> 34183371Simp#include <sys/module.h> 35183371Simp#include <sys/rman.h> 36183371Simp#include <sys/malloc.h> 37183371Simp 38183371Simp#include <machine/bus.h> 39183371Simp 40203319Sweongyo#include <dev/siba/siba_ids.h> 41203319Sweongyo#include <dev/siba/sibareg.h> 42183371Simp#include <dev/siba/sibavar.h> 43183371Simp 44183371Simp/* 45183371Simp * TODO: De-mipsify this code. 46183371Simp * TODO: cpu clock calculation. -> move to siba_cc instance 47183371Simp * TODO: Hardwire IRQs for attached cores on siba at probe time. 48183371Simp * TODO: Support detach. 49183371Simp * TODO: Power management. 50183371Simp * TODO: code cleanup. 51183371Simp * TODO: Support deployments of siba other than as a system bus. 52183371Simp */ 53183371Simp 54183371Simp#ifndef MIPS_MEM_RID 55183371Simp#define MIPS_MEM_RID 0x20 56183371Simp#endif 57183371Simp 58183371Simpextern int rman_debug; 59183371Simp 60183371Simpstatic struct rman mem_rman; /* XXX move to softc */ 61183371Simp 62183371Simpstatic int siba_debug = 1; 63183371Simpstatic const char descfmt[] = "Sonics SiliconBackplane rev %s"; 64183371Simp#define SIBA_DEVDESCLEN sizeof(descfmt) + 8 65183371Simp 66183371Simp/* 67183371Simp * Device identifiers and descriptions. 68183371Simp */ 69183371Simpstatic struct siba_devid siba_devids[] = { 70183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_CHIPCOMMON, SIBA_REV_ANY, 71183371Simp "ChipCommon" }, 72183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_SDRAM, SIBA_REV_ANY, 73183371Simp "SDRAM controller" }, 74183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_PCI, SIBA_REV_ANY, 75183371Simp "PCI host interface" }, 76183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_MIPS, SIBA_REV_ANY, 77183371Simp "MIPS core" }, 78183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_ETHERNET, SIBA_REV_ANY, 79183371Simp "Ethernet core" }, 80203319Sweongyo { SIBA_VID_BROADCOM, SIBA_DEVID_USB11_HOSTDEV, SIBA_REV_ANY, 81183371Simp "USB host controller" }, 82183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_IPSEC, SIBA_REV_ANY, 83183371Simp "IPSEC accelerator" }, 84183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_SDRAMDDR, SIBA_REV_ANY, 85183371Simp "SDRAM/DDR controller" }, 86183371Simp { SIBA_VID_BROADCOM, SIBA_DEVID_MIPS_3302, SIBA_REV_ANY, 87183371Simp "MIPS 3302 core" }, 88183371Simp { 0, 0, 0, NULL } 89183371Simp}; 90183371Simp 91183371Simpstatic int siba_activate_resource(device_t, device_t, int, int, 92183371Simp struct resource *); 93212413Savgstatic device_t siba_add_child(device_t, u_int, const char *, int); 94183371Simpstatic struct resource * 95183371Simp siba_alloc_resource(device_t, device_t, int, int *, u_long, 96183371Simp u_long, u_long, u_int); 97183371Simpstatic int siba_attach(device_t); 98183371Simp#ifdef notyet 99183371Simpstatic void siba_destroy_devinfo(struct siba_devinfo *); 100183371Simp#endif 101183371Simpstatic struct siba_devid * 102183371Simp siba_dev_match(uint16_t, uint16_t, uint8_t); 103183371Simpstatic struct resource_list * 104183371Simp siba_get_reslist(device_t, device_t); 105183371Simpstatic uint8_t siba_getirq(uint16_t); 106183371Simpstatic int siba_print_all_resources(device_t dev); 107183371Simpstatic int siba_print_child(device_t, device_t); 108183371Simpstatic int siba_probe(device_t); 109183371Simpstatic void siba_probe_nomatch(device_t, device_t); 110183371Simpint siba_read_ivar(device_t, device_t, int, uintptr_t *); 111183371Simpstatic struct siba_devinfo * 112183371Simp siba_setup_devinfo(device_t, uint8_t); 113183371Simpint siba_write_ivar(device_t, device_t, int, uintptr_t); 114203319Sweongyouint8_t siba_getncores(device_t, uint16_t); 115183371Simp 116183371Simp/* 117183371Simp * On the Sentry5, the system bus IRQs are the same as the 118183371Simp * MIPS IRQs. Particular cores are hardwired to certain IRQ lines. 119183371Simp */ 120183371Simpstatic uint8_t 121183371Simpsiba_getirq(uint16_t devid) 122183371Simp{ 123183371Simp uint8_t irq; 124183371Simp 125183371Simp switch (devid) { 126183371Simp case SIBA_DEVID_CHIPCOMMON: 127183371Simp irq = 0; 128183371Simp break; 129183371Simp case SIBA_DEVID_ETHERNET: 130183371Simp irq = 1; 131183371Simp break; 132183371Simp case SIBA_DEVID_IPSEC: 133183371Simp irq = 2; 134183371Simp break; 135203319Sweongyo case SIBA_DEVID_USB11_HOSTDEV: 136183371Simp irq = 3; 137183371Simp break; 138183371Simp case SIBA_DEVID_PCI: 139183371Simp irq = 4; 140183371Simp break; 141183371Simp#if 0 142183371Simp /* 143183371Simp * 5 is reserved for the MIPS on-chip timer interrupt; 144183371Simp * it is hard-wired by the tick driver. 145183371Simp */ 146183371Simp case SIBA_DEVID_MIPS: 147183371Simp case SIBA_DEVID_MIPS_3302: 148183371Simp irq = 5; 149183371Simp break; 150183371Simp#endif 151183371Simp default: 152183371Simp irq = 0xFF; /* this core does not need an irq */ 153183371Simp break; 154183371Simp } 155183371Simp 156183371Simp return (irq); 157183371Simp} 158183371Simp 159183371Simpstatic int 160183371Simpsiba_probe(device_t dev) 161183371Simp{ 162183371Simp struct siba_softc *sc = device_get_softc(dev); 163183371Simp uint32_t idlo, idhi; 164183371Simp uint16_t ccid; 165183371Simp int rid; 166183371Simp 167203319Sweongyo sc->siba_dev = dev; 168183371Simp 169183371Simp //rman_debug = 1; /* XXX */ 170183371Simp 171183371Simp /* 172183371Simp * Map the ChipCommon register set using the hints the kernel 173183371Simp * was compiled with. 174183371Simp */ 175183371Simp rid = MIPS_MEM_RID; 176203319Sweongyo sc->siba_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 177183371Simp RF_ACTIVE); 178203319Sweongyo if (sc->siba_mem_res == NULL) { 179183371Simp device_printf(dev, "unable to allocate probe aperture\n"); 180183371Simp return (ENXIO); 181183371Simp } 182203319Sweongyo sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res); 183203319Sweongyo sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res); 184203319Sweongyo sc->siba_maddr = rman_get_start(sc->siba_mem_res); 185203319Sweongyo sc->siba_msize = rman_get_size(sc->siba_mem_res); 186183371Simp 187183371Simp if (siba_debug) { 188183371Simp device_printf(dev, "start %08x len %08x\n", 189203319Sweongyo sc->siba_maddr, sc->siba_msize); 190183371Simp } 191183371Simp 192203319Sweongyo idlo = siba_mips_read_4(sc, 0, SIBA_IDLOW); 193203319Sweongyo idhi = siba_mips_read_4(sc, 0, SIBA_IDHIGH); 194183371Simp ccid = ((idhi & 0x8ff0) >> 4); 195183371Simp if (siba_debug) { 196183371Simp device_printf(dev, "idlo = %08x\n", idlo); 197183371Simp device_printf(dev, "idhi = %08x\n", idhi); 198183371Simp device_printf(dev, " chipcore id = %08x\n", ccid); 199183371Simp } 200183371Simp 201183371Simp /* 202183371Simp * For now, check that the first core is the ChipCommon core. 203183371Simp */ 204183371Simp if (ccid != SIBA_DEVID_CHIPCOMMON) { 205183371Simp if (siba_debug) 206183371Simp device_printf(dev, "first core is not ChipCommon\n"); 207183371Simp return (ENXIO); 208183371Simp } 209183371Simp 210183371Simp /* 211183371Simp * Determine backplane revision and set description string. 212183371Simp */ 213183371Simp uint32_t rev; 214183371Simp char *revp; 215183371Simp char descbuf[SIBA_DEVDESCLEN]; 216183371Simp 217183371Simp rev = idlo & 0xF0000000; 218183371Simp revp = "unknown"; 219183371Simp if (rev == 0x00000000) 220183371Simp revp = "2.2"; 221183371Simp else if (rev == 0x10000000) 222183371Simp revp = "2.3"; 223183371Simp 224183371Simp (void)snprintf(descbuf, sizeof(descbuf), descfmt, revp); 225183371Simp device_set_desc_copy(dev, descbuf); 226183371Simp 227183371Simp /* 228183371Simp * Determine how many cores are present on this siba bus, so 229183371Simp * that we may map them all. 230183371Simp */ 231183371Simp uint32_t ccidreg; 232183371Simp uint16_t cc_id; 233183371Simp uint16_t cc_rev; 234183371Simp 235203319Sweongyo ccidreg = siba_mips_read_4(sc, 0, SIBA_CC_CHIPID); 236183371Simp cc_id = (ccidreg & SIBA_CC_IDMASK); 237183371Simp cc_rev = (ccidreg & SIBA_CC_REVMASK) >> SIBA_CC_REVSHIFT; 238183371Simp if (siba_debug) { 239183371Simp device_printf(dev, "ccid = %08x, cc_id = %04x, cc_rev = %04x\n", 240183371Simp ccidreg, cc_id, cc_rev); 241183371Simp } 242183371Simp 243203319Sweongyo sc->siba_ncores = siba_getncores(dev, cc_id); 244183371Simp if (siba_debug) { 245203319Sweongyo device_printf(dev, "%d cores detected.\n", sc->siba_ncores); 246183371Simp } 247183371Simp 248183371Simp /* 249183371Simp * Now we know how many cores are on this siba, release the 250183371Simp * mapping and allocate a new mapping spanning all cores on the bus. 251183371Simp */ 252183371Simp rid = MIPS_MEM_RID; 253183371Simp int result; 254203319Sweongyo result = bus_release_resource(dev, SYS_RES_MEMORY, rid, 255203319Sweongyo sc->siba_mem_res); 256183371Simp if (result != 0) { 257183371Simp device_printf(dev, "error %d releasing resource\n", result); 258183371Simp return (ENXIO); 259183371Simp } 260183371Simp 261183371Simp uint32_t total; 262203319Sweongyo total = sc->siba_ncores * SIBA_CORE_LEN; 263183371Simp 264183371Simp /* XXX Don't allocate the entire window until we 265183371Simp * enumerate the bus. Once the bus has been enumerated, 266183371Simp * and instance variables/children instantiated + populated, 267183371Simp * release the resource so children may attach. 268183371Simp */ 269203319Sweongyo sc->siba_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 270203319Sweongyo sc->siba_maddr, sc->siba_maddr + total - 1, total, RF_ACTIVE); 271203319Sweongyo if (sc->siba_mem_res == NULL) { 272183371Simp device_printf(dev, "unable to allocate entire aperture\n"); 273183371Simp return (ENXIO); 274183371Simp } 275203319Sweongyo sc->siba_mem_bt = rman_get_bustag(sc->siba_mem_res); 276203319Sweongyo sc->siba_mem_bh = rman_get_bushandle(sc->siba_mem_res); 277203319Sweongyo sc->siba_maddr = rman_get_start(sc->siba_mem_res); 278203319Sweongyo sc->siba_msize = rman_get_size(sc->siba_mem_res); 279183371Simp 280183371Simp if (siba_debug) { 281183371Simp device_printf(dev, "after remapping: start %08x len %08x\n", 282203319Sweongyo sc->siba_maddr, sc->siba_msize); 283183371Simp } 284203319Sweongyo bus_set_resource(dev, SYS_RES_MEMORY, rid, sc->siba_maddr, 285203319Sweongyo sc->siba_msize); 286183371Simp 287183371Simp /* 288183371Simp * We need a manager for the space we claim on nexus to 289183371Simp * satisfy requests from children. 290183371Simp * We need to keep the source reservation we took because 291183371Simp * otherwise it may be claimed elsewhere. 292183371Simp * XXX move to softc 293183371Simp */ 294203319Sweongyo mem_rman.rm_start = sc->siba_maddr; 295203319Sweongyo mem_rman.rm_end = sc->siba_maddr + sc->siba_msize - 1; 296183371Simp mem_rman.rm_type = RMAN_ARRAY; 297183371Simp mem_rman.rm_descr = "SiBa I/O memory addresses"; 298183371Simp if (rman_init(&mem_rman) != 0 || 299203319Sweongyo rman_manage_region(&mem_rman, mem_rman.rm_start, 300203319Sweongyo mem_rman.rm_end) != 0) { 301183371Simp panic("%s: mem_rman", __func__); 302183371Simp } 303183371Simp 304183371Simp return (0); 305183371Simp} 306183371Simp 307183371Simpstatic int 308183371Simpsiba_attach(device_t dev) 309183371Simp{ 310183371Simp struct siba_softc *sc = device_get_softc(dev); 311183371Simp struct siba_devinfo *sdi; 312183371Simp device_t child; 313183371Simp int idx; 314183371Simp 315183371Simp if (siba_debug) 316183371Simp printf("%s: entry\n", __func__); 317183371Simp 318183371Simp bus_generic_probe(dev); 319183371Simp 320183371Simp /* 321183371Simp * Now that all bus space is mapped and visible to the CPU, 322183371Simp * enumerate its children. 323183371Simp * NB: only one core may be mapped at any time if the siba bus 324183371Simp * is the child of a PCI or PCMCIA bus. 325183371Simp */ 326203319Sweongyo for (idx = 0; idx < sc->siba_ncores; idx++) { 327183371Simp sdi = siba_setup_devinfo(dev, idx); 328183371Simp child = device_add_child(dev, NULL, -1); 329183371Simp if (child == NULL) 330183371Simp panic("%s: device_add_child() failed\n", __func__); 331183371Simp device_set_ivars(child, sdi); 332183371Simp } 333183371Simp 334183371Simp return (bus_generic_attach(dev)); 335183371Simp} 336183371Simp 337183371Simpstatic struct siba_devid * 338183371Simpsiba_dev_match(uint16_t vid, uint16_t devid, uint8_t rev) 339183371Simp{ 340183371Simp size_t i, bound; 341183371Simp struct siba_devid *sd; 342183371Simp 343183371Simp bound = sizeof(siba_devids) / sizeof(struct siba_devid); 344183371Simp sd = &siba_devids[0]; 345183371Simp for (i = 0; i < bound; i++, sd++) { 346183371Simp if (((vid == SIBA_VID_ANY) || (vid == sd->sd_vendor)) && 347183371Simp ((devid == SIBA_DEVID_ANY) || (devid == sd->sd_device)) && 348183371Simp ((rev == SIBA_REV_ANY) || (rev == sd->sd_rev) || 349183371Simp (sd->sd_rev == SIBA_REV_ANY))) 350183371Simp break; 351183371Simp } 352183371Simp if (i == bound) 353183371Simp sd = NULL; 354183371Simp 355183371Simp return (sd); 356183371Simp} 357183371Simp 358183371Simpstatic int 359183371Simpsiba_print_child(device_t bus, device_t child) 360183371Simp{ 361183371Simp int retval = 0; 362183371Simp 363183371Simp retval += bus_print_child_header(bus, child); 364183371Simp retval += siba_print_all_resources(child); 365183371Simp if (device_get_flags(child)) 366183371Simp retval += printf(" flags %#x", device_get_flags(child)); 367183371Simp retval += printf(" on %s\n", device_get_nameunit(bus)); 368183371Simp 369183371Simp return (retval); 370183371Simp} 371183371Simp 372183371Simpstatic struct resource * 373183371Simpsiba_alloc_resource(device_t bus, device_t child, int type, int *rid, 374183371Simp u_long start, u_long end, u_long count, u_int flags) 375183371Simp{ 376183371Simp struct resource *rv; 377183371Simp struct resource_list *rl; 378183371Simp struct resource_list_entry *rle; 379183371Simp int isdefault, needactivate; 380183371Simp 381183371Simp#if 0 382183371Simp if (siba_debug) 383183371Simp printf("%s: entry\n", __func__); 384183371Simp#endif 385183371Simp 386183371Simp isdefault = (start == 0UL && end == ~0UL && count == 1); 387183371Simp needactivate = flags & RF_ACTIVE; 388183371Simp rl = BUS_GET_RESOURCE_LIST(bus, child); 389183371Simp rle = NULL; 390183371Simp 391183371Simp if (isdefault) { 392183371Simp rle = resource_list_find(rl, type, *rid); 393183371Simp if (rle == NULL) 394183371Simp return (NULL); 395183371Simp if (rle->res != NULL) 396183371Simp panic("%s: resource entry is busy", __func__); 397183371Simp start = rle->start; 398183371Simp end = rle->end; 399183371Simp count = rle->count; 400183371Simp } 401183371Simp 402183371Simp /* 403183371Simp * If the request is for a resource which we manage, 404183371Simp * attempt to satisfy the allocation ourselves. 405183371Simp */ 406183371Simp if (type == SYS_RES_MEMORY && 407183371Simp start >= mem_rman.rm_start && end <= mem_rman.rm_end) { 408183371Simp 409183371Simp rv = rman_reserve_resource(&mem_rman, start, end, count, 410183371Simp flags, child); 411183371Simp if (rv == 0) { 412183371Simp printf("%s: could not reserve resource\n", __func__); 413183371Simp return (0); 414183371Simp } 415183371Simp 416183371Simp rman_set_rid(rv, *rid); 417183371Simp 418183371Simp if (needactivate) { 419183371Simp if (bus_activate_resource(child, type, *rid, rv)) { 420183371Simp printf("%s: could not activate resource\n", 421183371Simp __func__); 422183371Simp rman_release_resource(rv); 423183371Simp return (0); 424183371Simp } 425183371Simp } 426183371Simp 427183371Simp return (rv); 428183371Simp } 429183371Simp 430183371Simp /* 431183371Simp * Pass the request to the parent, usually MIPS nexus. 432183371Simp */ 433183371Simp if (siba_debug) 434183371Simp printf("%s: proxying request to parent\n", __func__); 435183371Simp return (resource_list_alloc(rl, bus, child, type, rid, 436183371Simp start, end, count, flags)); 437183371Simp} 438183371Simp 439183371Simp/* 440183371Simp * The parent bus is responsible for resource activation; in the 441183371Simp * case of MIPS, this boils down to setting the virtual address and 442183371Simp * bus handle by mapping the physical address into KSEG1. 443183371Simp */ 444183371Simpstatic int 445183371Simpsiba_activate_resource(device_t bus, device_t child, int type, int rid, 446183371Simp struct resource *r) 447183371Simp{ 448183371Simp 449183371Simp return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child, type, 450183371Simp rid, r)); 451183371Simp} 452183371Simp 453183371Simpstatic struct siba_devinfo * 454183371Simpsiba_setup_devinfo(device_t dev, uint8_t idx) 455183371Simp{ 456183371Simp struct siba_softc *sc = device_get_softc(dev); 457183371Simp struct siba_devinfo *sdi; 458183371Simp uint32_t idlo, idhi, rev; 459183371Simp uint16_t vendorid, devid; 460183371Simp bus_addr_t baseaddr; 461183371Simp 462183371Simp sdi = malloc(sizeof(*sdi), M_DEVBUF, M_WAITOK | M_ZERO); 463183371Simp resource_list_init(&sdi->sdi_rl); 464183371Simp 465203319Sweongyo idlo = siba_mips_read_4(sc, idx, SIBA_IDLOW); 466203319Sweongyo idhi = siba_mips_read_4(sc, idx, SIBA_IDHIGH); 467183371Simp 468203319Sweongyo vendorid = (idhi & SIBA_IDHIGH_VENDORMASK) >> 469203319Sweongyo SIBA_IDHIGH_VENDOR_SHIFT; 470183371Simp devid = ((idhi & 0x8ff0) >> 4); 471203319Sweongyo rev = (idhi & SIBA_IDHIGH_REVLO); 472203319Sweongyo rev |= (idhi & SIBA_IDHIGH_REVHI) >> SIBA_IDHIGH_REVHI_SHIFT; 473183371Simp 474183371Simp sdi->sdi_vid = vendorid; 475183371Simp sdi->sdi_devid = devid; 476183371Simp sdi->sdi_rev = rev; 477183371Simp sdi->sdi_idx = idx; 478183371Simp sdi->sdi_irq = siba_getirq(devid); 479183371Simp 480183371Simp /* 481183371Simp * Determine memory window on bus and irq if one is needed. 482183371Simp */ 483203319Sweongyo baseaddr = sc->siba_maddr + (idx * SIBA_CORE_LEN); 484183371Simp resource_list_add(&sdi->sdi_rl, SYS_RES_MEMORY, 485183371Simp MIPS_MEM_RID, /* XXX */ 486183371Simp baseaddr, baseaddr + SIBA_CORE_LEN - 1, SIBA_CORE_LEN); 487183371Simp 488183371Simp if (sdi->sdi_irq != 0xff) { 489183371Simp resource_list_add(&sdi->sdi_rl, SYS_RES_IRQ, 490183371Simp 0, sdi->sdi_irq, sdi->sdi_irq, 1); 491183371Simp } 492183371Simp 493183371Simp return (sdi); 494183371Simp} 495183371Simp 496183371Simp#ifdef notyet 497183371Simpstatic void 498183371Simpsiba_destroy_devinfo(struct siba_devinfo *sdi) 499183371Simp{ 500183371Simp 501183371Simp resource_list_free(&sdi->sdi_rl); 502183371Simp free(sdi, M_DEVBUF); 503183371Simp} 504183371Simp#endif 505183371Simp 506183371Simp/* XXX is this needed? */ 507183371Simpstatic device_t 508212413Savgsiba_add_child(device_t dev, u_int order, const char *name, int unit) 509183371Simp{ 510183371Simp#if 1 511183371Simp 512183371Simp device_printf(dev, "%s: entry\n", __func__); 513183371Simp return (NULL); 514183371Simp#else 515183371Simp device_t child; 516183371Simp struct siba_devinfo *sdi; 517183371Simp 518183371Simp child = device_add_child_ordered(dev, order, name, unit); 519183371Simp if (child == NULL) 520183371Simp return (NULL); 521183371Simp 522183371Simp sdi = malloc(sizeof(struct siba_devinfo), M_DEVBUF, M_NOWAIT|M_ZERO); 523183371Simp if (sdi == NULL) 524183371Simp return (NULL); 525183371Simp 526183371Simp device_set_ivars(child, sdi); 527183371Simp return (child); 528183371Simp#endif 529183371Simp} 530183371Simp 531183371Simpint 532183371Simpsiba_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 533183371Simp{ 534183371Simp struct siba_devinfo *sdi; 535183371Simp 536183371Simp sdi = device_get_ivars(child); 537183371Simp 538183371Simp switch (which) { 539183371Simp case SIBA_IVAR_VENDOR: 540183371Simp *result = sdi->sdi_vid; 541183371Simp break; 542183371Simp case SIBA_IVAR_DEVICE: 543183371Simp *result = sdi->sdi_devid; 544183371Simp break; 545183371Simp case SIBA_IVAR_REVID: 546183371Simp *result = sdi->sdi_rev; 547183371Simp break; 548183371Simp case SIBA_IVAR_CORE_INDEX: 549183371Simp *result = sdi->sdi_idx; 550183371Simp break; 551183371Simp default: 552183371Simp return (ENOENT); 553183371Simp } 554183371Simp 555183371Simp return (0); 556183371Simp} 557183371Simp 558183371Simpint 559183371Simpsiba_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 560183371Simp{ 561183371Simp 562183371Simp return (EINVAL); 563183371Simp} 564183371Simp 565183371Simpstatic void 566183371Simpsiba_probe_nomatch(device_t dev, device_t child) 567183371Simp{ 568183371Simp 569183371Simp /* 570183371Simp * Announce devices which weren't attached after we probed the bus. 571183371Simp */ 572183371Simp if (siba_debug) { 573183371Simp struct siba_devid *sd; 574183371Simp 575183371Simp sd = siba_dev_match(siba_get_vendor(child), 576183371Simp siba_get_device(child), SIBA_REV_ANY); 577183371Simp if (sd != NULL && sd->sd_desc != NULL) { 578183371Simp device_printf(dev, "<%s> " 579183371Simp "at device %d (no driver attached)\n", 580183371Simp sd->sd_desc, siba_get_core_index(child)); 581183371Simp } else { 582183371Simp device_printf(dev, "<0x%04x, 0x%04x> " 583183371Simp "at device %d (no driver attached)\n", 584183371Simp siba_get_vendor(child), siba_get_device(child), 585183371Simp siba_get_core_index(child)); 586183371Simp } 587183371Simp } 588183371Simp} 589183371Simp 590183371Simpstatic int 591183371Simpsiba_print_all_resources(device_t dev) 592183371Simp{ 593183371Simp struct siba_devinfo *sdi = device_get_ivars(dev); 594183371Simp struct resource_list *rl = &sdi->sdi_rl; 595183371Simp int retval = 0; 596183371Simp 597183371Simp if (STAILQ_FIRST(rl)) 598183371Simp retval += printf(" at"); 599183371Simp 600183371Simp retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); 601183371Simp retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); 602183371Simp 603183371Simp return (retval); 604183371Simp} 605183371Simp 606183371Simpstatic struct resource_list * 607183371Simpsiba_get_reslist(device_t dev, device_t child) 608183371Simp{ 609183371Simp struct siba_devinfo *sdi = device_get_ivars(child); 610183371Simp 611183371Simp return (&sdi->sdi_rl); 612183371Simp} 613183371Simp 614183371Simpstatic device_method_t siba_methods[] = { 615183371Simp /* Device interface */ 616183371Simp DEVMETHOD(device_attach, siba_attach), 617183371Simp DEVMETHOD(device_detach, bus_generic_detach), 618183371Simp DEVMETHOD(device_probe, siba_probe), 619183371Simp DEVMETHOD(device_resume, bus_generic_resume), 620183371Simp DEVMETHOD(device_shutdown, bus_generic_shutdown), 621183371Simp DEVMETHOD(device_suspend, bus_generic_suspend), 622183371Simp 623183371Simp /* Bus interface */ 624183371Simp DEVMETHOD(bus_activate_resource,siba_activate_resource), 625183371Simp DEVMETHOD(bus_add_child, siba_add_child), 626183371Simp DEVMETHOD(bus_alloc_resource, siba_alloc_resource), 627183371Simp DEVMETHOD(bus_get_resource_list,siba_get_reslist), 628183371Simp DEVMETHOD(bus_print_child, siba_print_child), 629183371Simp DEVMETHOD(bus_probe_nomatch, siba_probe_nomatch), 630183371Simp DEVMETHOD(bus_read_ivar, siba_read_ivar), 631183371Simp DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 632183371Simp DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 633183371Simp DEVMETHOD(bus_write_ivar, siba_write_ivar), 634183371Simp 635227848Smarius DEVMETHOD_END 636183371Simp}; 637183371Simp 638183371Simpstatic driver_t siba_driver = { 639183371Simp "siba", 640183371Simp siba_methods, 641183371Simp sizeof(struct siba_softc), 642183371Simp}; 643183371Simpstatic devclass_t siba_devclass; 644183371Simp 645183371SimpDRIVER_MODULE(siba, nexus, siba_driver, siba_devclass, 0, 0); 646