aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-10-20 21:11:35 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-10-20 21:11:35 +0100
commitac793156f650ae2d77834932d72224175ee69086 (patch)
tree573940f3a8b5ad0e08ea71d2f210f776b7620909 /hw
parent4c41341af76cfc85b5a6c0f87de4838672ab9f89 (diff)
parent8128c8e8cc9489a8387c74075974f86dc0222e7f (diff)
downloadqemu-ac793156f650ae2d77834932d72224175ee69086.zip
qemu-ac793156f650ae2d77834932d72224175ee69086.tar.gz
qemu-ac793156f650ae2d77834932d72224175ee69086.tar.bz2
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20201020-1' into staging
target-arm queue: * Fix AArch32 SMLAD incorrect setting of Q bit * AArch32 VCVT fixed-point to float is always round-to-nearest * strongarm: Fix 'time to transmit a char' unit comment * Restrict APEI tables generation to the 'virt' machine * bcm2835: minor code cleanups * bcm2835: connect all IRQs from SYS_timer device * correctly flush TLBs when TBI is enabled * tests/qtest: Add npcm7xx timer test * loads-stores.rst: add footnote that clarifies GETPC usage * Fix reported EL for mte_check_fail * Ignore HCR_EL2.ATA when {E2H,TGE} != 11 * microbit_i2c: Fix coredump when dump-vmstate * nseries: Fix loading kernel image on n8x0 machines * Implement v8.1M low-overhead-loops # gpg: Signature made Tue 20 Oct 2020 21:10:35 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-20201020-1: (29 commits) target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension target/arm: Allow M-profile CPUs with FP16 to set FPSCR.FP16 target/arm: Fix has_vfp/has_neon ID reg squashing for M-profile target/arm: Implement v8.1M low-overhead-loop instructions target/arm: Implement v8.1M branch-future insns (as NOPs) target/arm: Don't allow BLX imm for M-profile target/arm: Make the t32 insn[25:23]=111 group non-overlapping target/arm: Implement v8.1M conditional-select insns target/arm: Implement v8.1M NOCP handling decodetree: Fix codegen for non-overlapping group inside overlapping group hw/arm/nseries: Fix loading kernel image on n8x0 machines microbit_i2c: Fix coredump when dump-vmstate target/arm: Ignore HCR_EL2.ATA when {E2H,TGE} != 11 target/arm: Fix reported EL for mte_check_fail target/arm: Remove redundant mmu_idx lookup hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers loads-stores.rst: add footnote that clarifies GETPC usage tests/qtest: Add npcm7xx timer test target/arm: Use tlb_flush_page_bits_by_mmuidx* ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/Kconfig1
-rw-r--r--hw/arm/bcm2835_peripherals.c13
-rw-r--r--hw/arm/nseries.c1
-rw-r--r--hw/arm/strongarm.c2
-rw-r--r--hw/i2c/microbit_i2c.c1
-rw-r--r--hw/intc/bcm2835_ic.c4
-rw-r--r--hw/intc/bcm2836_control.c8
-rw-r--r--hw/intc/trace-events4
-rw-r--r--hw/timer/bcm2835_systmr.c57
-rw-r--r--hw/timer/trace-events6
10 files changed, 66 insertions, 31 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index f303c6b..7d04082 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -26,6 +26,7 @@ config ARM_VIRT
select ACPI_MEMORY_HOTPLUG
select ACPI_HW_REDUCED
select ACPI_NVDIMM
+ select ACPI_APEI
config CHEETAH
bool
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 15c5c72..48909a4 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -171,8 +171,17 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
- INTERRUPT_ARM_TIMER));
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_TIMER0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 1,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_TIMER1));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 2,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_TIMER2));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 3,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_TIMER3));
/* UART0 */
qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index e48092c..76fd7fe 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1318,6 +1318,7 @@ static void n8x0_init(MachineState *machine,
g_free(sz);
exit(EXIT_FAILURE);
}
+ binfo->ram_size = machine->ram_size;
memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
machine->ram);
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index d7133ee..ca7c385 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -935,7 +935,7 @@ struct StrongARMUARTState {
uint8_t rx_start;
uint8_t rx_len;
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
+ uint64_t char_transmit_time; /* time to transmit a char in nanoseconds */
bool wait_break_end;
QEMUTimer *rx_timeout_timer;
QEMUTimer *tx_timer;
diff --git a/hw/i2c/microbit_i2c.c b/hw/i2c/microbit_i2c.c
index 8024739..e92f9f8 100644
--- a/hw/i2c/microbit_i2c.c
+++ b/hw/i2c/microbit_i2c.c
@@ -83,6 +83,7 @@ static const VMStateDescription microbit_i2c_vmstate = {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, MicrobitI2CState, MICROBIT_I2C_NREGS),
VMSTATE_UINT32(read_idx, MicrobitI2CState),
+ VMSTATE_END_OF_LIST()
},
};
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
index 53ab8f5..9000d99 100644
--- a/hw/intc/bcm2835_ic.c
+++ b/hw/intc/bcm2835_ic.c
@@ -18,6 +18,7 @@
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
+#include "trace.h"
#define GPU_IRQS 64
#define ARM_IRQS 8
@@ -51,7 +52,6 @@ static void bcm2835_ic_update(BCM2835ICState *s)
set = (s->gpu_irq_level & s->gpu_irq_enable)
|| (s->arm_irq_level & s->arm_irq_enable);
qemu_set_irq(s->irq, set);
-
}
static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
@@ -59,6 +59,7 @@ static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
BCM2835ICState *s = opaque;
assert(irq >= 0 && irq < 64);
+ trace_bcm2835_ic_set_gpu_irq(irq, level);
s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
bcm2835_ic_update(s);
}
@@ -68,6 +69,7 @@ static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
BCM2835ICState *s = opaque;
assert(irq >= 0 && irq < 8);
+ trace_bcm2835_ic_set_cpu_irq(irq, level);
s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
bcm2835_ic_update(s);
}
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
index 53dba00..2ead76f 100644
--- a/hw/intc/bcm2836_control.c
+++ b/hw/intc/bcm2836_control.c
@@ -157,22 +157,22 @@ static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq,
static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
{
- bcm2836_control_set_local_irq(opaque, core, 0, level);
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPSIRQ, level);
}
static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
{
- bcm2836_control_set_local_irq(opaque, core, 1, level);
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPNSIRQ, level);
}
static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
{
- bcm2836_control_set_local_irq(opaque, core, 2, level);
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTHPIRQ, level);
}
static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
{
- bcm2836_control_set_local_irq(opaque, core, 3, level);
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTVIRQ, level);
}
static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 527c3f7..22782b3 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -199,3 +199,7 @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg wri
heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
+
+# bcm2835_ic.c
+bcm2835_ic_set_gpu_irq(int irq, int level) "GPU irq #%d level %d"
+bcm2835_ic_set_cpu_irq(int irq, int level) "CPU irq #%d level %d"
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
index 3387a62..67669a5 100644
--- a/hw/timer/bcm2835_systmr.c
+++ b/hw/timer/bcm2835_systmr.c
@@ -28,20 +28,13 @@ REG32(COMPARE1, 0x10)
REG32(COMPARE2, 0x14)
REG32(COMPARE3, 0x18)
-static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
+static void bcm2835_systmr_timer_expire(void *opaque)
{
- bool enable = !!s->reg.status;
+ BCM2835SystemTimerCompare *tmr = opaque;
- trace_bcm2835_systmr_irq(enable);
- qemu_set_irq(s->irq, enable);
-}
-
-static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
- unsigned timer_index)
-{
- /* TODO fow now, since neither Linux nor U-boot use these timers. */
- qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
- timer_index);
+ trace_bcm2835_systmr_timer_expired(tmr->id);
+ tmr->state->reg.ctrl_status |= 1 << tmr->id;
+ qemu_set_irq(tmr->irq, 1);
}
static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
@@ -52,7 +45,7 @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
switch (offset) {
case A_CTRL_STATUS:
- r = s->reg.status;
+ r = s->reg.ctrl_status;
break;
case A_COMPARE0 ... A_COMPARE3:
r = s->reg.compare[(offset - A_COMPARE0) >> 2];
@@ -75,19 +68,33 @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
}
static void bcm2835_systmr_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
+ uint64_t value64, unsigned size)
{
BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
+ int index;
+ uint32_t value = value64;
+ uint32_t triggers_delay_us;
+ uint64_t now;
trace_bcm2835_systmr_write(offset, value);
switch (offset) {
case A_CTRL_STATUS:
- s->reg.status &= ~value; /* Ack */
- bcm2835_systmr_update_irq(s);
+ s->reg.ctrl_status &= ~value; /* Ack */
+ for (index = 0; index < ARRAY_SIZE(s->tmr); index++) {
+ if (extract32(value, index, 1)) {
+ trace_bcm2835_systmr_irq_ack(index);
+ qemu_set_irq(s->tmr[index].irq, 0);
+ }
+ }
break;
case A_COMPARE0 ... A_COMPARE3:
- s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
- bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
+ index = (offset - A_COMPARE0) >> 2;
+ s->reg.compare[index] = value;
+ now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+ /* Compare lower 32-bits of the free-running counter. */
+ triggers_delay_us = value - now;
+ trace_bcm2835_systmr_run(index, triggers_delay_us);
+ timer_mod(&s->tmr[index].timer, now + triggers_delay_us);
break;
case A_COUNTER_LOW:
case A_COUNTER_HIGH:
@@ -125,7 +132,14 @@ static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
s, "bcm2835-sys-timer", 0x20);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+
+ for (size_t i = 0; i < ARRAY_SIZE(s->tmr); i++) {
+ s->tmr[i].id = i;
+ s->tmr[i].state = s;
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->tmr[i].irq);
+ timer_init_us(&s->tmr[i].timer, QEMU_CLOCK_VIRTUAL,
+ bcm2835_systmr_timer_expire, &s->tmr[i]);
+ }
}
static const VMStateDescription bcm2835_systmr_vmstate = {
@@ -133,8 +147,9 @@ static const VMStateDescription bcm2835_systmr_vmstate = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
- VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
+ VMSTATE_UINT32(reg.ctrl_status, BCM2835SystemTimerState),
+ VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
+ BCM2835_SYSTIMER_COUNT),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index b996d99..7a4326d 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -77,9 +77,11 @@ nrf51_timer_write(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size
nrf51_timer_set_count(uint8_t timer_id, uint8_t counter_id, uint32_t value) "timer %u counter %u count 0x%" PRIx32
# bcm2835_systmr.c
-bcm2835_systmr_irq(bool enable) "timer irq state %u"
+bcm2835_systmr_timer_expired(unsigned id) "timer #%u expired"
+bcm2835_systmr_irq_ack(unsigned id) "timer #%u acked"
bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
-bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
+bcm2835_systmr_write(uint64_t offset, uint32_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx32
+bcm2835_systmr_run(unsigned id, uint64_t delay_us) "timer #%u expiring in %"PRIu64" us"
# avr_timer16.c
avr_timer16_read(uint8_t addr, uint8_t value) "timer16 read addr:%u value:%u"