1 /*
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 #define ACPI_RES_INVALID ACPI_RESOURCE_TYPE_MAX
12 
13 #define ACPI_DRHD_FLAG_INCLUDE_PCI_ALL			BIT(0)
14 #define ACPI_DMAR_FLAG_INTR_REMAP				BIT(0)
15 #define ACPI_DMAR_FLAG_X2APIC_OPT_OUT			BIT(1)
16 #define ACPI_DMAR_FLAG_DMA_CTRL_PLATFORM_OPT_IN	BIT(2)
17 
18 struct acpi_dev {
19 	ACPI_HANDLE handle;
20 	char *path;
21 	char hid[CONFIG_ACPI_HID_LEN_MAX];
22 	ACPI_RESOURCE *res_lst;
23 	int res_type;
24 	ACPI_DEVICE_INFO *dev_info;
25 };
26 
27 union acpi_dmar_id {
28 	struct {
29 		uint16_t function: 3;
30 		uint16_t device: 5;
31 		uint16_t bus: 8;
32 	} bits;
33 
34 	uint16_t raw;
35 };
36 
37 struct acpi_mcfg {
38 	struct acpi_table_header header;
39 	uint64_t _reserved;
40 	struct acpi_mcfg_allocation pci_segs[];
41 } __packed;
42 
43 /**
44  * @brief Retrieve a legacy interrupt number for a PCI device.
45  *
46  * @param bdf the BDF of endpoint/PCI device
47  * @return return IRQ number or UINT_MAX if not found
48  */
49 uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf);
50 
51 /**
52  * @brief Retrieve the current resource settings of a device.
53  *
54  * @param dev_name the name of the device
55  * @param res the list of acpi resource list
56  * @return return 0 on success or error code
57  */
58 int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res);
59 
60 /**
61  * @brief Retrieve possible resource settings of a device.
62  *
63  * @param dev_name the name of the device
64  * @param res the list of acpi resource list
65  * @return return 0 on success or error code
66  */
67 int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res);
68 
69 /**
70  * @brief Free current resource list memory which is retrieved by
71  * acpi_current_resource_get().
72  *
73  * @param res the list of acpi resource list
74  * @return return 0 on success or error code
75  */
76 int acpi_current_resource_free(ACPI_RESOURCE *res);
77 
78 /**
79  * @brief Retrieve IRQ routing table of a bus.
80  *
81  * @param bus_name the name of the bus
82  * @param rt_table the IRQ routing table
83  * @param rt_size the the size of IRQ routing table
84  * @return return 0 on success or error code
85  */
86 int acpi_get_irq_routing_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size);
87 
88 /**
89  * @brief Parse resource table for a given resource type.
90  *
91  * @param res the list of acpi resource list
92  * @param res_type the acpi resource type
93  * @return resource list for the given type on success or NULL
94  */
95 ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type);
96 
97 /**
98  * @brief Retrieve acpi device info for given hardware id and unique id.
99  *
100  * @param hid the hardware id of the acpi child device
101  * @param inst the unique id of the acpi child device
102  * @return acpi child device info on success or NULL
103  */
104 struct acpi_dev *acpi_device_get(char *hid, int inst);
105 
106 /**
107  * @brief Retrieve acpi device info from the index.
108  *
109  * @param index the device index of an acpi child device
110  * @return acpi child device info on success or NULL
111  */
112 struct acpi_dev *acpi_device_by_index_get(int index);
113 
114 /**
115  * @brief Parse resource table for irq info.
116  *
117  * @param res_lst the list of acpi resource list
118  * @return irq resource list on success or NULL
119  */
acpi_irq_res_get(ACPI_RESOURCE * res_lst)120 static inline ACPI_RESOURCE_IRQ *acpi_irq_res_get(ACPI_RESOURCE *res_lst)
121 {
122 	ACPI_RESOURCE *res = acpi_resource_parse(res_lst, ACPI_RESOURCE_TYPE_IRQ);
123 
124 	return res ? &res->Data.Irq : NULL;
125 }
126 
127 /**
128  * @brief Parse resource table for identify resource type.
129  *
130  * @param res the list of acpi resource list
131  * @return resource type on success or invalid resource type
132  */
133 int acpi_device_type_get(ACPI_RESOURCE *res);
134 
135 /**
136  * @brief Retrieve acpi table for the given signature.
137  *
138  * @param signature pointer to the 4-character ACPI signature for the requested table
139  * @param inst instance number for the requested table
140  * @return acpi_table pointer to the acpi table on success else return NULL
141  */
142 void *acpi_table_get(char *signature, int inst);
143 
144 /**
145  * @brief retrieve acpi MAD table for the given type.
146  *
147  * @param type type of requested MAD table
148  * @param tables pointer to the MAD table
149  * @param num_inst number of instance for the requested table
150  * @return return 0 on success or error code
151  */
152 int acpi_madt_entry_get(int type, struct acpi_subtable_header **tables, int *num_inst);
153 
154 /**
155  * @brief retrieve DMA remapping structure for the given type.
156  *
157  * @param type type of remapping structure
158  * @param tables pointer to the dmar id structure
159  * @return return 0 on success or error code
160  */
161 int acpi_dmar_entry_get(enum AcpiDmarType type,
162 	struct acpi_subtable_header **tables);
163 
164 /**
165  * @brief retrieve acpi DRHD info for the given scope.
166  *
167  * @param scope scope of requested DHRD table
168  * @param dev_scope pointer to the sub table (optional)
169  * @param dmar_id pointer to the DHRD info
170  * @param num_inst number of instance for the requested table
171  * @param max_inst maximum number of entry for the given dmar_id buffer
172  * @return return 0 on success or error code
173  */
174 int acpi_drhd_get(enum AcpiDmarScopeType scope, struct acpi_dmar_device_scope *dev_scope,
175 	union acpi_dmar_id *dmar_id, int *num_inst, int max_inst);
176 
177 /**
178  * @brief Retrieve lapic info for a specific cpu.
179  *
180  * @param cpu_num the cpu number
181  * @return lapic info on success or NULL
182  */
183 struct acpi_madt_local_apic *acpi_local_apic_get(uint32_t cpu_num);
184 #endif
185