1 | Target-arm queue for rc2 -- just some minor bugfixes. | 1 | Handful of bugfixes for rc2. None of these are particularly critical |
---|---|---|---|
2 | or exciting. | ||
2 | 3 | ||
3 | thanks | ||
4 | -- PMM | 4 | -- PMM |
5 | 5 | ||
6 | The following changes since commit 6e5d4999c761ffa082f60d72a14e5c953515b417: | 6 | The following changes since commit 45a150aa2b3492acf6691c7bdbeb25a8545d8345: |
7 | 7 | ||
8 | Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2019-11-19' into staging (2019-11-19 11:29:01 +0000) | 8 | Merge remote-tracking branch 'remotes/ericb/tags/pull-bitmaps-2020-08-03' into staging (2020-08-03 15:13:49 +0100) |
9 | 9 | ||
10 | are available in the Git repository at: | 10 | are available in the Git repository at: |
11 | 11 | ||
12 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191119 | 12 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200803 |
13 | 13 | ||
14 | for you to fetch changes up to 04c9c81b8fa2ee33f59a26265700fae6fc646062: | 14 | for you to fetch changes up to 13557fd392890cbd985bceba7f717e01efd674b8: |
15 | 15 | ||
16 | target/arm: Support EL0 v7m msr/mrs for CONFIG_USER_ONLY (2019-11-19 13:20:28 +0000) | 16 | hw/timer/imx_epit: Avoid assertion when CR.SWR is written (2020-08-03 17:56:11 +0100) |
17 | 17 | ||
18 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
19 | target-arm queue: | 19 | target-arm queue: |
20 | * Support EL0 v7m msr/mrs for CONFIG_USER_ONLY | 20 | * hw/timer/imx_epit: Avoid assertion when CR.SWR is written |
21 | * Relax r13 restriction for ldrex/strex for v8.0 | 21 | * netduino2, netduinoplus2, microbit: set system_clock_scale so that |
22 | * Do not reject rt == rt2 for strexd | 22 | SysTick running on the CPU clock works |
23 | * net/cadence_gem: Set PHY autonegotiation restart status | 23 | * target/arm: Avoid maybe-uninitialized warning with gcc 4.9 |
24 | * ssi: xilinx_spips: Skip spi bus update for a few register writes | 24 | * target/arm: Fix AddPAC error indication |
25 | * pl031: Expose RTCICR as proper WC register | 25 | * Make AIRCR.SYSRESETREQ actually reset the system for the |
26 | microbit, mps2-*, musca-*, netduino* boards | ||
26 | 27 | ||
27 | ---------------------------------------------------------------- | 28 | ---------------------------------------------------------------- |
28 | Alexander Graf (1): | 29 | Kaige Li (1): |
29 | pl031: Expose RTCICR as proper WC register | 30 | target/arm: Avoid maybe-uninitialized warning with gcc 4.9 |
30 | 31 | ||
31 | Linus Ziegert (1): | 32 | Peter Maydell (6): |
32 | net/cadence_gem: Set PHY autonegotiation restart status | 33 | hw/arm/netduino2, netduinoplus2: Set system_clock_scale |
34 | include/hw/irq.h: New function qemu_irq_is_connected() | ||
35 | hw/intc/armv7m_nvic: Provide default "reset the system" behaviour for SYSRESETREQ | ||
36 | msf2-soc, stellaris: Don't wire up SYSRESETREQ | ||
37 | hw/arm/nrf51_soc: Set system_clock_scale | ||
38 | hw/timer/imx_epit: Avoid assertion when CR.SWR is written | ||
33 | 39 | ||
34 | Richard Henderson (4): | 40 | Richard Henderson (1): |
35 | target/arm: Merge arm_cpu_vq_map_next_smaller into sole caller | 41 | target/arm: Fix AddPAC error indication |
36 | target/arm: Do not reject rt == rt2 for strexd | ||
37 | target/arm: Relax r13 restriction for ldrex/strex for v8.0 | ||
38 | target/arm: Support EL0 v7m msr/mrs for CONFIG_USER_ONLY | ||
39 | 42 | ||
40 | Sai Pavan Boddu (1): | 43 | include/hw/arm/armv7m.h | 4 +++- |
41 | ssi: xilinx_spips: Skip spi bus update for a few register writes | 44 | include/hw/irq.h | 18 ++++++++++++++++++ |
45 | hw/arm/msf2-soc.c | 11 ----------- | ||
46 | hw/arm/netduino2.c | 10 ++++++++++ | ||
47 | hw/arm/netduinoplus2.c | 10 ++++++++++ | ||
48 | hw/arm/nrf51_soc.c | 5 +++++ | ||
49 | hw/arm/stellaris.c | 12 ------------ | ||
50 | hw/intc/armv7m_nvic.c | 17 ++++++++++++++++- | ||
51 | hw/timer/imx_epit.c | 13 ++++++++++--- | ||
52 | target/arm/pauth_helper.c | 6 +++++- | ||
53 | target/arm/translate-a64.c | 2 +- | ||
54 | tests/tcg/aarch64/pauth-5.c | 33 +++++++++++++++++++++++++++++++++ | ||
55 | tests/tcg/aarch64/Makefile.target | 2 +- | ||
56 | 13 files changed, 112 insertions(+), 31 deletions(-) | ||
57 | create mode 100644 tests/tcg/aarch64/pauth-5.c | ||
42 | 58 | ||
43 | target/arm/cpu.h | 5 +-- | ||
44 | hw/net/cadence_gem.c | 9 ++-- | ||
45 | hw/rtc/pl031.c | 6 +-- | ||
46 | hw/ssi/xilinx_spips.c | 22 ++++++++-- | ||
47 | target/arm/cpu64.c | 15 ------- | ||
48 | target/arm/helper.c | 9 +++- | ||
49 | target/arm/m_helper.c | 114 ++++++++++++++++++++++++++++++------------------- | ||
50 | target/arm/translate.c | 14 +++--- | ||
51 | 8 files changed, 113 insertions(+), 81 deletions(-) | ||
52 | diff view generated by jsdifflib |
1 | From: Linus Ziegert <linus.ziegert+qemu@holoplot.com> | 1 | The netduino2 and netduinoplus2 boards forgot to set the system_clock_scale |
---|---|---|---|
2 | global, which meant that if guest code used the systick timer in "use | ||
3 | the processor clock" mode it would hang because time never advances. | ||
2 | 4 | ||
3 | The Linux kernel PHY driver sets AN_RESTART in the BMCR of the | 5 | Set the global to match the documented CPU clock speed of these boards. |
4 | PHY when autonegotiation is started. | 6 | Judging by the data sheet this is slightly simplistic because the |
5 | Recently the kernel started to read back the PHY's AN_RESTART | 7 | SoC allows configuration of the SYSCLK source and frequency via the |
6 | bit and now checks whether the autonegotiation is complete and | 8 | RCC (reset and clock control) module, but we don't model that. |
7 | the bit was cleared [1]. Otherwise the link status is down. | ||
8 | 9 | ||
9 | The emulated PHY needs to clear AN_RESTART immediately to inform | 10 | Fixes: https://bugs.launchpad.net/qemu/+bug/1876187 |
10 | the kernel driver about the completion of autonegotiation phase. | 11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-id: 20200727162617.26227-1-peter.maydell@linaro.org | ||
14 | --- | ||
15 | hw/arm/netduino2.c | 10 ++++++++++ | ||
16 | hw/arm/netduinoplus2.c | 10 ++++++++++ | ||
17 | 2 files changed, 20 insertions(+) | ||
11 | 18 | ||
12 | [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c36757eb9dee | 19 | diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c |
13 | |||
14 | Signed-off-by: Linus Ziegert <linus.ziegert+qemu@holoplot.com> | ||
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | Message-id: 20191104181604.21943-1-linus.ziegert+qemu@holoplot.com | ||
17 | Cc: qemu-stable@nongnu.org | ||
18 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
19 | --- | ||
20 | hw/net/cadence_gem.c | 9 +++++---- | ||
21 | 1 file changed, 5 insertions(+), 4 deletions(-) | ||
22 | |||
23 | diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/hw/net/cadence_gem.c | 21 | --- a/hw/arm/netduino2.c |
26 | +++ b/hw/net/cadence_gem.c | 22 | +++ b/hw/arm/netduino2.c |
27 | @@ -XXX,XX +XXX,XX @@ | 23 | @@ -XXX,XX +XXX,XX @@ |
28 | #define PHY_REG_EXT_PHYSPCFC_ST 27 | 24 | #include "hw/arm/stm32f205_soc.h" |
29 | #define PHY_REG_CABLE_DIAG 28 | 25 | #include "hw/arm/boot.h" |
30 | 26 | ||
31 | -#define PHY_REG_CONTROL_RST 0x8000 | 27 | +/* Main SYSCLK frequency in Hz (120MHz) */ |
32 | -#define PHY_REG_CONTROL_LOOP 0x4000 | 28 | +#define SYSCLK_FRQ 120000000ULL |
33 | -#define PHY_REG_CONTROL_ANEG 0x1000 | 29 | + |
34 | +#define PHY_REG_CONTROL_RST 0x8000 | 30 | static void netduino2_init(MachineState *machine) |
35 | +#define PHY_REG_CONTROL_LOOP 0x4000 | 31 | { |
36 | +#define PHY_REG_CONTROL_ANEG 0x1000 | 32 | DeviceState *dev; |
37 | +#define PHY_REG_CONTROL_ANRESTART 0x0200 | 33 | |
38 | 34 | + /* | |
39 | #define PHY_REG_STATUS_LINK 0x0004 | 35 | + * TODO: ideally we would model the SoC RCC and let it handle |
40 | #define PHY_REG_STATUS_ANEGCMPL 0x0020 | 36 | + * system_clock_scale, including its ability to define different |
41 | @@ -XXX,XX +XXX,XX @@ static void gem_phy_write(CadenceGEMState *s, unsigned reg_num, uint16_t val) | 37 | + * possible SYSCLK sources. |
42 | } | 38 | + */ |
43 | if (val & PHY_REG_CONTROL_ANEG) { | 39 | + system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ; |
44 | /* Complete autonegotiation immediately */ | 40 | + |
45 | - val &= ~PHY_REG_CONTROL_ANEG; | 41 | dev = qdev_new(TYPE_STM32F205_SOC); |
46 | + val &= ~(PHY_REG_CONTROL_ANEG | PHY_REG_CONTROL_ANRESTART); | 42 | qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3")); |
47 | s->phy_regs[PHY_REG_STATUS] |= PHY_REG_STATUS_ANEGCMPL; | 43 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
48 | } | 44 | diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c |
49 | if (val & PHY_REG_CONTROL_LOOP) { | 45 | index XXXXXXX..XXXXXXX 100644 |
46 | --- a/hw/arm/netduinoplus2.c | ||
47 | +++ b/hw/arm/netduinoplus2.c | ||
48 | @@ -XXX,XX +XXX,XX @@ | ||
49 | #include "hw/arm/stm32f405_soc.h" | ||
50 | #include "hw/arm/boot.h" | ||
51 | |||
52 | +/* Main SYSCLK frequency in Hz (168MHz) */ | ||
53 | +#define SYSCLK_FRQ 168000000ULL | ||
54 | + | ||
55 | static void netduinoplus2_init(MachineState *machine) | ||
56 | { | ||
57 | DeviceState *dev; | ||
58 | |||
59 | + /* | ||
60 | + * TODO: ideally we would model the SoC RCC and let it handle | ||
61 | + * system_clock_scale, including its ability to define different | ||
62 | + * possible SYSCLK sources. | ||
63 | + */ | ||
64 | + system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ; | ||
65 | + | ||
66 | dev = qdev_new(TYPE_STM32F405_SOC); | ||
67 | qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4")); | ||
68 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
50 | -- | 69 | -- |
51 | 2.20.1 | 70 | 2.20.1 |
52 | 71 | ||
53 | 72 | diff view generated by jsdifflib |
1 | From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> | 1 | Mostly devices don't need to care whether one of their output |
---|---|---|---|
2 | qemu_irq lines is connected, because functions like qemu_set_irq() | ||
3 | silently do nothing if there is nothing on the other end. However | ||
4 | sometimes a device might want to implement default behaviour for the | ||
5 | case where the machine hasn't wired the line up to anywhere. | ||
2 | 6 | ||
3 | A few configuration register writes need not update the spi bus state, so just | 7 | Provide a function qemu_irq_is_connected() that devices can use for |
4 | return after the register write. | 8 | this purpose. (The test is trivial but encapsulating it in a |
9 | function makes it easier to see where we're doing it in case we need | ||
10 | to change the implementation later.) | ||
5 | 11 | ||
6 | Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> | 12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
13 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com> | 15 | Message-id: 20200728103744.6909-2-peter.maydell@linaro.org |
9 | Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com> | ||
10 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> | ||
11 | Message-id: 1573830705-14579-1-git-send-email-sai.pavan.boddu@xilinx.com | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | --- | 16 | --- |
14 | hw/ssi/xilinx_spips.c | 22 ++++++++++++++++++---- | 17 | include/hw/irq.h | 18 ++++++++++++++++++ |
15 | 1 file changed, 18 insertions(+), 4 deletions(-) | 18 | 1 file changed, 18 insertions(+) |
16 | 19 | ||
17 | diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c | 20 | diff --git a/include/hw/irq.h b/include/hw/irq.h |
18 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/ssi/xilinx_spips.c | 22 | --- a/include/hw/irq.h |
20 | +++ b/hw/ssi/xilinx_spips.c | 23 | +++ b/include/hw/irq.h |
21 | @@ -XXX,XX +XXX,XX @@ | 24 | @@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); |
22 | #define R_GPIO (0x30 / 4) | 25 | on an existing vector of qemu_irq. */ |
23 | #define R_LPBK_DLY_ADJ (0x38 / 4) | 26 | void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); |
24 | #define R_LPBK_DLY_ADJ_RESET (0x33) | 27 | |
25 | +#define R_IOU_TAPDLY_BYPASS (0x3C / 4) | 28 | +/** |
26 | #define R_TXD1 (0x80 / 4) | 29 | + * qemu_irq_is_connected: Return true if IRQ line is wired up |
27 | #define R_TXD2 (0x84 / 4) | 30 | + * |
28 | #define R_TXD3 (0x88 / 4) | 31 | + * If a qemu_irq has a device on the other (receiving) end of it, |
29 | @@ -XXX,XX +XXX,XX @@ | 32 | + * return true; otherwise return false. |
30 | #define R_LQSPI_STS (0xA4 / 4) | 33 | + * |
31 | #define LQSPI_STS_WR_RECVD (1 << 1) | 34 | + * Usually device models don't need to care whether the machine model |
32 | 35 | + * has wired up their outbound qemu_irq lines, because functions like | |
33 | +#define R_DUMMY_CYCLE_EN (0xC8 / 4) | 36 | + * qemu_set_irq() silently do nothing if there is nothing on the other |
34 | +#define R_ECO (0xF8 / 4) | 37 | + * end of the line. However occasionally a device model will want to |
35 | #define R_MOD_ID (0xFC / 4) | 38 | + * provide default behaviour if its output is left floating, and |
36 | 39 | + * it can use this function to identify when that is the case. | |
37 | #define R_GQSPI_SELECT (0x144 / 4) | 40 | + */ |
38 | @@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr, | 41 | +static inline bool qemu_irq_is_connected(qemu_irq irq) |
39 | { | 42 | +{ |
40 | int mask = ~0; | 43 | + return irq != NULL; |
41 | XilinxSPIPS *s = opaque; | 44 | +} |
42 | + bool try_flush = true; | 45 | + |
43 | 46 | #endif | |
44 | DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value); | ||
45 | addr >>= 2; | ||
46 | @@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr, | ||
47 | tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3, | ||
48 | s->regs[R_CONFIG] & R_CONFIG_ENDIAN); | ||
49 | goto no_reg_update; | ||
50 | + /* Skip SPI bus update for below registers writes */ | ||
51 | + case R_GPIO: | ||
52 | + case R_LPBK_DLY_ADJ: | ||
53 | + case R_IOU_TAPDLY_BYPASS: | ||
54 | + case R_DUMMY_CYCLE_EN: | ||
55 | + case R_ECO: | ||
56 | + try_flush = false; | ||
57 | + break; | ||
58 | } | ||
59 | s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); | ||
60 | no_reg_update: | ||
61 | - xilinx_spips_update_cs_lines(s); | ||
62 | - xilinx_spips_check_flush(s); | ||
63 | - xilinx_spips_update_cs_lines(s); | ||
64 | - xilinx_spips_update_ixr(s); | ||
65 | + if (try_flush) { | ||
66 | + xilinx_spips_update_cs_lines(s); | ||
67 | + xilinx_spips_check_flush(s); | ||
68 | + xilinx_spips_update_cs_lines(s); | ||
69 | + xilinx_spips_update_ixr(s); | ||
70 | + } | ||
71 | } | ||
72 | |||
73 | static const MemoryRegionOps spips_ops = { | ||
74 | -- | 47 | -- |
75 | 2.20.1 | 48 | 2.20.1 |
76 | 49 | ||
77 | 50 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | The NVIC provides an outbound qemu_irq "SYSRESETREQ" which it signals |
---|---|---|---|
2 | when the guest sets the SYSRESETREQ bit in the AIRCR register. This | ||
3 | matches the hardware design (where the CPU has a signal of this name | ||
4 | and it is up to the SoC to connect that up to an actual reset | ||
5 | mechanism), but in QEMU it mostly results in duplicated code in SoC | ||
6 | objects and bugs where SoC model implementors forget to wire up the | ||
7 | SYSRESETREQ line. | ||
2 | 8 | ||
3 | Simply moving the non-stub helper_v7m_mrs/msr outside of | 9 | Provide a default behaviour for the case where SYSRESETREQ is not |
4 | !CONFIG_USER_ONLY is not an option, because of all of the | 10 | actually connected to anything: use qemu_system_reset_request() to |
5 | other system-mode helpers that are called. | 11 | perform a system reset. This will allow us to remove the |
12 | implementations of SYSRESETREQ handling from the boards where that's | ||
13 | exactly what it does, and also fixes the bugs in the board models | ||
14 | which forgot to wire up the signal: | ||
6 | 15 | ||
7 | But we can split out a few subroutines to handle the few | 16 | * microbit |
8 | EL0 accessible registers without duplicating code. | 17 | * mps2-an385 |
18 | * mps2-an505 | ||
19 | * mps2-an511 | ||
20 | * mps2-an521 | ||
21 | * musca-a | ||
22 | * musca-b1 | ||
23 | * netduino | ||
24 | * netduinoplus2 | ||
9 | 25 | ||
10 | Reported-by: Christophe Lyon <christophe.lyon@linaro.org> | 26 | We still allow the board to wire up the signal if it needs to, in case |
11 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 27 | we need to model more complicated reset controller logic or to model |
12 | Message-id: 20191118194916.3670-1-richard.henderson@linaro.org | 28 | buggy SoC hardware which forgot to wire up the line itself. But |
13 | [PMM: deleted now-redundant comment; added a default case | 29 | defaulting to "reset the system" is more often going to be correct |
14 | to switch in v7m_msr helper] | 30 | than defaulting to "do nothing". |
15 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 31 | |
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 32 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
33 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
34 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
35 | Message-id: 20200728103744.6909-3-peter.maydell@linaro.org | ||
17 | --- | 36 | --- |
18 | target/arm/cpu.h | 2 + | 37 | include/hw/arm/armv7m.h | 4 +++- |
19 | target/arm/m_helper.c | 114 ++++++++++++++++++++++++++---------------- | 38 | hw/intc/armv7m_nvic.c | 17 ++++++++++++++++- |
20 | 2 files changed, 73 insertions(+), 43 deletions(-) | 39 | 2 files changed, 19 insertions(+), 2 deletions(-) |
21 | 40 | ||
22 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | 41 | diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h |
23 | index XXXXXXX..XXXXXXX 100644 | 42 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/arm/cpu.h | 43 | --- a/include/hw/arm/armv7m.h |
25 | +++ b/target/arm/cpu.h | 44 | +++ b/include/hw/arm/armv7m.h |
26 | @@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | 45 | @@ -XXX,XX +XXX,XX @@ typedef struct { |
27 | if (mask & XPSR_GE) { | 46 | |
28 | env->GE = (val & XPSR_GE) >> 16; | 47 | /* ARMv7M container object. |
29 | } | 48 | * + Unnamed GPIO input lines: external IRQ lines for the NVIC |
30 | +#ifndef CONFIG_USER_ONLY | 49 | - * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ |
31 | if (mask & XPSR_T) { | 50 | + * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ. |
32 | env->thumb = ((val & XPSR_T) != 0); | 51 | + * If this GPIO is not wired up then the NVIC will default to performing |
33 | } | 52 | + * a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET). |
34 | @@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | 53 | * + Property "cpu-type": CPU type to instantiate |
35 | /* Note that this only happens on exception exit */ | 54 | * + Property "num-irq": number of external IRQ lines |
36 | write_v7m_exception(env, val & XPSR_EXCP); | 55 | * + Property "memory": MemoryRegion defining the physical address space |
37 | } | 56 | diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c |
38 | +#endif | ||
39 | } | ||
40 | |||
41 | #define HCR_VM (1ULL << 0) | ||
42 | diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | 57 | index XXXXXXX..XXXXXXX 100644 |
44 | --- a/target/arm/m_helper.c | 58 | --- a/hw/intc/armv7m_nvic.c |
45 | +++ b/target/arm/m_helper.c | 59 | +++ b/hw/intc/armv7m_nvic.c |
46 | @@ -XXX,XX +XXX,XX @@ | 60 | @@ -XXX,XX +XXX,XX @@ |
47 | #include "exec/cpu_ldst.h" | 61 | #include "hw/intc/armv7m_nvic.h" |
48 | #endif | 62 | #include "hw/irq.h" |
49 | 63 | #include "hw/qdev-properties.h" | |
50 | +static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask, | 64 | +#include "sysemu/runstate.h" |
51 | + uint32_t reg, uint32_t val) | 65 | #include "target/arm/cpu.h" |
66 | #include "exec/exec-all.h" | ||
67 | #include "exec/memop.h" | ||
68 | @@ -XXX,XX +XXX,XX @@ static const uint8_t nvic_id[] = { | ||
69 | 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 | ||
70 | }; | ||
71 | |||
72 | +static void signal_sysresetreq(NVICState *s) | ||
52 | +{ | 73 | +{ |
53 | + /* Only APSR is actually writable */ | 74 | + if (qemu_irq_is_connected(s->sysresetreq)) { |
54 | + if (!(reg & 4)) { | 75 | + qemu_irq_pulse(s->sysresetreq); |
55 | + uint32_t apsrmask = 0; | 76 | + } else { |
56 | + | 77 | + /* |
57 | + if (mask & 8) { | 78 | + * Default behaviour if the SoC doesn't need to wire up |
58 | + apsrmask |= XPSR_NZCV | XPSR_Q; | 79 | + * SYSRESETREQ (eg to a system reset controller of some kind): |
59 | + } | 80 | + * perform a system reset via the usual QEMU API. |
60 | + if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) { | 81 | + */ |
61 | + apsrmask |= XPSR_GE; | 82 | + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
62 | + } | ||
63 | + xpsr_write(env, val, apsrmask); | ||
64 | + } | 83 | + } |
65 | +} | 84 | +} |
66 | + | 85 | + |
67 | +static uint32_t v7m_mrs_xpsr(CPUARMState *env, uint32_t reg, unsigned el) | 86 | static int nvic_pending_prio(NVICState *s) |
68 | +{ | ||
69 | + uint32_t mask = 0; | ||
70 | + | ||
71 | + if ((reg & 1) && el) { | ||
72 | + mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */ | ||
73 | + } | ||
74 | + if (!(reg & 4)) { | ||
75 | + mask |= XPSR_NZCV | XPSR_Q; /* APSR */ | ||
76 | + if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) { | ||
77 | + mask |= XPSR_GE; | ||
78 | + } | ||
79 | + } | ||
80 | + /* EPSR reads as zero */ | ||
81 | + return xpsr_read(env) & mask; | ||
82 | +} | ||
83 | + | ||
84 | +static uint32_t v7m_mrs_control(CPUARMState *env, uint32_t secure) | ||
85 | +{ | ||
86 | + uint32_t value = env->v7m.control[secure]; | ||
87 | + | ||
88 | + if (!secure) { | ||
89 | + /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */ | ||
90 | + value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK; | ||
91 | + } | ||
92 | + return value; | ||
93 | +} | ||
94 | + | ||
95 | #ifdef CONFIG_USER_ONLY | ||
96 | |||
97 | -/* These should probably raise undefined insn exceptions. */ | ||
98 | -void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) | ||
99 | +void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) | ||
100 | { | 87 | { |
101 | - ARMCPU *cpu = env_archcpu(env); | 88 | /* return the group priority of the current pending interrupt, |
102 | + uint32_t mask = extract32(maskreg, 8, 4); | 89 | @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, |
103 | + uint32_t reg = extract32(maskreg, 0, 8); | 90 | if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) { |
104 | 91 | if (attrs.secure || | |
105 | - cpu_abort(CPU(cpu), "v7m_msr %d\n", reg); | 92 | !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) { |
106 | + switch (reg) { | 93 | - qemu_irq_pulse(s->sysresetreq); |
107 | + case 0 ... 7: /* xPSR sub-fields */ | 94 | + signal_sysresetreq(s); |
108 | + v7m_msr_xpsr(env, mask, reg, val); | 95 | } |
109 | + break; | 96 | } |
110 | + case 20: /* CONTROL */ | 97 | if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) { |
111 | + /* There are no sub-fields that are actually writable from EL0. */ | ||
112 | + break; | ||
113 | + default: | ||
114 | + /* Unprivileged writes to other registers are ignored */ | ||
115 | + break; | ||
116 | + } | ||
117 | } | ||
118 | |||
119 | uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) | ||
120 | { | ||
121 | - ARMCPU *cpu = env_archcpu(env); | ||
122 | - | ||
123 | - cpu_abort(CPU(cpu), "v7m_mrs %d\n", reg); | ||
124 | - return 0; | ||
125 | + switch (reg) { | ||
126 | + case 0 ... 7: /* xPSR sub-fields */ | ||
127 | + return v7m_mrs_xpsr(env, reg, 0); | ||
128 | + case 20: /* CONTROL */ | ||
129 | + return v7m_mrs_control(env, 0); | ||
130 | + default: | ||
131 | + /* Unprivileged reads others as zero. */ | ||
132 | + return 0; | ||
133 | + } | ||
134 | } | ||
135 | |||
136 | void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest) | ||
137 | @@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) | ||
138 | |||
139 | uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) | ||
140 | { | ||
141 | - uint32_t mask; | ||
142 | unsigned el = arm_current_el(env); | ||
143 | |||
144 | /* First handle registers which unprivileged can read */ | ||
145 | - | ||
146 | switch (reg) { | ||
147 | case 0 ... 7: /* xPSR sub-fields */ | ||
148 | - mask = 0; | ||
149 | - if ((reg & 1) && el) { | ||
150 | - mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */ | ||
151 | - } | ||
152 | - if (!(reg & 4)) { | ||
153 | - mask |= XPSR_NZCV | XPSR_Q; /* APSR */ | ||
154 | - if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) { | ||
155 | - mask |= XPSR_GE; | ||
156 | - } | ||
157 | - } | ||
158 | - /* EPSR reads as zero */ | ||
159 | - return xpsr_read(env) & mask; | ||
160 | - break; | ||
161 | + return v7m_mrs_xpsr(env, reg, el); | ||
162 | case 20: /* CONTROL */ | ||
163 | - { | ||
164 | - uint32_t value = env->v7m.control[env->v7m.secure]; | ||
165 | - if (!env->v7m.secure) { | ||
166 | - /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */ | ||
167 | - value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK; | ||
168 | - } | ||
169 | - return value; | ||
170 | - } | ||
171 | + return v7m_mrs_control(env, env->v7m.secure); | ||
172 | case 0x94: /* CONTROL_NS */ | ||
173 | /* | ||
174 | * We have to handle this here because unprivileged Secure code | ||
175 | @@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) | ||
176 | |||
177 | switch (reg) { | ||
178 | case 0 ... 7: /* xPSR sub-fields */ | ||
179 | - /* only APSR is actually writable */ | ||
180 | - if (!(reg & 4)) { | ||
181 | - uint32_t apsrmask = 0; | ||
182 | - | ||
183 | - if (mask & 8) { | ||
184 | - apsrmask |= XPSR_NZCV | XPSR_Q; | ||
185 | - } | ||
186 | - if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) { | ||
187 | - apsrmask |= XPSR_GE; | ||
188 | - } | ||
189 | - xpsr_write(env, val, apsrmask); | ||
190 | - } | ||
191 | + v7m_msr_xpsr(env, mask, reg, val); | ||
192 | break; | ||
193 | case 8: /* MSP */ | ||
194 | if (v7m_using_psp(env)) { | ||
195 | -- | 98 | -- |
196 | 2.20.1 | 99 | 2.20.1 |
197 | 100 | ||
198 | 101 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | The MSF2 SoC model and the Stellaris board code both wire |
---|---|---|---|
2 | SYSRESETREQ up to a function that just invokes | ||
3 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); | ||
4 | This is now the default action that the NVIC does if the line is | ||
5 | not connected, so we can delete the handling code. | ||
2 | 6 | ||
3 | Coverity reports, in sve_zcr_get_valid_len, | 7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-id: 20200728103744.6909-4-peter.maydell@linaro.org | ||
11 | --- | ||
12 | hw/arm/msf2-soc.c | 11 ----------- | ||
13 | hw/arm/stellaris.c | 12 ------------ | ||
14 | 2 files changed, 23 deletions(-) | ||
4 | 15 | ||
5 | "Subtract operation overflows on operands | 16 | diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c |
6 | arm_cpu_vq_map_next_smaller(cpu, start_vq + 1U) and 1U" | ||
7 | |||
8 | First, the aarch32 stub version of arm_cpu_vq_map_next_smaller, | ||
9 | returning 0, does exactly what Coverity reports. Remove it. | ||
10 | |||
11 | Second, the aarch64 version of arm_cpu_vq_map_next_smaller has | ||
12 | a set of asserts, but they don't cover the case in question. | ||
13 | Further, there is a fair amount of extra arithmetic needed to | ||
14 | convert from the 0-based zcr register, to the 1-base vq form, | ||
15 | to the 0-based bitmap, and back again. This can be simplified | ||
16 | by leaving the value in the 0-based form. | ||
17 | |||
18 | Finally, use test_bit to simplify the common case, where the | ||
19 | length in the zcr registers is in fact a supported length. | ||
20 | |||
21 | Reported-by: Coverity (CID 1407217) | ||
22 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
23 | Reviewed-by: Andrew Jones <drjones@redhat.com> | ||
24 | Message-id: 20191118091414.19440-1-richard.henderson@linaro.org | ||
25 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
26 | --- | ||
27 | target/arm/cpu.h | 3 --- | ||
28 | target/arm/cpu64.c | 15 --------------- | ||
29 | target/arm/helper.c | 9 +++++++-- | ||
30 | 3 files changed, 7 insertions(+), 20 deletions(-) | ||
31 | |||
32 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | ||
33 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/target/arm/cpu.h | 18 | --- a/hw/arm/msf2-soc.c |
35 | +++ b/target/arm/cpu.h | 19 | +++ b/hw/arm/msf2-soc.c |
36 | @@ -XXX,XX +XXX,XX @@ typedef struct { | 20 | @@ -XXX,XX +XXX,XX @@ |
37 | #ifdef TARGET_AARCH64 | 21 | #include "hw/irq.h" |
38 | # define ARM_MAX_VQ 16 | 22 | #include "hw/arm/msf2-soc.h" |
39 | void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp); | 23 | #include "hw/misc/unimp.h" |
40 | -uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq); | 24 | -#include "sysemu/runstate.h" |
41 | #else | 25 | #include "sysemu/sysemu.h" |
42 | # define ARM_MAX_VQ 1 | 26 | |
43 | static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { } | 27 | #define MSF2_TIMER_BASE 0x40004000 |
44 | -static inline uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq) | 28 | @@ -XXX,XX +XXX,XX @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 }; |
45 | -{ return 0; } | 29 | static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 }; |
46 | #endif | 30 | static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 }; |
47 | 31 | ||
48 | typedef struct ARMVectorReg { | 32 | -static void do_sys_reset(void *opaque, int n, int level) |
49 | diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/target/arm/cpu64.c | ||
52 | +++ b/target/arm/cpu64.c | ||
53 | @@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) | ||
54 | cpu->sve_max_vq = max_vq; | ||
55 | } | ||
56 | |||
57 | -uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq) | ||
58 | -{ | 33 | -{ |
59 | - uint32_t bitnum; | 34 | - if (level) { |
60 | - | 35 | - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
61 | - /* | 36 | - } |
62 | - * We allow vq == ARM_MAX_VQ + 1 to be input because the caller may want | ||
63 | - * to find the maximum vq enabled, which may be ARM_MAX_VQ, but this | ||
64 | - * function always returns the next smaller than the input. | ||
65 | - */ | ||
66 | - assert(vq && vq <= ARM_MAX_VQ + 1); | ||
67 | - | ||
68 | - bitnum = find_last_bit(cpu->sve_vq_map, vq - 1); | ||
69 | - return bitnum == vq - 1 ? 0 : bitnum + 1; | ||
70 | -} | 37 | -} |
71 | - | 38 | - |
72 | static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name, | 39 | static void m2sxxx_soc_initfn(Object *obj) |
73 | void *opaque, Error **errp) | ||
74 | { | 40 | { |
75 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 41 | MSF2State *s = MSF2_SOC(obj); |
42 | @@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | - qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0, | ||
47 | - qemu_allocate_irq(&do_sys_reset, NULL, 0)); | ||
48 | - | ||
49 | system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk; | ||
50 | |||
51 | for (i = 0; i < MSF2_NUM_UARTS; i++) { | ||
52 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | 53 | index XXXXXXX..XXXXXXX 100644 |
77 | --- a/target/arm/helper.c | 54 | --- a/hw/arm/stellaris.c |
78 | +++ b/target/arm/helper.c | 55 | +++ b/hw/arm/stellaris.c |
79 | @@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el) | 56 | @@ -XXX,XX +XXX,XX @@ |
80 | 57 | #include "hw/boards.h" | |
81 | static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len) | 58 | #include "qemu/log.h" |
82 | { | 59 | #include "exec/address-spaces.h" |
83 | - uint32_t start_vq = (start_len & 0xf) + 1; | 60 | -#include "sysemu/runstate.h" |
84 | + uint32_t end_len; | 61 | #include "sysemu/sysemu.h" |
85 | 62 | #include "hw/arm/armv7m.h" | |
86 | - return arm_cpu_vq_map_next_smaller(cpu, start_vq + 1) - 1; | 63 | #include "hw/char/pl011.h" |
87 | + end_len = start_len &= 0xf; | 64 | @@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj) |
88 | + if (!test_bit(start_len, cpu->sve_vq_map)) { | 65 | qdev_init_gpio_in(dev, stellaris_adc_trigger, 1); |
89 | + end_len = find_last_bit(cpu->sve_vq_map, start_len); | ||
90 | + assert(end_len < start_len); | ||
91 | + } | ||
92 | + return end_len; | ||
93 | } | 66 | } |
94 | 67 | ||
95 | /* | 68 | -static |
69 | -void do_sys_reset(void *opaque, int n, int level) | ||
70 | -{ | ||
71 | - if (level) { | ||
72 | - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); | ||
73 | - } | ||
74 | -} | ||
75 | - | ||
76 | /* Board init. */ | ||
77 | static stellaris_board_info stellaris_boards[] = { | ||
78 | { "LM3S811EVB", | ||
79 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
80 | /* This will exit with an error if the user passed us a bad cpu_type */ | ||
81 | sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal); | ||
82 | |||
83 | - qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0, | ||
84 | - qemu_allocate_irq(&do_sys_reset, NULL, 0)); | ||
85 | - | ||
86 | if (board->dc1 & (1 << 16)) { | ||
87 | dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, | ||
88 | qdev_get_gpio_in(nvic, 14), | ||
96 | -- | 89 | -- |
97 | 2.20.1 | 90 | 2.20.1 |
98 | 91 | ||
99 | 92 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Richard Henderson <richard.henderson@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Armv8-A removes UNPREDICTABLE for R13 for these cases. | 3 | The definition of top_bit used in this function is one higher |
4 | than that used in the Arm ARM psuedo-code, which put the error | ||
5 | indication at top_bit - 1 at the wrong place, which meant that | ||
6 | it wasn't visible to Auth. | ||
4 | 7 | ||
8 | Fixing the definition of top_bit requires more changes, because | ||
9 | its most common use is for the count of bits in top_bit:bot_bit, | ||
10 | which would then need to be computed as top_bit - bot_bit + 1. | ||
11 | |||
12 | For now, prefer the minimal fix to the error indication alone. | ||
13 | |||
14 | Fixes: 63ff0ca94cb | ||
15 | Reported-by: Derrick McKee <derrick.mckee@gmail.com> | ||
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 16 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | Message-id: 20191117090621.32425-3-richard.henderson@linaro.org | 17 | Message-id: 20200728195706.11087-1-richard.henderson@linaro.org |
7 | [PMM: changed ENABLE_ARCH_8 checks to check a new bool 'v8a', | ||
8 | since these cases are still UNPREDICTABLE for v8M] | ||
9 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 18 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
19 | [PMM: added comment about the divergence from the pseudocode] | ||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 20 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
11 | --- | 21 | --- |
12 | target/arm/translate.c | 12 ++++++++---- | 22 | target/arm/pauth_helper.c | 6 +++++- |
13 | 1 file changed, 8 insertions(+), 4 deletions(-) | 23 | tests/tcg/aarch64/pauth-5.c | 33 +++++++++++++++++++++++++++++++ |
24 | tests/tcg/aarch64/Makefile.target | 2 +- | ||
25 | 3 files changed, 39 insertions(+), 2 deletions(-) | ||
26 | create mode 100644 tests/tcg/aarch64/pauth-5.c | ||
14 | 27 | ||
15 | diff --git a/target/arm/translate.c b/target/arm/translate.c | 28 | diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c |
16 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/translate.c | 30 | --- a/target/arm/pauth_helper.c |
18 | +++ b/target/arm/translate.c | 31 | +++ b/target/arm/pauth_helper.c |
19 | @@ -XXX,XX +XXX,XX @@ static bool trans_SWPB(DisasContext *s, arg_SWP *a) | 32 | @@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier, |
20 | static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel) | 33 | */ |
21 | { | 34 | test = sextract64(ptr, bot_bit, top_bit - bot_bit); |
22 | TCGv_i32 addr; | 35 | if (test != 0 && test != -1) { |
23 | + /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */ | 36 | - pac ^= MAKE_64BIT_MASK(top_bit - 1, 1); |
24 | + bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M); | 37 | + /* |
25 | 38 | + * Note that our top_bit is one greater than the pseudocode's | |
26 | /* We UNDEF for these UNPREDICTABLE cases. */ | 39 | + * version, hence "- 2" here. |
27 | if (a->rd == 15 || a->rn == 15 || a->rt == 15 | 40 | + */ |
28 | || a->rd == a->rn || a->rd == a->rt | 41 | + pac ^= MAKE_64BIT_MASK(top_bit - 2, 1); |
29 | - || (s->thumb && (a->rd == 13 || a->rt == 13)) | ||
30 | + || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13)) | ||
31 | || (mop == MO_64 | ||
32 | && (a->rt2 == 15 | ||
33 | || a->rd == a->rt2 | ||
34 | - || (s->thumb && a->rt2 == 13)))) { | ||
35 | + || (!v8a && s->thumb && a->rt2 == 13)))) { | ||
36 | unallocated_encoding(s); | ||
37 | return true; | ||
38 | } | 42 | } |
39 | @@ -XXX,XX +XXX,XX @@ static bool trans_STLH(DisasContext *s, arg_STL *a) | 43 | |
40 | static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq) | 44 | /* |
41 | { | 45 | diff --git a/tests/tcg/aarch64/pauth-5.c b/tests/tcg/aarch64/pauth-5.c |
42 | TCGv_i32 addr; | 46 | new file mode 100644 |
43 | + /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */ | 47 | index XXXXXXX..XXXXXXX |
44 | + bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M); | 48 | --- /dev/null |
45 | 49 | +++ b/tests/tcg/aarch64/pauth-5.c | |
46 | /* We UNDEF for these UNPREDICTABLE cases. */ | 50 | @@ -XXX,XX +XXX,XX @@ |
47 | if (a->rn == 15 || a->rt == 15 | 51 | +#include <assert.h> |
48 | - || (s->thumb && a->rt == 13) | 52 | + |
49 | + || (!v8a && s->thumb && a->rt == 13) | 53 | +static int x; |
50 | || (mop == MO_64 | 54 | + |
51 | && (a->rt2 == 15 || a->rt == a->rt2 | 55 | +int main() |
52 | - || (s->thumb && a->rt2 == 13)))) { | 56 | +{ |
53 | + || (!v8a && s->thumb && a->rt2 == 13)))) { | 57 | + int *p0 = &x, *p1, *p2, *p3; |
54 | unallocated_encoding(s); | 58 | + unsigned long salt = 0; |
55 | return true; | 59 | + |
56 | } | 60 | + /* |
61 | + * With TBI enabled and a 48-bit VA, there are 7 bits of auth, and so | ||
62 | + * a 1/128 chance of auth = pac(ptr,key,salt) producing zero. | ||
63 | + * Find a salt that creates auth != 0. | ||
64 | + */ | ||
65 | + do { | ||
66 | + salt++; | ||
67 | + asm("pacda %0, %1" : "=r"(p1) : "r"(salt), "0"(p0)); | ||
68 | + } while (p0 == p1); | ||
69 | + | ||
70 | + /* | ||
71 | + * This pac must fail, because the input pointer bears an encryption, | ||
72 | + * and so is not properly extended within bits [55:47]. This will | ||
73 | + * toggle bit 54 in the output... | ||
74 | + */ | ||
75 | + asm("pacda %0, %1" : "=r"(p2) : "r"(salt), "0"(p1)); | ||
76 | + | ||
77 | + /* ... so that the aut must fail, setting bit 53 in the output ... */ | ||
78 | + asm("autda %0, %1" : "=r"(p3) : "r"(salt), "0"(p2)); | ||
79 | + | ||
80 | + /* ... which means this equality must not hold. */ | ||
81 | + assert(p3 != p0); | ||
82 | + return 0; | ||
83 | +} | ||
84 | diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target | ||
85 | index XXXXXXX..XXXXXXX 100644 | ||
86 | --- a/tests/tcg/aarch64/Makefile.target | ||
87 | +++ b/tests/tcg/aarch64/Makefile.target | ||
88 | @@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt | ||
89 | |||
90 | # Pauth Tests | ||
91 | ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_3),) | ||
92 | -AARCH64_TESTS += pauth-1 pauth-2 pauth-4 | ||
93 | +AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 | ||
94 | pauth-%: CFLAGS += -march=armv8.3-a | ||
95 | run-pauth-%: QEMU_OPTS += -cpu max | ||
96 | run-plugin-pauth-%: QEMU_OPTS += -cpu max | ||
57 | -- | 97 | -- |
58 | 2.20.1 | 98 | 2.20.1 |
59 | 99 | ||
60 | 100 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Kaige Li <likaige@loongson.cn> |
---|---|---|---|
2 | 2 | ||
3 | There was too much cut and paste between ldrexd and strexd, | 3 | GCC version 4.9.4 isn't clever enough to figure out that all |
4 | as ldrexd does prohibit two output registers the same. | 4 | execution paths in disas_ldst() that use 'fn' will have initialized |
5 | it first, and so it warns: | ||
5 | 6 | ||
6 | Fixes: af288228995 | 7 | /home/LiKaige/qemu/target/arm/translate-a64.c: In function ‘disas_ldst’: |
7 | Reported-by: Michael Goffioul <michael.goffioul@gmail.com> | 8 | /home/LiKaige/qemu/target/arm/translate-a64.c:3392:5: error: ‘fn’ may be used uninitialized in this function [-Werror=maybe-uninitialized] |
8 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 9 | fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s), |
9 | Message-id: 20191117090621.32425-2-richard.henderson@linaro.org | 10 | ^ |
10 | Reviewed-by: Robert Foley <robert.foley@linaro.org> | 11 | /home/LiKaige/qemu/target/arm/translate-a64.c:3318:22: note: ‘fn’ was declared here |
12 | AtomicThreeOpFn *fn; | ||
13 | ^ | ||
14 | |||
15 | Make it happy by initializing the variable to NULL. | ||
16 | |||
17 | Signed-off-by: Kaige Li <likaige@loongson.cn> | ||
18 | Message-id: 1596110248-7366-2-git-send-email-likaige@loongson.cn | ||
11 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 19 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
20 | [PMM: Clean up commit message and note which gcc version this was] | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 21 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
13 | --- | 22 | --- |
14 | target/arm/translate.c | 2 +- | 23 | target/arm/translate-a64.c | 2 +- |
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | 24 | 1 file changed, 1 insertion(+), 1 deletion(-) |
16 | 25 | ||
17 | diff --git a/target/arm/translate.c b/target/arm/translate.c | 26 | diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c |
18 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/arm/translate.c | 28 | --- a/target/arm/translate-a64.c |
20 | +++ b/target/arm/translate.c | 29 | +++ b/target/arm/translate-a64.c |
21 | @@ -XXX,XX +XXX,XX @@ static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel) | 30 | @@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn, |
22 | || (s->thumb && (a->rd == 13 || a->rt == 13)) | 31 | bool r = extract32(insn, 22, 1); |
23 | || (mop == MO_64 | 32 | bool a = extract32(insn, 23, 1); |
24 | && (a->rt2 == 15 | 33 | TCGv_i64 tcg_rs, clean_addr; |
25 | - || a->rd == a->rt2 || a->rt == a->rt2 | 34 | - AtomicThreeOpFn *fn; |
26 | + || a->rd == a->rt2 | 35 | + AtomicThreeOpFn *fn = NULL; |
27 | || (s->thumb && a->rt2 == 13)))) { | 36 | |
37 | if (is_vector || !dc_isar_feature(aa64_atomics, s)) { | ||
28 | unallocated_encoding(s); | 38 | unallocated_encoding(s); |
29 | return true; | ||
30 | -- | 39 | -- |
31 | 2.20.1 | 40 | 2.20.1 |
32 | 41 | ||
33 | 42 | diff view generated by jsdifflib |
1 | From: Alexander Graf <graf@amazon.com> | 1 | The nrf51 SoC model wasn't setting the system_clock_scale |
---|---|---|---|
2 | global.which meant that if guest code used the systick timer in "use | ||
3 | the processor clock" mode it would hang because time never advances. | ||
2 | 4 | ||
3 | The current PL031 RTCICR register implementation always clears the | 5 | Set the global to match the documented CPU clock speed for this SoC. |
4 | IRQ pending status on a register write, regardless of the value the | ||
5 | guest writes. | ||
6 | 6 | ||
7 | To justify that behavior, it references the ARM926EJ-S Development | 7 | This SoC in fact doesn't have a SysTick timer (which is the only thing |
8 | Chip Reference Manual (DDI0287B) and indicates that said document | 8 | currently that cares about the system_clock_scale), because it's |
9 | states that any write clears the internal IRQ state. It is indeed | 9 | a configurable option in the Cortex-M0. However our Cortex-M0 and |
10 | true that in section 11.1 this document says: | 10 | thus our nrf51 and our micro:bit board do provide a SysTick, so |
11 | we ought to provide a functional one rather than a broken one. | ||
11 | 12 | ||
12 | "The interrupt is cleared by writing any data value to the | 13 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
13 | interrupt clear register RTCICR". | 14 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
15 | Message-id: 20200727193458.31250-1-peter.maydell@linaro.org | ||
16 | --- | ||
17 | hw/arm/nrf51_soc.c | 5 +++++ | ||
18 | 1 file changed, 5 insertions(+) | ||
14 | 19 | ||
15 | However, later in section 11.2.2 it contradicts itself by saying: | 20 | diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c |
16 | |||
17 | "Writing 1 to bit 0 of RTCICR clears the RTCINTR flag." | ||
18 | |||
19 | The latter statement matches the PL031 TRM (DDI0224C), which says: | ||
20 | |||
21 | "Writing 1 to bit position 0 clears the corresponding interrupt. | ||
22 | Writing 0 has no effect." | ||
23 | |||
24 | Let's assume that the self-contradictory DDI0287B is in error, and | ||
25 | follow the reference manual for the device itself, by making the | ||
26 | register write-one-to-clear. | ||
27 | |||
28 | Reported-by: Hendrik Borghorst <hborghor@amazon.de> | ||
29 | Signed-off-by: Alexander Graf <graf@amazon.com> | ||
30 | Message-id: 20191104115228.30745-1-graf@amazon.com | ||
31 | [PMM: updated commit message to note that DDI0287B says two | ||
32 | conflicting things] | ||
33 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
34 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
35 | --- | ||
36 | hw/rtc/pl031.c | 6 +----- | ||
37 | 1 file changed, 1 insertion(+), 5 deletions(-) | ||
38 | |||
39 | diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/hw/rtc/pl031.c | 22 | --- a/hw/arm/nrf51_soc.c |
42 | +++ b/hw/rtc/pl031.c | 23 | +++ b/hw/arm/nrf51_soc.c |
43 | @@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset, | 24 | @@ -XXX,XX +XXX,XX @@ |
44 | pl031_update(s); | 25 | |
45 | break; | 26 | #define BASE_TO_IRQ(base) ((base >> 12) & 0x1F) |
46 | case RTC_ICR: | 27 | |
47 | - /* The PL031 documentation (DDI0224B) states that the interrupt is | 28 | +/* HCLK (the main CPU clock) on this SoC is always 16MHz */ |
48 | - cleared when bit 0 of the written value is set. However the | 29 | +#define HCLK_FRQ 16000000 |
49 | - arm926e documentation (DDI0287B) states that the interrupt is | 30 | + |
50 | - cleared when any value is written. */ | 31 | static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size) |
51 | - s->is = 0; | 32 | { |
52 | + s->is &= ~value; | 33 | qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n", |
53 | pl031_update(s); | 34 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) |
54 | break; | 35 | return; |
55 | case RTC_CR: | 36 | } |
37 | |||
38 | + system_clock_scale = NANOSECONDS_PER_SECOND / HCLK_FRQ; | ||
39 | + | ||
40 | object_property_set_link(OBJECT(&s->cpu), "memory", OBJECT(&s->container), | ||
41 | &error_abort); | ||
42 | if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu), errp)) { | ||
56 | -- | 43 | -- |
57 | 2.20.1 | 44 | 2.20.1 |
58 | 45 | ||
59 | 46 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | The imx_epit device has a software-controllable reset triggered by | ||
2 | setting the SWR bit in the CR register. An error in commit cc2722ec83ad9 | ||
3 | means that we will end up assert()ing if the guest does this, because | ||
4 | the code in imx_epit_write() starts ptimer transactions, and then | ||
5 | imx_epit_reset() also starts ptimer transactions, triggering | ||
6 | "ptimer_transaction_begin: Assertion `!s->in_transaction' failed". | ||
1 | 7 | ||
8 | The cleanest way to avoid this double-transaction is to move the | ||
9 | start-transaction for the CR write handling down below the check of | ||
10 | the SWR bit. | ||
11 | |||
12 | Fixes: https://bugs.launchpad.net/qemu/+bug/1880424 | ||
13 | Fixes: cc2722ec83ad944505fe | ||
14 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
15 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
16 | Message-id: 20200727154550.3409-1-peter.maydell@linaro.org | ||
17 | --- | ||
18 | hw/timer/imx_epit.c | 13 ++++++++++--- | ||
19 | 1 file changed, 10 insertions(+), 3 deletions(-) | ||
20 | |||
21 | diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/timer/imx_epit.c | ||
24 | +++ b/hw/timer/imx_epit.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value, | ||
26 | |||
27 | switch (offset >> 2) { | ||
28 | case 0: /* CR */ | ||
29 | - ptimer_transaction_begin(s->timer_cmp); | ||
30 | - ptimer_transaction_begin(s->timer_reload); | ||
31 | |||
32 | oldcr = s->cr; | ||
33 | s->cr = value & 0x03ffffff; | ||
34 | if (s->cr & CR_SWR) { | ||
35 | /* handle the reset */ | ||
36 | imx_epit_reset(DEVICE(s)); | ||
37 | - } else { | ||
38 | + /* | ||
39 | + * TODO: could we 'break' here? following operations appear | ||
40 | + * to duplicate the work imx_epit_reset() already did. | ||
41 | + */ | ||
42 | + } | ||
43 | + | ||
44 | + ptimer_transaction_begin(s->timer_cmp); | ||
45 | + ptimer_transaction_begin(s->timer_reload); | ||
46 | + | ||
47 | + if (!(s->cr & CR_SWR)) { | ||
48 | imx_epit_set_freq(s); | ||
49 | } | ||
50 | |||
51 | -- | ||
52 | 2.20.1 | ||
53 | |||
54 | diff view generated by jsdifflib |