|
@@ -102,11 +102,14 @@ struct SDState {
|
|
uint32_t card_status;
|
|
uint32_t card_status;
|
|
uint8_t sd_status[64];
|
|
uint8_t sd_status[64];
|
|
|
|
|
|
- /* Configurable properties */
|
|
|
|
|
|
+ /* Static properties */
|
|
|
|
+
|
|
uint8_t spec_version;
|
|
uint8_t spec_version;
|
|
BlockBackend *blk;
|
|
BlockBackend *blk;
|
|
bool spi;
|
|
bool spi;
|
|
|
|
|
|
|
|
+ /* Runtime changeables */
|
|
|
|
+
|
|
uint32_t mode; /* current card mode, one of SDCardModes */
|
|
uint32_t mode; /* current card mode, one of SDCardModes */
|
|
int32_t state; /* current card state, one of SDCardStates */
|
|
int32_t state; /* current card state, one of SDCardStates */
|
|
uint32_t vhs;
|
|
uint32_t vhs;
|
|
@@ -251,11 +254,11 @@ static const int sd_cmd_class[SDMMC_CMD_MAX] = {
|
|
7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8,
|
|
7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8,
|
|
};
|
|
};
|
|
|
|
|
|
-static uint8_t sd_crc7(void *message, size_t width)
|
|
|
|
|
|
+static uint8_t sd_crc7(const void *message, size_t width)
|
|
{
|
|
{
|
|
int i, bit;
|
|
int i, bit;
|
|
uint8_t shift_reg = 0x00;
|
|
uint8_t shift_reg = 0x00;
|
|
- uint8_t *msg = (uint8_t *) message;
|
|
|
|
|
|
+ const uint8_t *msg = (const uint8_t *)message;
|
|
|
|
|
|
for (i = 0; i < width; i ++, msg ++)
|
|
for (i = 0; i < width; i ++, msg ++)
|
|
for (bit = 7; bit >= 0; bit --) {
|
|
for (bit = 7; bit >= 0; bit --) {
|
|
@@ -267,11 +270,11 @@ static uint8_t sd_crc7(void *message, size_t width)
|
|
return shift_reg;
|
|
return shift_reg;
|
|
}
|
|
}
|
|
|
|
|
|
-static uint16_t sd_crc16(void *message, size_t width)
|
|
|
|
|
|
+static uint16_t sd_crc16(const void *message, size_t width)
|
|
{
|
|
{
|
|
int i, bit;
|
|
int i, bit;
|
|
uint16_t shift_reg = 0x0000;
|
|
uint16_t shift_reg = 0x0000;
|
|
- uint16_t *msg = (uint16_t *) message;
|
|
|
|
|
|
+ const uint16_t *msg = (const uint16_t *)message;
|
|
width <<= 1;
|
|
width <<= 1;
|
|
|
|
|
|
for (i = 0; i < width; i ++, msg ++)
|
|
for (i = 0; i < width; i ++, msg ++)
|
|
@@ -824,6 +827,7 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
|
|
sd->data[12] = 0x80; /* Supported group 1 functions */
|
|
sd->data[12] = 0x80; /* Supported group 1 functions */
|
|
sd->data[13] = 0x03;
|
|
sd->data[13] = 0x03;
|
|
|
|
|
|
|
|
+ memset(&sd->data[14], 0, 3);
|
|
for (i = 0; i < 6; i ++) {
|
|
for (i = 0; i < 6; i ++) {
|
|
new_func = (arg >> (i * 4)) & 0x0f;
|
|
new_func = (arg >> (i * 4)) & 0x0f;
|
|
if (mode && new_func != 0x0f)
|
|
if (mode && new_func != 0x0f)
|
|
@@ -1676,7 +1680,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
|
|
return sd_illegal;
|
|
return sd_illegal;
|
|
}
|
|
}
|
|
|
|
|
|
-static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
|
|
|
|
|
|
+static int cmd_valid_while_locked(SDState *sd, const uint8_t cmd)
|
|
{
|
|
{
|
|
/* Valid commands in locked state:
|
|
/* Valid commands in locked state:
|
|
* basic class (0)
|
|
* basic class (0)
|
|
@@ -1687,13 +1691,12 @@ static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
|
|
* Anything else provokes an "illegal command" response.
|
|
* Anything else provokes an "illegal command" response.
|
|
*/
|
|
*/
|
|
if (sd->expecting_acmd) {
|
|
if (sd->expecting_acmd) {
|
|
- return req->cmd == 41 || req->cmd == 42;
|
|
|
|
|
|
+ return cmd == 41 || cmd == 42;
|
|
}
|
|
}
|
|
- if (req->cmd == 16 || req->cmd == 55) {
|
|
|
|
|
|
+ if (cmd == 16 || cmd == 55) {
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- return sd_cmd_class[req->cmd] == 0
|
|
|
|
- || sd_cmd_class[req->cmd] == 7;
|
|
|
|
|
|
+ return sd_cmd_class[cmd] == 0 || sd_cmd_class[cmd] == 7;
|
|
}
|
|
}
|
|
|
|
|
|
int sd_do_command(SDState *sd, SDRequest *req,
|
|
int sd_do_command(SDState *sd, SDRequest *req,
|
|
@@ -1719,7 +1722,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
|
|
}
|
|
}
|
|
|
|
|
|
if (sd->card_status & CARD_IS_LOCKED) {
|
|
if (sd->card_status & CARD_IS_LOCKED) {
|
|
- if (!cmd_valid_while_locked(sd, req)) {
|
|
|
|
|
|
+ if (!cmd_valid_while_locked(sd, req->cmd)) {
|
|
sd->card_status |= ILLEGAL_COMMAND;
|
|
sd->card_status |= ILLEGAL_COMMAND;
|
|
sd->expecting_acmd = false;
|
|
sd->expecting_acmd = false;
|
|
qemu_log_mask(LOG_GUEST_ERROR, "SD: Card is locked\n");
|
|
qemu_log_mask(LOG_GUEST_ERROR, "SD: Card is locked\n");
|
|
@@ -1980,7 +1983,7 @@ uint8_t sd_read_byte(SDState *sd)
|
|
{
|
|
{
|
|
/* TODO: Append CRCs */
|
|
/* TODO: Append CRCs */
|
|
uint8_t ret;
|
|
uint8_t ret;
|
|
- int io_len;
|
|
|
|
|
|
+ uint32_t io_len;
|
|
|
|
|
|
if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
|
|
if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
|
|
return 0x00;
|
|
return 0x00;
|