test: dm: Test for default led naming
[platform/kernel/u-boot.git] / test / dm / acpi_dp.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Tests for ACPI code generation via a device-property table
4  *
5  * Copyright 2019 Google LLC
6  * Written by Simon Glass <sjg@chromium.org>
7  */
8
9 #include <common.h>
10 #include <dm.h>
11 #include <uuid.h>
12 #include <acpi/acpigen.h>
13 #include <acpi/acpi_dp.h>
14 #include <asm/unaligned.h>
15 #include <dm/acpi.h>
16 #include <dm/test.h>
17 #include <test/ut.h>
18 #include "acpi.h"
19
20 /* Maximum size of the ACPI context needed for most tests */
21 #define ACPI_CONTEXT_SIZE       500
22
23 #define TEST_INT8       0x7d
24 #define TEST_INT16      0x2345
25 #define TEST_INT32      0x12345678
26 #define TEST_INT64      0x4567890123456
27 #define TEST_STR        "testing acpi strings"
28 #define TEST_REF        "\\SB.I2C0.TPM2"
29 #define EXPECT_REF      "SB__I2C0TPM2"
30
31 static int alloc_context(struct acpi_ctx **ctxp)
32 {
33         return acpi_test_alloc_context_size(ctxp, ACPI_CONTEXT_SIZE);
34
35         return 0;
36 }
37
38 static void free_context(struct acpi_ctx **ctxp)
39 {
40         free(*ctxp);
41         *ctxp = NULL;
42 }
43
44 /* Test emitting an empty table */
45 static int dm_test_acpi_dp_new_table(struct unit_test_state *uts)
46 {
47         struct acpi_ctx *ctx;
48         struct acpi_dp *dp;
49         u8 *ptr;
50
51         ut_assertok(alloc_context(&ctx));
52
53         dp = acpi_dp_new_table("FRED");
54         ut_assertnonnull(dp);
55
56         ptr = acpigen_get_current(ctx);
57         ut_assertok(acpi_dp_write(ctx, dp));
58         ut_asserteq(10, acpigen_get_current(ctx) - ptr);
59         ut_asserteq(NAME_OP, *(u8 *)ptr);
60         ut_asserteq_strn("FRED", (char *)ptr + 1);
61         ut_asserteq(PACKAGE_OP, ptr[5]);
62         ut_asserteq(4, acpi_test_get_length(ptr + 6));
63         ut_asserteq(0, ptr[9]);
64
65         free_context(&ctx);
66
67         return 0;
68 }
69 DM_TEST(dm_test_acpi_dp_new_table, 0);
70
71 /* Test emitting an integer */
72 static int dm_test_acpi_dp_int(struct unit_test_state *uts)
73 {
74         struct acpi_ctx *ctx;
75         char uuid[UUID_STR_LEN + 1];
76         struct acpi_dp *dp;
77         u8 *ptr;
78
79         ut_assertok(alloc_context(&ctx));
80
81         dp = acpi_dp_new_table("FRED");
82         ut_assertnonnull(dp);
83         ut_assertnonnull(acpi_dp_add_integer(dp, "MARY", TEST_INT32));
84
85         ptr = acpigen_get_current(ctx);
86         ut_assertok(acpi_dp_write(ctx, dp));
87         ut_asserteq(54, acpigen_get_current(ctx) - ptr);
88         ut_asserteq(NAME_OP, *(u8 *)ptr);
89         ut_asserteq_strn("FRED", (char *)ptr + 1);
90         ut_asserteq(PACKAGE_OP, ptr[5]);
91         ut_asserteq(48, acpi_test_get_length(ptr + 6));
92         ut_asserteq(2, ptr[9]);
93
94         /* UUID */
95         ut_asserteq(BUFFER_OP, ptr[10]);
96         ut_asserteq(22, acpi_test_get_length(ptr + 11));
97         ut_asserteq(WORD_PREFIX, ptr[14]);
98         ut_asserteq(16, get_unaligned((u16 *)(ptr + 15)));
99         uuid_bin_to_str(ptr + 17, uuid, 1);
100         ut_asserteq_str(ACPI_DP_UUID, uuid);
101
102         /* Container package */
103         ut_asserteq(PACKAGE_OP, ptr[33]);
104         ut_asserteq(20, acpi_test_get_length(ptr + 34));
105         ut_asserteq(1, ptr[37]);
106
107         /* Package with name and (integer) value */
108         ut_asserteq(PACKAGE_OP, ptr[38]);
109         ut_asserteq(15, acpi_test_get_length(ptr + 39));
110         ut_asserteq(2, ptr[42]);
111         ut_asserteq(STRING_PREFIX, ptr[43]);
112         ut_asserteq_str("MARY", (char *)ptr + 44);
113
114         ut_asserteq(DWORD_PREFIX, ptr[49]);
115         ut_asserteq(TEST_INT32, get_unaligned((u32 *)(ptr + 50)));
116
117         free_context(&ctx);
118
119         return 0;
120 }
121 DM_TEST(dm_test_acpi_dp_int, 0);
122
123 /* Test emitting a 64-bit integer */
124 static int dm_test_acpi_dp_int64(struct unit_test_state *uts)
125 {
126         struct acpi_ctx *ctx;
127         struct acpi_dp *dp;
128         u8 *ptr;
129
130         ut_assertok(alloc_context(&ctx));
131
132         dp = acpi_dp_new_table("FRED");
133         ut_assertnonnull(dp);
134         ut_assertnonnull(acpi_dp_add_integer(dp, "MARY", TEST_INT64));
135
136         ptr = acpigen_get_current(ctx);
137         ut_assertok(acpi_dp_write(ctx, dp));
138         ut_asserteq(58, acpigen_get_current(ctx) - ptr);
139
140         ut_asserteq(QWORD_PREFIX, ptr[49]);
141         ut_asserteq_64(TEST_INT64, get_unaligned((u64 *)(ptr + 50)));
142
143         free_context(&ctx);
144
145         return 0;
146 }
147 DM_TEST(dm_test_acpi_dp_int64, 0);
148
149 /* Test emitting a 16-bit integer */
150 static int dm_test_acpi_dp_int16(struct unit_test_state *uts)
151 {
152         struct acpi_ctx *ctx;
153         struct acpi_dp *dp;
154         u8 *ptr;
155
156         ut_assertok(alloc_context(&ctx));
157
158         dp = acpi_dp_new_table("FRED");
159         ut_assertnonnull(dp);
160         ut_assertnonnull(acpi_dp_add_integer(dp, "MARY", TEST_INT16));
161
162         ptr = acpigen_get_current(ctx);
163         ut_assertok(acpi_dp_write(ctx, dp));
164         ut_asserteq(52, acpigen_get_current(ctx) - ptr);
165
166         ut_asserteq(WORD_PREFIX, ptr[49]);
167         ut_asserteq(TEST_INT16, get_unaligned((u16 *)(ptr + 50)));
168
169         free_context(&ctx);
170
171         return 0;
172 }
173 DM_TEST(dm_test_acpi_dp_int16, 0);
174
175 /* Test emitting a 8-bit integer */
176 static int dm_test_acpi_dp_int8(struct unit_test_state *uts)
177 {
178         struct acpi_ctx *ctx;
179         struct acpi_dp *dp;
180         u8 *ptr;
181
182         ut_assertok(alloc_context(&ctx));
183
184         dp = acpi_dp_new_table("FRED");
185         ut_assertnonnull(dp);
186         ut_assertnonnull(acpi_dp_add_integer(dp, "MARY", TEST_INT8));
187
188         ptr = acpigen_get_current(ctx);
189         ut_assertok(acpi_dp_write(ctx, dp));
190         ut_asserteq(51, acpigen_get_current(ctx) - ptr);
191
192         ut_asserteq(BYTE_PREFIX, ptr[49]);
193         ut_asserteq(TEST_INT8, ptr[50]);
194
195         free_context(&ctx);
196
197         return 0;
198 }
199 DM_TEST(dm_test_acpi_dp_int8, 0);
200
201 /* Test emitting multiple values */
202 static int dm_test_acpi_dp_multiple(struct unit_test_state *uts)
203 {
204         struct acpi_ctx *ctx;
205         struct acpi_dp *dp;
206         u8 *ptr;
207
208         ut_assertok(alloc_context(&ctx));
209
210         dp = acpi_dp_new_table("FRED");
211         ut_assertnonnull(dp);
212         ut_assertnonnull(acpi_dp_add_integer(dp, "int16", TEST_INT16));
213         ut_assertnonnull(acpi_dp_add_string(dp, "str", TEST_STR));
214         ut_assertnonnull(acpi_dp_add_reference(dp, "ref", TEST_REF));
215
216         ptr = acpigen_get_current(ctx);
217         ut_assertok(acpi_dp_write(ctx, dp));
218         ut_asserteq(110, acpigen_get_current(ctx) - ptr);
219
220         ut_asserteq(WORD_PREFIX, ptr[0x32]);
221         ut_asserteq(TEST_INT16, get_unaligned((u16 *)(ptr + 0x33)));
222         ut_asserteq(STRING_PREFIX, ptr[0x3f]);
223         ut_asserteq_str(TEST_STR, (char *)ptr + 0x40);
224         ut_asserteq(ROOT_PREFIX, ptr[0x5f]);
225         ut_asserteq(MULTI_NAME_PREFIX, ptr[0x60]);
226         ut_asserteq(3, ptr[0x61]);
227         ut_asserteq_strn(EXPECT_REF, (char *)ptr + 0x62);
228
229         free_context(&ctx);
230
231         return 0;
232 }
233 DM_TEST(dm_test_acpi_dp_multiple, 0);
234
235 /* Test emitting an array */
236 static int dm_test_acpi_dp_array(struct unit_test_state *uts)
237 {
238         struct acpi_ctx *ctx;
239         struct acpi_dp *dp;
240         u64 speed[4];
241         u8 *ptr;
242
243         ut_assertok(alloc_context(&ctx));
244
245         dp = acpi_dp_new_table("FRED");
246         ut_assertnonnull(dp);
247         speed[0] = TEST_INT8;
248         speed[1] = TEST_INT16;
249         speed[2] = TEST_INT32;
250         speed[3] = TEST_INT64;
251         ut_assertnonnull(acpi_dp_add_integer_array(dp, "speeds", speed,
252                                                    ARRAY_SIZE(speed)));
253
254         ptr = acpigen_get_current(ctx);
255         ut_assertok(acpi_dp_write(ctx, dp));
256         ut_asserteq(75, acpigen_get_current(ctx) - ptr);
257
258         ut_asserteq(BYTE_PREFIX, ptr[0x38]);
259         ut_asserteq(TEST_INT8, ptr[0x39]);
260
261         ut_asserteq(WORD_PREFIX, ptr[0x3a]);
262         ut_asserteq(TEST_INT16, get_unaligned((u16 *)(ptr + 0x3b)));
263
264         ut_asserteq(DWORD_PREFIX, ptr[0x3d]);
265         ut_asserteq(TEST_INT32, get_unaligned((u32 *)(ptr + 0x3e)));
266
267         ut_asserteq(QWORD_PREFIX, ptr[0x42]);
268         ut_asserteq_64(TEST_INT64, get_unaligned((u64 *)(ptr + 0x43)));
269
270         free_context(&ctx);
271
272         return 0;
273 }
274 DM_TEST(dm_test_acpi_dp_array, 0);
275
276 /* Test emitting a child */
277 static int dm_test_acpi_dp_child(struct unit_test_state *uts)
278 {
279         struct acpi_ctx *ctx;
280         struct acpi_dp *dp, *child1, *child2;
281         char uuid[UUID_STR_LEN + 1];
282         u8 *ptr, *pptr;
283         int i;
284
285         ut_assertok(alloc_context(&ctx));
286
287         child1 = acpi_dp_new_table("child");
288         ut_assertnonnull(child1);
289         ut_assertnonnull(acpi_dp_add_integer(child1, "height", TEST_INT16));
290
291         child2 = acpi_dp_new_table("child");
292         ut_assertnonnull(child2);
293         ut_assertnonnull(acpi_dp_add_integer(child2, "age", TEST_INT8));
294
295         dp = acpi_dp_new_table("FRED");
296         ut_assertnonnull(dp);
297
298         ut_assertnonnull(acpi_dp_add_child(dp, "anna", child1));
299         ut_assertnonnull(acpi_dp_add_child(dp, "john", child2));
300
301         ptr = acpigen_get_current(ctx);
302         ut_assertok(acpi_dp_write(ctx, dp));
303         ut_asserteq(178, acpigen_get_current(ctx) - ptr);
304
305         /* UUID for child extension using Hierarchical Data Extension UUID */
306         ut_asserteq(BUFFER_OP, ptr[10]);
307         ut_asserteq(22, acpi_test_get_length(ptr + 11));
308         ut_asserteq(WORD_PREFIX, ptr[14]);
309         ut_asserteq(16, get_unaligned((u16 *)(ptr + 15)));
310         uuid_bin_to_str(ptr + 17, uuid, 1);
311         ut_asserteq_str(ACPI_DP_CHILD_UUID, uuid);
312
313         /* Package with two children */
314         ut_asserteq(PACKAGE_OP, ptr[0x21]);
315         ut_asserteq(0x28, acpi_test_get_length(ptr + 0x22));
316         ut_asserteq(2, ptr[0x25]);
317
318         /* First we expect the two children as string/value */
319         pptr = ptr + 0x26;
320         for (i = 0; i < 2; i++) {
321                 ut_asserteq(PACKAGE_OP, pptr[0]);
322                 ut_asserteq(0x11, acpi_test_get_length(pptr + 1));
323                 ut_asserteq(2, pptr[4]);
324                 ut_asserteq(STRING_PREFIX, pptr[5]);
325                 ut_asserteq_str(i ? "john" : "anna", (char *)pptr + 6);
326                 ut_asserteq(STRING_PREFIX, pptr[11]);
327                 ut_asserteq_str("child", (char *)pptr + 12);
328                 pptr += 0x12;
329         }
330
331         /* Write the two children */
332         ut_asserteq(0x4a, pptr - ptr);
333         for (i = 0; i < 2; i++) {
334                 const char *prop = i ? "age" : "height";
335                 const int datalen = i ? 1 : 2;
336                 int len = strlen(prop) + 1;
337
338                 ut_asserteq(NAME_OP, pptr[0]);
339                 ut_asserteq_strn("chil", (char *)pptr + 1);
340                 ut_asserteq(PACKAGE_OP, pptr[5]);
341                 ut_asserteq(0x27 + len + datalen, acpi_test_get_length(pptr + 6));
342                 ut_asserteq(2, pptr[9]);
343
344                 /* UUID */
345                 ut_asserteq(BUFFER_OP, pptr[10]);
346                 ut_asserteq(22, acpi_test_get_length(pptr + 11));
347                 ut_asserteq(WORD_PREFIX, pptr[14]);
348                 ut_asserteq(16, get_unaligned((u16 *)(pptr + 15)));
349                 uuid_bin_to_str(pptr + 17, uuid, 1);
350                 ut_asserteq_str(ACPI_DP_UUID, uuid);
351                 pptr += 33;
352
353                 /* Containing package */
354                 ut_asserteq(i ? 0xa1 : 0x6b, pptr - ptr);
355                 ut_asserteq(PACKAGE_OP, pptr[0]);
356                 ut_asserteq(0xb + len + datalen, acpi_test_get_length(pptr + 1));
357                 ut_asserteq(1, pptr[4]);
358
359                 /* Package containing the property-name string and the value */
360                 pptr += 5;
361                 ut_asserteq(i ? 0xa6 : 0x70, pptr - ptr);
362                 ut_asserteq(PACKAGE_OP, pptr[0]);
363                 ut_asserteq(6 + len + datalen, acpi_test_get_length(pptr + 1));
364                 ut_asserteq(2, pptr[4]);
365
366                 ut_asserteq(STRING_PREFIX, pptr[5]);
367                 ut_asserteq_str(i ? "age" : "height", (char *)pptr + 6);
368                 pptr += 6 + len;
369                 if (i) {
370                         ut_asserteq(BYTE_PREFIX, pptr[0]);
371                         ut_asserteq(TEST_INT8, pptr[1]);
372                 } else {
373                         ut_asserteq(WORD_PREFIX, pptr[0]);
374                         ut_asserteq(TEST_INT16,
375                                     get_unaligned((u16 *)(pptr + 1)));
376                 }
377                 pptr += 1 + datalen;
378         }
379         ut_asserteq(178, pptr - ptr);
380
381         free_context(&ctx);
382
383         return 0;
384 }
385 DM_TEST(dm_test_acpi_dp_child, 0);
386
387 /* Test emitting a GPIO */
388 static int dm_test_acpi_dp_gpio(struct unit_test_state *uts)
389 {
390         struct acpi_ctx *ctx;
391         struct acpi_dp *dp;
392         u8 *ptr, *pptr;
393
394         ut_assertok(alloc_context(&ctx));
395
396         dp = acpi_dp_new_table("FRED");
397         ut_assertnonnull(dp);
398
399         /* Try a few different parameters */
400         ut_assertnonnull(acpi_dp_add_gpio(dp, "reset", TEST_REF, 0x23, 0x24,
401                                           ACPI_GPIO_ACTIVE_HIGH));
402         ut_assertnonnull(acpi_dp_add_gpio(dp, "allow", TEST_REF, 0, 0,
403                                           ACPI_GPIO_ACTIVE_LOW));
404
405         ptr = acpigen_get_current(ctx);
406         ut_assertok(acpi_dp_write(ctx, dp));
407         ut_asserteq(0x6e, acpigen_get_current(ctx) - ptr);
408
409         pptr = ptr + 0x2c; //0x3a;
410         ut_asserteq_str("reset", (char *)pptr);
411         ut_asserteq_strn(EXPECT_REF, (char *)pptr + 0xe);
412         ut_asserteq(0x23, pptr[0x1b]);
413         ut_asserteq(0x24, pptr[0x1d]);
414         ut_asserteq(ZERO_OP, pptr[0x1e]);
415
416         pptr = ptr + 0x51;
417         ut_asserteq_str("allow", (char *)pptr);
418         ut_asserteq_strn(EXPECT_REF, (char *)pptr + 0xe);
419         ut_asserteq(ZERO_OP, pptr[0x1a]);
420         ut_asserteq(ZERO_OP, pptr[0x1b]);
421         ut_asserteq(ONE_OP, pptr[0x1c]);
422
423         return 0;
424 }
425 DM_TEST(dm_test_acpi_dp_gpio, 0);
426
427 /* Test copying info from the device tree to ACPI tables */
428 static int dm_test_acpi_dp_copy(struct unit_test_state *uts)
429 {
430         struct acpi_ctx *ctx;
431         struct udevice *dev;
432         struct acpi_dp *dp;
433         ofnode node;
434         u8 *ptr;
435
436         ut_assertok(alloc_context(&ctx));
437
438         dp = acpi_dp_new_table("FRED");
439         ut_assertnonnull(dp);
440
441         ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
442         ut_asserteq_str("a-test", dev->name);
443
444         ut_assertok(acpi_dp_dev_copy_int(dev, dp, "int-value"));
445         ut_asserteq(-EINVAL, acpi_dp_dev_copy_int(dev, dp, "missing-value"));
446         ut_assertok(acpi_dp_dev_copy_int(dev, dp, "uint-value"));
447
448         ut_assertok(acpi_dp_dev_copy_str(dev, dp, "str-value"));
449         ut_asserteq(-EINVAL, acpi_dp_dev_copy_str(dev, dp, "missing-value"));
450
451         node = ofnode_path("/chosen");
452         ut_assert(ofnode_valid(node));
453         ut_assertok(acpi_dp_ofnode_copy_int(node, dp, "int-values"));
454         ut_asserteq(-EINVAL,
455                     acpi_dp_ofnode_copy_int(node, dp, "missing-value"));
456
457         ut_assertok(acpi_dp_ofnode_copy_str(node, dp, "setting"));
458         ut_asserteq(-EINVAL,
459                     acpi_dp_ofnode_copy_str(node, dp, "missing-value"));
460
461         ptr = acpigen_get_current(ctx);
462         ut_assertok(acpi_dp_write(ctx, dp));
463         ut_asserteq(0x9d, acpigen_get_current(ctx) - ptr);
464
465         ut_asserteq(STRING_PREFIX, ptr[0x2b]);
466         ut_asserteq_str("int-value", (char *)ptr + 0x2c);
467         ut_asserteq(WORD_PREFIX, ptr[0x36]);
468         ut_asserteq(1234, get_unaligned((u16 *)(ptr + 0x37)));
469
470         ut_asserteq(STRING_PREFIX, ptr[0x3e]);
471         ut_asserteq_str("uint-value", (char *)ptr + 0x3f);
472         ut_asserteq(DWORD_PREFIX, ptr[0x4a]);
473         ut_asserteq(-1234, get_unaligned((u32 *)(ptr + 0x4b)));
474
475         ut_asserteq(STRING_PREFIX, ptr[0x54]);
476         ut_asserteq_str("str-value", (char *)ptr + 0x55);
477         ut_asserteq(STRING_PREFIX, ptr[0x5f]);
478         ut_asserteq_str("test string", (char *)ptr + 0x60);
479
480         ut_asserteq(STRING_PREFIX, ptr[0x71]);
481         ut_asserteq_str("int-values", (char *)ptr + 0x72);
482         ut_asserteq(WORD_PREFIX, ptr[0x7d]);
483         ut_asserteq(0x1937, get_unaligned((u16 *)(ptr + 0x7e)));
484
485         ut_asserteq(STRING_PREFIX, ptr[0x85]);
486         ut_asserteq_str("setting", (char *)ptr + 0x86);
487         ut_asserteq(STRING_PREFIX, ptr[0x8e]);
488         ut_asserteq_str("sunrise ohoka", (char *)(ptr + 0x8f));
489
490         return 0;
491 }
492 DM_TEST(dm_test_acpi_dp_copy, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);