Line data Source code
1 0 : /*
2 : * Copyright (c) 2023 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 : #ifndef ZEPHYR_INCLUDE_DRIVERS_ACPI_H_
7 : #define ZEPHYR_INCLUDE_DRIVERS_ACPI_H_
8 : #include <acpica/source/include/acpi.h>
9 : #include <zephyr/drivers/pcie/pcie.h>
10 :
11 0 : #define ACPI_RES_INVALID ACPI_RESOURCE_TYPE_MAX
12 :
13 0 : #define ACPI_DRHD_FLAG_INCLUDE_PCI_ALL BIT(0)
14 0 : #define ACPI_DMAR_FLAG_INTR_REMAP BIT(0)
15 0 : #define ACPI_DMAR_FLAG_X2APIC_OPT_OUT BIT(1)
16 0 : #define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN BIT(2)
17 :
18 0 : #define ACPI_MMIO_GET(res) (res)->reg_base[0].mmio
19 0 : #define ACPI_IO_GET(res) (res)->reg_base[0].port
20 0 : #define ACPI_RESOURCE_SIZE_GET(res) (res)->reg_base[0].length
21 0 : #define ACPI_RESOURCE_TYPE_GET(res) (res)->reg_base[0].type
22 :
23 0 : #define ACPI_MULTI_MMIO_GET(res, idx) (res)->reg_base[idx].mmio
24 0 : #define ACPI_MULTI_IO_GET(res, idx) (res)->reg_base[idx].port
25 0 : #define ACPI_MULTI_RESOURCE_SIZE_GET(res, idx) (res)->reg_base[idx].length
26 0 : #define ACPI_MULTI_RESOURCE_TYPE_GET(res, idx) (res)->reg_base[idx].type
27 :
28 0 : #define ACPI_RESOURCE_COUNT_GET(res) (res)->mmio_max
29 :
30 0 : enum acpi_res_type {
31 : /** IO mapped Resource type */
32 : ACPI_RES_TYPE_IO,
33 : /** Memory mapped Resource type */
34 : ACPI_RES_TYPE_MEM,
35 : /** Unknown Resource type */
36 : ACPI_RES_TYPE_UNKNOWN,
37 : };
38 :
39 0 : struct acpi_dev {
40 0 : ACPI_HANDLE handle;
41 0 : char *path;
42 0 : ACPI_RESOURCE *res_lst;
43 0 : int res_type;
44 0 : ACPI_DEVICE_INFO *dev_info;
45 : };
46 :
47 0 : union acpi_dmar_id {
48 : struct {
49 0 : uint16_t function: 3;
50 0 : uint16_t device: 5;
51 0 : uint16_t bus: 8;
52 0 : } bits;
53 :
54 0 : uint16_t raw;
55 : };
56 :
57 0 : struct acpi_mcfg {
58 0 : ACPI_TABLE_HEADER header;
59 : uint64_t _reserved;
60 0 : ACPI_MCFG_ALLOCATION pci_segs[];
61 : } __packed;
62 :
63 0 : struct acpi_irq_resource {
64 0 : uint32_t flags;
65 0 : uint8_t irq_vector_max;
66 0 : uint16_t *irqs;
67 : };
68 :
69 0 : struct acpi_reg_base {
70 0 : enum acpi_res_type type;
71 : union {
72 0 : uintptr_t mmio;
73 0 : uintptr_t port;
74 0 : };
75 0 : uint32_t length;
76 : };
77 :
78 0 : struct acpi_mmio_resource {
79 0 : uint8_t mmio_max;
80 0 : struct acpi_reg_base *reg_base;
81 : };
82 :
83 : /**
84 : * @brief Get the ACPI HID for a node
85 : *
86 : * @param node_id DTS node identifier
87 : * @return The HID of the ACPI node
88 : */
89 1 : #define ACPI_DT_HID(node_id) DT_PROP(node_id, acpi_hid)
90 :
91 : /**
92 : * @brief Get the ACPI UID for a node if one exist
93 : *
94 : * @param node_id DTS node identifier
95 : * @return The UID of the ACPI node else NULL if does not exist
96 : */
97 1 : #define ACPI_DT_UID(node_id) DT_PROP_OR(node_id, acpi_uid, NULL)
98 :
99 : /**
100 : * @brief check whether the node has ACPI HID property or not
101 : *
102 : * @param node_id DTS node identifier
103 : * @return 1 if the node has the HID, 0 otherwise.
104 : */
105 1 : #define ACPI_DT_HAS_HID(node_id) DT_NODE_HAS_PROP(node_id, acpi_hid)
106 :
107 : /**
108 : * @brief check whether the node has ACPI UID property or not
109 : *
110 : * @param node_id DTS node identifier
111 : * @return 1 if the node has the UID, 0 otherwise.
112 : */
113 1 : #define ACPI_DT_HAS_UID(node_id) DT_NODE_HAS_PROP(node_id, acpi_uid)
114 :
115 : /**
116 : * @brief Init legacy interrupt routing table information from ACPI.
117 : * Currently assume platform have only one PCI bus.
118 : *
119 : * @param hid the hardware id of the ACPI child device
120 : * @param uid the unique id of the ACPI child device. The uid can be
121 : * NULL if only one device with given hid present in the platform.
122 : * @return return 0 on success or error code
123 : */
124 1 : int acpi_legacy_irq_init(const char *hid, const char *uid);
125 :
126 : /**
127 : * @brief Retrieve a legacy interrupt number for a PCI device.
128 : *
129 : * @param bdf the BDF of endpoint/PCI device
130 : * @return return IRQ number or UINT_MAX if not found
131 : */
132 1 : uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf);
133 :
134 : /**
135 : * @brief Retrieve the current resource settings of a device.
136 : *
137 : * @param dev_name the name of the device
138 : * @param res the list of acpi resource list
139 : * @return return 0 on success or error code
140 : */
141 1 : int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res);
142 :
143 : /**
144 : * @brief Retrieve possible resource settings of a device.
145 : *
146 : * @param dev_name the name of the device
147 : * @param res the list of acpi resource list
148 : * @return return 0 on success or error code
149 : */
150 1 : int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res);
151 :
152 : /**
153 : * @brief Free current resource list memory which is retrieved by
154 : * acpi_current_resource_get().
155 : *
156 : * @param res the list of acpi resource list
157 : * @return return 0 on success or error code
158 : */
159 1 : int acpi_current_resource_free(ACPI_RESOURCE *res);
160 :
161 : /**
162 : * @brief Parse resource table for a given resource type.
163 : *
164 : * @param res the list of acpi resource list
165 : * @param res_type the acpi resource type
166 : * @return resource list for the given type on success or NULL
167 : */
168 1 : ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type);
169 :
170 : /**
171 : * @brief Retrieve ACPI device info for given hardware id and unique id.
172 : *
173 : * @param hid the hardware id of the ACPI child device
174 : * @param uid the unique id of the ACPI child device. The uid can be
175 : * NULL if only one device with given HID present in the platform.
176 : * @return ACPI child device info on success or NULL
177 : */
178 1 : struct acpi_dev *acpi_device_get(const char *hid, const char *uid);
179 :
180 : /**
181 : * @brief Retrieve acpi device info from the index.
182 : *
183 : * @param index the device index of an acpi child device
184 : * @return acpi child device info on success or NULL
185 : */
186 1 : struct acpi_dev *acpi_device_by_index_get(int index);
187 :
188 : /**
189 : * @brief Parse resource table for irq info.
190 : *
191 : * @param res_lst the list of acpi resource list
192 : * @return irq resource list on success or NULL
193 : */
194 1 : static inline ACPI_RESOURCE_IRQ *acpi_irq_res_get(ACPI_RESOURCE *res_lst)
195 : {
196 : ACPI_RESOURCE *res = acpi_resource_parse(res_lst, ACPI_RESOURCE_TYPE_IRQ);
197 :
198 : return res ? &res->Data.Irq : NULL;
199 : }
200 :
201 : /**
202 : * @brief Parse resource table for irq info.
203 : *
204 : * @param child_dev the device object of the ACPI node
205 : * @param irq_res irq resource info
206 : * @return return 0 on success or error code
207 : */
208 1 : int acpi_device_irq_get(struct acpi_dev *child_dev, struct acpi_irq_resource *irq_res);
209 :
210 : /**
211 : * @brief Parse resource table for MMIO info.
212 : *
213 : * @param child_dev the device object of the ACPI node
214 : * @param mmio_res MMIO resource info
215 : * @return return 0 on success or error code
216 : */
217 1 : int acpi_device_mmio_get(struct acpi_dev *child_dev, struct acpi_mmio_resource *mmio_res);
218 :
219 : /**
220 : * @brief Parse resource table for identify resource type.
221 : *
222 : * @param res the list of acpi resource list
223 : * @return resource type on success or invalid resource type
224 : */
225 1 : int acpi_device_type_get(ACPI_RESOURCE *res);
226 :
227 : /**
228 : * @brief Retrieve acpi table for the given signature.
229 : *
230 : * @param signature pointer to the 4-character ACPI signature for the requested table
231 : * @param inst instance number for the requested table
232 : * @return acpi_table pointer to the acpi table on success else return NULL
233 : */
234 1 : void *acpi_table_get(char *signature, int inst);
235 :
236 : /**
237 : * @brief retrieve acpi MAD table for the given type.
238 : *
239 : * @param type type of requested MAD table
240 : * @param tables pointer to the MAD table
241 : * @param num_inst number of instance for the requested table
242 : * @return return 0 on success or error code
243 : */
244 1 : int acpi_madt_entry_get(int type, ACPI_SUBTABLE_HEADER **tables, int *num_inst);
245 :
246 : /**
247 : * @brief retrieve DMA remapping structure for the given type.
248 : *
249 : * @param type type of remapping structure
250 : * @param tables pointer to the dmar id structure
251 : * @return return 0 on success or error code
252 : */
253 1 : int acpi_dmar_entry_get(enum AcpiDmarType type, ACPI_SUBTABLE_HEADER **tables);
254 :
255 : /**
256 : * @brief retrieve acpi DRHD info for the given scope.
257 : *
258 : * @param scope scope of requested DHRD table
259 : * @param dev_scope pointer to the sub table (optional)
260 : * @param dmar_id pointer to the DHRD info
261 : * @param num_inst number of instance for the requested table
262 : * @param max_inst maximum number of entry for the given dmar_id buffer
263 : * @return return 0 on success or error code
264 : */
265 1 : int acpi_drhd_get(enum AcpiDmarScopeType scope, ACPI_DMAR_DEVICE_SCOPE *dev_scope,
266 : union acpi_dmar_id *dmar_id, int *num_inst, int max_inst);
267 :
268 0 : typedef void (*dmar_foreach_subtable_func_t)(ACPI_DMAR_HEADER *subtable, void *arg);
269 0 : typedef void (*dmar_foreach_devscope_func_t)(ACPI_DMAR_DEVICE_SCOPE *devscope, void *arg);
270 :
271 0 : void acpi_dmar_foreach_subtable(ACPI_TABLE_DMAR *dmar, dmar_foreach_subtable_func_t func,
272 : void *arg);
273 0 : void acpi_dmar_foreach_devscope(ACPI_DMAR_HARDWARE_UNIT *hu,
274 : dmar_foreach_devscope_func_t func, void *arg);
275 :
276 : /**
277 : * @brief Retrieve IOAPIC id
278 : *
279 : * @param ioapic_id IOAPIC id
280 : * @return return 0 on success or error code
281 : */
282 1 : int acpi_dmar_ioapic_get(uint16_t *ioapic_id);
283 :
284 : /**
285 : * @brief Retrieve the 'n'th enabled local apic info.
286 : *
287 : * @param cpu_num the cpu number
288 : * @return local apic info on success or NULL otherwise
289 : */
290 1 : ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num);
291 :
292 : /**
293 : * @brief invoke an ACPI method and return the result.
294 : *
295 : * @param path the path name of the ACPI object
296 : * @param arg_list the list of arguments to be pass down
297 : * @param ret_obj the ACPI result to be return
298 : * @return return 0 on success or error code
299 : */
300 1 : int acpi_invoke_method(char *path, ACPI_OBJECT_LIST *arg_list, ACPI_OBJECT *ret_obj);
301 :
302 : #endif
|