Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Nov 2017 15:50:08 -0700
From:      Landon J Fuller <landonf@freebsd.org>
To:        freebsd-mips@freebsd.org
Subject:   MIPS INTRNG changes
Message-ID:  <1510699808.25350.3@smtp.office.plausible.coop>

next in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1510699808.25350.3>