1#pragma once
2
3#include <uacpi/status.h>
4#include <uacpi/types.h>
5#include <uacpi/internal/shareable.h>
6
7#ifndef UACPI_BAREBONES_MODE
8
9// object->flags field if object->type == UACPI_OBJECT_REFERENCE
10enum uacpi_reference_kind {
11 UACPI_REFERENCE_KIND_REFOF = 0,
12 UACPI_REFERENCE_KIND_LOCAL = 1,
13 UACPI_REFERENCE_KIND_ARG = 2,
14 UACPI_REFERENCE_KIND_NAMED = 3,
15 UACPI_REFERENCE_KIND_PKG_INDEX = 4,
16};
17
18// object->flags field if object->type == UACPI_OBJECT_STRING
19enum uacpi_string_kind {
20 UACPI_STRING_KIND_NORMAL = 0,
21 UACPI_STRING_KIND_PATH,
22};
23
24typedef struct uacpi_buffer {
25 struct uacpi_shareable shareable;
26 union {
27 void *data;
28 uacpi_u8 *byte_data;
29 uacpi_char *text;
30 };
31 uacpi_size size;
32} uacpi_buffer;
33
34typedef struct uacpi_package {
35 struct uacpi_shareable shareable;
36 uacpi_object **objects;
37 uacpi_size count;
38} uacpi_package;
39
40typedef struct uacpi_buffer_field {
41 uacpi_buffer *backing;
42 uacpi_size bit_index;
43 uacpi_u32 bit_length;
44 uacpi_bool force_buffer;
45} uacpi_buffer_field;
46
47typedef struct uacpi_buffer_index {
48 uacpi_size idx;
49 uacpi_buffer *buffer;
50} uacpi_buffer_index;
51
52typedef struct uacpi_mutex {
53 struct uacpi_shareable shareable;
54 uacpi_handle handle;
55 uacpi_thread_id owner;
56 uacpi_u16 depth;
57 uacpi_u8 sync_level;
58} uacpi_mutex;
59
60typedef struct uacpi_event {
61 struct uacpi_shareable shareable;
62 uacpi_handle handle;
63} uacpi_event;
64
65typedef struct uacpi_address_space_handler {
66 struct uacpi_shareable shareable;
67 uacpi_region_handler callback;
68 uacpi_handle user_context;
69 struct uacpi_address_space_handler *next;
70 struct uacpi_operation_region *regions;
71 uacpi_u16 space;
72
73#define UACPI_ADDRESS_SPACE_HANDLER_DEFAULT (1 << 0)
74 uacpi_u16 flags;
75} uacpi_address_space_handler;
76
77/*
78 * NOTE: These are common object headers.
79 * Any changes to these structs must be propagated to all objects.
80 * ==============================================================
81 * Common for the following objects:
82 * - UACPI_OBJECT_OPERATION_REGION
83 * - UACPI_OBJECT_PROCESSOR
84 * - UACPI_OBJECT_DEVICE
85 * - UACPI_OBJECT_THERMAL_ZONE
86 */
87typedef struct uacpi_address_space_handlers {
88 struct uacpi_shareable shareable;
89 uacpi_address_space_handler *head;
90} uacpi_address_space_handlers;
91
92typedef struct uacpi_device_notify_handler {
93 uacpi_notify_handler callback;
94 uacpi_handle user_context;
95 struct uacpi_device_notify_handler *next;
96} uacpi_device_notify_handler;
97
98/*
99 * Common for the following objects:
100 * - UACPI_OBJECT_PROCESSOR
101 * - UACPI_OBJECT_DEVICE
102 * - UACPI_OBJECT_THERMAL_ZONE
103 */
104typedef struct uacpi_handlers {
105 struct uacpi_shareable shareable;
106 uacpi_address_space_handler *address_space_head;
107 uacpi_device_notify_handler *notify_head;
108} uacpi_handlers;
109
110// This region has a corresponding _REG method that was succesfully executed
111#define UACPI_OP_REGION_STATE_REG_EXECUTED (1 << 0)
112
113// This region was successfully attached to a handler
114#define UACPI_OP_REGION_STATE_ATTACHED (1 << 1)
115
116typedef struct uacpi_operation_region {
117 struct uacpi_shareable shareable;
118 uacpi_address_space_handler *handler;
119 uacpi_handle user_context;
120 uacpi_u16 space;
121 uacpi_u8 state_flags;
122 uacpi_u64 offset;
123 uacpi_u64 length;
124
125 union {
126 // If space == TABLE_DATA
127 uacpi_u64 table_idx;
128
129 // If space == PCC
130 uacpi_u8 *internal_buffer;
131 };
132
133 // Used to link regions sharing the same handler
134 struct uacpi_operation_region *next;
135} uacpi_operation_region;
136
137typedef struct uacpi_device {
138 struct uacpi_shareable shareable;
139 uacpi_address_space_handler *address_space_handlers;
140 uacpi_device_notify_handler *notify_handlers;
141} uacpi_device;
142
143typedef struct uacpi_processor {
144 struct uacpi_shareable shareable;
145 uacpi_address_space_handler *address_space_handlers;
146 uacpi_device_notify_handler *notify_handlers;
147 uacpi_u8 id;
148 uacpi_u32 block_address;
149 uacpi_u8 block_length;
150} uacpi_processor;
151
152typedef struct uacpi_thermal_zone {
153 struct uacpi_shareable shareable;
154 uacpi_address_space_handler *address_space_handlers;
155 uacpi_device_notify_handler *notify_handlers;
156} uacpi_thermal_zone;
157
158typedef struct uacpi_power_resource {
159 uacpi_u8 system_level;
160 uacpi_u16 resource_order;
161} uacpi_power_resource;
162
163typedef uacpi_status (*uacpi_native_call_handler)(
164 uacpi_handle ctx, uacpi_object *retval
165);
166
167typedef struct uacpi_control_method {
168 struct uacpi_shareable shareable;
169 union {
170 uacpi_u8 *code;
171 uacpi_native_call_handler handler;
172 };
173 uacpi_mutex *mutex;
174 uacpi_u32 size;
175 uacpi_u8 sync_level : 4;
176 uacpi_u8 args : 3;
177 uacpi_u8 is_serialized : 1;
178 uacpi_u8 named_objects_persist: 1;
179 uacpi_u8 native_call : 1;
180 uacpi_u8 owns_code : 1;
181} uacpi_control_method;
182
183typedef enum uacpi_access_type {
184 UACPI_ACCESS_TYPE_ANY = 0,
185 UACPI_ACCESS_TYPE_BYTE = 1,
186 UACPI_ACCESS_TYPE_WORD = 2,
187 UACPI_ACCESS_TYPE_DWORD = 3,
188 UACPI_ACCESS_TYPE_QWORD = 4,
189 UACPI_ACCESS_TYPE_BUFFER = 5,
190} uacpi_access_type;
191
192typedef enum uacpi_lock_rule {
193 UACPI_LOCK_RULE_NO_LOCK = 0,
194 UACPI_LOCK_RULE_LOCK = 1,
195} uacpi_lock_rule;
196
197typedef enum uacpi_update_rule {
198 UACPI_UPDATE_RULE_PRESERVE = 0,
199 UACPI_UPDATE_RULE_WRITE_AS_ONES = 1,
200 UACPI_UPDATE_RULE_WRITE_AS_ZEROES = 2,
201} uacpi_update_rule;
202
203typedef enum uacpi_field_unit_kind {
204 UACPI_FIELD_UNIT_KIND_NORMAL = 0,
205 UACPI_FIELD_UNIT_KIND_INDEX = 1,
206 UACPI_FIELD_UNIT_KIND_BANK = 2,
207} uacpi_field_unit_kind;
208
209typedef struct uacpi_field_unit {
210 struct uacpi_shareable shareable;
211
212 union {
213 // UACPI_FIELD_UNIT_KIND_NORMAL
214 struct {
215 uacpi_namespace_node *region;
216 };
217
218 // UACPI_FIELD_UNIT_KIND_INDEX
219 struct {
220 struct uacpi_field_unit *index;
221 struct uacpi_field_unit *data;
222 };
223
224 // UACPI_FIELD_UNIT_KIND_BANK
225 struct {
226 uacpi_namespace_node *bank_region;
227 struct uacpi_field_unit *bank_selection;
228 uacpi_u64 bank_value;
229 };
230 };
231
232 uacpi_object *connection;
233
234 uacpi_u32 byte_offset;
235 uacpi_u32 bit_length;
236 uacpi_u32 pin_offset;
237 uacpi_u8 bit_offset_within_first_byte;
238 uacpi_u8 access_width_bytes;
239 uacpi_u8 access_length;
240
241 uacpi_u8 attributes : 4;
242 uacpi_u8 update_rule : 2;
243 uacpi_u8 kind : 2;
244 uacpi_u8 lock_rule : 1;
245} uacpi_field_unit;
246
247typedef struct uacpi_object {
248 struct uacpi_shareable shareable;
249 uacpi_u8 type;
250 uacpi_u8 flags;
251
252 union {
253 uacpi_u64 integer;
254 uacpi_package *package;
255 uacpi_buffer_field buffer_field;
256 uacpi_object *inner_object;
257 uacpi_control_method *method;
258 uacpi_buffer *buffer;
259 uacpi_mutex *mutex;
260 uacpi_event *event;
261 uacpi_buffer_index buffer_index;
262 uacpi_operation_region *op_region;
263 uacpi_device *device;
264 uacpi_processor *processor;
265 uacpi_thermal_zone *thermal_zone;
266 uacpi_address_space_handlers *address_space_handlers;
267 uacpi_handlers *handlers;
268 uacpi_power_resource power_resource;
269 uacpi_field_unit *field_unit;
270 };
271} uacpi_object;
272
273uacpi_object *uacpi_create_object(uacpi_object_type type);
274
275enum uacpi_assign_behavior {
276 UACPI_ASSIGN_BEHAVIOR_DEEP_COPY,
277 UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY,
278};
279
280uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src,
281 enum uacpi_assign_behavior);
282
283void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child);
284void uacpi_object_detach_child(uacpi_object *parent);
285
286struct uacpi_object *uacpi_create_internal_reference(
287 enum uacpi_reference_kind kind, uacpi_object *child
288);
289uacpi_object *uacpi_unwrap_internal_reference(uacpi_object *object);
290
291enum uacpi_prealloc_objects {
292 UACPI_PREALLOC_OBJECTS_NO,
293 UACPI_PREALLOC_OBJECTS_YES,
294};
295
296uacpi_bool uacpi_package_fill(
297 uacpi_package *pkg, uacpi_size num_elements,
298 enum uacpi_prealloc_objects prealloc_objects
299);
300
301uacpi_mutex *uacpi_create_mutex(void);
302void uacpi_mutex_unref(uacpi_mutex*);
303
304void uacpi_method_unref(uacpi_control_method*);
305
306void uacpi_address_space_handler_unref(uacpi_address_space_handler *handler);
307
308void uacpi_buffer_to_view(uacpi_buffer*, uacpi_data_view*);
309
310#endif // !UACPI_BAREBONES_MODE
311