PatchworkOS
Loading...
Searching...
No Matches
aml.c
Go to the documentation of this file.
2
10#include <kernel/log/log.h>
11#include <kernel/log/panic.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 DEREF_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 {
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
107void aml_init(void)
108{
109 LOG_INFO("AML revision %d, init and parse all\n", AML_CURRENT_REVISION);
110
113
115 if (root == NULL)
116 {
117 panic(NULL, "failed to create root AML object\n");
118 }
119 DEREF_DEFER(root);
120
121 // We dont need to add the root to the namespace map as it has no name.
122 if (aml_predefined_scope_set(root) == ERR)
123 {
124 panic(NULL, "failed to set predefined scope for root object\n");
125 }
126
127 if (aml_namespace_init(root) == ERR)
128 {
129 panic(NULL, "failed to initialize AML namespace\n");
130 }
131
133 {
134 panic(NULL, "failed to initialize AML integer handling\n");
135 }
136
137 if (aml_predefined_init() == ERR)
138 {
139 panic(NULL, "failed to initialize AML predefined names\n");
140 }
141
142 if (aml_patch_up_init() == ERR)
143 {
144 panic(NULL, "failed to initialize AML patch up\n");
145 }
146
147#ifdef TESTING
148 if (aml_tests_post_init() == ERR)
149 {
150 panic(NULL, "failed to run tests post init\n");
151 }
152#endif
153
154 if (aml_init_parse_all() == ERR)
155 {
156 panic(NULL, "failed to parse all AML code\n");
157 }
158
159 LOG_INFO("resolving %llu unresolved objects\n", aml_patch_up_unresolved_count());
161 {
162 panic(NULL, "failed to resolve all unresolved objects\n");
163 }
164
166 {
167 panic(NULL, "there are still %llu unresolved objects after patch up\n", aml_patch_up_unresolved_count());
168 }
169
170 if (aml_namespace_expose() == ERR)
171 {
172 panic(NULL, "failed to expose AML namespace in sysfs\n");
173 }
174
175#ifdef TESTING
176 if (aml_tests_post_parse_all() == ERR)
177 {
178 panic(NULL, "failed to run tests post parse all\n");
179 }
180#endif
181}
182
184{
185 return &bigMutex;
186}
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
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:216
uint64_t aml_integer_handling_init(void)
Initialize integer handling.
Definition integer.c:8
uint64_t aml_namespace_commit(aml_namespace_overlay_t *overlay)
Commit all names in a namespace overlay to the global namespace heirarchy.
Definition namespace.c:443
uint64_t aml_namespace_init(aml_object_t *root)
Initialize the namespace heirarchy.
Definition namespace.c:68
uint64_t aml_namespace_expose(void)
Expose the entire namespace heirarchy to sysfs.
Definition namespace.c:80
aml_object_t * aml_namespace_get_root(void)
Get the root object of the namespace heirarchy.
Definition namespace.c:86
aml_object_t * aml_object_new(void)
Allocate a new ACPI object.
Definition object.c:54
uint64_t aml_predefined_scope_set(aml_object_t *object)
Set a object as a predefined scope with the given name.
Definition object.c:1162
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:116
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:79
void 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:183
#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 n)
Lookup the n'th table matching the signature.
Definition tables.c:266
#define DSDT_SIGNATURE
DSDT table signature.
Definition tables.h:221
#define SSDT_SIGNATURE
SSDT table signature.
Definition tables.h:240
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:362
#define LOG_ERR(format,...)
Definition log.h:89
#define LOG_INFO(format,...)
Definition log.h:87
void mutex_init(mutex_t *mtx)
Initializes a mutex.
Definition mutex.c:12
#define MUTEX_SCOPE(mutex)
Acquires a mutex for the reminder of the current scope.
Definition mutex.h:23
#define DEREF_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
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:425
AML State.
Definition state.h:25
aml_namespace_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30
Differentiated System Description Table.
Definition tables.h:213
uint8_t definitionBlock[]
Definition tables.h:215
sdt_header_t header
Definition tables.h:214
Mutex structure.
Definition mutex.h:39
uint32_t length
Definition acpi.h:92
Secondary System Description Table.
Definition tables.h:230
uint8_t definitionBlock[]
Definition tables.h:232
sdt_header_t header
Definition tables.h:231