arch/x86/c_start.S: Remove duplicated "the" in comments
[coreboot.git] / tests / acpi / acpigen-test.c
blob6bd1d02689f9687bb05feac444b8a83c4cfce31b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <stdlib.h>
4 #include <types.h>
5 #include <tests/test.h>
6 #include <acpi/acpigen.h>
8 #define ACPIGEN_TEST_BUFFER_SZ (16 * KiB)
10 /* Returns AML package length. Works with normal and extended packages.
11 This implementation is independent from acpigen.c implementation of package length. */
12 static u32 decode_package_length(const char *ptr)
14 const u8 *aml = (u8 *)ptr;
15 const u32 offset = (aml[0] == EXT_OP_PREFIX ? 2 : 1);
16 u32 byte_zero_mask = 0x3F; /* Bits [0:5] */
17 u32 byte_count = aml[offset] >> 6;
18 u32 package_length = 0;
20 while (byte_count) {
21 package_length |= aml[offset + byte_count] << ((byte_count << 3) - 4);
22 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
23 byte_count--;
26 package_length |= (aml[offset] & byte_zero_mask);
28 return package_length;
31 static u32 get_current_block_length(const char *base)
33 const u32 offset = (base[0] == EXT_OP_PREFIX ? 2 : 1);
35 return ((uintptr_t)acpigen_get_current() - ((uintptr_t)base + offset));
38 static int setup_acpigen(void **state)
40 void *buffer = malloc(ACPIGEN_TEST_BUFFER_SZ);
42 if (buffer == NULL)
43 return -1;
45 memset(buffer, 0, ACPIGEN_TEST_BUFFER_SZ);
47 *state = buffer;
48 return 0;
51 static int teardown_acpigen(void **state)
53 free(*state);
54 return 0;
57 static void test_acpigen_single_if(void **state)
59 char *acpigen_buf = *state;
60 u32 if_package_length = 0;
61 u32 block_length = 0;
63 acpigen_set_current(acpigen_buf);
65 /* Create dummy AML */
66 acpigen_write_if_lequal_op_int(LOCAL0_OP, 64);
68 for (int i = 0; i < 20; ++i)
69 acpigen_write_store_ops(ZERO_OP, LOCAL1_OP);
71 /* Close if */
72 acpigen_pop_len();
74 if_package_length = decode_package_length(acpigen_buf);
75 block_length = get_current_block_length(acpigen_buf);
76 assert_int_equal(if_package_length, block_length);
79 static void create_nested_ifs_recursive(char *stack_start[], char *stack_end[], u32 i, u32 n)
81 if (i >= n)
82 return;
84 stack_start[i] = acpigen_get_current();
85 acpigen_write_if_and(LOCAL0_OP, ZERO_OP);
87 for (int k = 0; k < 3; ++k)
88 acpigen_write_store_ops(ZERO_OP, LOCAL1_OP);
90 create_nested_ifs_recursive(stack_start, stack_end, i + 1, n);
92 acpigen_pop_len();
93 stack_end[i] = acpigen_get_current();
96 static void test_acpigen_nested_ifs(void **state)
98 char *acpigen_buf = *state;
99 const size_t nesting_level = 8;
100 char *block_start[8] = {0};
101 char *block_end[8] = {0};
103 acpigen_set_current(acpigen_buf);
105 create_nested_ifs_recursive(block_start, block_end, 0, nesting_level);
107 for (int i = 0; i < nesting_level; ++i)
108 assert_int_equal(decode_package_length(block_start[i]),
109 block_end[i] - block_start[i] - 1);
112 static void test_acpigen_write_package(void **state)
114 char *acpigen_buf = *state;
115 u32 package_length;
116 u32 block_length;
118 acpigen_set_current(acpigen_buf);
119 acpigen_write_package(3);
121 acpigen_write_return_singleton_buffer(0xA);
122 acpigen_write_return_singleton_buffer(0x7);
123 acpigen_write_return_singleton_buffer(0xF);
125 acpigen_pop_len();
127 package_length = decode_package_length(acpigen_buf);
128 block_length = get_current_block_length(acpigen_buf);
129 assert_int_equal(package_length, block_length);
132 static void test_acpigen_scope_with_contents(void **state)
134 char *acpigen_buf = *state;
135 char *block_start[8] = {0};
136 u32 block_counter = 0;
137 u32 package_length;
138 u32 block_length;
140 acpigen_set_current(acpigen_buf);
142 /* Scope("\_SB") { */
143 block_start[block_counter++] = acpigen_get_current();
144 acpigen_write_scope("\\_SB");
146 /* Device("PCI0") { */
147 block_start[block_counter++] = acpigen_get_current();
148 acpigen_write_device("PCI0");
150 /* Name(INT1, 0x1234) */
151 acpigen_write_name_integer("INT1", 0x1234);
153 /* Name (_HID, EisaId ("PNP0A08")) // PCI Express Bus */
154 acpigen_write_name("_HID");
155 acpigen_emit_eisaid("PNP0A08");
157 /* Method(^BN00, 0, NotSerialized) { */
158 block_start[block_counter++] = acpigen_get_current();
159 acpigen_write_method("^BN00", 0);
161 /* Return( 0x12 + ^PCI0.INT1 ) */
162 acpigen_write_return_op(AND_OP);
163 acpigen_write_byte(0x12);
164 acpigen_emit_namestring("^PCI0.INT1");
166 /* } */
167 acpigen_pop_len();
168 block_counter--;
169 package_length = decode_package_length(block_start[block_counter]);
170 block_length = get_current_block_length(block_start[block_counter]);
171 assert_int_equal(package_length, block_length);
173 /* Method (_BBN, 0, NotSerialized) { */
174 block_start[block_counter++] = acpigen_get_current();
175 acpigen_write_method("_BBN", 0);
177 /* Return (BN00 ()) */
178 acpigen_write_return_namestr("BN00");
179 acpigen_emit_byte(0x0A);
181 /* } */
182 acpigen_pop_len();
183 block_counter--;
184 package_length = decode_package_length(block_start[block_counter]);
185 block_length = get_current_block_length(block_start[block_counter]);
186 assert_int_equal(package_length, block_length);
188 /* } */
189 acpigen_pop_len();
190 block_counter--;
191 package_length = decode_package_length(block_start[block_counter]);
192 block_length = get_current_block_length(block_start[block_counter]);
193 assert_int_equal(package_length, block_length);
195 /* } */
196 acpigen_pop_len();
197 block_counter--;
198 package_length = decode_package_length(block_start[block_counter]);
199 block_length = get_current_block_length(block_start[block_counter]);
200 assert_int_equal(package_length, block_length);
203 int main(void)
205 const struct CMUnitTest tests[] = {
206 cmocka_unit_test_setup_teardown(test_acpigen_single_if,
207 setup_acpigen, teardown_acpigen),
208 cmocka_unit_test_setup_teardown(test_acpigen_nested_ifs,
209 setup_acpigen, teardown_acpigen),
210 cmocka_unit_test_setup_teardown(test_acpigen_write_package,
211 setup_acpigen, teardown_acpigen),
212 cmocka_unit_test_setup_teardown(test_acpigen_scope_with_contents,
213 setup_acpigen, teardown_acpigen),
216 return cb_run_group_tests(tests, NULL, NULL);