]>
Commit | Line | Data |
---|---|---|
8640cc11 PMD |
1 | /* |
2 | * QTest testcase for SDHCI controllers | |
3 | * | |
4 | * Written by Philippe Mathieu-Daudé <[email protected]> | |
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 | * SPDX-License-Identifier: GPL-2.0-or-later | |
9 | */ | |
0b8fa32f | 10 | |
8640cc11 PMD |
11 | #include "qemu/osdep.h" |
12 | #include "hw/registerfields.h" | |
13 | #include "libqtest.h" | |
0b8fa32f | 14 | #include "qemu/module.h" |
8640cc11 PMD |
15 | #include "libqos/pci-pc.h" |
16 | #include "hw/pci/pci.h" | |
757c6eac EGE |
17 | #include "libqos/qgraph.h" |
18 | #include "libqos/sdhci.h" | |
8640cc11 PMD |
19 | |
20 | #define SDHC_CAPAB 0x40 | |
0c78f51e | 21 | FIELD(SDHC_CAPAB, BASECLKFREQ, 8, 8); /* since v2 */ |
bc13038f | 22 | FIELD(SDHC_CAPAB, SDMA, 22, 1); |
f18e6d50 PMD |
23 | FIELD(SDHC_CAPAB, SDR, 32, 3); /* since v3 */ |
24 | FIELD(SDHC_CAPAB, DRIVER, 36, 3); /* since v3 */ | |
8640cc11 PMD |
25 | #define SDHC_HCVER 0xFE |
26 | ||
efe9d524 PMD |
27 | static void check_specs_version(QSDHCI *s, uint8_t version) |
28 | { | |
29 | uint32_t v; | |
30 | ||
757c6eac | 31 | v = s->readw(s, SDHC_HCVER); |
efe9d524 PMD |
32 | v &= 0xff; |
33 | v += 1; | |
34 | g_assert_cmpuint(v, ==, version); | |
35 | } | |
36 | ||
8640cc11 PMD |
37 | static void check_capab_capareg(QSDHCI *s, uint64_t expec_capab) |
38 | { | |
39 | uint64_t capab; | |
40 | ||
757c6eac | 41 | capab = s->readq(s, SDHC_CAPAB); |
8640cc11 PMD |
42 | g_assert_cmphex(capab, ==, expec_capab); |
43 | } | |
44 | ||
556f9aca PMD |
45 | static void check_capab_readonly(QSDHCI *s) |
46 | { | |
47 | const uint64_t vrand = 0x123456789abcdef; | |
48 | uint64_t capab0, capab1; | |
49 | ||
757c6eac | 50 | capab0 = s->readq(s, SDHC_CAPAB); |
556f9aca PMD |
51 | g_assert_cmpuint(capab0, !=, vrand); |
52 | ||
757c6eac EGE |
53 | s->writeq(s, SDHC_CAPAB, vrand); |
54 | capab1 = s->readq(s, SDHC_CAPAB); | |
556f9aca PMD |
55 | g_assert_cmpuint(capab1, !=, vrand); |
56 | g_assert_cmpuint(capab1, ==, capab0); | |
57 | } | |
58 | ||
0c78f51e PMD |
59 | static void check_capab_baseclock(QSDHCI *s, uint8_t expec_freq) |
60 | { | |
61 | uint64_t capab, capab_freq; | |
62 | ||
63 | if (!expec_freq) { | |
64 | return; | |
65 | } | |
757c6eac | 66 | capab = s->readq(s, SDHC_CAPAB); |
0c78f51e PMD |
67 | capab_freq = FIELD_EX64(capab, SDHC_CAPAB, BASECLKFREQ); |
68 | g_assert_cmpuint(capab_freq, ==, expec_freq); | |
69 | } | |
70 | ||
bc13038f PMD |
71 | static void check_capab_sdma(QSDHCI *s, bool supported) |
72 | { | |
73 | uint64_t capab, capab_sdma; | |
74 | ||
757c6eac | 75 | capab = s->readq(s, SDHC_CAPAB); |
bc13038f PMD |
76 | capab_sdma = FIELD_EX64(capab, SDHC_CAPAB, SDMA); |
77 | g_assert_cmpuint(capab_sdma, ==, supported); | |
78 | } | |
79 | ||
f18e6d50 PMD |
80 | static void check_capab_v3(QSDHCI *s, uint8_t version) |
81 | { | |
82 | uint64_t capab, capab_v3; | |
83 | ||
84 | if (version < 3) { | |
85 | /* before v3 those fields are RESERVED */ | |
757c6eac | 86 | capab = s->readq(s, SDHC_CAPAB); |
f18e6d50 PMD |
87 | capab_v3 = FIELD_EX64(capab, SDHC_CAPAB, SDR); |
88 | g_assert_cmpuint(capab_v3, ==, 0); | |
89 | capab_v3 = FIELD_EX64(capab, SDHC_CAPAB, DRIVER); | |
90 | g_assert_cmpuint(capab_v3, ==, 0); | |
91 | } | |
92 | } | |
93 | ||
757c6eac | 94 | static void test_registers(void *obj, void *data, QGuestAllocator *alloc) |
8640cc11 | 95 | { |
757c6eac | 96 | QSDHCI *s = obj; |
8640cc11 | 97 | |
757c6eac EGE |
98 | check_specs_version(s, s->props.version); |
99 | check_capab_capareg(s, s->props.capab.reg); | |
556f9aca | 100 | check_capab_readonly(s); |
757c6eac EGE |
101 | check_capab_v3(s, s->props.version); |
102 | check_capab_sdma(s, s->props.capab.sdma); | |
103 | check_capab_baseclock(s, s->props.baseclock); | |
8640cc11 PMD |
104 | } |
105 | ||
757c6eac | 106 | static void register_sdhci_test(void) |
8640cc11 | 107 | { |
757c6eac | 108 | qos_add_test("registers", "sdhci", test_registers, NULL); |
8640cc11 | 109 | } |
757c6eac EGE |
110 | |
111 | libqos_init(register_sdhci_test); |