1
A surprisingly short target-arm queue, but no point in holding
1
Handful of bugfixes for rc2. None of these are particularly critical
2
onto these waiting for more code to arrive :-)
2
or exciting.
3
3
4
thanks
5
-- PMM
4
-- PMM
6
5
7
The following changes since commit 3d0bf8dfdfebd7f2ae41b6f220444b8047d6b1ee:
6
The following changes since commit 45a150aa2b3492acf6691c7bdbeb25a8545d8345:
8
7
9
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20170710a' into staging (2017-07-10 18:13:03 +0100)
8
Merge remote-tracking branch 'remotes/ericb/tags/pull-bitmaps-2020-08-03' into staging (2020-08-03 15:13:49 +0100)
10
9
11
are available in the git repository at:
10
are available in the Git repository at:
12
11
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170711
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200803
14
13
15
for you to fetch changes up to 792dac309c8660306557ba058b8b5a6a75ab3c1f:
14
for you to fetch changes up to 13557fd392890cbd985bceba7f717e01efd674b8:
16
15
17
target-arm: v7M: ignore writes to CONTROL.SPSEL from Thread mode (2017-07-11 11:21:26 +0100)
16
hw/timer/imx_epit: Avoid assertion when CR.SWR is written (2020-08-03 17:56:11 +0100)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* v7M: ignore writes to CONTROL.SPSEL from Thread mode
20
* hw/timer/imx_epit: Avoid assertion when CR.SWR is written
22
* KVM: Enable in-kernel timers with user space gic
21
* netduino2, netduinoplus2, microbit: set system_clock_scale so that
23
* aspeed: Register all watchdogs
22
SysTick running on the CPU clock works
24
* hw/misc: Add Exynos4210 Pseudo Random Number Generator
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
Alexander Graf (1):
29
Kaige Li (1):
28
ARM: KVM: Enable in-kernel timers with user space gic
30
target/arm: Avoid maybe-uninitialized warning with gcc 4.9
29
31
30
Joel Stanley (1):
32
Peter Maydell (6):
31
aspeed: Register all watchdogs
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
32
39
33
Krzysztof Kozlowski (1):
40
Richard Henderson (1):
34
hw/misc: Add Exynos4210 Pseudo Random Number Generator
41
target/arm: Fix AddPAC error indication
35
42
36
Peter Maydell (1):
43
include/hw/arm/armv7m.h | 4 +++-
37
target-arm: v7M: ignore writes to CONTROL.SPSEL from Thread mode
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
38
58
39
hw/misc/Makefile.objs | 2 +-
40
include/hw/arm/aspeed_soc.h | 4 +-
41
include/sysemu/kvm.h | 11 ++
42
target/arm/cpu.h | 3 +
43
accel/kvm/kvm-all.c | 5 +
44
accel/stubs/kvm-stub.c | 5 +
45
hw/arm/aspeed_soc.c | 25 ++--
46
hw/arm/exynos4210.c | 4 +
47
hw/intc/arm_gic.c | 7 ++
48
hw/misc/exynos4210_rng.c | 277 ++++++++++++++++++++++++++++++++++++++++++++
49
target/arm/helper.c | 13 ++-
50
target/arm/kvm.c | 51 ++++++++
51
12 files changed, 394 insertions(+), 13 deletions(-)
52
create mode 100644 hw/misc/exynos4210_rng.c
53
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
From: Alexander Graf <agraf@suse.de>
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
When running with KVM enabled, you can choose between emulating the
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
gic in kernel or user space. If the kernel supports in-kernel virtualization
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
of the interrupt controller, it will default to that. If not, if will
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
default to user space emulation.
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(-)
7
15
8
Unfortunately when running in user mode gic emulation, we miss out on
16
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
9
interrupt events which are only available from kernel space, such as the timer.
10
This patch leverages the new kernel/user space pending line synchronization for
11
timer events. It does not handle PMU events yet.
12
13
Signed-off-by: Alexander Graf <agraf@suse.de>
14
Reviewed-by: Andrew Jones <drjones@redhat.com>
15
Message-id: 1498577737-130264-1-git-send-email-agraf@suse.de
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/sysemu/kvm.h | 11 +++++++++++
19
target/arm/cpu.h | 3 +++
20
accel/kvm/kvm-all.c | 5 +++++
21
accel/stubs/kvm-stub.c | 5 +++++
22
hw/intc/arm_gic.c | 7 +++++++
23
target/arm/kvm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
24
6 files changed, 82 insertions(+)
25
26
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/include/sysemu/kvm.h
18
--- a/hw/arm/msf2-soc.c
29
+++ b/include/sysemu/kvm.h
19
+++ b/hw/arm/msf2-soc.c
30
@@ -XXX,XX +XXX,XX @@ int kvm_init_vcpu(CPUState *cpu);
20
@@ -XXX,XX +XXX,XX @@
31
int kvm_cpu_exec(CPUState *cpu);
21
#include "hw/irq.h"
32
int kvm_destroy_vcpu(CPUState *cpu);
22
#include "hw/arm/msf2-soc.h"
33
23
#include "hw/misc/unimp.h"
34
+/**
24
-#include "sysemu/runstate.h"
35
+ * kvm_arm_supports_user_irq
25
#include "sysemu/sysemu.h"
36
+ *
26
37
+ * Not all KVM implementations support notifications for kernel generated
27
#define MSF2_TIMER_BASE 0x40004000
38
+ * interrupt events to user space. This function indicates whether the current
28
@@ -XXX,XX +XXX,XX @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
39
+ * KVM implementation does support them.
29
static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
40
+ *
30
static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
41
+ * Returns: true if KVM supports using kernel generated IRQs from user space
31
42
+ */
32
-static void do_sys_reset(void *opaque, int n, int level)
43
+bool kvm_arm_supports_user_irq(void);
33
-{
44
+
34
- if (level) {
45
#ifdef NEED_CPU_H
35
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
46
#include "cpu.h"
36
- }
47
37
-}
48
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
-
49
index XXXXXXX..XXXXXXX 100644
39
static void m2sxxx_soc_initfn(Object *obj)
50
--- a/target/arm/cpu.h
51
+++ b/target/arm/cpu.h
52
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
53
void *el_change_hook_opaque;
54
55
int32_t node_id; /* NUMA node this CPU belongs to */
56
+
57
+ /* Used to synchronize KVM and QEMU in-kernel device levels */
58
+ uint8_t device_irq_level;
59
};
60
61
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
62
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/accel/kvm/kvm-all.c
65
+++ b/accel/kvm/kvm-all.c
66
@@ -XXX,XX +XXX,XX @@ int kvm_has_intx_set_mask(void)
67
return kvm_state->intx_set_mask;
68
}
69
70
+bool kvm_arm_supports_user_irq(void)
71
+{
72
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_USER_IRQ);
73
+}
74
+
75
#ifdef KVM_CAP_SET_GUEST_DEBUG
76
struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
77
target_ulong pc)
78
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/stubs/kvm-stub.c
81
+++ b/accel/stubs/kvm-stub.c
82
@@ -XXX,XX +XXX,XX @@ void kvm_init_cpu_signals(CPUState *cpu)
83
{
40
{
84
abort();
41
MSF2State *s = MSF2_SOC(obj);
85
}
42
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
86
+
87
+bool kvm_arm_supports_user_irq(void)
88
+{
89
+ return false;
90
+}
91
#endif
92
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/intc/arm_gic.c
95
+++ b/hw/intc/arm_gic.c
96
@@ -XXX,XX +XXX,XX @@
97
#include "qom/cpu.h"
98
#include "qemu/log.h"
99
#include "trace.h"
100
+#include "sysemu/kvm.h"
101
102
/* #define DEBUG_GIC */
103
104
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
105
return;
43
return;
106
}
44
}
107
45
108
+ if (kvm_enabled() && !kvm_arm_supports_user_irq()) {
46
- qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0,
109
+ error_setg(errp, "KVM with user space irqchip only works when the "
47
- qemu_allocate_irq(&do_sys_reset, NULL, 0));
110
+ "host kernel supports KVM_CAP_ARM_USER_IRQ");
48
-
111
+ return;
49
system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk;
112
+ }
50
113
+
51
for (i = 0; i < MSF2_NUM_UARTS; i++) {
114
/* This creates distributor and main CPU interface (s->cpuiomem[0]) */
52
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
115
gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops);
116
117
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
118
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/kvm.c
54
--- a/hw/arm/stellaris.c
120
+++ b/target/arm/kvm.c
55
+++ b/hw/arm/stellaris.c
121
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
56
@@ -XXX,XX +XXX,XX @@
122
*/
57
#include "hw/boards.h"
123
kvm_async_interrupts_allowed = true;
58
#include "qemu/log.h"
124
59
#include "exec/address-spaces.h"
125
+ /*
60
-#include "sysemu/runstate.h"
126
+ * PSCI wakes up secondary cores, so we always need to
61
#include "sysemu/sysemu.h"
127
+ * have vCPUs waiting in kernel space
62
#include "hw/arm/armv7m.h"
128
+ */
63
#include "hw/char/pl011.h"
129
+ kvm_halt_in_kernel_allowed = true;
64
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
130
+
65
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
131
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
132
133
type_register_static(&host_arm_cpu_type_info);
134
@@ -XXX,XX +XXX,XX @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
135
136
MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
137
{
138
+ ARMCPU *cpu;
139
+ uint32_t switched_level;
140
+
141
+ if (kvm_irqchip_in_kernel()) {
142
+ /*
143
+ * We only need to sync timer states with user-space interrupt
144
+ * controllers, so return early and save cycles if we don't.
145
+ */
146
+ return MEMTXATTRS_UNSPECIFIED;
147
+ }
148
+
149
+ cpu = ARM_CPU(cs);
150
+
151
+ /* Synchronize our shadowed in-kernel device irq lines with the kvm ones */
152
+ if (run->s.regs.device_irq_level != cpu->device_irq_level) {
153
+ switched_level = cpu->device_irq_level ^ run->s.regs.device_irq_level;
154
+
155
+ qemu_mutex_lock_iothread();
156
+
157
+ if (switched_level & KVM_ARM_DEV_EL1_VTIMER) {
158
+ qemu_set_irq(cpu->gt_timer_outputs[GTIMER_VIRT],
159
+ !!(run->s.regs.device_irq_level &
160
+ KVM_ARM_DEV_EL1_VTIMER));
161
+ switched_level &= ~KVM_ARM_DEV_EL1_VTIMER;
162
+ }
163
+
164
+ if (switched_level & KVM_ARM_DEV_EL1_PTIMER) {
165
+ qemu_set_irq(cpu->gt_timer_outputs[GTIMER_PHYS],
166
+ !!(run->s.regs.device_irq_level &
167
+ KVM_ARM_DEV_EL1_PTIMER));
168
+ switched_level &= ~KVM_ARM_DEV_EL1_PTIMER;
169
+ }
170
+
171
+ /* XXX PMU IRQ is missing */
172
+
173
+ if (switched_level) {
174
+ qemu_log_mask(LOG_UNIMP, "%s: unhandled in-kernel device IRQ %x\n",
175
+ __func__, switched_level);
176
+ }
177
+
178
+ /* We also mark unknown levels as processed to not waste cycles */
179
+ cpu->device_irq_level = run->s.regs.device_irq_level;
180
+ qemu_mutex_unlock_iothread();
181
+ }
182
+
183
return MEMTXATTRS_UNSPECIFIED;
184
}
66
}
185
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
-}
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),
186
--
89
--
187
2.7.4
90
2.20.1
188
91
189
92
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add emulation for Exynos4210 Pseudo Random Number Generator which could
3
The definition of top_bit used in this function is one higher
4
work on fixed seeds or with seeds provided by True Random Number
4
than that used in the Arm ARM psuedo-code, which put the error
5
Generator block inside the SoC.
5
indication at top_bit - 1 at the wrong place, which meant that
6
it wasn't visible to Auth.
6
7
7
Implement only the fixed seeds part of it in polling mode (no
8
Fixing the definition of top_bit requires more changes, because
8
interrupts).
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.
9
11
10
Emulation tested with two independent Linux kernel exynos-rng drivers:
12
For now, prefer the minimal fix to the error indication alone.
11
1. New kcapi-rng interface (targeting Linux v4.12),
12
2. Old hwrng inteface
13
# echo "exynos" > /sys/class/misc/hw_random/rng_current
14
# dd if=/dev/hwrng of=/dev/null bs=1 count=16
15
13
16
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
14
Fixes: 63ff0ca94cb
17
Message-id: 20170425180609.11004-1-krzk@kernel.org
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>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: wrapped a few overlong lines; more efficient implementation
19
[PMM: added comment about the divergence from the pseudocode]
20
of exynos4210_rng_seed_ready()]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
21
---
23
hw/misc/Makefile.objs | 2 +-
22
target/arm/pauth_helper.c | 6 +++++-
24
hw/arm/exynos4210.c | 4 +
23
tests/tcg/aarch64/pauth-5.c | 33 +++++++++++++++++++++++++++++++
25
hw/misc/exynos4210_rng.c | 277 +++++++++++++++++++++++++++++++++++++++++++++++
24
tests/tcg/aarch64/Makefile.target | 2 +-
26
3 files changed, 282 insertions(+), 1 deletion(-)
25
3 files changed, 39 insertions(+), 2 deletions(-)
27
create mode 100644 hw/misc/exynos4210_rng.c
26
create mode 100644 tests/tcg/aarch64/pauth-5.c
28
27
29
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
28
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
30
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/misc/Makefile.objs
30
--- a/target/arm/pauth_helper.c
32
+++ b/hw/misc/Makefile.objs
31
+++ b/target/arm/pauth_helper.c
33
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
32
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
34
obj-$(CONFIG_REALVIEW) += arm_sysctl.o
33
*/
35
obj-$(CONFIG_NSERIES) += cbus.o
34
test = sextract64(ptr, bot_bit, top_bit - bot_bit);
36
obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
35
if (test != 0 && test != -1) {
37
-obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o
36
- pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
38
+obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o exynos4210_rng.o
37
+ /*
39
obj-$(CONFIG_IMX) += imx_ccm.o
38
+ * Note that our top_bit is one greater than the pseudocode's
40
obj-$(CONFIG_IMX) += imx31_ccm.o
39
+ * version, hence "- 2" here.
41
obj-$(CONFIG_IMX) += imx25_ccm.o
40
+ */
42
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
41
+ pac ^= MAKE_64BIT_MASK(top_bit - 2, 1);
43
index XXXXXXX..XXXXXXX 100644
42
}
44
--- a/hw/arm/exynos4210.c
43
45
+++ b/hw/arm/exynos4210.c
44
/*
46
@@ -XXX,XX +XXX,XX @@
45
diff --git a/tests/tcg/aarch64/pauth-5.c b/tests/tcg/aarch64/pauth-5.c
47
/* Clock controller SFR base address */
48
#define EXYNOS4210_CLK_BASE_ADDR 0x10030000
49
50
+/* PRNG/HASH SFR base address */
51
+#define EXYNOS4210_RNG_BASE_ADDR 0x10830400
52
+
53
/* Display controllers (FIMD) */
54
#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
55
56
@@ -XXX,XX +XXX,XX @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
57
sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
58
59
sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
60
+ sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);
61
62
/* PWM */
63
sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
64
diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c
65
new file mode 100644
46
new file mode 100644
66
index XXXXXXX..XXXXXXX
47
index XXXXXXX..XXXXXXX
67
--- /dev/null
48
--- /dev/null
68
+++ b/hw/misc/exynos4210_rng.c
49
+++ b/tests/tcg/aarch64/pauth-5.c
69
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
70
+/*
51
+#include <assert.h>
71
+ * Exynos4210 Pseudo Random Nubmer Generator Emulation
72
+ *
73
+ * Copyright (c) 2017 Krzysztof Kozlowski <krzk@kernel.org>
74
+ *
75
+ * This program is free software; you can redistribute it and/or modify it
76
+ * under the terms of the GNU General Public License as published by the
77
+ * Free Software Foundation; either version 2 of the License, or
78
+ * (at your option) any later version.
79
+ *
80
+ * This program is distributed in the hope that it will be useful, but WITHOUT
81
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
82
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
83
+ * for more details.
84
+ *
85
+ * You should have received a copy of the GNU General Public License along
86
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
87
+ */
88
+
52
+
89
+#include "qemu/osdep.h"
53
+static int x;
90
+#include "crypto/random.h"
91
+#include "hw/sysbus.h"
92
+#include "qemu/log.h"
93
+
54
+
94
+#define DEBUG_EXYNOS_RNG 0
55
+int main()
56
+{
57
+ int *p0 = &x, *p1, *p2, *p3;
58
+ unsigned long salt = 0;
95
+
59
+
96
+#define DPRINTF(fmt, ...) \
60
+ /*
97
+ do { \
61
+ * With TBI enabled and a 48-bit VA, there are 7 bits of auth, and so
98
+ if (DEBUG_EXYNOS_RNG) { \
62
+ * a 1/128 chance of auth = pac(ptr,key,salt) producing zero.
99
+ printf("exynos4210_rng: " fmt, ## __VA_ARGS__); \
63
+ * Find a salt that creates auth != 0.
100
+ } \
64
+ */
101
+ } while (0)
65
+ do {
66
+ salt++;
67
+ asm("pacda %0, %1" : "=r"(p1) : "r"(salt), "0"(p0));
68
+ } while (p0 == p1);
102
+
69
+
103
+#define TYPE_EXYNOS4210_RNG "exynos4210.rng"
70
+ /*
104
+#define EXYNOS4210_RNG(obj) \
71
+ * This pac must fail, because the input pointer bears an encryption,
105
+ OBJECT_CHECK(Exynos4210RngState, (obj), TYPE_EXYNOS4210_RNG)
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));
106
+
76
+
107
+/*
77
+ /* ... so that the aut must fail, setting bit 53 in the output ... */
108
+ * Exynos4220, PRNG, only polling mode is supported.
78
+ asm("autda %0, %1" : "=r"(p3) : "r"(salt), "0"(p2));
109
+ */
110
+
79
+
111
+/* RNG_CONTROL_1 register bitfields, reset value: 0x0 */
80
+ /* ... which means this equality must not hold. */
112
+#define EXYNOS4210_RNG_CONTROL_1_PRNG 0x8
81
+ assert(p3 != p0);
113
+#define EXYNOS4210_RNG_CONTROL_1_START_INIT BIT(4)
82
+ return 0;
114
+/* RNG_STATUS register bitfields, reset value: 0x1 */
115
+#define EXYNOS4210_RNG_STATUS_PRNG_ERROR BIT(7)
116
+#define EXYNOS4210_RNG_STATUS_PRNG_DONE BIT(5)
117
+#define EXYNOS4210_RNG_STATUS_MSG_DONE BIT(4)
118
+#define EXYNOS4210_RNG_STATUS_PARTIAL_DONE BIT(3)
119
+#define EXYNOS4210_RNG_STATUS_PRNG_BUSY BIT(2)
120
+#define EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE BIT(1)
121
+#define EXYNOS4210_RNG_STATUS_BUFFER_READY BIT(0)
122
+#define EXYNOS4210_RNG_STATUS_WRITE_MASK (EXYNOS4210_RNG_STATUS_PRNG_DONE \
123
+ | EXYNOS4210_RNG_STATUS_MSG_DONE \
124
+ | EXYNOS4210_RNG_STATUS_PARTIAL_DONE)
125
+
126
+#define EXYNOS4210_RNG_CONTROL_1 0x0
127
+#define EXYNOS4210_RNG_STATUS 0x10
128
+#define EXYNOS4210_RNG_SEED_IN 0x140
129
+#define EXYNOS4210_RNG_SEED_IN_OFFSET(n) (EXYNOS4210_RNG_SEED_IN + (n * 0x4))
130
+#define EXYNOS4210_RNG_PRNG 0x160
131
+#define EXYNOS4210_RNG_PRNG_OFFSET(n) (EXYNOS4210_RNG_PRNG + (n * 0x4))
132
+
133
+#define EXYNOS4210_RNG_PRNG_NUM 5
134
+
135
+#define EXYNOS4210_RNG_REGS_MEM_SIZE 0x200
136
+
137
+typedef struct Exynos4210RngState {
138
+ SysBusDevice parent_obj;
139
+ MemoryRegion iomem;
140
+
141
+ int32_t randr_value[EXYNOS4210_RNG_PRNG_NUM];
142
+ /* bits from 0 to EXYNOS4210_RNG_PRNG_NUM if given seed register was set */
143
+ uint32_t seed_set;
144
+
145
+ /* Register values */
146
+ uint32_t reg_control;
147
+ uint32_t reg_status;
148
+} Exynos4210RngState;
149
+
150
+static bool exynos4210_rng_seed_ready(const Exynos4210RngState *s)
151
+{
152
+ uint32_t mask = MAKE_64BIT_MASK(0, EXYNOS4210_RNG_PRNG_NUM);
153
+
154
+ /* Return true if all the seed-set bits are set. */
155
+ return (s->seed_set & mask) == mask;
156
+}
83
+}
157
+
84
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
158
+static void exynos4210_rng_set_seed(Exynos4210RngState *s, unsigned int i,
85
index XXXXXXX..XXXXXXX 100644
159
+ uint64_t val)
86
--- a/tests/tcg/aarch64/Makefile.target
160
+{
87
+++ b/tests/tcg/aarch64/Makefile.target
161
+ /*
88
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
162
+ * We actually ignore the seed and always generate true random numbers.
89
163
+ * Theoretically this should not match the device as Exynos has
90
# Pauth Tests
164
+ * a Pseudo Random Number Generator but testing shown that it always
91
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_3),)
165
+ * generates random numbers regardless of the seed value.
92
-AARCH64_TESTS += pauth-1 pauth-2 pauth-4
166
+ */
93
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
167
+ s->seed_set |= BIT(i);
94
pauth-%: CFLAGS += -march=armv8.3-a
168
+
95
run-pauth-%: QEMU_OPTS += -cpu max
169
+ /* If all seeds were written, update the status to reflect it */
96
run-plugin-pauth-%: QEMU_OPTS += -cpu max
170
+ if (exynos4210_rng_seed_ready(s)) {
171
+ s->reg_status |= EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE;
172
+ } else {
173
+ s->reg_status &= ~EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE;
174
+ }
175
+}
176
+
177
+static void exynos4210_rng_run_engine(Exynos4210RngState *s)
178
+{
179
+ Error *err = NULL;
180
+ int ret;
181
+
182
+ /* Seed set? */
183
+ if ((s->reg_status & EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE) == 0) {
184
+ goto out;
185
+ }
186
+
187
+ /* PRNG engine chosen? */
188
+ if ((s->reg_control & EXYNOS4210_RNG_CONTROL_1_PRNG) == 0) {
189
+ goto out;
190
+ }
191
+
192
+ /* PRNG engine started? */
193
+ if ((s->reg_control & EXYNOS4210_RNG_CONTROL_1_START_INIT) == 0) {
194
+ goto out;
195
+ }
196
+
197
+ /* Get randoms */
198
+ ret = qcrypto_random_bytes((uint8_t *)s->randr_value,
199
+ sizeof(s->randr_value), &err);
200
+ if (!ret) {
201
+ /* Notify that PRNG is ready */
202
+ s->reg_status |= EXYNOS4210_RNG_STATUS_PRNG_DONE;
203
+ } else {
204
+ error_report_err(err);
205
+ }
206
+
207
+out:
208
+ /* Always clear start engine bit */
209
+ s->reg_control &= ~EXYNOS4210_RNG_CONTROL_1_START_INIT;
210
+}
211
+
212
+static uint64_t exynos4210_rng_read(void *opaque, hwaddr offset,
213
+ unsigned size)
214
+{
215
+ Exynos4210RngState *s = (Exynos4210RngState *)opaque;
216
+ uint32_t val = 0;
217
+
218
+ assert(size == 4);
219
+
220
+ switch (offset) {
221
+ case EXYNOS4210_RNG_CONTROL_1:
222
+ val = s->reg_control;
223
+ break;
224
+
225
+ case EXYNOS4210_RNG_STATUS:
226
+ val = s->reg_status;
227
+ break;
228
+
229
+ case EXYNOS4210_RNG_PRNG_OFFSET(0):
230
+ case EXYNOS4210_RNG_PRNG_OFFSET(1):
231
+ case EXYNOS4210_RNG_PRNG_OFFSET(2):
232
+ case EXYNOS4210_RNG_PRNG_OFFSET(3):
233
+ case EXYNOS4210_RNG_PRNG_OFFSET(4):
234
+ val = s->randr_value[(offset - EXYNOS4210_RNG_PRNG_OFFSET(0)) / 4];
235
+ DPRINTF("returning random @0x%" HWADDR_PRIx ": 0x%" PRIx32 "\n",
236
+ offset, val);
237
+ break;
238
+
239
+ default:
240
+ qemu_log_mask(LOG_GUEST_ERROR,
241
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
242
+ __func__, offset);
243
+ }
244
+
245
+ return val;
246
+}
247
+
248
+static void exynos4210_rng_write(void *opaque, hwaddr offset,
249
+ uint64_t val, unsigned size)
250
+{
251
+ Exynos4210RngState *s = (Exynos4210RngState *)opaque;
252
+
253
+ assert(size == 4);
254
+
255
+ switch (offset) {
256
+ case EXYNOS4210_RNG_CONTROL_1:
257
+ DPRINTF("RNG_CONTROL_1 = 0x%" PRIx64 "\n", val);
258
+ s->reg_control = val;
259
+ exynos4210_rng_run_engine(s);
260
+ break;
261
+
262
+ case EXYNOS4210_RNG_STATUS:
263
+ /* For clearing status fields */
264
+ s->reg_status &= ~EXYNOS4210_RNG_STATUS_WRITE_MASK;
265
+ s->reg_status |= val & EXYNOS4210_RNG_STATUS_WRITE_MASK;
266
+ break;
267
+
268
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(0):
269
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(1):
270
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(2):
271
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(3):
272
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(4):
273
+ exynos4210_rng_set_seed(s,
274
+ (offset - EXYNOS4210_RNG_SEED_IN_OFFSET(0)) / 4,
275
+ val);
276
+ break;
277
+
278
+ default:
279
+ qemu_log_mask(LOG_GUEST_ERROR,
280
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
281
+ __func__, offset);
282
+ }
283
+}
284
+
285
+static const MemoryRegionOps exynos4210_rng_ops = {
286
+ .read = exynos4210_rng_read,
287
+ .write = exynos4210_rng_write,
288
+ .endianness = DEVICE_NATIVE_ENDIAN,
289
+};
290
+
291
+static void exynos4210_rng_reset(DeviceState *dev)
292
+{
293
+ Exynos4210RngState *s = EXYNOS4210_RNG(dev);
294
+
295
+ s->reg_control = 0;
296
+ s->reg_status = EXYNOS4210_RNG_STATUS_BUFFER_READY;
297
+ memset(s->randr_value, 0, sizeof(s->randr_value));
298
+ s->seed_set = 0;
299
+}
300
+
301
+static void exynos4210_rng_init(Object *obj)
302
+{
303
+ Exynos4210RngState *s = EXYNOS4210_RNG(obj);
304
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
305
+
306
+ memory_region_init_io(&s->iomem, obj, &exynos4210_rng_ops, s,
307
+ TYPE_EXYNOS4210_RNG, EXYNOS4210_RNG_REGS_MEM_SIZE);
308
+ sysbus_init_mmio(dev, &s->iomem);
309
+}
310
+
311
+static const VMStateDescription exynos4210_rng_vmstate = {
312
+ .name = TYPE_EXYNOS4210_RNG,
313
+ .version_id = 1,
314
+ .minimum_version_id = 1,
315
+ .fields = (VMStateField[]) {
316
+ VMSTATE_INT32_ARRAY(randr_value, Exynos4210RngState,
317
+ EXYNOS4210_RNG_PRNG_NUM),
318
+ VMSTATE_UINT32(seed_set, Exynos4210RngState),
319
+ VMSTATE_UINT32(reg_status, Exynos4210RngState),
320
+ VMSTATE_UINT32(reg_control, Exynos4210RngState),
321
+ VMSTATE_END_OF_LIST()
322
+ }
323
+};
324
+
325
+static void exynos4210_rng_class_init(ObjectClass *klass, void *data)
326
+{
327
+ DeviceClass *dc = DEVICE_CLASS(klass);
328
+
329
+ dc->reset = exynos4210_rng_reset;
330
+ dc->vmsd = &exynos4210_rng_vmstate;
331
+}
332
+
333
+static const TypeInfo exynos4210_rng_info = {
334
+ .name = TYPE_EXYNOS4210_RNG,
335
+ .parent = TYPE_SYS_BUS_DEVICE,
336
+ .instance_size = sizeof(Exynos4210RngState),
337
+ .instance_init = exynos4210_rng_init,
338
+ .class_init = exynos4210_rng_class_init,
339
+};
340
+
341
+static void exynos4210_rng_register(void)
342
+{
343
+ type_register_static(&exynos4210_rng_info);
344
+}
345
+
346
+type_init(exynos4210_rng_register)
347
--
97
--
348
2.7.4
98
2.20.1
349
99
350
100
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Kaige Li <likaige@loongson.cn>
2
2
3
The ast2400 contains two and the ast2500 contains three watchdogs.
3
GCC version 4.9.4 isn't clever enough to figure out that all
4
Add this information to the AspeedSoCInfo and realise the correct number
4
execution paths in disas_ldst() that use 'fn' will have initialized
5
of watchdogs for that each SoC type.
5
it first, and so it warns:
6
6
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
/home/LiKaige/qemu/target/arm/translate-a64.c: In function ‘disas_ldst’:
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
/home/LiKaige/qemu/target/arm/translate-a64.c:3392:5: error: ‘fn’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
9
Tested-by: Cédric Le Goater <clg@kaod.org>
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
^
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
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
[PMM: Clean up commit message and note which gcc version this was]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
include/hw/arm/aspeed_soc.h | 4 +++-
23
target/arm/translate-a64.c | 2 +-
13
hw/arm/aspeed_soc.c | 25 +++++++++++++++++--------
24
1 file changed, 1 insertion(+), 1 deletion(-)
14
2 files changed, 20 insertions(+), 9 deletions(-)
15
25
16
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
26
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed_soc.h
28
--- a/target/arm/translate-a64.c
19
+++ b/include/hw/arm/aspeed_soc.h
29
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
21
#include "hw/net/ftgmac100.h"
31
bool r = extract32(insn, 22, 1);
22
32
bool a = extract32(insn, 23, 1);
23
#define ASPEED_SPIS_NUM 2
33
TCGv_i64 tcg_rs, clean_addr;
24
+#define ASPEED_WDTS_NUM 3
34
- AtomicThreeOpFn *fn;
25
35
+ AtomicThreeOpFn *fn = NULL;
26
typedef struct AspeedSoCState {
36
27
/*< private >*/
37
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
28
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
38
unallocated_encoding(s);
29
AspeedSMCState fmc;
30
AspeedSMCState spi[ASPEED_SPIS_NUM];
31
AspeedSDMCState sdmc;
32
- AspeedWDTState wdt;
33
+ AspeedWDTState wdt[ASPEED_WDTS_NUM];
34
FTGMAC100State ftgmac100;
35
} AspeedSoCState;
36
37
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
38
const hwaddr *spi_bases;
39
const char *fmc_typename;
40
const char **spi_typename;
41
+ int wdts_num;
42
} AspeedSoCInfo;
43
44
typedef struct AspeedSoCClass {
45
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/aspeed_soc.c
48
+++ b/hw/arm/aspeed_soc.c
49
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
50
.spi_bases = aspeed_soc_ast2400_spi_bases,
51
.fmc_typename = "aspeed.smc.fmc",
52
.spi_typename = aspeed_soc_ast2400_typenames,
53
+ .wdts_num = 2,
54
}, {
55
.name = "ast2400-a1",
56
.cpu_model = "arm926",
57
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
58
.spi_bases = aspeed_soc_ast2400_spi_bases,
59
.fmc_typename = "aspeed.smc.fmc",
60
.spi_typename = aspeed_soc_ast2400_typenames,
61
+ .wdts_num = 2,
62
}, {
63
.name = "ast2400",
64
.cpu_model = "arm926",
65
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
66
.spi_bases = aspeed_soc_ast2400_spi_bases,
67
.fmc_typename = "aspeed.smc.fmc",
68
.spi_typename = aspeed_soc_ast2400_typenames,
69
+ .wdts_num = 2,
70
}, {
71
.name = "ast2500-a1",
72
.cpu_model = "arm1176",
73
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
74
.spi_bases = aspeed_soc_ast2500_spi_bases,
75
.fmc_typename = "aspeed.smc.ast2500-fmc",
76
.spi_typename = aspeed_soc_ast2500_typenames,
77
+ .wdts_num = 3,
78
},
79
};
80
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
82
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
83
"ram-size", &error_abort);
84
85
- object_initialize(&s->wdt, sizeof(s->wdt), TYPE_ASPEED_WDT);
86
- object_property_add_child(obj, "wdt", OBJECT(&s->wdt), NULL);
87
- qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
88
+ for (i = 0; i < sc->info->wdts_num; i++) {
89
+ object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
90
+ object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL);
91
+ qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default());
92
+ }
93
94
object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100);
95
object_property_add_child(obj, "ftgmac100", OBJECT(&s->ftgmac100), NULL);
96
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
97
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
98
99
/* Watch dog */
100
- object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err);
101
- if (err) {
102
- error_propagate(errp, err);
103
- return;
104
+ for (i = 0; i < sc->info->wdts_num; i++) {
105
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
106
+ if (err) {
107
+ error_propagate(errp, err);
108
+ return;
109
+ }
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
111
+ ASPEED_SOC_WDT_BASE + i * 0x20);
112
}
113
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, ASPEED_SOC_WDT_BASE);
114
115
/* Net */
116
qdev_set_nic_properties(DEVICE(&s->ftgmac100), &nd_table[0]);
117
--
39
--
118
2.7.4
40
2.20.1
119
41
120
42
diff view generated by jsdifflib
New patch
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.
1
4
5
Set the global to match the documented CPU clock speed for this SoC.
6
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.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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(+)
19
20
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/nrf51_soc.c
23
+++ b/hw/arm/nrf51_soc.c
24
@@ -XXX,XX +XXX,XX @@
25
26
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
27
28
+/* HCLK (the main CPU clock) on this SoC is always 16MHz */
29
+#define HCLK_FRQ 16000000
30
+
31
static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
32
{
33
qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
34
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
35
return;
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)) {
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
1
For v7M, writes to the CONTROL register are only permitted for
1
The imx_epit device has a software-controllable reset triggered by
2
privileged code. However even if the code is privileged, the
2
setting the SWR bit in the CR register. An error in commit cc2722ec83ad9
3
write must not affect the SPSEL bit in the CONTROL register
3
means that we will end up assert()ing if the guest does this, because
4
if the CPU is in Thread mode (as documented in the pseudocode
4
the code in imx_epit_write() starts ptimer transactions, and then
5
for the MSR instruction). Implement this, instead of permitting
5
imx_epit_reset() also starts ptimer transactions, triggering
6
SPSEL to be written in all cases.
6
"ptimer_transaction_begin: Assertion `!s->in_transaction' failed".
7
7
8
This was causing mbed applications not to run, because the
8
The cleanest way to avoid this double-transaction is to move the
9
RTX RTOS they use relies on this behaviour.
9
start-transaction for the CR write handling down below the check of
10
the SWR bit.
10
11
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1880424
13
Fixes: cc2722ec83ad944505fe
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 1498820791-8130-1-git-send-email-peter.maydell@linaro.org
16
Message-id: 20200727154550.3409-1-peter.maydell@linaro.org
14
---
17
---
15
target/arm/helper.c | 13 ++++++++++---
18
hw/timer/imx_epit.c | 13 ++++++++++---
16
1 file changed, 10 insertions(+), 3 deletions(-)
19
1 file changed, 10 insertions(+), 3 deletions(-)
17
20
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
23
--- a/hw/timer/imx_epit.c
21
+++ b/target/arm/helper.c
24
+++ b/hw/timer/imx_epit.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
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);
23
}
49
}
24
break;
50
25
case 20: /* CONTROL */
26
- switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
27
- env->v7m.control = val & (R_V7M_CONTROL_SPSEL_MASK |
28
- R_V7M_CONTROL_NPRIV_MASK);
29
+ /* Writing to the SPSEL bit only has an effect if we are in
30
+ * thread mode; other bits can be updated by any privileged code.
31
+ * switch_v7m_sp() deals with updating the SPSEL bit in
32
+ * env->v7m.control, so we only need update the others.
33
+ */
34
+ if (env->v7m.exception == 0) {
35
+ switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
36
+ }
37
+ env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
38
+ env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK;
39
break;
40
default:
41
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
42
--
51
--
43
2.7.4
52
2.20.1
44
53
45
54
diff view generated by jsdifflib