From patchwork Thu Apr 5 15:48:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mitsyanko Igor X-Patchwork-Id: 151089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E8C7EB7085 for ; Fri, 6 Apr 2012 16:41:05 +1000 (EST) Received: from localhost ([::1]:48876 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFoxo-0004cD-H8 for incoming@patchwork.ozlabs.org; Thu, 05 Apr 2012 11:51:08 -0400 Received: from eggs.gnu.org ([208.118.235.92]:38578) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFovh-0001bm-S6 for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:49:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFovb-0006j3-62 for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:48:57 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:9329) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFova-0006iB-Pc for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:48:51 -0400 Received: from euspt2 (mailout1.w1.samsung.com [210.118.77.11]) by mailout1.w1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTP id <0M2000EURJVZCR@mailout1.w1.samsung.com> for qemu-devel@nongnu.org; Thu, 05 Apr 2012 16:48:00 +0100 (BST) Received: from dodo.rnd.samsung.ru ([106.109.8.162]) by spt2.w1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0M2000IDGJWVHW@spt2.w1.samsung.com> for qemu-devel@nongnu.org; Thu, 05 Apr 2012 16:48:45 +0100 (BST) Date: Thu, 05 Apr 2012 19:48:29 +0400 From: Igor Mitsyanko In-reply-to: <1333640913-16028-1-git-send-email-i.mitsyanko@samsung.com> To: qemu-devel@nongnu.org Message-id: <1333640913-16028-7-git-send-email-i.mitsyanko@samsung.com> MIME-version: 1.0 X-Mailer: git-send-email 1.7.4.1 Content-type: TEXT/PLAIN Content-transfer-encoding: 7BIT References: <1333640913-16028-1-git-send-email-i.mitsyanko@samsung.com> X-detected-operating-system: by eggs.gnu.org: Solaris 9.1 X-Received-From: 210.118.77.11 Cc: peter.maydell@linaro.org, Igor Mitsyanko , quintela@redhat.com, kyungmin.park@samsung.com, michael@walle.cc, paul@codesourcery.com, afaerber@suse.de, d.solodkiy@samsung.com Subject: [Qemu-devel] [PATCH V2 06/10] hw/sd.c: convert to QOM object X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org A straightforward conversion of SD card implementation to a proper QEMU object. Signed-off-by: Igor Mitsyanko --- hw/milkymist-memcard.c | 24 ++++++++++++++---------- hw/omap_mmc.c | 28 ++++++++++++++++------------ hw/pl181.c | 14 ++++++++------ hw/pxa2xx_mmci.c | 22 ++++++++++++++-------- hw/sd.c | 48 +++++++++++++++++++++++++++++++++++++----------- hw/sd.h | 38 ++++++++++++++++++++++++++++++-------- hw/ssi-sd.c | 11 ++++++----- 7 files changed, 125 insertions(+), 60 deletions(-) diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c index 3515c3c..1d84d44 100644 --- a/hw/milkymist-memcard.c +++ b/hw/milkymist-memcard.c @@ -97,7 +97,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 = SD_DO_COMMAND(s->card, &req, s->response + 1); s->response_read_ptr = 0; if (s->response_len == 16) { @@ -141,11 +141,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 +171,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 +200,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 +252,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_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..15bc1ae 100644 --- a/hw/omap_mmc.c +++ b/hw/omap_mmc.c @@ -138,7 +138,7 @@ 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_DO_COMMAND(host->card, &request, response); /* TODO: validate CRCs */ switch (resptype) { @@ -219,6 +219,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 +230,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 +245,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 +593,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_INIT(s->card, bd, false); return s; } @@ -617,10 +619,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_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_SET_CB(s->card, NULL, s->cdet); return s; } @@ -628,14 +631,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_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_SET_CB(s->card, ro, cover); + } } void omap_mmc_enable(struct omap_mmc_s *s, int enable) { - sd_enable(s->card, enable); + SD_ENABLE(s->card, !!enable); } diff --git a/hw/pl181.c b/hw/pl181.c index 7d91fbb..b2b1ed4 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_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_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_INIT(s->card, dinfo ? dinfo->bdrv : NULL, false); return 0; } diff --git a/hw/pxa2xx_mmci.c b/hw/pxa2xx_mmci.c index b505a4c..a7081b0 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_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_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_SET_CB(s->card, readonly, coverswitch); } diff --git a/hw/sd.c b/hw/sd.c index 6f6be88..58d94ed 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -75,6 +75,8 @@ enum { }; struct SDState { + Object parent_obj; + uint32_t mode; int32_t state; uint32_t ocr; @@ -484,11 +486,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; @@ -498,10 +497,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; @@ -1332,7 +1330,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; @@ -1500,7 +1498,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; @@ -1624,7 +1622,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; @@ -1743,12 +1741,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..d8f0195 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,32 @@ 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) + +#define SD_INIT(sd, bdrv, is_spi) (SD_GET_CLASS(sd)->init(sd, bdrv, is_spi)) +#define SD_DO_COMMAND(sd, req, rsp) (SD_GET_CLASS(sd)->do_command(sd, req, rsp)) +#define SD_WRITE(sd, value) (SD_GET_CLASS(sd)->write_data(sd, value)) +#define SD_READ(sd) (SD_GET_CLASS(sd)->read_data(sd)) +#define SD_SET_CB(sd, ro, ins) (SD_GET_CLASS(sd)->set_cb(sd, ro, ins)) +#define SD_DATA_READY(sd) (SD_GET_CLASS(sd)->data_ready(sd)) +#define SD_ENABLE(sd, enbl) (SD_GET_CLASS(sd)->enable(sd, enbl)) #endif /* __hw_sd_h */ diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c index b519bdb..beecc0e 100644 --- a/hw/ssi-sd.c +++ b/hw/ssi-sd.c @@ -94,7 +94,7 @@ 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_DO_COMMAND(s->sd, &request, longresp); if (s->arglen <= 0) { s->arglen = 1; s->response[0] = 4; @@ -171,7 +171,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_DATA_READY(s->sd)) { DPRINTF("Data read\n"); s->mode = SSI_SD_DATA_START; } else { @@ -184,8 +184,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_READ(s->sd); + if (!SD_DATA_READY(s->sd)) { DPRINTF("Data read end\n"); s->mode = SSI_SD_CMD; } @@ -239,7 +239,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_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; }