:p
atchew
Login
target-arm queue: aspeed patches from Cédric, and cleanup and sd card patches from Philippe. thanks -- PMM The following changes since commit bac5ba3dc5da706f52c149fa6c0bd1dc96899bec: Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging (2018-06-08 10:26:16 +0100) are available in the Git repository at: git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180608 for you to fetch changes up to 113f31c06c6bf16451892b2459d83c9b9c5e9844: sdcard: Disable CMD19/CMD23 for Spec v2 (2018-06-08 13:15:34 +0100) ---------------------------------------------------------------- target-arm queue: * arm_gicv3_kvm: fix migration of registers corresponding to IRQs 992 to 1020 in the KVM GIC * aspeed: remove ignore_memory_transaction_failures on all boards * aspeed: add support for the witherspoon-bmc board * aspeed: add an I2C RTC device and EEPROM I2C devices * aspeed: add the pc9552 chips to the witherspoon machine * ftgmac100: fix various bugs * hw/arm: Remove the deprecated xlnx-ep108 machine * hw/i2c: Add trace events * add missing '\n' on various qemu_log() logging strings * sdcard: clean up spec version support so we report the right spec version to the guest and only implement the commands that are supposed to be present in that version ---------------------------------------------------------------- Cédric Le Goater (11): aspeed: remove ignore_memory_transaction_failures on all boards aspeed: add support for the witherspoon-bmc board aspeed: add an I2C RTC device to all machines smbus: add a smbus_eeprom_init_one() routine aspeed: Add EEPROM I2C devices misc: add pca9552 LED blinker model aspeed: add the pc9552 chips to the witherspoon machine ftgmac100: compute maximum frame size depending on the protocol ftgmac100: add IEEE 802.1Q VLAN support ftgmac100: fix multicast hash routine ftgmac100: remove check on runt messages Philippe Mathieu-Daudé (18): hw/i2c: Add trace events hw/sd/milkymist-memcard: Add trailing '\n' to qemu_log() call hw/digic: Add trailing '\n' to qemu_log() calls xilinx-dp: Add trailing '\n' to qemu_log() call ppc/pnv: Add trailing '\n' to qemu_log() calls hw/core/register: Add trailing '\n' to qemu_log() call hw/mips/boston: Add trailing '\n' to qemu_log() calls stellaris: Add trailing '\n' to qemu_log() calls target/arm: Add trailing '\n' to qemu_log() calls target/m68k: Add trailing '\n' to qemu_log() call RISC-V: Add trailing '\n' to qemu_log() calls target/xtensa: Add trailing '\n' to qemu_log() calls sdcard: Update the Configuration Register (SCR) to Spec Version 1.10 sdcard: Allow commands valid in SPI mode sdcard: Add a 'spec_version' property, default to Spec v2.00 sdcard: Disable SEND_IF_COND (CMD8) for Spec v1 sdcard: Reflect when the Spec v3 is supported in the Config Register (SCR) sdcard: Disable CMD19/CMD23 for Spec v2 Shannon Zhao (1): arm_gicv3_kvm: kvm_dist_get/put: skip the registers banked by GICR Thomas Huth (1): hw/arm: Remove the deprecated xlnx-ep108 machine Makefile.objs | 1 + hw/misc/Makefile.objs | 1 + tests/Makefile.include | 2 + include/hw/i2c/smbus.h | 1 + include/hw/intc/arm_gicv3_common.h | 1 + include/hw/misc/pca9552.h | 32 +++++ include/hw/misc/pca9552_regs.h | 32 +++++ include/hw/net/ftgmac100.h | 7 +- include/hw/sd/sd.h | 6 + tests/libqos/i2c.h | 2 + hw/arm/aspeed.c | 88 +++++++++++++- hw/arm/stellaris.c | 11 +- hw/arm/xlnx-zcu102.c | 62 +--------- hw/char/digic-uart.c | 4 +- hw/core/register.c | 2 +- hw/display/xlnx_dp.c | 4 +- hw/i2c/core.c | 25 ++-- hw/i2c/smbus_eeprom.c | 16 ++- hw/intc/arm_gicv3_common.c | 79 ++++++++++++ hw/intc/arm_gicv3_kvm.c | 38 ++++++ hw/mips/boston.c | 8 +- hw/misc/pca9552.c | 240 +++++++++++++++++++++++++++++++++++++ hw/net/ftgmac100.c | 64 ++++++---- hw/ppc/pnv_core.c | 4 +- hw/sd/milkymist-memcard.c | 2 +- hw/sd/sd.c | 50 +++++--- hw/timer/digic-timer.c | 4 +- target/arm/helper.c | 4 +- target/m68k/translate.c | 2 +- target/riscv/op_helper.c | 6 +- target/xtensa/translate.c | 6 +- tests/pca9552-test.c | 116 ++++++++++++++++++ tests/tmp105-test.c | 2 - default-configs/arm-softmmu.mak | 1 + hw/i2c/trace-events | 7 ++ qemu-doc.texi | 5 - 36 files changed, 788 insertions(+), 147 deletions(-) create mode 100644 include/hw/misc/pca9552.h create mode 100644 include/hw/misc/pca9552_regs.h create mode 100644 hw/misc/pca9552.c create mode 100644 tests/pca9552-test.c create mode 100644 hw/i2c/trace-events
From: Shannon Zhao <zhaoshenglong@huawei.com> While we skip the GIC_INTERNAL irqs, we don't change the register offset accordingly. This will overlap the GICR registers value and leave the last GIC_INTERNAL irq's registers out of update. Fix this by skipping the registers banked by GICR. Also for migration compatibility if the migration source (old version qemu) doesn't send gicd_no_migration_shift_bug = 1 to destination, then we shift the data of PPI to get the right data for SPI. Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920 Cc: qemu-stable@nongnu.org Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com> Message-id: 1527816987-16108-1-git-send-email-zhaoshenglong@huawei.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/intc/arm_gicv3_common.h | 1 + hw/intc/arm_gicv3_common.c | 79 ++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_kvm.c | 38 ++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -XXX,XX +XXX,XX @@ struct GICv3State { uint32_t revision; bool security_extn; bool irq_reset_nonsecure; + bool gicd_no_migration_shift_bug; int dev_fd; /* kvm device fd if backed by kvm vgic support */ Error *migration_blocker; diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -XXX,XX +XXX,XX @@ #include "hw/intc/arm_gicv3_common.h" #include "gicv3_internal.h" #include "hw/arm/linux-boot-if.h" +#include "sysemu/kvm.h" static int gicv3_pre_save(void *opaque) { @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3_cpu = { } }; +static int gicv3_gicd_no_migration_shift_bug_pre_load(void *opaque) +{ + GICv3State *cs = opaque; + + /* + * The gicd_no_migration_shift_bug flag is used for migration compatibility + * for old version QEMU which may have the GICD bmp shift bug under KVM mode. + * Strictly, what we want to know is whether the migration source is using + * KVM. Since we don't have any way to determine that, we look at whether the + * destination is using KVM; this is close enough because for the older QEMU + * versions with this bug KVM -> TCG migration didn't work anyway. If the + * source is a newer QEMU without this bug it will transmit the migration + * subsection which sets the flag to true; otherwise it will remain set to + * the value we select here. + */ + if (kvm_enabled()) { + cs->gicd_no_migration_shift_bug = false; + } + + return 0; +} + +static int gicv3_gicd_no_migration_shift_bug_post_load(void *opaque, + int version_id) +{ + GICv3State *cs = opaque; + + if (cs->gicd_no_migration_shift_bug) { + return 0; + } + + /* Older versions of QEMU had a bug in the handling of state save/restore + * to the KVM GICv3: they got the offset in the bitmap arrays wrong, + * so that instead of the data for external interrupts 32 and up + * starting at bit position 32 in the bitmap, it started at bit + * position 64. If we're receiving data from a QEMU with that bug, + * we must move the data down into the right place. + */ + memmove(cs->group, (uint8_t *)cs->group + GIC_INTERNAL / 8, + sizeof(cs->group) - GIC_INTERNAL / 8); + memmove(cs->grpmod, (uint8_t *)cs->grpmod + GIC_INTERNAL / 8, + sizeof(cs->grpmod) - GIC_INTERNAL / 8); + memmove(cs->enabled, (uint8_t *)cs->enabled + GIC_INTERNAL / 8, + sizeof(cs->enabled) - GIC_INTERNAL / 8); + memmove(cs->pending, (uint8_t *)cs->pending + GIC_INTERNAL / 8, + sizeof(cs->pending) - GIC_INTERNAL / 8); + memmove(cs->active, (uint8_t *)cs->active + GIC_INTERNAL / 8, + sizeof(cs->active) - GIC_INTERNAL / 8); + memmove(cs->edge_trigger, (uint8_t *)cs->edge_trigger + GIC_INTERNAL / 8, + sizeof(cs->edge_trigger) - GIC_INTERNAL / 8); + + /* + * While this new version QEMU doesn't have this kind of bug as we fix it, + * so it needs to set the flag to true to indicate that and it's necessary + * for next migration to work from this new version QEMU. + */ + cs->gicd_no_migration_shift_bug = true; + + return 0; +} + +const VMStateDescription vmstate_gicv3_gicd_no_migration_shift_bug = { + .name = "arm_gicv3/gicd_no_migration_shift_bug", + .version_id = 1, + .minimum_version_id = 1, + .pre_load = gicv3_gicd_no_migration_shift_bug_pre_load, + .post_load = gicv3_gicd_no_migration_shift_bug_post_load, + .fields = (VMStateField[]) { + VMSTATE_BOOL(gicd_no_migration_shift_bug, GICv3State), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_gicv3 = { .name = "arm_gicv3", .version_id = 1, @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3 = { VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, GICv3State, num_cpu, vmstate_gicv3_cpu, GICv3CPUState), VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &vmstate_gicv3_gicd_no_migration_shift_bug, + NULL } }; @@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_reset(DeviceState *dev) gicv3_gicd_group_set(s, i); } } + s->gicd_no_migration_shift_bug = true; } static void arm_gic_common_linux_init(ARMLinuxBootIf *obj, diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -XXX,XX +XXX,XX @@ static void kvm_dist_get_edge_trigger(GICv3State *s, uint32_t offset, uint32_t reg; int irq; + /* For the KVM GICv3, affinity routing is always enabled, and the first 2 + * GICD_ICFGR<n> registers are always RAZ/WI. The corresponding + * functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync + * them. So it should increase the offset to skip GIC_INTERNAL irqs. + * This matches the for_each_dist_irq_reg() macro which also skips the + * first GIC_INTERNAL irqs. + */ + offset += (GIC_INTERNAL * 2) / 8; for_each_dist_irq_reg(irq, s->num_irq, 2) { kvm_gicd_access(s, offset, ®, false); reg = half_unshuffle32(reg >> 1); @@ -XXX,XX +XXX,XX @@ static void kvm_dist_put_edge_trigger(GICv3State *s, uint32_t offset, uint32_t reg; int irq; + /* For the KVM GICv3, affinity routing is always enabled, and the first 2 + * GICD_ICFGR<n> registers are always RAZ/WI. The corresponding + * functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync + * them. So it should increase the offset to skip GIC_INTERNAL irqs. + * This matches the for_each_dist_irq_reg() macro which also skips the + * first GIC_INTERNAL irqs. + */ + offset += (GIC_INTERNAL * 2) / 8; for_each_dist_irq_reg(irq, s->num_irq, 2) { reg = *gic_bmp_ptr32(bmp, irq); if (irq % 32 != 0) { @@ -XXX,XX +XXX,XX @@ static void kvm_dist_getbmp(GICv3State *s, uint32_t offset, uint32_t *bmp) uint32_t reg; int irq; + /* For the KVM GICv3, affinity routing is always enabled, and the + * GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/ + * GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding + * functionality is replaced by the GICR registers. It doesn't need to sync + * them. So it should increase the offset to skip GIC_INTERNAL irqs. + * This matches the for_each_dist_irq_reg() macro which also skips the + * first GIC_INTERNAL irqs. + */ + offset += (GIC_INTERNAL * 1) / 8; for_each_dist_irq_reg(irq, s->num_irq, 1) { kvm_gicd_access(s, offset, ®, false); *gic_bmp_ptr32(bmp, irq) = reg; @@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset, uint32_t reg; int irq; + /* For the KVM GICv3, affinity routing is always enabled, and the + * GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/ + * GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding + * functionality is replaced by the GICR registers. It doesn't need to sync + * them. So it should increase the offset and clroffset to skip GIC_INTERNAL + * irqs. This matches the for_each_dist_irq_reg() macro which also skips the + * first GIC_INTERNAL irqs. + */ + offset += (GIC_INTERNAL * 1) / 8; + if (clroffset != 0) { + clroffset += (GIC_INTERNAL * 1) / 8; + } + for_each_dist_irq_reg(irq, s->num_irq, 1) { /* If this bitmap is a set/clear register pair, first write to the * clear-reg to clear all bits before using the set-reg to write -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20180530064049.27976-2-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/aspeed.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data) mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_parallel = 1; - mc->ignore_memory_transaction_failures = true; } static const TypeInfo palmetto_bmc_type = { @@ -XXX,XX +XXX,XX @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data) mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_parallel = 1; - mc->ignore_memory_transaction_failures = true; } static const TypeInfo ast2500_evb_type = { @@ -XXX,XX +XXX,XX @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data) mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_parallel = 1; - mc->ignore_memory_transaction_failures = true; } static const TypeInfo romulus_bmc_type = { -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The Witherspoon boards are OpenPOWER system hosting POWER9 Processors. Add support for their BMC including a couple of I2C devices as found on real HW. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Message-id: 20180530064049.27976-3-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/aspeed.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ enum { PALMETTO_BMC, AST2500_EVB, ROMULUS_BMC, + WITHERSPOON_BMC, }; /* Palmetto hardware value: 0x120CE416 */ @@ -XXX,XX +XXX,XX @@ enum { SCU_AST2500_HW_STRAP_ACPI_ENABLE | \ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER)) +/* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */ +#define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1 + static void palmetto_bmc_i2c_init(AspeedBoardState *bmc); static void ast2500_evb_i2c_init(AspeedBoardState *bmc); +static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc); static const AspeedBoardConfig aspeed_boards[] = { [PALMETTO_BMC] = { @@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = { .spi_model = "mx66l1g45g", .num_cs = 2, }, + [WITHERSPOON_BMC] = { + .soc_name = "ast2500-a1", + .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1, + .fmc_model = "mx25l25635e", + .spi_model = "mx66l1g45g", + .num_cs = 2, + .i2c_init = witherspoon_bmc_i2c_init, + }, }; #define FIRMWARE_ADDR 0x0 @@ -XXX,XX +XXX,XX @@ static const TypeInfo romulus_bmc_type = { .class_init = romulus_bmc_class_init, }; +static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) +{ + AspeedSoCState *soc = &bmc->soc; + + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c); + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c); + + /* The Witherspoon expects a TMP275 but a TMP105 is compatible */ + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a); +} + +static void witherspoon_bmc_init(MachineState *machine) +{ + aspeed_board_init(machine, &aspeed_boards[WITHERSPOON_BMC]); +} + +static void witherspoon_bmc_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)"; + mc->init = witherspoon_bmc_init; + mc->max_cpus = 1; + mc->no_sdcard = 1; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->no_parallel = 1; +} + +static const TypeInfo witherspoon_bmc_type = { + .name = MACHINE_TYPE_NAME("witherspoon-bmc"), + .parent = TYPE_MACHINE, + .class_init = witherspoon_bmc_class_init, +}; + static void aspeed_machine_init(void) { type_register_static(&palmetto_bmc_type); type_register_static(&ast2500_evb_type); type_register_static(&romulus_bmc_type); + type_register_static(&witherspoon_bmc_type); } type_init(aspeed_machine_init) -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The AST2500 EVB does not have an RTC but we can pretend that one is plugged on the I2C bus header. The romulus and witherspoon boards expects an Epson RX8900 I2C RTC but a ds1338 is good enough for the basic features we need. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Message-id: 20180530064049.27976-4-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/aspeed.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ enum { static void palmetto_bmc_i2c_init(AspeedBoardState *bmc); static void ast2500_evb_i2c_init(AspeedBoardState *bmc); +static void romulus_bmc_i2c_init(AspeedBoardState *bmc); static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc); static const AspeedBoardConfig aspeed_boards[] = { @@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = { .fmc_model = "n25q256a", .spi_model = "mx66l1g45g", .num_cs = 2, + .i2c_init = romulus_bmc_i2c_init, }, [WITHERSPOON_BMC] = { .soc_name = "ast2500-a1", @@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc) /* The AST2500 EVB expects a LM75 but a TMP105 is compatible */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d); + + /* The AST2500 EVB does not have an RTC. Let's pretend that one is + * plugged on the I2C bus header */ + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); } static void ast2500_evb_init(MachineState *machine) @@ -XXX,XX +XXX,XX @@ static const TypeInfo ast2500_evb_type = { .class_init = ast2500_evb_class_init, }; +static void romulus_bmc_i2c_init(AspeedBoardState *bmc) +{ + AspeedSoCState *soc = &bmc->soc; + + /* The romulus board expects Epson RX8900 I2C RTC but a ds1338 is + * good enough */ + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); +} + static void romulus_bmc_init(MachineState *machine) { aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]); @@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) /* The Witherspoon expects a TMP275 but a TMP105 is compatible */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a); + + /* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is + * good enough */ + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); } static void witherspoon_bmc_init(MachineState *machine) -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> This is an helper routine to add a single EEPROM on an I2C bus. It can be directly used by smbus_eeprom_init() which adds a certain number of EEPROMs on mips and x86 machines. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530064049.27976-5-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/i2c/smbus.h | 1 + hw/i2c/smbus_eeprom.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/i2c/smbus.h +++ b/include/hw/i2c/smbus.h @@ -XXX,XX +XXX,XX @@ int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data); int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data, int len); +void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf); void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, const uint8_t *eeprom_spd, int size); diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i2c/smbus_eeprom.c +++ b/hw/i2c/smbus_eeprom.c @@ -XXX,XX +XXX,XX @@ static void smbus_eeprom_register_types(void) type_init(smbus_eeprom_register_types) +void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf) +{ + DeviceState *dev; + + dev = qdev_create((BusState *) smbus, "smbus-eeprom"); + qdev_prop_set_uint8(dev, "address", address); + qdev_prop_set_ptr(dev, "data", eeprom_buf); + qdev_init_nofail(dev); +} + void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, const uint8_t *eeprom_spd, int eeprom_spd_size) { @@ -XXX,XX +XXX,XX @@ void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, } for (i = 0; i < nb_eeprom; i++) { - DeviceState *eeprom; - eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_prop_set_uint8(eeprom, "address", 0x50 + i); - qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); - qdev_init_nofail(eeprom); + smbus_eeprom_init_one(smbus, 0x50 + i, eeprom_buf + (i * 256)); } } -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The Aspeed boards have at least one EEPROM to hold the Vital Product Data (VPD). Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Message-id: 20180530064049.27976-6-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/aspeed.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ #include "hw/arm/arm.h" #include "hw/arm/aspeed_soc.h" #include "hw/boards.h" +#include "hw/i2c/smbus.h" #include "qemu/log.h" #include "sysemu/block-backend.h" #include "hw/loader.h" @@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_i2c_init(AspeedBoardState *bmc) { AspeedSoCState *soc = &bmc->soc; DeviceState *dev; + uint8_t *eeprom_buf = g_malloc0(32 * 1024); /* The palmetto platform expects a ds3231 RTC but a ds1338 is * enough to provide basic RTC features. Alarms will be missing */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68); + smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), 0x50, + eeprom_buf); + /* add a TMP423 temperature sensor */ dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), "tmp423", 0x4c); @@ -XXX,XX +XXX,XX @@ static const TypeInfo palmetto_bmc_type = { static void ast2500_evb_i2c_init(AspeedBoardState *bmc) { AspeedSoCState *soc = &bmc->soc; + uint8_t *eeprom_buf = g_malloc0(8 * 1024); + + smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), 0x50, + eeprom_buf); /* The AST2500 EVB expects a LM75 but a TMP105 is compatible */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d); @@ -XXX,XX +XXX,XX @@ static const TypeInfo romulus_bmc_type = { static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) { AspeedSoCState *soc = &bmc->soc; + uint8_t *eeprom_buf = g_malloc0(8 * 1024); i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c); i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c); @@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) /* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is * good enough */ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); + + smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51, + eeprom_buf); } static void witherspoon_bmc_init(MachineState *machine) -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> Specs are available here : https://www.nxp.com/docs/en/application-note/AN264.pdf This is a simple model supporting the basic registers for led and GPIO mode. The device also supports two blinking rates but not the model yet. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530064049.27976-7-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/misc/Makefile.objs | 1 + tests/Makefile.include | 2 + include/hw/misc/pca9552.h | 32 +++++ include/hw/misc/pca9552_regs.h | 32 +++++ tests/libqos/i2c.h | 2 + hw/misc/pca9552.c | 240 ++++++++++++++++++++++++++++++++ tests/pca9552-test.c | 116 +++++++++++++++ tests/tmp105-test.c | 2 - default-configs/arm-softmmu.mak | 1 + 9 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 include/hw/misc/pca9552.h create mode 100644 include/hw/misc/pca9552_regs.h create mode 100644 hw/misc/pca9552.c create mode 100644 tests/pca9552-test.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SGA) += sga.o common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o common-obj-$(CONFIG_EDU) += edu.o +common-obj-$(CONFIG_PCA9552) += pca9552.o common-obj-y += unimp.o common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o diff --git a/tests/Makefile.include b/tests/Makefile.include index XXXXXXX..XXXXXXX 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -XXX,XX +XXX,XX @@ check-qtest-sparc64-y += tests/prom-env-test$(EXESUF) check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF) check-qtest-arm-y = tests/tmp105-test$(EXESUF) +check-qtest-arm-y += tests/pca9552-test$(EXESUF) check-qtest-arm-y += tests/ds1338-test$(EXESUF) check-qtest-arm-y += tests/m25p80-test$(EXESUF) gcov-files-arm-y += hw/misc/tmp105.c @@ -XXX,XX +XXX,XX @@ tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y) tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y) tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) +tests/pca9552-test$(EXESUF): tests/pca9552-test.o $(libqos-omap-obj-y) tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y) tests/m25p80-test$(EXESUF): tests/m25p80-test.o tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) diff --git a/include/hw/misc/pca9552.h b/include/hw/misc/pca9552.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/include/hw/misc/pca9552.h @@ -XXX,XX +XXX,XX @@ +/* + * PCA9552 I2C LED blinker + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ +#ifndef PCA9552_H +#define PCA9552_H + +#include "hw/i2c/i2c.h" + +#define TYPE_PCA9552 "pca9552" +#define PCA9552(obj) OBJECT_CHECK(PCA9552State, (obj), TYPE_PCA9552) + +#define PCA9552_NR_REGS 10 + +typedef struct PCA9552State { + /*< private >*/ + I2CSlave i2c; + /*< public >*/ + + uint8_t len; + uint8_t pointer; + + uint8_t regs[PCA9552_NR_REGS]; + uint8_t max_reg; + uint8_t nr_leds; +} PCA9552State; + +#endif diff --git a/include/hw/misc/pca9552_regs.h b/include/hw/misc/pca9552_regs.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/include/hw/misc/pca9552_regs.h @@ -XXX,XX +XXX,XX @@ +/* + * PCA9552 I2C LED blinker registers + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ +#ifndef PCA9552_REGS_H +#define PCA9552_REGS_H + +/* + * Bits [0:3] are used to address a specific register. + */ +#define PCA9552_INPUT0 0 /* read only input register 0 */ +#define PCA9552_INPUT1 1 /* read only input register 1 */ +#define PCA9552_PSC0 2 /* read/write frequency prescaler 0 */ +#define PCA9552_PWM0 3 /* read/write PWM register 0 */ +#define PCA9552_PSC1 4 /* read/write frequency prescaler 1 */ +#define PCA9552_PWM1 5 /* read/write PWM register 1 */ +#define PCA9552_LS0 6 /* read/write LED0 to LED3 selector */ +#define PCA9552_LS1 7 /* read/write LED4 to LED7 selector */ +#define PCA9552_LS2 8 /* read/write LED8 to LED11 selector */ +#define PCA9552_LS3 9 /* read/write LED12 to LED15 selector */ + +/* + * Bit [4] is used to activate the Auto-Increment option of the + * register address + */ +#define PCA9552_AUTOINC (1 << 4) + +#endif diff --git a/tests/libqos/i2c.h b/tests/libqos/i2c.h index XXXXXXX..XXXXXXX 100644 --- a/tests/libqos/i2c.h +++ b/tests/libqos/i2c.h @@ -XXX,XX +XXX,XX @@ struct I2CAdapter { QTestState *qts; }; +#define OMAP2_I2C_1_BASE 0x48070000 + void i2c_send(I2CAdapter *i2c, uint8_t addr, const uint8_t *buf, uint16_t len); void i2c_recv(I2CAdapter *i2c, uint8_t addr, diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/hw/misc/pca9552.c @@ -XXX,XX +XXX,XX @@ +/* + * PCA9552 I2C LED blinker + * + * https://www.nxp.com/docs/en/application-note/AN264.pdf + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/hw.h" +#include "hw/misc/pca9552.h" +#include "hw/misc/pca9552_regs.h" + +#define PCA9552_LED_ON 0x0 +#define PCA9552_LED_OFF 0x1 +#define PCA9552_LED_PWM0 0x2 +#define PCA9552_LED_PWM1 0x3 + +static uint8_t pca9552_pin_get_config(PCA9552State *s, int pin) +{ + uint8_t reg = PCA9552_LS0 + (pin / 4); + uint8_t shift = (pin % 4) << 1; + + return extract32(s->regs[reg], shift, 2); +} + +static void pca9552_update_pin_input(PCA9552State *s) +{ + int i; + + for (i = 0; i < s->nr_leds; i++) { + uint8_t input_reg = PCA9552_INPUT0 + (i / 8); + uint8_t input_shift = (i % 8); + uint8_t config = pca9552_pin_get_config(s, i); + + switch (config) { + case PCA9552_LED_ON: + s->regs[input_reg] |= 1 << input_shift; + break; + case PCA9552_LED_OFF: + s->regs[input_reg] &= ~(1 << input_shift); + break; + case PCA9552_LED_PWM0: + case PCA9552_LED_PWM1: + /* TODO */ + default: + break; + } + } +} + +static uint8_t pca9552_read(PCA9552State *s, uint8_t reg) +{ + switch (reg) { + case PCA9552_INPUT0: + case PCA9552_INPUT1: + case PCA9552_PSC0: + case PCA9552_PWM0: + case PCA9552_PSC1: + case PCA9552_PWM1: + case PCA9552_LS0: + case PCA9552_LS1: + case PCA9552_LS2: + case PCA9552_LS3: + return s->regs[reg]; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected read to register %d\n", + __func__, reg); + return 0xFF; + } +} + +static void pca9552_write(PCA9552State *s, uint8_t reg, uint8_t data) +{ + switch (reg) { + case PCA9552_PSC0: + case PCA9552_PWM0: + case PCA9552_PSC1: + case PCA9552_PWM1: + s->regs[reg] = data; + break; + + case PCA9552_LS0: + case PCA9552_LS1: + case PCA9552_LS2: + case PCA9552_LS3: + s->regs[reg] = data; + pca9552_update_pin_input(s); + break; + + case PCA9552_INPUT0: + case PCA9552_INPUT1: + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected write to register %d\n", + __func__, reg); + } +} + +/* + * When Auto-Increment is on, the register address is incremented + * after each byte is sent to or received by the device. The index + * rollovers to 0 when the maximum register address is reached. + */ +static void pca9552_autoinc(PCA9552State *s) +{ + if (s->pointer != 0xFF && s->pointer & PCA9552_AUTOINC) { + uint8_t reg = s->pointer & 0xf; + + reg = (reg + 1) % (s->max_reg + 1); + s->pointer = reg | PCA9552_AUTOINC; + } +} + +static int pca9552_recv(I2CSlave *i2c) +{ + PCA9552State *s = PCA9552(i2c); + uint8_t ret; + + ret = pca9552_read(s, s->pointer & 0xf); + + /* + * From the Specs: + * + * Important Note: When a Read sequence is initiated and the + * AI bit is set to Logic Level 1, the Read Sequence MUST + * start by a register different from 0. + * + * I don't know what should be done in this case, so throw an + * error. + */ + if (s->pointer == PCA9552_AUTOINC) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Autoincrement read starting with register 0\n", + __func__); + } + + pca9552_autoinc(s); + + return ret; +} + +static int pca9552_send(I2CSlave *i2c, uint8_t data) +{ + PCA9552State *s = PCA9552(i2c); + + /* First byte sent by is the register address */ + if (s->len == 0) { + s->pointer = data; + s->len++; + } else { + pca9552_write(s, s->pointer & 0xf, data); + + pca9552_autoinc(s); + } + + return 0; +} + +static int pca9552_event(I2CSlave *i2c, enum i2c_event event) +{ + PCA9552State *s = PCA9552(i2c); + + s->len = 0; + return 0; +} + +static const VMStateDescription pca9552_vmstate = { + .name = "PCA9552", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT8(len, PCA9552State), + VMSTATE_UINT8(pointer, PCA9552State), + VMSTATE_UINT8_ARRAY(regs, PCA9552State, PCA9552_NR_REGS), + VMSTATE_I2C_SLAVE(i2c, PCA9552State), + VMSTATE_END_OF_LIST() + } +}; + +static void pca9552_reset(DeviceState *dev) +{ + PCA9552State *s = PCA9552(dev); + + s->regs[PCA9552_PSC0] = 0xFF; + s->regs[PCA9552_PWM0] = 0x80; + s->regs[PCA9552_PSC1] = 0xFF; + s->regs[PCA9552_PWM1] = 0x80; + s->regs[PCA9552_LS0] = 0x55; /* all OFF */ + s->regs[PCA9552_LS1] = 0x55; + s->regs[PCA9552_LS2] = 0x55; + s->regs[PCA9552_LS3] = 0x55; + + pca9552_update_pin_input(s); + + s->pointer = 0xFF; + s->len = 0; +} + +static void pca9552_initfn(Object *obj) +{ + PCA9552State *s = PCA9552(obj); + + /* If support for the other PCA955X devices are implemented, these + * constant values might be part of class structure describing the + * PCA955X device + */ + s->max_reg = PCA9552_LS3; + s->nr_leds = 16; +} + +static void pca9552_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); + + k->event = pca9552_event; + k->recv = pca9552_recv; + k->send = pca9552_send; + dc->reset = pca9552_reset; + dc->vmsd = &pca9552_vmstate; +} + +static const TypeInfo pca9552_info = { + .name = TYPE_PCA9552, + .parent = TYPE_I2C_SLAVE, + .instance_init = pca9552_initfn, + .instance_size = sizeof(PCA9552State), + .class_init = pca9552_class_init, +}; + +static void pca9552_register_types(void) +{ + type_register_static(&pca9552_info); +} + +type_init(pca9552_register_types) diff --git a/tests/pca9552-test.c b/tests/pca9552-test.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/pca9552-test.c @@ -XXX,XX +XXX,XX @@ +/* + * QTest testcase for the PCA9552 LED blinker + * + * Copyright (c) 2017-2018, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "libqtest.h" +#include "libqos/i2c.h" +#include "hw/misc/pca9552_regs.h" + +#define PCA9552_TEST_ID "pca9552-test" +#define PCA9552_TEST_ADDR 0x60 + +static I2CAdapter *i2c; + +static uint8_t pca9552_get8(I2CAdapter *i2c, uint8_t addr, uint8_t reg) +{ + uint8_t resp[1]; + i2c_send(i2c, addr, ®, 1); + i2c_recv(i2c, addr, resp, 1); + return resp[0]; +} + +static void pca9552_set8(I2CAdapter *i2c, uint8_t addr, uint8_t reg, + uint8_t value) +{ + uint8_t cmd[2]; + uint8_t resp[1]; + + cmd[0] = reg; + cmd[1] = value; + i2c_send(i2c, addr, cmd, 2); + i2c_recv(i2c, addr, resp, 1); + g_assert_cmphex(resp[0], ==, cmd[1]); +} + +static void receive_autoinc(void) +{ + uint8_t resp; + uint8_t reg = PCA9552_LS0 | PCA9552_AUTOINC; + + i2c_send(i2c, PCA9552_TEST_ADDR, ®, 1); + + /* PCA9552_LS0 */ + i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1); + g_assert_cmphex(resp, ==, 0x54); + + /* PCA9552_LS1 */ + i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1); + g_assert_cmphex(resp, ==, 0x55); + + /* PCA9552_LS2 */ + i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1); + g_assert_cmphex(resp, ==, 0x55); + + /* PCA9552_LS3 */ + i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1); + g_assert_cmphex(resp, ==, 0x54); +} + +static void send_and_receive(void) +{ + uint8_t value; + + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0); + g_assert_cmphex(value, ==, 0x55); + + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0); + g_assert_cmphex(value, ==, 0x0); + + /* Switch on LED 0 */ + pca9552_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0, 0x54); + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0); + g_assert_cmphex(value, ==, 0x54); + + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0); + g_assert_cmphex(value, ==, 0x01); + + /* Switch on LED 12 */ + pca9552_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3, 0x54); + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3); + g_assert_cmphex(value, ==, 0x54); + + value = pca9552_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT1); + g_assert_cmphex(value, ==, 0x10); +} + +int main(int argc, char **argv) +{ + QTestState *s = NULL; + int ret; + + g_test_init(&argc, &argv, NULL); + + s = qtest_start("-machine n800 " + "-device pca9552,bus=i2c-bus.0,id=" PCA9552_TEST_ID + ",address=0x60"); + i2c = omap_i2c_create(s, OMAP2_I2C_1_BASE); + + qtest_add_func("/pca9552/tx-rx", send_and_receive); + qtest_add_func("/pca9552/rx-autoinc", receive_autoinc); + + ret = g_test_run(); + + if (s) { + qtest_quit(s); + } + g_free(i2c); + + return ret; +} diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c index XXXXXXX..XXXXXXX 100644 --- a/tests/tmp105-test.c +++ b/tests/tmp105-test.c @@ -XXX,XX +XXX,XX @@ #include "qapi/qmp/qdict.h" #include "hw/misc/tmp105_regs.h" -#define OMAP2_I2C_1_BASE 0x48070000 - #define TMP105_TEST_ID "tmp105-test" #define TMP105_TEST_ADDR 0x49 diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index XXXXXXX..XXXXXXX 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -XXX,XX +XXX,XX @@ CONFIG_TSC2005=y CONFIG_LM832X=y CONFIG_TMP105=y CONFIG_TMP421=y +CONFIG_PCA9552=y CONFIG_STELLARIS=y CONFIG_STELLARIS_INPUT=y CONFIG_STELLARIS_ENET=y -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The pca9552 LED blinkers on the Witherspoon machine are used for leds but also as GPIOs to control fans and GPUs. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530064049.27976-8-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/aspeed.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) AspeedSoCState *soc = &bmc->soc; uint8_t *eeprom_buf = g_malloc0(8 * 1024); + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60); + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c); i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c); @@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51, eeprom_buf); + i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552", + 0x60); } static void witherspoon_bmc_init(MachineState *machine) -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The maximum frame size includes the CRC and depends if a VLAN tag is inserted or not. Adjust the frame size limit in the transmit handler using on the FTGMAC100State buffer size and in the receive handler use the packet protocol. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530061711.23673-2-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/net/ftgmac100.h | 7 ++++++- hw/net/ftgmac100.c | 23 ++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/hw/net/ftgmac100.h b/include/hw/net/ftgmac100.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/net/ftgmac100.h +++ b/include/hw/net/ftgmac100.h @@ -XXX,XX +XXX,XX @@ #include "hw/sysbus.h" #include "net/net.h" +/* + * Max frame size for the receiving buffer + */ +#define FTGMAC100_MAX_FRAME_SIZE 9220 + typedef struct FTGMAC100State { /*< private >*/ SysBusDevice parent_obj; @@ -XXX,XX +XXX,XX @@ typedef struct FTGMAC100State { qemu_irq irq; MemoryRegion iomem; - uint8_t *frame; + uint8_t frame[FTGMAC100_MAX_FRAME_SIZE]; uint32_t irq_state; uint32_t isr; diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -XXX,XX +XXX,XX @@ typedef struct { /* * Max frame size for the receiving buffer */ -#define FTGMAC100_MAX_FRAME_SIZE 10240 +#define FTGMAC100_MAX_FRAME_SIZE 9220 /* Limits depending on the type of the frame * * 9216 for Jumbo frames (+ 4 for VLAN) * 1518 for other frames (+ 4 for VLAN) */ -static int ftgmac100_max_frame_size(FTGMAC100State *s) +static int ftgmac100_max_frame_size(FTGMAC100State *s, uint16_t proto) { - return (s->maccr & FTGMAC100_MACCR_JUMBO_LF ? 9216 : 1518) + 4; + int max = (s->maccr & FTGMAC100_MACCR_JUMBO_LF ? 9216 : 1518); + + return max + (proto == ETH_P_VLAN ? 4 : 0); } static void ftgmac100_update_irq(FTGMAC100State *s) @@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, uint8_t *ptr = s->frame; uint32_t addr = tx_descriptor; uint32_t flags = 0; - int max_frame_size = ftgmac100_max_frame_size(s); while (1) { FTGMAC100Desc bd; @@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, flags = bd.des1; } - len = bd.des0 & 0x3FFF; - if (frame_size + len > max_frame_size) { + len = FTGMAC100_TXDES0_TXBUF_SIZE(bd.des0); + if (frame_size + len > sizeof(s->frame)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n", __func__, len); - len = max_frame_size - frame_size; + s->isr |= FTGMAC100_INT_XPKT_LOST; + len = sizeof(s->frame) - frame_size; } if (dma_memory_read(&address_space_memory, bd.des3, ptr, len)) { @@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, uint32_t buf_len; size_t size = len; uint32_t first = FTGMAC100_RXDES0_FRS; - int max_frame_size = ftgmac100_max_frame_size(s); + uint16_t proto = be16_to_cpu(PKT_GET_ETH_HDR(buf)->h_proto); + int max_frame_size = ftgmac100_max_frame_size(s, proto); if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) != (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) { @@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, /* Huge frames are truncated. */ if (size > max_frame_size) { - size = max_frame_size; qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %zd bytes\n", __func__, size); + size = max_frame_size; flags |= FTGMAC100_RXDES0_FTL; } @@ -XXX,XX +XXX,XX @@ static void ftgmac100_realize(DeviceState *dev, Error **errp) object_get_typename(OBJECT(dev)), DEVICE(dev)->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - - s->frame = g_malloc(FTGMAC100_MAX_FRAME_SIZE); } static const VMStateDescription vmstate_ftgmac100 = { -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> The ftgmac100 NIC supports VLAN tag insertion and the MAC engine also has a control to remove VLAN tags from received packets. The VLAN control bits and VLAN tag information are contained in the second word of the transmit and receive descriptors. The Insert VLAN bit and the VLAN Tag available bit are only valid in the first segment of the packet. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530061711.23673-3-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/net/ftgmac100.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, break; } + /* Check for VLAN */ + if (bd.des0 & FTGMAC100_TXDES0_FTS && + bd.des1 & FTGMAC100_TXDES1_INS_VLANTAG && + be16_to_cpu(PKT_GET_ETH_HDR(ptr)->h_proto) != ETH_P_VLAN) { + if (frame_size + len + 4 > sizeof(s->frame)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n", + __func__, len); + s->isr |= FTGMAC100_INT_XPKT_LOST; + len = sizeof(s->frame) - frame_size - 4; + } + memmove(ptr + 16, ptr + 12, len - 12); + stw_be_p(ptr + 12, ETH_P_VLAN); + stw_be_p(ptr + 14, bd.des1); + len += 4; + } + ptr += len; frame_size += len; if (bd.des0 & FTGMAC100_TXDES0_LTS) { @@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, buf_len += size - 4; } buf_addr = bd.des3; - dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); + if (first && proto == ETH_P_VLAN && buf_len >= 18) { + bd.des1 = lduw_be_p(buf + 14) | FTGMAC100_RXDES1_VLANTAG_AVAIL; + + if (s->maccr & FTGMAC100_MACCR_RM_VLAN) { + dma_memory_write(&address_space_memory, buf_addr, buf, 12); + dma_memory_write(&address_space_memory, buf_addr + 12, buf + 16, + buf_len - 16); + } else { + dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); + } + } else { + bd.des1 = 0; + dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); + } buf += buf_len; if (size < 4) { dma_memory_write(&address_space_memory, buf_addr + buf_len, -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> Based on the multicast hash calculation of the FTGMAC100 Linux driver. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180530061711.23673-4-clg@kaod.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/net/ftgmac100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -XXX,XX +XXX,XX @@ static int ftgmac100_filter(FTGMAC100State *s, const uint8_t *buf, size_t len) return 0; } - /* TODO: this does not seem to work for ftgmac100 */ - mcast_idx = net_crc32(buf, ETH_ALEN) >> 26; + mcast_idx = net_crc32_le(buf, ETH_ALEN); + mcast_idx = (~(mcast_idx >> 2)) & 0x3f; if (!(s->math[mcast_idx / 32] & (1 << (mcast_idx % 32)))) { return 0; } -- 2.17.1
From: Cédric Le Goater <clg@kaod.org> This is a ethernet wire limitation not needed in emulation. It breaks U-Boot n/w stack also. Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-id: 20180530061711.23673-5-clg@kaod.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/net/ftgmac100.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, return size; } - if (size < 64 && !(s->maccr & FTGMAC100_MACCR_RX_RUNT)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped runt frame of %zd bytes\n", - __func__, size); - return size; - } - if (!ftgmac100_filter(s, buf, size)) { return size; } -- 2.17.1
From: Thomas Huth <thuth@redhat.com> It has been marked as deprecated since QEMU v2.11, so it is time to remove this now. The xlnx-zcu102 machine is very much the same and can be used as a replacement instead. Signed-off-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/xlnx-zcu102.c | 62 ++------------------------------------------ qemu-doc.texi | 5 ---- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -XXX,XX +XXX,XX @@ typedef struct XlnxZCU102 { #define ZCU102_MACHINE(obj) \ OBJECT_CHECK(XlnxZCU102, (obj), TYPE_ZCU102_MACHINE) -#define TYPE_EP108_MACHINE MACHINE_TYPE_NAME("xlnx-ep108") -#define EP108_MACHINE(obj) \ - OBJECT_CHECK(XlnxZCU102, (obj), TYPE_EP108_MACHINE) - static struct arm_boot_info xlnx_zcu102_binfo; static bool zcu102_get_secure(Object *obj, Error **errp) @@ -XXX,XX +XXX,XX @@ static void zcu102_set_virt(Object *obj, bool value, Error **errp) s->virt = value; } -static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine) +static void xlnx_zcu102_init(MachineState *machine) { + XlnxZCU102 *s = ZCU102_MACHINE(machine); int i; uint64_t ram_size = machine->ram_size; @@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine) arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_zcu102_binfo); } -static void xlnx_ep108_init(MachineState *machine) -{ - XlnxZCU102 *s = EP108_MACHINE(machine); - - if (!qtest_enabled()) { - info_report("The Xilinx EP108 machine is deprecated, please use the " - "ZCU102 machine (which has the same features) instead."); - } - - xlnx_zynqmp_init(s, machine); -} - -static void xlnx_ep108_machine_instance_init(Object *obj) -{ - XlnxZCU102 *s = EP108_MACHINE(obj); - - /* EP108, we don't support setting secure or virt */ - s->secure = false; - s->virt = false; -} - -static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "Xilinx ZynqMP EP108 board (Deprecated, please use xlnx-zcu102)"; - mc->init = xlnx_ep108_init; - mc->block_default_type = IF_IDE; - mc->units_per_default_bus = 1; - mc->ignore_memory_transaction_failures = true; - mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS; - mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS; -} - -static const TypeInfo xlnx_ep108_machine_init_typeinfo = { - .name = MACHINE_TYPE_NAME("xlnx-ep108"), - .parent = TYPE_MACHINE, - .class_init = xlnx_ep108_machine_class_init, - .instance_init = xlnx_ep108_machine_instance_init, - .instance_size = sizeof(XlnxZCU102), -}; - -static void xlnx_ep108_machine_init_register_types(void) -{ - type_register_static(&xlnx_ep108_machine_init_typeinfo); -} - -static void xlnx_zcu102_init(MachineState *machine) -{ - XlnxZCU102 *s = ZCU102_MACHINE(machine); - - xlnx_zynqmp_init(s, machine); -} - static void xlnx_zcu102_machine_instance_init(Object *obj) { XlnxZCU102 *s = ZCU102_MACHINE(obj); @@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_init_register_types(void) } type_init(xlnx_zcu102_machine_init_register_types) -type_init(xlnx_ep108_machine_init_register_types) diff --git a/qemu-doc.texi b/qemu-doc.texi index XXXXXXX..XXXXXXX 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -XXX,XX +XXX,XX @@ support page sizes < 4096 any longer. @section System emulator machines -@subsection Xilinx EP108 (since 2.11.0) - -The ``xlnx-ep108'' machine has been replaced by the ``xlnx-zcu102'' machine. -The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU. - @section Block device options @subsection "backing": "" (since 2.12.0) -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606191801.6331-1-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- Makefile.objs | 1 + hw/i2c/core.c | 25 ++++++++++++++++++------- hw/i2c/trace-events | 7 +++++++ 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 hw/i2c/trace-events diff --git a/Makefile.objs b/Makefile.objs index XXXXXXX..XXXXXXX 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -XXX,XX +XXX,XX @@ trace-events-subdirs += hw/char trace-events-subdirs += hw/display trace-events-subdirs += hw/dma trace-events-subdirs += hw/hppa +trace-events-subdirs += hw/i2c trace-events-subdirs += hw/i386 trace-events-subdirs += hw/i386/xen trace-events-subdirs += hw/ide diff --git a/hw/i2c/core.c b/hw/i2c/core.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "hw/i2c/i2c.h" +#include "trace.h" #define I2C_BROADCAST 0x00 @@ -XXX,XX +XXX,XX @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv) } QLIST_FOREACH(node, &bus->current_devs, next) { + I2CSlave *s = node->elt; int rv; - sc = I2C_SLAVE_GET_CLASS(node->elt); + sc = I2C_SLAVE_GET_CLASS(s); /* If the bus is already busy, assume this is a repeated start condition. */ if (sc->event) { - rv = sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND); + trace_i2c_event("start", s->address); + rv = sc->event(s, recv ? I2C_START_RECV : I2C_START_SEND); if (rv && !bus->broadcast) { if (bus_scanned) { /* First call, terminate the transfer. */ @@ -XXX,XX +XXX,XX @@ void i2c_end_transfer(I2CBus *bus) I2CNode *node, *next; QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) { - sc = I2C_SLAVE_GET_CLASS(node->elt); + I2CSlave *s = node->elt; + sc = I2C_SLAVE_GET_CLASS(s); if (sc->event) { - sc->event(node->elt, I2C_FINISH); + trace_i2c_event("finish", s->address); + sc->event(s, I2C_FINISH); } QLIST_REMOVE(node, next); g_free(node); @@ -XXX,XX +XXX,XX @@ void i2c_end_transfer(I2CBus *bus) int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send) { I2CSlaveClass *sc; + I2CSlave *s; I2CNode *node; int ret = 0; if (send) { QLIST_FOREACH(node, &bus->current_devs, next) { - sc = I2C_SLAVE_GET_CLASS(node->elt); + s = node->elt; + sc = I2C_SLAVE_GET_CLASS(s); if (sc->send) { - ret = ret || sc->send(node->elt, *data); + trace_i2c_send(s->address, *data); + ret = ret || sc->send(s, *data); } else { ret = -1; } @@ -XXX,XX +XXX,XX @@ int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send) sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt); if (sc->recv) { - ret = sc->recv(QLIST_FIRST(&bus->current_devs)->elt); + s = QLIST_FIRST(&bus->current_devs)->elt; + ret = sc->recv(s); + trace_i2c_recv(s->address, ret); if (ret < 0) { return ret; } else { @@ -XXX,XX +XXX,XX @@ void i2c_nack(I2CBus *bus) QLIST_FOREACH(node, &bus->current_devs, next) { sc = I2C_SLAVE_GET_CLASS(node->elt); if (sc->event) { + trace_i2c_event("nack", node->elt->address); sc->event(node->elt, I2C_NACK); } } diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/hw/i2c/trace-events @@ -XXX,XX +XXX,XX @@ +# See docs/devel/tracing.txt for syntax documentation. + +# hw/i2c/core.c + +i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)" +i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x" +i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x" -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-2-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/sd/milkymist-memcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/milkymist-memcard.c +++ b/hw/sd/milkymist-memcard.c @@ -XXX,XX +XXX,XX @@ static uint64_t memcard_read(void *opaque, hwaddr addr, r = s->response[s->response_read_ptr++]; if (s->response_read_ptr > s->response_len) { qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: " - "read more cmd bytes than available. Clipping."); + "read more cmd bytes than available: clipping\n"); s->response_read_ptr = 0; } } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-3-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/char/digic-uart.c | 4 ++-- hw/timer/digic-timer.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c index XXXXXXX..XXXXXXX 100644 --- a/hw/char/digic-uart.c +++ b/hw/char/digic-uart.c @@ -XXX,XX +XXX,XX @@ static uint64_t digic_uart_read(void *opaque, hwaddr addr, default: qemu_log_mask(LOG_UNIMP, "digic-uart: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); + TARGET_FMT_plx "\n", addr << 2); } return ret; @@ -XXX,XX +XXX,XX @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value, default: qemu_log_mask(LOG_UNIMP, "digic-uart: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); + TARGET_FMT_plx "\n", addr << 2); } } diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/digic-timer.c +++ b/hw/timer/digic-timer.c @@ -XXX,XX +XXX,XX @@ static uint64_t digic_timer_read(void *opaque, hwaddr offset, unsigned size) default: qemu_log_mask(LOG_UNIMP, "digic-timer: read access to unknown register 0x" - TARGET_FMT_plx, offset); + TARGET_FMT_plx "\n", offset); } return ret; @@ -XXX,XX +XXX,XX @@ static void digic_timer_write(void *opaque, hwaddr offset, default: qemu_log_mask(LOG_UNIMP, "digic-timer: read access to unknown register 0x" - TARGET_FMT_plx, offset); + TARGET_FMT_plx "\n", offset); } } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180606152128.449-4-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/display/xlnx_dp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -XXX,XX +XXX,XX @@ static void xlnx_dp_avbufm_write(void *opaque, hwaddr offset, uint64_t value, case AV_BUF_STC_SNAPSHOT1: case AV_BUF_HCOUNT_VCOUNT_INT0: case AV_BUF_HCOUNT_VCOUNT_INT1: - qemu_log_mask(LOG_UNIMP, "avbufm: unimplmented"); + qemu_log_mask(LOG_UNIMP, "avbufm: unimplemented register 0x%04" + PRIx64 "\n", + offset << 2); break; default: s->avbufm_registers[offset] = value; -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Acked-by: David Gibson <david@gibson.dropbear.id.au> Message-id: 20180606152128.449-5-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/ppc/pnv_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index XXXXXXX..XXXXXXX 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -XXX,XX +XXX,XX @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr, val = 0x24f000000000000ull; break; default: - qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx, + qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", addr); } @@ -XXX,XX +XXX,XX @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr, static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val, unsigned int width) { - qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx, + qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n", addr); } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180606152128.449-6-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/core/register.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/core/register.c b/hw/core/register.c index XXXXXXX..XXXXXXX 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -XXX,XX +XXX,XX @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we, if (test) { qemu_log_mask(LOG_UNIMP, "%s:%s writing %#" PRIx64 " to unimplemented bits:" \ - " %#" PRIx64 "", + " %#" PRIx64 "\n", prefix, reg->access->name, val, ac->unimp); } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-7-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/mips/boston.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index XXXXXXX..XXXXXXX 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -XXX,XX +XXX,XX @@ static uint64_t boston_platreg_read(void *opaque, hwaddr addr, uint32_t gic_freq, val; if (size != 4) { - qemu_log_mask(LOG_UNIMP, "%uB platform register read", size); + qemu_log_mask(LOG_UNIMP, "%uB platform register read\n", size); return 0; } @@ -XXX,XX +XXX,XX @@ static uint64_t boston_platreg_read(void *opaque, hwaddr addr, val |= PLAT_DDR_CFG_MHZ; return val; default: - qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx, + qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx "\n", addr & 0xffff); return 0; } @@ -XXX,XX +XXX,XX @@ static void boston_platreg_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { if (size != 4) { - qemu_log_mask(LOG_UNIMP, "%uB platform register write", size); + qemu_log_mask(LOG_UNIMP, "%uB platform register write\n", size); return; } @@ -XXX,XX +XXX,XX @@ static void boston_platreg_write(void *opaque, hwaddr addr, break; default: qemu_log_mask(LOG_UNIMP, "Write platform register 0x%" HWADDR_PRIx - " = 0x%" PRIx64, addr & 0xffff, val); + " = 0x%" PRIx64 "\n", addr & 0xffff, val); break; } } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-8-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/stellaris.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -XXX,XX +XXX,XX @@ static uint64_t gptm_read(void *opaque, hwaddr offset, return s->rtc; } qemu_log_mask(LOG_UNIMP, - "GPTM: read of TAR but timer read not supported"); + "GPTM: read of TAR but timer read not supported\n"); return 0; case 0x4c: /* TBR */ qemu_log_mask(LOG_UNIMP, - "GPTM: read of TBR but timer read not supported"); + "GPTM: read of TBR but timer read not supported\n"); return 0; default: qemu_log_mask(LOG_GUEST_ERROR, @@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset, break; case 0x20: /* MCR */ if (value & 1) { - qemu_log_mask(LOG_UNIMP, "stellaris_i2c: Loopback not implemented"); + qemu_log_mask(LOG_UNIMP, + "stellaris_i2c: Loopback not implemented\n"); } if (value & 0x20) { qemu_log_mask(LOG_UNIMP, - "stellaris_i2c: Slave mode not implemented"); + "stellaris_i2c: Slave mode not implemented\n"); } s->mcr = value & 0x31; break; @@ -XXX,XX +XXX,XX @@ static void stellaris_adc_write(void *opaque, hwaddr offset, s->sspri = value; break; case 0x28: /* PSSI */ - qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented"); + qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented\n"); break; case 0x30: /* SAC */ s->sac = value; -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-9-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n) case 4: /* unlinked address mismatch (reserved if AArch64) */ case 5: /* linked address mismatch (reserved if AArch64) */ qemu_log_mask(LOG_UNIMP, - "arm: address mismatch breakpoint types not implemented"); + "arm: address mismatch breakpoint types not implemented\n"); return; case 0: /* unlinked address match */ case 1: /* linked address match */ @@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n) case 8: /* unlinked VMID match (reserved if no EL2) */ case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ qemu_log_mask(LOG_UNIMP, - "arm: unlinked context breakpoint types not implemented"); + "arm: unlinked context breakpoint types not implemented\n"); return; case 9: /* linked VMID match (reserved if no EL2) */ case 11: /* linked context ID and VMID match (reserved if no EL2) */ -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-id: 20180606152128.449-10-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/m68k/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index XXXXXXX..XXXXXXX 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -XXX,XX +XXX,XX @@ DISAS_INSN(undef) /* ??? This is both instructions that are as yet unimplemented for the 680x0 series, as well as those that are implemented but actually illegal for CPU32 or pre-68020. */ - qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x", + qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x\n", insn, s->insn_pc); gen_exception(s, s->insn_pc, EXCP_UNSUPPORTED); } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180606152128.449-11-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/riscv/op_helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -XXX,XX +XXX,XX @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, if ((val_to_write & 3) == 0) { env->stvec = val_to_write >> 2 << 2; } else { - qemu_log_mask(LOG_UNIMP, "CSR_STVEC: vectored traps not supported"); + qemu_log_mask(LOG_UNIMP, + "CSR_STVEC: vectored traps not supported\n"); } break; case CSR_SCOUNTEREN: @@ -XXX,XX +XXX,XX @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, if ((val_to_write & 3) == 0) { env->mtvec = val_to_write >> 2 << 2; } else { - qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: vectored traps not supported"); + qemu_log_mask(LOG_UNIMP, + "CSR_MTVEC: vectored traps not supported\n"); } break; case CSR_MCOUNTEREN: -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Acked-by: Max Filippov <jcmvbkbc@gmail.com> Message-id: 20180606152128.449-12-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/xtensa/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index XXXXXXX..XXXXXXX 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -XXX,XX +XXX,XX @@ static void translate_rur(DisasContext *dc, const uint32_t arg[], if (uregnames[par[0]].name) { tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]); } else { - qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", par[0]); + qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]); } } } @@ -XXX,XX +XXX,XX @@ static void translate_slli(DisasContext *dc, const uint32_t arg[], { if (gen_window_check2(dc, arg[0], arg[1])) { if (arg[2] == 32) { - qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined", + qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n", arg[0], arg[1]); } tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f); @@ -XXX,XX +XXX,XX @@ static void translate_wur(DisasContext *dc, const uint32_t arg[], if (uregnames[par[0]].name) { gen_wur(par[0], cpu_R[arg[0]]); } else { - qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", par[0]); + qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]); } } } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> The initial implementation is based on the Specs v1.10 (see a1bb27b1e98). However the SCR is anouncing the card being v1.01. The new chapters added in version 1.10 are: 4.3.10 Switch function command Switch function command (CMD6) 1 is used to switch or expand memory card functions. [...] This is a new feature, introduced in SD physical Layer Specification Version 1.10. Therefore, cards that are compatible with earlier versions of the spec do not support it. The host shall check the "SD_SPEC" field in the SCR register to recognize what version of the spec the card complies with before using CMD6. It is mandatory for SD memory card of Ver1.10 to support CMD6. 4.3.11 High-Speed mode (25MB/sec interface speed) Though the Rev 1.01 SD memory card supports up to 12.5MB/sec interface speed, the speed of 25MB/sec is necessary to support increasing performance needs of the host and because of memory size which continues to grow. To achieve 25MB/sec interface speed, clock rate is increased to 50MHz and CLK/CMD/DAT signal timing and circuit conditions are reconsidered and changed from Physical Layer Specification Version 1.01. 4.3.12 Command system (This chapter is newly added in version 1.10) SD commands CMD34-37, CMD50, CMD57 are reserved for SD command system expansion via the switch command. [These commands] will be considered as illegal commands (as defined in revision 1.01 of the SD physical layer specification). The SWITCH_FUNCTION is implemented since the first commit, a1bb27b1e98. The 25MB/sec High-Speed mode was already updated in d7ecb867529. The current implementation does not implements CMD34-37, CMD50 and CMD57, thus these commands already return ILLEGAL. With this patch, the SCR register now matches the description of the header: * SD Memory Card emulation as defined in the "SD Memory Card Physical * layer specification, Version 1.10." Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180607180641.874-2-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/sd/sd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static void sd_ocr_powerup(void *opaque) static void sd_set_scr(SDState *sd) { - sd->scr[0] = (0 << 4) /* SCR version 1.0 */ - | 0; /* Spec Versions 1.0 and 1.01 */ + sd->scr[0] = (0 << 4) /* SCR structure version 1.0 */ + | 1; /* Spec Version 1.10 */ sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */ | 0b0101; /* 1-bit or 4-bit width bus modes */ sd->scr[2] = 0x00; /* Extended Security is not supported. */ -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> From the "Physical Layer Simplified Specification Version 1.10" Chapter 7.3 "SPI Mode Transaction Packets" Table 57: "Commands and arguments" Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180607180641.874-3-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/sd/sd.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) return sd_illegal; case 6: /* CMD6: SWITCH_FUNCTION */ - if (sd->spi) - goto bad_cmd; switch (sd->mode) { case sd_data_transfer_mode: sd_function_switch(sd, req.arg); @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Block write commands (Class 4) */ case 24: /* CMD24: WRITE_SINGLE_BLOCK */ - if (sd->spi) { - goto unimplemented_spi_cmd; - } switch (sd->state) { case sd_transfer_state: /* Writing in SPI mode not implemented. */ @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ - if (sd->spi) { - goto unimplemented_spi_cmd; - } switch (sd->state) { case sd_transfer_state: /* Writing in SPI mode not implemented. */ @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 27: /* CMD27: PROGRAM_CSD */ - if (sd->spi) { - goto unimplemented_spi_cmd; - } switch (sd->state) { case sd_transfer_state: sd->state = sd_receivingdata_state; @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) /* Lock card commands (Class 7) */ case 42: /* CMD42: LOCK_UNLOCK */ - if (sd->spi) { - goto unimplemented_spi_cmd; - } switch (sd->state) { case sd_transfer_state: sd->state = sd_receivingdata_state; -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> As of this commit, the Spec v1 is not working, and all controllers expect the cards to be conformant to Spec v2. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180607180641.874-4-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/sd/sd.h | 5 +++++ hw/sd/sd.c | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -XXX,XX +XXX,XX @@ #define APP_CMD (1 << 5) #define AKE_SEQ_ERROR (1 << 3) +enum SDPhySpecificationVersion { + SD_PHY_SPECv1_10_VERS = 1, + SD_PHY_SPECv2_00_VERS = 2, +}; + typedef enum { SD_VOLTAGE_0_4V = 400, /* currently not supported */ SD_VOLTAGE_1_8V = 1800, diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ /* * SD Memory Card emulation as defined in the "SD Memory Card Physical - * layer specification, Version 1.10." + * layer specification, Version 2.00." * * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org> * Copyright (c) 2007 CodeSourcery + * Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -XXX,XX +XXX,XX @@ struct SDState { uint8_t sd_status[64]; /* Configurable properties */ + uint8_t spec_version; BlockBackend *blk; bool spi; @@ -XXX,XX +XXX,XX @@ static void sd_ocr_powerup(void *opaque) static void sd_set_scr(SDState *sd) { - sd->scr[0] = (0 << 4) /* SCR structure version 1.0 */ - | 1; /* Spec Version 1.10 */ + sd->scr[0] = 0 << 4; /* SCR structure version 1.0 */ + if (sd->spec_version == SD_PHY_SPECv1_10_VERS) { + sd->scr[0] |= 1; /* Spec Version 1.10 */ + } else { + sd->scr[0] |= 2; /* Spec Version 2.00 */ + } sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */ | 0b0101; /* 1-bit or 4-bit width bus modes */ sd->scr[2] = 0x00; /* Extended Security is not supported. */ @@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp) sd->proto_name = sd->spi ? "SPI" : "SD"; + switch (sd->spec_version) { + case SD_PHY_SPECv1_10_VERS + ... SD_PHY_SPECv2_00_VERS: + break; + default: + error_setg(errp, "Invalid SD card Spec version: %u", sd->spec_version); + return; + } + if (sd->blk && blk_is_read_only(sd->blk)) { error_setg(errp, "Cannot use read-only drive as SD card"); return; @@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp) } static Property sd_properties[] = { + DEFINE_PROP_UINT8("spec_version", SDState, + spec_version, SD_PHY_SPECv2_00_VERS), DEFINE_PROP_DRIVE("drive", SDState, blk), /* We do not model the chip select pin, so allow the board to select * whether card should be in SSI or MMC/SD mode. It is also up to the -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> CMD8 is "Reserved" in Spec v1.10. Spec v2.00 introduces the SEND_IF_COND command: 6.4.1 Power Up CMD8 is newly added in the Physical Layer Specification Version 2.00 to support multiple voltage ranges and used to check whether the card supports supplied voltage. The version 2.00 or later host shall issue CMD8 and verify voltage before card initialization. The host that does not support CMD8 shall supply high voltage range. Message-Id: 201204252110.20873.paul@codesourcery.com Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180607180641.874-5-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/sd/sd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 8: /* CMD8: SEND_IF_COND */ - /* Physical Layer Specification Version 2.00 command */ + if (sd->spec_version < SD_PHY_SPECv2_00_VERS) { + break; + } if (sd->state != sd_idle_state) { break; } -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180607180641.874-6-f4bug@amsat.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/sd/sd.h | 1 + hw/sd/sd.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -XXX,XX +XXX,XX @@ enum SDPhySpecificationVersion { SD_PHY_SPECv1_10_VERS = 1, SD_PHY_SPECv2_00_VERS = 2, + SD_PHY_SPECv3_01_VERS = 3, }; typedef enum { diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static void sd_set_scr(SDState *sd) if (sd->spec_version == SD_PHY_SPECv1_10_VERS) { sd->scr[0] |= 1; /* Spec Version 1.10 */ } else { - sd->scr[0] |= 2; /* Spec Version 2.00 */ + sd->scr[0] |= 2; /* Spec Version 2.00 or Version 3.0X */ } sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */ | 0b0101; /* 1-bit or 4-bit width bus modes */ sd->scr[2] = 0x00; /* Extended Security is not supported. */ + if (sd->spec_version >= SD_PHY_SPECv3_01_VERS) { + sd->scr[2] |= 1 << 7; /* Spec Version 3.0X */ + } sd->scr[3] = 0x00; /* reserved for manufacturer usage */ sd->scr[4] = 0x00; @@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp) switch (sd->spec_version) { case SD_PHY_SPECv1_10_VERS - ... SD_PHY_SPECv2_00_VERS: + ... SD_PHY_SPECv3_01_VERS: break; default: error_setg(errp, "Invalid SD card Spec version: %u", sd->spec_version); -- 2.17.1
From: Philippe Mathieu-Daudé <f4bug@amsat.org> These commands got introduced by Spec v3 (see 0c3fb03f7ec and 4481bbc79d2). Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20180607180641.874-7-f4bug@amsat.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/sd/sd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */ + if (sd->spec_version < SD_PHY_SPECv3_01_VERS) { + break; + } if (sd->state == sd_transfer_state) { sd->state = sd_sendingdata_state; sd->data_offset = 0; @@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) break; case 23: /* CMD23: SET_BLOCK_COUNT */ + if (sd->spec_version < SD_PHY_SPECv3_01_VERS) { + break; + } switch (sd->state) { case sd_transfer_state: sd->multi_blk_cnt = req.arg; -- 2.17.1
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb