diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-02-26 16:02:00 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-02-26 16:02:00 +0000 |
commit | 6e378dd214fbbae8138ff011ec3de7ddf13a445f (patch) | |
tree | 5ce6d8aca244eb11dd94daa2a6b94afdc038f124 /hw | |
parent | aa53d5bfc35d73099184bdd1c538591a5f795c9e (diff) | |
parent | e20d84c1407d43d5a2e2ac95dbb46db3b0af8f9f (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160226' into staging
target-arm queue:
* Clean up handling of bad mode switches writing to CPSR, and implement
the ARMv8 requirement that they set PSTATE.IL
* Implement MDCR_EL3.TPM and MDCR_EL2.TPM traps on perf monitor
register accesses
* Don't implement stellaris-pl061-only registers on generic-pl061
* Fix SD card handling for raspi
* Add missing include files to MAINTAINERS
* Mark CNTHP_TVAL_EL2 as ARM_CP_NO_RAW
* Make reserved ranges in ID_AA64* spaces RAZ, not UNDEF
# gpg: Signature made Fri 26 Feb 2016 15:19:07 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg: aka "Peter Maydell <pmaydell@gmail.com>"
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
* remotes/pmaydell/tags/pull-target-arm-20160226:
target-arm: Make reserved ranges in ID_AA64* spaces RAZ, not UNDEF
target-arm: Mark CNTHP_TVAL_EL2 as ARM_CP_NO_RAW
sdhci: add quirk property for card insert interrupt status on Raspberry Pi
sdhci: Revert "add optional quirk property to disable card insertion/removal interrupts"
MAINTAINERS: Add some missing ARM related header files
raspi: fix SD card with recent sdhci changes
ARM: PL061: Checking register r/w accesses to reserved area
target-arm: Implement MDCR_EL3.TPM and MDCR_EL2.TPM traps
target-arm: Fix handling of SDCR for 32-bit code
target-arm: Make Monitor->NS PL1 mode changes illegal if HCR.TGE is 1
target-arm: Make mode switches from Hyp via CPS and MRS illegal
target-arm: In v8, make illegal AArch32 mode changes set PSTATE.IL
target-arm: Forbid mode switch to Mon from Secure EL1
target-arm: Add Hyp mode checks to bad_mode_switch()
target-arm: Add comment about not implementing NSACR.RFR
target-arm: In cpsr_write() ignore mode switches from User mode
linux-user: Use restrictive mask when calling cpsr_write()
target-arm: Raw CPSR writes should skip checks and bank switching
target-arm: Add write_type argument to cpsr_write()
target-arm: Give CPSR setting on 32-bit exception return its own helper
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm/bcm2835_peripherals.c | 7 | ||||
-rw-r--r-- | hw/arm/bcm2836.c | 7 | ||||
-rw-r--r-- | hw/arm/raspi.c | 16 | ||||
-rw-r--r-- | hw/gpio/pl061.c | 30 | ||||
-rw-r--r-- | hw/sd/sdhci.c | 47 |
5 files changed, 92 insertions, 15 deletions
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 72467fd907..6d66fa0280 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -182,6 +182,13 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_ARASANSDIO)); + object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->sdhci), "sd-bus", + &err); + if (err) { + error_propagate(errp, err); + return; + } + } static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data) diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c index 15c7622ad1..032143905e 100644 --- a/hw/arm/bcm2836.c +++ b/hw/arm/bcm2836.c @@ -73,6 +73,13 @@ static void bcm2836_realize(DeviceState *dev, Error **errp) return; } + object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->peripherals), + "sd-bus", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0, BCM2836_PERI_BASE, 1); diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 48d014c8d3..65822792fe 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -113,6 +113,10 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) static void raspi2_init(MachineState *machine) { RasPiState *s = g_new0(RasPiState, 1); + DriveInfo *di; + BlockBackend *blk; + BusState *bus; + DeviceState *carddev; object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836); object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), @@ -133,6 +137,18 @@ static void raspi2_init(MachineState *machine) &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); + /* Create and plug in the SD cards */ + di = drive_get_next(IF_SD); + blk = di ? blk_by_legacy_dinfo(di) : NULL; + bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus"); + if (bus == NULL) { + error_report("No SD bus found in SOC object"); + exit(1); + } + carddev = qdev_create(bus, TYPE_SD_CARD); + qdev_prop_set_drive(carddev, "drive", blk, &error_fatal); + object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal); + setup_boot(machine, 2, machine->ram_size); } diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index 5ece8b068e..29dc7fc38e 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -60,6 +60,7 @@ typedef struct PL061State { qemu_irq irq; qemu_irq out[8]; const unsigned char *id; + uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */ } PL061State; static const VMStateDescription vmstate_pl061 = { @@ -152,12 +153,15 @@ static uint64_t pl061_read(void *opaque, hwaddr offset, { PL061State *s = (PL061State *)opaque; - if (offset >= 0xfd0 && offset < 0x1000) { - return s->id[(offset - 0xfd0) >> 2]; - } if (offset < 0x400) { return s->data & (offset >> 2); } + if (offset >= s->rsvd_start && offset <= 0xfcc) { + goto err_out; + } + if (offset >= 0xfd0 && offset < 0x1000) { + return s->id[(offset - 0xfd0) >> 2]; + } switch (offset) { case 0x400: /* Direction */ return s->dir; @@ -198,10 +202,12 @@ static uint64_t pl061_read(void *opaque, hwaddr offset, case 0x528: /* Analog mode select */ return s->amsel; default: - qemu_log_mask(LOG_GUEST_ERROR, - "pl061_read: Bad offset %x\n", (int)offset); - return 0; + break; } +err_out: + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_read: Bad offset %x\n", (int)offset); + return 0; } static void pl061_write(void *opaque, hwaddr offset, @@ -216,6 +222,9 @@ static void pl061_write(void *opaque, hwaddr offset, pl061_update(s); return; } + if (offset >= s->rsvd_start) { + goto err_out; + } switch (offset) { case 0x400: /* Direction */ s->dir = value & 0xff; @@ -274,10 +283,13 @@ static void pl061_write(void *opaque, hwaddr offset, s->amsel = value & 0xff; break; default: - qemu_log_mask(LOG_GUEST_ERROR, - "pl061_write: Bad offset %x\n", (int)offset); + goto err_out; } pl061_update(s); + return; +err_out: + qemu_log_mask(LOG_GUEST_ERROR, + "pl061_write: Bad offset %x\n", (int)offset); } static void pl061_reset(DeviceState *dev) @@ -347,6 +359,7 @@ static void pl061_luminary_init(Object *obj) PL061State *s = PL061(obj); s->id = pl061_id_luminary; + s->rsvd_start = 0x52c; } static void pl061_init(Object *obj) @@ -354,6 +367,7 @@ static void pl061_init(Object *obj) PL061State *s = PL061(obj); s->id = pl061_id; + s->rsvd_start = 0x424; } static void pl061_class_init(ObjectClass *klass, void *data) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 73e7c87fbf..e087c17ad7 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -198,14 +198,13 @@ static void sdhci_reset(SDHCIState *s) * initialization */ memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad); - if (!s->noeject_quirk) { - /* Reset other state based on current card insertion/readonly status */ - sdhci_set_inserted(dev, sdbus_get_inserted(&s->sdbus)); - sdhci_set_readonly(dev, sdbus_get_readonly(&s->sdbus)); - } + /* Reset other state based on current card insertion/readonly status */ + sdhci_set_inserted(dev, sdbus_get_inserted(&s->sdbus)); + sdhci_set_readonly(dev, sdbus_get_readonly(&s->sdbus)); s->data_count = 0; s->stopped_state = sdhc_not_stopped; + s->pending_insert_state = false; } static void sdhci_data_transfer(void *opaque); @@ -1097,6 +1096,13 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) } else { s->norintsts &= ~SDHC_NIS_ERR; } + /* Quirk for Raspberry Pi: pending card insert interrupt + * appears when first enabled after power on */ + if ((s->norintstsen & SDHC_NISEN_INSERT) && s->pending_insert_state) { + assert(s->pending_insert_quirk); + s->norintsts |= SDHC_NIS_INSERT; + s->pending_insert_state = false; + } sdhci_update_irq(s); break; case SDHC_NORINTSIGEN: @@ -1183,6 +1189,24 @@ static void sdhci_uninitfn(SDHCIState *s) s->fifo_buffer = NULL; } +static bool sdhci_pending_insert_vmstate_needed(void *opaque) +{ + SDHCIState *s = opaque; + + return s->pending_insert_state; +} + +static const VMStateDescription sdhci_pending_insert_vmstate = { + .name = "sdhci/pending-insert", + .version_id = 1, + .minimum_version_id = 1, + .needed = sdhci_pending_insert_vmstate_needed, + .fields = (VMStateField[]) { + VMSTATE_BOOL(pending_insert_state, SDHCIState), + VMSTATE_END_OF_LIST() + }, +}; + const VMStateDescription sdhci_vmstate = { .name = "sdhci", .version_id = 1, @@ -1217,7 +1241,11 @@ const VMStateDescription sdhci_vmstate = { VMSTATE_TIMER_PTR(insert_timer, SDHCIState), VMSTATE_TIMER_PTR(transfer_timer, SDHCIState), VMSTATE_END_OF_LIST() - } + }, + .subsections = (const VMStateDescription*[]) { + &sdhci_pending_insert_vmstate, + NULL + }, }; /* Capabilities registers provide information on supported features of this @@ -1275,7 +1303,8 @@ static Property sdhci_sysbus_properties[] = { DEFINE_PROP_UINT32("capareg", SDHCIState, capareg, SDHC_CAPAB_REG_DEFAULT), DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0), - DEFINE_PROP_BOOL("noeject-quirk", SDHCIState, noeject_quirk, false), + DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk, + false), DEFINE_PROP_END_OF_LIST(), }; @@ -1303,6 +1332,10 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp) memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci", SDHC_REGISTERS_MAP_SIZE); sysbus_init_mmio(sbd, &s->iomem); + + if (s->pending_insert_quirk) { + s->pending_insert_state = true; + } } static void sdhci_sysbus_class_init(ObjectClass *klass, void *data) |