qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

erst-test.c (3823B)


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