PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
devices.c
Go to the documentation of this file.
1#include <modules/acpi/acpi.h>
4
5#include <kernel/cpu/irq.h>
6#include <kernel/log/log.h>
7#include <kernel/log/panic.h>
9#include <kernel/utils/map.h>
10#include <kernel/utils/ref.h>
19#include <modules/acpi/tables.h>
20
21#include <errno.h>
22#include <stdint.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27static uint64_t acpi_id_object_to_string(aml_object_t* idObject, char* out, size_t outSize)
28{
29 if (idObject->type == AML_STRING)
30 {
31 size_t len = MIN(idObject->string.length, outSize - 1);
32 strncpy_s(out, outSize, idObject->string.content, len);
33 out[len] = '\0';
34 }
35 else if (idObject->type == AML_INTEGER)
36 {
37 if (aml_eisa_id_to_string(idObject->integer.value, out, outSize) == ERR)
38 {
39 return ERR;
40 }
41 }
42 else
43 {
44 LOG_ERR("id object '%s' is of invalid type '%s'\n", AML_NAME_TO_STRING(idObject->name),
45 aml_type_to_string(idObject->type));
46 errno = EILSEQ;
47 return ERR;
48 }
49
50 return 0;
51}
52
54{
55 aml_object_t* sta = aml_namespace_find_child(NULL, device, AML_NAME('_', 'S', 'T', 'A'));
56 if (sta == NULL)
57 {
59 return 0;
60 }
61 UNREF_DEFER(sta);
62
63 aml_object_t* staResult = aml_evaluate(NULL, sta, AML_INTEGER);
64 if (staResult == NULL)
65 {
66 LOG_ERR("failed to evaluate %s._STA\n", AML_NAME_TO_STRING(device->name));
67 return ERR;
68 }
69 aml_uint_t value = staResult->integer.value;
70 UNREF(staResult);
71
72 if (value &
74 {
75 LOG_ERR("%s._STA returned invalid value 0x%llx\n", AML_NAME_TO_STRING(device->name), value);
76 errno = EILSEQ;
77 return ERR;
78 }
79
80 *out = (acpi_sta_flags_t)value;
81 return 0;
82}
83
84typedef struct
85{
86 char hid[MAX_NAME];
87 char cid[MAX_NAME];
88 char path[MAX_PATH];
89} acpi_id_t;
90
91typedef struct
92{
96
97static uint64_t acpi_ids_push(acpi_ids_t* ids, const char* hid, const char* cid, const char* path)
98{
99 if (hid == NULL || hid[0] == '\0')
100 {
101 return 0;
102 }
103
104 acpi_id_t* newArray = realloc(ids->array, sizeof(acpi_id_t) * (ids->length + 1));
105 if (newArray == NULL)
106 {
107 return ERR;
108 }
109 ids->array = newArray;
110
111 strncpy_s(ids->array[ids->length].hid, MAX_NAME, hid, MAX_NAME);
112 if (cid != NULL)
113 {
114 strncpy_s(ids->array[ids->length].cid, MAX_NAME, cid, MAX_NAME);
115 }
116 else
117 {
118 ids->array[ids->length].cid[0] = '\0';
119 }
120 strncpy_s(ids->array[ids->length].path, MAX_PATH, path, MAX_PATH);
121 ids->length++;
122
123 return 0;
124}
125
126static uint64_t acpi_ids_push_if_absent(acpi_ids_t* ids, const char* hid, const char* path)
127{
128 for (uint64_t i = 0; i < ids->length; i++)
129 {
130 if (strcmp(ids->array[i].hid, hid) == 0)
131 {
132 return 0;
133 }
134 }
135
136 return acpi_ids_push(ids, hid, NULL, path);
137}
138
139static uint64_t acpi_ids_push_device(acpi_ids_t* ids, aml_object_t* device, const char* path)
140{
141 acpi_id_t deviceId = {0};
142
143 aml_object_t* hid = aml_namespace_find_child(NULL, device, AML_NAME('_', 'H', 'I', 'D'));
144 if (hid == NULL)
145 {
146 return 0; // Nothing to do
147 }
148 UNREF_DEFER(hid);
149
151 if (hidResult == NULL)
152 {
153 return ERR;
154 }
155 UNREF_DEFER(hidResult);
156
157 if (acpi_id_object_to_string(hidResult, deviceId.hid, MAX_NAME) == ERR)
158 {
159 return ERR;
160 }
161
162 if (strcmp(deviceId.hid, "ACPI0010") == 0) // Ignore Processor Container Device
163 {
164 return 0;
165 }
166
167 aml_object_t* cid = aml_namespace_find_child(NULL, device, AML_NAME('_', 'C', 'I', 'D'));
168 if (cid != NULL)
169 {
170 UNREF_DEFER(cid);
171
173 if (cidResult == NULL)
174 {
175 return ERR;
176 }
177 UNREF_DEFER(cidResult);
178
179 if (acpi_id_object_to_string(cidResult, deviceId.cid, MAX_NAME) == ERR)
180 {
181 return ERR;
182 }
183 }
184
185 if (acpi_ids_push(ids, deviceId.hid, deviceId.cid, path) == ERR)
186 {
187 return ERR;
188 }
189
190 return 0;
191}
192
194{
195 aml_object_t* sb = aml_namespace_find(NULL, NULL, 1, AML_NAME('_', 'S', 'B', '_'));
196 if (sb == NULL) // Should never happen
197 {
198 LOG_ERR("failed to find \\_SB_ in namespace\n");
199 return NULL;
200 }
201 UNREF_DEFER(sb);
202
204 if (acpi_sta_get_flags(sb, &sta) == ERR)
205 {
206 return NULL;
207 }
208
209 if (!(sta & ACPI_STA_PRESENT))
210 {
211 LOG_INFO("\\_SB_ is not present, skipping initialization\n");
212 return NULL;
213 }
214
215 aml_object_t* ini = aml_namespace_find_child(NULL, sb, AML_NAME('_', 'I', 'N', 'I'));
216 if (ini != NULL)
217 {
218 UNREF_DEFER(ini);
219 LOG_INFO("found \\_SB_._INI\n");
220 aml_object_t* iniResult = aml_evaluate(NULL, ini, AML_ALL_TYPES);
221 if (iniResult == NULL)
222 {
223 LOG_ERR("failed to evaluate \\_SB_._INI\n");
224 return NULL;
225 }
226 UNREF(iniResult);
227 }
228
229 return REF(sb);
230}
231
232static uint64_t acpi_device_init_children(acpi_ids_t* ids, aml_object_t* device, const char* path)
233{
234 aml_object_t* child = NULL;
235 LIST_FOR_EACH(child, &device->children, siblingsEntry)
236 {
237 if (child->type != AML_DEVICE)
238 {
239 continue;
240 }
241
242 char childPath[MAX_PATH];
243 int written = snprintf(childPath, MAX_PATH, "%s.%s", path, AML_NAME_TO_STRING(child->name));
244 if (written < 0 || written >= MAX_PATH)
245 {
246 LOG_ERR("ACPI path truncation for %s.%s, skipping deep nesting\n", path, AML_NAME_TO_STRING(child->name));
247 continue;
248 }
249
251 if (acpi_sta_get_flags(child, &sta) == ERR)
252 {
253 return ERR;
254 }
255
256 if (sta & ACPI_STA_PRESENT)
257 {
258 aml_object_t* ini = aml_namespace_find_child(NULL, child, AML_NAME('_', 'I', 'N', 'I'));
259 if (ini != NULL)
260 {
261 UNREF_DEFER(ini);
262 aml_object_t* iniResult = aml_evaluate(NULL, ini, AML_ALL_TYPES);
263 if (iniResult == NULL)
264 {
265 LOG_ERR("failed to evaluate %s._INI\n", childPath);
266 return ERR;
267 }
268 UNREF(iniResult);
269 }
270
271 if (acpi_ids_push_device(ids, child, childPath) == ERR)
272 {
273 return ERR;
274 }
275 }
276
278 {
279 if (acpi_device_init_children(ids, child, childPath) == ERR)
280 {
281 return ERR;
282 }
283 }
284 }
285 return 0;
286}
287
288static int acpi_id_compare(const void* left, const void* right)
289{
290 const acpi_id_t* aPtr = (const acpi_id_t*)left;
291 const acpi_id_t* bPtr = (const acpi_id_t*)right;
292
293 const char* a = aPtr->hid;
294 if (a[0] == '\0')
295 {
296 a = aPtr->cid;
297 }
298
299 const char* b = bPtr->hid;
300 if (b[0] == '\0')
301 {
302 b = bPtr->cid;
303 }
304
305 // If alphabetic non-hex prefix differs, compare lexicographically
306 while (*a && *b && ((*a < '0' || *a > '9') && (*a < 'A' || *a > 'F')) &&
307 ((*b < '0' || *b > '9') && (*b < 'A' || *b > 'F')))
308 {
309 if (*a != *b)
310 {
311 return (unsigned char)*a - (unsigned char)*b;
312 }
313 a++;
314 b++;
315 }
316
317 // If alphabetic prefix is the same, compare hex numerically
318 uint64_t numA = 0;
319 sscanf(a, "%llx", &numA);
320 uint64_t numB = 0;
321 sscanf(b, "%llx", &numB);
322 return numA - numB;
323}
324
326{
327 if (cfg == NULL)
328 {
329 return;
330 }
331
332 for (uint64_t i = 0; i < cfg->irqCount; i++)
333 {
334 irq_virt_free(cfg->irqs[i].virt);
335 }
336
337 for (uint64_t i = 0; i < cfg->ioCount; i++)
338 {
339 io_release(cfg->ios[i].base, cfg->ios[i].length);
340 }
341
342 free(cfg->irqs);
343 free(cfg->ios);
344 free(cfg);
345}
346
347static uint64_t acpi_device_configure(const char* name)
348{
349 if (name[0] == '.')
350 {
351 LOG_DEBUG("skipping configuration for fake ACPI device '%s'\n", name);
352 return 0;
353 }
354
356 if (device == NULL)
357 {
358 LOG_ERR("failed to find ACPI device '%s' in namespace for configuration\n", name);
359 return ERR;
360 }
361 UNREF_DEFER(device);
362
363 if (device->type != AML_DEVICE)
364 {
365 LOG_ERR("ACPI object '%s' is not a device, cannot configure\n", name);
366 errno = EINVAL;
367 return ERR;
368 }
369
370 if (device->device.cfg != NULL)
371 {
372 LOG_DEBUG("ACPI device '%s' is already configured, skipping\n", name);
373 return 0;
374 }
375
376 acpi_device_cfg_t* cfg = calloc(1, sizeof(acpi_device_cfg_t));
377 if (cfg == NULL)
378 {
379 return ERR;
380 }
381
382 acpi_resources_t* resources = acpi_resources_current(device);
383 if (resources == NULL)
384 {
385 if (errno == ENOENT) // No resources exist, assign empty config
386 {
387 device->device.cfg = cfg;
388 return 0;
389 }
390 LOG_ERR("failed to get current resources for ACPI device '%s' due to '%s'\n", name, strerror(errno));
391 free(cfg);
392 return ERR;
393 }
394
395 acpi_resource_t* resource;
396 ACPI_RESOURCES_FOR_EACH(resource, resources)
397 {
398 acpi_item_name_t itemName = ACPI_RESOURCE_ITEM_NAME(resource);
399 switch (itemName)
400 {
402 {
405
409
410 for (irq_phys_t phys = 0; phys < 16; phys++)
411 {
412 if (!((desc->mask >> phys) & 1))
413 {
414 continue;
415 }
416
417 irq_virt_t virt;
418 if (irq_virt_alloc(&virt, phys, flags, NULL) == ERR)
419 {
420 LOG_ERR("failed to allocate virtual IRQ for ACPI device '%s' due to '%s'\n", name, strerror(errno));
421 goto error;
422 }
423
424 acpi_device_irq_t* newIrqs = realloc(cfg->irqs, sizeof(acpi_device_irq_t) * (cfg->irqCount + 1));
425 if (newIrqs == NULL)
426 {
427 LOG_ERR("failed to allocate memory for IRQs for ACPI device '%s' due to '%s'\n", name,
428 strerror(errno));
429 irq_virt_free(virt);
430 goto error;
431 }
432 cfg->irqs = newIrqs;
433 cfg->irqs[cfg->irqCount].phys = phys;
434 cfg->irqs[cfg->irqCount].virt = virt;
435 cfg->irqs[cfg->irqCount].flags = flags;
436 cfg->irqCount++;
437 }
438 }
439 break;
441 {
443
444 acpi_device_io_t* newIos = realloc(cfg->ios, sizeof(acpi_device_io_t) * (cfg->ioCount + 1));
445 if (newIos == NULL)
446 {
447 LOG_ERR("failed to allocate memory for IO ports for ACPI device '%s' due to '%s'\n", name,
448 strerror(errno));
449 goto error;
450 }
451 cfg->ios = newIos;
452
453 port_t base;
454 if (io_reserve(&base, desc->minBase, desc->maxBase, desc->alignment, desc->length, name) == ERR)
455 {
456 LOG_ERR("failed to reserve IO ports for ACPI device '%s' due to '%s'\n", name, strerror(errno));
457 goto error;
458 }
459
460 cfg->ios[cfg->ioCount].base = base;
461 cfg->ios[cfg->ioCount].length = desc->length;
462 cfg->ioCount++;
463 }
464 break;
465 default:
466 break;
467 }
468 }
469
470 free(resources);
471 device->device.cfg = cfg;
472 return 0;
473
474error:
475 free(resources);
477 return ERR;
478}
479
481{
483
484 acpi_ids_t ids = {
485 .array = NULL,
486 .length = 0,
487 };
488
490 if (sb == NULL)
491 {
492 LOG_ERR("failed to initialize ACPI devices\n");
493 return ERR;
494 }
495 UNREF_DEFER(sb);
496
497 LOG_DEBUG("initializing ACPI devices under \\_SB_\n");
498 if (acpi_device_init_children(&ids, sb, "\\_SB_") == ERR)
499 {
500 LOG_ERR("failed to initialize ACPI devices\n");
501 return ERR;
502 }
503
504 // Because of... reasons some hardware wont report certain devices via ACPI
505 // even if they actually do have it. In these cases we manually add their HIDs.
506
507 if (acpi_tables_lookup("HPET", sizeof(sdt_header_t), 0) != NULL) // HPET
508 {
509 if (acpi_ids_push_if_absent(&ids, "PNP0103", ".HPET") == ERR)
510 {
511 LOG_ERR("failed to initialize ACPI devices\n");
512 return ERR;
513 }
514 }
515
516 if (acpi_tables_lookup("APIC", sizeof(sdt_header_t), 0) != NULL) // APIC
517 {
518 if (acpi_ids_push_if_absent(&ids, "PNP0003", ".APIC") == ERR)
519 {
520 LOG_ERR("failed to initialize ACPI devices\n");
521 return ERR;
522 }
523 }
524
525 if (ids.array != NULL && ids.length > 0)
526 {
527 qsort(ids.array, ids.length, sizeof(acpi_id_t), acpi_id_compare);
528 }
529
530 for (size_t i = 0; i < ids.length; i++)
531 {
532 if (acpi_device_configure(ids.array[i].path) == ERR)
533 {
534 // Dont load module for unconfigurable device
535 memmove(&ids.array[i], &ids.array[i + 1], sizeof(acpi_id_t) * (ids.length - i - 1));
536 ids.length--;
537 i--;
538 continue;
539 }
540 }
541
542 for (size_t i = 0; i < ids.length; i++)
543 {
544 uint64_t loadedModules = module_device_attach(ids.array[i].hid, ids.array[i].path, MODULE_LOAD_ONE);
545 if (loadedModules == ERR)
546 {
547 LOG_ERR("failed to load module for HID '%s' due to '%s'\n", ids.array[i].hid, strerror(errno));
548 continue;
549 }
550
551 if (loadedModules != 0 || ids.array[i].cid[0] == '\0')
552 {
553 continue;
554 }
555
556 loadedModules = module_device_attach(ids.array[i].cid, ids.array[i].path, MODULE_LOAD_ONE);
557 if (loadedModules == ERR)
558 {
559 LOG_ERR("failed to load module for CID '%s' due to '%s'\n", ids.array[i].cid, strerror(errno));
560 }
561 }
562
563 free(ids.array);
564 return 0;
565}
566
568{
569 if (name == NULL)
570 {
571 errno = EINVAL;
572 return NULL;
573 }
574
576
578 if (device == NULL)
579 {
580 LOG_ERR("failed to find ACPI device '%s' in namespace for configuration retrieval\n", name);
581 errno = ENOENT;
582 return NULL;
583 }
584 UNREF_DEFER(device);
585
586 if (device->type != AML_DEVICE)
587 {
588 LOG_ERR("ACPI object '%s' is not a device, cannot retrieve configuration\n", name);
589 errno = ENOTTY;
590 return NULL;
591 }
592
593 if (device->device.cfg == NULL)
594 {
595 LOG_ERR("ACPI device '%s' is not configured\n", name);
596 errno = ENODEV;
597 return NULL;
598 }
599
600 return device->device.cfg;
601}
602
604{
605 if (cfg == NULL)
606 {
607 errno = EINVAL;
608 return ERR;
609 }
610
611 for (uint64_t i = 0; i < cfg->ioCount; i++)
612 {
613 if (cfg->ios[i].length > index)
614 {
615 *out = cfg->ios[i].base + index;
616 return 0;
617 }
618 index -= cfg->ios[i].length;
619 }
620
621 errno = ENOSPC;
622 return ERR;
623}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
#define MAX_PATH
Maximum length of filepaths.
Definition MAX_PATH.h:11
static uint64_t acpi_id_object_to_string(aml_object_t *idObject, char *out, size_t outSize)
Definition devices.c:27
static uint64_t acpi_ids_push_if_absent(acpi_ids_t *ids, const char *hid, const char *path)
Definition devices.c:126
static uint64_t acpi_ids_push(acpi_ids_t *ids, const char *hid, const char *cid, const char *path)
Definition devices.c:97
static void acpi_device_cfg_free(acpi_device_cfg_t *cfg)
Definition devices.c:325
static int acpi_id_compare(const void *left, const void *right)
Definition devices.c:288
static uint64_t acpi_ids_push_device(acpi_ids_t *ids, aml_object_t *device, const char *path)
Definition devices.c:139
static uint64_t acpi_device_init_children(acpi_ids_t *ids, aml_object_t *device, const char *path)
Definition devices.c:232
static uint64_t acpi_device_configure(const char *name)
Definition devices.c:347
static uint64_t acpi_sta_get_flags(aml_object_t *device, acpi_sta_flags_t *out)
Definition devices.c:53
static aml_object_t * acpi_sb_init(void)
Definition devices.c:193
uint64_t io_reserve(port_t *out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, const char *owner)
Find and reserve a range of I/O ports if available.
Definition io.c:15
void io_release(port_t base, uint64_t length)
Release a previously reserved range of I/O ports.
Definition io.c:43
uint16_t port_t
I/O port type.
Definition io.h:27
void irq_virt_free(irq_virt_t virt)
Free a previously allocated virtual IRQ.
Definition irq.c:253
uint32_t irq_phys_t
Physical IRQ numbers.
Definition irq.h:46
irq_flags_t
IRQ flags.
Definition irq.h:94
uint64_t irq_virt_alloc(irq_virt_t *out, irq_phys_t phys, irq_flags_t flags, cpu_t *cpu)
Allocate a virtual IRQ mapped to the given physical IRQ.
Definition irq.c:171
uint8_t irq_virt_t
Virtual IRQ numbers.
Definition irq.h:57
@ IRQ_TRIGGER_EDGE
If set, the IRQ is edge triggered. Otherwise, level triggered.
Definition irq.h:98
@ IRQ_POLARITY_HIGH
If set, the IRQ is active high.
Definition irq.h:95
@ IRQ_SHARED
If set, the IRQ is shared.
Definition irq.h:100
@ IRQ_TRIGGER_LEVEL
If set, the IRQ is level triggered.
Definition irq.h:97
@ IRQ_POLARITY_LOW
If set, the IRQ is active low. Otherwise, active high.
Definition irq.h:96
@ IRQ_EXCLUSIVE
If set, the IRQ is exclusive (not shared).
Definition irq.h:99
#define LOG_ERR(format,...)
Definition log.h:108
#define LOG_INFO(format,...)
Definition log.h:106
#define LOG_DEBUG(format,...)
Definition log.h:100
uint64_t module_device_attach(const char *type, const char *name, module_load_flags_t flags)
Notify the module system of a device being attached.
Definition module.c:1056
@ MODULE_LOAD_ONE
If set, will load only the first module matching the device type.
Definition module.h:398
#define MUTEX_SCOPE(mutex)
Acquires a mutex for the reminder of the current scope.
Definition mutex.h:23
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define REF(ptr)
Increment reference count.
Definition ref.h:65
#define UNREF(ptr)
Decrement reference count.
Definition ref.h:80
#define ENOENT
No such file or directory.
Definition errno.h:42
#define ENOSPC
No space left on device.
Definition errno.h:172
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define ENODEV
No such device.
Definition errno.h:127
#define ENOTTY
Not a typewriter.
Definition errno.h:157
#define EILSEQ
Illegal byte sequence.
Definition errno.h:447
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
Definition list.h:63
#define MIN(x, y)
Definition math.h:16
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
aml_object_t * aml_evaluate(aml_state_t *state, aml_object_t *object, aml_type_t targetTypes)
Evaluate an AML object.
Definition evaluate.c:8
uint64_t aml_uint_t
AML Integer type.
Definition integer.h:20
#define AML_NAME_TO_STRING(name)
Macro to convert an aml_name_t to a stack allocated string.
Definition namespace.h:129
aml_object_t * aml_namespace_find_by_path(aml_overlay_t *overlay, aml_object_t *start, const char *path)
Find an object in the namespace heirarchy by a path string.
Definition namespace.c:288
#define AML_NAME(a, b, c, d)
Macro to create an aml_name_t from 4 characters.
Definition namespace.h:112
aml_object_t * aml_namespace_find_child(aml_overlay_t *overlay, aml_object_t *parent, aml_name_t name)
Find a child object directly under a parent object in the namespace heirarchy.
Definition namespace.c:154
aml_object_t * aml_namespace_find(aml_overlay_t *overlay, aml_object_t *start, uint64_t nameCount,...)
Find an object in the namespace heirarchy by name segments.
Definition namespace.c:192
@ AML_STRING
Definition object.h:85
@ AML_DEVICE
Definition object.h:64
@ AML_ALL_TYPES
Definition object.h:114
@ AML_INTEGER
Definition object.h:67
uint64_t aml_eisa_id_to_string(uint32_t eisaId, char *buffer, size_t bufferSize)
Convert a numeric EISA ID to a string EISA ID.
Definition eisa_id.c:56
const char * aml_type_to_string(aml_type_t type)
Convert an aml data type to a string.
Definition to_string.c:5
mutex_t * aml_big_mutex_get(void)
Get the mutex for the entire AML subsystem.
Definition aml.c:179
acpi_device_cfg_t * acpi_device_cfg_lookup(const char *name)
Retrieves the ACPI device configuration for a device by its name.
Definition devices.c:567
uint64_t acpi_devices_init(void)
Enumerate, configure and load modules for ACPI devices.
Definition devices.c:480
uint64_t acpi_device_cfg_get_port(acpi_device_cfg_t *cfg, uint64_t index, port_t *out)
Retrieves an the nth IO port assigned to an ACPI device.
Definition devices.c:603
acpi_sta_flags_t
Flags for the _STA method.
Definition devices.h:64
#define ACPI_STA_FLAGS_DEFAULT
Default _STA flags if the _STA method does not exist.
Definition devices.h:80
@ ACPI_STA_BATTERY_PRESENT
Set if a battery is present.
Definition devices.h:70
@ ACPI_STA_SHOW_IN_UI
Set if the device should be shown in the UI.
Definition devices.h:67
@ ACPI_STA_PRESENT
Set if the device is present.
Definition devices.h:65
@ ACPI_STA_FUNCTIONAL
Set if the device is functioning properly (cleared if device failed its diagnostics)
Definition devices.h:68
@ ACPI_STA_ENABLED
Set if the device is enabled and decoding its resources.
Definition devices.h:66
#define ACPI_IRQ_DESCRIPTOR_INFO(descriptor)
Retrieves the IRQ descriptor info flags from an IRQ resource descriptor.
Definition resources.h:115
#define ACPI_RESOURCES_FOR_EACH(resource, resources)
Helper macro to iterate over all resource descriptors in an ACPI resources structure.
Definition resources.h:268
#define ACPI_RESOURCE_ITEM_NAME(resource)
Helper macro to get the generic item name of a resource descriptor.
Definition resources.h:243
acpi_irq_descriptor_info_t
ACPI IRQ descriptor info flags.
Definition resources.h:92
acpi_resources_t * acpi_resources_current(aml_object_t *device)
Get the current ACPI resource settings for a device.
Definition resources.c:25
acpi_item_name_t
Generic ACPI resource item names.
Definition resources.h:225
@ ACPI_IRQ_EDGE_TRIGGERED
Interrupt is triggered in response to a change in signal state from low to high.
Definition resources.h:94
@ ACPI_IRQ_EXCLUSIVE
This interrupt is not shared with other devices.
Definition resources.h:99
@ ACPI_IRQ_ACTIVE_LOW
This interrupt is sampled with the signal is low, or false.
Definition resources.h:97
@ ACPI_ITEM_NAME_IRQ
Definition resources.h:226
@ ACPI_ITEM_NAME_IO_PORT
Definition resources.h:227
sdt_header_t * acpi_tables_lookup(const char *signature, uint64_t minSize, uint64_t n)
Lookup the n'th table matching the signature.
Definition tables.c:260
static fb_info_t info
Definition gop.c:51
static const path_flag_t flags[]
Definition path.c:42
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sscanf.c:4
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
Definition snprintf.c:3
_PUBLIC void * realloc(void *ptr, size_t size)
Definition realloc.c:13
_PUBLIC void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
Definition qsort.c:47
_PUBLIC void * calloc(size_t nmemb, size_t size)
Definition calloc.c:6
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC int strcmp(const char *s1, const char *s2)
Definition strcmp.c:3
errno_t strncpy_s(char *_RESTRICT s1, rsize_t s1max, const char *_RESTRICT s2, rsize_t n)
Definition strncpy_s.c:9
ACPI device configuration structure.
Definition devices.h:112
acpi_device_irq_t * irqs
Definition devices.h:115
uint64_t ioCount
Definition devices.h:118
uint64_t irqCount
Definition devices.h:116
acpi_device_io_t * ios
Definition devices.h:117
Represents an IO port range assigned to an ACPI device.
Definition devices.h:98
uint64_t length
Definition devices.h:100
Represents a IRQ assigned to an ACPI device.
Definition devices.h:87
irq_virt_t virt
Definition devices.h:89
irq_phys_t phys
Definition devices.h:88
irq_flags_t flags
Definition devices.h:90
char path[MAX_PATH]
Definition devices.c:88
char cid[MAX_NAME]
Definition devices.c:87
char hid[MAX_NAME]
Definition devices.c:86
uint64_t length
Definition devices.c:94
acpi_id_t * array
Definition devices.c:93
ACPI IO port resource descriptor.
Definition resources.h:145
uint8_t alignment
Alignment of the IO port(s) to utilize within the min and max range.
Definition resources.h:151
uint16_t minBase
Minimum base IO port address that may be used for the device.
Definition resources.h:149
uint16_t maxBase
Maximum base IO port address that may be used for the device.
Definition resources.h:150
uint8_t length
The amount of contiguous IO ports required by the device.
Definition resources.h:152
ACPI IRQ resource descriptor.
Definition resources.h:79
uint16_t mask
Mask of IRQs used by the device, bit 0 = IRQ 0, bit 1 = IRQ 1, etc..
Definition resources.h:81
Generic ACPI resource descriptor.
Definition resources.h:210
ACPI resources structure.
Definition resources.h:198
acpi_device_cfg_t * cfg
Definition object.h:249
aml_uint_t value
Definition object.h:288
ACPI object.
Definition object.h:447
aml_integer_t integer
Definition object.h:458
aml_string_t string
Definition object.h:467
aml_device_t device
Definition object.h:455
uint64_t length
Definition object.h:393
char * content
Definition object.h:392
System Description Table Header.
Definition acpi.h:90