2 * MMC Host Controller Commands
4 * Copyright (c) 2021 Google LLC
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "qemu/osdep.h"
18 #include "sdhci-cmd.h"
19 #include "../libqtest.h"
21 static ssize_t
read_fifo(QTestState
*qts
, uint64_t reg
, char *msg
, size_t count
)
27 while (index
< count
) {
32 msg_frag
= qtest_readl(qts
, reg
);
34 msg
[index
] = msg_frag
& mask
;
35 if (msg
[index
++] == 0) {
45 static void write_fifo(QTestState
*qts
, uint64_t reg
, const char *msg
,
52 while (index
< count
) {
59 while (frag_i
< size
) {
60 msg_frag
|= ((uint32_t)msg
[index
++]) << (frag_i
* 8);
63 qtest_writel(qts
, reg
, msg_frag
);
67 static void fill_block(QTestState
*qts
, uint64_t reg
, int count
)
69 while (--count
>= 0) {
70 qtest_writel(qts
, reg
, 0);
74 void sdhci_cmd_regs(QTestState
*qts
, uint64_t base_addr
, uint16_t blksize
,
75 uint16_t blkcnt
, uint32_t argument
, uint16_t trnmod
,
78 qtest_writew(qts
, base_addr
+ SDHC_BLKSIZE
, blksize
);
79 qtest_writew(qts
, base_addr
+ SDHC_BLKCNT
, blkcnt
);
80 qtest_writel(qts
, base_addr
+ SDHC_ARGUMENT
, argument
);
81 qtest_writew(qts
, base_addr
+ SDHC_TRNMOD
, trnmod
);
82 qtest_writew(qts
, base_addr
+ SDHC_CMDREG
, cmdreg
);
85 ssize_t
sdhci_read_cmd(QTestState
*qts
, uint64_t base_addr
, char *msg
,
88 sdhci_cmd_regs(qts
, base_addr
, count
, 1, 0,
89 SDHC_TRNS_MULTI
| SDHC_TRNS_READ
| SDHC_TRNS_BLK_CNT_EN
,
90 SDHC_READ_MULTIPLE_BLOCK
| SDHC_CMD_DATA_PRESENT
);
92 /* read sd fifo_buffer */
93 ssize_t bytes_read
= read_fifo(qts
, base_addr
+ SDHC_BDATA
, msg
, count
);
95 sdhci_cmd_regs(qts
, base_addr
, 0, 0, 0,
96 SDHC_TRNS_MULTI
| SDHC_TRNS_READ
| SDHC_TRNS_BLK_CNT_EN
,
97 SDHC_STOP_TRANSMISSION
);
102 void sdhci_write_cmd(QTestState
*qts
, uint64_t base_addr
, const char *msg
,
103 size_t count
, size_t blksize
)
105 sdhci_cmd_regs(qts
, base_addr
, blksize
, 1, 0,
106 SDHC_TRNS_MULTI
| SDHC_TRNS_WRITE
| SDHC_TRNS_BLK_CNT_EN
,
107 SDHC_WRITE_MULTIPLE_BLOCK
| SDHC_CMD_DATA_PRESENT
);
109 /* write to sd fifo_buffer */
110 write_fifo(qts
, base_addr
+ SDHC_BDATA
, msg
, count
);
111 fill_block(qts
, base_addr
+ SDHC_BDATA
, (blksize
- count
) / 4);
113 sdhci_cmd_regs(qts
, base_addr
, 0, 0, 0,
114 SDHC_TRNS_MULTI
| SDHC_TRNS_WRITE
| SDHC_TRNS_BLK_CNT_EN
,
115 SDHC_STOP_TRANSMISSION
);