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 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 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 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 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 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 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 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 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) { 101bd24550eSEric DeVolder s->qs = qtest_pc_boot(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 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 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); 159*66997c42SMarkus Armbruster return g_test_run(); 160bd24550eSEric DeVolder } 161