1
Arm patches for rc1:
1
Handful of bugfixes for rc2. None of these are particularly critical
2
* two final "remove the old API" patches for some API transitions
2
or exciting.
3
* bugfix for raspi/highbank Linux boot
4
3
5
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 654efcb511d394c1d3f5292c28503d1d19e5b1d3:
6
The following changes since commit 45a150aa2b3492acf6691c7bdbeb25a8545d8345:
9
7
10
Merge remote-tracking branch 'remotes/vivier/tags/q800-branch-pull-request' into staging (2019-11-11 09:23:46 +0000)
8
Merge remote-tracking branch 'remotes/ericb/tags/pull-bitmaps-2020-08-03' into staging (2020-08-03 15:13:49 +0100)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191111
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200803
15
13
16
for you to fetch changes up to 45c078f163fd47c35e7505d98928fae63baada7d:
14
for you to fetch changes up to 13557fd392890cbd985bceba7f717e01efd674b8:
17
15
18
hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine (2019-11-11 13:44:16 +0000)
16
hw/timer/imx_epit: Avoid assertion when CR.SWR is written (2020-08-03 17:56:11 +0100)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
target-arm queue:
19
target-arm queue:
22
* Remove old unassigned_access CPU hook API
20
* hw/timer/imx_epit: Avoid assertion when CR.SWR is written
23
* Remove old ptimer_init_with_bh() API
21
* netduino2, netduinoplus2, microbit: set system_clock_scale so that
24
* hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine
22
SysTick running on the CPU clock works
23
* target/arm: Avoid maybe-uninitialized warning with gcc 4.9
24
* target/arm: Fix AddPAC error indication
25
* Make AIRCR.SYSRESETREQ actually reset the system for the
26
microbit, mps2-*, musca-*, netduino* boards
25
27
26
----------------------------------------------------------------
28
----------------------------------------------------------------
27
Clement Deschamps (1):
29
Kaige Li (1):
28
hw/arm/boot: Set NSACR.{CP11, CP10} in dummy SMC setup routine
30
target/arm: Avoid maybe-uninitialized warning with gcc 4.9
29
31
30
Peter Maydell (2):
32
Peter Maydell (6):
31
ptimer: Remove old ptimer_init_with_bh() API
33
hw/arm/netduino2, netduinoplus2: Set system_clock_scale
32
Remove unassigned_access CPU hook
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
include/hw/arm/boot.h | 7 ++--
40
Richard Henderson (1):
35
include/hw/core/cpu.h | 24 --------------
41
target/arm: Fix AddPAC error indication
36
include/hw/ptimer.h | 45 ++++++++++++-------------
37
accel/tcg/cputlb.c | 2 --
38
hw/arm/boot.c | 3 ++
39
hw/core/ptimer.c | 91 +++++++++------------------------------------------
40
memory.c | 7 ----
41
7 files changed, 44 insertions(+), 135 deletions(-)
42
42
43
include/hw/arm/armv7m.h | 4 +++-
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
58
diff view generated by jsdifflib
New patch
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.
1
4
5
Set the global to match the documented CPU clock speed of these boards.
6
Judging by the data sheet this is slightly simplistic because the
7
SoC allows configuration of the SYSCLK source and frequency via the
8
RCC (reset and clock control) module, but we don't model that.
9
10
Fixes: https://bugs.launchpad.net/qemu/+bug/1876187
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(+)
18
19
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/netduino2.c
22
+++ b/hw/arm/netduino2.c
23
@@ -XXX,XX +XXX,XX @@
24
#include "hw/arm/stm32f205_soc.h"
25
#include "hw/arm/boot.h"
26
27
+/* Main SYSCLK frequency in Hz (120MHz) */
28
+#define SYSCLK_FRQ 120000000ULL
29
+
30
static void netduino2_init(MachineState *machine)
31
{
32
DeviceState *dev;
33
34
+ /*
35
+ * TODO: ideally we would model the SoC RCC and let it handle
36
+ * system_clock_scale, including its ability to define different
37
+ * possible SYSCLK sources.
38
+ */
39
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
40
+
41
dev = qdev_new(TYPE_STM32F205_SOC);
42
qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
43
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
44
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
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);
69
--
70
2.20.1
71
72
diff view generated by jsdifflib
New patch
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.
1
6
7
Provide a function qemu_irq_is_connected() that devices can use for
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.)
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20200728103744.6909-2-peter.maydell@linaro.org
16
---
17
include/hw/irq.h | 18 ++++++++++++++++++
18
1 file changed, 18 insertions(+)
19
20
diff --git a/include/hw/irq.h b/include/hw/irq.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/irq.h
23
+++ b/include/hw/irq.h
24
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
25
on an existing vector of qemu_irq. */
26
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
27
28
+/**
29
+ * qemu_irq_is_connected: Return true if IRQ line is wired up
30
+ *
31
+ * If a qemu_irq has a device on the other (receiving) end of it,
32
+ * return true; otherwise return false.
33
+ *
34
+ * Usually device models don't need to care whether the machine model
35
+ * has wired up their outbound qemu_irq lines, because functions like
36
+ * qemu_set_irq() silently do nothing if there is nothing on the other
37
+ * end of the line. However occasionally a device model will want to
38
+ * provide default behaviour if its output is left floating, and
39
+ * it can use this function to identify when that is the case.
40
+ */
41
+static inline bool qemu_irq_is_connected(qemu_irq irq)
42
+{
43
+ return irq != NULL;
44
+}
45
+
46
#endif
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
New patch
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.
1
8
9
Provide a default behaviour for the case where SYSRESETREQ is not
10
actually connected to anything: use qemu_system_reset_request() to
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:
15
16
* microbit
17
* mps2-an385
18
* mps2-an505
19
* mps2-an511
20
* mps2-an521
21
* musca-a
22
* musca-b1
23
* netduino
24
* netduinoplus2
25
26
We still allow the board to wire up the signal if it needs to, in case
27
we need to model more complicated reset controller logic or to model
28
buggy SoC hardware which forgot to wire up the line itself. But
29
defaulting to "reset the system" is more often going to be correct
30
than defaulting to "do nothing".
31
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
36
---
37
include/hw/arm/armv7m.h | 4 +++-
38
hw/intc/armv7m_nvic.c | 17 ++++++++++++++++-
39
2 files changed, 19 insertions(+), 2 deletions(-)
40
41
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/arm/armv7m.h
44
+++ b/include/hw/arm/armv7m.h
45
@@ -XXX,XX +XXX,XX @@ typedef struct {
46
47
/* ARMv7M container object.
48
* + Unnamed GPIO input lines: external IRQ lines for the NVIC
49
- * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ
50
+ * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ.
51
+ * If this GPIO is not wired up then the NVIC will default to performing
52
+ * a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET).
53
* + Property "cpu-type": CPU type to instantiate
54
* + Property "num-irq": number of external IRQ lines
55
* + Property "memory": MemoryRegion defining the physical address space
56
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/armv7m_nvic.c
59
+++ b/hw/intc/armv7m_nvic.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/intc/armv7m_nvic.h"
62
#include "hw/irq.h"
63
#include "hw/qdev-properties.h"
64
+#include "sysemu/runstate.h"
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)
73
+{
74
+ if (qemu_irq_is_connected(s->sysresetreq)) {
75
+ qemu_irq_pulse(s->sysresetreq);
76
+ } else {
77
+ /*
78
+ * Default behaviour if the SoC doesn't need to wire up
79
+ * SYSRESETREQ (eg to a system reset controller of some kind):
80
+ * perform a system reset via the usual QEMU API.
81
+ */
82
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
83
+ }
84
+}
85
+
86
static int nvic_pending_prio(NVICState *s)
87
{
88
/* return the group priority of the current pending interrupt,
89
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
90
if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {
91
if (attrs.secure ||
92
!(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {
93
- qemu_irq_pulse(s->sysresetreq);
94
+ signal_sysresetreq(s);
95
}
96
}
97
if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {
98
--
99
2.20.1
100
101
diff view generated by jsdifflib
1
All targets have now migrated away from the old unassigned_access
1
The MSF2 SoC model and the Stellaris board code both wire
2
hook to the new do_transaction_failed hook. This means we can remove
2
SYSRESETREQ up to a function that just invokes
3
the core-code infrastructure for that hook and the code that calls it.
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.
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20191108173732.11816-1-peter.maydell@linaro.org
10
Message-id: 20200728103744.6909-4-peter.maydell@linaro.org
9
---
11
---
10
include/hw/core/cpu.h | 24 ------------------------
12
hw/arm/msf2-soc.c | 11 -----------
11
accel/tcg/cputlb.c | 2 --
13
hw/arm/stellaris.c | 12 ------------
12
memory.c | 7 -------
14
2 files changed, 23 deletions(-)
13
3 files changed, 33 deletions(-)
14
15
15
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
16
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/core/cpu.h
18
--- a/hw/arm/msf2-soc.c
18
+++ b/include/hw/core/cpu.h
19
+++ b/hw/arm/msf2-soc.c
19
@@ -XXX,XX +XXX,XX @@ typedef enum MMUAccessType {
20
@@ -XXX,XX +XXX,XX @@
20
21
#include "hw/irq.h"
21
typedef struct CPUWatchpoint CPUWatchpoint;
22
#include "hw/arm/msf2-soc.h"
22
23
#include "hw/misc/unimp.h"
23
-typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
24
-#include "sysemu/runstate.h"
24
- bool is_write, bool is_exec, int opaque,
25
#include "sysemu/sysemu.h"
25
- unsigned size);
26
26
-
27
#define MSF2_TIMER_BASE 0x40004000
27
struct TranslationBlock;
28
@@ -XXX,XX +XXX,XX @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
28
29
static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
29
/**
30
static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
30
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
31
31
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
32
-static void do_sys_reset(void *opaque, int n, int level)
32
* @has_work: Callback for checking if there is work to do.
33
* @do_interrupt: Callback for interrupt handling.
34
- * @do_unassigned_access: Callback for unassigned access handling.
35
- * (this is deprecated: new targets should use do_transaction_failed instead)
36
* @do_unaligned_access: Callback for unaligned access handling, if
37
* the target defines #TARGET_ALIGNED_ONLY.
38
* @do_transaction_failed: Callback for handling failed memory transactions
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
40
int reset_dump_flags;
41
bool (*has_work)(CPUState *cpu);
42
void (*do_interrupt)(CPUState *cpu);
43
- CPUUnassignedAccess do_unassigned_access;
44
void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
45
MMUAccessType access_type,
46
int mmu_idx, uintptr_t retaddr);
47
@@ -XXX,XX +XXX,XX @@ struct CPUState {
48
* we store some rarely used information in the CPU context.
49
*/
50
uintptr_t mem_io_pc;
51
- /*
52
- * This is only needed for the legacy cpu_unassigned_access() hook;
53
- * when all targets using it have been converted to use
54
- * cpu_transaction_failed() instead it can be removed.
55
- */
56
- MMUAccessType mem_io_access_type;
57
58
int kvm_fd;
59
struct KVMState *kvm_state;
60
@@ -XXX,XX +XXX,XX @@ void cpu_interrupt(CPUState *cpu, int mask);
61
#ifdef NEED_CPU_H
62
63
#ifdef CONFIG_SOFTMMU
64
-static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr,
65
- bool is_write, bool is_exec,
66
- int opaque, unsigned size)
67
-{
33
-{
68
- CPUClass *cc = CPU_GET_CLASS(cpu);
34
- if (level) {
69
-
35
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
70
- if (cc->do_unassigned_access) {
71
- cc->do_unassigned_access(cpu, addr, is_write, is_exec, opaque, size);
72
- }
36
- }
73
-}
37
-}
74
-
38
-
75
static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
39
static void m2sxxx_soc_initfn(Object *obj)
76
MMUAccessType access_type,
40
{
77
int mmu_idx, uintptr_t retaddr)
41
MSF2State *s = MSF2_SOC(obj);
78
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
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
79
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/tcg/cputlb.c
54
--- a/hw/arm/stellaris.c
81
+++ b/accel/tcg/cputlb.c
55
+++ b/hw/arm/stellaris.c
82
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
56
@@ -XXX,XX +XXX,XX @@
83
cpu_io_recompile(cpu, retaddr);
57
#include "hw/boards.h"
84
}
58
#include "qemu/log.h"
85
59
#include "exec/address-spaces.h"
86
- cpu->mem_io_access_type = access_type;
60
-#include "sysemu/runstate.h"
61
#include "sysemu/sysemu.h"
62
#include "hw/arm/armv7m.h"
63
#include "hw/char/pl011.h"
64
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
65
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
66
}
67
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
-}
87
-
75
-
88
if (mr->global_locking && !qemu_mutex_iothread_locked()) {
76
/* Board init. */
89
qemu_mutex_lock_iothread();
77
static stellaris_board_info stellaris_boards[] = {
90
locked = true;
78
{ "LM3S811EVB",
91
diff --git a/memory.c b/memory.c
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
92
index XXXXXXX..XXXXXXX 100644
80
/* This will exit with an error if the user passed us a bad cpu_type */
93
--- a/memory.c
81
sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal);
94
+++ b/memory.c
82
95
@@ -XXX,XX +XXX,XX @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
83
- qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
96
#ifdef DEBUG_UNASSIGNED
84
- qemu_allocate_irq(&do_sys_reset, NULL, 0));
97
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
85
-
98
#endif
86
if (board->dc1 & (1 << 16)) {
99
- if (current_cpu != NULL) {
87
dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
100
- bool is_exec = current_cpu->mem_io_access_type == MMU_INST_FETCH;
88
qdev_get_gpio_in(nvic, 14),
101
- cpu_unassigned_access(current_cpu, addr, false, is_exec, 0, size);
102
- }
103
return 0;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
107
#ifdef DEBUG_UNASSIGNED
108
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
109
#endif
110
- if (current_cpu != NULL) {
111
- cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
112
- }
113
}
114
115
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
116
--
89
--
117
2.20.1
90
2.20.1
118
91
119
92
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
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.
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>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20200728195706.11087-1-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: added comment about the divergence from the pseudocode]
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
target/arm/pauth_helper.c | 6 +++++-
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
27
28
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/pauth_helper.c
31
+++ b/target/arm/pauth_helper.c
32
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
33
*/
34
test = sextract64(ptr, bot_bit, top_bit - bot_bit);
35
if (test != 0 && test != -1) {
36
- pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
37
+ /*
38
+ * Note that our top_bit is one greater than the pseudocode's
39
+ * version, hence "- 2" here.
40
+ */
41
+ pac ^= MAKE_64BIT_MASK(top_bit - 2, 1);
42
}
43
44
/*
45
diff --git a/tests/tcg/aarch64/pauth-5.c b/tests/tcg/aarch64/pauth-5.c
46
new file mode 100644
47
index XXXXXXX..XXXXXXX
48
--- /dev/null
49
+++ b/tests/tcg/aarch64/pauth-5.c
50
@@ -XXX,XX +XXX,XX @@
51
+#include <assert.h>
52
+
53
+static int x;
54
+
55
+int main()
56
+{
57
+ int *p0 = &x, *p1, *p2, *p3;
58
+ unsigned long salt = 0;
59
+
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
97
--
98
2.20.1
99
100
diff view generated by jsdifflib
1
From: Clement Deschamps <clement.deschamps@greensocs.com>
1
From: Kaige Li <likaige@loongson.cn>
2
2
3
The boot.c code usually puts the CPU into NS mode directly when it is
3
GCC version 4.9.4 isn't clever enough to figure out that all
4
booting a kernel. Since fc1120a7f5f2d4b6 this has included a
4
execution paths in disas_ldst() that use 'fn' will have initialized
5
requirement to set NSACR to give NS state access to the FPU; we fixed
5
it first, and so it warns:
6
that for the usual code path in ece628fcf6. However, it is also
7
possible for a board model to request an alternative mode of booting,
8
where its 'board_setup' code hook runs in Secure state and is
9
responsible for doing the S->NS transition after it has done whatever
10
work it must do in Secure state. In this situation the board_setup
11
code now also needs to update NSACR.
12
6
13
This affects all boards which set info->secure_board_setup, which is
7
/home/LiKaige/qemu/target/arm/translate-a64.c: In function ‘disas_ldst’:
14
currently the 'raspi' and 'highbank' families. They both use the
8
/home/LiKaige/qemu/target/arm/translate-a64.c:3392:5: error: ‘fn’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
15
common arm_write_secure_board_setup_dummy_smc().
9
fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
10
^
11
/home/LiKaige/qemu/target/arm/translate-a64.c:3318:22: note: ‘fn’ was declared here
12
AtomicThreeOpFn *fn;
13
^
16
14
17
Set the NSACR CP11 and CP10 bits in the code written by that
15
Make it happy by initializing the variable to NULL.
18
function, to allow FPU access in Non-Secure state when using dummy
19
SMC setup routine. Otherwise an AArch32 kernel booted on the
20
highbank or raspi boards will UNDEF as soon as it tries to use the
21
FPU.
22
16
23
Update the comment describing secure_board_setup to note the new
17
Signed-off-by: Kaige Li <likaige@loongson.cn>
24
requirements on users of it.
18
Message-id: 1596110248-7366-2-git-send-email-likaige@loongson.cn
25
26
This fixes a kernel panic when booting raspbian on raspi2.
27
28
Successfully tested with:
29
2017-01-11-raspbian-jessie-lite.img
30
2018-11-13-raspbian-stretch-lite.img
31
2019-07-10-raspbian-buster-lite.img
32
33
Fixes: fc1120a7f5
34
Signed-off-by: Clement Deschamps <clement.deschamps@greensocs.com>
35
Tested-by: Laurent Bonnans <laurent.bonnans@here.com>
36
Message-id: 20191104151137.81931-1-clement.deschamps@greensocs.com
37
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
38
[PMM: updated comment to boot.h to note new requirement on
20
[PMM: Clean up commit message and note which gcc version this was]
39
users of secure_board_setup; edited/rewrote commit message]
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
---
22
---
42
include/hw/arm/boot.h | 7 +++++--
23
target/arm/translate-a64.c | 2 +-
43
hw/arm/boot.c | 3 +++
24
1 file changed, 1 insertion(+), 1 deletion(-)
44
2 files changed, 8 insertions(+), 2 deletions(-)
45
25
46
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
26
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
48
--- a/include/hw/arm/boot.h
28
--- a/target/arm/translate-a64.c
49
+++ b/include/hw/arm/boot.h
29
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info {
30
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
51
void (*write_board_setup)(ARMCPU *cpu,
31
bool r = extract32(insn, 22, 1);
52
const struct arm_boot_info *info);
32
bool a = extract32(insn, 23, 1);
53
33
TCGv_i64 tcg_rs, clean_addr;
54
- /* If set, the board specific loader/setup blob will be run from secure
34
- AtomicThreeOpFn *fn;
55
+ /*
35
+ AtomicThreeOpFn *fn = NULL;
56
+ * If set, the board specific loader/setup blob will be run from secure
36
57
* mode, regardless of secure_boot. The blob becomes responsible for
37
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
58
- * changing to non-secure state if implementing a non-secure boot
38
unallocated_encoding(s);
59
+ * changing to non-secure state if implementing a non-secure boot,
60
+ * including setting up EL3/Secure registers such as the NSACR as
61
+ * required by the Linux booting ABI before the switch to non-secure.
62
*/
63
bool secure_board_setup;
64
65
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/boot.c
68
+++ b/hw/arm/boot.c
69
@@ -XXX,XX +XXX,XX @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
70
};
71
uint32_t board_setup_blob[] = {
72
/* board setup addr */
73
+ 0xee110f51, /* mrc p15, 0, r0, c1, c1, 2 ;read NSACR */
74
+ 0xe3800b03, /* orr r0, #0xc00 ;set CP11, CP10 */
75
+ 0xee010f51, /* mcr p15, 0, r0, c1, c1, 2 ;write NSACR */
76
0xe3a00e00 + (mvbar_addr >> 4), /* mov r0, #mvbar_addr */
77
0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 ;set MVBAR */
78
0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 ;read SCR */
79
--
39
--
80
2.20.1
40
2.20.1
81
41
82
42
diff view generated by jsdifflib
1
Now all the users of ptimers have converted to the transaction-based
1
The nrf51 SoC model wasn't setting the system_clock_scale
2
API, we can remove ptimer_init_with_bh() and all the code paths
2
global.which meant that if guest code used the systick timer in "use
3
that are used only by bottom-half based ptimers, and tidy up the
3
the processor clock" mode it would hang because time never advances.
4
documentation comments to consider the transaction-based API the
5
only possibility.
6
4
7
The code changes result from:
5
Set the global to match the documented CPU clock speed for this SoC.
8
* s->bh no longer exists
6
9
* s->callback is now always non-NULL
7
This SoC in fact doesn't have a SysTick timer (which is the only thing
8
currently that cares about the system_clock_scale), because it's
9
a configurable option in the Cortex-M0. However our Cortex-M0 and
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.
10
12
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20191025142411.17085-1-peter.maydell@linaro.org
15
Message-id: 20200727193458.31250-1-peter.maydell@linaro.org
14
---
16
---
15
include/hw/ptimer.h | 45 +++++++++++-----------
17
hw/arm/nrf51_soc.c | 5 +++++
16
hw/core/ptimer.c | 91 ++++++++-------------------------------------
18
1 file changed, 5 insertions(+)
17
2 files changed, 36 insertions(+), 100 deletions(-)
18
19
19
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
20
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/ptimer.h
22
--- a/hw/arm/nrf51_soc.c
22
+++ b/include/hw/ptimer.h
23
+++ b/hw/arm/nrf51_soc.c
23
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
24
25
25
#include "qemu/timer.h"
26
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
26
27
27
-/* The ptimer API implements a simple periodic countdown timer.
28
+/* HCLK (the main CPU clock) on this SoC is always 16MHz */
28
+/*
29
+#define HCLK_FRQ 16000000
29
+ * The ptimer API implements a simple periodic countdown timer.
30
+
30
* The countdown timer has a value (which can be read and written via
31
static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
31
* ptimer_get_count() and ptimer_set_count()). When it is enabled
32
* using ptimer_run(), the value will count downwards at the frequency
33
* which has been configured using ptimer_set_period() or ptimer_set_freq().
34
- * When it reaches zero it will trigger a QEMU bottom half handler, and
35
+ * When it reaches zero it will trigger a callback function, and
36
* can be set to either reload itself from a specified limit value
37
* and keep counting down, or to stop (as a one-shot timer).
38
*
39
+ * A transaction-based API is used for modifying ptimer state: all calls
40
+ * to functions which modify ptimer state must be between matched calls to
41
+ * ptimer_transaction_begin() and ptimer_transaction_commit().
42
+ * When ptimer_transaction_commit() is called it will evaluate the state
43
+ * of the timer after all the changes in the transaction, and call the
44
+ * callback if necessary. (See the ptimer_init() documentation for the full
45
+ * list of state-modifying functions and detailed semantics of the callback.)
46
+ *
47
* Forgetting to set the period/frequency (or setting it to zero) is a
48
* bug in the QEMU device and will cause warning messages to be printed
49
* to stderr when the guest attempts to enable the timer.
50
@@ -XXX,XX +XXX,XX @@
51
* ptimer_set_count() or ptimer_set_limit() will not trigger the timer
52
* (though it will cause a reload). Only a counter decrement to "0"
53
* will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER;
54
- * ptimer_init_with_bh() will assert() that you don't set both.
55
+ * ptimer_init() will assert() that you don't set both.
56
*/
57
#define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5)
58
59
@@ -XXX,XX +XXX,XX @@
60
typedef struct ptimer_state ptimer_state;
61
typedef void (*ptimer_cb)(void *opaque);
62
63
-/**
64
- * ptimer_init_with_bh - Allocate and return a new ptimer
65
- * @bh: QEMU bottom half which is run on timer expiry
66
- * @policy: PTIMER_POLICY_* bits specifying behaviour
67
- *
68
- * The ptimer returned must be freed using ptimer_free().
69
- * The ptimer takes ownership of @bh and will delete it
70
- * when the ptimer is eventually freed.
71
- */
72
-ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask);
73
-
74
/**
75
* ptimer_init - Allocate and return a new ptimer
76
* @callback: function to call on ptimer expiry
77
@@ -XXX,XX +XXX,XX @@ ptimer_state *ptimer_init(ptimer_cb callback,
78
* ptimer_free - Free a ptimer
79
* @s: timer to free
80
*
81
- * Free a ptimer created using ptimer_init_with_bh() (including
82
- * deleting the bottom half which it is using).
83
+ * Free a ptimer created using ptimer_init().
84
*/
85
void ptimer_free(ptimer_state *s);
86
87
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
88
* may be more appropriate.
89
*
90
* This function will assert if it is called outside a
91
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
92
+ * ptimer_transaction_begin/commit block.
93
*/
94
void ptimer_set_period(ptimer_state *s, int64_t period);
95
96
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period);
97
* precise to fractions of a nanosecond, avoiding rounding errors.
98
*
99
* This function will assert if it is called outside a
100
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
101
+ * ptimer_transaction_begin/commit block.
102
*/
103
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
104
105
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_limit(ptimer_state *s);
106
* reload the counter when their reload register is written to.
107
*
108
* This function will assert if it is called outside a
109
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
110
+ * ptimer_transaction_begin/commit block.
111
*/
112
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
113
114
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_count(ptimer_state *s);
115
* point in the future.
116
*
117
* This function will assert if it is called outside a
118
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
119
+ * ptimer_transaction_begin/commit block.
120
*/
121
void ptimer_set_count(ptimer_state *s, uint64_t count);
122
123
@@ -XXX,XX +XXX,XX @@ void ptimer_set_count(ptimer_state *s, uint64_t count);
124
* @s: ptimer
125
* @oneshot: non-zero if this timer should only count down once
126
*
127
- * Start a ptimer counting down; when it reaches zero the bottom half
128
- * passed to ptimer_init_with_bh() will be invoked.
129
+ * Start a ptimer counting down; when it reaches zero the callback function
130
+ * passed to ptimer_init() will be invoked.
131
* If the @oneshot argument is zero,
132
* the counter value will then be reloaded from the limit and it will
133
* start counting down again. If @oneshot is non-zero, then the counter
134
* will disable itself when it reaches zero.
135
*
136
* This function will assert if it is called outside a
137
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
138
+ * ptimer_transaction_begin/commit block.
139
*/
140
void ptimer_run(ptimer_state *s, int oneshot);
141
142
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot);
143
* restarted.
144
*
145
* This function will assert if it is called outside a
146
- * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer.
147
+ * ptimer_transaction_begin/commit block.
148
*/
149
void ptimer_stop(ptimer_state *s);
150
151
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/core/ptimer.c
154
+++ b/hw/core/ptimer.c
155
@@ -XXX,XX +XXX,XX @@ struct ptimer_state
156
int64_t last_event;
157
int64_t next_event;
158
uint8_t policy_mask;
159
- QEMUBH *bh;
160
QEMUTimer *timer;
161
ptimer_cb callback;
162
void *callback_opaque;
163
@@ -XXX,XX +XXX,XX @@ struct ptimer_state
164
/* Use a bottom-half routine to avoid reentrancy issues. */
165
static void ptimer_trigger(ptimer_state *s)
166
{
32
{
167
- if (s->bh) {
33
qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
168
- replay_bh_schedule_event(s->bh);
34
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
169
- }
35
return;
170
- if (s->callback) {
171
- s->callback(s->callback_opaque);
172
- }
173
+ s->callback(s->callback_opaque);
174
}
175
176
static void ptimer_reload(ptimer_state *s, int delta_adjust)
177
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_count(ptimer_state *s)
178
179
void ptimer_set_count(ptimer_state *s, uint64_t count)
180
{
181
- assert(s->in_transaction || !s->callback);
182
+ assert(s->in_transaction);
183
s->delta = count;
184
if (s->enabled) {
185
- if (!s->callback) {
186
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
187
- ptimer_reload(s, 0);
188
- } else {
189
- s->need_reload = true;
190
- }
191
+ s->need_reload = true;
192
}
36
}
193
}
37
194
38
+ system_clock_scale = NANOSECONDS_PER_SECOND / HCLK_FRQ;
195
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
39
+
196
{
40
object_property_set_link(OBJECT(&s->cpu), "memory", OBJECT(&s->container),
197
bool was_disabled = !s->enabled;
41
&error_abort);
198
42
if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu), errp)) {
199
- assert(s->in_transaction || !s->callback);
200
+ assert(s->in_transaction);
201
202
if (was_disabled && s->period == 0) {
203
if (!qtest_enabled()) {
204
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
205
}
206
s->enabled = oneshot ? 2 : 1;
207
if (was_disabled) {
208
- if (!s->callback) {
209
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
210
- ptimer_reload(s, 0);
211
- } else {
212
- s->need_reload = true;
213
- }
214
+ s->need_reload = true;
215
}
216
}
217
218
@@ -XXX,XX +XXX,XX @@ void ptimer_run(ptimer_state *s, int oneshot)
219
is immediately restarted. */
220
void ptimer_stop(ptimer_state *s)
221
{
222
- assert(s->in_transaction || !s->callback);
223
+ assert(s->in_transaction);
224
225
if (!s->enabled)
226
return;
227
@@ -XXX,XX +XXX,XX @@ void ptimer_stop(ptimer_state *s)
228
s->delta = ptimer_get_count(s);
229
timer_del(s->timer);
230
s->enabled = 0;
231
- if (s->callback) {
232
- s->need_reload = false;
233
- }
234
+ s->need_reload = false;
235
}
236
237
/* Set counter increment interval in nanoseconds. */
238
void ptimer_set_period(ptimer_state *s, int64_t period)
239
{
240
- assert(s->in_transaction || !s->callback);
241
+ assert(s->in_transaction);
242
s->delta = ptimer_get_count(s);
243
s->period = period;
244
s->period_frac = 0;
245
if (s->enabled) {
246
- if (!s->callback) {
247
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
248
- ptimer_reload(s, 0);
249
- } else {
250
- s->need_reload = true;
251
- }
252
+ s->need_reload = true;
253
}
254
}
255
256
/* Set counter frequency in Hz. */
257
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
258
{
259
- assert(s->in_transaction || !s->callback);
260
+ assert(s->in_transaction);
261
s->delta = ptimer_get_count(s);
262
s->period = 1000000000ll / freq;
263
s->period_frac = (1000000000ll << 32) / freq;
264
if (s->enabled) {
265
- if (!s->callback) {
266
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
267
- ptimer_reload(s, 0);
268
- } else {
269
- s->need_reload = true;
270
- }
271
+ s->need_reload = true;
272
}
273
}
274
275
@@ -XXX,XX +XXX,XX @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
276
count = limit. */
277
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
278
{
279
- assert(s->in_transaction || !s->callback);
280
+ assert(s->in_transaction);
281
s->limit = limit;
282
if (reload)
283
s->delta = limit;
284
if (s->enabled && reload) {
285
- if (!s->callback) {
286
- s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
287
- ptimer_reload(s, 0);
288
- } else {
289
- s->need_reload = true;
290
- }
291
+ s->need_reload = true;
292
}
293
}
294
295
@@ -XXX,XX +XXX,XX @@ uint64_t ptimer_get_limit(ptimer_state *s)
296
297
void ptimer_transaction_begin(ptimer_state *s)
298
{
299
- assert(!s->in_transaction || !s->callback);
300
+ assert(!s->in_transaction);
301
s->in_transaction = true;
302
s->need_reload = false;
303
}
304
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_ptimer = {
305
}
306
};
307
308
-ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask)
309
-{
310
- ptimer_state *s;
311
-
312
- s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
313
- s->bh = bh;
314
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
315
- s->policy_mask = policy_mask;
316
-
317
- /*
318
- * These two policies are incompatible -- trigger-on-decrement implies
319
- * a timer trigger when the count becomes 0, but no-immediate-trigger
320
- * implies a trigger when the count stops being 0.
321
- */
322
- assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
323
- (policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)));
324
- return s;
325
-}
326
-
327
ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque,
328
uint8_t policy_mask)
329
{
330
ptimer_state *s;
331
332
- /*
333
- * The callback function is mandatory; so we use it to distinguish
334
- * old-style QEMUBH ptimers from new transaction API ptimers.
335
- * (ptimer_init_with_bh() allows a NULL bh pointer and at least
336
- * one device (digic-timer) passes NULL, so it's not the case
337
- * that either s->bh != NULL or s->callback != NULL.)
338
- */
339
+ /* The callback function is mandatory. */
340
assert(callback);
341
342
s = g_new0(ptimer_state, 1);
343
@@ -XXX,XX +XXX,XX @@ ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque,
344
345
void ptimer_free(ptimer_state *s)
346
{
347
- if (s->bh) {
348
- qemu_bh_delete(s->bh);
349
- }
350
timer_free(s->timer);
351
g_free(s);
352
}
353
--
43
--
354
2.20.1
44
2.20.1
355
45
356
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