MIPS INTRNG changes
Landon J Fuller
landonf at freebsd.org
Tue Nov 14 22:50:19 UTC 2017
Howdy -
To support nested INTRNG interrupt controllers on non-FDT MIPS targets,
I've
implemented a replacement for the cpu_establish_[hard|soft]intr()
workaround
introduced in r305527 (D7692); I'll be commiting this in three days
unless
anyone objects:
https://reviews.freebsd.org/D12385
Background:
Since non-FDT INTRNG targets do not have an equivalent to
OFW_BUS_MAP_INTR(),
it is necessary for the MIPS nexus driver to implicitly establish INTRNG
interrupt mappings on behalf of child devices.
The workaround introduced in r305527 implements this as follows, on
non-FDT
INTRNG MIPS targets:
- mips/nexus.c assumes that all bus interrupt requests are for a MIPS
interrupt managed by mips/mips_pic.c
- Call mips_pic's cpu_create_intr_map() from nexus_activate_resource()
to
allocate a new interrupt mapping on-demand.
- Call mips_pic's cpu_get_irq_resource() from nexus_setup_intr() to
fetch a
shared IRQ struct resource for the MIPS interrupt.
In addition to assuming that all IRQs are owned by mips_pic, on-demand
IRQ
mapping in the BUS_ACTIVATE_RESOURCE() path produces some unexpected
behavior:
- Any child bus that uses bus_generic_rl_alloc_resource() or
resource_list_alloc()
to implement BUS_ALLOC_RESOURCE() will update the child device's
resource
list entry to reference the newly mapped IRQ -- but only if the
resource is
allocated with the RF_ACTIVE flag, resulting in
BUS_ACTIVATE_RESOURCE() being
called from BUS_ALLOC_RESOURCE() before the resource_list_entry
update is
performed.
- BUS_ACTIVATE_RESOURCE() is itself not resource_list-aware; if
RF_ACTIVE is
not set during allocation, and bus_activate_resource() is instead
called
directly, the child's resource list entry will _not_ updated to the
newly
mapped IRQ.
Since the resource_list_entry _may_ be updated to reference the IRQ
mapping, IRQs
mappings implicitly created in nexus_activate_resource() cannot be
implicitly
unmapped in nexus_deactivate_resource() and must be leaked, as
references to
the mapping may remain in a child's resource_list_entry.
Rather than performing on-demand mapping during resource activation, my
changes
preemptively produce (on non-FDT targets) a set of IRQ mappings for all
MIPS
IRQs in nexus_attach(), using a fixed range of INTRNG IRQ assignments
(0-7) that
may be statically referenced by child devices.
With D12385, the mips nexus behavior will now be:
- On non-FDT MIPS INTRNG targets, produce a set of fixed MIPS IRQ
mappings
in nexus_attach() for the MIPS IRQ range.
- On all MIPS INTRNG targets, call mips_pic_activate_intr() from
nexus_activate_resource() to perform activation; this will either
perform
mips_pic-specific activation if the IRQ is found in mips_pic' table
of
MIPS IRQ mappings, or will call intr_activate_irq() for IRQs not
managed by
mips_pic (e.g. IRQs mapped by a child PIC).
- On all MIPS INTRNG targets, call mips_pic_deactivate_intr() from
nexus_deactivate_resource(); this will either perform
mips_pic-specific
deactivation, or call intr_deactivate_irq() for IRQs not managed by
mips_pic.
Cheers,
Landon
More information about the freebsd-mips
mailing list