summaryrefslogtreecommitdiff
path: root/documentation/6.components/device-driver/pci/pci_irq.md
blob: 8ed6b6d1a1635d2773d7db84edb834570f7d1da2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@page page_device_pci_irq PCI INTx interrupts

# Legacy INTx (`irq.c` + core)

**INTx** (legacy PCI pin A–D) assignment and masking. MSI/MSI-X: @ref page_device_pci_msi. DT routing: @ref page_device_pci_ofw.

Sources: **`components/drivers/pci/irq.c`**, INTx helpers in **`pci.c`**.

---

## Assignment (`rt_pci_assign_irq`)

During setup, if host provides **`irq_map`**:

1. Read **`PCIR_INTPIN`** from config
2. Optional **`irq_slot`** swizzle on bridges
3. **`irq_map(pdev, slot, pin)`** → **`pdev->irq`**
4. Write **`PCIR_INTLINE`** in config

Without **`irq_map`**, logs debug and leaves IRQ 0 — use OFW or MSI.

### OFW path

**`rt_pci_ofw_irq_parse_and_map`** sets **`pdev->intx_pic`** and IRQ via **`rt_ofw_map_irq`** — preferred on DT platforms (@ref page_device_pci_ofw).

---

## Swizzling

| API | Role |
| --- | --- |
| **`rt_pci_irq_intx(pdev, pin)`** | Swizzle INTPIN across P2P bridges |
| **`rt_pci_irq_slot(pdev, &pin)`** | Slot number for **`interrupt-map`** key |

Used when building **`interrupt-map`** address cells on root bridge.

---

## Mask / unmask

| API | Role |
| --- | --- |
| **`rt_pci_intx(pdev, enable)`** | Enable/disable INTx in command register |
| **`rt_pci_check_and_mask_intx`** | Mask if supported |
| **`rt_pci_check_and_unmask_intx`** | Unmask |
| **`rt_pci_irq_mask` / `rt_pci_irq_unmask`** | Device-level helpers |

**`pdev->broken_intx_masking`**: set when hardware cannot mask INTx reliably.

---

## Unified vector API (`pci.h`, `RT_PCI_MSI`)

**`rt_pci_alloc_vector(pdev, min, max, flags, affinities)`**:

| Flag | Meaning |
| --- | --- |
| **`RT_PCI_IRQ_F_LEGACY`** | Allow INTx |
| **`RT_PCI_IRQ_F_MSI`** | Allow MSI |
| **`RT_PCI_IRQ_F_MSIX`** | Allow MSI-X |
| **`RT_PCI_IRQ_F_AFFINITY`** | CPU affinity |

Picks best available type; **`rt_pci_free_vector`** on teardown.

---

## Pitfalls

| Issue | Mitigation |
| --- | --- |
| MSI + INTx both active | Core often masks INTx when MSI enabled — use one path |
| **`interrupt-map` missing** | **`-RT_EEMPTY`** from OFW — enable MSI or fix DTS |
| Wrong pin after bridge | Use **`rt_pci_irq_intx`**, not raw config pin on child |
| **`irq == 0`** | May mean unassigned — do not register handler |

## See also

- @ref page_device_pci_msi
- @ref page_device_pci_ofw
- @ref page_device_ofw_irq
- @ref page_device_pic