From f82a0f449b2fdf314900116047ea6d9ee5a2da06 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:15 +0000 Subject: sdhci: clean up includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20180115182436.2066-2-f4bug@amsat.org Signed-off-by: Peter Maydell --- include/hw/sd/sdhci.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 0f0c3f1e64..1335373d3c 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -26,17 +26,19 @@ #define SDHCI_H #include "qemu-common.h" -#include "hw/block/block.h" #include "hw/pci/pci.h" #include "hw/sysbus.h" #include "hw/sd/sd.h" /* SD/MMC host controller state */ typedef struct SDHCIState { + /*< private >*/ union { PCIDevice pcidev; SysBusDevice busdev; }; + + /*< public >*/ SDBus sdbus; MemoryRegion iomem; @@ -46,6 +48,7 @@ typedef struct SDHCIState { qemu_irq ro_cb; qemu_irq irq; + /* Registers cleared on reset */ uint32_t sdmasysad; /* SDMA System Address register */ uint16_t blksize; /* Host DMA Buff Boundary and Transfer BlkSize Reg */ uint16_t blkcnt; /* Blocks count for current transfer */ @@ -70,8 +73,10 @@ typedef struct SDHCIState { uint16_t acmd12errsts; /* Auto CMD12 error status register */ uint64_t admasysaddr; /* ADMA System Address Register */ + /* Read-only registers */ uint32_t capareg; /* Capabilities Register */ uint32_t maxcurr; /* Maximum Current Capabilities Register */ + uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */ uint32_t buf_maxsz; uint16_t data_count; /* current element in FIFO buffer */ -- cgit 1.4.1 From 03603958a4bdd35b464ee30b9afd6d134cff4cd2 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:15 +0000 Subject: sdhci: remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20180115182436.2066-3-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/sd/sdhci.c | 2 -- include/hw/sd/sdhci.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index b7d2a20985..365bc80009 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1200,8 +1200,6 @@ static void sdhci_uninitfn(SDHCIState *s) timer_free(s->insert_timer); timer_del(s->transfer_timer); timer_free(s->transfer_timer); - qemu_free_irq(s->eject_cb); - qemu_free_irq(s->ro_cb); g_free(s->fifo_buffer); s->fifo_buffer = NULL; diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 1335373d3c..dacd726537 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -44,8 +44,6 @@ typedef struct SDHCIState { QEMUTimer *insert_timer; /* timer for 'changing' sd card. */ QEMUTimer *transfer_timer; - qemu_irq eject_cb; - qemu_irq ro_cb; qemu_irq irq; /* Registers cleared on reset */ -- cgit 1.4.1 From b635d98cf323ec7f9e639d52a0e0d29fa7b33e38 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:16 +0000 Subject: sdhci: use DEFINE_SDHCI_COMMON_PROPERTIES() for common sysbus/pci properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add common/sysbus/pci/sdbus comments to have clearer code blocks separation. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20180115182436.2066-4-f4bug@amsat.org Signed-off-by: Peter Maydell Reviewed-by: Peter Maydell --- hw/sd/sdhci.c | 25 +++++++++++++++++-------- include/hw/sd/sdhci.h | 4 +++- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 365bc80009..c0b4b8457a 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" @@ -1185,6 +1186,14 @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s) } } +/* --- qdev common --- */ + +#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \ + /* Capabilities registers provide information on supported features + * of this specific host controller implementation */ \ + DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \ + DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0) + static void sdhci_initfn(SDHCIState *s) { qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), @@ -1264,12 +1273,10 @@ const VMStateDescription sdhci_vmstate = { }, }; -/* Capabilities registers provide information on supported features of this - * specific host controller implementation */ +/* --- qdev PCI --- */ + static Property sdhci_pci_properties[] = { - DEFINE_PROP_UINT32("capareg", SDHCIState, capareg, - SDHC_CAPAB_REG_DEFAULT), - DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0), + DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), DEFINE_PROP_END_OF_LIST(), }; @@ -1320,10 +1327,10 @@ static const TypeInfo sdhci_pci_info = { }, }; +/* --- qdev SysBus --- */ + static Property sdhci_sysbus_properties[] = { - DEFINE_PROP_UINT32("capareg", SDHCIState, capareg, - SDHC_CAPAB_REG_DEFAULT), - DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0), + DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk, false), DEFINE_PROP_END_OF_LIST(), @@ -1374,6 +1381,8 @@ static const TypeInfo sdhci_sysbus_info = { .class_init = sdhci_sysbus_class_init, }; +/* --- qdev bus master --- */ + static void sdhci_bus_class_init(ObjectClass *klass, void *data) { SDBusClass *sbc = SD_BUS_CLASS(klass); diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index dacd726537..8041c9629e 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -79,13 +79,15 @@ typedef struct SDHCIState { uint32_t buf_maxsz; uint16_t data_count; /* current element in FIFO buffer */ uint8_t stopped_state;/* Current SDHC state */ - bool pending_insert_quirk;/* Quirk for Raspberry Pi card insert int */ bool pending_insert_state; /* Buffer Data Port Register - virtual access point to R and W buffers */ /* Software Reset Register - always reads as 0 */ /* Force Event Auto CMD12 Error Interrupt Reg - write only */ /* Force Event Error Interrupt Register- write only */ /* RO Host Controller Version Register always reads as 0x2401 */ + + /* Configurable properties */ + bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */ } SDHCIState; #define TYPE_PCI_SDHCI "sdhci-pci" -- cgit 1.4.1 From 5efc9016e52596ec054b19bb0ae1d274f77f2a2b Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:20 +0000 Subject: sdhci: fix CAPAB/MAXCURR registers, both are 64bit and read-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit running qtests: $ make check-qtest-arm GTESTER check-qtest-arm SDHC rd_4b @0x44 not implemented SDHC wr_4b @0x40 <- 0x89abcdef not implemented SDHC wr_4b @0x44 <- 0x01234567 not implemented Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20180115182436.2066-12-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/sd/sdhci.c | 23 +++++++++++++++++++---- include/hw/sd/sdhci.h | 4 ++-- 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index c4e486e2ff..d4fcebcd6a 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -899,10 +899,16 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size) ret = s->acmd12errsts; break; case SDHC_CAPAB: - ret = s->capareg; + ret = (uint32_t)s->capareg; + break; + case SDHC_CAPAB + 4: + ret = (uint32_t)(s->capareg >> 32); break; case SDHC_MAXCURR: - ret = s->maxcurr; + ret = (uint32_t)s->maxcurr; + break; + case SDHC_MAXCURR + 4: + ret = (uint32_t)(s->maxcurr >> 32); break; case SDHC_ADMAERR: ret = s->admaerr; @@ -1123,6 +1129,15 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) } sdhci_update_irq(s); break; + + case SDHC_CAPAB: + case SDHC_CAPAB + 4: + case SDHC_MAXCURR: + case SDHC_MAXCURR + 4: + qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx + " <- 0x%08x read-only\n", size, offset, value >> shift); + break; + default: qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x " "not implemented\n", size, offset, value >> shift); @@ -1163,8 +1178,8 @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s) #define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \ /* Capabilities registers provide information on supported features * of this specific host controller implementation */ \ - DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \ - DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0) + DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \ + DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0) static void sdhci_initfn(SDHCIState *s) { diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 8041c9629e..442e30aff2 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -72,8 +72,8 @@ typedef struct SDHCIState { uint64_t admasysaddr; /* ADMA System Address Register */ /* Read-only registers */ - uint32_t capareg; /* Capabilities Register */ - uint32_t maxcurr; /* Maximum Current Capabilities Register */ + uint64_t capareg; /* Capabilities Register */ + uint64_t maxcurr; /* Maximum Current Capabilities Register */ uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */ uint32_t buf_maxsz; -- cgit 1.4.1 From dd55c485ec2fcd28c245061b320398d35b92d30d Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:21 +0000 Subject: sdhci: fix the PCI device, using the PCI address space for DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While SysBus devices can use the get_system_memory() address space, PCI devices should use the bus master address space for DMA. Suggested-by: Peter Maydell Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Message-id: 20180115182436.2066-14-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/sd/sdhci.c | 29 +++++++++++++++-------------- include/hw/sd/sdhci.h | 1 + 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 9bdbcd0a04..dd400695e4 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -496,7 +496,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) s->blkcnt--; } } - dma_memory_write(&address_space_memory, s->sdmasysad, + dma_memory_write(s->dma_as, s->sdmasysad, &s->fifo_buffer[begin], s->data_count - begin); s->sdmasysad += s->data_count - begin; if (s->data_count == block_size) { @@ -518,7 +518,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) s->data_count = block_size; boundary_count -= block_size - begin; } - dma_memory_read(&address_space_memory, s->sdmasysad, + dma_memory_read(s->dma_as, s->sdmasysad, &s->fifo_buffer[begin], s->data_count - begin); s->sdmasysad += s->data_count - begin; if (s->data_count == block_size) { @@ -556,11 +556,9 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s) for (n = 0; n < datacnt; n++) { s->fifo_buffer[n] = sdbus_read_data(&s->sdbus); } - dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer, - datacnt); + dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt); } else { - dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer, - datacnt); + dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt); for (n = 0; n < datacnt; n++) { sdbus_write_data(&s->sdbus, s->fifo_buffer[n]); } @@ -584,7 +582,7 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) hwaddr entry_addr = (hwaddr)s->admasysaddr; switch (SDHC_DMA_TYPE(s->hostctl)) { case SDHC_CTRL_ADMA2_32: - dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma2, + dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2, sizeof(adma2)); adma2 = le64_to_cpu(adma2); /* The spec does not specify endianness of descriptor table. @@ -596,7 +594,7 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) dscr->incr = 8; break; case SDHC_CTRL_ADMA1_32: - dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma1, + dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1, sizeof(adma1)); adma1 = le32_to_cpu(adma1); dscr->addr = (hwaddr)(adma1 & 0xFFFFF000); @@ -609,12 +607,12 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) } break; case SDHC_CTRL_ADMA2_64: - dma_memory_read(&address_space_memory, entry_addr, + dma_memory_read(s->dma_as, entry_addr, (uint8_t *)(&dscr->attr), 1); - dma_memory_read(&address_space_memory, entry_addr + 2, + dma_memory_read(s->dma_as, entry_addr + 2, (uint8_t *)(&dscr->length), 2); dscr->length = le16_to_cpu(dscr->length); - dma_memory_read(&address_space_memory, entry_addr + 4, + dma_memory_read(s->dma_as, entry_addr + 4, (uint8_t *)(&dscr->addr), 8); dscr->attr = le64_to_cpu(dscr->attr); dscr->attr &= 0xfffffff8; @@ -673,7 +671,7 @@ static void sdhci_do_adma(SDHCIState *s) s->data_count = block_size; length -= block_size - begin; } - dma_memory_write(&address_space_memory, dscr.addr, + dma_memory_write(s->dma_as, dscr.addr, &s->fifo_buffer[begin], s->data_count - begin); dscr.addr += s->data_count - begin; @@ -697,7 +695,7 @@ static void sdhci_do_adma(SDHCIState *s) s->data_count = block_size; length -= block_size - begin; } - dma_memory_read(&address_space_memory, dscr.addr, + dma_memory_read(s->dma_as, dscr.addr, &s->fifo_buffer[begin], s->data_count - begin); dscr.addr += s->data_count - begin; @@ -1312,7 +1310,8 @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp) dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */ dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ s->irq = pci_allocate_irq(dev); - pci_register_bar(dev, 0, 0, &s->iomem); + s->dma_as = pci_get_address_space(dev); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem); } static void sdhci_pci_exit(PCIDevice *dev) @@ -1381,6 +1380,8 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp) return; } + s->dma_as = &address_space_memory; + sysbus_init_irq(sbd, &s->irq); sysbus_init_mmio(sbd, &s->iomem); } diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 442e30aff2..4a102b86ce 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -41,6 +41,7 @@ typedef struct SDHCIState { /*< public >*/ SDBus sdbus; MemoryRegion iomem; + AddressSpace *dma_as; QEMUTimer *insert_timer; /* timer for 'changing' sd card. */ QEMUTimer *transfer_timer; -- cgit 1.4.1 From 60765b6ceeb4998a0d4220b3a53f1f185061da77 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Tue, 16 Jan 2018 13:28:21 +0000 Subject: sdhci: add a 'dma' property to the sysbus devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a 'dma' property allowing machine creation to provide the address-space SDHCI DMA operates on. [based on a patch from Alistair Francis from qemu/xilinx tag xilinx-v2016.1] Signed-off-by: Philippe Mathieu-Daudé Message-id: 20180115182436.2066-15-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/sd/sdhci.c | 18 +++++++++++++++++- include/hw/sd/sdhci.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'include/hw/sd/sdhci.h') diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index dd400695e4..f9264d3be5 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1354,6 +1354,8 @@ static Property sdhci_sysbus_properties[] = { DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState), DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk, false), + DEFINE_PROP_LINK("dma", SDHCIState, + dma_mr, TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_END_OF_LIST(), }; @@ -1367,6 +1369,11 @@ static void sdhci_sysbus_init(Object *obj) static void sdhci_sysbus_finalize(Object *obj) { SDHCIState *s = SYSBUS_SDHCI(obj); + + if (s->dma_mr) { + object_unparent(OBJECT(s->dma_mr)); + } + sdhci_uninitfn(s); } @@ -1380,7 +1387,12 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp) return; } - s->dma_as = &address_space_memory; + if (s->dma_mr) { + address_space_init(s->dma_as, s->dma_mr, "sdhci-dma"); + } else { + /* use system_memory() if property "dma" not set */ + s->dma_as = &address_space_memory; + } sysbus_init_irq(sbd, &s->irq); sysbus_init_mmio(sbd, &s->iomem); @@ -1391,6 +1403,10 @@ static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp) SDHCIState *s = SYSBUS_SDHCI(dev); sdhci_common_unrealize(s, &error_abort); + + if (s->dma_mr) { + address_space_destroy(s->dma_as); + } } static void sdhci_sysbus_class_init(ObjectClass *klass, void *data) diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 4a102b86ce..cb37182536 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -42,6 +42,7 @@ typedef struct SDHCIState { SDBus sdbus; MemoryRegion iomem; AddressSpace *dma_as; + MemoryRegion *dma_mr; QEMUTimer *insert_timer; /* timer for 'changing' sd card. */ QEMUTimer *transfer_timer; -- cgit 1.4.1