diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-07-02 12:58:32 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-07-02 12:58:32 +0100 |
commit | c4e42a9c2b714de5cddabffe46c7789fcff49c30 (patch) | |
tree | 4a9b7f8a620492deb865c17e952ca20f717b6a1e /hw/intc | |
parent | d247c8e7f4fc856abf799c37ca9818514ddb08b7 (diff) | |
parent | 787a7e76c2e93a48c47b324fea592c9910a70483 (diff) | |
download | qemu-c4e42a9c2b714de5cddabffe46c7789fcff49c30.zip qemu-c4e42a9c2b714de5cddabffe46c7789fcff49c30.tar.gz qemu-c4e42a9c2b714de5cddabffe46c7789fcff49c30.tar.bz2 |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190701' into staging
target-arm queue:
* hw/arm/boot: fix direct kernel boot with initrd
* hw/arm/msf2-som: Exit when the cpu is not the expected one
* i.mx7: fix bugs in PCI controller needed to boot recent kernels
* aspeed: add RTC device
* aspeed: fix some timer device bugs
* aspeed: add swift-bmc board
* aspeed: vic: Add support for legacy register interface
* aspeed: add aspeed-xdma device
* Add new sbsa-ref board for aarch64
* target/arm: code refactoring in preparation for support of
compilation with TCG disabled
# gpg: Signature made Mon 01 Jul 2019 17:38:10 BST
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20190701: (46 commits)
target/arm: Declare some M-profile functions publicly
target/arm: Declare arm_log_exception() function publicly
target/arm: Restrict PSCI to TCG
target/arm/vfp_helper: Restrict the SoftFloat use to TCG
target/arm/vfp_helper: Extract vfp_set_fpscr_from_host()
target/arm/vfp_helper: Extract vfp_set_fpscr_to_host()
target/arm/vfp_helper: Move code around
target/arm: Move TLB related routines to tlb_helper.c
target/arm: Declare get_phys_addr() function publicly
target/arm: Move CPU state dumping routines to cpu.c
target/arm: Move the DC ZVA helper into op_helper
target/arm: Fix coding style issues
target/arm: Fix multiline comment syntax
target/arm/helper: Remove unused include
target/arm: Add copyright boilerplate
target/arm: Makefile cleanup (softmmu)
target/arm: Makefile cleanup (KVM)
target/arm: Makefile cleanup (ARM)
target/arm: Makefile cleanup (Aarch64)
hw/arm: Add arm SBSA reference machine, devices part
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/aspeed_vic.c | 105 |
1 files changed, 63 insertions, 42 deletions
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c index 927638d..266a309 100644 --- a/hw/intc/aspeed_vic.c +++ b/hw/intc/aspeed_vic.c @@ -104,54 +104,63 @@ static void aspeed_vic_set_irq(void *opaque, int irq, int level) static uint64_t aspeed_vic_read(void *opaque, hwaddr offset, unsigned size) { - uint64_t val; - const bool high = !!(offset & 0x4); - hwaddr n_offset = (offset & ~0x4); AspeedVICState *s = (AspeedVICState *)opaque; + hwaddr n_offset; + uint64_t val; + bool high; if (offset < AVIC_NEW_BASE_OFFSET) { - qemu_log_mask(LOG_UNIMP, "%s: Ignoring read from legacy registers " - "at 0x%" HWADDR_PRIx "[%u]\n", __func__, offset, size); - return 0; + high = false; + n_offset = offset; + } else { + high = !!(offset & 0x4); + n_offset = (offset & ~0x4); } - n_offset -= AVIC_NEW_BASE_OFFSET; - switch (n_offset) { - case 0x0: /* IRQ Status */ + case 0x80: /* IRQ Status */ + case 0x00: val = s->raw & ~s->select & s->enable; break; - case 0x08: /* FIQ Status */ + case 0x88: /* FIQ Status */ + case 0x04: val = s->raw & s->select & s->enable; break; - case 0x10: /* Raw Interrupt Status */ + case 0x90: /* Raw Interrupt Status */ + case 0x08: val = s->raw; break; - case 0x18: /* Interrupt Selection */ + case 0x98: /* Interrupt Selection */ + case 0x0c: val = s->select; break; - case 0x20: /* Interrupt Enable */ + case 0xa0: /* Interrupt Enable */ + case 0x10: val = s->enable; break; - case 0x30: /* Software Interrupt */ + case 0xb0: /* Software Interrupt */ + case 0x18: val = s->trigger; break; - case 0x40: /* Interrupt Sensitivity */ + case 0xc0: /* Interrupt Sensitivity */ + case 0x24: val = s->sense; break; - case 0x48: /* Interrupt Both Edge Trigger Control */ + case 0xc8: /* Interrupt Both Edge Trigger Control */ + case 0x28: val = s->dual_edge; break; - case 0x50: /* Interrupt Event */ + case 0xd0: /* Interrupt Event */ + case 0x2c: val = s->event; break; - case 0x60: /* Edge Triggered Interrupt Status */ + case 0xe0: /* Edge Triggered Interrupt Status */ val = s->raw & ~s->sense; break; /* Illegal */ - case 0x28: /* Interrupt Enable Clear */ - case 0x38: /* Software Interrupt Clear */ - case 0x58: /* Edge Triggered Interrupt Clear */ + case 0xa8: /* Interrupt Enable Clear */ + case 0xb8: /* Software Interrupt Clear */ + case 0xd8: /* Edge Triggered Interrupt Clear */ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read of write-only register with offset 0x%" HWADDR_PRIx "\n", __func__, offset); @@ -166,6 +175,8 @@ static uint64_t aspeed_vic_read(void *opaque, hwaddr offset, unsigned size) } if (high) { val = extract64(val, 32, 19); + } else { + val = extract64(val, 0, 32); } trace_aspeed_vic_read(offset, size, val); return val; @@ -174,19 +185,18 @@ static uint64_t aspeed_vic_read(void *opaque, hwaddr offset, unsigned size) static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data, unsigned size) { - const bool high = !!(offset & 0x4); - hwaddr n_offset = (offset & ~0x4); AspeedVICState *s = (AspeedVICState *)opaque; + hwaddr n_offset; + bool high; if (offset < AVIC_NEW_BASE_OFFSET) { - qemu_log_mask(LOG_UNIMP, - "%s: Ignoring write to legacy registers at 0x%" - HWADDR_PRIx "[%u] <- 0x%" PRIx64 "\n", __func__, offset, - size, data); - return; + high = false; + n_offset = offset; + } else { + high = !!(offset & 0x4); + n_offset = (offset & ~0x4); } - n_offset -= AVIC_NEW_BASE_OFFSET; trace_aspeed_vic_write(offset, size, data); /* Given we have members using separate enable/clear registers, deposit64() @@ -201,7 +211,8 @@ static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data, } switch (n_offset) { - case 0x18: /* Interrupt Selection */ + case 0x98: /* Interrupt Selection */ + case 0x0c: /* Register has deposit64() semantics - overwrite requested 32 bits */ if (high) { s->select &= AVIC_L_MASK; @@ -210,21 +221,25 @@ static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data, } s->select |= data; break; - case 0x20: /* Interrupt Enable */ + case 0xa0: /* Interrupt Enable */ + case 0x10: s->enable |= data; break; - case 0x28: /* Interrupt Enable Clear */ + case 0xa8: /* Interrupt Enable Clear */ + case 0x14: s->enable &= ~data; break; - case 0x30: /* Software Interrupt */ + case 0xb0: /* Software Interrupt */ + case 0x18: qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. " "IRQs requested: 0x%016" PRIx64 "\n", __func__, data); break; - case 0x38: /* Software Interrupt Clear */ + case 0xb8: /* Software Interrupt Clear */ + case 0x1c: qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. " "IRQs to be cleared: 0x%016" PRIx64 "\n", __func__, data); break; - case 0x50: /* Interrupt Event */ + case 0xd0: /* Interrupt Event */ /* Register has deposit64() semantics - overwrite the top four valid * IRQ bits, as only the top four IRQs (GPIOs) can change their event * type */ @@ -236,15 +251,21 @@ static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data, "Ignoring invalid write to interrupt event register"); } break; - case 0x58: /* Edge Triggered Interrupt Clear */ + case 0xd8: /* Edge Triggered Interrupt Clear */ + case 0x38: s->raw &= ~(data & ~s->sense); break; - case 0x00: /* IRQ Status */ - case 0x08: /* FIQ Status */ - case 0x10: /* Raw Interrupt Status */ - case 0x40: /* Interrupt Sensitivity */ - case 0x48: /* Interrupt Both Edge Trigger Control */ - case 0x60: /* Edge Triggered Interrupt Status */ + case 0x80: /* IRQ Status */ + case 0x00: + case 0x88: /* FIQ Status */ + case 0x04: + case 0x90: /* Raw Interrupt Status */ + case 0x08: + case 0xc0: /* Interrupt Sensitivity */ + case 0x24: + case 0xc8: /* Interrupt Both Edge Trigger Control */ + case 0x28: + case 0xe0: /* Edge Triggered Interrupt Status */ qemu_log_mask(LOG_GUEST_ERROR, "%s: Write of read-only register with offset 0x%" HWADDR_PRIx "\n", __func__, offset); |