1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qemu/units.h"
12#include "libqtest.h"
13#include "libqos/libqos-pc.h"
14
15static QOSState *qnvme_start(const char *extra_opts)
16{
17 QOSState *qs;
18 const char *arch = qtest_get_arch();
19 const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
20 "-device nvme,addr=0x4.0,serial=foo,drive=drv0 %s";
21
22 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
23 qs = qtest_pc_boot(cmd, extra_opts ? : "");
24 global_qtest = qs->qts;
25 return qs;
26 }
27
28 g_printerr("nvme tests are only available on x86\n");
29 exit(EXIT_FAILURE);
30}
31
32static void qnvme_stop(QOSState *qs)
33{
34 qtest_shutdown(qs);
35}
36
37static void nop(void)
38{
39 QOSState *qs;
40
41 qs = qnvme_start(NULL);
42 qnvme_stop(qs);
43}
44
45static void nvmetest_cmb_test(void)
46{
47 const int cmb_bar_size = 2 * MiB;
48 QOSState *qs;
49 QPCIDevice *pdev;
50 QPCIBar bar;
51
52 qs = qnvme_start("-global nvme.cmb_size_mb=2");
53 pdev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
54 g_assert(pdev != NULL);
55
56 qpci_device_enable(pdev);
57 bar = qpci_iomap(pdev, 2, NULL);
58
59 qpci_io_writel(pdev, bar, 0, 0xccbbaa99);
60 g_assert_cmpint(qpci_io_readb(pdev, bar, 0), ==, 0x99);
61 g_assert_cmpint(qpci_io_readw(pdev, bar, 0), ==, 0xaa99);
62
63
64 qpci_io_writel(pdev, bar, cmb_bar_size - 1, 0x44332211);
65 g_assert_cmpint(qpci_io_readb(pdev, bar, cmb_bar_size - 1), ==, 0x11);
66 g_assert_cmpint(qpci_io_readw(pdev, bar, cmb_bar_size - 1), !=, 0x2211);
67 g_assert_cmpint(qpci_io_readl(pdev, bar, cmb_bar_size - 1), !=, 0x44332211);
68 g_free(pdev);
69
70 qnvme_stop(qs);
71}
72
73int main(int argc, char **argv)
74{
75 g_test_init(&argc, &argv, NULL);
76 qtest_add_func("/nvme/nop", nop);
77 qtest_add_func("/nvme/cmb_test", nvmetest_cmb_test);
78
79 return g_test_run();
80}
81