aboutsummaryrefslogtreecommitdiff
path: root/hw/sd/sd.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-08-22 23:53:08 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-08-22 23:53:08 +0100
commitd7df0ceee0fd2e512cd214a9074ebeeb40da3099 (patch)
tree560af189a2bad02766cfff6170621430b9905f23 /hw/sd/sd.c
parent3a52b42c949ddd6ebb9f7e86ad83243bd1d52d9e (diff)
parent6d2d4069c47e23b9e3913f9c8204fd0edcb99fb3 (diff)
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/sd-next-20200821' into staging
SD/MMC patches - Convert legacy SD host controller to the SDBus API - Move legacy API to a separate "sdcard_legacy.h" header - Introduce methods to access multiple bytes on SDBus data lines - Fix 'switch function' group location - Fix SDSC maximum card size (2GB) CI jobs result: https://gitlab.com/philmd/qemu/-/pipelines/180605963 # gpg: Signature made Fri 21 Aug 2020 18:27:50 BST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * remotes/philmd-gitlab/tags/sd-next-20200821: (23 commits) hw/sd: Correct the maximum size of a Standard Capacity SD Memory Card hw/sd: Fix incorrect populated function switch status data structure hw/sd: Use sdbus_read_data() instead of sdbus_read_byte() when possible hw/sd: Add sdbus_read_data() to read multiples bytes on the data line hw/sd: Use sdbus_write_data() instead of sdbus_write_byte when possible hw/sd: Add sdbus_write_data() to write multiples bytes on the data line hw/sd: Rename sdbus_read_data() as sdbus_read_byte() hw/sd: Rename sdbus_write_data() as sdbus_write_byte() hw/sd: Rename read/write_data() as read/write_byte() hw/sd: Move sdcard legacy API to 'hw/sd/sdcard_legacy.h' hw/sd/sdcard: Make sd_data_ready() static hw/sd/pl181: Replace disabled fprintf()s by trace events hw/sd/pl181: Do not create SD card within the SD host controller hw/sd/pl181: Expose a SDBus and connect the SDCard to it hw/sd/pl181: Use named GPIOs hw/sd/pl181: Add TODO to use Fifo32 API hw/sd/pl181: Rename pl181_send_command() as pl181_do_command() hw/sd/pl181: Replace fprintf(stderr, "*\n") with error_report() hw/sd/milkymist: Do not create SD card within the SD host controller hw/sd/milkymist: Create the SDBus at init() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/sd/sd.c')
-rw-r--r--hw/sd/sd.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index fad9cf1ee7..483c4f1720 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -37,6 +37,7 @@
#include "hw/registerfields.h"
#include "sysemu/block-backend.h"
#include "hw/sd/sd.h"
+#include "hw/sd/sdcard_legacy.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/bitmap.h"
@@ -50,6 +51,8 @@
//#define DEBUG_SD 1
+#define SDSC_MAX_CAPACITY (2 * GiB)
+
typedef enum {
sd_r0 = 0, /* no response */
sd_r1, /* normal response command */
@@ -313,7 +316,7 @@ static void sd_ocr_powerup(void *opaque)
/* card power-up OK */
sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
- if (sd->size > 1 * GiB) {
+ if (sd->size > SDSC_MAX_CAPACITY) {
sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
}
}
@@ -385,7 +388,7 @@ static void sd_set_csd(SDState *sd, uint64_t size)
uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
- if (size <= 1 * GiB) { /* Standard Capacity SD */
+ if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
sd->csd[0] = 0x00; /* CSD structure */
sd->csd[1] = 0x26; /* Data read access-time-1 */
sd->csd[2] = 0x00; /* Data read access-time-2 */
@@ -806,11 +809,12 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
sd->data[11] = 0x43;
sd->data[12] = 0x80; /* Supported group 1 functions */
sd->data[13] = 0x03;
+
for (i = 0; i < 6; i ++) {
new_func = (arg >> (i * 4)) & 0x0f;
if (mode && new_func != 0x0f)
sd->function_group[i] = new_func;
- sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
+ sd->data[16 - (i >> 1)] |= new_func << ((i % 2) * 4);
}
memset(&sd->data[17], 0, 47);
stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
@@ -1808,7 +1812,7 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
#define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len)
#define APP_WRITE_BLOCK(a, len)
-void sd_write_data(SDState *sd, uint8_t value)
+void sd_write_byte(SDState *sd, uint8_t value)
{
int i;
@@ -1817,7 +1821,7 @@ void sd_write_data(SDState *sd, uint8_t value)
if (sd->state != sd_receivingdata_state) {
qemu_log_mask(LOG_GUEST_ERROR,
- "sd_write_data: not in Receiving-Data state\n");
+ "%s: not in Receiving-Data state\n", __func__);
return;
}
@@ -1939,7 +1943,7 @@ void sd_write_data(SDState *sd, uint8_t value)
break;
default:
- qemu_log_mask(LOG_GUEST_ERROR, "sd_write_data: unknown command\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: unknown command\n", __func__);
break;
}
}
@@ -1958,7 +1962,7 @@ static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
};
-uint8_t sd_read_data(SDState *sd)
+uint8_t sd_read_byte(SDState *sd)
{
/* TODO: Append CRCs */
uint8_t ret;
@@ -1969,7 +1973,7 @@ uint8_t sd_read_data(SDState *sd)
if (sd->state != sd_sendingdata_state) {
qemu_log_mask(LOG_GUEST_ERROR,
- "sd_read_data: not in Sending-Data state\n");
+ "%s: not in Sending-Data state\n", __func__);
return 0x00;
}
@@ -2075,14 +2079,14 @@ uint8_t sd_read_data(SDState *sd)
break;
default:
- qemu_log_mask(LOG_GUEST_ERROR, "sd_read_data: unknown command\n");
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: unknown command\n", __func__);
return 0x00;
}
return ret;
}
-bool sd_data_ready(SDState *sd)
+static bool sd_data_ready(SDState *sd)
{
return sd->state == sd_sendingdata_state;
}
@@ -2191,8 +2195,8 @@ static void sd_class_init(ObjectClass *klass, void *data)
sc->get_dat_lines = sd_get_dat_lines;
sc->get_cmd_line = sd_get_cmd_line;
sc->do_command = sd_do_command;
- sc->write_data = sd_write_data;
- sc->read_data = sd_read_data;
+ sc->write_byte = sd_write_byte;
+ sc->read_byte = sd_read_byte;
sc->data_ready = sd_data_ready;
sc->enable = sd_enable;
sc->get_inserted = sd_get_inserted;