Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| complicated_interrupts [2016/07/26 16:16] – NathanWhitehorn | complicated_interrupts [2018/03/12 17:58] (current) – wiki markup MarkLinimon | ||
|---|---|---|---|
| Line 15: | Line 15: | ||
| Under the hood, this calls into machine-dependent code. The most general implementations (e.g. on %%PowerPC%%) have a mapping table that records the assigned IRQ and the interrupt specifier data. As PICs attach themselves during newbus discovery, they register their interest in a particular iparent value with the machine-dependent interrupt layer and eventually -- potentially at attach time but at latest by configure_final() -- are passed the section of the table corresponding to the registered iparent value and asked to configure them as specified by the PIC-dependent byte string and send interrupts corresponding to that descriptor to the IRQ assigned. | Under the hood, this calls into machine-dependent code. The most general implementations (e.g. on %%PowerPC%%) have a mapping table that records the assigned IRQ and the interrupt specifier data. As PICs attach themselves during newbus discovery, they register their interest in a particular iparent value with the machine-dependent interrupt layer and eventually -- potentially at attach time but at latest by configure_final() -- are passed the section of the table corresponding to the registered iparent value and asked to configure them as specified by the PIC-dependent byte string and send interrupts corresponding to that descriptor to the IRQ assigned. | ||
| - | To be used with other enumeration mechanisms (e.g. ACPI), you could either abuse the function above or add another function (e.g. acpi_bus_map_intr) that takes the appropriate information and conveys it to the machine-dependent code appropriately. | + | To be used with other enumeration mechanisms (e.g. ACPI), you could either abuse the function above or add another function (e.g. acpi_bus_map_intr) that takes the appropriate information and conveys it to the machine-dependent code appropriately |
| ====== Rationale ====== | ====== Rationale ====== | ||
| Line 31: | Line 31: | ||
| ==== Case 1: the G5 Powermac ==== | ==== Case 1: the G5 Powermac ==== | ||
| - | Apple PowerMac G5s have two PICs, one cascaded from the other. PIC 1 lives in the northbridge, | + | Apple %%PowerMac%% G5s have two PICs, one cascaded from the other. PIC 1 lives in the northbridge, |
| - | This presents | + | This presents |
| - | A. How do I represent interrupts on the PCI bus parent of PIC 2 that are handled by PIC 2? PIC 2 obviously can't attach before its bus parent, but the bus parent can't complete initialization without the ability to setup its interrupts. | + | - How do I represent interrupts on the PCI bus parent of PIC 2 that are handled by PIC 2? PIC 2 obviously can't attach before its bus parent, but the bus parent can't complete initialization without the ability to setup its interrupts. |
| + | - Devices on the PCI bus have interrupts handled by a mixture of PIC 1 and PIC 2, sometimes on the same device and not always expressable through the bus hierarchy. For example, one of the two storage controllers has an interrupt on PIC 2 run through a wire that doesn' | ||
| + | - Both PICs are %%OpenPIC%% devices. In a multipass-type framework, how do you ensure that the attach order of the two %%OpenPICs%% is correct? The two %%OpenPIC%% devices are distinguished only by one of them (which one depends on the model of the machine) having an interrupts property and the other not and are implemented by the same driver. | ||
| - | B. Devices on the PCI bus have interrupts handled by a mixture of PIC 1 and PIC 2, sometimes on the same device and not always expressable through the bus hierarchy. For example, one of the two storage controllers has an interrupt on PIC 2 run through a wire that doesn' | + | These are solved by allowing bus_setup_intr() etc. to succeed before the PIC(s) has(have) attached, which breaks what would otherwise be a circular dependency loop (1). This also fixes (3) by removing any requirement on attach order of the two PICs. Because devices are free to modify their own resource lists and can call ofw_bus_map_intr() themselves, the ATA driver is free to allocate its own interrupt to satisfy (2). |
| - | + | ||
| - | These are solved by allowing bus_setup_intr() etc. to succeed before the PIC(s) has(have) attached, which breaks what would otherwise be a circular dependency loop. | + | |
| ==== Case 2: IBM OPAL firmware ==== | ==== Case 2: IBM OPAL firmware ==== | ||
| Line 58: | Line 58: | ||
| These are solved by allowing the IRQ to be a single scalar number and making knowledge of the routing independent of the newbus hierarchy after assignment time. The PCI layer gets a number like it wants and handles it appropriately after assignment by the device-tree-aware PCI host bridge driver. | These are solved by allowing the IRQ to be a single scalar number and making knowledge of the routing independent of the newbus hierarchy after assignment time. The PCI layer gets a number like it wants and handles it appropriately after assignment by the device-tree-aware PCI host bridge driver. | ||
| + | |||
| + | ==== Case 5: PCI LSIs ==== | ||
| + | |||
| + | The PCI LSI API (PCIB_ROUTE_INTERRUPT(%%))%% is when it is possible to match a unit and pin to the interrupt-map property of the PCI bridge, which gives an interrupt specifier and parent. The output of this routine is a single number (the IRQ). By mapping this IRQ to the specifier using ofw_bus_map_intr(), | ||
| ===== API Control Flow: The life and times of an interrupt descriptor ===== | ===== API Control Flow: The life and times of an interrupt descriptor ===== | ||