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