2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/systm.h>
40 #include <machine/bus.h>
42 #include <dev/bhnd/cores/chipc/chipcreg.h>
43 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
48 static bhnd_erom_class_t *
49 siba_get_erom_class(driver_t *driver)
51 return (&siba_erom_parser);
55 siba_probe(device_t dev)
57 device_set_desc(dev, "SIBA BHND bus");
58 return (BUS_PROBE_DEFAULT);
62 * Default siba(4) bus driver implementation of DEVICE_ATTACH().
64 * This implementation initializes internal siba(4) state and performs
65 * bus enumeration, and must be called by subclassing drivers in
66 * DEVICE_ATTACH() before any other bus methods.
69 siba_attach(device_t dev)
71 struct siba_softc *sc;
74 sc = device_get_softc(dev);
77 /* Enumerate children */
78 if ((error = siba_add_children(dev))) {
79 device_delete_children(dev);
87 siba_detach(device_t dev)
89 return (bhnd_generic_detach(dev));
93 siba_resume(device_t dev)
95 return (bhnd_generic_resume(dev));
99 siba_suspend(device_t dev)
101 return (bhnd_generic_suspend(dev));
105 siba_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
107 const struct siba_devinfo *dinfo;
108 const struct bhnd_core_info *cfg;
110 dinfo = device_get_ivars(child);
111 cfg = &dinfo->core_id.core_info;
114 case BHND_IVAR_VENDOR:
115 *result = cfg->vendor;
117 case BHND_IVAR_DEVICE:
118 *result = cfg->device;
120 case BHND_IVAR_HWREV:
121 *result = cfg->hwrev;
123 case BHND_IVAR_DEVICE_CLASS:
124 *result = bhnd_core_class(cfg);
126 case BHND_IVAR_VENDOR_NAME:
127 *result = (uintptr_t) bhnd_vendor_name(cfg->vendor);
129 case BHND_IVAR_DEVICE_NAME:
130 *result = (uintptr_t) bhnd_core_name(cfg);
132 case BHND_IVAR_CORE_INDEX:
133 *result = cfg->core_idx;
135 case BHND_IVAR_CORE_UNIT:
138 case BHND_IVAR_PMU_INFO:
139 *result = (uintptr_t) dinfo->pmu_info;
147 siba_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
149 struct siba_devinfo *dinfo;
151 dinfo = device_get_ivars(child);
154 case BHND_IVAR_VENDOR:
155 case BHND_IVAR_DEVICE:
156 case BHND_IVAR_HWREV:
157 case BHND_IVAR_DEVICE_CLASS:
158 case BHND_IVAR_VENDOR_NAME:
159 case BHND_IVAR_DEVICE_NAME:
160 case BHND_IVAR_CORE_INDEX:
161 case BHND_IVAR_CORE_UNIT:
163 case BHND_IVAR_PMU_INFO:
164 dinfo->pmu_info = (struct bhnd_core_pmu_info *) value;
171 static struct resource_list *
172 siba_get_resource_list(device_t dev, device_t child)
174 struct siba_devinfo *dinfo = device_get_ivars(child);
175 return (&dinfo->resources);
179 siba_read_iost(device_t dev, device_t child, uint16_t *iost)
184 error = bhnd_read_config(child, SIBA_CFG0_TMSTATEHIGH, &tmhigh, 4);
188 *iost = (SIBA_REG_GET(tmhigh, TMH_SISF));
193 siba_read_ioctl(device_t dev, device_t child, uint16_t *ioctl)
198 if ((error = bhnd_read_config(child, SIBA_CFG0_TMSTATELOW, &ts_low, 4)))
201 *ioctl = (SIBA_REG_GET(ts_low, TML_SICF));
206 siba_write_ioctl(device_t dev, device_t child, uint16_t value, uint16_t mask)
208 struct siba_devinfo *dinfo;
209 struct bhnd_resource *r;
210 uint32_t ts_low, ts_mask;
212 if (device_get_parent(child) != dev)
215 /* Fetch CFG0 mapping */
216 dinfo = device_get_ivars(child);
217 if ((r = dinfo->cfg[0]) == NULL)
220 /* Mask and set TMSTATELOW core flag bits */
221 ts_mask = (mask << SIBA_TML_SICF_SHIFT) & SIBA_TML_SICF_MASK;
222 ts_low = (value << SIBA_TML_SICF_SHIFT) & ts_mask;
224 return (siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
229 siba_is_hw_suspended(device_t dev, device_t child)
235 /* Fetch target state */
236 error = bhnd_read_config(child, SIBA_CFG0_TMSTATELOW, &ts_low, 4);
238 device_printf(child, "error reading HW reset state: %d\n",
243 /* Is core held in RESET? */
244 if (ts_low & SIBA_TML_RESET)
247 /* Is core clocked? */
248 ioctl = SIBA_REG_GET(ts_low, TML_SICF);
249 if (!(ioctl & BHND_IOCTL_CLK_EN))
256 siba_reset_hw(device_t dev, device_t child, uint16_t ioctl)
258 struct siba_devinfo *dinfo;
259 struct bhnd_resource *r;
260 uint32_t ts_low, imstate;
263 if (device_get_parent(child) != dev)
266 dinfo = device_get_ivars(child);
268 /* Can't suspend the core without access to the CFG0 registers */
269 if ((r = dinfo->cfg[0]) == NULL)
272 /* We require exclusive control over BHND_IOCTL_CLK_EN and
273 * BHND_IOCTL_CLK_FORCE. */
274 if (ioctl & (BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE))
277 /* Place core into known RESET state */
278 if ((error = BHND_BUS_SUSPEND_HW(dev, child)))
281 /* Leaving the core in reset, set the caller's IOCTL flags and
282 * enable the core's clocks. */
283 ts_low = (ioctl | BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE) <<
285 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
286 ts_low, SIBA_TML_SICF_MASK);
290 /* Clear any target errors */
291 if (bhnd_bus_read_4(r, SIBA_CFG0_TMSTATEHIGH) & SIBA_TMH_SERR) {
292 error = siba_write_target_state(child, dinfo,
293 SIBA_CFG0_TMSTATEHIGH, 0, SIBA_TMH_SERR);
298 /* Clear any initiator errors */
299 imstate = bhnd_bus_read_4(r, SIBA_CFG0_IMSTATE);
300 if (imstate & (SIBA_IM_IBE|SIBA_IM_TO)) {
301 error = siba_write_target_state(child, dinfo, SIBA_CFG0_IMSTATE,
302 0, SIBA_IM_IBE|SIBA_IM_TO);
307 /* Release from RESET while leaving clocks forced, ensuring the
308 * signal propagates throughout the core */
309 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
310 0x0, SIBA_TML_RESET);
314 /* The core should now be active; we can clear the BHND_IOCTL_CLK_FORCE
315 * bit and allow the core to manage clock gating. */
316 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
317 0x0, (BHND_IOCTL_CLK_FORCE << SIBA_TML_SICF_SHIFT));
325 siba_suspend_hw(device_t dev, device_t child)
327 struct siba_devinfo *dinfo;
328 struct bhnd_core_pmu_info *pm;
329 struct bhnd_resource *r;
330 uint32_t idl, ts_low;
334 if (device_get_parent(child) != dev)
337 dinfo = device_get_ivars(child);
338 pm = dinfo->pmu_info;
340 /* Can't suspend the core without access to the CFG0 registers */
341 if ((r = dinfo->cfg[0]) == NULL)
344 /* Already in RESET? */
345 ts_low = bhnd_bus_read_4(r, SIBA_CFG0_TMSTATELOW);
346 if (ts_low & SIBA_TML_RESET) {
347 /* Clear IOCTL flags, ensuring the clock is disabled */
348 return (siba_write_target_state(child, dinfo,
349 SIBA_CFG0_TMSTATELOW, 0x0, SIBA_TML_SICF_MASK));
354 /* If clocks are already disabled, we can put the core directly
356 ioctl = SIBA_REG_GET(ts_low, TML_SICF);
357 if (!(ioctl & BHND_IOCTL_CLK_EN)) {
358 /* Set RESET and clear IOCTL flags */
359 return (siba_write_target_state(child, dinfo,
360 SIBA_CFG0_TMSTATELOW,
362 SIBA_TML_RESET | SIBA_TML_SICF_MASK));
365 /* Reject any further target backplane transactions */
366 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
367 SIBA_TML_REJ, SIBA_TML_REJ);
371 /* If this is an initiator core, we need to reject initiator
372 * transactions too. */
373 idl = bhnd_bus_read_4(r, SIBA_CFG0_IDLOW);
374 if (idl & SIBA_IDL_INIT) {
375 error = siba_write_target_state(child, dinfo, SIBA_CFG0_IMSTATE,
376 SIBA_IM_RJ, SIBA_IM_RJ);
381 /* Put the core into RESET|REJECT, forcing clocks to ensure the RESET
382 * signal propagates throughout the core, leaving REJECT asserted. */
383 ts_low = SIBA_TML_RESET;
384 ts_low |= (BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE) <<
387 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
392 /* Give RESET ample time */
395 /* Leaving core in reset, disable all clocks, clear REJ flags and
397 error = siba_write_target_state(child, dinfo, SIBA_CFG0_TMSTATELOW,
399 SIBA_TML_RESET | SIBA_TML_REJ | SIBA_TML_SICF_MASK);
403 /* Clear previously asserted initiator reject */
404 if (idl & SIBA_IDL_INIT) {
405 error = siba_write_target_state(child, dinfo, SIBA_CFG0_IMSTATE,
411 /* Core is now in RESET, with clocks disabled and REJ not asserted.
413 * We lastly need to inform the PMU, releasing any outstanding per-core
416 if ((error = BHND_PMU_CORE_RELEASE(pm->pm_pmu, pm)))
424 siba_read_config(device_t dev, device_t child, bus_size_t offset, void *value,
427 struct siba_devinfo *dinfo;
430 /* Must be directly attached */
431 if (device_get_parent(child) != dev)
434 /* CFG0 registers must be available */
435 dinfo = device_get_ivars(child);
436 if (dinfo->cfg[0] == NULL)
439 /* Offset must fall within CFG0 */
440 r_size = rman_get_size(dinfo->cfg[0]->res);
441 if (r_size < offset || r_size - offset < width)
446 *((uint8_t *)value) = bhnd_bus_read_1(dinfo->cfg[0], offset);
449 *((uint16_t *)value) = bhnd_bus_read_2(dinfo->cfg[0], offset);
452 *((uint32_t *)value) = bhnd_bus_read_4(dinfo->cfg[0], offset);
460 siba_write_config(device_t dev, device_t child, bus_size_t offset,
461 const void *value, u_int width)
463 struct siba_devinfo *dinfo;
464 struct bhnd_resource *r;
467 /* Must be directly attached */
468 if (device_get_parent(child) != dev)
471 /* CFG0 registers must be available */
472 dinfo = device_get_ivars(child);
473 if ((r = dinfo->cfg[0]) == NULL)
476 /* Offset must fall within CFG0 */
477 r_size = rman_get_size(r->res);
478 if (r_size < offset || r_size - offset < width)
483 bhnd_bus_write_1(r, offset, *(const uint8_t *)value);
486 bhnd_bus_write_2(r, offset, *(const uint8_t *)value);
489 bhnd_bus_write_4(r, offset, *(const uint8_t *)value);
497 siba_get_port_count(device_t dev, device_t child, bhnd_port_type type)
499 struct siba_devinfo *dinfo;
501 /* delegate non-bus-attached devices to our parent */
502 if (device_get_parent(child) != dev)
503 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child,
506 dinfo = device_get_ivars(child);
507 return (siba_addrspace_port_count(dinfo->core_id.num_addrspace));
511 siba_get_region_count(device_t dev, device_t child, bhnd_port_type type,
514 struct siba_devinfo *dinfo;
516 /* delegate non-bus-attached devices to our parent */
517 if (device_get_parent(child) != dev)
518 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child,
521 dinfo = device_get_ivars(child);
522 if (!siba_is_port_valid(dinfo->core_id.num_addrspace, type, port))
525 return (siba_addrspace_region_count(dinfo->core_id.num_addrspace,
530 siba_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type,
531 u_int port_num, u_int region_num)
533 struct siba_devinfo *dinfo;
534 struct siba_addrspace *addrspace;
536 /* delegate non-bus-attached devices to our parent */
537 if (device_get_parent(child) != dev)
538 return (BHND_BUS_GET_PORT_RID(device_get_parent(dev), child,
539 port_type, port_num, region_num));
541 dinfo = device_get_ivars(child);
542 addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num);
543 if (addrspace == NULL)
546 return (addrspace->sa_rid);
550 siba_decode_port_rid(device_t dev, device_t child, int type, int rid,
551 bhnd_port_type *port_type, u_int *port_num, u_int *region_num)
553 struct siba_devinfo *dinfo;
555 /* delegate non-bus-attached devices to our parent */
556 if (device_get_parent(child) != dev)
557 return (BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), child,
558 type, rid, port_type, port_num, region_num));
560 dinfo = device_get_ivars(child);
562 /* Ports are always memory mapped */
563 if (type != SYS_RES_MEMORY)
566 for (int i = 0; i < dinfo->core_id.num_addrspace; i++) {
567 if (dinfo->addrspace[i].sa_rid != rid)
570 *port_type = BHND_PORT_DEVICE;
571 *port_num = siba_addrspace_port(i);
572 *region_num = siba_addrspace_region(i);
581 siba_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type,
582 u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size)
584 struct siba_devinfo *dinfo;
585 struct siba_addrspace *addrspace;
587 /* delegate non-bus-attached devices to our parent */
588 if (device_get_parent(child) != dev) {
589 return (BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), child,
590 port_type, port_num, region_num, addr, size));
593 dinfo = device_get_ivars(child);
594 addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num);
595 if (addrspace == NULL)
598 *addr = addrspace->sa_base;
599 *size = addrspace->sa_size - addrspace->sa_bus_reserved;
604 * Default siba(4) bus driver implementation of BHND_BUS_GET_INTR_COUNT().
606 * This implementation consults @p child's configuration block mapping,
607 * returning SIBA_CORE_NUM_INTR if a valid CFG0 block is mapped.
610 siba_get_intr_count(device_t dev, device_t child)
612 struct siba_devinfo *dinfo;
614 /* delegate non-bus-attached devices to our parent */
615 if (device_get_parent(child) != dev)
616 return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), child));
618 dinfo = device_get_ivars(child);
620 /* We can get/set interrupt sbflags on any core with a valid cfg0
621 * block; whether the core actually makes use of it is another matter
623 if (dinfo->cfg[0] == NULL)
626 return (SIBA_CORE_NUM_INTR);
630 * Default siba(4) bus driver implementation of BHND_BUS_GET_CORE_IVEC().
632 * This implementation consults @p child's CFG0 register block,
633 * returning the interrupt flag assigned to @p child.
636 siba_get_core_ivec(device_t dev, device_t child, u_int intr, uint32_t *ivec)
638 struct siba_devinfo *dinfo;
641 /* delegate non-bus-attached devices to our parent */
642 if (device_get_parent(child) != dev)
643 return (BHND_BUS_GET_CORE_IVEC(device_get_parent(dev), child,
646 /* Must be a valid interrupt ID */
647 if (intr >= siba_get_intr_count(dev, child))
650 /* Fetch sbflag number */
651 dinfo = device_get_ivars(child);
652 tpsflag = bhnd_bus_read_4(dinfo->cfg[0], SIBA_CFG0_TPSFLAG);
653 *ivec = SIBA_REG_GET(tpsflag, TPS_NUM0);
659 * Register all address space mappings for @p di.
661 * @param dev The siba bus device.
662 * @param di The device info instance on which to register all address
664 * @param r A resource mapping the enumeration table block for @p di.
667 siba_register_addrspaces(device_t dev, struct siba_devinfo *di,
668 struct bhnd_resource *r)
670 struct siba_core_id *cid;
678 /* Register the device address space entries */
679 for (uint8_t i = 0; i < di->core_id.num_addrspace; i++) {
682 uint32_t bus_reserved;
684 /* Determine the register offset */
685 adm_offset = siba_admatch_offset(i);
686 if (adm_offset == 0) {
687 device_printf(dev, "addrspace %hhu is unsupported", i);
691 /* Fetch the address match register value */
692 adm = bhnd_bus_read_4(r, adm_offset);
694 /* Parse the value */
695 if ((error = siba_parse_admatch(adm, &addr, &size))) {
696 device_printf(dev, "failed to decode address "
697 " match register value 0x%x\n", adm);
701 /* If this is the device's core/enumeration addrespace,
702 * reserve the Sonics configuration register blocks for the
705 if (i == SIBA_CORE_ADDRSPACE)
706 bus_reserved = cid->num_cfg_blocks * SIBA_CFG_SIZE;
708 /* Append the region info */
709 error = siba_append_dinfo_region(di, i, addr, size,
719 * Map per-core configuration blocks for @p dinfo.
721 * @param dev The siba bus device.
722 * @param dinfo The device info instance on which to map all per-core
723 * configuration blocks.
726 siba_map_cfg_resources(device_t dev, struct siba_devinfo *dinfo)
728 struct siba_addrspace *addrspace;
729 rman_res_t r_start, r_count, r_end;
732 num_cfg = dinfo->core_id.num_cfg_blocks;
733 if (num_cfg > SIBA_MAX_CFG) {
734 device_printf(dev, "config block count %hhu out of range\n",
739 /* Fetch the core register address space */
740 addrspace = siba_find_addrspace(dinfo, BHND_PORT_DEVICE, 0, 0);
741 if (addrspace == NULL) {
742 device_printf(dev, "missing device registers\n");
747 * Map the per-core configuration blocks
749 for (uint8_t i = 0; i < num_cfg; i++) {
750 /* Determine the config block's address range; configuration
751 * blocks are allocated starting at SIBA_CFG0_OFFSET,
752 * growing downwards. */
753 r_start = addrspace->sa_base + SIBA_CFG0_OFFSET;
754 r_start -= i * SIBA_CFG_SIZE;
756 r_count = SIBA_CFG_SIZE;
757 r_end = r_start + r_count - 1;
759 /* Allocate the config resource */
760 dinfo->cfg_rid[i] = SIBA_CFG_RID(dinfo, i);
761 dinfo->cfg[i] = BHND_BUS_ALLOC_RESOURCE(dev, dev,
762 SYS_RES_MEMORY, &dinfo->cfg_rid[i], r_start, r_end,
765 if (dinfo->cfg[i] == NULL) {
766 device_printf(dev, "failed to allocate SIBA_CFG%hhu\n",
776 siba_add_child(device_t dev, u_int order, const char *name, int unit)
778 struct siba_devinfo *dinfo;
781 child = device_add_child_ordered(dev, order, name, unit);
785 if ((dinfo = siba_alloc_dinfo(dev)) == NULL) {
786 device_delete_child(dev, child);
790 device_set_ivars(child, dinfo);
796 siba_child_deleted(device_t dev, device_t child)
798 struct bhnd_softc *sc;
799 struct siba_devinfo *dinfo;
801 sc = device_get_softc(dev);
803 /* Call required bhnd(4) implementation */
804 bhnd_generic_child_deleted(dev, child);
806 /* Free siba device info */
807 if ((dinfo = device_get_ivars(child)) != NULL)
808 siba_free_dinfo(dev, dinfo);
810 device_set_ivars(child, NULL);
814 * Scan the core table and add all valid discovered cores to
817 * @param dev The siba bus device.
820 siba_add_children(device_t dev)
822 const struct bhnd_chipid *chipid;
823 struct bhnd_core_info *cores;
824 struct siba_devinfo *dinfo;
825 struct bhnd_resource *r;
833 chipid = BHND_BUS_GET_CHIPID(dev, dev);
835 /* Allocate our temporary core table and enumerate all cores */
836 cores = malloc(sizeof(*cores) * chipid->ncores, M_BHND, M_NOWAIT);
841 for (u_int i = 0; i < chipid->ncores; i++) {
842 struct siba_core_id cid;
844 uint32_t idhigh, idlow;
845 rman_res_t r_count, r_end, r_start;
848 /* Map the core's register block */
850 r_start = SIBA_CORE_ADDR(i);
851 r_count = SIBA_CORE_SIZE;
852 r_end = r_start + SIBA_CORE_SIZE - 1;
853 r = bhnd_alloc_resource(dev, SYS_RES_MEMORY, &rid, r_start,
854 r_end, r_count, RF_ACTIVE);
860 /* Add the child device */
861 child = BUS_ADD_CHILD(dev, 0, NULL, -1);
867 /* Read the core info */
868 idhigh = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
869 idlow = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW));
871 cid = siba_parse_core_id(idhigh, idlow, i, 0);
872 cores[i] = cid.core_info;
874 /* Determine unit number */
875 for (u_int j = 0; j < i; j++) {
876 if (cores[j].vendor == cores[i].vendor &&
877 cores[j].device == cores[i].device)
881 /* Initialize per-device bus info */
882 if ((dinfo = device_get_ivars(child)) == NULL) {
887 if ((error = siba_init_dinfo(dev, dinfo, &cid)))
890 /* Register the core's address space(s). */
891 if ((error = siba_register_addrspaces(dev, dinfo, r)))
894 /* Release our resource covering the register blocks
895 * we're about to map */
896 bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r);
899 /* Map the core's config blocks */
900 if ((error = siba_map_cfg_resources(dev, dinfo)))
903 /* Assign interrupts */
904 nintr = bhnd_get_intr_count(child);
905 for (int rid = 0; rid < nintr; rid++) {
906 error = BHND_BUS_ASSIGN_INTR(dev, child, rid);
908 device_printf(dev, "failed to assign interrupt "
909 "%d to core %u: %d\n", rid, i, error);
913 /* If pins are floating or the hardware is otherwise
914 * unpopulated, the device shouldn't be used. */
915 if (bhnd_is_hw_disabled(child))
916 device_disable(child);
918 /* Issue bus callback for fully initialized child. */
919 BHND_BUS_CHILD_ADDED(dev, child);
927 bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r);
932 static device_method_t siba_methods[] = {
933 /* Device interface */
934 DEVMETHOD(device_probe, siba_probe),
935 DEVMETHOD(device_attach, siba_attach),
936 DEVMETHOD(device_detach, siba_detach),
937 DEVMETHOD(device_resume, siba_resume),
938 DEVMETHOD(device_suspend, siba_suspend),
941 DEVMETHOD(bus_add_child, siba_add_child),
942 DEVMETHOD(bus_child_deleted, siba_child_deleted),
943 DEVMETHOD(bus_read_ivar, siba_read_ivar),
944 DEVMETHOD(bus_write_ivar, siba_write_ivar),
945 DEVMETHOD(bus_get_resource_list, siba_get_resource_list),
948 DEVMETHOD(bhnd_bus_get_erom_class, siba_get_erom_class),
949 DEVMETHOD(bhnd_bus_read_ioctl, siba_read_ioctl),
950 DEVMETHOD(bhnd_bus_write_ioctl, siba_write_ioctl),
951 DEVMETHOD(bhnd_bus_read_iost, siba_read_iost),
952 DEVMETHOD(bhnd_bus_is_hw_suspended, siba_is_hw_suspended),
953 DEVMETHOD(bhnd_bus_reset_hw, siba_reset_hw),
954 DEVMETHOD(bhnd_bus_suspend_hw, siba_suspend_hw),
955 DEVMETHOD(bhnd_bus_read_config, siba_read_config),
956 DEVMETHOD(bhnd_bus_write_config, siba_write_config),
957 DEVMETHOD(bhnd_bus_get_port_count, siba_get_port_count),
958 DEVMETHOD(bhnd_bus_get_region_count, siba_get_region_count),
959 DEVMETHOD(bhnd_bus_get_port_rid, siba_get_port_rid),
960 DEVMETHOD(bhnd_bus_decode_port_rid, siba_decode_port_rid),
961 DEVMETHOD(bhnd_bus_get_region_addr, siba_get_region_addr),
962 DEVMETHOD(bhnd_bus_get_intr_count, siba_get_intr_count),
963 DEVMETHOD(bhnd_bus_get_core_ivec, siba_get_core_ivec),
968 DEFINE_CLASS_1(bhnd, siba_driver, siba_methods, sizeof(struct siba_softc), bhnd_driver);
970 MODULE_VERSION(siba, 1);
971 MODULE_DEPEND(siba, bhnd, 1, 1, 1);