[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object
From: |
Igor Mitsyanko |
Subject: |
[Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object |
Date: |
Mon, 02 Apr 2012 18:28:41 +0400 |
A straightforward conversion of SD card implementation to a proper QEMU object.
Signed-off-by: Igor Mitsyanko <address@hidden>
---
hw/milkymist-memcard.c | 25 +++++++++++++++----------
hw/omap_mmc.c | 29 +++++++++++++++++------------
hw/pl181.c | 14 ++++++++------
hw/pxa2xx_mmci.c | 22 ++++++++++++++--------
hw/sd.c | 48 +++++++++++++++++++++++++++++++++++++-----------
hw/sd.h | 30 ++++++++++++++++++++++--------
hw/ssi-sd.c | 12 +++++++-----
7 files changed, 120 insertions(+), 60 deletions(-)
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
index 3515c3c..8a2b9b8 100644
--- a/hw/milkymist-memcard.c
+++ b/hw/milkymist-memcard.c
@@ -97,7 +97,8 @@ 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 =
+ SD_GET_CLASS(s->card)->do_command(s->card, &req, s->response + 1);
s->response_read_ptr = 0;
if (s->response_len == 16) {
@@ -141,11 +142,12 @@ static uint64_t memcard_read(void *opaque,
target_phys_addr_t addr,
if (!s->enabled) {
r = 0xffffffff;
} else {
+ SDClass *sd_class = SD_GET_CLASS(s->card);
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 |= sd_class->read_data(s->card) << 24;
+ r |= sd_class->read_data(s->card) << 16;
+ r |= sd_class->read_data(s->card) << 8;
+ r |= sd_class->read_data(s->card);
}
break;
case R_CLK2XDIV:
@@ -170,6 +172,7 @@ static void memcard_write(void *opaque, target_phys_addr_t
addr, uint64_t value,
unsigned size)
{
MilkymistMemcardState *s = opaque;
+ SDClass *sd_class;
trace_milkymist_memcard_memory_write(addr, value);
@@ -198,10 +201,11 @@ static void memcard_write(void *opaque,
target_phys_addr_t 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);
+ sd_class = SD_GET_CLASS(s->card);
+ sd_class->write_data(s->card, (value >> 24) & 0xff);
+ sd_class->write_data(s->card, (value >> 16) & 0xff);
+ sd_class->write_data(s->card, (value >> 8) & 0xff);
+ sd_class->write_data(s->card, value & 0xff);
break;
case R_ENABLE:
s->regs[addr] = value;
@@ -249,8 +253,9 @@ static int milkymist_memcard_init(SysBusDevice *dev)
MilkymistMemcardState *s = FROM_SYSBUS(typeof(*s), dev);
DriveInfo *dinfo;
+ s->card = SD_CARD(object_new(TYPE_SD_CARD));
dinfo = drive_get_next(IF_SD);
- s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
+ SD_GET_CLASS(s->card)->init(s->card, dinfo ? dinfo->bdrv : NULL, false);
s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
memory_region_init_io(&s->regs_region, &memcard_mmio_ops, s,
diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c
index aec0285..a16762e 100644
--- a/hw/omap_mmc.c
+++ b/hw/omap_mmc.c
@@ -138,7 +138,8 @@ static void omap_mmc_command(struct omap_mmc_s *host, int
cmd, int dir,
request.arg = host->arg;
request.crc = 0; /* FIXME */
- rsplen = sd_do_command(host->card, &request, response);
+ rsplen =
+ SD_GET_CLASS(host->card)->do_command(host->card, &request, response);
/* TODO: validate CRCs */
switch (resptype) {
@@ -219,6 +220,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int
cmd, int dir,
static void omap_mmc_transfer(struct omap_mmc_s *host)
{
+ SDClass *sd_class = SD_GET_CLASS(host->card);
uint8_t value;
if (!host->transfer)
@@ -229,10 +231,10 @@ static void omap_mmc_transfer(struct omap_mmc_s *host)
if (host->fifo_len > host->af_level)
break;
- value = sd_read_data(host->card);
+ value = sd_class->read_data(host->card);
host->fifo[(host->fifo_start + host->fifo_len) & 31] = value;
if (-- host->blen_counter) {
- value = sd_read_data(host->card);
+ value = sd_class->read_data(host->card);
host->fifo[(host->fifo_start + host->fifo_len) & 31] |=
value << 8;
host->blen_counter --;
@@ -244,10 +246,10 @@ static void omap_mmc_transfer(struct omap_mmc_s *host)
break;
value = host->fifo[host->fifo_start] & 0xff;
- sd_write_data(host->card, value);
+ sd_class->write_data(host->card, value);
if (-- host->blen_counter) {
value = host->fifo[host->fifo_start] >> 8;
- sd_write_data(host->card, value);
+ sd_class->write_data(host->card, value);
host->blen_counter --;
}
@@ -592,7 +594,8 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
memory_region_add_subregion(sysmem, base, &s->iomem);
/* Instantiate the storage */
- s->card = sd_init(bd, 0);
+ s->card = SD_CARD(object_new(TYPE_SD_CARD));
+ SD_GET_CLASS(s->card)->init(s->card, bd, false);
return s;
}
@@ -617,10 +620,11 @@ struct omap_mmc_s *omap2_mmc_init(struct
omap_target_agent_s *ta,
omap_l4_attach(ta, 0, &s->iomem);
/* Instantiate the storage */
- s->card = sd_init(bd, 0);
+ s->card = SD_CARD(object_new(TYPE_SD_CARD));
+ SD_GET_CLASS(s->card)->init(s->card, bd, false);
s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
- sd_set_cb(s->card, NULL, s->cdet);
+ SD_GET_CLASS(s->card)->set_cb(s->card, NULL, s->cdet);
return s;
}
@@ -628,14 +632,15 @@ struct omap_mmc_s *omap2_mmc_init(struct
omap_target_agent_s *ta,
void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
{
if (s->cdet) {
- sd_set_cb(s->card, ro, s->cdet);
+ SD_GET_CLASS(s->card)->set_cb(s->card, ro, s->cdet);
s->coverswitch = cover;
qemu_set_irq(cover, s->cdet_state);
- } else
- sd_set_cb(s->card, ro, cover);
+ } else {
+ SD_GET_CLASS(s->card)->set_cb(s->card, ro, cover);
+ }
}
void omap_mmc_enable(struct omap_mmc_s *s, int enable)
{
- sd_enable(s->card, enable);
+ SD_GET_CLASS(s->card)->enable(s->card, !!enable);
}
diff --git a/hw/pl181.c b/hw/pl181.c
index 7d91fbb..97d7d97 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -171,7 +171,7 @@ static void pl181_send_command(pl181_state *s)
request.cmd = s->cmd & PL181_CMD_INDEX;
request.arg = s->cmdarg;
DPRINTF("Command %d %08x\n", request.cmd, request.arg);
- rlen = sd_do_command(s->card, &request, response);
+ rlen = SD_GET_CLASS(s->card)->do_command(s->card, &request, response);
if (rlen < 0)
goto error;
if (s->cmd & PL181_CMD_RESPONSE) {
@@ -209,18 +209,19 @@ error:
static void pl181_fifo_run(pl181_state *s)
{
+ SDClass *sd_class = SD_GET_CLASS(s->card);
uint32_t bits;
uint32_t value = 0;
int n;
int is_read;
is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
- if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
+ if (s->datacnt != 0 && (!is_read || sd_class->data_ready(s->card))
&& !s->linux_hack) {
if (is_read) {
n = 0;
while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
- value |= (uint32_t)sd_read_data(s->card) << (n * 8);
+ value |= (uint32_t)sd_class->read_data(s->card) << (n * 8);
s->datacnt--;
n++;
if (n == 4) {
@@ -241,7 +242,7 @@ static void pl181_fifo_run(pl181_state *s)
}
n--;
s->datacnt--;
- sd_write_data(s->card, value & 0xff);
+ sd_class->write_data(s->card, value & 0xff);
value >>= 8;
}
}
@@ -469,7 +470,7 @@ static void pl181_reset(DeviceState *d)
s->mask[1] = 0;
/* We can assume our GPIO outputs have been wired up now */
- sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
+ SD_GET_CLASS(s->card)->set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
}
static int pl181_init(SysBusDevice *dev)
@@ -483,7 +484,8 @@ static int pl181_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq[1]);
qdev_init_gpio_out(&s->busdev.qdev, s->cardstatus, 2);
dinfo = drive_get_next(IF_SD);
- s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
+ s->card = SD_CARD(object_new(TYPE_SD_CARD));
+ SD_GET_CLASS(s->card)->init(s->card, dinfo ? dinfo->bdrv : NULL, false);
return 0;
}
diff --git a/hw/pxa2xx_mmci.c b/hw/pxa2xx_mmci.c
index b505a4c..ef796b1 100644
--- a/hw/pxa2xx_mmci.c
+++ b/hw/pxa2xx_mmci.c
@@ -117,25 +117,30 @@ static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
static void pxa2xx_mmci_fifo_update(PXA2xxMMCIState *s)
{
- if (!s->active)
+ SDClass *sd_class = SD_GET_CLASS(s->card);
+
+ if (!s->active) {
return;
+ }
if (s->cmdat & CMDAT_WR_RD) {
while (s->bytesleft && s->tx_len) {
- sd_write_data(s->card, s->tx_fifo[s->tx_start ++]);
+ sd_class->write_data(s->card, s->tx_fifo[s->tx_start++]);
s->tx_start &= 0x1f;
s->tx_len --;
s->bytesleft --;
}
- if (s->bytesleft)
+ if (s->bytesleft) {
s->intreq |= INT_TXFIFO_REQ;
- } else
+ }
+ } else {
while (s->bytesleft && s->rx_len < 32) {
s->rx_fifo[(s->rx_start + (s->rx_len ++)) & 0x1f] =
- sd_read_data(s->card);
+ sd_class->read_data(s->card);
s->bytesleft --;
s->intreq |= INT_RXFIFO_REQ;
}
+ }
if (!s->bytesleft) {
s->active = 0;
@@ -166,7 +171,7 @@ static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
request.arg = s->arg;
request.crc = 0; /* FIXME */
- rsplen = sd_do_command(s->card, &request, response);
+ rsplen = SD_GET_CLASS(s->card)->do_command(s->card, &request, response);
s->intreq |= INT_END_CMD;
memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
@@ -538,7 +543,8 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
memory_region_add_subregion(sysmem, base, &s->iomem);
/* Instantiate the actual storage */
- s->card = sd_init(bd, 0);
+ s->card = SD_CARD(object_new(TYPE_SD_CARD));
+ SD_GET_CLASS(s->card)->init(s->card, bd, false);
register_savevm(NULL, "pxa2xx_mmci", 0, 0,
pxa2xx_mmci_save, pxa2xx_mmci_load, s);
@@ -549,5 +555,5 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
qemu_irq coverswitch)
{
- sd_set_cb(s->card, readonly, coverswitch);
+ SD_GET_CLASS(s->card)->set_cb(s->card, readonly, coverswitch);
}
diff --git a/hw/sd.c b/hw/sd.c
index 20e10bb..1abd198 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -74,6 +74,8 @@ enum {
};
struct SDState {
+ Object parent_obj;
+
uint32_t mode;
int32_t state;
uint32_t ocr;
@@ -482,11 +484,8 @@ static const VMStateDescription sd_vmstate = {
whether card should be in SSI or MMC/SD mode. It is also up to the
board to ensure that ssi transfers only occur when the chip select
is asserted. */
-SDState *sd_init(BlockDriverState *bs, bool is_spi)
+static void sd_init(SDState *sd, BlockDriverState *bs, bool is_spi)
{
- SDState *sd;
-
- sd = (SDState *) g_malloc0(sizeof(SDState));
sd->buf = qemu_blockalign(bs, 512);
sd->spi = is_spi;
sd->enable = true;
@@ -496,10 +495,9 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi)
bdrv_set_dev_ops(sd->bdrv, &sd_block_ops, sd);
}
vmstate_register(NULL, -1, &sd_vmstate, sd);
- return sd;
}
-void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
+static void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
{
sd->readonly_cb = readonly;
sd->inserted_cb = insert;
@@ -1334,7 +1332,7 @@ static int cmd_valid_while_locked(SDState *sd, SDRequest
*req)
return sd_cmd_class[req->cmd] == 0 || sd_cmd_class[req->cmd] == 7;
}
-int sd_do_command(SDState *sd, SDRequest *req,
+static int sd_do_command(SDState *sd, SDRequest *req,
uint8_t *response) {
int last_state;
sd_rsp_type_t rtype;
@@ -1502,7 +1500,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)
+static void sd_write_data(SDState *sd, uint8_t value)
{
int i;
@@ -1626,7 +1624,7 @@ void sd_write_data(SDState *sd, uint8_t value)
}
}
-uint8_t sd_read_data(SDState *sd)
+static uint8_t sd_read_data(SDState *sd)
{
/* TODO: Append CRCs */
uint8_t ret;
@@ -1745,12 +1743,40 @@ uint8_t sd_read_data(SDState *sd)
return ret;
}
-bool sd_data_ready(SDState *sd)
+static bool sd_data_ready(SDState *sd)
{
return sd->state == sd_sendingdata_state;
}
-void sd_enable(SDState *sd, bool enable)
+static void sd_enable(SDState *sd, bool enable)
{
sd->enable = enable;
}
+
+static void sd_class_init(ObjectClass *class, void *data)
+{
+ SDClass *k = SD_CLASS(class);
+
+ k->init = sd_init;
+ k->set_cb = sd_set_cb;
+ k->do_command = sd_do_command;
+ k->data_ready = sd_data_ready;
+ k->read_data = sd_read_data;
+ k->write_data = sd_write_data;
+ k->enable = sd_enable;
+}
+
+static TypeInfo sd_type_info = {
+ .name = TYPE_SD_CARD,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(SDState),
+ .class_init = sd_class_init,
+ .class_size = sizeof(SDClass)
+};
+
+static void sd_register_type(void)
+{
+ type_register_static(&sd_type_info);
+}
+
+type_init(sd_register_type)
diff --git a/hw/sd.h b/hw/sd.h
index 4eb9679..63b8203 100644
--- a/hw/sd.h
+++ b/hw/sd.h
@@ -29,6 +29,9 @@
#ifndef __hw_sd_h
#define __hw_sd_h 1
+#include "qemu-common.h"
+#include "qemu/object.h"
+
#define OUT_OF_RANGE (1 << 31)
#define ADDRESS_ERROR (1 << 30)
#define BLOCK_LEN_ERROR (1 << 29)
@@ -67,13 +70,24 @@ typedef struct {
typedef struct SDState SDState;
-SDState *sd_init(BlockDriverState *bs, bool is_spi);
-int sd_do_command(SDState *sd, SDRequest *req,
- uint8_t *response);
-void sd_write_data(SDState *sd, uint8_t value);
-uint8_t sd_read_data(SDState *sd);
-void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
-bool sd_data_ready(SDState *sd);
-void sd_enable(SDState *sd, bool enable);
+typedef struct SDClass {
+ ObjectClass parent_class;
+
+ void (*init)(SDState *sd, BlockDriverState *bs, bool is_spi);
+ int (*do_command)(SDState *sd, SDRequest *req, uint8_t *response);
+ void (*write_data)(SDState *sd, uint8_t value);
+ uint8_t (*read_data)(SDState *sd);
+ void (*set_cb)(SDState *sd, qemu_irq readonly, qemu_irq insert);
+ bool (*data_ready)(SDState *sd);
+ void (*enable)(SDState *sd, bool enable);
+} SDClass;
+
+#define TYPE_SD_CARD "sd-card"
+#define SD_CARD(obj) \
+ OBJECT_CHECK(SDState, (obj), TYPE_SD_CARD)
+#define SD_CLASS(klass) \
+ OBJECT_CLASS_CHECK(SDClass, (klass), TYPE_SD_CARD)
+#define SD_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(SDClass, (obj), TYPE_SD_CARD)
#endif /* __hw_sd_h */
diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c
index b519bdb..9d6f95d 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -94,7 +94,8 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
| (s->cmdarg[2] << 8) | s->cmdarg[3];
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
- s->arglen = sd_do_command(s->sd, &request, longresp);
+ s->arglen =
+ SD_GET_CLASS(s->sd)->do_command(s->sd, &request, longresp);
if (s->arglen <= 0) {
s->arglen = 1;
s->response[0] = 4;
@@ -171,7 +172,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
return s->response[s->response_pos++];
}
- if (sd_data_ready(s->sd)) {
+ if (SD_GET_CLASS(s->sd)->data_ready(s->sd)) {
DPRINTF("Data read\n");
s->mode = SSI_SD_DATA_START;
} else {
@@ -184,8 +185,8 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
s->mode = SSI_SD_DATA_READ;
return 0xfe;
case SSI_SD_DATA_READ:
- val = sd_read_data(s->sd);
- if (!sd_data_ready(s->sd)) {
+ val = SD_GET_CLASS(s->sd)->read_data(s->sd);
+ if (!SD_GET_CLASS(s->sd)->data_ready(s->sd)) {
DPRINTF("Data read end\n");
s->mode = SSI_SD_CMD;
}
@@ -239,7 +240,8 @@ static int ssi_sd_init(SSISlave *dev)
s->mode = SSI_SD_CMD;
dinfo = drive_get_next(IF_SD);
- s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, 1);
+ s->sd = SD_CARD(object_new(TYPE_SD_CARD));
+ SD_GET_CLASS(s->sd)->init(s->sd, dinfo ? dinfo->bdrv : NULL, true);
register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
return 0;
}
--
1.7.4.1
- [Qemu-devel] [PATCH 0/6] SD save/load support and SD qomification, Igor Mitsyanko, 2012/04/02
- [Qemu-devel] [PATCH 3/6] hw/sd.c: make sd_dataready() return bool, Igor Mitsyanko, 2012/04/02
- [Qemu-devel] [PATCH 2/6] hw/sd.c: convert binary variables to bool, Igor Mitsyanko, 2012/04/02
- [Qemu-devel] [PATCH 5/6] hw/sd.c: add SD card save/load support, Igor Mitsyanko, 2012/04/02
- [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object,
Igor Mitsyanko <=
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Peter Maydell, 2012/04/02
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Paolo Bonzini, 2012/04/02
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Igor Mitsyanko, 2012/04/02
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Peter Maydell, 2012/04/02
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Paolo Bonzini, 2012/04/02
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Igor Mitsyanko, 2012/04/03
- Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object, Paolo Bonzini, 2012/04/03
[Qemu-devel] [PATCH 4/6] hw/sd.c: make sd_wp_addr() return bool, Igor Mitsyanko, 2012/04/02
[Qemu-devel] [PATCH 1/6] hw/sd.c: convert wp_groups in SDState to bitfield, Igor Mitsyanko, 2012/04/02