blob: a4adfbfdf8360f269bccc46bd0000896c70ca084 [file] [log] [blame]
Simon Glass98528d42020-07-07 13:11:42 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Tests for ACPI code generation
4 *
5 * Copyright 2019 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass3d39c132020-07-07 13:11:43 -060011#include <irq.h>
Simon Glass98528d42020-07-07 13:11:42 -060012#include <malloc.h>
13#include <acpi/acpigen.h>
Simon Glass3d39c132020-07-07 13:11:43 -060014#include <acpi/acpi_device.h>
Simon Glass98528d42020-07-07 13:11:42 -060015#include <asm/unaligned.h>
16#include <dm/acpi.h>
17#include <dm/test.h>
18#include <test/ut.h>
19
20/* Maximum size of the ACPI context needed for most tests */
21#define ACPI_CONTEXT_SIZE 150
22
23static int alloc_context(struct acpi_ctx **ctxp)
24{
25 struct acpi_ctx *ctx;
26
27 *ctxp = NULL;
28 ctx = malloc(sizeof(*ctx));
29 if (!ctx)
30 return -ENOMEM;
31 ctx->base = malloc(ACPI_CONTEXT_SIZE);
32 if (!ctx->base) {
33 free(ctx);
34 return -ENOMEM;
35 }
36 ctx->current = ctx->base;
37 *ctxp = ctx;
38
39 return 0;
40}
41
42static void free_context(struct acpi_ctx **ctxp)
43{
44 free((*ctxp)->base);
45 free(*ctxp);
46 *ctxp = NULL;
47}
48
49/* Test emitting simple types and acpigen_get_current() */
50static int dm_test_acpi_emit_simple(struct unit_test_state *uts)
51{
52 struct acpi_ctx *ctx;
53 u8 *ptr;
54
55 ut_assertok(alloc_context(&ctx));
56
57 ptr = acpigen_get_current(ctx);
58 acpigen_emit_byte(ctx, 0x23);
59 ut_asserteq(1, acpigen_get_current(ctx) - ptr);
60 ut_asserteq(0x23, *(u8 *)ptr);
61
62 acpigen_emit_word(ctx, 0x1234);
63 ut_asserteq(3, acpigen_get_current(ctx) - ptr);
64 ut_asserteq(0x1234, get_unaligned((u16 *)(ptr + 1)));
65
66 acpigen_emit_dword(ctx, 0x87654321);
67 ut_asserteq(7, acpigen_get_current(ctx) - ptr);
68 ut_asserteq(0x87654321, get_unaligned((u32 *)(ptr + 3)));
69
70 free_context(&ctx);
71
72 return 0;
73}
74DM_TEST(dm_test_acpi_emit_simple, 0);
Simon Glass3d39c132020-07-07 13:11:43 -060075
76/* Test emitting an interrupt descriptor */
77static int dm_test_acpi_interrupt(struct unit_test_state *uts)
78{
79 struct acpi_ctx *ctx;
80 struct udevice *dev;
81 struct irq irq;
82 u8 *ptr;
83
84 ut_assertok(alloc_context(&ctx));
85
86 ptr = acpigen_get_current(ctx);
87
88 ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
89 ut_assertok(irq_get_by_index(dev, 0, &irq));
90
91 /* See a-test, property interrupts-extended in the device tree */
92 ut_asserteq(3, acpi_device_write_interrupt_irq(ctx, &irq));
93 ut_asserteq(9, acpigen_get_current(ctx) - ptr);
94 ut_asserteq(ACPI_DESCRIPTOR_INTERRUPT, ptr[0]);
95 ut_asserteq(6, get_unaligned((u16 *)(ptr + 1)));
96 ut_asserteq(0x19, ptr[3]);
97 ut_asserteq(1, ptr[4]);
98 ut_asserteq(3, get_unaligned((u32 *)(ptr + 5)));
99
100 free_context(&ctx);
101
102 return 0;
103}
104DM_TEST(dm_test_acpi_interrupt, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);