xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/pci/acpi_prt.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpigen.h>
5 #include <acpi/acpigen_pci.h>
6 #include <amdblocks/amd_pci_util.h>
7 #include <arch/ioapic.h>
8 #include <device/device.h>
9 
10 /* GNB IO-APIC is located after the FCH IO-APIC */
11 #define FCH_IOAPIC_INTERRUPTS	24
12 #define GNB_GSI_BASE		FCH_IOAPIC_INTERRUPTS
13 
acpigen_write_PRT_GSI(const struct pci_routing_info * routing_info)14 static void acpigen_write_PRT_GSI(const struct pci_routing_info *routing_info)
15 {
16 	unsigned int irq;
17 
18 	acpigen_write_package(4); /* Package - APIC Routing */
19 	for (unsigned int i = 0; i < 4; ++i) {
20 		irq = pci_calculate_irq(routing_info, i);
21 
22 		acpigen_write_PRT_GSI_entry(
23 			0, /* There is only one device attached to the bridge */
24 			i, /* pin */
25 			GNB_GSI_BASE + irq);
26 	}
27 	acpigen_pop_len(); /* Package - APIC Routing */
28 }
29 
acpigen_write_PRT_PIC(const struct pci_routing_info * routing_info)30 static void acpigen_write_PRT_PIC(const struct pci_routing_info *routing_info)
31 {
32 	unsigned int irq;
33 	char link_template[] = "\\_SB.INTX";
34 
35 	acpigen_write_package(4); /* Package - PIC Routing */
36 	for (unsigned int i = 0; i < 4; ++i) {
37 		irq = pci_calculate_irq(routing_info, i);
38 
39 		link_template[8] = 'A' + (irq % 8);
40 
41 		acpigen_write_PRT_source_entry(
42 			0, /* There is only one device attached to the bridge */
43 			i, /* pin */
44 			link_template /* Source */,
45 			0 /* Source Index */);
46 	}
47 	acpigen_pop_len(); /* Package - PIC Routing */
48 }
49 
50 /*
51  * This method writes a PCI _PRT table that uses the GNB IO-APIC / PIC :
52  *     Method (_PRT, 0, NotSerialized)  // _PRT: PCI Routing Table
53  *     {
54  *         If (PICM)
55  *         {
56  *             Return (Package (0x04)
57  *             {
58  *                 Package (0x04)
59  *                 {
60  *                     0x0000FFFF,
61  *                     0x00,
62  *                     0x00,
63  *                     0x00000034
64  *                 },
65  *
66  *                 Package (0x04)
67  *                 {
68  *                     0x0000FFFF,
69  *                     0x01,
70  *                     0x00,
71  *                     0x00000035
72  *                 },
73  *
74  *                 Package (0x04)
75  *                 {
76  *                     0x0000FFFF,
77  *                     0x02,
78  *                     0x00,
79  *                     0x00000036
80  *                 },
81  *
82  *                 Package (0x04)
83  *                 {
84  *                     0x0000FFFF,
85  *                     0x03,
86  *                     0x00,
87  *                     0x00000037
88  *                 }
89  *             })
90  *         }
91  *         Else
92  *         {
93  *             Return (Package (0x04)
94  *             {
95  *                 Package (0x04)
96  *                 {
97  *                     0x0000FFFF,
98  *                     0x00,
99  *                     \_SB.INTA,
100  *                     0x00000000
101  *                 },
102  *
103  *                 Package (0x04)
104  *                 {
105  *                     0x0000FFFF,
106  *                     0x01,
107  *                     \_SB.INTB,
108  *                     0x00000000
109  *                 },
110  *
111  *                 Package (0x04)
112  *                 {
113  *                     0x0000FFFF,
114  *                     0x02,
115  *                     \_SB.INTC,
116  *                     0x00000000
117  *                 },
118  *
119  *                 Package (0x04)
120  *                 {
121  *                     0x0000FFFF,
122  *                     0x03,
123  *                     \_SB.INTD,
124  *                     0x00000000
125  *                 }
126  *             })
127  *         }
128  *    }
129  */
acpigen_write_pci_GNB_PRT(const struct device * dev)130 void acpigen_write_pci_GNB_PRT(const struct device *dev)
131 {
132 	const struct pci_routing_info *routing_info =
133 		get_pci_routing_info(dev->path.pci.devfn);
134 
135 	if (!routing_info)
136 		return;
137 
138 	acpigen_write_method("_PRT", 0);
139 
140 	/* If (PICM) */
141 	acpigen_write_if();
142 	acpigen_emit_namestring("PICM");
143 
144 	/* Return (Package{...}) */
145 	acpigen_emit_byte(RETURN_OP);
146 	acpigen_write_PRT_GSI(routing_info);
147 
148 	/* Else */
149 	acpigen_write_else();
150 
151 	/* Return (Package{...}) */
152 	acpigen_emit_byte(RETURN_OP);
153 	acpigen_write_PRT_PIC(routing_info);
154 
155 	acpigen_pop_len(); /* End Else */
156 
157 	acpigen_pop_len(); /* Method */
158 }
159 
160  /*
161  * This method writes a PCI _PRT table that uses the FCH IO-APIC / PIC :
162  *     Name (_PRT, Package (0x04)
163  *     {
164  *         Package (0x04)
165  *         {
166  *             0x0000FFFF,
167  *             0x00,
168  *             \_SB.INTA,
169  *             0x00000000
170  *         },
171  *
172  *         Package (0x04)
173  *         {
174  *             0x0000FFFF,
175  *             0x01,
176  *             \_SB.INTB,
177  *             0x00000000
178  *         },
179  *
180  *         Package (0x04)
181  *         {
182  *             0x0000FFFF,
183  *             0x02,
184  *             \_SB.INTC,
185  *             0x00000000
186  *         },
187  *
188  *         Package (0x04)
189  *         {
190  *             0x0000FFFF,
191  *             0x03,
192  *             \_SB.INTD,
193  *             0x00000000
194  *         }
195  *     })
196  */
acpigen_write_pci_FCH_PRT(const struct device * dev)197 void acpigen_write_pci_FCH_PRT(const struct device *dev)
198 {
199 	const struct pci_routing_info *routing_info =
200 		get_pci_routing_info(dev->path.pci.devfn);
201 
202 	if (!routing_info)
203 		return;
204 
205 	acpigen_write_name("_PRT");
206 	acpigen_write_PRT_PIC(routing_info);
207 }
208