1bd24550eSEric DeVolder /*
2bd24550eSEric DeVolder * QTest testcase for acpi-erst
3bd24550eSEric DeVolder *
4bd24550eSEric DeVolder * Copyright (c) 2021 Oracle
5bd24550eSEric DeVolder *
6bd24550eSEric DeVolder * This work is licensed under the terms of the GNU GPL, version 2 or later.
7bd24550eSEric DeVolder * See the COPYING file in the top-level directory.
8bd24550eSEric DeVolder */
9bd24550eSEric DeVolder
10bd24550eSEric DeVolder #include "qemu/osdep.h"
11bd24550eSEric DeVolder #include <glib/gstdio.h>
12bd24550eSEric DeVolder #include "libqos/libqos-pc.h"
13907b5105SMarc-André Lureau #include "libqtest.h"
14bd24550eSEric DeVolder
15bd24550eSEric DeVolder #include "hw/pci/pci.h"
16bd24550eSEric DeVolder
save_fn(QPCIDevice * dev,int devfn,void * data)17bd24550eSEric DeVolder static void save_fn(QPCIDevice *dev, int devfn, void *data)
18bd24550eSEric DeVolder {
19bd24550eSEric DeVolder QPCIDevice **pdev = (QPCIDevice **) data;
20bd24550eSEric DeVolder
21bd24550eSEric DeVolder *pdev = dev;
22bd24550eSEric DeVolder }
23bd24550eSEric DeVolder
get_erst_device(QPCIBus * pcibus)24bd24550eSEric DeVolder static QPCIDevice *get_erst_device(QPCIBus *pcibus)
25bd24550eSEric DeVolder {
26bd24550eSEric DeVolder QPCIDevice *dev;
27bd24550eSEric DeVolder
28bd24550eSEric DeVolder dev = NULL;
29bd24550eSEric DeVolder qpci_device_foreach(pcibus,
30bd24550eSEric DeVolder PCI_VENDOR_ID_REDHAT,
31bd24550eSEric DeVolder PCI_DEVICE_ID_REDHAT_ACPI_ERST,
32bd24550eSEric DeVolder save_fn, &dev);
33bd24550eSEric DeVolder g_assert(dev != NULL);
34bd24550eSEric DeVolder
35bd24550eSEric DeVolder return dev;
36bd24550eSEric DeVolder }
37bd24550eSEric DeVolder
38bd24550eSEric DeVolder typedef struct _ERSTState {
39bd24550eSEric DeVolder QOSState *qs;
40bd24550eSEric DeVolder QPCIBar reg_bar, mem_bar;
41bd24550eSEric DeVolder uint64_t reg_barsize, mem_barsize;
42bd24550eSEric DeVolder QPCIDevice *dev;
43bd24550eSEric DeVolder } ERSTState;
44bd24550eSEric DeVolder
45bd24550eSEric DeVolder #define ACTION 0
46bd24550eSEric DeVolder #define VALUE 8
47bd24550eSEric DeVolder
reg2str(unsigned reg)48bd24550eSEric DeVolder static const char *reg2str(unsigned reg)
49bd24550eSEric DeVolder {
50bd24550eSEric DeVolder switch (reg) {
51bd24550eSEric DeVolder case 0:
52bd24550eSEric DeVolder return "ACTION";
53bd24550eSEric DeVolder case 8:
54bd24550eSEric DeVolder return "VALUE";
55bd24550eSEric DeVolder default:
56bd24550eSEric DeVolder return NULL;
57bd24550eSEric DeVolder }
58bd24550eSEric DeVolder }
59bd24550eSEric DeVolder
in_reg32(ERSTState * s,unsigned reg)60bd24550eSEric DeVolder static inline uint32_t in_reg32(ERSTState *s, unsigned reg)
61bd24550eSEric DeVolder {
62bd24550eSEric DeVolder const char *name = reg2str(reg);
63bd24550eSEric DeVolder uint32_t res;
64bd24550eSEric DeVolder
65bd24550eSEric DeVolder res = qpci_io_readl(s->dev, s->reg_bar, reg);
66bd24550eSEric DeVolder g_test_message("*%s -> %08x", name, res);
67bd24550eSEric DeVolder
68bd24550eSEric DeVolder return res;
69bd24550eSEric DeVolder }
70bd24550eSEric DeVolder
in_reg64(ERSTState * s,unsigned reg)71bd24550eSEric DeVolder static inline uint64_t in_reg64(ERSTState *s, unsigned reg)
72bd24550eSEric DeVolder {
73bd24550eSEric DeVolder const char *name = reg2str(reg);
74bd24550eSEric DeVolder uint64_t res;
75bd24550eSEric DeVolder
76bd24550eSEric DeVolder res = qpci_io_readq(s->dev, s->reg_bar, reg);
77c4407f19SMichael S. Tsirkin g_test_message("*%s -> %016" PRIx64, name, res);
78bd24550eSEric DeVolder
79bd24550eSEric DeVolder return res;
80bd24550eSEric DeVolder }
81bd24550eSEric DeVolder
out_reg32(ERSTState * s,unsigned reg,uint32_t v)82bd24550eSEric DeVolder static inline void out_reg32(ERSTState *s, unsigned reg, uint32_t v)
83bd24550eSEric DeVolder {
84bd24550eSEric DeVolder const char *name = reg2str(reg);
85bd24550eSEric DeVolder
86bd24550eSEric DeVolder g_test_message("%08x -> *%s", v, name);
87bd24550eSEric DeVolder qpci_io_writel(s->dev, s->reg_bar, reg, v);
88bd24550eSEric DeVolder }
89bd24550eSEric DeVolder
cleanup_vm(ERSTState * s)90bd24550eSEric DeVolder static void cleanup_vm(ERSTState *s)
91bd24550eSEric DeVolder {
92bd24550eSEric DeVolder g_free(s->dev);
93bd24550eSEric DeVolder qtest_shutdown(s->qs);
94bd24550eSEric DeVolder }
95bd24550eSEric DeVolder
setup_vm_cmd(ERSTState * s,const char * cmd)96bd24550eSEric DeVolder static void setup_vm_cmd(ERSTState *s, const char *cmd)
97bd24550eSEric DeVolder {
98bd24550eSEric DeVolder const char *arch = qtest_get_arch();
99bd24550eSEric DeVolder
100bd24550eSEric DeVolder if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
101*0472b2e5SDaniel P. Berrangé s->qs = qtest_pc_boot("%s", cmd);
102bd24550eSEric DeVolder } else {
103bd24550eSEric DeVolder g_printerr("erst-test tests are only available on x86\n");
104bd24550eSEric DeVolder exit(EXIT_FAILURE);
105bd24550eSEric DeVolder }
106bd24550eSEric DeVolder s->dev = get_erst_device(s->qs->pcibus);
107bd24550eSEric DeVolder
108bd24550eSEric DeVolder s->reg_bar = qpci_iomap(s->dev, 0, &s->reg_barsize);
109bd24550eSEric DeVolder g_assert_cmpuint(s->reg_barsize, ==, 16);
110bd24550eSEric DeVolder
111bd24550eSEric DeVolder s->mem_bar = qpci_iomap(s->dev, 1, &s->mem_barsize);
112bd24550eSEric DeVolder g_assert_cmpuint(s->mem_barsize, ==, 0x2000);
113bd24550eSEric DeVolder
114bd24550eSEric DeVolder qpci_device_enable(s->dev);
115bd24550eSEric DeVolder }
116bd24550eSEric DeVolder
test_acpi_erst_basic(void)117bd24550eSEric DeVolder static void test_acpi_erst_basic(void)
118bd24550eSEric DeVolder {
119bd24550eSEric DeVolder ERSTState state;
120bd24550eSEric DeVolder uint64_t log_address_range;
121bd24550eSEric DeVolder uint64_t log_address_length;
122bd24550eSEric DeVolder uint32_t log_address_attr;
123bd24550eSEric DeVolder
124bd24550eSEric DeVolder setup_vm_cmd(&state,
125bd24550eSEric DeVolder "-object memory-backend-file,"
126bd24550eSEric DeVolder "mem-path=acpi-erst.XXXXXX,"
127bd24550eSEric DeVolder "size=64K,"
128bd24550eSEric DeVolder "share=on,"
129bd24550eSEric DeVolder "id=nvram "
130bd24550eSEric DeVolder "-device acpi-erst,"
131bd24550eSEric DeVolder "memdev=nvram");
132bd24550eSEric DeVolder
133bd24550eSEric DeVolder out_reg32(&state, ACTION, 0xD);
134bd24550eSEric DeVolder log_address_range = in_reg64(&state, VALUE);
135bd24550eSEric DeVolder out_reg32(&state, ACTION, 0xE);
136bd24550eSEric DeVolder log_address_length = in_reg64(&state, VALUE);
137bd24550eSEric DeVolder out_reg32(&state, ACTION, 0xF);
138bd24550eSEric DeVolder log_address_attr = in_reg32(&state, VALUE);
139bd24550eSEric DeVolder
140bd24550eSEric DeVolder /* Check log_address_range is not 0, ~0 or base */
141bd24550eSEric DeVolder g_assert_cmpuint(log_address_range, !=, 0ULL);
142bd24550eSEric DeVolder g_assert_cmpuint(log_address_range, !=, ~0ULL);
143bd24550eSEric DeVolder g_assert_cmpuint(log_address_range, !=, state.reg_bar.addr);
144bd24550eSEric DeVolder g_assert_cmpuint(log_address_range, ==, state.mem_bar.addr);
145bd24550eSEric DeVolder
146bd24550eSEric DeVolder /* Check log_address_length is bar1_size */
147bd24550eSEric DeVolder g_assert_cmpuint(log_address_length, ==, state.mem_barsize);
148bd24550eSEric DeVolder
149bd24550eSEric DeVolder /* Check log_address_attr is 0 */
150bd24550eSEric DeVolder g_assert_cmpuint(log_address_attr, ==, 0);
151bd24550eSEric DeVolder
152bd24550eSEric DeVolder cleanup_vm(&state);
153bd24550eSEric DeVolder }
154bd24550eSEric DeVolder
main(int argc,char ** argv)155bd24550eSEric DeVolder int main(int argc, char **argv)
156bd24550eSEric DeVolder {
157bd24550eSEric DeVolder g_test_init(&argc, &argv, NULL);
158bd24550eSEric DeVolder qtest_add_func("/acpi-erst/basic", test_acpi_erst_basic);
15966997c42SMarkus Armbruster return g_test_run();
160bd24550eSEric DeVolder }
161