PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
aml.c
Go to the documentation of this file.
2
3#include <kernel/log/log.h>
4#include <kernel/log/panic.h>
11#include <modules/acpi/tables.h>
12
13#ifdef TESTING
15#endif
16
17#include <kernel/log/log.h>
18
19#include <errno.h>
20#include <sys/math.h>
21
23
24static inline uint64_t aml_parse(const uint8_t* start, const uint8_t* end)
25{
26 if (start == NULL || end == NULL || start > end)
27 {
28 errno = EINVAL;
29 return ERR;
30 }
31
32 if (start == end)
33 {
34 // Im not sure why but some firmwares have empty SSDTs.
35 return 0;
36 }
37
38 // In section 20.2.1, we see the definition AMLCode := DefBlockHeader TermList.
39 // The DefBlockHeader is already read as thats the `sdt_header_t`.
40 // So the entire code is a termlist.
41
42 aml_state_t state;
43 if (aml_state_init(&state, NULL) == ERR)
44 {
45 return ERR;
46 }
47
49 UNREF_DEFER(root);
50
51 uint64_t result = aml_term_list_read(&state, root, start, end, NULL);
52
53 if (result != ERR)
54 {
56 }
57
58 aml_state_deinit(&state);
59 return result;
60}
61
62static inline uint64_t aml_init_parse_all(void)
63{
65 if (dsdt == NULL)
66 {
67 LOG_ERR("failed to retrieve DSDT\n");
68 return ERR;
69 }
70
71 LOG_INFO("DSDT found containing %llu bytes of AML code\n", dsdt->header.length - sizeof(dsdt_t));
72
73 const uint8_t* dsdtEnd = (const uint8_t*)dsdt + dsdt->header.length;
74 if (aml_parse(dsdt->definitionBlock, dsdtEnd) == ERR)
75 {
76 LOG_ERR("failed to parse DSDT\n");
77 return ERR;
78 }
79
80 uint64_t index = 0;
81 ssdt_t* ssdt = NULL;
82 while (true)
83 {
84 ssdt = (ssdt_t*)acpi_tables_lookup(SSDT_SIGNATURE, sizeof(ssdt_t), index);
85 if (ssdt == NULL)
86 {
87 break;
88 }
89
90 LOG_INFO("SSDT%llu found containing %llu bytes of AML code\n", index, ssdt->header.length - sizeof(ssdt_t));
91
92 const uint8_t* ssdtEnd = (const uint8_t*)ssdt + ssdt->header.length;
93 if (aml_parse(ssdt->definitionBlock, ssdtEnd) == ERR)
94 {
95 LOG_ERR("failed to parse SSDT%llu\n", index);
96 return ERR;
97 }
98
99 index++;
100 }
101
102 LOG_INFO("parsed 1 DSDT and %llu SSDTs\n", index);
103
104 return 0;
105}
106
108{
109 LOG_INFO("AML revision %d, init and parse all\n", AML_CURRENT_REVISION);
110
113
115 if (root == NULL)
116 {
117 LOG_ERR("failed to create root AML object\n");
118 return ERR;
119 }
120 UNREF_DEFER(root);
121
122 // We dont need to add the root to the namespace map as it has no name.
123 if (aml_predefined_scope_set(root) == ERR)
124 {
125 LOG_ERR("failed to set predefined scope for root object\n");
126 return ERR;
127 }
128
129 aml_namespace_init(root);
130
132 {
133 LOG_ERR("failed to initialize AML integer handling\n");
134 return ERR;
135 }
136
137 if (aml_predefined_init() == ERR)
138 {
139 LOG_ERR("failed to initialize AML predefined names\n");
140 return ERR;
141 }
142
143 if (aml_patch_up_init() == ERR)
144 {
145 LOG_ERR("failed to initialize AML patch up\n");
146 return ERR;
147 }
148
149 if (aml_init_parse_all() == ERR)
150 {
151 LOG_ERR("failed to parse all AML code\n");
152 return ERR;
153 }
154
155 LOG_INFO("resolving %llu unresolved objects\n", aml_patch_up_unresolved_count());
157 {
158 LOG_ERR("failed to resolve all unresolved objects\n");
159 return ERR;
160 }
161
163 {
164 LOG_ERR("there are still %llu unresolved objects after patch up\n", aml_patch_up_unresolved_count());
165 return ERR;
166 }
167
168#ifdef TESTING
169 if (aml_tests_run_all() == ERR)
170 {
171 LOG_ERR("failed to run tests post parse all\n");
172 return ERR;
173 }
174#endif
175
176 return 0;
177}
178
180{
181 return &bigMutex;
182}
static uint64_t aml_parse(const uint8_t *start, const uint8_t *end)
Definition aml.c:24
static uint64_t aml_init_parse_all(void)
Definition aml.c:62
static mutex_t bigMutex
Definition aml.c:22
#define LOG_ERR(format,...)
Definition log.h:108
#define LOG_INFO(format,...)
Definition log.h:106
void mutex_init(mutex_t *mtx)
Initializes a mutex.
Definition mutex.c:14
#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 EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
uint64_t aml_term_list_read(aml_state_t *state, aml_object_t *scope, const uint8_t *start, const uint8_t *end, aml_term_list_ctx_t *parentCtx)
Reads a TermList structure from the AML byte stream.
Definition term.c:189
uint64_t aml_integer_handling_init(void)
Initialize integer handling.
Definition integer.c:8
uint64_t aml_namespace_commit(aml_overlay_t *overlay)
Commit all names in a namespace overlay to the global namespace heirarchy.
Definition namespace.c:506
void aml_namespace_init(aml_object_t *root)
Initialize the namespace heirarchy.
Definition namespace.c:74
aml_object_t * aml_namespace_get_root(void)
Get the root object of the namespace heirarchy.
Definition namespace.c:149
aml_object_t * aml_object_new(void)
Allocate a new ACPI object.
Definition object.c:62
uint64_t aml_predefined_scope_set(aml_object_t *object)
Set a object as a predefined scope with the given name.
Definition object.c:1219
uint64_t aml_patch_up_init(void)
Initialize the patch-up system.
Definition patch_up.c:15
uint64_t aml_patch_up_unresolved_count(void)
Get the number of unresolved references in the global list.
Definition patch_up.c:105
uint64_t aml_patch_up_resolve_all(void)
Attempts to resolve all unresolved references.
Definition patch_up.c:60
uint64_t aml_predefined_init(void)
Initialize predefined AML names and objects.
Definition predefined.c:117
uint64_t aml_state_init(aml_state_t *state, aml_object_t **args)
Initialize an AML state.
Definition state.c:8
void aml_state_deinit(aml_state_t *state)
Deinitialize an AML state.
Definition state.c:68
uint64_t aml_init(void)
Initialize the AML subsystem.
Definition aml.c:107
mutex_t * aml_big_mutex_get(void)
Get the mutex for the entire AML subsystem.
Definition aml.c:179
#define AML_CURRENT_REVISION
The current revision of the AML subsystem.
Definition aml.h:46
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
#define DSDT_SIGNATURE
DSDT table signature.
Definition tables.h:219
#define SSDT_SIGNATURE
SSDT table signature.
Definition tables.h:238
static void start()
Definition main.c:542
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
ACPI object.
Definition object.h:447
AML State.
Definition state.h:25
aml_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30
Differentiated System Description Table.
Definition tables.h:211
uint8_t definitionBlock[]
Definition tables.h:213
sdt_header_t header
Definition tables.h:212
Mutex structure.
Definition mutex.h:41
uint32_t length
Definition acpi.h:92
Secondary System Description Table.
Definition tables.h:228
uint8_t definitionBlock[]
Definition tables.h:230
sdt_header_t header
Definition tables.h:229