diff options
Diffstat (limited to 'hw/sd/milkymist-memcard.c')
| -rw-r--r-- | hw/sd/milkymist-memcard.c | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c index 341da88552..5570c1e9a0 100644 --- a/hw/sd/milkymist-memcard.c +++ b/hw/sd/milkymist-memcard.c @@ -22,11 +22,12 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "trace.h" -#include "qemu/error-report.h" +#include "include/qapi/error.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "hw/sd/sd.h" @@ -68,7 +69,7 @@ struct MilkymistMemcardState { SysBusDevice parent_obj; MemoryRegion regs_region; - SDState *card; + SDBus sdbus; int command_write_ptr; int response_read_ptr; @@ -104,7 +105,7 @@ static void memcard_sd_command(MilkymistMemcardState *s) req.crc = s->command[5]; s->response[0] = req.cmd; - s->response_len = sd_do_command(s->card, &req, s->response+1); + s->response_len = sdbus_do_command(&s->sdbus, &req, s->response + 1); s->response_read_ptr = 0; if (s->response_len == 16) { @@ -138,8 +139,8 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, } else { r = s->response[s->response_read_ptr++]; if (s->response_read_ptr > s->response_len) { - error_report("milkymist_memcard: " - "read more cmd bytes than available. Clipping."); + qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: " + "read more cmd bytes than available. Clipping."); s->response_read_ptr = 0; } } @@ -149,10 +150,10 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, r = 0xffffffff; } else { r = 0; - r |= sd_read_data(s->card) << 24; - r |= sd_read_data(s->card) << 16; - r |= sd_read_data(s->card) << 8; - r |= sd_read_data(s->card); + r |= sdbus_read_data(&s->sdbus) << 24; + r |= sdbus_read_data(&s->sdbus) << 16; + r |= sdbus_read_data(&s->sdbus) << 8; + r |= sdbus_read_data(&s->sdbus); } break; case R_CLK2XDIV: @@ -163,8 +164,9 @@ static uint64_t memcard_read(void *opaque, hwaddr addr, break; default: - error_report("milkymist_memcard: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); + qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " + "read access to unknown register 0x%" HWADDR_PRIx "\n", + addr << 2); break; } @@ -205,10 +207,10 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value, if (!s->enabled) { break; } - sd_write_data(s->card, (value >> 24) & 0xff); - sd_write_data(s->card, (value >> 16) & 0xff); - sd_write_data(s->card, (value >> 8) & 0xff); - sd_write_data(s->card, value & 0xff); + sdbus_write_data(&s->sdbus, (value >> 24) & 0xff); + sdbus_write_data(&s->sdbus, (value >> 16) & 0xff); + sdbus_write_data(&s->sdbus, (value >> 8) & 0xff); + sdbus_write_data(&s->sdbus, value & 0xff); break; case R_ENABLE: s->regs[addr] = value; @@ -220,8 +222,9 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value, break; default: - error_report("milkymist_memcard: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); + qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " + "write access to unknown register 0x%" HWADDR_PRIx " " + "(value 0x%" PRIx64 ")\n", addr << 2, value); break; } } @@ -248,33 +251,41 @@ static void milkymist_memcard_reset(DeviceState *d) for (i = 0; i < R_MAX; i++) { s->regs[i] = 0; } - /* Since we're still using the legacy SD API the card is not plugged - * into any bus, and we must reset it manually. - */ - device_reset(DEVICE(s->card)); } -static int milkymist_memcard_init(SysBusDevice *dev) +static void milkymist_memcard_init(Object *obj) +{ + MilkymistMemcardState *s = MILKYMIST_MEMCARD(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s, + "milkymist-memcard", R_MAX * 4); + sysbus_init_mmio(dev, &s->regs_region); +} + +static void milkymist_memcard_realize(DeviceState *dev, Error **errp) { MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev); - DriveInfo *dinfo; + DeviceState *carddev; BlockBackend *blk; + DriveInfo *dinfo; + Error *err = NULL; + + qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, + dev, "sd-bus"); + /* Create and plug in the sd card */ /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_SD); blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL; - s->card = sd_init(blk, false); - if (s->card == NULL) { - return -1; + carddev = qdev_create(&s->sdbus.qbus, TYPE_SD_CARD); + qdev_prop_set_drive(carddev, "drive", blk, &err); + object_property_set_bool(OBJECT(carddev), true, "realized", &err); + if (err) { + error_setg(errp, "failed to init SD card: %s", error_get_pretty(err)); + return; } - s->enabled = blk && blk_is_inserted(blk); - - memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s, - "milkymist-memcard", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; } static const VMStateDescription vmstate_milkymist_memcard = { @@ -297,9 +308,8 @@ static const VMStateDescription vmstate_milkymist_memcard = { static void milkymist_memcard_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_memcard_init; + dc->realize = milkymist_memcard_realize; dc->reset = milkymist_memcard_reset; dc->vmsd = &vmstate_milkymist_memcard; /* Reason: init() method uses drive_get_next() */ @@ -310,6 +320,7 @@ static const TypeInfo milkymist_memcard_info = { .name = TYPE_MILKYMIST_MEMCARD, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MilkymistMemcardState), + .instance_init = milkymist_memcard_init, .class_init = milkymist_memcard_class_init, }; |