diff options
Diffstat (limited to 'hw/sd/sd.c')
-rw-r--r-- | hw/sd/sd.c | 150 |
1 files changed, 46 insertions, 104 deletions
@@ -37,9 +37,8 @@ #include "qemu/cutils.h" #include "hw/irq.h" #include "hw/registerfields.h" -#include "sysemu/block-backend.h" +#include "system/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" @@ -71,6 +70,14 @@ typedef enum { sd_illegal = -2, } sd_rsp_type_t; +typedef enum { + sd_spi, + sd_bc, /* broadcast -- no response */ + sd_bcr, /* broadcast with response */ + sd_ac, /* addressed -- no data transfer */ + sd_adtc, /* addressed with data transfer */ +} sd_cmd_type_t; + enum SDCardModes { sd_inactive, sd_card_identification_mode, @@ -112,10 +119,6 @@ typedef struct SDProto { struct SDState { DeviceState parent_obj; - /* If true, created by sd_init() for a non-qdevified caller */ - /* TODO purge them with fire */ - bool me_no_qdev_me_kill_mammoth_with_rocks; - /* SD Memory Card Registers */ uint32_t ocr; uint8_t scr[8]; @@ -169,10 +172,7 @@ struct SDState { uint32_t data_offset; size_t data_size; uint8_t data[512]; - qemu_irq readonly_cb; - qemu_irq inserted_cb; QEMUTimer *ocr_power_timer; - bool enable; uint8_t dat_lines; bool cmd_line; }; @@ -291,12 +291,12 @@ static const char *sd_acmd_name(SDState *sd, uint8_t cmd) static uint8_t sd_get_dat_lines(SDState *sd) { - return sd->enable ? sd->dat_lines : 0; + return sd->dat_lines; } static bool sd_get_cmd_line(SDState *sd) { - return sd->enable ? sd->cmd_line : false; + return sd->cmd_line; } static void sd_set_voltage(SDState *sd, uint16_t millivolts) @@ -774,19 +774,12 @@ static uint32_t sd_blk_len(SDState *sd) */ static uint32_t sd_bootpart_offset(SDState *sd) { - bool partitions_enabled; unsigned partition_access; if (!sd->boot_part_size || !sd_is_emmc(sd)) { return 0; } - partitions_enabled = sd->ext_csd[EXT_CSD_PART_CONFIG] - & EXT_CSD_PART_CONFIG_EN_MASK; - if (!partitions_enabled) { - return 0; - } - partition_access = sd->ext_csd[EXT_CSD_PART_CONFIG] & EXT_CSD_PART_CONFIG_ACC_MASK; switch (partition_access) { @@ -833,7 +826,9 @@ static void sd_reset(DeviceState *dev) sect = 0; } size = sect << HWBLOCK_SHIFT; - size -= sd_bootpart_offset(sd); + if (sd_is_emmc(sd)) { + size -= sd->boot_part_size * 2; + } sect = sd_addr_to_wpnum(size) + 1; @@ -889,17 +884,10 @@ static void sd_cardchange(void *opaque, bool load, Error **errp) trace_sdcard_ejected(); } - if (sd->me_no_qdev_me_kill_mammoth_with_rocks) { - qemu_set_irq(sd->inserted_cb, inserted); - if (inserted) { - qemu_set_irq(sd->readonly_cb, readonly); - } - } else { - sdbus = SD_BUS(qdev_get_parent_bus(dev)); - sdbus_set_inserted(sdbus, inserted); - if (inserted) { - sdbus_set_readonly(sdbus, readonly); - } + sdbus = SD_BUS(qdev_get_parent_bus(dev)); + sdbus_set_inserted(sdbus, inserted); + if (inserted) { + sdbus_set_readonly(sdbus, readonly); } } @@ -987,7 +975,7 @@ static const VMStateDescription sd_vmstate = { VMSTATE_UINT32(data_offset, SDState), VMSTATE_UINT8_ARRAY(data, SDState, 512), VMSTATE_UNUSED_V(1, 512), - VMSTATE_BOOL(enable, SDState), + VMSTATE_UNUSED(1), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription * const []) { @@ -997,48 +985,6 @@ static const VMStateDescription sd_vmstate = { }, }; -/* Legacy initialization function for use by non-qdevified callers */ -SDState *sd_init(BlockBackend *blk, bool is_spi) -{ - Object *obj; - DeviceState *dev; - SDState *sd; - Error *err = NULL; - - obj = object_new(is_spi ? TYPE_SD_CARD_SPI : TYPE_SD_CARD); - dev = DEVICE(obj); - if (!qdev_prop_set_drive_err(dev, "drive", blk, &err)) { - error_reportf_err(err, "sd_init failed: "); - return NULL; - } - - /* - * Realizing the device properly would put it into the QOM - * composition tree even though it is not plugged into an - * appropriate bus. That's a no-no. Hide the device from - * QOM/qdev, and call its qdev realize callback directly. - */ - object_ref(obj); - object_unparent(obj); - sd_realize(dev, &err); - if (err) { - error_reportf_err(err, "sd_init failed: "); - return NULL; - } - - sd = SD_CARD(dev); - sd->me_no_qdev_me_kill_mammoth_with_rocks = true; - return sd; -} - -void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert) -{ - sd->readonly_cb = readonly; - sd->inserted_cb = insert; - qemu_set_irq(readonly, sd->blk ? !blk_is_writable(sd->blk) : 0); - qemu_set_irq(insert, sd->blk ? blk_is_inserted(sd->blk) : 0); -} - static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len) { trace_sdcard_read_block(addr, len); @@ -2193,13 +2139,13 @@ static bool cmd_valid_while_locked(SDState *sd, unsigned cmd) return cmd_class == 0 || cmd_class == 7; } -int sd_do_command(SDState *sd, SDRequest *req, - uint8_t *response) { +static int sd_do_command(SDState *sd, SDRequest *req, + uint8_t *response) { int last_state; sd_rsp_type_t rtype; int rsplen; - if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable) { + if (!sd->blk || !blk_is_inserted(sd->blk)) { return 0; } @@ -2346,12 +2292,13 @@ static bool sd_generic_read_byte(SDState *sd, uint8_t *value) return false; } -void sd_write_byte(SDState *sd, uint8_t value) +static void sd_write_byte(SDState *sd, uint8_t value) { int i; - if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable) + if (!sd->blk || !blk_is_inserted(sd->blk)) { return; + } if (sd->state != sd_receivingdata_state) { qemu_log_mask(LOG_GUEST_ERROR, @@ -2475,23 +2422,26 @@ void sd_write_byte(SDState *sd, uint8_t value) } } -uint8_t sd_read_byte(SDState *sd) +static uint8_t sd_read_byte(SDState *sd) { /* TODO: Append CRCs */ + const uint8_t dummy_byte = 0x00; uint8_t ret; uint32_t io_len; - if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable) - return 0x00; + if (!sd->blk || !blk_is_inserted(sd->blk)) { + return dummy_byte; + } if (sd->state != sd_sendingdata_state) { qemu_log_mask(LOG_GUEST_ERROR, "%s: not in Sending-Data state\n", __func__); - return 0x00; + return dummy_byte; } - if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION)) - return 0x00; + if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION)) { + return dummy_byte; + } io_len = sd_blk_len(sd); @@ -2517,7 +2467,7 @@ uint8_t sd_read_byte(SDState *sd) if (sd->data_offset == 0) { if (!address_in_range(sd, "READ_MULTIPLE_BLOCK", sd->data_start, io_len)) { - return 0x00; + return dummy_byte; } sd_blk_read(sd, sd->data_start, io_len); } @@ -2538,7 +2488,9 @@ uint8_t sd_read_byte(SDState *sd) break; default: - g_assert_not_reached(); + qemu_log_mask(LOG_GUEST_ERROR, "%s: DAT read illegal for command %s\n", + __func__, sd->last_cmd_name); + return dummy_byte; } return ret; @@ -2554,11 +2506,6 @@ static bool sd_data_ready(SDState *sd) return sd->state == sd_sendingdata_state; } -void sd_enable(SDState *sd, bool enable) -{ - sd->enable = enable; -} - static const SDProto sd_proto_spi = { .name = "SPI", .cmd = { @@ -2718,7 +2665,6 @@ static void sd_instance_init(Object *obj) sd->proto = sc->proto; sd->last_cmd_name = "UNSET"; - sd->enable = true; sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sd_ocr_powerup, sd); } @@ -2791,31 +2737,28 @@ static void emmc_realize(DeviceState *dev, Error **errp) sd_realize(dev, errp); } -static Property sdmmc_common_properties[] = { +static const Property sdmmc_common_properties[] = { DEFINE_PROP_DRIVE("drive", SDState, blk), - DEFINE_PROP_END_OF_LIST() }; -static Property sd_properties[] = { +static const Property sd_properties[] = { DEFINE_PROP_UINT8("spec_version", SDState, spec_version, SD_PHY_SPECv3_01_VERS), - DEFINE_PROP_END_OF_LIST() }; -static Property emmc_properties[] = { +static const Property emmc_properties[] = { DEFINE_PROP_UINT64("boot-partition-size", SDState, boot_part_size, 0), DEFINE_PROP_UINT8("boot-config", SDState, boot_config, 0x0), - DEFINE_PROP_END_OF_LIST() }; -static void sdmmc_common_class_init(ObjectClass *klass, void *data) +static void sdmmc_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); device_class_set_props(dc, sdmmc_common_properties); dc->vmsd = &sd_vmstate; - dc->reset = sd_reset; + device_class_set_legacy_reset(dc, sd_reset); dc->bus_type = TYPE_SD_BUS; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); @@ -2827,12 +2770,11 @@ static void sdmmc_common_class_init(ObjectClass *klass, void *data) sc->read_byte = sd_read_byte; sc->receive_ready = sd_receive_ready; sc->data_ready = sd_data_ready; - sc->enable = sd_enable; sc->get_inserted = sd_get_inserted; sc->get_readonly = sd_get_readonly; } -static void sd_class_init(ObjectClass *klass, void *data) +static void sd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); @@ -2851,7 +2793,7 @@ static void sd_class_init(ObjectClass *klass, void *data) * board to ensure that ssi transfers only occur when the chip select * is asserted. */ -static void sd_spi_class_init(ObjectClass *klass, void *data) +static void sd_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); @@ -2860,7 +2802,7 @@ static void sd_spi_class_init(ObjectClass *klass, void *data) sc->proto = &sd_proto_spi; } -static void emmc_class_init(ObjectClass *klass, void *data) +static void emmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); |