Page MenuHomeFreeBSD

Preemptively perform intr_map_irq() on non-FDT MIPS targets.

Authored by landonf on Sep 15 2017, 7:50 PM.



This replaces a nexus-level workaround (introduced in r305527 to
support INTRNG on non-FDT targets) that is incompatible with
implementing nested interrupt controllers on non-FDT MIPS INTRNG

The existing workaround assumes that all interrupts passed to
nexus_activate_resource() and nexus_setup_intr() are MIPS interrupts
managed by the root MIPS pic (mips/mips_pic.c).

Since non-FDT/OFW MIPS targets do not provide an equivalent to
OFW_BUS_MAP_INTR(), it is necessary to implicitly establish
interrupt mappings on behalf of consumers. The existing workaround:

  • Assumes that all requests are for a MIPS CPU IRQ
  • Calls mips_pic's cpu_create_intr_map() to allocate a new interrupt mapping on-demand in nexus_activate_resource(), and
  • Calls mips_pic's cpu_get_irq_resource() to fetch a shared IRQ resource for the MIPS interrupt in nexus_setup_intr().
  • Leaks that map entry in nexus_deactivate_resource()

This introduces some unexpected behavior; by allocating a new mapping implicitly
in bus_activate_resource, any child bus that use resource_list_alloc() to
implement BUS_ALLOC_RESOURCE() (or reimplements similar functionality) will
automatically 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.
Otherwise, if bus_activate_resource() is called independently of bus_alloc_resource(),
the child's resource list entry will be left unmodified.

The IRQ mapping must be leaked in nexus_deactivate_resource(), as child references
to the mapping may remain in the child's resource_list_entry after
nexus_deactivate_resource() is called.

Rather than on-demand mapping, this diff adds support (on non-FDT targets) for
producing a fixed set of IRQ mappings for all MIPS IRQs in nexus_attach(), with
a known range of INTRNG IRQ assignments (0-7) that may be referenced by child
devices, used by the nexus/mips_pic to differentiate between IRQs managed by mips_pic,
and IRQs managed by a child interrupt controller.

In brief:

  • On non-FDT targets, produce a set of fixed INTRNG MIPS irq map entries in nexus_attach().
  • Always call mips_pic_activate_intr() from nexus_activate_resource(); this will either perform mips_pic-specific activation, or call intr_activate_irq() directly for IRQs not managed by mips_pic.
  • Always call mips_pic_deactivate_intr() from nexus_deactivate_resource(); this will either perform mips_pic-specific deactivation, or call intr_deactivate_irq() directly for IRQs not managed by mips_pic.

Refer to D7692 for additional discussion on the original workaround.

Test Plan

Diff Detail

rS FreeBSD src repository - subversion
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Drop minor unnecessary whitespace change.

have you tested this on a non-FDT MIPS board? (if not, please do get a carambola2? ;-)


have you tested this on a non-FDT MIPS board? (if not, please do get a carambola2? ;-)

Nope, for lack of hardware. I went ahead and ordered a carambola2 just now.

have you tested this on a non-FDT MIPS board? (if not, please do get a carambola2? ;-)

My test hardware arrived; I can confirm that this doesn't introduce regressions on the carambola2.

This revision is now accepted and ready to land.Nov 14 2017, 9:43 PM

If mips_pic_map_fixed_intr() fails when called from cpu_establish_intr(), include the returned error in the panic() message.

This revision now requires review to proceed.Nov 15 2017, 9:31 PM
This revision is now accepted and ready to land.Nov 20 2017, 11:29 PM
This revision was automatically updated to reflect the committed changes.