1#pragma once
2
3#include <uacpi/status.h>
4#include <uacpi/platform/types.h>
5#include <uacpi/platform/compiler.h>
6#include <uacpi/platform/arch_helpers.h>
7#include <uacpi/platform/config.h>
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13#if UACPI_POINTER_SIZE == 4 && defined(UACPI_PHYS_ADDR_IS_32BITS)
14typedef uacpi_u32 uacpi_phys_addr;
15typedef uacpi_u32 uacpi_io_addr;
16#else
17typedef uacpi_u64 uacpi_phys_addr;
18typedef uacpi_u64 uacpi_io_addr;
19#endif
20
21typedef void *uacpi_handle;
22
23typedef union uacpi_object_name {
24 uacpi_char text[4];
25 uacpi_u32 id;
26} uacpi_object_name;
27
28typedef enum uacpi_iteration_decision {
29 UACPI_ITERATION_DECISION_CONTINUE = 0,
30 UACPI_ITERATION_DECISION_BREAK,
31
32 /**
33 * Ignore all of the children of the current node and proceed directly to
34 * its peer nodes.
35 *
36 * Only applicable for API that interacts with the AML namespace such as
37 * uacpi_namespace_for_each_child, uacpi_find_deivces, etc.
38 */
39 UACPI_ITERATION_DECISION_NEXT_PEER,
40} uacpi_iteration_decision;
41
42typedef enum uacpi_address_space {
43 UACPI_ADDRESS_SPACE_SYSTEM_MEMORY = 0,
44 UACPI_ADDRESS_SPACE_SYSTEM_IO = 1,
45 UACPI_ADDRESS_SPACE_PCI_CONFIG = 2,
46 UACPI_ADDRESS_SPACE_EMBEDDED_CONTROLLER = 3,
47 UACPI_ADDRESS_SPACE_SMBUS = 4,
48 UACPI_ADDRESS_SPACE_SYSTEM_CMOS = 5,
49 UACPI_ADDRESS_SPACE_PCI_BAR_TARGET = 6,
50 UACPI_ADDRESS_SPACE_IPMI = 7,
51 UACPI_ADDRESS_SPACE_GENERAL_PURPOSE_IO = 8,
52 UACPI_ADDRESS_SPACE_GENERIC_SERIAL_BUS = 9,
53 UACPI_ADDRESS_SPACE_PCC = 0x0A,
54 UACPI_ADDRESS_SPACE_PRM = 0x0B,
55 UACPI_ADDRESS_SPACE_FFIXEDHW = 0x7F,
56
57 // Internal type
58 UACPI_ADDRESS_SPACE_TABLE_DATA = 0xDA1A,
59} uacpi_address_space;
60const uacpi_char *uacpi_address_space_to_string(uacpi_address_space space);
61
62#ifndef UACPI_BAREBONES_MODE
63
64typedef enum uacpi_init_level {
65 // Reboot state, nothing is available
66 UACPI_INIT_LEVEL_EARLY = 0,
67
68 /**
69 * State after a successfull call to uacpi_initialize. Table API and
70 * other helpers that don't depend on the ACPI namespace may be used.
71 */
72 UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED = 1,
73
74 /**
75 * State after a successfull call to uacpi_namespace_load. Most API may be
76 * used, namespace can be iterated, etc.
77 */
78 UACPI_INIT_LEVEL_NAMESPACE_LOADED = 2,
79
80 /**
81 * The final initialization stage, this is entered after the call to
82 * uacpi_namespace_initialize. All API is available to use.
83 */
84 UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED = 3,
85} uacpi_init_level;
86
87typedef struct uacpi_pci_address {
88 uacpi_u16 segment;
89 uacpi_u8 bus;
90 uacpi_u8 device;
91 uacpi_u8 function;
92} uacpi_pci_address;
93
94typedef struct uacpi_data_view {
95 union {
96 uacpi_u8 *bytes;
97 const uacpi_u8 *const_bytes;
98
99 uacpi_char *text;
100 const uacpi_char *const_text;
101
102 void *data;
103 const void *const_data;
104 };
105 uacpi_size length;
106} uacpi_data_view;
107
108typedef struct uacpi_namespace_node uacpi_namespace_node;
109
110typedef enum uacpi_object_type {
111 UACPI_OBJECT_UNINITIALIZED = 0,
112 UACPI_OBJECT_INTEGER = 1,
113 UACPI_OBJECT_STRING = 2,
114 UACPI_OBJECT_BUFFER = 3,
115 UACPI_OBJECT_PACKAGE = 4,
116 UACPI_OBJECT_FIELD_UNIT = 5,
117 UACPI_OBJECT_DEVICE = 6,
118 UACPI_OBJECT_EVENT = 7,
119 UACPI_OBJECT_METHOD = 8,
120 UACPI_OBJECT_MUTEX = 9,
121 UACPI_OBJECT_OPERATION_REGION = 10,
122 UACPI_OBJECT_POWER_RESOURCE = 11,
123 UACPI_OBJECT_PROCESSOR = 12,
124 UACPI_OBJECT_THERMAL_ZONE = 13,
125 UACPI_OBJECT_BUFFER_FIELD = 14,
126 UACPI_OBJECT_DEBUG = 16,
127
128 UACPI_OBJECT_REFERENCE = 20,
129 UACPI_OBJECT_BUFFER_INDEX = 21,
130 UACPI_OBJECT_MAX_TYPE_VALUE = UACPI_OBJECT_BUFFER_INDEX
131} uacpi_object_type;
132
133// Type bits for API requiring a bit mask, e.g. uacpi_eval_typed
134typedef enum uacpi_object_type_bits {
135 UACPI_OBJECT_INTEGER_BIT = (1 << UACPI_OBJECT_INTEGER),
136 UACPI_OBJECT_STRING_BIT = (1 << UACPI_OBJECT_STRING),
137 UACPI_OBJECT_BUFFER_BIT = (1 << UACPI_OBJECT_BUFFER),
138 UACPI_OBJECT_PACKAGE_BIT = (1 << UACPI_OBJECT_PACKAGE),
139 UACPI_OBJECT_FIELD_UNIT_BIT = (1 << UACPI_OBJECT_FIELD_UNIT),
140 UACPI_OBJECT_DEVICE_BIT = (1 << UACPI_OBJECT_DEVICE),
141 UACPI_OBJECT_EVENT_BIT = (1 << UACPI_OBJECT_EVENT),
142 UACPI_OBJECT_METHOD_BIT = (1 << UACPI_OBJECT_METHOD),
143 UACPI_OBJECT_MUTEX_BIT = (1 << UACPI_OBJECT_MUTEX),
144 UACPI_OBJECT_OPERATION_REGION_BIT = (1 << UACPI_OBJECT_OPERATION_REGION),
145 UACPI_OBJECT_POWER_RESOURCE_BIT = (1 << UACPI_OBJECT_POWER_RESOURCE),
146 UACPI_OBJECT_PROCESSOR_BIT = (1 << UACPI_OBJECT_PROCESSOR),
147 UACPI_OBJECT_THERMAL_ZONE_BIT = (1 << UACPI_OBJECT_THERMAL_ZONE),
148 UACPI_OBJECT_BUFFER_FIELD_BIT = (1 << UACPI_OBJECT_BUFFER_FIELD),
149 UACPI_OBJECT_DEBUG_BIT = (1 << UACPI_OBJECT_DEBUG),
150 UACPI_OBJECT_REFERENCE_BIT = (1 << UACPI_OBJECT_REFERENCE),
151 UACPI_OBJECT_BUFFER_INDEX_BIT = (1 << UACPI_OBJECT_BUFFER_INDEX),
152 UACPI_OBJECT_ANY_BIT = 0xFFFFFFFF,
153} uacpi_object_type_bits;
154
155typedef struct uacpi_object uacpi_object;
156
157void uacpi_object_ref(uacpi_object *obj);
158void uacpi_object_unref(uacpi_object *obj);
159
160uacpi_object_type uacpi_object_get_type(uacpi_object*);
161uacpi_object_type_bits uacpi_object_get_type_bit(uacpi_object*);
162
163/**
164 * Returns UACPI_TRUE if the provided object's type matches this type.
165 */
166uacpi_bool uacpi_object_is(uacpi_object*, uacpi_object_type);
167
168/**
169 * Returns UACPI_TRUE if the provided object's type is one of the values
170 * specified in the 'type_mask' of UACPI_OBJECT_*_BIT.
171 */
172uacpi_bool uacpi_object_is_one_of(
173 uacpi_object*, uacpi_object_type_bits type_mask
174);
175
176const uacpi_char *uacpi_object_type_to_string(uacpi_object_type);
177
178/**
179 * Create an uninitialized object. The object can be further overwritten via
180 * uacpi_object_assign_* to anything.
181 */
182uacpi_object *uacpi_object_create_uninitialized(void);
183
184/**
185 * Create an integer object with the value provided.
186 */
187uacpi_object *uacpi_object_create_integer(uacpi_u64);
188
189typedef enum uacpi_overflow_behavior {
190 UACPI_OVERFLOW_ALLOW = 0,
191 UACPI_OVERFLOW_TRUNCATE,
192 UACPI_OVERFLOW_DISALLOW,
193} uacpi_overflow_behavior;
194
195/**
196 * Same as uacpi_object_create_integer, but introduces additional ways to
197 * control what happens if the provided integer is larger than 32-bits, and the
198 * AML code expects 32-bit integers.
199 *
200 * - UACPI_OVERFLOW_ALLOW -> do nothing, same as the vanilla helper
201 * - UACPI_OVERFLOW_TRUNCATE -> truncate the integer to 32-bits if it happens to
202 * be larger than allowed by the DSDT
203 * - UACPI_OVERFLOW_DISALLOW -> fail object creation with
204 * UACPI_STATUS_INVALID_ARGUMENT if the provided
205 * value happens to be too large
206 */
207uacpi_status uacpi_object_create_integer_safe(
208 uacpi_u64, uacpi_overflow_behavior, uacpi_object **out_obj
209);
210
211uacpi_status uacpi_object_assign_integer(uacpi_object*, uacpi_u64 value);
212uacpi_status uacpi_object_get_integer(uacpi_object*, uacpi_u64 *out);
213
214/**
215 * Create a string/buffer object. Takes in a constant view of the data.
216 *
217 * NOTE: The data is copied to a separately allocated buffer and is not taken
218 * ownership of.
219 */
220uacpi_object *uacpi_object_create_string(uacpi_data_view);
221uacpi_object *uacpi_object_create_cstring(const uacpi_char*);
222uacpi_object *uacpi_object_create_buffer(uacpi_data_view);
223
224/**
225 * Returns a writable view of the data stored in the string or buffer type
226 * object.
227 */
228uacpi_status uacpi_object_get_string_or_buffer(
229 uacpi_object*, uacpi_data_view *out
230);
231uacpi_status uacpi_object_get_string(uacpi_object*, uacpi_data_view *out);
232uacpi_status uacpi_object_get_buffer(uacpi_object*, uacpi_data_view *out);
233
234/**
235 * Returns UACPI_TRUE if the provided string object is actually an AML namepath.
236 *
237 * This can only be the case for package elements. If a package element is
238 * specified as a path to an object in AML, it's not resolved by the interpreter
239 * right away as it might not have been defined at that point yet, and is
240 * instead stored as a special string object to be resolved by client code
241 * when needed.
242 *
243 * Example usage:
244 * uacpi_namespace_node *target_node = UACPI_NULL;
245 *
246 * uacpi_object *obj = UACPI_NULL;
247 * uacpi_eval(scope, path, UACPI_NULL, &obj);
248 *
249 * uacpi_object_array arr;
250 * uacpi_object_get_package(obj, &arr);
251 *
252 * if (uacpi_object_is_aml_namepath(arr.objects[0])) {
253 * uacpi_object_resolve_as_aml_namepath(
254 * arr.objects[0], scope, &target_node
255 * );
256 * }
257 */
258uacpi_bool uacpi_object_is_aml_namepath(uacpi_object*);
259
260/**
261 * Resolve an AML namepath contained in a string object.
262 *
263 * This is only applicable to objects that are package elements. See an
264 * explanation of how this works in the comment above the declaration of
265 * uacpi_object_is_aml_namepath.
266 *
267 * This is a shorthand for:
268 * uacpi_data_view view;
269 * uacpi_object_get_string(object, &view);
270 *
271 * target_node = uacpi_namespace_node_resolve_from_aml_namepath(
272 * scope, view.text
273 * );
274 */
275uacpi_status uacpi_object_resolve_as_aml_namepath(
276 uacpi_object*, uacpi_namespace_node *scope, uacpi_namespace_node **out_node
277);
278
279/**
280 * Make the provided object a string/buffer.
281 * Takes in a constant view of the data to be stored in the object.
282 *
283 * NOTE: The data is copied to a separately allocated buffer and is not taken
284 * ownership of.
285 */
286uacpi_status uacpi_object_assign_string(uacpi_object*, uacpi_data_view in);
287uacpi_status uacpi_object_assign_buffer(uacpi_object*, uacpi_data_view in);
288
289typedef struct uacpi_object_array {
290 uacpi_object **objects;
291 uacpi_size count;
292} uacpi_object_array;
293
294/**
295 * Create a package object and store all of the objects in the array inside.
296 * The array is allowed to be empty.
297 *
298 * NOTE: the reference count of each object is incremented before being stored
299 * in the object. Client code must remove all of the locally created
300 * references at its own discretion.
301 */
302uacpi_object *uacpi_object_create_package(uacpi_object_array in);
303
304/**
305 * Returns the list of objects stored in a package object.
306 *
307 * NOTE: the reference count of the objects stored inside is not incremented,
308 * which means destorying/overwriting the object also potentially destroys
309 * all of the objects stored inside unless the reference count is
310 * incremented by the client via uacpi_object_ref.
311 */
312uacpi_status uacpi_object_get_package(uacpi_object*, uacpi_object_array *out);
313
314/**
315 * Make the provided object a package and store all of the objects in the array
316 * inside. The array is allowed to be empty.
317 *
318 * NOTE: the reference count of each object is incremented before being stored
319 * in the object. Client code must remove all of the locally created
320 * references at its own discretion.
321 */
322uacpi_status uacpi_object_assign_package(uacpi_object*, uacpi_object_array in);
323
324/**
325 * Create a reference object and make it point to 'child'.
326 *
327 * NOTE: child's reference count is incremented by one. Client code must remove
328 * all of the locally created references at its own discretion.
329 */
330uacpi_object *uacpi_object_create_reference(uacpi_object *child);
331
332/**
333 * Make the provided object a reference and make it point to 'child'.
334 *
335 * NOTE: child's reference count is incremented by one. Client code must remove
336 * all of the locally created references at its own discretion.
337 */
338uacpi_status uacpi_object_assign_reference(uacpi_object*, uacpi_object *child);
339
340/**
341 * Retrieve the object pointed to by a reference object.
342 *
343 * NOTE: the reference count of the returned object is incremented by one and
344 * must be uacpi_object_unref'ed by the client when no longer needed.
345 */
346uacpi_status uacpi_object_get_dereferenced(uacpi_object*, uacpi_object **out);
347
348typedef struct uacpi_processor_info {
349 uacpi_u8 id;
350 uacpi_u32 block_address;
351 uacpi_u8 block_length;
352} uacpi_processor_info;
353
354/**
355 * Returns the information about the provided processor object.
356 */
357uacpi_status uacpi_object_get_processor_info(
358 uacpi_object*, uacpi_processor_info *out
359);
360
361typedef struct uacpi_power_resource_info {
362 uacpi_u8 system_level;
363 uacpi_u16 resource_order;
364} uacpi_power_resource_info;
365
366/**
367 * Returns the information about the provided power resource object.
368 */
369uacpi_status uacpi_object_get_power_resource_info(
370 uacpi_object*, uacpi_power_resource_info *out
371);
372
373typedef enum uacpi_region_op {
374 // data => uacpi_region_attach_data
375 UACPI_REGION_OP_ATTACH = 0,
376 // data => uacpi_region_detach_data
377 UACPI_REGION_OP_DETACH,
378
379 // data => uacpi_region_rw_data
380 UACPI_REGION_OP_READ,
381 UACPI_REGION_OP_WRITE,
382
383 // data => uacpi_region_pcc_send_data
384 UACPI_REGION_OP_PCC_SEND,
385
386 // data => uacpi_region_gpio_rw_data
387 UACPI_REGION_OP_GPIO_READ,
388 UACPI_REGION_OP_GPIO_WRITE,
389
390 // data => uacpi_region_ipmi_rw_data
391 UACPI_REGION_OP_IPMI_COMMAND,
392
393 // data => uacpi_region_ffixedhw_rw_data
394 UACPI_REGION_OP_FFIXEDHW_COMMAND,
395
396 // data => uacpi_region_prm_rw_data
397 UACPI_REGION_OP_PRM_COMMAND,
398
399 // data => uacpi_region_serial_rw_data
400 UACPI_REGION_OP_SERIAL_READ,
401 UACPI_REGION_OP_SERIAL_WRITE,
402} uacpi_region_op;
403
404typedef struct uacpi_generic_region_info {
405 uacpi_u64 base;
406 uacpi_u64 length;
407} uacpi_generic_region_info;
408
409typedef struct uacpi_pcc_region_info {
410 uacpi_data_view buffer;
411 uacpi_u8 subspace_id;
412} uacpi_pcc_region_info;
413
414typedef struct uacpi_gpio_region_info
415{
416 uacpi_u64 num_pins;
417} uacpi_gpio_region_info;
418
419typedef struct uacpi_region_attach_data {
420 void *handler_context;
421 uacpi_namespace_node *region_node;
422 union {
423 uacpi_generic_region_info generic_info;
424 uacpi_pcc_region_info pcc_info;
425 uacpi_gpio_region_info gpio_info;
426 };
427 void *out_region_context;
428} uacpi_region_attach_data;
429
430typedef struct uacpi_region_rw_data {
431 void *handler_context;
432 void *region_context;
433 union {
434 uacpi_phys_addr address;
435 uacpi_u64 offset;
436 };
437 uacpi_u64 value;
438 uacpi_u8 byte_width;
439} uacpi_region_rw_data;
440
441typedef struct uacpi_region_pcc_send_data {
442 void *handler_context;
443 void *region_context;
444 uacpi_data_view buffer;
445} uacpi_region_pcc_send_data;
446
447typedef struct uacpi_region_gpio_rw_data
448{
449 void *handler_context;
450 void *region_context;
451 uacpi_data_view connection;
452 uacpi_u32 pin_offset;
453 uacpi_u32 num_pins;
454 uacpi_u64 value;
455} uacpi_region_gpio_rw_data;
456
457typedef struct uacpi_region_ipmi_rw_data
458{
459 void *handler_context;
460 void *region_context;
461 uacpi_data_view in_out_message;
462 uacpi_u64 command;
463} uacpi_region_ipmi_rw_data;
464
465typedef uacpi_region_ipmi_rw_data uacpi_region_ffixedhw_rw_data;
466
467typedef struct uacpi_region_prm_rw_data
468{
469 void *handler_context;
470 void *region_context;
471 uacpi_data_view in_out_message;
472} uacpi_region_prm_rw_data;
473
474typedef enum uacpi_access_attribute {
475 UACPI_ACCESS_ATTRIBUTE_QUICK = 0x02,
476 UACPI_ACCESS_ATTRIBUTE_SEND_RECEIVE = 0x04,
477 UACPI_ACCESS_ATTRIBUTE_BYTE = 0x06,
478 UACPI_ACCESS_ATTRIBUTE_WORD = 0x08,
479 UACPI_ACCESS_ATTRIBUTE_BLOCK = 0x0A,
480 UACPI_ACCESS_ATTRIBUTE_BYTES = 0x0B,
481 UACPI_ACCESS_ATTRIBUTE_PROCESS_CALL = 0x0C,
482 UACPI_ACCESS_ATTRIBUTE_BLOCK_PROCESS_CALL = 0x0D,
483 UACPI_ACCESS_ATTRIBUTE_RAW_BYTES = 0x0E,
484 UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES = 0x0F,
485} uacpi_access_attribute;
486
487typedef struct uacpi_region_serial_rw_data {
488 void *handler_context;
489 void *region_context;
490 uacpi_u64 command;
491 uacpi_data_view connection;
492 uacpi_data_view in_out_buffer;
493 uacpi_access_attribute access_attribute;
494
495 /**
496 * Applicable if access_attribute is one of:
497 * - UACPI_ACCESS_ATTRIBUTE_BYTES
498 * - UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
499 * - UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
500 */
501 uacpi_u8 access_length;
502} uacpi_region_serial_rw_data;
503
504typedef struct uacpi_region_detach_data {
505 void *handler_context;
506 void *region_context;
507 uacpi_namespace_node *region_node;
508} uacpi_region_detach_data;
509
510typedef uacpi_status (*uacpi_region_handler)
511 (uacpi_region_op op, uacpi_handle op_data);
512
513typedef uacpi_status (*uacpi_notify_handler)
514 (uacpi_handle context, uacpi_namespace_node *node, uacpi_u64 value);
515
516typedef enum uacpi_firmware_request_type {
517 UACPI_FIRMWARE_REQUEST_TYPE_BREAKPOINT,
518 UACPI_FIRMWARE_REQUEST_TYPE_FATAL,
519} uacpi_firmware_request_type;
520
521typedef struct uacpi_firmware_request {
522 uacpi_u8 type;
523
524 union {
525 // UACPI_FIRMWARE_REQUEST_BREAKPOINT
526 struct {
527 // The context of the method currently being executed
528 uacpi_handle ctx;
529 } breakpoint;
530
531 // UACPI_FIRMWARE_REQUEST_FATAL
532 struct {
533 uacpi_u8 type;
534 uacpi_u32 code;
535 uacpi_u64 arg;
536 } fatal;
537 };
538} uacpi_firmware_request;
539
540#define UACPI_INTERRUPT_NOT_HANDLED 0
541#define UACPI_INTERRUPT_HANDLED 1
542typedef uacpi_u32 uacpi_interrupt_ret;
543
544typedef uacpi_interrupt_ret (*uacpi_interrupt_handler)(uacpi_handle);
545
546#endif // !UACPI_BAREBONES_MODE
547
548#ifdef __cplusplus
549}
550#endif
551