PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
tests.c
Go to the documentation of this file.
1#ifdef _TESTING_
2
3#include "acpica_tests/all_tests.h"
4
5#include <kernel/log/log.h>
8#include <kernel/utils/test.h>
15#include <kernel/acpi/tables.h>
16
17#include <stdlib.h>
18#include <string.h>
19#include <sys/list.h>
20
21static uint64_t aml_tests_check_object_leak(void)
22{
25
28 LOG_INFO("total objects after parsing %llu\n", totalObjects);
29 if (totalObjects != rootChildren + 1)
30 {
31 LOG_ERR("memory leak detected, total objects %llu, but root has %llu children\n", totalObjects, rootChildren);
32 return ERR;
33 }
34 return 0;
35}
36
37static uint64_t aml_tests_acpica_do_test(const acpica_test_t* test)
38{
39 LOG_INFO("running test '%s'\n", test->name);
40
41 ssdt_t* testAml = (ssdt_t*)test->aml;
42 const uint8_t* end = (const uint8_t*)testAml + testAml->header.length;
43
44 aml_state_t state;
45 if (aml_state_init(&state, NULL) == ERR)
46 {
47 return ERR;
48 }
49
52
53 if (aml_term_list_read(&state, root, testAml->definitionBlock, end, NULL) == ERR)
54 {
55 LOG_ERR("test '%s' failed to parse AML\n", test->name);
56 aml_state_deinit(&state);
57 return ERR;
58 }
59
60 // Set the "Settings number, used to adjust the aslts tests for different releases of ACPICA".
61 // We set it to 6 as that is the latest version as of writing this.
62 aml_object_t* setn = aml_namespace_find(&state.overlay, root, 1, AML_NAME('S', 'E', 'T', 'N'));
63 if (setn == NULL)
64 {
65 LOG_ERR("test '%s' does not contain a valid SETN object\n", test->name);
66 aml_state_deinit(&state);
67 return ERR;
68 }
69 UNREF_DEFER(setn);
70
71 if (aml_integer_set(setn, 6) == ERR)
72 {
73 LOG_ERR("test '%s' failed to set SETN value\n", test->name);
74 aml_state_deinit(&state);
75 return ERR;
76 }
77
78 // We dont use the \MAIN method directly instead we use the \MN01 method which enables "slack mode".
79 // Basically, certain features that would normally just result in a crash are allowed in slack mode, for example
80 // implicit returns, which some firmware depends on. See section 5.2 of the ACPICA reference for more details.
81 aml_object_t* mainObj = aml_namespace_find(&state.overlay, root, 1, AML_NAME('M', 'N', '0', '1'));
82 if (mainObj == NULL || mainObj->type != AML_METHOD)
83 {
84 LOG_ERR("test '%s' does not contain a valid method\n", test->name);
85 aml_state_deinit(&state);
86 return ERR;
87 }
88 UNREF_DEFER(mainObj);
89
90 aml_object_t* result = aml_method_invoke(&state, &mainObj->method, NULL);
91 if (result == NULL)
92 {
93 LOG_ERR("test '%s' method evaluation failed\n", test->name);
94 aml_state_deinit(&state);
95 return ERR;
96 }
97 UNREF_DEFER(result);
98
99 aml_state_deinit(&state);
100
101 if (result->type != AML_INTEGER)
102 {
103 LOG_ERR("test '%s' method did not return an integer\n", test->name);
104 return ERR;
105 }
106
107 if (result->integer.value != 0)
108 {
109 LOG_ERR("test '%s' failed, returned %llu\n", test->name, result->integer.value);
110 return ERR;
111 }
112
113 LOG_INFO("test '%s' passed\n", test->name);
114 return 0;
115}
116
117static uint64_t aml_tests_acpica_run_all(void)
118{
119 for (int32_t i = 0; i < ACPICA_TEST_COUNT; i++)
120 {
121 const acpica_test_t* test = &acpicaTests[i];
122 if (aml_tests_acpica_do_test(test) == ERR)
123 {
124 return ERR;
125 }
126 }
127 return 0;
128}
129
130TEST_DEFINE(aml)
131{
132 if (aml_tests_check_object_leak() == ERR)
133 {
134 return ERR;
135 }
136
137 uint64_t startingObjects = aml_object_get_total_count();
138
139 if (aml_tests_acpica_run_all() == ERR)
140 {
141 // For now this is definitely going to fail as we havent implemented everything yet.
142 // So just log it and continue.
143 LOG_WARN("ACPICA tests failed, this is expected until more AML features are implemented\n");
144 // return ERR;
145 }
146
147 if (startingObjects != aml_object_get_total_count())
148 {
149 LOG_ERR("memory leak detected, total objects before test %llu, after test %llu\n", startingObjects,
151 return ERR;
152 }
153
154 LOG_INFO("post parse all tests passed\n");
155 return 0;
156}
157
158#endif
static dentry_t * root
Definition devfs.c:25
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:188
aml_object_t * aml_method_invoke(aml_state_t *parentState, aml_method_t *method, aml_object_t **args)
Invoke a method with the given arguments.
Definition method.c:11
#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_get_root(void)
Get the root object of the namespace heirarchy.
Definition namespace.c:149
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
uint64_t aml_object_count_children(aml_object_t *parent)
Recursively count how many children an object has.
Definition object.c:257
uint64_t aml_object_get_total_count(void)
Get the total amount of allocated ACPI objects.
Definition object.c:20
uint64_t aml_integer_set(aml_object_t *object, aml_uint_t value)
Set a object as an integer with the given value and bit width.
Definition object.c:752
@ AML_METHOD
Definition object.h:77
@ AML_INTEGER
Definition object.h:67
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
#define LOG_ERR(format,...)
Definition log.h:93
#define LOG_WARN(format,...)
Definition log.h:92
#define LOG_INFO(format,...)
Definition log.h:91
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:122
#define TEST_DEFINE(_name)
Define a test function to be run by TEST_ALL().
Definition test.h:71
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
static uint64_t totalObjects
Definition object.c:16
__INT32_TYPE__ int32_t
Definition stdint.h:14
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
aml_uint_t value
Definition object.h:288
ACPI object.
Definition object.h:447
aml_integer_t integer
Definition object.h:458
aml_method_t method
Definition object.h:460
AML State.
Definition state.h:25
aml_overlay_t overlay
Holds any named objects created during parsing.
Definition state.h:30
Secondary System Description Table.
Definition tables.h:228