2 * QTest testcase for SDHCI controllers
4 * Written by Philippe Mathieu-Daudé <f4bug@amsat.org>
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 * SPDX-License-Identifier: GPL-2.0-or-later
10 #include "qemu/osdep.h"
11 #include "hw/registerfields.h"
13 #include "libqos/pci-pc.h"
14 #include "hw/pci/pci.h"
15 #include "libqos/qgraph.h"
16 #include "libqos/sdhci.h"
18 #define SDHC_CAPAB 0x40
19 FIELD(SDHC_CAPAB
, BASECLKFREQ
, 8, 8); /* since v2 */
20 FIELD(SDHC_CAPAB
, SDMA
, 22, 1);
21 FIELD(SDHC_CAPAB
, SDR
, 32, 3); /* since v3 */
22 FIELD(SDHC_CAPAB
, DRIVER
, 36, 3); /* since v3 */
23 #define SDHC_HCVER 0xFE
25 static void check_specs_version(QSDHCI
*s
, uint8_t version
)
29 v
= s
->readw(s
, SDHC_HCVER
);
32 g_assert_cmpuint(v
, ==, version
);
35 static void check_capab_capareg(QSDHCI
*s
, uint64_t expec_capab
)
39 capab
= s
->readq(s
, SDHC_CAPAB
);
40 g_assert_cmphex(capab
, ==, expec_capab
);
43 static void check_capab_readonly(QSDHCI
*s
)
45 const uint64_t vrand
= 0x123456789abcdef;
46 uint64_t capab0
, capab1
;
48 capab0
= s
->readq(s
, SDHC_CAPAB
);
49 g_assert_cmpuint(capab0
, !=, vrand
);
51 s
->writeq(s
, SDHC_CAPAB
, vrand
);
52 capab1
= s
->readq(s
, SDHC_CAPAB
);
53 g_assert_cmpuint(capab1
, !=, vrand
);
54 g_assert_cmpuint(capab1
, ==, capab0
);
57 static void check_capab_baseclock(QSDHCI
*s
, uint8_t expec_freq
)
59 uint64_t capab
, capab_freq
;
64 capab
= s
->readq(s
, SDHC_CAPAB
);
65 capab_freq
= FIELD_EX64(capab
, SDHC_CAPAB
, BASECLKFREQ
);
66 g_assert_cmpuint(capab_freq
, ==, expec_freq
);
69 static void check_capab_sdma(QSDHCI
*s
, bool supported
)
71 uint64_t capab
, capab_sdma
;
73 capab
= s
->readq(s
, SDHC_CAPAB
);
74 capab_sdma
= FIELD_EX64(capab
, SDHC_CAPAB
, SDMA
);
75 g_assert_cmpuint(capab_sdma
, ==, supported
);
78 static void check_capab_v3(QSDHCI
*s
, uint8_t version
)
80 uint64_t capab
, capab_v3
;
83 /* before v3 those fields are RESERVED */
84 capab
= s
->readq(s
, SDHC_CAPAB
);
85 capab_v3
= FIELD_EX64(capab
, SDHC_CAPAB
, SDR
);
86 g_assert_cmpuint(capab_v3
, ==, 0);
87 capab_v3
= FIELD_EX64(capab
, SDHC_CAPAB
, DRIVER
);
88 g_assert_cmpuint(capab_v3
, ==, 0);
92 static void test_registers(void *obj
, void *data
, QGuestAllocator
*alloc
)
96 check_specs_version(s
, s
->props
.version
);
97 check_capab_capareg(s
, s
->props
.capab
.reg
);
98 check_capab_readonly(s
);
99 check_capab_v3(s
, s
->props
.version
);
100 check_capab_sdma(s
, s
->props
.capab
.sdma
);
101 check_capab_baseclock(s
, s
->props
.baseclock
);
104 static void register_sdhci_test(void)
106 qos_add_test("registers", "sdhci", test_registers
, NULL
);
109 libqos_init(register_sdhci_test
);