Lines Matching +full:child +full:- +full:interrupt +full:- +full:base
1 /*-
2 * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
48 static int siba_register_interrupts(device_t dev, device_t child,
51 uint8_t addridx, uint32_t base, uint32_t size,
55 * Map a siba(4) OCP vendor code to its corresponding JEDEC JEP-106 vendor
89 for (u_int i = 0; i < nitems(dinfo->cfg); i++) { in siba_alloc_dinfo()
90 dinfo->cfg[i] = ((struct siba_cfg_block){ in siba_alloc_dinfo()
93 .cb_rid = -1, in siba_alloc_dinfo()
95 dinfo->cfg_res[i] = NULL; in siba_alloc_dinfo()
96 dinfo->cfg_rid[i] = -1; in siba_alloc_dinfo()
99 resource_list_init(&dinfo->resources); in siba_alloc_dinfo()
101 dinfo->pmu_state = SIBA_PMU_NONE; in siba_alloc_dinfo()
103 dinfo->intr = (struct siba_intr) { in siba_alloc_dinfo()
105 .rid = -1 in siba_alloc_dinfo()
116 * @param child The siba child device.
121 * @retval non-zero initialization failed.
124 siba_init_dinfo(device_t dev, device_t child, struct siba_devinfo *dinfo, in siba_init_dinfo() argument
129 dinfo->core_id = *core_id; in siba_init_dinfo()
132 for (uint8_t i = 0; i < core_id->num_admatch; i++) { in siba_init_dinfo()
140 bus_reserved = core_id->num_cfg_blocks * SIBA_CFG_SIZE; in siba_init_dinfo()
144 core_id->admatch[i].am_base, core_id->admatch[i].am_size, in siba_init_dinfo()
150 /* Register all interrupt(s) */ in siba_init_dinfo()
151 if ((error = siba_register_interrupts(dev, child, dinfo))) in siba_init_dinfo()
161 * @param child The siba child device.
162 * @param dinfo The device info instance on which to register all interrupt
166 siba_register_interrupts(device_t dev, device_t child, in siba_register_interrupts() argument
171 /* Is backplane interrupt distribution enabled for this core? */ in siba_register_interrupts()
172 if (!dinfo->core_id.intr_en) in siba_register_interrupts()
175 /* Have one interrupt */ in siba_register_interrupts()
176 dinfo->intr.mapped = false; in siba_register_interrupts()
177 dinfo->intr.irq = 0; in siba_register_interrupts()
178 dinfo->intr.rid = -1; in siba_register_interrupts()
180 /* Map the interrupt */ in siba_register_interrupts()
181 error = BHND_BUS_MAP_INTR(dev, child, 0 /* single intr is always 0 */, in siba_register_interrupts()
182 &dinfo->intr.irq); in siba_register_interrupts()
184 device_printf(dev, "failed mapping interrupt line for core %u: " in siba_register_interrupts()
185 "%d\n", dinfo->core_id.core_info.core_idx, error); in siba_register_interrupts()
188 dinfo->intr.mapped = true; in siba_register_interrupts()
191 dinfo->intr.rid = resource_list_add_next(&dinfo->resources, SYS_RES_IRQ, in siba_register_interrupts()
192 dinfo->intr.irq, dinfo->intr.irq, 1); in siba_register_interrupts()
224 * are mapped to device1.0 + (n - 1) */ in siba_addrspace_device_region()
228 return (addrspace - 1); in siba_addrspace_device_region()
273 return (min(core_id->num_admatch, 2)); in siba_port_count()
277 if (core_id->num_cfg_blocks > 0) in siba_port_count()
327 return (min(core_id->num_admatch, 1)); in siba_port_region_count()
329 /* All remaining address spaces are mapped to device0.(n - 1) */ in siba_port_region_count()
330 if (port == 1 && core_id->num_admatch >= 2) in siba_port_region_count()
331 return (core_id->num_admatch - 1); in siba_port_region_count()
338 return (core_id->num_cfg_blocks); in siba_port_region_count()
383 if (region >= core_id->num_cfg_blocks) in siba_cfg_index()
413 error = siba_cfg_index(&dinfo->core_id, type, port, region, &cfgidx); in siba_find_cfg_block()
418 return (&dinfo->cfg[cfgidx]); in siba_find_cfg_block()
465 if (idx >= core_id->num_admatch) in siba_addrspace_index()
492 error = siba_addrspace_index(&dinfo->core_id, type, port, region, in siba_find_addrspace()
501 return (&dinfo->addrspace[addridx]); in siba_find_addrspace()
509 * @param base The mapping's base address.
516 * @retval non-zero An error occurred appending the entry.
520 uint32_t base, uint32_t size, uint32_t bus_reserved) in siba_append_dinfo_region() argument
525 /* Verify that base + size will not overflow */ in siba_append_dinfo_region()
526 if (size > 0 && UINT32_MAX - (size - 1) < base) in siba_append_dinfo_region()
529 /* Verify that size - bus_reserved will not underflow */ in siba_append_dinfo_region()
533 /* Must not be 0-length */ in siba_append_dinfo_region()
538 if (addridx >= nitems(dinfo->addrspace)) in siba_append_dinfo_region()
542 sa = &dinfo->addrspace[addridx]; in siba_append_dinfo_region()
543 sa->sa_base = base; in siba_append_dinfo_region()
544 sa->sa_size = size; in siba_append_dinfo_region()
545 sa->sa_bus_reserved = bus_reserved; in siba_append_dinfo_region()
548 r_size = size - bus_reserved; in siba_append_dinfo_region()
549 sa->sa_rid = resource_list_add_next(&dinfo->resources, SYS_RES_MEMORY, in siba_append_dinfo_region()
550 base, base + (r_size - 1), r_size); in siba_append_dinfo_region()
559 * @param child The siba child device.
560 * @param dinfo Device info associated with @p child to be deallocated.
563 siba_free_dinfo(device_t dev, device_t child, struct siba_devinfo *dinfo) in siba_free_dinfo() argument
565 resource_list_free(&dinfo->resources); in siba_free_dinfo()
568 for (u_int i = 0; i < nitems(dinfo->cfg); i++) { in siba_free_dinfo()
569 if (dinfo->cfg_res[i] == NULL) in siba_free_dinfo()
572 bhnd_release_resource(dev, SYS_RES_MEMORY, dinfo->cfg_rid[i], in siba_free_dinfo()
573 dinfo->cfg_res[i]); in siba_free_dinfo()
575 dinfo->cfg_res[i] = NULL; in siba_free_dinfo()
576 dinfo->cfg_rid[i] = -1; in siba_free_dinfo()
579 /* Unmap the core's interrupt */ in siba_free_dinfo()
580 if (dinfo->core_id.intr_en && dinfo->intr.mapped) { in siba_free_dinfo()
581 BHND_BUS_UNMAP_INTR(dev, child, dinfo->intr.irq); in siba_free_dinfo()
582 dinfo->intr.mapped = false; in siba_free_dinfo()
589 * Return the core-enumeration-relative offset for the @p addrspace
594 * @retval non-zero success
622 * @retval non-zero a parse error occurred.
629 /* Extract the base address and size */ in siba_parse_admatch()
635 admatch->am_base = am & SIBA_AM_BASE0_MASK; in siba_parse_admatch()
636 admatch->am_size = 1 << (SIBA_REG_GET(am, AM_ADINT0) + 1); in siba_parse_admatch()
637 admatch->am_enabled = true; in siba_parse_admatch()
638 admatch->am_negative = false; in siba_parse_admatch()
641 admatch->am_base = am & SIBA_AM_BASE1_MASK; in siba_parse_admatch()
642 admatch->am_size = 1 << (SIBA_REG_GET(am, AM_ADINT1) + 1); in siba_parse_admatch()
643 admatch->am_enabled = ((am & SIBA_AM_ADEN) != 0); in siba_parse_admatch()
644 admatch->am_negative = ((am & SIBA_AM_ADNEG) != 0); in siba_parse_admatch()
647 admatch->am_base = am & SIBA_AM_BASE2_MASK; in siba_parse_admatch()
648 admatch->am_size = 1 << (SIBA_REG_GET(am, AM_ADINT2) + 1); in siba_parse_admatch()
649 admatch->am_enabled = ((am & SIBA_AM_ADEN) != 0); in siba_parse_admatch()
650 admatch->am_negative = ((am & SIBA_AM_ADNEG) != 0); in siba_parse_admatch()
661 * required read-back and waiting for completion.
663 * @param dev The siba(4) child device.
676 r = dinfo->cfg_res[0]; in siba_write_target_state()
680 KASSERT(reg <= SIBA_CFG_SIZE-4, ("%s invalid CFG0 register offset %#jx", in siba_write_target_state()
688 bhnd_bus_read_4(r, reg); /* read-back */ in siba_write_target_state()
697 * @param dev The siba(4) child device to wait on.
716 if ((r = dinfo->cfg_res[0]) == NULL) in siba_wait_target_state()