Start bit callback models arrival of first bit of data on card's DAT line. Busy deasserted callback models releasing of DAT0 line by card when it transitions from a programming state to a writing data state.
Both of them will be used for async IO later. Signed-off-by: Igor Mitsyanko <i.mitsya...@gmail.com> --- hw/sd/omap_mmc.c | 6 +++--- hw/sd/pl181.c | 2 +- hw/sd/pxa2xx_mmci.c | 2 +- hw/sd/sd.c | 24 +++++++++++++++++++++--- hw/sd/sdhci.c | 4 ++-- include/hw/sd.h | 3 ++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c index d4079cd..94580bb 100644 --- a/hw/sd/omap_mmc.c +++ b/hw/sd/omap_mmc.c @@ -620,7 +620,7 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta, s->card = sd_init(bd, 0); 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, NULL, NULL); return s; } @@ -628,11 +628,11 @@ 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, NULL, NULL); s->coverswitch = cover; qemu_set_irq(cover, s->cdet_state); } else - sd_set_cb(s->card, ro, cover); + sd_set_cb(s->card, ro, cover, NULL, NULL); } void omap_mmc_enable(struct omap_mmc_s *s, int enable) diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c index 2527296..2caacc2 100644 --- a/hw/sd/pl181.c +++ b/hw/sd/pl181.c @@ -471,7 +471,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], NULL, NULL); } static int pl181_init(SysBusDevice *dev) diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c index 2db1cab..64a3050 100644 --- a/hw/sd/pxa2xx_mmci.c +++ b/hw/sd/pxa2xx_mmci.c @@ -549,5 +549,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, NULL, NULL); } diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 775a55c..2e75201 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -108,6 +108,8 @@ struct SDState { uint8_t data[512]; qemu_irq readonly_cb; qemu_irq inserted_cb; + qemu_irq start_bit_cb; + qemu_irq datbusy_cb; BlockDriverState *bdrv; uint8_t *buf; @@ -519,10 +521,13 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi) return sd; } -void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert) +void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert, + qemu_irq startbit, qemu_irq endbusy) { sd->readonly_cb = readonly; sd->inserted_cb = insert; + sd->start_bit_cb = startbit; + sd->datbusy_cb = endbusy; qemu_set_irq(readonly, sd->bdrv ? bdrv_is_read_only(sd->bdrv) : 0); qemu_set_irq(insert, sd->bdrv ? bdrv_is_inserted(sd->bdrv) : 0); } @@ -762,6 +767,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, sd->state = sd_sendingdata_state; sd->data_start = 0; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -841,6 +847,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, memcpy(sd->data, sd->csd, 16); sd->data_start = addr; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -863,6 +870,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, memcpy(sd->data, sd->cid, 16); sd->data_start = addr; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -1111,6 +1119,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, *(uint32_t *) sd->data = sd_wpbits(sd, req.arg); sd->data_start = addr; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1b; default: @@ -1201,10 +1210,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, switch (sd->state) { case sd_transfer_state: sd->data_offset = 0; - if (req.arg & 1) + if (req.arg & 1) { sd->state = sd_sendingdata_state; - else + qemu_irq_raise(sd->start_bit_cb); + } else { sd->state = sd_receivingdata_state; + } return sd_r1; default: @@ -1251,6 +1262,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd, sd->state = sd_sendingdata_state; sd->data_start = 0; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -1266,6 +1278,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd, sd->state = sd_sendingdata_state; sd->data_start = 0; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -1319,6 +1332,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd, sd->state = sd_sendingdata_state; sd->data_start = 0; sd->data_offset = 0; + qemu_irq_raise(sd->start_bit_cb); return sd_r1; default: @@ -1596,6 +1610,7 @@ void sd_write_data(SDState *sd, uint8_t value) } /* Bzzzzzzztt .... Operation complete. */ sd->state = sd_transfer_state; + qemu_irq_raise(sd->datbusy_cb); } break; @@ -1620,6 +1635,7 @@ void sd_write_data(SDState *sd, uint8_t value) } /* Bzzzzzzztt .... Operation complete. */ sd->state = sd_transfer_state; + qemu_irq_raise(sd->datbusy_cb); } break; @@ -1631,6 +1647,7 @@ void sd_write_data(SDState *sd, uint8_t value) sd_lock_command(sd); /* Bzzzzzzztt .... Operation complete. */ sd->state = sd_transfer_state; + qemu_irq_raise(sd->datbusy_cb); } break; @@ -1639,6 +1656,7 @@ void sd_write_data(SDState *sd, uint8_t value) if (sd->data_offset >= sd->blk_len) { APP_WRITE_BLOCK(sd->data_start, sd->data_offset); sd->state = sd_transfer_state; + qemu_irq_raise(sd->datbusy_cb); } break; diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 91dc9b0..bb33368 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -193,7 +193,7 @@ static void sdhci_reset(SDHCIState *s) * initialization */ memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad); - sd_set_cb(s->card, s->ro_cb, s->eject_cb); + sd_set_cb(s->card, s->ro_cb, s->eject_cb, NULL, NULL); s->data_count = 0; s->stopped_state = sdhc_not_stopped; } @@ -1168,7 +1168,7 @@ static void sdhci_initfn(Object *obj) s->card = sd_init(di ? di->bdrv : NULL, 0); s->eject_cb = qemu_allocate_irqs(sdhci_insert_eject_cb, s, 1)[0]; s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0]; - sd_set_cb(s->card, s->ro_cb, s->eject_cb); + sd_set_cb(s->card, s->ro_cb, s->eject_cb, NULL, NULL); s->insert_timer = qemu_new_timer_ns(vm_clock, sdhci_raise_insertion_irq, s); s->transfer_timer = qemu_new_timer_ns(vm_clock, sdhci_do_data_transfer, s); diff --git a/include/hw/sd.h b/include/hw/sd.h index d9b97e4..a7024d4 100644 --- a/include/hw/sd.h +++ b/include/hw/sd.h @@ -73,7 +73,8 @@ 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); +void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert, + qemu_irq startbit, qemu_irq endbusy); bool sd_data_ready(SDState *sd); void sd_enable(SDState *sd, bool enable); -- 1.8.1.4