1
Another lump of target-arm patches. I still have some patches in
1
The following changes since commit 7e7eb9f852a46b51a71ae9d82590b2e4d28827ee:
2
my to-review queue, but this is a big enough set that I wanted
3
to send it out.
4
2
5
thanks
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-01-28' into staging (2021-01-28 22:43:18 +0000)
6
-- PMM
7
8
The following changes since commit 04bb7fe2bf55bdf66d5b7a5a719b40bbb4048178:
9
10
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180208' into staging (2018-02-08 17:41:15 +0000)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180209
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210129
15
8
16
for you to fetch changes up to bbba7757bacc9f890a3f028d328b4b429dbe78ec:
9
for you to fetch changes up to 11749122e1a86866591306d43603d2795a3dea1a:
17
10
18
hw/core/generic-loader: Allow PC to be set on command line (2018-02-09 10:55:40 +0000)
11
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS (2021-01-29 10:47:29 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* Support M profile derived exceptions on exception entry and exit
15
* Implement ID_PFR2
23
* Implement AArch64 v8.2 crypto insns (SHA-512, SHA-3, SM3, SM4)
16
* Conditionalize DBGDIDR
24
* Implement working i.MX6 SD controller
17
* rename xlnx-zcu102.canbusN properties
25
* Various devices preparatory to i.MX7 support
18
* provide powerdown/reset mechanism for secure firmware on 'virt' board
26
* Preparatory patches for SVE emulation
19
* hw/misc: Fix arith overflow in NPCM7XX PWM module
27
* v8M: Fix bug in implementation of 'TT' insn
20
* target/arm: Replace magic value by MMU_DATA_LOAD definition
28
* Give useful error if user tries to use userspace GICv3 with KVM
21
* configure: fix preadv errors on Catalina macOS with new XCode
22
* Various configure and other cleanups in preparation for iOS support
23
* hvf: Add hypervisor entitlement to output binaries (needed for Big Sur)
24
* Implement pvpanic-pci device
25
* Convert the CMSDK timer devices to the Clock framework
29
26
30
----------------------------------------------------------------
27
----------------------------------------------------------------
31
Andrey Smirnov (10):
28
Alexander Graf (1):
32
sdhci: Add i.MX specific subtype of SDHCI
29
hvf: Add hypervisor entitlement to output binaries
33
hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC
34
i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks
35
i.MX: Add code to emulate i.MX2 watchdog IP block
36
i.MX: Add code to emulate i.MX7 SNVS IP-block
37
i.MX: Add code to emulate GPCv2 IP block
38
i.MX: Add i.MX7 GPT variant
39
i.MX: Add implementation of i.MX7 GPR IP block
40
usb: Add basic code to emulate Chipidea USB IP
41
hw/arm: Move virt's PSCI DT fixup code to arm/boot.c
42
30
43
Ard Biesheuvel (5):
31
Hao Wu (1):
44
target/arm: implement SHA-512 instructions
32
hw/misc: Fix arith overflow in NPCM7XX PWM module
45
target/arm: implement SHA-3 instructions
46
target/arm: implement SM3 instructions
47
target/arm: implement SM4 instructions
48
target/arm: enable user-mode SHA-3, SM3, SM4 and SHA-512 instruction support
49
33
50
Christoffer Dall (1):
34
Joelle van Dyne (7):
51
target/arm/kvm: gic: Prevent creating userspace GICv3 with KVM
35
configure: cross-compiling with empty cross_prefix
36
osdep: build with non-working system() function
37
darwin: remove redundant dependency declaration
38
darwin: fix cross-compiling for Darwin
39
configure: cross compile should use x86_64 cpu_family
40
darwin: detect CoreAudio for build
41
darwin: remove 64-bit build detection on 32-bit OS
52
42
53
Peter Maydell (9):
43
Maxim Uvarov (3):
54
target/arm: Add armv7m_nvic_set_pending_derived()
44
hw: gpio: implement gpio-pwr driver for qemu reset/poweroff
55
target/arm: Split "get pending exception info" from "acknowledge it"
45
arm-virt: refactor gpios creation
56
target/arm: Add ignore_stackfaults argument to v7m_exception_taken()
46
arm-virt: add secure pl061 for reset/power down
57
target/arm: Make v7M exception entry stack push check MPU
58
target/arm: Make v7m_push_callee_stack() honour MPU
59
target/arm: Make exception vector loads honour the SAU
60
target/arm: Handle exceptions during exception stack pop
61
target/arm/translate.c: Fix missing 'break' for TT insns
62
hw/core/generic-loader: Allow PC to be set on command line
63
47
64
Richard Henderson (5):
48
Mihai Carabas (4):
65
target/arm: Expand vector registers for SVE
49
hw/misc/pvpanic: split-out generic and bus dependent code
66
target/arm: Add predicate registers for SVE
50
hw/misc/pvpanic: add PCI interface support
67
target/arm: Add SVE to migration state
51
pvpanic : update pvpanic spec document
68
target/arm: Add ZCR_ELx
52
tests/qtest: add a test case for pvpanic-pci
69
target/arm: Add SVE state to TB->FLAGS
70
53
71
hw/intc/Makefile.objs | 2 +-
54
Paolo Bonzini (1):
72
hw/misc/Makefile.objs | 4 +
55
arm: rename xlnx-zcu102.canbusN properties
73
hw/usb/Makefile.objs | 1 +
74
hw/sd/sdhci-internal.h | 23 ++
75
include/hw/intc/imx_gpcv2.h | 22 ++
76
include/hw/misc/imx2_wdt.h | 33 +++
77
include/hw/misc/imx7_ccm.h | 139 +++++++++++
78
include/hw/misc/imx7_gpr.h | 28 +++
79
include/hw/misc/imx7_snvs.h | 35 +++
80
include/hw/sd/sdhci.h | 13 ++
81
include/hw/timer/imx_gpt.h | 1 +
82
include/hw/usb/chipidea.h | 16 ++
83
target/arm/cpu.h | 120 ++++++++--
84
target/arm/helper.h | 12 +
85
target/arm/kvm_arm.h | 4 +
86
target/arm/translate.h | 2 +
87
hw/arm/boot.c | 65 ++++++
88
hw/arm/fsl-imx6.c | 2 +-
89
hw/arm/virt.c | 61 -----
90
hw/core/generic-loader.c | 2 +-
91
hw/intc/armv7m_nvic.c | 98 +++++++-
92
hw/intc/imx_gpcv2.c | 125 ++++++++++
93
hw/misc/imx2_wdt.c | 89 +++++++
94
hw/misc/imx7_ccm.c | 277 ++++++++++++++++++++++
95
hw/misc/imx7_gpr.c | 124 ++++++++++
96
hw/misc/imx7_snvs.c | 83 +++++++
97
hw/sd/sdhci.c | 230 ++++++++++++++++++-
98
hw/timer/imx_gpt.c | 25 ++
99
hw/usb/chipidea.c | 176 ++++++++++++++
100
linux-user/elfload.c | 19 ++
101
target/arm/cpu64.c | 4 +
102
target/arm/crypto_helper.c | 277 +++++++++++++++++++++-
103
target/arm/helper.c | 548 +++++++++++++++++++++++++++++++++++++-------
104
target/arm/machine.c | 88 ++++++-
105
target/arm/translate-a64.c | 350 +++++++++++++++++++++++++++-
106
target/arm/translate.c | 8 +-
107
hw/intc/trace-events | 5 +-
108
hw/misc/trace-events | 4 +
109
38 files changed, 2928 insertions(+), 187 deletions(-)
110
create mode 100644 include/hw/intc/imx_gpcv2.h
111
create mode 100644 include/hw/misc/imx2_wdt.h
112
create mode 100644 include/hw/misc/imx7_ccm.h
113
create mode 100644 include/hw/misc/imx7_gpr.h
114
create mode 100644 include/hw/misc/imx7_snvs.h
115
create mode 100644 include/hw/usb/chipidea.h
116
create mode 100644 hw/intc/imx_gpcv2.c
117
create mode 100644 hw/misc/imx2_wdt.c
118
create mode 100644 hw/misc/imx7_ccm.c
119
create mode 100644 hw/misc/imx7_gpr.c
120
create mode 100644 hw/misc/imx7_snvs.c
121
create mode 100644 hw/usb/chipidea.c
122
56
57
Peter Maydell (26):
58
configure: Move preadv check to meson.build
59
ptimer: Add new ptimer_set_period_from_clock() function
60
clock: Add new clock_has_source() function
61
tests: Add a simple test of the CMSDK APB timer
62
tests: Add a simple test of the CMSDK APB watchdog
63
tests: Add a simple test of the CMSDK APB dual timer
64
hw/timer/cmsdk-apb-timer: Rename CMSDKAPBTIMER struct to CMSDKAPBTimer
65
hw/timer/cmsdk-apb-timer: Add Clock input
66
hw/timer/cmsdk-apb-dualtimer: Add Clock input
67
hw/watchdog/cmsdk-apb-watchdog: Add Clock input
68
hw/arm/armsse: Rename "MAINCLK" property to "MAINCLK_FRQ"
69
hw/arm/armsse: Wire up clocks
70
hw/arm/mps2: Inline CMSDK_APB_TIMER creation
71
hw/arm/mps2: Create and connect SYSCLK Clock
72
hw/arm/mps2-tz: Create and connect ARMSSE Clocks
73
hw/arm/musca: Create and connect ARMSSE Clocks
74
hw/arm/stellaris: Convert SSYS to QOM device
75
hw/arm/stellaris: Create Clock input for watchdog
76
hw/timer/cmsdk-apb-timer: Convert to use Clock input
77
hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
78
hw/watchdog/cmsdk-apb-watchdog: Convert to use Clock input
79
tests/qtest/cmsdk-apb-watchdog-test: Test clock changes
80
hw/arm/armsse: Use Clock to set system_clock_scale
81
arm: Don't set freq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
82
arm: Remove frq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
83
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS
84
85
Philippe Mathieu-Daudé (1):
86
target/arm: Replace magic value by MMU_DATA_LOAD definition
87
88
Richard Henderson (2):
89
target/arm: Implement ID_PFR2
90
target/arm: Conditionalize DBGDIDR
91
92
docs/devel/clocks.rst | 16 +++
93
docs/specs/pci-ids.txt | 1 +
94
docs/specs/pvpanic.txt | 13 ++-
95
docs/system/arm/virt.rst | 2 +
96
configure | 78 ++++++++------
97
meson.build | 34 ++++++-
98
include/hw/arm/armsse.h | 14 ++-
99
include/hw/arm/virt.h | 2 +
100
include/hw/clock.h | 15 +++
101
include/hw/misc/pvpanic.h | 24 ++++-
102
include/hw/pci/pci.h | 1 +
103
include/hw/ptimer.h | 22 ++++
104
include/hw/timer/cmsdk-apb-dualtimer.h | 5 +-
105
include/hw/timer/cmsdk-apb-timer.h | 34 ++-----
106
include/hw/watchdog/cmsdk-apb-watchdog.h | 5 +-
107
include/qemu/osdep.h | 12 +++
108
include/qemu/typedefs.h | 1 +
109
target/arm/cpu.h | 1 +
110
hw/arm/armsse.c | 48 ++++++---
111
hw/arm/mps2-tz.c | 14 ++-
112
hw/arm/mps2.c | 28 ++++-
113
hw/arm/musca.c | 13 ++-
114
hw/arm/stellaris.c | 170 +++++++++++++++++++++++--------
115
hw/arm/virt.c | 111 ++++++++++++++++----
116
hw/arm/xlnx-zcu102.c | 4 +-
117
hw/core/ptimer.c | 34 +++++++
118
hw/gpio/gpio_pwr.c | 70 +++++++++++++
119
hw/misc/npcm7xx_pwm.c | 23 ++++-
120
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++
121
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++
122
hw/misc/pvpanic.c | 85 ++--------------
123
hw/timer/cmsdk-apb-dualtimer.c | 53 +++++++---
124
hw/timer/cmsdk-apb-timer.c | 55 +++++-----
125
hw/watchdog/cmsdk-apb-watchdog.c | 29 ++++--
126
target/arm/helper.c | 27 +++--
127
target/arm/kvm64.c | 2 +
128
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++
129
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++
130
tests/qtest/cmsdk-apb-watchdog-test.c | 131 ++++++++++++++++++++++++
131
tests/qtest/npcm7xx_pwm-test.c | 4 +-
132
tests/qtest/pvpanic-pci-test.c | 94 +++++++++++++++++
133
tests/qtest/xlnx-can-test.c | 30 +++---
134
MAINTAINERS | 3 +
135
accel/hvf/entitlements.plist | 8 ++
136
hw/arm/Kconfig | 1 +
137
hw/gpio/Kconfig | 3 +
138
hw/gpio/meson.build | 1 +
139
hw/i386/Kconfig | 2 +-
140
hw/misc/Kconfig | 12 ++-
141
hw/misc/meson.build | 4 +-
142
scripts/entitlement.sh | 13 +++
143
tests/qtest/meson.build | 6 +-
144
52 files changed, 1432 insertions(+), 319 deletions(-)
145
create mode 100644 hw/gpio/gpio_pwr.c
146
create mode 100644 hw/misc/pvpanic-isa.c
147
create mode 100644 hw/misc/pvpanic-pci.c
148
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
149
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
150
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
151
create mode 100644 tests/qtest/pvpanic-pci-test.c
152
create mode 100644 accel/hvf/entitlements.plist
153
create mode 100755 scripts/entitlement.sh
154
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add both SVE exception state and vector length.
3
This was defined at some point before ARMv8.4, and will
4
shortly be used by new processor descriptions.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20210120204400.1056582-1-richard.henderson@linaro.org
7
Message-id: 20180123035349.24538-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/cpu.h | 8 ++++++++
11
target/arm/cpu.h | 1 +
11
target/arm/translate.h | 2 ++
12
target/arm/helper.c | 4 ++--
12
target/arm/helper.c | 25 ++++++++++++++++++++++++-
13
target/arm/kvm64.c | 2 ++
13
target/arm/translate-a64.c | 2 ++
14
3 files changed, 5 insertions(+), 2 deletions(-)
14
4 files changed, 36 insertions(+), 1 deletion(-)
15
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
21
uint32_t id_mmfr4;
22
#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */
22
uint32_t id_pfr0;
23
#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
23
uint32_t id_pfr1;
24
+#define ARM_TBFLAG_SVEEXC_EL_SHIFT 2
24
+ uint32_t id_pfr2;
25
+#define ARM_TBFLAG_SVEEXC_EL_MASK (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
25
uint32_t mvfr0;
26
+#define ARM_TBFLAG_ZCR_LEN_SHIFT 4
26
uint32_t mvfr1;
27
+#define ARM_TBFLAG_ZCR_LEN_MASK (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
27
uint32_t mvfr2;
28
29
/* some convenience accessor macros */
30
#define ARM_TBFLAG_AARCH64_STATE(F) \
31
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
32
(((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
33
#define ARM_TBFLAG_TBI1(F) \
34
(((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
35
+#define ARM_TBFLAG_SVEEXC_EL(F) \
36
+ (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
37
+#define ARM_TBFLAG_ZCR_LEN(F) \
38
+ (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
39
40
static inline bool bswap_code(bool sctlr_b)
41
{
42
diff --git a/target/arm/translate.h b/target/arm/translate.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate.h
45
+++ b/target/arm/translate.h
46
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
47
bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
48
bool ns; /* Use non-secure CPREG bank on access */
49
int fp_excp_el; /* FP exception EL or 0 if enabled */
50
+ int sve_excp_el; /* SVE exception EL or 0 if enabled */
51
+ int sve_len; /* SVE vector length in bytes */
52
/* Flag indicating that exceptions from secure mode are routed to EL3. */
53
bool secure_routed_to_el3;
54
bool vfp_enabled; /* FP enabled via FPSCR.EN */
55
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
56
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/helper.c
30
--- a/target/arm/helper.c
58
+++ b/target/arm/helper.c
31
+++ b/target/arm/helper.c
59
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
60
target_ulong *cs_base, uint32_t *pflags)
33
.access = PL1_R, .type = ARM_CP_CONST,
61
{
34
.accessfn = access_aa64_tid3,
62
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
35
.resetvalue = 0 },
63
+ int fp_el = fp_exception_el(env);
36
- { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
64
uint32_t flags;
37
+ { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
65
38
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
66
if (is_a64(env)) {
39
.access = PL1_R, .type = ARM_CP_CONST,
67
+ int sve_el = sve_exception_el(env);
40
.accessfn = access_aa64_tid3,
68
+ uint32_t zcr_len;
41
- .resetvalue = 0 },
69
+
42
+ .resetvalue = cpu->isar.id_pfr2 },
70
*pc = env->pc;
43
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
71
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
44
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
72
/* Get control bits for tagged addresses */
45
.access = PL1_R, .type = ARM_CP_CONST,
73
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
46
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
74
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
75
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
76
+
77
+ /* If SVE is disabled, but FP is enabled,
78
+ then the effective len is 0. */
79
+ if (sve_el != 0 && fp_el == 0) {
80
+ zcr_len = 0;
81
+ } else {
82
+ int current_el = arm_current_el(env);
83
+
84
+ zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
85
+ zcr_len &= 0xf;
86
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
87
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
88
+ }
89
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
90
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
91
+ }
92
+ }
93
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
94
} else {
95
*pc = env->regs[15];
96
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
98
if (arm_cpu_data_is_big_endian(env)) {
99
flags |= ARM_TBFLAG_BE_DATA_MASK;
100
}
101
- flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
102
+ flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
103
104
if (arm_v7m_is_handler_mode(env)) {
105
flags |= ARM_TBFLAG_HANDLER_MASK;
106
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-a64.c
48
--- a/target/arm/kvm64.c
109
+++ b/target/arm/translate-a64.c
49
+++ b/target/arm/kvm64.c
110
@@ -XXX,XX +XXX,XX @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
50
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
111
dc->user = (dc->current_el == 0);
51
ARM64_SYS_REG(3, 0, 0, 1, 0));
112
#endif
52
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
113
dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
53
ARM64_SYS_REG(3, 0, 0, 1, 1));
114
+ dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
54
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
115
+ dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
55
+ ARM64_SYS_REG(3, 0, 0, 3, 4));
116
dc->vec_len = 0;
56
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
117
dc->vec_stride = 0;
57
ARM64_SYS_REG(3, 0, 0, 1, 2));
118
dc->cp_regs = arm_cpu->cp_regs;
58
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
119
--
59
--
120
2.16.1
60
2.20.1
121
61
122
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Define ZCR_EL[1-3].
3
Only define the register if it exists for the cpu.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210120031656.737646-1-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180123035349.24538-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/cpu.h | 5 ++
10
target/arm/helper.c | 21 +++++++++++++++------
11
target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 15 insertions(+), 6 deletions(-)
12
2 files changed, 136 insertions(+)
13
12
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
19
*/
20
float_status fp_status;
21
float_status standard_fp_status;
22
+
23
+ /* ZCR_EL[1-3] */
24
+ uint64_t zcr_el[4];
25
} vfp;
26
uint64_t exclusive_addr;
27
uint64_t exclusive_val;
28
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
29
#define CPTR_TCPAC (1U << 31)
30
#define CPTR_TTA (1U << 20)
31
#define CPTR_TFP (1U << 10)
32
+#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
33
+#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
34
35
#define MDCR_EPMAD (1U << 21)
36
#define MDCR_EDAD (1U << 20)
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
17
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
42
REGINFO_SENTINEL
18
*/
43
};
19
int i;
44
20
int wrps, brps, ctx_cmps;
45
+/* Return the exception level to which SVE-disabled exceptions should
21
- ARMCPRegInfo dbgdidr = {
46
+ * be taken, or 0 if SVE is enabled.
22
- .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
47
+ */
23
- .access = PL0_R, .accessfn = access_tda,
48
+static int sve_exception_el(CPUARMState *env)
24
- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
49
+{
25
- };
50
+#ifndef CONFIG_USER_ONLY
51
+ unsigned current_el = arm_current_el(env);
52
+
26
+
53
+ /* The CPACR.ZEN controls traps to EL1:
27
+ /*
54
+ * 0, 2 : trap EL0 and EL1 accesses
28
+ * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
55
+ * 1 : trap only EL0 accesses
29
+ * use AArch32. Given that bit 15 is RES1, if the value is 0 then
56
+ * 3 : trap no accesses
30
+ * the register must not exist for this cpu.
57
+ */
31
+ */
58
+ switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
32
+ if (cpu->isar.dbgdidr != 0) {
59
+ default:
33
+ ARMCPRegInfo dbgdidr = {
60
+ if (current_el <= 1) {
34
+ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
61
+ /* Trap to PL1, which might be EL1 or EL3 */
35
+ .opc1 = 0, .opc2 = 0,
62
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
36
+ .access = PL0_R, .accessfn = access_tda,
63
+ return 3;
37
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
64
+ }
38
+ };
65
+ return 1;
39
+ define_one_arm_cp_reg(cpu, &dbgdidr);
66
+ }
67
+ break;
68
+ case 1:
69
+ if (current_el == 0) {
70
+ return 1;
71
+ }
72
+ break;
73
+ case 3:
74
+ break;
75
+ }
40
+ }
76
+
41
77
+ /* Similarly for CPACR.FPEN, after having checked ZEN. */
42
/* Note that all these register fields hold "number of Xs minus 1". */
78
+ switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
43
brps = arm_num_brps(cpu);
79
+ default:
44
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
80
+ if (current_el <= 1) {
45
81
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
46
assert(ctx_cmps <= brps);
82
+ return 3;
47
83
+ }
48
- define_one_arm_cp_reg(cpu, &dbgdidr);
84
+ return 1;
49
define_arm_cp_regs(cpu, debug_cp_reginfo);
85
+ }
50
86
+ break;
51
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
87
+ case 1:
88
+ if (current_el == 0) {
89
+ return 1;
90
+ }
91
+ break;
92
+ case 3:
93
+ break;
94
+ }
95
+
96
+ /* CPTR_EL2. Check both TZ and TFP. */
97
+ if (current_el <= 2
98
+ && (env->cp15.cptr_el[2] & (CPTR_TFP | CPTR_TZ))
99
+ && !arm_is_secure_below_el3(env)) {
100
+ return 2;
101
+ }
102
+
103
+ /* CPTR_EL3. Check both EZ and TFP. */
104
+ if (!(env->cp15.cptr_el[3] & CPTR_EZ)
105
+ || (env->cp15.cptr_el[3] & CPTR_TFP)) {
106
+ return 3;
107
+ }
108
+#endif
109
+ return 0;
110
+}
111
+
112
+static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
113
+ bool isread)
114
+{
115
+ switch (sve_exception_el(env)) {
116
+ case 3:
117
+ return CP_ACCESS_TRAP_EL3;
118
+ case 2:
119
+ return CP_ACCESS_TRAP_EL2;
120
+ case 1:
121
+ return CP_ACCESS_TRAP;
122
+ }
123
+ return CP_ACCESS_OK;
124
+}
125
+
126
+static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
127
+ uint64_t value)
128
+{
129
+ /* Bits other than [3:0] are RAZ/WI. */
130
+ raw_write(env, ri, value & 0xf);
131
+}
132
+
133
+static const ARMCPRegInfo zcr_el1_reginfo = {
134
+ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
135
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
136
+ .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
137
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
138
+ .writefn = zcr_write, .raw_writefn = raw_write
139
+};
140
+
141
+static const ARMCPRegInfo zcr_el2_reginfo = {
142
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
143
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
144
+ .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
145
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
146
+ .writefn = zcr_write, .raw_writefn = raw_write
147
+};
148
+
149
+static const ARMCPRegInfo zcr_no_el2_reginfo = {
150
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
151
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
152
+ .access = PL2_RW, .type = ARM_CP_64BIT,
153
+ .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
154
+};
155
+
156
+static const ARMCPRegInfo zcr_el3_reginfo = {
157
+ .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
158
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
159
+ .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
160
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
161
+ .writefn = zcr_write, .raw_writefn = raw_write
162
+};
163
+
164
void hw_watchpoint_update(ARMCPU *cpu, int n)
165
{
166
CPUARMState *env = &cpu->env;
167
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
168
}
169
define_one_arm_cp_reg(cpu, &sctlr);
170
}
171
+
172
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
173
+ define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
174
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
175
+ define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
176
+ } else {
177
+ define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
178
+ }
179
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
180
+ define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
181
+ }
182
+ }
183
}
184
185
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
186
--
52
--
187
2.16.1
53
2.20.1
188
54
189
55
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
The properties to attach a CANBUS object to the xlnx-zcu102 machine have
4
a period in them. We want to use periods in properties for compound QAPI types,
5
and besides the "xlnx-zcu102." prefix is both unnecessary and different
6
from any other machine property name. Remove it.
7
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Message-id: 20210118162537.779542-1-pbonzini@redhat.com
10
Reviewed-by: Vikram Garhwal <fnu.vikram@xilinx.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/xlnx-zcu102.c | 4 ++--
14
tests/qtest/xlnx-can-test.c | 30 +++++++++++++++---------------
15
2 files changed, 17 insertions(+), 17 deletions(-)
16
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/xlnx-zcu102.c
20
+++ b/hw/arm/xlnx-zcu102.c
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
22
s->secure = false;
23
/* Default to virt (EL2) being disabled */
24
s->virt = false;
25
- object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
26
+ object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
27
(Object **)&s->canbus[0],
28
object_property_allow_set_link,
29
0);
30
31
- object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
32
+ object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
33
(Object **)&s->canbus[1],
34
object_property_allow_set_link,
35
0);
36
diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/qtest/xlnx-can-test.c
39
+++ b/tests/qtest/xlnx-can-test.c
40
@@ -XXX,XX +XXX,XX @@ static void test_can_bus(void)
41
uint8_t can_timestamp = 1;
42
43
QTestState *qts = qtest_init("-machine xlnx-zcu102"
44
- " -object can-bus,id=canbus0"
45
- " -machine xlnx-zcu102.canbus0=canbus0"
46
- " -machine xlnx-zcu102.canbus1=canbus0"
47
+ " -object can-bus,id=canbus"
48
+ " -machine canbus0=canbus"
49
+ " -machine canbus1=canbus"
50
);
51
52
/* Configure the CAN0 and CAN1. */
53
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
54
uint32_t status = 0;
55
56
QTestState *qts = qtest_init("-machine xlnx-zcu102"
57
- " -object can-bus,id=canbus0"
58
- " -machine xlnx-zcu102.canbus0=canbus0"
59
- " -machine xlnx-zcu102.canbus1=canbus0"
60
+ " -object can-bus,id=canbus"
61
+ " -machine canbus0=canbus"
62
+ " -machine canbus1=canbus"
63
);
64
65
/* Configure the CAN0 in loopback mode. */
66
@@ -XXX,XX +XXX,XX @@ static void test_can_filter(void)
67
uint8_t can_timestamp = 1;
68
69
QTestState *qts = qtest_init("-machine xlnx-zcu102"
70
- " -object can-bus,id=canbus0"
71
- " -machine xlnx-zcu102.canbus0=canbus0"
72
- " -machine xlnx-zcu102.canbus1=canbus0"
73
+ " -object can-bus,id=canbus"
74
+ " -machine canbus0=canbus"
75
+ " -machine canbus1=canbus"
76
);
77
78
/* Configure the CAN0 and CAN1. */
79
@@ -XXX,XX +XXX,XX @@ static void test_can_sleepmode(void)
80
uint8_t can_timestamp = 1;
81
82
QTestState *qts = qtest_init("-machine xlnx-zcu102"
83
- " -object can-bus,id=canbus0"
84
- " -machine xlnx-zcu102.canbus0=canbus0"
85
- " -machine xlnx-zcu102.canbus1=canbus0"
86
+ " -object can-bus,id=canbus"
87
+ " -machine canbus0=canbus"
88
+ " -machine canbus1=canbus"
89
);
90
91
/* Configure the CAN0. */
92
@@ -XXX,XX +XXX,XX @@ static void test_can_snoopmode(void)
93
uint8_t can_timestamp = 1;
94
95
QTestState *qts = qtest_init("-machine xlnx-zcu102"
96
- " -object can-bus,id=canbus0"
97
- " -machine xlnx-zcu102.canbus0=canbus0"
98
- " -machine xlnx-zcu102.canbus1=canbus0"
99
+ " -object can-bus,id=canbus"
100
+ " -machine canbus0=canbus"
101
+ " -machine canbus1=canbus"
102
);
103
104
/* Configure the CAN0. */
105
--
106
2.20.1
107
108
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
3
Implement gpio-pwr driver to allow reboot and poweroff machine.
4
work against:
4
This is simple driver with just 2 gpios lines. Current use case
5
is to reboot and poweroff virt machine in secure mode. Secure
6
pl066 gpio chip is needed for that.
5
7
6
-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
8
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
usb-storage,bus=usb-bus.0,drive=stick
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
13
Cc: Michael S. Tsirkin <mst@redhat.com>
14
Cc: qemu-devel@nongnu.org
15
Cc: qemu-arm@nongnu.org
16
Cc: yurovsky@gmail.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
12
---
21
hw/usb/Makefile.objs | 1 +
13
hw/gpio/gpio_pwr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
22
include/hw/usb/chipidea.h | 16 +++++
14
hw/gpio/Kconfig | 3 ++
23
hw/usb/chipidea.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++
15
hw/gpio/meson.build | 1 +
24
3 files changed, 193 insertions(+)
16
3 files changed, 74 insertions(+)
25
create mode 100644 include/hw/usb/chipidea.h
17
create mode 100644 hw/gpio/gpio_pwr.c
26
create mode 100644 hw/usb/chipidea.c
27
18
28
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
19
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/usb/Makefile.objs
31
+++ b/hw/usb/Makefile.objs
32
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
33
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
34
35
obj-$(CONFIG_TUSB6010) += tusb6010.o
36
+obj-$(CONFIG_IMX) += chipidea.o
37
38
# emulated usb devices
39
common-obj-$(CONFIG_USB) += dev-hub.o
40
diff --git a/include/hw/usb/chipidea.h b/include/hw/usb/chipidea.h
41
new file mode 100644
20
new file mode 100644
42
index XXXXXXX..XXXXXXX
21
index XXXXXXX..XXXXXXX
43
--- /dev/null
22
--- /dev/null
44
+++ b/include/hw/usb/chipidea.h
23
+++ b/hw/gpio/gpio_pwr.c
45
@@ -XXX,XX +XXX,XX @@
46
+#ifndef CHIPIDEA_H
47
+#define CHIPIDEA_H
48
+
49
+#include "hw/usb/hcd-ehci.h"
50
+
51
+typedef struct ChipideaState {
52
+ /*< private >*/
53
+ EHCISysBusState parent_obj;
54
+
55
+ MemoryRegion iomem[3];
56
+} ChipideaState;
57
+
58
+#define TYPE_CHIPIDEA "usb-chipidea"
59
+#define CHIPIDEA(obj) OBJECT_CHECK(ChipideaState, (obj), TYPE_CHIPIDEA)
60
+
61
+#endif /* CHIPIDEA_H */
62
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
63
new file mode 100644
64
index XXXXXXX..XXXXXXX
65
--- /dev/null
66
+++ b/hw/usb/chipidea.c
67
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
68
+/*
25
+/*
69
+ * Copyright (c) 2018, Impinj, Inc.
26
+ * GPIO qemu power controller
70
+ *
27
+ *
71
+ * Chipidea USB block emulation code
28
+ * Copyright (c) 2020 Linaro Limited
72
+ *
29
+ *
73
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
30
+ * Author: Maxim Uvarov <maxim.uvarov@linaro.org>
31
+ *
32
+ * Virtual gpio driver which can be used on top of pl061
33
+ * to reboot and shutdown qemu virtual machine. One of use
34
+ * case is gpio driver for secure world application (ARM
35
+ * Trusted Firmware.).
74
+ *
36
+ *
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
37
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
76
+ * See the COPYING file in the top-level directory.
38
+ * See the COPYING file in the top-level directory.
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
+ */
41
+
42
+/*
43
+ * QEMU interface:
44
+ * two named input GPIO lines:
45
+ * 'reset' : when asserted, trigger system reset
46
+ * 'shutdown' : when asserted, trigger system shutdown
77
+ */
47
+ */
78
+
48
+
79
+#include "qemu/osdep.h"
49
+#include "qemu/osdep.h"
80
+#include "hw/usb/hcd-ehci.h"
50
+#include "hw/sysbus.h"
81
+#include "hw/usb/chipidea.h"
51
+#include "sysemu/runstate.h"
82
+#include "qemu/log.h"
83
+
52
+
84
+enum {
53
+#define TYPE_GPIOPWR "gpio-pwr"
85
+ CHIPIDEA_USBx_DCIVERSION = 0x000,
54
+OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
86
+ CHIPIDEA_USBx_DCCPARAMS = 0x004,
55
+
87
+ CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
56
+struct GPIO_PWR_State {
57
+ SysBusDevice parent_obj;
88
+};
58
+};
89
+
59
+
90
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
60
+static void gpio_pwr_reset(void *opaque, int n, int level)
91
+ unsigned size)
92
+{
61
+{
93
+ return 0;
62
+ if (level) {
94
+}
63
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
95
+
96
+static void chipidea_write(void *opaque, hwaddr offset,
97
+ uint64_t value, unsigned size)
98
+{
99
+}
100
+
101
+static const struct MemoryRegionOps chipidea_ops = {
102
+ .read = chipidea_read,
103
+ .write = chipidea_write,
104
+ .endianness = DEVICE_NATIVE_ENDIAN,
105
+ .impl = {
106
+ /*
107
+ * Our device would not work correctly if the guest was doing
108
+ * unaligned access. This might not be a limitation on the
109
+ * real device but in practice there is no reason for a guest
110
+ * to access this device unaligned.
111
+ */
112
+ .min_access_size = 4,
113
+ .max_access_size = 4,
114
+ .unaligned = false,
115
+ },
116
+};
117
+
118
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
119
+ unsigned size)
120
+{
121
+ switch (offset) {
122
+ case CHIPIDEA_USBx_DCIVERSION:
123
+ return 0x1;
124
+ case CHIPIDEA_USBx_DCCPARAMS:
125
+ /*
126
+ * Real hardware (at least i.MX7) will also report the
127
+ * controller as "Device Capable" (and 8 supported endpoints),
128
+ * but there doesn't seem to be much point in doing so, since
129
+ * we don't emulate that part.
130
+ */
131
+ return CHIPIDEA_USBx_DCCPARAMS_HC;
132
+ }
133
+
134
+ return 0;
135
+}
136
+
137
+static void chipidea_dc_write(void *opaque, hwaddr offset,
138
+ uint64_t value, unsigned size)
139
+{
140
+}
141
+
142
+static const struct MemoryRegionOps chipidea_dc_ops = {
143
+ .read = chipidea_dc_read,
144
+ .write = chipidea_dc_write,
145
+ .endianness = DEVICE_NATIVE_ENDIAN,
146
+ .impl = {
147
+ /*
148
+ * Our device would not work correctly if the guest was doing
149
+ * unaligned access. This might not be a limitation on the real
150
+ * device but in practice there is no reason for a guest to access
151
+ * this device unaligned.
152
+ */
153
+ .min_access_size = 4,
154
+ .max_access_size = 4,
155
+ .unaligned = false,
156
+ },
157
+};
158
+
159
+static void chipidea_init(Object *obj)
160
+{
161
+ EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
162
+ ChipideaState *ci = CHIPIDEA(obj);
163
+ int i;
164
+
165
+ for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
166
+ const struct {
167
+ const char *name;
168
+ hwaddr offset;
169
+ uint64_t size;
170
+ const struct MemoryRegionOps *ops;
171
+ } regions[ARRAY_SIZE(ci->iomem)] = {
172
+ /*
173
+ * Registers located between offsets 0x000 and 0xFC
174
+ */
175
+ {
176
+ .name = TYPE_CHIPIDEA ".misc",
177
+ .offset = 0x000,
178
+ .size = 0x100,
179
+ .ops = &chipidea_ops,
180
+ },
181
+ /*
182
+ * Registers located between offsets 0x1A4 and 0x1DC
183
+ */
184
+ {
185
+ .name = TYPE_CHIPIDEA ".endpoints",
186
+ .offset = 0x1A4,
187
+ .size = 0x1DC - 0x1A4 + 4,
188
+ .ops = &chipidea_ops,
189
+ },
190
+ /*
191
+ * USB_x_DCIVERSION and USB_x_DCCPARAMS
192
+ */
193
+ {
194
+ .name = TYPE_CHIPIDEA ".dc",
195
+ .offset = 0x120,
196
+ .size = 8,
197
+ .ops = &chipidea_dc_ops,
198
+ },
199
+ };
200
+
201
+ memory_region_init_io(&ci->iomem[i],
202
+ obj,
203
+ regions[i].ops,
204
+ ci,
205
+ regions[i].name,
206
+ regions[i].size);
207
+
208
+ memory_region_add_subregion(&ehci->mem,
209
+ regions[i].offset,
210
+ &ci->iomem[i]);
211
+ }
64
+ }
212
+}
65
+}
213
+
66
+
214
+static void chipidea_class_init(ObjectClass *klass, void *data)
67
+static void gpio_pwr_shutdown(void *opaque, int n, int level)
215
+{
68
+{
216
+ DeviceClass *dc = DEVICE_CLASS(klass);
69
+ if (level) {
217
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);
70
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
218
+
71
+ }
219
+ /*
220
+ * Offsets used were taken from i.MX7Dual Applications Processor
221
+ * Reference Manual, Rev 0.1, p. 3177, Table 11-59
222
+ */
223
+ sec->capsbase = 0x100;
224
+ sec->opregbase = 0x140;
225
+ sec->portnr = 1;
226
+
227
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
228
+ dc->desc = "Chipidea USB Module";
229
+}
72
+}
230
+
73
+
231
+static const TypeInfo chipidea_info = {
74
+static void gpio_pwr_init(Object *obj)
232
+ .name = TYPE_CHIPIDEA,
75
+{
233
+ .parent = TYPE_SYS_BUS_EHCI,
76
+ DeviceState *dev = DEVICE(obj);
234
+ .instance_size = sizeof(ChipideaState),
77
+
235
+ .instance_init = chipidea_init,
78
+ qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
236
+ .class_init = chipidea_class_init,
79
+ qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
80
+}
81
+
82
+static const TypeInfo gpio_pwr_info = {
83
+ .name = TYPE_GPIOPWR,
84
+ .parent = TYPE_SYS_BUS_DEVICE,
85
+ .instance_size = sizeof(GPIO_PWR_State),
86
+ .instance_init = gpio_pwr_init,
237
+};
87
+};
238
+
88
+
239
+static void chipidea_register_type(void)
89
+static void gpio_pwr_register_types(void)
240
+{
90
+{
241
+ type_register_static(&chipidea_info);
91
+ type_register_static(&gpio_pwr_info);
242
+}
92
+}
243
+type_init(chipidea_register_type)
93
+
94
+type_init(gpio_pwr_register_types)
95
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/gpio/Kconfig
98
+++ b/hw/gpio/Kconfig
99
@@ -XXX,XX +XXX,XX @@ config PL061
100
config GPIO_KEY
101
bool
102
103
+config GPIO_PWR
104
+ bool
105
+
106
config SIFIVE_GPIO
107
bool
108
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/gpio/meson.build
111
+++ b/hw/gpio/meson.build
112
@@ -XXX,XX +XXX,XX @@
113
softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
114
softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
115
+softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
116
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
117
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
118
softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
244
--
119
--
245
2.16.1
120
2.20.1
246
121
247
122
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
3
No functional change. Just refactor code to better
4
happen automatically for every board that doesn't mark "psci-conduit"
4
support secure and normal world gpios.
5
as disabled. This way emulated boards other than "virt" that rely on
6
PSIC for SMP could benefit from that code.
7
5
8
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
12
Cc: Michael S. Tsirkin <mst@redhat.com>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
15
Cc: yurovsky@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
9
---
21
hw/arm/boot.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
hw/arm/virt.c | 57 ++++++++++++++++++++++++++++++++-------------------
22
hw/arm/virt.c | 61 -------------------------------------------------------
11
1 file changed, 36 insertions(+), 21 deletions(-)
23
2 files changed, 65 insertions(+), 61 deletions(-)
24
12
25
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/boot.c
28
+++ b/hw/arm/boot.c
29
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info)
30
}
31
}
32
33
+static void fdt_add_psci_node(void *fdt)
34
+{
35
+ uint32_t cpu_suspend_fn;
36
+ uint32_t cpu_off_fn;
37
+ uint32_t cpu_on_fn;
38
+ uint32_t migrate_fn;
39
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
40
+ const char *psci_method;
41
+ int64_t psci_conduit;
42
+
43
+ psci_conduit = object_property_get_int(OBJECT(armcpu),
44
+ "psci-conduit",
45
+ &error_abort);
46
+ switch (psci_conduit) {
47
+ case QEMU_PSCI_CONDUIT_DISABLED:
48
+ return;
49
+ case QEMU_PSCI_CONDUIT_HVC:
50
+ psci_method = "hvc";
51
+ break;
52
+ case QEMU_PSCI_CONDUIT_SMC:
53
+ psci_method = "smc";
54
+ break;
55
+ default:
56
+ g_assert_not_reached();
57
+ }
58
+
59
+ qemu_fdt_add_subnode(fdt, "/psci");
60
+ if (armcpu->psci_version == 2) {
61
+ const char comp[] = "arm,psci-0.2\0arm,psci";
62
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
63
+
64
+ cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
65
+ if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
66
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
67
+ cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
68
+ migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
69
+ } else {
70
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
71
+ cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
72
+ migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
73
+ }
74
+ } else {
75
+ qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
76
+
77
+ cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
78
+ cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
79
+ cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
80
+ migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
81
+ }
82
+
83
+ /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
84
+ * to the instruction that should be used to invoke PSCI functions.
85
+ * However, the device tree binding uses 'method' instead, so that is
86
+ * what we should use here.
87
+ */
88
+ qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
89
+
90
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
91
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
92
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
93
+ qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
94
+}
95
+
96
/**
97
* load_dtb() - load a device tree binary image into memory
98
* @addr: the address to load the image at
99
@@ -XXX,XX +XXX,XX @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
100
}
101
}
102
103
+ fdt_add_psci_node(fdt);
104
+
105
if (binfo->modify_dtb) {
106
binfo->modify_dtb(binfo, fdt);
107
}
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
15
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
16
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
17
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
113
}
18
}
114
}
19
}
115
20
116
-static void fdt_add_psci_node(const VirtMachineState *vms)
21
-static void create_gpio(const VirtMachineState *vms)
117
-{
22
+static void create_gpio_keys(const VirtMachineState *vms,
118
- uint32_t cpu_suspend_fn;
23
+ DeviceState *pl061_dev,
119
- uint32_t cpu_off_fn;
24
+ uint32_t phandle)
120
- uint32_t cpu_on_fn;
25
+{
121
- uint32_t migrate_fn;
26
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
122
- void *fdt = vms->fdt;
27
+ qdev_get_gpio_in(pl061_dev, 3));
123
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
28
+
124
- const char *psci_method;
29
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
30
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
31
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
32
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
33
+
34
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
35
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
36
+ "label", "GPIO Key Poweroff");
37
+ qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
38
+ KEY_POWER);
39
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
40
+ "gpios", phandle, 3, 0);
41
+}
42
+
43
+static void create_gpio_devices(const VirtMachineState *vms, int gpio,
44
+ MemoryRegion *mem)
45
{
46
char *nodename;
47
DeviceState *pl061_dev;
48
- hwaddr base = vms->memmap[VIRT_GPIO].base;
49
- hwaddr size = vms->memmap[VIRT_GPIO].size;
50
- int irq = vms->irqmap[VIRT_GPIO];
51
+ hwaddr base = vms->memmap[gpio].base;
52
+ hwaddr size = vms->memmap[gpio].size;
53
+ int irq = vms->irqmap[gpio];
54
const char compat[] = "arm,pl061\0arm,primecell";
55
+ SysBusDevice *s;
56
57
- pl061_dev = sysbus_create_simple("pl061", base,
58
- qdev_get_gpio_in(vms->gic, irq));
59
+ pl061_dev = qdev_new("pl061");
60
+ s = SYS_BUS_DEVICE(pl061_dev);
61
+ sysbus_realize_and_unref(s, &error_fatal);
62
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
63
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
64
65
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
66
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
67
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms)
68
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
69
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
70
71
- gpio_key_dev = sysbus_create_simple("gpio-key", -1,
72
- qdev_get_gpio_in(pl061_dev, 3));
73
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
74
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
75
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
76
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
125
-
77
-
126
- switch (vms->psci_conduit) {
78
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
127
- case QEMU_PSCI_CONDUIT_DISABLED:
79
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
128
- return;
80
- "label", "GPIO Key Poweroff");
129
- case QEMU_PSCI_CONDUIT_HVC:
81
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
130
- psci_method = "hvc";
82
- KEY_POWER);
131
- break;
83
- qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
132
- case QEMU_PSCI_CONDUIT_SMC:
84
- "gpios", phandle, 3, 0);
133
- psci_method = "smc";
85
g_free(nodename);
134
- break;
86
+
135
- default:
87
+ /* Child gpio devices */
136
- g_assert_not_reached();
88
+ create_gpio_keys(vms, pl061_dev, phandle);
137
- }
89
}
138
-
90
139
- qemu_fdt_add_subnode(fdt, "/psci");
91
static void create_virtio_devices(const VirtMachineState *vms)
140
- if (armcpu->psci_version == 2) {
141
- const char comp[] = "arm,psci-0.2\0arm,psci";
142
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
143
-
144
- cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
145
- if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
146
- cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
147
- cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
148
- migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
149
- } else {
150
- cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
151
- cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
152
- migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
153
- }
154
- } else {
155
- qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
156
-
157
- cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
158
- cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
159
- cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
160
- migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
161
- }
162
-
163
- /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
164
- * to the instruction that should be used to invoke PSCI functions.
165
- * However, the device tree binding uses 'method' instead, so that is
166
- * what we should use here.
167
- */
168
- qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
169
-
170
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
171
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
172
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
173
- qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
174
-}
175
-
176
static void fdt_add_timer_nodes(const VirtMachineState *vms)
177
{
178
/* On real hardware these interrupts are level-triggered.
179
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
92
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
93
if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
94
vms->acpi_dev = create_acpi_ged(vms);
95
} else {
96
- create_gpio(vms);
97
+ create_gpio_devices(vms, VIRT_GPIO, sysmem);
180
}
98
}
181
fdt_add_timer_nodes(vms);
99
182
fdt_add_cpu_nodes(vms);
100
/* connect powerdown request */
183
- fdt_add_psci_node(vms);
184
185
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
186
machine->ram_size);
187
--
101
--
188
2.16.1
102
2.20.1
189
103
190
104
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
This implements emulation of the new SHA-512 instructions that have
3
Add secure pl061 for reset/power down machine from
4
been added as an optional extensions to the ARMv8 Crypto Extensions
4
the secure world (Arm Trusted Firmware). Connect it
5
in ARM v8.2.
5
with gpio-pwr driver.
6
6
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
Message-id: 20180207111729.15737-2-ard.biesheuvel@linaro.org
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
[PMM: Added mention of the new device to the documentation]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/cpu.h | 1 +
12
docs/system/arm/virt.rst | 2 ++
13
target/arm/helper.h | 5 +++
13
include/hw/arm/virt.h | 2 ++
14
target/arm/crypto_helper.c | 90 ++++++++++++++++++++++++++++++++++++-
14
hw/arm/virt.c | 56 +++++++++++++++++++++++++++++++++++++++-
15
target/arm/translate-a64.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
15
hw/arm/Kconfig | 1 +
16
4 files changed, 205 insertions(+), 1 deletion(-)
16
4 files changed, 60 insertions(+), 1 deletion(-)
17
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
20
--- a/docs/system/arm/virt.rst
21
+++ b/target/arm/cpu.h
21
+++ b/docs/system/arm/virt.rst
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
22
@@ -XXX,XX +XXX,XX @@ The virt board supports:
23
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
23
- Secure-World-only devices if the CPU has TrustZone:
24
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
24
25
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
25
- A second PL011 UART
26
+ ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
26
+ - A second PL061 GPIO controller, with GPIO lines for triggering
27
+ a system reset or system poweroff
28
- A secure flash memory
29
- 16MB of secure RAM
30
31
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/arm/virt.h
34
+++ b/include/hw/arm/virt.h
35
@@ -XXX,XX +XXX,XX @@ enum {
36
VIRT_GPIO,
37
VIRT_SECURE_UART,
38
VIRT_SECURE_MEM,
39
+ VIRT_SECURE_GPIO,
40
VIRT_PCDIMM_ACPI,
41
VIRT_ACPI_GED,
42
VIRT_NVDIMM_ACPI,
43
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
44
bool kvm_no_adjvtime;
45
bool no_kvm_steal_time;
46
bool acpi_expose_flash;
47
+ bool no_secure_gpio;
27
};
48
};
28
49
29
static inline int arm_feature(CPUARMState *env, int feature)
50
struct VirtMachineState {
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
31
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
53
--- a/hw/arm/virt.c
33
+++ b/target/arm/helper.h
54
+++ b/hw/arm/virt.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
55
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
35
DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
56
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
36
DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
57
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
37
58
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
38
+DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
59
+ [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
39
+DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
60
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
40
+DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
61
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
41
+DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
62
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
63
@@ -XXX,XX +XXX,XX @@ static void create_gpio_keys(const VirtMachineState *vms,
64
"gpios", phandle, 3, 0);
65
}
66
67
+#define SECURE_GPIO_POWEROFF 0
68
+#define SECURE_GPIO_RESET 1
42
+
69
+
43
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
70
+static void create_secure_gpio_pwr(const VirtMachineState *vms,
44
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
71
+ DeviceState *pl061_dev,
45
DEF_HELPER_2(dc_zva, void, env, i64)
72
+ uint32_t phandle)
46
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
73
+{
47
index XXXXXXX..XXXXXXX 100644
74
+ DeviceState *gpio_pwr_dev;
48
--- a/target/arm/crypto_helper.c
49
+++ b/target/arm/crypto_helper.c
50
@@ -XXX,XX +XXX,XX @@
51
/*
52
* crypto_helper.c - emulate v8 Crypto Extensions instructions
53
*
54
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
55
+ * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
56
*
57
* This library is free software; you can redistribute it and/or
58
* modify it under the terms of the GNU Lesser General Public
59
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
60
rd[0] = d.l[0];
61
rd[1] = d.l[1];
62
}
63
+
75
+
64
+/*
76
+ /* gpio-pwr */
65
+ * The SHA-512 logical functions (same as above but using 64-bit operands)
77
+ gpio_pwr_dev = sysbus_create_simple("gpio-pwr", -1, NULL);
66
+ */
67
+
78
+
68
+static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
79
+ /* connect secure pl061 to gpio-pwr */
69
+{
80
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_RESET,
70
+ return (x & (y ^ z)) ^ z;
81
+ qdev_get_gpio_in_named(gpio_pwr_dev, "reset", 0));
82
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_POWEROFF,
83
+ qdev_get_gpio_in_named(gpio_pwr_dev, "shutdown", 0));
84
+
85
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-poweroff");
86
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "compatible",
87
+ "gpio-poweroff");
88
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-poweroff",
89
+ "gpios", phandle, SECURE_GPIO_POWEROFF, 0);
90
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "status", "disabled");
91
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "secure-status",
92
+ "okay");
93
+
94
+ qemu_fdt_add_subnode(vms->fdt, "/gpio-restart");
95
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "compatible",
96
+ "gpio-restart");
97
+ qemu_fdt_setprop_cells(vms->fdt, "/gpio-restart",
98
+ "gpios", phandle, SECURE_GPIO_RESET, 0);
99
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "status", "disabled");
100
+ qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "secure-status",
101
+ "okay");
71
+}
102
+}
72
+
103
+
73
+static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
104
static void create_gpio_devices(const VirtMachineState *vms, int gpio,
74
+{
105
MemoryRegion *mem)
75
+ return (x & y) | ((x | y) & z);
106
{
76
+}
107
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
77
+
108
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
78
+static uint64_t S0_512(uint64_t x)
109
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
79
+{
110
80
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
111
+ if (gpio != VIRT_GPIO) {
81
+}
112
+ /* Mark as not usable by the normal world */
82
+
113
+ qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
83
+static uint64_t S1_512(uint64_t x)
114
+ qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
84
+{
115
+ }
85
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
116
g_free(nodename);
86
+}
117
87
+
118
/* Child gpio devices */
88
+static uint64_t s0_512(uint64_t x)
119
- create_gpio_keys(vms, pl061_dev, phandle);
89
+{
120
+ if (gpio == VIRT_GPIO) {
90
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
121
+ create_gpio_keys(vms, pl061_dev, phandle);
91
+}
122
+ } else {
92
+
123
+ create_secure_gpio_pwr(vms, pl061_dev, phandle);
93
+static uint64_t s1_512(uint64_t x)
124
+ }
94
+{
95
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
96
+}
97
+
98
+void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
99
+{
100
+ uint64_t *rd = vd;
101
+ uint64_t *rn = vn;
102
+ uint64_t *rm = vm;
103
+ uint64_t d0 = rd[0];
104
+ uint64_t d1 = rd[1];
105
+
106
+ d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
107
+ d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
108
+
109
+ rd[0] = d0;
110
+ rd[1] = d1;
111
+}
112
+
113
+void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
114
+{
115
+ uint64_t *rd = vd;
116
+ uint64_t *rn = vn;
117
+ uint64_t *rm = vm;
118
+ uint64_t d0 = rd[0];
119
+ uint64_t d1 = rd[1];
120
+
121
+ d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
122
+ d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
123
+
124
+ rd[0] = d0;
125
+ rd[1] = d1;
126
+}
127
+
128
+void HELPER(crypto_sha512su0)(void *vd, void *vn)
129
+{
130
+ uint64_t *rd = vd;
131
+ uint64_t *rn = vn;
132
+ uint64_t d0 = rd[0];
133
+ uint64_t d1 = rd[1];
134
+
135
+ d0 += s0_512(rd[1]);
136
+ d1 += s0_512(rn[0]);
137
+
138
+ rd[0] = d0;
139
+ rd[1] = d1;
140
+}
141
+
142
+void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
143
+{
144
+ uint64_t *rd = vd;
145
+ uint64_t *rn = vn;
146
+ uint64_t *rm = vm;
147
+
148
+ rd[0] += s1_512(rn[0]) + rm[0];
149
+ rd[1] += s1_512(rn[1]) + rm[1];
150
+}
151
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate-a64.c
154
+++ b/target/arm/translate-a64.c
155
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
156
tcg_temp_free_ptr(tcg_rn_ptr);
157
}
125
}
158
126
159
+/* Crypto three-reg SHA512
127
static void create_virtio_devices(const VirtMachineState *vms)
160
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
128
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
161
+ * +-----------------------+------+---+---+-----+--------+------+------+
129
create_gpio_devices(vms, VIRT_GPIO, sysmem);
162
+ * | 1 1 0 0 1 1 1 0 0 1 1 | Rm | 1 | O | 0 0 | opcode | Rn | Rd |
130
}
163
+ * +-----------------------+------+---+---+-----+--------+------+------+
131
164
+ */
132
+ if (vms->secure && !vmc->no_secure_gpio) {
165
+static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
133
+ create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
166
+{
167
+ int opcode = extract32(insn, 10, 2);
168
+ int o = extract32(insn, 14, 1);
169
+ int rm = extract32(insn, 16, 5);
170
+ int rn = extract32(insn, 5, 5);
171
+ int rd = extract32(insn, 0, 5);
172
+ int feature;
173
+ CryptoThreeOpFn *genfn;
174
+
175
+ if (o == 0) {
176
+ switch (opcode) {
177
+ case 0: /* SHA512H */
178
+ feature = ARM_FEATURE_V8_SHA512;
179
+ genfn = gen_helper_crypto_sha512h;
180
+ break;
181
+ case 1: /* SHA512H2 */
182
+ feature = ARM_FEATURE_V8_SHA512;
183
+ genfn = gen_helper_crypto_sha512h2;
184
+ break;
185
+ case 2: /* SHA512SU1 */
186
+ feature = ARM_FEATURE_V8_SHA512;
187
+ genfn = gen_helper_crypto_sha512su1;
188
+ break;
189
+ default:
190
+ unallocated_encoding(s);
191
+ return;
192
+ }
193
+ } else {
194
+ unallocated_encoding(s);
195
+ return;
196
+ }
134
+ }
197
+
135
+
198
+ if (!arm_dc_feature(s, feature)) {
136
/* connect powerdown request */
199
+ unallocated_encoding(s);
137
vms->powerdown_notifier.notify = virt_powerdown_req;
200
+ return;
138
qemu_register_powerdown_notifier(&vms->powerdown_notifier);
201
+ }
139
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
140
141
static void virt_machine_5_2_options(MachineClass *mc)
142
{
143
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
202
+
144
+
203
+ if (!fp_access_check(s)) {
145
virt_machine_6_0_options(mc);
204
+ return;
146
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
205
+ }
147
+ vmc->no_secure_gpio = true;
206
+
148
}
207
+ if (genfn) {
149
DEFINE_VIRT_MACHINE(5, 2)
208
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
150
209
+
151
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
210
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
152
index XXXXXXX..XXXXXXX 100644
211
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
153
--- a/hw/arm/Kconfig
212
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
154
+++ b/hw/arm/Kconfig
213
+
155
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
214
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
156
select PL011 # UART
215
+
157
select PL031 # RTC
216
+ tcg_temp_free_ptr(tcg_rd_ptr);
158
select PL061 # GPIO
217
+ tcg_temp_free_ptr(tcg_rn_ptr);
159
+ select GPIO_PWR
218
+ tcg_temp_free_ptr(tcg_rm_ptr);
160
select PLATFORM_BUS
219
+ } else {
161
select SMBIOS
220
+ g_assert_not_reached();
162
select VIRTIO_MMIO
221
+ }
222
+}
223
+
224
+/* Crypto two-reg SHA512
225
+ * 31 12 11 10 9 5 4 0
226
+ * +-----------------------------------------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 | opcode | Rn | Rd |
228
+ * +-----------------------------------------+--------+------+------+
229
+ */
230
+static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int rn = extract32(insn, 5, 5);
234
+ int rd = extract32(insn, 0, 5);
235
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
236
+ int feature;
237
+ CryptoTwoOpFn *genfn;
238
+
239
+ switch (opcode) {
240
+ case 0: /* SHA512SU0 */
241
+ feature = ARM_FEATURE_V8_SHA512;
242
+ genfn = gen_helper_crypto_sha512su0;
243
+ break;
244
+ default:
245
+ unallocated_encoding(s);
246
+ return;
247
+ }
248
+
249
+ if (!arm_dc_feature(s, feature)) {
250
+ unallocated_encoding(s);
251
+ return;
252
+ }
253
+
254
+ if (!fp_access_check(s)) {
255
+ return;
256
+ }
257
+
258
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
259
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
260
+
261
+ genfn(tcg_rd_ptr, tcg_rn_ptr);
262
+
263
+ tcg_temp_free_ptr(tcg_rd_ptr);
264
+ tcg_temp_free_ptr(tcg_rn_ptr);
265
+}
266
+
267
/* C3.6 Data processing - SIMD, inc Crypto
268
*
269
* As the decode gets a little complex we are using a table based
270
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
271
{ 0x4e280800, 0xff3e0c00, disas_crypto_aes },
272
{ 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
273
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
274
+ { 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
275
+ { 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
276
{ 0x00000000, 0x00000000, NULL }
277
};
278
279
--
163
--
280
2.16.1
164
2.20.1
281
165
282
166
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This implements emulation of the new SM3 instructions that have
3
Fix potential overflow problem when calculating pwm_duty.
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
1. Ensure p->cmr and p->cnr to be from [0,65535], according to the
5
in ARM v8.2.
5
hardware specification.
6
2. Changed duty to uint32_t. However, since MAX_DUTY * (p->cmr+1)
7
can excceed UINT32_MAX, we convert them to uint64_t in computation
8
and converted them back to uint32_t.
9
(duty is guaranteed to be <= MAX_DUTY so it won't overflow.)
6
10
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
11
Fixes: CID 1442342
8
Message-id: 20180207111729.15737-4-ard.biesheuvel@linaro.org
12
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Doug Evans <dje@google.com>
14
Signed-off-by: Hao Wu <wuhaotsh@google.com>
15
Message-id: 20210127011142.2122790-1-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
target/arm/cpu.h | 1 +
19
hw/misc/npcm7xx_pwm.c | 23 +++++++++++++++++++----
13
target/arm/helper.h | 4 ++
20
tests/qtest/npcm7xx_pwm-test.c | 4 ++--
14
target/arm/crypto_helper.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
21
2 files changed, 21 insertions(+), 6 deletions(-)
15
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++++++++++++--
16
4 files changed, 186 insertions(+), 3 deletions(-)
17
22
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
25
--- a/hw/misc/npcm7xx_pwm.c
21
+++ b/target/arm/cpu.h
26
+++ b/hw/misc/npcm7xx_pwm.c
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
27
@@ -XXX,XX +XXX,XX @@ REG32(NPCM7XX_PWM_PWDR3, 0x50);
23
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
28
#define NPCM7XX_CH_INV BIT(2)
24
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
29
#define NPCM7XX_CH_MOD BIT(3)
25
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
30
26
+ ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
31
+#define NPCM7XX_MAX_CMR 65535
27
};
32
+#define NPCM7XX_MAX_CNR 65535
28
29
static inline int arm_feature(CPUARMState *env, int feature)
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
33
+++ b/target/arm/helper.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
35
DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
36
DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
38
+DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
39
+DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
41
+
33
+
42
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
34
/* Offset of each PWM channel's prescaler in the PPR register. */
43
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
35
static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
44
DEF_HELPER_2(dc_zva, void, env, i64)
36
/* Offset of each PWM channel's clock selector in the CSR register. */
45
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
37
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p)
46
index XXXXXXX..XXXXXXX 100644
38
47
--- a/target/arm/crypto_helper.c
39
static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
48
+++ b/target/arm/crypto_helper.c
40
{
49
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
41
- uint64_t duty;
50
rd[0] += s1_512(rn[0]) + rm[0];
42
+ uint32_t duty;
51
rd[1] += s1_512(rn[1]) + rm[1];
43
52
}
44
if (p->running) {
53
+
45
if (p->cnr == 0) {
54
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
46
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
55
+{
47
} else if (p->cmr >= p->cnr) {
56
+ uint64_t *rd = vd;
48
duty = NPCM7XX_PWM_MAX_DUTY;
57
+ uint64_t *rn = vn;
49
} else {
58
+ uint64_t *rm = vm;
50
- duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
59
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
51
+ duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
60
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
61
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
62
+ uint32_t t;
63
+
64
+ t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
65
+ CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
66
+
67
+ t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
68
+ CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
69
+
70
+ t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
71
+ CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
72
+
73
+ t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
74
+ CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
75
+
76
+ rd[0] = d.l[0];
77
+ rd[1] = d.l[1];
78
+}
79
+
80
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
81
+{
82
+ uint64_t *rd = vd;
83
+ uint64_t *rn = vn;
84
+ uint64_t *rm = vm;
85
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
86
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
87
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
88
+ uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
89
+
90
+ CR_ST_WORD(d, 0) ^= t;
91
+ CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
92
+ CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
93
+ CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
94
+ ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
95
+
96
+ rd[0] = d.l[0];
97
+ rd[1] = d.l[1];
98
+}
99
+
100
+void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
101
+ uint32_t opcode)
102
+{
103
+ uint64_t *rd = vd;
104
+ uint64_t *rn = vn;
105
+ uint64_t *rm = vm;
106
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
107
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
108
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
109
+ uint32_t t;
110
+
111
+ assert(imm2 < 4);
112
+
113
+ if (opcode == 0 || opcode == 2) {
114
+ /* SM3TT1A, SM3TT2A */
115
+ t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
116
+ } else if (opcode == 1) {
117
+ /* SM3TT1B */
118
+ t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
119
+ } else if (opcode == 3) {
120
+ /* SM3TT2B */
121
+ t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
122
+ } else {
123
+ g_assert_not_reached();
124
+ }
125
+
126
+ t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
127
+
128
+ CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
129
+
130
+ if (opcode < 2) {
131
+ /* SM3TT1A, SM3TT1B */
132
+ t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
133
+
134
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
135
+ } else {
136
+ /* SM3TT2A, SM3TT2B */
137
+ t += CR_ST_WORD(n, 3);
138
+ t ^= rol32(t, 9) ^ rol32(t, 17);
139
+
140
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
141
+ }
142
+
143
+ CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
144
+ CR_ST_WORD(d, 3) = t;
145
+
146
+ rd[0] = d.l[0];
147
+ rd[1] = d.l[1];
148
+}
149
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-a64.c
152
+++ b/target/arm/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
154
break;
155
}
52
}
156
} else {
53
} else {
157
- unallocated_encoding(s);
54
duty = 0;
158
- return;
55
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
159
+ switch (opcode) {
56
case A_NPCM7XX_PWM_CNR2:
160
+ case 0: /* SM3PARTW1 */
57
case A_NPCM7XX_PWM_CNR3:
161
+ feature = ARM_FEATURE_V8_SM3;
58
p = &s->pwm[npcm7xx_cnr_index(offset)];
162
+ genfn = gen_helper_crypto_sm3partw1;
59
- p->cnr = value;
163
+ break;
60
+ if (value > NPCM7XX_MAX_CNR) {
164
+ case 1: /* SM3PARTW2 */
61
+ qemu_log_mask(LOG_GUEST_ERROR,
165
+ feature = ARM_FEATURE_V8_SM3;
62
+ "%s: invalid cnr value: %u", __func__, value);
166
+ genfn = gen_helper_crypto_sm3partw2;
63
+ p->cnr = NPCM7XX_MAX_CNR;
167
+ break;
64
+ } else {
168
+ default:
65
+ p->cnr = value;
169
+ unallocated_encoding(s);
170
+ return;
171
+ }
66
+ }
67
npcm7xx_pwm_update_output(p);
68
break;
69
70
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
71
case A_NPCM7XX_PWM_CMR2:
72
case A_NPCM7XX_PWM_CMR3:
73
p = &s->pwm[npcm7xx_cmr_index(offset)];
74
- p->cmr = value;
75
+ if (value > NPCM7XX_MAX_CMR) {
76
+ qemu_log_mask(LOG_GUEST_ERROR,
77
+ "%s: invalid cmr value: %u", __func__, value);
78
+ p->cmr = NPCM7XX_MAX_CMR;
79
+ } else {
80
+ p->cmr = value;
81
+ }
82
npcm7xx_pwm_update_output(p);
83
break;
84
85
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/tests/qtest/npcm7xx_pwm-test.c
88
+++ b/tests/qtest/npcm7xx_pwm-test.c
89
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
90
91
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
92
{
93
- uint64_t duty;
94
+ uint32_t duty;
95
96
if (cnr == 0) {
97
/* PWM is stopped. */
98
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
99
} else if (cmr >= cnr) {
100
duty = MAX_DUTY;
101
} else {
102
- duty = MAX_DUTY * (cmr + 1) / (cnr + 1);
103
+ duty = (uint64_t)MAX_DUTY * (cmr + 1) / (cnr + 1);
172
}
104
}
173
105
174
if (!arm_dc_feature(s, feature)) {
106
if (inverted) {
175
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
176
case 1: /* BCAX */
177
feature = ARM_FEATURE_V8_SHA3;
178
break;
179
+ case 2: /* SM3SS1 */
180
+ feature = ARM_FEATURE_V8_SM3;
181
+ break;
182
default:
183
unallocated_encoding(s);
184
return;
185
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
186
tcg_temp_free_i64(tcg_res[0]);
187
tcg_temp_free_i64(tcg_res[1]);
188
} else {
189
- g_assert_not_reached();
190
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3, tcg_res, tcg_zero;
191
+
192
+ tcg_op1 = tcg_temp_new_i32();
193
+ tcg_op2 = tcg_temp_new_i32();
194
+ tcg_op3 = tcg_temp_new_i32();
195
+ tcg_res = tcg_temp_new_i32();
196
+ tcg_zero = tcg_const_i32(0);
197
+
198
+ read_vec_element_i32(s, tcg_op1, rn, 3, MO_32);
199
+ read_vec_element_i32(s, tcg_op2, rm, 3, MO_32);
200
+ read_vec_element_i32(s, tcg_op3, ra, 3, MO_32);
201
+
202
+ tcg_gen_rotri_i32(tcg_res, tcg_op1, 20);
203
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op2);
204
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op3);
205
+ tcg_gen_rotri_i32(tcg_res, tcg_res, 25);
206
+
207
+ write_vec_element_i32(s, tcg_zero, rd, 0, MO_32);
208
+ write_vec_element_i32(s, tcg_zero, rd, 1, MO_32);
209
+ write_vec_element_i32(s, tcg_zero, rd, 2, MO_32);
210
+ write_vec_element_i32(s, tcg_res, rd, 3, MO_32);
211
+
212
+ tcg_temp_free_i32(tcg_op1);
213
+ tcg_temp_free_i32(tcg_op2);
214
+ tcg_temp_free_i32(tcg_op3);
215
+ tcg_temp_free_i32(tcg_res);
216
+ tcg_temp_free_i32(tcg_zero);
217
}
218
}
219
220
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
221
tcg_temp_free_i64(tcg_res[1]);
222
}
223
224
+/* Crypto three-reg imm2
225
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
226
+ * +-----------------------+------+-----+------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 0 1 0 | Rm | 1 0 | imm2 | opcode | Rn | Rd |
228
+ * +-----------------------+------+-----+------+--------+------+------+
229
+ */
230
+static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int imm2 = extract32(insn, 12, 2);
234
+ int rm = extract32(insn, 16, 5);
235
+ int rn = extract32(insn, 5, 5);
236
+ int rd = extract32(insn, 0, 5);
237
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
238
+ TCGv_i32 tcg_imm2, tcg_opcode;
239
+
240
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) {
241
+ unallocated_encoding(s);
242
+ return;
243
+ }
244
+
245
+ if (!fp_access_check(s)) {
246
+ return;
247
+ }
248
+
249
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
250
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
251
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
252
+ tcg_imm2 = tcg_const_i32(imm2);
253
+ tcg_opcode = tcg_const_i32(opcode);
254
+
255
+ gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
256
+ tcg_opcode);
257
+
258
+ tcg_temp_free_ptr(tcg_rd_ptr);
259
+ tcg_temp_free_ptr(tcg_rn_ptr);
260
+ tcg_temp_free_ptr(tcg_rm_ptr);
261
+ tcg_temp_free_i32(tcg_imm2);
262
+ tcg_temp_free_i32(tcg_opcode);
263
+}
264
+
265
/* C3.6 Data processing - SIMD, inc Crypto
266
*
267
* As the decode gets a little complex we are using a table based
268
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
269
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
270
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
271
{ 0xce800000, 0xffe00000, disas_crypto_xar },
272
+ { 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
273
{ 0x00000000, 0x00000000, NULL }
274
};
275
276
--
107
--
277
2.16.1
108
2.20.1
278
109
279
110
diff view generated by jsdifflib
1
The memory writes done to push registers on the stack
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
on exception entry in M profile CPUs are supposed to
3
go via MPU permissions checks, which may cause us to
4
take a derived exception instead of the original one of
5
the MPU lookup fails. We were implementing these as
6
always-succeeds direct writes to physical memory.
7
Rewrite v7m_push_stack() to do the necessary checks.
8
2
3
cpu_get_phys_page_debug() uses 'DATA LOAD' MMU access type.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210127232822.3530782-1-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1517324542-6607-5-git-send-email-peter.maydell@linaro.org
12
---
9
---
13
target/arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
10
target/arm/helper.c | 2 +-
14
1 file changed, 87 insertions(+), 16 deletions(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
15
12
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
17
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
21
return target_el;
18
22
}
19
*attrs = (MemTxAttrs) {};
23
20
24
-static void v7m_push(CPUARMState *env, uint32_t val)
21
- ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
25
+static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
22
+ ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
26
+ ARMMMUIdx mmu_idx, bool ignfault)
23
attrs, &prot, &page_size, &fi, &cacheattrs);
27
{
24
28
- CPUState *cs = CPU(arm_env_get_cpu(env));
25
if (ret) {
29
+ CPUState *cs = CPU(cpu);
30
+ CPUARMState *env = &cpu->env;
31
+ MemTxAttrs attrs = {};
32
+ MemTxResult txres;
33
+ target_ulong page_size;
34
+ hwaddr physaddr;
35
+ int prot;
36
+ ARMMMUFaultInfo fi;
37
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
38
+ int exc;
39
+ bool exc_secure;
40
41
- env->regs[13] -= 4;
42
- stl_phys(cs->as, env->regs[13], val);
43
+ if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &physaddr,
44
+ &attrs, &prot, &page_size, &fi, NULL)) {
45
+ /* MPU/SAU lookup failed */
46
+ if (fi.type == ARMFault_QEMU_SFault) {
47
+ qemu_log_mask(CPU_LOG_INT,
48
+ "...SecureFault with SFSR.AUVIOL during stacking\n");
49
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
50
+ env->v7m.sfar = addr;
51
+ exc = ARMV7M_EXCP_SECURE;
52
+ exc_secure = false;
53
+ } else {
54
+ qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
55
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
56
+ exc = ARMV7M_EXCP_MEM;
57
+ exc_secure = secure;
58
+ }
59
+ goto pend_fault;
60
+ }
61
+ address_space_stl_le(arm_addressspace(cs, attrs), physaddr, value,
62
+ attrs, &txres);
63
+ if (txres != MEMTX_OK) {
64
+ /* BusFault trying to write the data */
65
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
66
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
67
+ exc = ARMV7M_EXCP_BUS;
68
+ exc_secure = false;
69
+ goto pend_fault;
70
+ }
71
+ return true;
72
+
73
+pend_fault:
74
+ /* By pending the exception at this point we are making
75
+ * the IMPDEF choice "overridden exceptions pended" (see the
76
+ * MergeExcInfo() pseudocode). The other choice would be to not
77
+ * pend them now and then make a choice about which to throw away
78
+ * later if we have two derived exceptions.
79
+ * The only case when we must not pend the exception but instead
80
+ * throw it away is if we are doing the push of the callee registers
81
+ * and we've already generated a derived exception. Even in this
82
+ * case we will still update the fault status registers.
83
+ */
84
+ if (!ignfault) {
85
+ armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
86
+ }
87
+ return false;
88
}
89
90
/* Return true if we're using the process stack pointer (not the MSP) */
91
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
92
* should ignore further stack faults trying to process
93
* that derived exception.)
94
*/
95
+ bool stacked_ok;
96
CPUARMState *env = &cpu->env;
97
uint32_t xpsr = xpsr_read(env);
98
+ uint32_t frameptr = env->regs[13];
99
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
100
101
/* Align stack pointer if the guest wants that */
102
- if ((env->regs[13] & 4) &&
103
+ if ((frameptr & 4) &&
104
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
105
- env->regs[13] -= 4;
106
+ frameptr -= 4;
107
xpsr |= XPSR_SPREALIGN;
108
}
109
- /* Switch to the handler mode. */
110
- v7m_push(env, xpsr);
111
- v7m_push(env, env->regs[15]);
112
- v7m_push(env, env->regs[14]);
113
- v7m_push(env, env->regs[12]);
114
- v7m_push(env, env->regs[3]);
115
- v7m_push(env, env->regs[2]);
116
- v7m_push(env, env->regs[1]);
117
- v7m_push(env, env->regs[0]);
118
119
- return false;
120
+ frameptr -= 0x20;
121
+
122
+ /* Write as much of the stack frame as we can. If we fail a stack
123
+ * write this will result in a derived exception being pended
124
+ * (which may be taken in preference to the one we started with
125
+ * if it has higher priority).
126
+ */
127
+ stacked_ok =
128
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
129
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
130
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
131
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
132
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
133
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
134
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
135
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
136
+
137
+ /* Update SP regardless of whether any of the stack accesses failed.
138
+ * When we implement v8M stack limit checking then this attempt to
139
+ * update SP might also fail and result in a derived exception.
140
+ */
141
+ env->regs[13] = frameptr;
142
+
143
+ return !stacked_ok;
144
}
145
146
static void do_v7m_exception_exit(ARMCPU *cpu)
147
--
26
--
148
2.16.1
27
2.20.1
149
28
150
29
diff view generated by jsdifflib
New patch
1
Move the preadv availability check to meson.build. This is what we
2
want to be doing for host-OS-feature-checks anyway, but it also fixes
3
a problem with building for macOS with the most recent XCode SDK on a
4
Catalina host.
1
5
6
On that configuration, 'preadv()' is provided as a weak symbol, so
7
that programs can be built with optional support for it and make a
8
runtime availability check to see whether the preadv() they have is a
9
working one or one which they must not call because it will
10
runtime-assert. QEMU's configure test passes (unless you're building
11
with --enable-werror) because the test program using preadv()
12
compiles, but then QEMU crashes at runtime when preadv() is called,
13
with errors like:
14
15
dyld: lazy symbol binding failed: Symbol not found: _preadv
16
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
17
Expected in: /usr/lib/libSystem.B.dylib
18
19
dyld: Symbol not found: _preadv
20
Referenced from: /Users/pm215/src/qemu/./build/x86/tests/test-replication
21
Expected in: /usr/lib/libSystem.B.dylib
22
23
Meson's own function availability check has a special case for macOS
24
which adds '-Wl,-no_weak_imports' to the compiler flags, which forces
25
the test to require the real function, not the macOS-version-too-old
26
stub.
27
28
So this commit fixes the bug where macOS builds on Catalina currently
29
require --disable-werror.
30
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
33
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
34
Message-id: 20210126155846.17109-1-peter.maydell@linaro.org
35
---
36
configure | 16 ----------------
37
meson.build | 4 +++-
38
2 files changed, 3 insertions(+), 17 deletions(-)
39
40
diff --git a/configure b/configure
41
index XXXXXXX..XXXXXXX 100755
42
--- a/configure
43
+++ b/configure
44
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
45
iovec=yes
46
fi
47
48
-##########################################
49
-# preadv probe
50
-cat > $TMPC <<EOF
51
-#include <sys/types.h>
52
-#include <sys/uio.h>
53
-#include <unistd.h>
54
-int main(void) { return preadv(0, 0, 0, 0); }
55
-EOF
56
-preadv=no
57
-if compile_prog "" "" ; then
58
- preadv=yes
59
-fi
60
-
61
##########################################
62
# fdt probe
63
64
@@ -XXX,XX +XXX,XX @@ fi
65
if test "$iovec" = "yes" ; then
66
echo "CONFIG_IOVEC=y" >> $config_host_mak
67
fi
68
-if test "$preadv" = "yes" ; then
69
- echo "CONFIG_PREADV=y" >> $config_host_mak
70
-fi
71
if test "$membarrier" = "yes" ; then
72
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
73
fi
74
diff --git a/meson.build b/meson.build
75
index XXXXXXX..XXXXXXX 100644
76
--- a/meson.build
77
+++ b/meson.build
78
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
79
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
80
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
81
82
+config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
83
+
84
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
85
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
86
strings = ['HOST_DSOSUF', 'CONFIG_IASL']
87
@@ -XXX,XX +XXX,XX @@ summary_info += {'PIE': get_option('b_pie')}
88
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
89
summary_info += {'malloc trim support': has_malloc_trim}
90
summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
91
-summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
92
+summary_info += {'preadv support': config_host_data.get('CONFIG_PREADV')}
93
summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
94
summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
95
summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
96
--
97
2.20.1
98
99
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
The iOS toolchain does not use the host prefix naming convention. So we
4
need to enable cross-compile options while allowing the PREFIX to be
5
blank.
6
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Joelle van Dyne <j@getutm.app>
9
Message-id: 20210126012457.39046-3-j@getutm.app
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
configure | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/configure b/configure
16
index XXXXXXX..XXXXXXX 100755
17
--- a/configure
18
+++ b/configure
19
@@ -XXX,XX +XXX,XX @@ cpu=""
20
iasl="iasl"
21
interp_prefix="/usr/gnemul/qemu-%M"
22
static="no"
23
+cross_compile="no"
24
cross_prefix=""
25
audio_drv_list=""
26
block_drv_rw_whitelist=""
27
@@ -XXX,XX +XXX,XX @@ for opt do
28
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
29
case "$opt" in
30
--cross-prefix=*) cross_prefix="$optarg"
31
+ cross_compile="yes"
32
;;
33
--cc=*) CC="$optarg"
34
;;
35
@@ -XXX,XX +XXX,XX @@ $(echo Deprecated targets: $deprecated_targets_list | \
36
--target-list-exclude=LIST exclude a set of targets from the default target-list
37
38
Advanced options (experts only):
39
- --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
40
+ --cross-prefix=PREFIX use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
41
--cc=CC use C compiler CC [$cc]
42
--iasl=IASL use ACPI compiler IASL [$iasl]
43
--host-cc=CC use C compiler CC [$host_cc] for code run at
44
@@ -XXX,XX +XXX,XX @@ if has $sdl2_config; then
45
fi
46
echo "strip = [$(meson_quote $strip)]" >> $cross
47
echo "windres = [$(meson_quote $windres)]" >> $cross
48
-if test -n "$cross_prefix"; then
49
+if test "$cross_compile" = "yes"; then
50
cross_arg="--cross-file config-meson.cross"
51
echo "[host_machine]" >> $cross
52
if test "$mingw32" = "yes" ; then
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
Build without error on hosts without a working system(). If system()
4
is called, return -1 with ENOSYS.
5
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Message-id: 20210126012457.39046-6-j@getutm.app
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
meson.build | 1 +
12
include/qemu/osdep.h | 12 ++++++++++++
13
2 files changed, 13 insertions(+)
14
15
diff --git a/meson.build b/meson.build
16
index XXXXXXX..XXXXXXX 100644
17
--- a/meson.build
18
+++ b/meson.build
19
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
20
config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
21
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
22
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
23
+config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
24
25
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
26
27
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/qemu/osdep.h
30
+++ b/include/qemu/osdep.h
31
@@ -XXX,XX +XXX,XX @@ static inline void qemu_thread_jit_write(void) {}
32
static inline void qemu_thread_jit_execute(void) {}
33
#endif
34
35
+/**
36
+ * Platforms which do not support system() return ENOSYS
37
+ */
38
+#ifndef HAVE_SYSTEM_FUNCTION
39
+#define system platform_does_not_support_system
40
+static inline int platform_does_not_support_system(const char *command)
41
+{
42
+ errno = ENOSYS;
43
+ return -1;
44
+}
45
+#endif /* !HAVE_SYSTEM_FUNCTION */
46
+
47
#endif
48
--
49
2.20.1
50
51
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
Meson will find CoreFoundation, IOKit, and Cocoa as needed.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Message-id: 20210126012457.39046-7-j@getutm.app
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
configure | 1 -
11
1 file changed, 1 deletion(-)
12
13
diff --git a/configure b/configure
14
index XXXXXXX..XXXXXXX 100755
15
--- a/configure
16
+++ b/configure
17
@@ -XXX,XX +XXX,XX @@ Darwin)
18
fi
19
audio_drv_list="coreaudio try-sdl"
20
audio_possible_drivers="coreaudio sdl"
21
- QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
22
# Disable attempts to use ObjectiveC features in os/object.h since they
23
# won't work when we're compiling with gcc as a C compiler.
24
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
From: Christoffer Dall <christoffer.dall@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
KVM doesn't support emulating a GICv3 in userspace, only GICv2. We
3
Add objc to the Meson cross file as well as detection of Darwin.
4
currently attempt this anyway, and as a result a KVM guest doesn't
5
receive interrupts and the user is left wondering why. Report an error
6
to the user if this particular combination is requested.
7
4
8
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20180201205307.30343-1-christoffer.dall@linaro.org
8
Message-id: 20210126012457.39046-8-j@getutm.app
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/kvm_arm.h | 4 ++++
11
configure | 4 ++++
14
1 file changed, 4 insertions(+)
12
1 file changed, 4 insertions(+)
15
13
16
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
14
diff --git a/configure b/configure
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100755
18
--- a/target/arm/kvm_arm.h
16
--- a/configure
19
+++ b/target/arm/kvm_arm.h
17
+++ b/configure
20
@@ -XXX,XX +XXX,XX @@ static inline const char *gicv3_class_name(void)
18
@@ -XXX,XX +XXX,XX @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
21
exit(1);
19
echo "[binaries]" >> $cross
22
#endif
20
echo "c = [$(meson_quote $cc)]" >> $cross
23
} else {
21
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
24
+ if (kvm_enabled()) {
22
+test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
25
+ error_report("Userspace GICv3 is not supported with KVM");
23
echo "ar = [$(meson_quote $ar)]" >> $cross
26
+ exit(1);
24
echo "nm = [$(meson_quote $nm)]" >> $cross
27
+ }
25
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
28
return "arm-gicv3";
26
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
29
}
27
if test "$linux" = "yes" ; then
30
}
28
echo "system = 'linux'" >> $cross
29
fi
30
+ if test "$darwin" = "yes" ; then
31
+ echo "system = 'darwin'" >> $cross
32
+ fi
33
case "$ARCH" in
34
i386|x86_64)
35
echo "cpu_family = 'x86'" >> $cross
31
--
36
--
32
2.16.1
37
2.20.1
33
38
34
39
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Signed-off-by: Joelle van Dyne <j@getutm.app>
5
Message-id: 20210126012457.39046-9-j@getutm.app
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
configure | 5 ++++-
9
1 file changed, 4 insertions(+), 1 deletion(-)
10
11
diff --git a/configure b/configure
12
index XXXXXXX..XXXXXXX 100755
13
--- a/configure
14
+++ b/configure
15
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
16
echo "system = 'darwin'" >> $cross
17
fi
18
case "$ARCH" in
19
- i386|x86_64)
20
+ i386)
21
echo "cpu_family = 'x86'" >> $cross
22
;;
23
+ x86_64)
24
+ echo "cpu_family = 'x86_64'" >> $cross
25
+ ;;
26
ppc64le)
27
echo "cpu_family = 'ppc64'" >> $cross
28
;;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
On iOS there is no CoreAudio, so we should not assume Darwin always
4
has it.
5
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210126012457.39046-11-j@getutm.app
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
configure | 35 +++++++++++++++++++++++++++++++++--
12
1 file changed, 33 insertions(+), 2 deletions(-)
13
14
diff --git a/configure b/configure
15
index XXXXXXX..XXXXXXX 100755
16
--- a/configure
17
+++ b/configure
18
@@ -XXX,XX +XXX,XX @@ fdt="auto"
19
netmap="no"
20
sdl="auto"
21
sdl_image="auto"
22
+coreaudio="auto"
23
virtiofsd="auto"
24
virtfs="auto"
25
libudev="auto"
26
@@ -XXX,XX +XXX,XX @@ Darwin)
27
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
28
QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
29
fi
30
- audio_drv_list="coreaudio try-sdl"
31
+ audio_drv_list="try-coreaudio try-sdl"
32
audio_possible_drivers="coreaudio sdl"
33
# Disable attempts to use ObjectiveC features in os/object.h since they
34
# won't work when we're compiling with gcc as a C compiler.
35
@@ -XXX,XX +XXX,XX @@ EOF
36
fi
37
fi
38
39
+##########################################
40
+# detect CoreAudio
41
+if test "$coreaudio" != "no" ; then
42
+ coreaudio_libs="-framework CoreAudio"
43
+ cat > $TMPC << EOF
44
+#include <CoreAudio/CoreAudio.h>
45
+int main(void)
46
+{
47
+ return (int)AudioGetCurrentHostTime();
48
+}
49
+EOF
50
+ if compile_prog "" "$coreaudio_libs" ; then
51
+ coreaudio=yes
52
+ else
53
+ coreaudio=no
54
+ fi
55
+fi
56
+
57
##########################################
58
# Sound support libraries probe
59
60
@@ -XXX,XX +XXX,XX @@ for drv in $audio_drv_list; do
61
fi
62
;;
63
64
- coreaudio)
65
+ coreaudio | try-coreaudio)
66
+ if test "$coreaudio" = "no"; then
67
+ if test "$drv" = "try-coreaudio"; then
68
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio//')
69
+ else
70
+ error_exit "$drv check failed" \
71
+ "Make sure to have the $drv is available."
72
+ fi
73
+ else
74
coreaudio_libs="-framework CoreAudio"
75
+ if test "$drv" = "try-coreaudio"; then
76
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio/coreaudio/')
77
+ fi
78
+ fi
79
;;
80
81
dsound)
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
A workaround added in early days of 64-bit OSX forced x86_64 if the
4
host machine had 64-bit support. This creates issues when cross-
5
compiling for ARM64. Additionally, the user can always use --cpu=* to
6
manually set the host CPU and therefore this workaround should be
7
removed.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
11
Message-id: 20210126012457.39046-12-j@getutm.app
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
configure | 11 -----------
15
1 file changed, 11 deletions(-)
16
17
diff --git a/configure b/configure
18
index XXXXXXX..XXXXXXX 100755
19
--- a/configure
20
+++ b/configure
21
@@ -XXX,XX +XXX,XX @@ fi
22
# the correct CPU with the --cpu option.
23
case $targetos in
24
Darwin)
25
- # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
26
- # run 64-bit userspace code.
27
- # If the user didn't specify a CPU explicitly and the kernel says this is
28
- # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
29
- if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
30
- cpu="x86_64"
31
- fi
32
HOST_DSOSUF=".dylib"
33
;;
34
SunOS)
35
@@ -XXX,XX +XXX,XX @@ OpenBSD)
36
Darwin)
37
bsd="yes"
38
darwin="yes"
39
- if [ "$cpu" = "x86_64" ] ; then
40
- QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
41
- QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
42
- fi
43
audio_drv_list="try-coreaudio try-sdl"
44
audio_possible_drivers="coreaudio sdl"
45
# Disable attempts to use ObjectiveC features in os/object.h since they
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
From: Alexander Graf <agraf@csgraf.de>
1
2
3
In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
4
respective entitlement. Add an entitlement template and automatically self
5
sign and apply the entitlement in the build.
6
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
meson.build | 29 +++++++++++++++++++++++++----
13
accel/hvf/entitlements.plist | 8 ++++++++
14
scripts/entitlement.sh | 13 +++++++++++++
15
3 files changed, 46 insertions(+), 4 deletions(-)
16
create mode 100644 accel/hvf/entitlements.plist
17
create mode 100755 scripts/entitlement.sh
18
19
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
21
--- a/meson.build
22
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
24
}]
25
endif
26
foreach exe: execs
27
- emulators += {exe['name']:
28
- executable(exe['name'], exe['sources'],
29
- install: true,
30
+ exe_name = exe['name']
31
+ exe_sign = 'CONFIG_HVF' in config_target
32
+ if exe_sign
33
+ exe_name += '-unsigned'
34
+ endif
35
+
36
+ emulator = executable(exe_name, exe['sources'],
37
+ install: not exe_sign,
38
c_args: c_args,
39
dependencies: arch_deps + deps + exe['dependencies'],
40
objects: lib.extract_all_objects(recursive: true),
41
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
42
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
43
link_args: link_args,
44
gui_app: exe['gui'])
45
- }
46
+
47
+ if exe_sign
48
+ emulators += {exe['name'] : custom_target(exe['name'],
49
+ install: true,
50
+ install_dir: get_option('bindir'),
51
+ depends: emulator,
52
+ output: exe['name'],
53
+ command: [
54
+ meson.current_source_dir() / 'scripts/entitlement.sh',
55
+ meson.current_build_dir() / exe_name,
56
+ meson.current_build_dir() / exe['name'],
57
+ meson.current_source_dir() / 'accel/hvf/entitlements.plist'
58
+ ])
59
+ }
60
+ else
61
+ emulators += {exe['name']: emulator}
62
+ endif
63
64
if 'CONFIG_TRACE_SYSTEMTAP' in config_host
65
foreach stp: [
66
diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
67
new file mode 100644
68
index XXXXXXX..XXXXXXX
69
--- /dev/null
70
+++ b/accel/hvf/entitlements.plist
71
@@ -XXX,XX +XXX,XX @@
72
+<?xml version="1.0" encoding="UTF-8"?>
73
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
74
+<plist version="1.0">
75
+<dict>
76
+ <key>com.apple.security.hypervisor</key>
77
+ <true/>
78
+</dict>
79
+</plist>
80
diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
81
new file mode 100755
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/scripts/entitlement.sh
85
@@ -XXX,XX +XXX,XX @@
86
+#!/bin/sh -e
87
+#
88
+# Helper script for the build process to apply entitlements
89
+
90
+SRC="$1"
91
+DST="$2"
92
+ENTITLEMENT="$3"
93
+
94
+trap 'rm "$DST.tmp"' exit
95
+cp -af "$SRC" "$DST.tmp"
96
+codesign --entitlements "$ENTITLEMENT" --force -s - "$DST.tmp"
97
+mv "$DST.tmp" "$DST"
98
+trap '' exit
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
To ease the PCI device addition in next patches, split the code as follows:
4
4
- generic code (read/write/setup) is being kept in pvpanic.c
5
Cc: Peter Maydell <peter.maydell@linaro.org>
5
- ISA dependent code moved to pvpanic-isa.c
6
Cc: Jason Wang <jasowang@redhat.com>
6
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Also, rename:
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
8
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
9
Cc: Michael S. Tsirkin <mst@redhat.com>
9
- TYPE_PVPANIC -> TYPE_PVPANIC_ISA.
10
Cc: qemu-devel@nongnu.org
10
- MemoryRegion io -> mr.
11
Cc: qemu-arm@nongnu.org
11
- pvpanic_ioport_* in pvpanic_*.
12
Cc: yurovsky@gmail.com
12
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Update the build system with the new files and config structure.
14
15
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
---
18
hw/misc/Makefile.objs | 1 +
19
include/hw/misc/pvpanic.h | 23 +++++++++-
19
include/hw/misc/imx7_gpr.h | 28 ++++++++++
20
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++++++++++++++++++++++++
20
hw/misc/imx7_gpr.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
21
hw/misc/pvpanic.c | 85 +++--------------------------------
21
hw/misc/trace-events | 4 ++
22
hw/i386/Kconfig | 2 +-
22
4 files changed, 157 insertions(+)
23
hw/misc/Kconfig | 6 ++-
23
create mode 100644 include/hw/misc/imx7_gpr.h
24
hw/misc/meson.build | 3 +-
24
create mode 100644 hw/misc/imx7_gpr.c
25
tests/qtest/meson.build | 2 +-
25
26
7 files changed, 130 insertions(+), 85 deletions(-)
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
create mode 100644 hw/misc/pvpanic-isa.c
27
index XXXXXXX..XXXXXXX 100644
28
28
--- a/hw/misc/Makefile.objs
29
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
29
+++ b/hw/misc/Makefile.objs
30
index XXXXXXX..XXXXXXX 100644
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_src.o
31
--- a/include/hw/misc/pvpanic.h
31
obj-$(CONFIG_IMX) += imx7_ccm.o
32
+++ b/include/hw/misc/pvpanic.h
32
obj-$(CONFIG_IMX) += imx2_wdt.o
33
@@ -XXX,XX +XXX,XX @@
33
obj-$(CONFIG_IMX) += imx7_snvs.o
34
34
+obj-$(CONFIG_IMX) += imx7_gpr.o
35
#include "qom/object.h"
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
36
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
37
-#define TYPE_PVPANIC "pvpanic"
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
38
+#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
38
diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h
39
40
#define PVPANIC_IOPORT_PROP "ioport"
41
42
+/* The bit of supported pv event, TODO: include uapi header and remove this */
43
+#define PVPANIC_F_PANICKED 0
44
+#define PVPANIC_F_CRASHLOADED 1
45
+
46
+/* The pv event value */
47
+#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
48
+#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
49
+
50
+/*
51
+ * PVPanicState for any device type
52
+ */
53
+typedef struct PVPanicState PVPanicState;
54
+struct PVPanicState {
55
+ MemoryRegion mr;
56
+ uint8_t events;
57
+};
58
+
59
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size);
60
+
61
static inline uint16_t pvpanic_port(void)
62
{
63
- Object *o = object_resolve_path_type("", TYPE_PVPANIC, NULL);
64
+ Object *o = object_resolve_path_type("", TYPE_PVPANIC_ISA_DEVICE, NULL);
65
if (!o) {
66
return 0;
67
}
68
diff --git a/hw/misc/pvpanic-isa.c b/hw/misc/pvpanic-isa.c
39
new file mode 100644
69
new file mode 100644
40
index XXXXXXX..XXXXXXX
70
index XXXXXXX..XXXXXXX
41
--- /dev/null
71
--- /dev/null
42
+++ b/include/hw/misc/imx7_gpr.h
72
+++ b/hw/misc/pvpanic-isa.c
43
@@ -XXX,XX +XXX,XX @@
73
@@ -XXX,XX +XXX,XX @@
44
+/*
74
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
75
+ * QEMU simulated pvpanic device.
46
+ *
76
+ *
47
+ * i.MX7 GPR IP block emulation code
77
+ * Copyright Fujitsu, Corp. 2013
48
+ *
78
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
79
+ * Authors:
50
+ *
80
+ * Wen Congyang <wency@cn.fujitsu.com>
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
81
+ * Hu Tao <hutao@cn.fujitsu.com>
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef IMX7_GPR_H
56
+#define IMX7_GPR_H
57
+
58
+#include "qemu/bitops.h"
59
+#include "hw/sysbus.h"
60
+
61
+#define TYPE_IMX7_GPR "imx7.gpr"
62
+#define IMX7_GPR(obj) OBJECT_CHECK(IMX7GPRState, (obj), TYPE_IMX7_GPR)
63
+
64
+typedef struct IMX7GPRState {
65
+ /* <private> */
66
+ SysBusDevice parent_obj;
67
+
68
+ MemoryRegion mmio;
69
+} IMX7GPRState;
70
+
71
+#endif /* IMX7_GPR_H */
72
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/misc/imx7_gpr.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * Copyright (c) 2018, Impinj, Inc.
80
+ *
81
+ * i.MX7 GPR IP block emulation code
82
+ *
83
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
84
+ *
82
+ *
85
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
86
+ * See the COPYING file in the top-level directory.
84
+ * See the COPYING file in the top-level directory.
87
+ *
85
+ *
88
+ * Bare minimum emulation code needed to support being able to shut
89
+ * down linux guest gracefully.
90
+ */
86
+ */
91
+
87
+
92
+#include "qemu/osdep.h"
88
+#include "qemu/osdep.h"
93
+#include "hw/misc/imx7_gpr.h"
94
+#include "qemu/log.h"
89
+#include "qemu/log.h"
95
+#include "sysemu/sysemu.h"
90
+#include "qemu/module.h"
96
+
91
+#include "sysemu/runstate.h"
97
+#include "trace.h"
92
+
98
+
93
+#include "hw/nvram/fw_cfg.h"
99
+enum IMX7GPRRegisters {
94
+#include "hw/qdev-properties.h"
100
+ IOMUXC_GPR0 = 0x00,
95
+#include "hw/misc/pvpanic.h"
101
+ IOMUXC_GPR1 = 0x04,
96
+#include "qom/object.h"
102
+ IOMUXC_GPR2 = 0x08,
97
+#include "hw/isa/isa.h"
103
+ IOMUXC_GPR3 = 0x0c,
98
+
104
+ IOMUXC_GPR4 = 0x10,
99
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE)
105
+ IOMUXC_GPR5 = 0x14,
100
+
106
+ IOMUXC_GPR6 = 0x18,
101
+/*
107
+ IOMUXC_GPR7 = 0x1c,
102
+ * PVPanicISAState for ISA device and
108
+ IOMUXC_GPR8 = 0x20,
103
+ * use ioport.
109
+ IOMUXC_GPR9 = 0x24,
104
+ */
110
+ IOMUXC_GPR10 = 0x28,
105
+struct PVPanicISAState {
111
+ IOMUXC_GPR11 = 0x2c,
106
+ ISADevice parent_obj;
112
+ IOMUXC_GPR12 = 0x30,
107
+
113
+ IOMUXC_GPR13 = 0x34,
108
+ uint16_t ioport;
114
+ IOMUXC_GPR14 = 0x38,
109
+ PVPanicState pvpanic;
115
+ IOMUXC_GPR15 = 0x3c,
116
+ IOMUXC_GPR16 = 0x40,
117
+ IOMUXC_GPR17 = 0x44,
118
+ IOMUXC_GPR18 = 0x48,
119
+ IOMUXC_GPR19 = 0x4c,
120
+ IOMUXC_GPR20 = 0x50,
121
+ IOMUXC_GPR21 = 0x54,
122
+ IOMUXC_GPR22 = 0x58,
123
+};
110
+};
124
+
111
+
125
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
112
+static void pvpanic_isa_initfn(Object *obj)
126
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK BIT(13)
127
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK BIT(14)
128
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
129
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK BIT(17)
130
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK BIT(18)
131
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK (0x3 << 17)
132
+
133
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
134
+#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
135
+#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
136
+
137
+
138
+static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
139
+{
113
+{
140
+ trace_imx7_gpr_read(offset);
114
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
141
+
115
+
142
+ if (offset == IOMUXC_GPR22) {
116
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 1);
143
+ return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
117
+}
118
+
119
+static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
120
+{
121
+ ISADevice *d = ISA_DEVICE(dev);
122
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(dev);
123
+ PVPanicState *ps = &s->pvpanic;
124
+ FWCfgState *fw_cfg = fw_cfg_find();
125
+ uint16_t *pvpanic_port;
126
+
127
+ if (!fw_cfg) {
128
+ return;
144
+ }
129
+ }
145
+
130
+
146
+ return 0;
131
+ pvpanic_port = g_malloc(sizeof(*pvpanic_port));
132
+ *pvpanic_port = cpu_to_le16(s->ioport);
133
+ fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
134
+ sizeof(*pvpanic_port));
135
+
136
+ isa_register_ioport(d, &ps->mr, s->ioport);
147
+}
137
+}
148
+
138
+
149
+static void imx7_gpr_write(void *opaque, hwaddr offset,
139
+static Property pvpanic_isa_properties[] = {
150
+ uint64_t v, unsigned size)
140
+ DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
151
+{
141
+ DEFINE_PROP_UINT8("events", PVPanicISAState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
152
+ trace_imx7_gpr_write(offset, v);
142
+ DEFINE_PROP_END_OF_LIST(),
153
+}
154
+
155
+static const struct MemoryRegionOps imx7_gpr_ops = {
156
+ .read = imx7_gpr_read,
157
+ .write = imx7_gpr_write,
158
+ .endianness = DEVICE_NATIVE_ENDIAN,
159
+ .impl = {
160
+ /*
161
+ * Our device would not work correctly if the guest was doing
162
+ * unaligned access. This might not be a limitation on the
163
+ * real device but in practice there is no reason for a guest
164
+ * to access this device unaligned.
165
+ */
166
+ .min_access_size = 4,
167
+ .max_access_size = 4,
168
+ .unaligned = false,
169
+ },
170
+};
143
+};
171
+
144
+
172
+static void imx7_gpr_init(Object *obj)
145
+static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
173
+{
174
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
175
+ IMX7GPRState *s = IMX7_GPR(obj);
176
+
177
+ memory_region_init_io(&s->mmio, obj, &imx7_gpr_ops, s,
178
+ TYPE_IMX7_GPR, 64 * 1024);
179
+ sysbus_init_mmio(sd, &s->mmio);
180
+}
181
+
182
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
183
+{
146
+{
184
+ DeviceClass *dc = DEVICE_CLASS(klass);
147
+ DeviceClass *dc = DEVICE_CLASS(klass);
185
+
148
+
186
+ dc->desc = "i.MX7 General Purpose Registers Module";
149
+ dc->realize = pvpanic_isa_realizefn;
150
+ device_class_set_props(dc, pvpanic_isa_properties);
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
187
+}
152
+}
188
+
153
+
189
+static const TypeInfo imx7_gpr_info = {
154
+static TypeInfo pvpanic_isa_info = {
190
+ .name = TYPE_IMX7_GPR,
155
+ .name = TYPE_PVPANIC_ISA_DEVICE,
191
+ .parent = TYPE_SYS_BUS_DEVICE,
156
+ .parent = TYPE_ISA_DEVICE,
192
+ .instance_size = sizeof(IMX7GPRState),
157
+ .instance_size = sizeof(PVPanicISAState),
193
+ .instance_init = imx7_gpr_init,
158
+ .instance_init = pvpanic_isa_initfn,
194
+ .class_init = imx7_gpr_class_init,
159
+ .class_init = pvpanic_isa_class_init,
195
+};
160
+};
196
+
161
+
197
+static void imx7_gpr_register_type(void)
162
+static void pvpanic_register_types(void)
198
+{
163
+{
199
+ type_register_static(&imx7_gpr_info);
164
+ type_register_static(&pvpanic_isa_info);
200
+}
165
+}
201
+type_init(imx7_gpr_register_type)
166
+
202
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
167
+type_init(pvpanic_register_types)
203
index XXXXXXX..XXXXXXX 100644
168
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
204
--- a/hw/misc/trace-events
169
index XXXXXXX..XXXXXXX 100644
205
+++ b/hw/misc/trace-events
170
--- a/hw/misc/pvpanic.c
206
@@ -XXX,XX +XXX,XX @@ mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC
171
+++ b/hw/misc/pvpanic.c
207
msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg write: addr 0x%08" HWADDR_PRIx " data 0x%" PRIx32 " prev 0x%" PRIx32
172
@@ -XXX,XX +XXX,XX @@
208
msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32
173
#include "hw/misc/pvpanic.h"
209
msf2_sysreg_write_pll_status(void) "Invalid write to read only PLL status register"
174
#include "qom/object.h"
210
+
175
211
+#hw/misc/imx7_gpr.c
176
-/* The bit of supported pv event, TODO: include uapi header and remove this */
212
+imx7_gpr_read(uint64_t offset) "addr 0x%08" HWADDR_PRIx
177
-#define PVPANIC_F_PANICKED 0
213
+imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" HWADDR_PRIx "value 0x%08" HWADDR_PRIx
178
-#define PVPANIC_F_CRASHLOADED 1
179
-
180
-/* The pv event value */
181
-#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
182
-#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
183
-
184
-typedef struct PVPanicState PVPanicState;
185
-DECLARE_INSTANCE_CHECKER(PVPanicState, ISA_PVPANIC_DEVICE,
186
- TYPE_PVPANIC)
187
-
188
static void handle_event(int event)
189
{
190
static bool logged;
191
@@ -XXX,XX +XXX,XX @@ static void handle_event(int event)
192
}
193
}
194
195
-#include "hw/isa/isa.h"
196
-
197
-struct PVPanicState {
198
- ISADevice parent_obj;
199
-
200
- MemoryRegion io;
201
- uint16_t ioport;
202
- uint8_t events;
203
-};
204
-
205
/* return supported events on read */
206
-static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
207
+static uint64_t pvpanic_read(void *opaque, hwaddr addr, unsigned size)
208
{
209
PVPanicState *pvp = opaque;
210
return pvp->events;
211
}
212
213
-static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
214
+static void pvpanic_write(void *opaque, hwaddr addr, uint64_t val,
215
unsigned size)
216
{
217
handle_event(val);
218
}
219
220
static const MemoryRegionOps pvpanic_ops = {
221
- .read = pvpanic_ioport_read,
222
- .write = pvpanic_ioport_write,
223
+ .read = pvpanic_read,
224
+ .write = pvpanic_write,
225
.impl = {
226
.min_access_size = 1,
227
.max_access_size = 1,
228
},
229
};
230
231
-static void pvpanic_isa_initfn(Object *obj)
232
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size)
233
{
234
- PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
235
-
236
- memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
237
+ memory_region_init_io(&s->mr, OBJECT(dev), &pvpanic_ops, s, "pvpanic", size);
238
}
239
-
240
-static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
241
-{
242
- ISADevice *d = ISA_DEVICE(dev);
243
- PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
244
- FWCfgState *fw_cfg = fw_cfg_find();
245
- uint16_t *pvpanic_port;
246
-
247
- if (!fw_cfg) {
248
- return;
249
- }
250
-
251
- pvpanic_port = g_malloc(sizeof(*pvpanic_port));
252
- *pvpanic_port = cpu_to_le16(s->ioport);
253
- fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
254
- sizeof(*pvpanic_port));
255
-
256
- isa_register_ioport(d, &s->io, s->ioport);
257
-}
258
-
259
-static Property pvpanic_isa_properties[] = {
260
- DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505),
261
- DEFINE_PROP_UINT8("events", PVPanicState, events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
262
- DEFINE_PROP_END_OF_LIST(),
263
-};
264
-
265
-static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
266
-{
267
- DeviceClass *dc = DEVICE_CLASS(klass);
268
-
269
- dc->realize = pvpanic_isa_realizefn;
270
- device_class_set_props(dc, pvpanic_isa_properties);
271
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
272
-}
273
-
274
-static TypeInfo pvpanic_isa_info = {
275
- .name = TYPE_PVPANIC,
276
- .parent = TYPE_ISA_DEVICE,
277
- .instance_size = sizeof(PVPanicState),
278
- .instance_init = pvpanic_isa_initfn,
279
- .class_init = pvpanic_isa_class_init,
280
-};
281
-
282
-static void pvpanic_register_types(void)
283
-{
284
- type_register_static(&pvpanic_isa_info);
285
-}
286
-
287
-type_init(pvpanic_register_types)
288
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/i386/Kconfig
291
+++ b/hw/i386/Kconfig
292
@@ -XXX,XX +XXX,XX @@ config PC
293
imply ISA_DEBUG
294
imply PARALLEL
295
imply PCI_DEVICES
296
- imply PVPANIC
297
+ imply PVPANIC_ISA
298
imply QXL
299
imply SEV
300
imply SGA
301
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
302
index XXXXXXX..XXXXXXX 100644
303
--- a/hw/misc/Kconfig
304
+++ b/hw/misc/Kconfig
305
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSCTL
306
config IOTKIT_SYSINFO
307
bool
308
309
-config PVPANIC
310
+config PVPANIC_COMMON
311
+ bool
312
+
313
+config PVPANIC_ISA
314
bool
315
depends on ISA_BUS
316
+ select PVPANIC_COMMON
317
318
config AUX
319
bool
320
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/misc/meson.build
323
+++ b/hw/misc/meson.build
324
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
325
softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
326
softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
327
softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
328
+softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c'))
329
330
# ARM devices
331
softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c'))
332
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c')
333
softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
334
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
335
336
-softmmu_ss.add(when: 'CONFIG_PVPANIC', if_true: files('pvpanic.c'))
337
+softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
338
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
339
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
340
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
341
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
342
index XXXXXXX..XXXXXXX 100644
343
--- a/tests/qtest/meson.build
344
+++ b/tests/qtest/meson.build
345
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
346
(config_host.has_key('CONFIG_LINUX') and \
347
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
348
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
349
- (config_all_devices.has_key('CONFIG_PVPANIC') ? ['pvpanic-test'] : []) + \
350
+ (config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
351
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
352
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
353
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
214
--
354
--
215
2.16.1
355
2.20.1
216
356
217
357
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
Add PCI interface support for PVPANIC device. Create a new file pvpanic-pci.c
4
where the PCI specific routines reside and update the build system with the new
5
files and config structure.
4
6
5
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
6
Cc: Jason Wang <jasowang@redhat.com>
8
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
10
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
hw/misc/Makefile.objs | 1 +
13
docs/specs/pci-ids.txt | 1 +
18
include/hw/misc/imx7_ccm.h | 139 +++++++++++++++++++++++
14
include/hw/misc/pvpanic.h | 1 +
19
hw/misc/imx7_ccm.c | 277 +++++++++++++++++++++++++++++++++++++++++++++
15
include/hw/pci/pci.h | 1 +
20
3 files changed, 417 insertions(+)
16
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++++++++++++++++++++++++
21
create mode 100644 include/hw/misc/imx7_ccm.h
17
hw/misc/Kconfig | 6 +++
22
create mode 100644 hw/misc/imx7_ccm.c
18
hw/misc/meson.build | 1 +
19
6 files changed, 104 insertions(+)
20
create mode 100644 hw/misc/pvpanic-pci.c
23
21
24
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
22
diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
25
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/Makefile.objs
24
--- a/docs/specs/pci-ids.txt
27
+++ b/hw/misc/Makefile.objs
25
+++ b/docs/specs/pci-ids.txt
28
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx31_ccm.o
26
@@ -XXX,XX +XXX,XX @@ PCI devices (other than virtio):
29
obj-$(CONFIG_IMX) += imx25_ccm.o
27
1b36:000d PCI xhci usb host adapter
30
obj-$(CONFIG_IMX) += imx6_ccm.o
28
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
31
obj-$(CONFIG_IMX) += imx6_src.o
29
1b36:0010 PCIe NVMe device (-device nvme)
32
+obj-$(CONFIG_IMX) += imx7_ccm.o
30
+1b36:0011 PCI PVPanic device (-device pvpanic-pci)
33
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
31
34
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
32
All these devices are documented in docs/specs.
35
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
33
36
diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h
34
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/misc/pvpanic.h
37
+++ b/include/hw/misc/pvpanic.h
38
@@ -XXX,XX +XXX,XX @@
39
#include "qom/object.h"
40
41
#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
42
+#define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
43
44
#define PVPANIC_IOPORT_PROP "ioport"
45
46
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/include/hw/pci/pci.h
49
+++ b/include/hw/pci/pci.h
50
@@ -XXX,XX +XXX,XX @@ extern bool pci_available;
51
#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e
52
#define PCI_DEVICE_ID_REDHAT_MDPY 0x000f
53
#define PCI_DEVICE_ID_REDHAT_NVME 0x0010
54
+#define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
55
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
56
57
#define FMT_PCIBUS PRIx64
58
diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c
37
new file mode 100644
59
new file mode 100644
38
index XXXXXXX..XXXXXXX
60
index XXXXXXX..XXXXXXX
39
--- /dev/null
61
--- /dev/null
40
+++ b/include/hw/misc/imx7_ccm.h
62
+++ b/hw/misc/pvpanic-pci.c
41
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
42
+/*
64
+/*
43
+ * Copyright (c) 2017, Impinj, Inc.
65
+ * QEMU simulated PCI pvpanic device.
44
+ *
66
+ *
45
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
67
+ * Copyright (C) 2020 Oracle
46
+ *
68
+ *
47
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
69
+ * Authors:
70
+ * Mihai Carabas <mihai.carabas@oracle.com>
48
+ *
71
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
72
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
73
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
53
+#ifndef IMX7_CCM_H
54
+#define IMX7_CCM_H
55
+
56
+#include "hw/misc/imx_ccm.h"
57
+#include "qemu/bitops.h"
58
+
59
+enum IMX7AnalogRegisters {
60
+ ANALOG_PLL_ARM,
61
+ ANALOG_PLL_ARM_SET,
62
+ ANALOG_PLL_ARM_CLR,
63
+ ANALOG_PLL_ARM_TOG,
64
+ ANALOG_PLL_DDR,
65
+ ANALOG_PLL_DDR_SET,
66
+ ANALOG_PLL_DDR_CLR,
67
+ ANALOG_PLL_DDR_TOG,
68
+ ANALOG_PLL_DDR_SS,
69
+ ANALOG_PLL_DDR_SS_SET,
70
+ ANALOG_PLL_DDR_SS_CLR,
71
+ ANALOG_PLL_DDR_SS_TOG,
72
+ ANALOG_PLL_DDR_NUM,
73
+ ANALOG_PLL_DDR_NUM_SET,
74
+ ANALOG_PLL_DDR_NUM_CLR,
75
+ ANALOG_PLL_DDR_NUM_TOG,
76
+ ANALOG_PLL_DDR_DENOM,
77
+ ANALOG_PLL_DDR_DENOM_SET,
78
+ ANALOG_PLL_DDR_DENOM_CLR,
79
+ ANALOG_PLL_DDR_DENOM_TOG,
80
+ ANALOG_PLL_480,
81
+ ANALOG_PLL_480_SET,
82
+ ANALOG_PLL_480_CLR,
83
+ ANALOG_PLL_480_TOG,
84
+ ANALOG_PLL_480A,
85
+ ANALOG_PLL_480A_SET,
86
+ ANALOG_PLL_480A_CLR,
87
+ ANALOG_PLL_480A_TOG,
88
+ ANALOG_PLL_480B,
89
+ ANALOG_PLL_480B_SET,
90
+ ANALOG_PLL_480B_CLR,
91
+ ANALOG_PLL_480B_TOG,
92
+ ANALOG_PLL_ENET,
93
+ ANALOG_PLL_ENET_SET,
94
+ ANALOG_PLL_ENET_CLR,
95
+ ANALOG_PLL_ENET_TOG,
96
+ ANALOG_PLL_AUDIO,
97
+ ANALOG_PLL_AUDIO_SET,
98
+ ANALOG_PLL_AUDIO_CLR,
99
+ ANALOG_PLL_AUDIO_TOG,
100
+ ANALOG_PLL_AUDIO_SS,
101
+ ANALOG_PLL_AUDIO_SS_SET,
102
+ ANALOG_PLL_AUDIO_SS_CLR,
103
+ ANALOG_PLL_AUDIO_SS_TOG,
104
+ ANALOG_PLL_AUDIO_NUM,
105
+ ANALOG_PLL_AUDIO_NUM_SET,
106
+ ANALOG_PLL_AUDIO_NUM_CLR,
107
+ ANALOG_PLL_AUDIO_NUM_TOG,
108
+ ANALOG_PLL_AUDIO_DENOM,
109
+ ANALOG_PLL_AUDIO_DENOM_SET,
110
+ ANALOG_PLL_AUDIO_DENOM_CLR,
111
+ ANALOG_PLL_AUDIO_DENOM_TOG,
112
+ ANALOG_PLL_VIDEO,
113
+ ANALOG_PLL_VIDEO_SET,
114
+ ANALOG_PLL_VIDEO_CLR,
115
+ ANALOG_PLL_VIDEO_TOG,
116
+ ANALOG_PLL_VIDEO_SS,
117
+ ANALOG_PLL_VIDEO_SS_SET,
118
+ ANALOG_PLL_VIDEO_SS_CLR,
119
+ ANALOG_PLL_VIDEO_SS_TOG,
120
+ ANALOG_PLL_VIDEO_NUM,
121
+ ANALOG_PLL_VIDEO_NUM_SET,
122
+ ANALOG_PLL_VIDEO_NUM_CLR,
123
+ ANALOG_PLL_VIDEO_NUM_TOG,
124
+ ANALOG_PLL_VIDEO_DENOM,
125
+ ANALOG_PLL_VIDEO_DENOM_SET,
126
+ ANALOG_PLL_VIDEO_DENOM_CLR,
127
+ ANALOG_PLL_VIDEO_DENOM_TOG,
128
+ ANALOG_PLL_MISC0,
129
+ ANALOG_PLL_MISC0_SET,
130
+ ANALOG_PLL_MISC0_CLR,
131
+ ANALOG_PLL_MISC0_TOG,
132
+
133
+ ANALOG_DIGPROG = 0x800 / sizeof(uint32_t),
134
+ ANALOG_MAX,
135
+
136
+ ANALOG_PLL_LOCK = BIT(31)
137
+};
138
+
139
+enum IMX7CCMRegisters {
140
+ CCM_MAX = 0xBE00 / sizeof(uint32_t) + 1,
141
+};
142
+
143
+enum IMX7PMURegisters {
144
+ PMU_MAX = 0x140 / sizeof(uint32_t),
145
+};
146
+
147
+#define TYPE_IMX7_CCM "imx7.ccm"
148
+#define IMX7_CCM(obj) OBJECT_CHECK(IMX7CCMState, (obj), TYPE_IMX7_CCM)
149
+
150
+typedef struct IMX7CCMState {
151
+ /* <private> */
152
+ IMXCCMState parent_obj;
153
+
154
+ /* <public> */
155
+ MemoryRegion iomem;
156
+
157
+ uint32_t ccm[CCM_MAX];
158
+} IMX7CCMState;
159
+
160
+
161
+#define TYPE_IMX7_ANALOG "imx7.analog"
162
+#define IMX7_ANALOG(obj) OBJECT_CHECK(IMX7AnalogState, (obj), TYPE_IMX7_ANALOG)
163
+
164
+typedef struct IMX7AnalogState {
165
+ /* <private> */
166
+ IMXCCMState parent_obj;
167
+
168
+ /* <public> */
169
+ struct {
170
+ MemoryRegion container;
171
+ MemoryRegion analog;
172
+ MemoryRegion digprog;
173
+ MemoryRegion pmu;
174
+ } mmio;
175
+
176
+ uint32_t analog[ANALOG_MAX];
177
+ uint32_t pmu[PMU_MAX];
178
+} IMX7AnalogState;
179
+
180
+#endif /* IMX7_CCM_H */
181
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
182
new file mode 100644
183
index XXXXXXX..XXXXXXX
184
--- /dev/null
185
+++ b/hw/misc/imx7_ccm.c
186
@@ -XXX,XX +XXX,XX @@
187
+/*
188
+ * Copyright (c) 2018, Impinj, Inc.
189
+ *
74
+ *
190
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
191
+ *
192
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
193
+ *
194
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
195
+ * See the COPYING file in the top-level directory.
196
+ */
75
+ */
197
+
76
+
198
+#include "qemu/osdep.h"
77
+#include "qemu/osdep.h"
199
+#include "qemu/log.h"
78
+#include "qemu/log.h"
79
+#include "qemu/module.h"
80
+#include "sysemu/runstate.h"
200
+
81
+
201
+#include "hw/misc/imx7_ccm.h"
82
+#include "hw/nvram/fw_cfg.h"
83
+#include "hw/qdev-properties.h"
84
+#include "migration/vmstate.h"
85
+#include "hw/misc/pvpanic.h"
86
+#include "qom/object.h"
87
+#include "hw/pci/pci.h"
202
+
88
+
203
+static void imx7_analog_reset(DeviceState *dev)
89
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE)
204
+{
205
+ IMX7AnalogState *s = IMX7_ANALOG(dev);
206
+
90
+
207
+ memset(s->pmu, 0, sizeof(s->pmu));
91
+/*
208
+ memset(s->analog, 0, sizeof(s->analog));
92
+ * PVPanicPCIState for PCI device
93
+ */
94
+typedef struct PVPanicPCIState {
95
+ PCIDevice dev;
96
+ PVPanicState pvpanic;
97
+} PVPanicPCIState;
209
+
98
+
210
+ s->analog[ANALOG_PLL_ARM] = 0x00002042;
99
+static const VMStateDescription vmstate_pvpanic_pci = {
211
+ s->analog[ANALOG_PLL_DDR] = 0x0060302c;
100
+ .name = "pvpanic-pci",
212
+ s->analog[ANALOG_PLL_DDR_SS] = 0x00000000;
213
+ s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
214
+ s->analog[ANALOG_PLL_DDR_DENOM] = 0x100003ec;
215
+ s->analog[ANALOG_PLL_480] = 0x00002000;
216
+ s->analog[ANALOG_PLL_480A] = 0x52605a56;
217
+ s->analog[ANALOG_PLL_480B] = 0x52525216;
218
+ s->analog[ANALOG_PLL_ENET] = 0x00001fc0;
219
+ s->analog[ANALOG_PLL_AUDIO] = 0x0001301b;
220
+ s->analog[ANALOG_PLL_AUDIO_SS] = 0x00000000;
221
+ s->analog[ANALOG_PLL_AUDIO_NUM] = 0x05f5e100;
222
+ s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
223
+ s->analog[ANALOG_PLL_VIDEO] = 0x0008201b;
224
+ s->analog[ANALOG_PLL_VIDEO_SS] = 0x00000000;
225
+ s->analog[ANALOG_PLL_VIDEO_NUM] = 0x0000f699;
226
+ s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
227
+ s->analog[ANALOG_PLL_MISC0] = 0x00000000;
228
+
229
+ /* all PLLs need to be locked */
230
+ s->analog[ANALOG_PLL_ARM] |= ANALOG_PLL_LOCK;
231
+ s->analog[ANALOG_PLL_DDR] |= ANALOG_PLL_LOCK;
232
+ s->analog[ANALOG_PLL_480] |= ANALOG_PLL_LOCK;
233
+ s->analog[ANALOG_PLL_480A] |= ANALOG_PLL_LOCK;
234
+ s->analog[ANALOG_PLL_480B] |= ANALOG_PLL_LOCK;
235
+ s->analog[ANALOG_PLL_ENET] |= ANALOG_PLL_LOCK;
236
+ s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
237
+ s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
238
+ s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
239
+
240
+ /*
241
+ * Since I couldn't find any info about this in the reference
242
+ * manual the value of this register is based strictly on matching
243
+ * what Linux kernel expects it to be.
244
+ */
245
+ s->analog[ANALOG_DIGPROG] = 0x720000;
246
+ /*
247
+ * Set revision to be 1.0 (Arbitrary choice, no particular
248
+ * reason).
249
+ */
250
+ s->analog[ANALOG_DIGPROG] |= 0x000010;
251
+}
252
+
253
+static void imx7_ccm_reset(DeviceState *dev)
254
+{
255
+ IMX7CCMState *s = IMX7_CCM(dev);
256
+
257
+ memset(s->ccm, 0, sizeof(s->ccm));
258
+}
259
+
260
+#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
261
+#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
262
+
263
+enum {
264
+ CCM_BITOP_NONE = 0x00,
265
+ CCM_BITOP_SET = 0x04,
266
+ CCM_BITOP_CLR = 0x08,
267
+ CCM_BITOP_TOG = 0x0C,
268
+};
269
+
270
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
271
+ unsigned size)
272
+{
273
+ const uint32_t *mmio = opaque;
274
+
275
+ return mmio[CCM_INDEX(offset)];
276
+}
277
+
278
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
279
+ uint64_t value, unsigned size)
280
+{
281
+ const uint8_t bitop = CCM_BITOP(offset);
282
+ const uint32_t index = CCM_INDEX(offset);
283
+ uint32_t *mmio = opaque;
284
+
285
+ switch (bitop) {
286
+ case CCM_BITOP_NONE:
287
+ mmio[index] = value;
288
+ break;
289
+ case CCM_BITOP_SET:
290
+ mmio[index] |= value;
291
+ break;
292
+ case CCM_BITOP_CLR:
293
+ mmio[index] &= ~value;
294
+ break;
295
+ case CCM_BITOP_TOG:
296
+ mmio[index] ^= value;
297
+ break;
298
+ };
299
+}
300
+
301
+static const struct MemoryRegionOps imx7_set_clr_tog_ops = {
302
+ .read = imx7_set_clr_tog_read,
303
+ .write = imx7_set_clr_tog_write,
304
+ .endianness = DEVICE_NATIVE_ENDIAN,
305
+ .impl = {
306
+ /*
307
+ * Our device would not work correctly if the guest was doing
308
+ * unaligned access. This might not be a limitation on the real
309
+ * device but in practice there is no reason for a guest to access
310
+ * this device unaligned.
311
+ */
312
+ .min_access_size = 4,
313
+ .max_access_size = 4,
314
+ .unaligned = false,
315
+ },
316
+};
317
+
318
+static const struct MemoryRegionOps imx7_digprog_ops = {
319
+ .read = imx7_set_clr_tog_read,
320
+ .endianness = DEVICE_NATIVE_ENDIAN,
321
+ .impl = {
322
+ .min_access_size = 4,
323
+ .max_access_size = 4,
324
+ .unaligned = false,
325
+ },
326
+};
327
+
328
+static void imx7_ccm_init(Object *obj)
329
+{
330
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
331
+ IMX7CCMState *s = IMX7_CCM(obj);
332
+
333
+ memory_region_init_io(&s->iomem,
334
+ obj,
335
+ &imx7_set_clr_tog_ops,
336
+ s->ccm,
337
+ TYPE_IMX7_CCM ".ccm",
338
+ sizeof(s->ccm));
339
+
340
+ sysbus_init_mmio(sd, &s->iomem);
341
+}
342
+
343
+static void imx7_analog_init(Object *obj)
344
+{
345
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
346
+ IMX7AnalogState *s = IMX7_ANALOG(obj);
347
+
348
+ memory_region_init(&s->mmio.container, obj, TYPE_IMX7_ANALOG,
349
+ 0x10000);
350
+
351
+ memory_region_init_io(&s->mmio.analog,
352
+ obj,
353
+ &imx7_set_clr_tog_ops,
354
+ s->analog,
355
+ TYPE_IMX7_ANALOG,
356
+ sizeof(s->analog));
357
+
358
+ memory_region_add_subregion(&s->mmio.container,
359
+ 0x60, &s->mmio.analog);
360
+
361
+ memory_region_init_io(&s->mmio.pmu,
362
+ obj,
363
+ &imx7_set_clr_tog_ops,
364
+ s->pmu,
365
+ TYPE_IMX7_ANALOG ".pmu",
366
+ sizeof(s->pmu));
367
+
368
+ memory_region_add_subregion(&s->mmio.container,
369
+ 0x200, &s->mmio.pmu);
370
+
371
+ memory_region_init_io(&s->mmio.digprog,
372
+ obj,
373
+ &imx7_digprog_ops,
374
+ &s->analog[ANALOG_DIGPROG],
375
+ TYPE_IMX7_ANALOG ".digprog",
376
+ sizeof(uint32_t));
377
+
378
+ memory_region_add_subregion_overlap(&s->mmio.container,
379
+ 0x800, &s->mmio.digprog, 10);
380
+
381
+
382
+ sysbus_init_mmio(sd, &s->mmio.container);
383
+}
384
+
385
+static const VMStateDescription vmstate_imx7_ccm = {
386
+ .name = TYPE_IMX7_CCM,
387
+ .version_id = 1,
101
+ .version_id = 1,
388
+ .minimum_version_id = 1,
102
+ .minimum_version_id = 1,
389
+ .fields = (VMStateField[]) {
103
+ .fields = (VMStateField[]) {
390
+ VMSTATE_UINT32_ARRAY(ccm, IMX7CCMState, CCM_MAX),
104
+ VMSTATE_PCI_DEVICE(dev, PVPanicPCIState),
391
+ VMSTATE_END_OF_LIST()
105
+ VMSTATE_END_OF_LIST()
392
+ },
106
+ }
393
+};
107
+};
394
+
108
+
395
+static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
109
+static void pvpanic_pci_realizefn(PCIDevice *dev, Error **errp)
396
+{
110
+{
397
+ /*
111
+ PVPanicPCIState *s = PVPANIC_PCI_DEVICE(dev);
398
+ * This function is "consumed" by GPT emulation code, however on
112
+ PVPanicState *ps = &s->pvpanic;
399
+ * i.MX7 each GPT block can have their own clock root. This means
113
+
400
+ * that this functions needs somehow to know requester's identity
114
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 2);
401
+ * and the way to pass it: be it via additional IMXClk constants
115
+
402
+ * or by adding another argument to this method needs to be
116
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &ps->mr);
403
+ * figured out
404
+ */
405
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
406
+ TYPE_IMX7_CCM, __func__);
407
+ return 0;
408
+}
117
+}
409
+
118
+
410
+static void imx7_ccm_class_init(ObjectClass *klass, void *data)
119
+static Property pvpanic_pci_properties[] = {
120
+ DEFINE_PROP_UINT8("events", PVPanicPCIState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
121
+ DEFINE_PROP_END_OF_LIST(),
122
+};
123
+
124
+static void pvpanic_pci_class_init(ObjectClass *klass, void *data)
411
+{
125
+{
412
+ DeviceClass *dc = DEVICE_CLASS(klass);
126
+ DeviceClass *dc = DEVICE_CLASS(klass);
413
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
127
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
414
+
128
+
415
+ dc->reset = imx7_ccm_reset;
129
+ device_class_set_props(dc, pvpanic_pci_properties);
416
+ dc->vmsd = &vmstate_imx7_ccm;
417
+ dc->desc = "i.MX7 Clock Control Module";
418
+
130
+
419
+ ccm->get_clock_frequency = imx7_ccm_get_clock_frequency;
131
+ pc->realize = pvpanic_pci_realizefn;
132
+ pc->vendor_id = PCI_VENDOR_ID_REDHAT;
133
+ pc->device_id = PCI_DEVICE_ID_REDHAT_PVPANIC;
134
+ pc->revision = 1;
135
+ pc->class_id = PCI_CLASS_SYSTEM_OTHER;
136
+ dc->vmsd = &vmstate_pvpanic_pci;
137
+
138
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
420
+}
139
+}
421
+
140
+
422
+static const TypeInfo imx7_ccm_info = {
141
+static TypeInfo pvpanic_pci_info = {
423
+ .name = TYPE_IMX7_CCM,
142
+ .name = TYPE_PVPANIC_PCI_DEVICE,
424
+ .parent = TYPE_IMX_CCM,
143
+ .parent = TYPE_PCI_DEVICE,
425
+ .instance_size = sizeof(IMX7CCMState),
144
+ .instance_size = sizeof(PVPanicPCIState),
426
+ .instance_init = imx7_ccm_init,
145
+ .class_init = pvpanic_pci_class_init,
427
+ .class_init = imx7_ccm_class_init,
146
+ .interfaces = (InterfaceInfo[]) {
147
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
148
+ { }
149
+ }
428
+};
150
+};
429
+
151
+
430
+static const VMStateDescription vmstate_imx7_analog = {
152
+static void pvpanic_register_types(void)
431
+ .name = TYPE_IMX7_ANALOG,
432
+ .version_id = 1,
433
+ .minimum_version_id = 1,
434
+ .fields = (VMStateField[]) {
435
+ VMSTATE_UINT32_ARRAY(analog, IMX7AnalogState, ANALOG_MAX),
436
+ VMSTATE_UINT32_ARRAY(pmu, IMX7AnalogState, PMU_MAX),
437
+ VMSTATE_END_OF_LIST()
438
+ },
439
+};
440
+
441
+static void imx7_analog_class_init(ObjectClass *klass, void *data)
442
+{
153
+{
443
+ DeviceClass *dc = DEVICE_CLASS(klass);
154
+ type_register_static(&pvpanic_pci_info);
444
+
445
+ dc->reset = imx7_analog_reset;
446
+ dc->vmsd = &vmstate_imx7_analog;
447
+ dc->desc = "i.MX7 Analog Module";
448
+}
155
+}
449
+
156
+
450
+static const TypeInfo imx7_analog_info = {
157
+type_init(pvpanic_register_types);
451
+ .name = TYPE_IMX7_ANALOG,
158
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
452
+ .parent = TYPE_SYS_BUS_DEVICE,
159
index XXXXXXX..XXXXXXX 100644
453
+ .instance_size = sizeof(IMX7AnalogState),
160
--- a/hw/misc/Kconfig
454
+ .instance_init = imx7_analog_init,
161
+++ b/hw/misc/Kconfig
455
+ .class_init = imx7_analog_class_init,
162
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSINFO
456
+};
163
config PVPANIC_COMMON
164
bool
165
166
+config PVPANIC_PCI
167
+ bool
168
+ default y if PCI_DEVICES
169
+ depends on PCI
170
+ select PVPANIC_COMMON
457
+
171
+
458
+static void imx7_ccm_register_type(void)
172
config PVPANIC_ISA
459
+{
173
bool
460
+ type_register_static(&imx7_ccm_info);
174
depends on ISA_BUS
461
+ type_register_static(&imx7_analog_info);
175
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
462
+}
176
index XXXXXXX..XXXXXXX 100644
463
+type_init(imx7_ccm_register_type)
177
--- a/hw/misc/meson.build
178
+++ b/hw/misc/meson.build
179
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
180
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
181
182
softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
183
+softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
184
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
185
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
186
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
464
--
187
--
465
2.16.1
188
2.20.1
466
189
467
190
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
Add support for the new ARMv8.2 SHA-3, SM3, SM4 and SHA-512 instructions to
3
Add pvpanic PCI device support details in docs/specs/pvpanic.txt.
4
AArch64 user mode emulation.
5
4
6
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
5
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
7
Message-id: 20180207111729.15737-6-ard.biesheuvel@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
linux-user/elfload.c | 19 +++++++++++++++++++
9
docs/specs/pvpanic.txt | 13 ++++++++++++-
12
target/arm/cpu64.c | 4 ++++
10
1 file changed, 12 insertions(+), 1 deletion(-)
13
2 files changed, 23 insertions(+)
14
11
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
12
diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
14
--- a/docs/specs/pvpanic.txt
18
+++ b/linux-user/elfload.c
15
+++ b/docs/specs/pvpanic.txt
19
@@ -XXX,XX +XXX,XX @@ enum {
16
@@ -XXX,XX +XXX,XX @@
20
ARM_HWCAP_A64_SHA1 = 1 << 5,
17
PVPANIC DEVICE
21
ARM_HWCAP_A64_SHA2 = 1 << 6,
18
==============
22
ARM_HWCAP_A64_CRC32 = 1 << 7,
19
23
+ ARM_HWCAP_A64_ATOMICS = 1 << 8,
20
-pvpanic device is a simulated ISA device, through which a guest panic
24
+ ARM_HWCAP_A64_FPHP = 1 << 9,
21
+pvpanic device is a simulated device, through which a guest panic
25
+ ARM_HWCAP_A64_ASIMDHP = 1 << 10,
22
event is sent to qemu, and a QMP event is generated. This allows
26
+ ARM_HWCAP_A64_CPUID = 1 << 11,
23
management apps (e.g. libvirt) to be notified and respond to the event.
27
+ ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
24
28
+ ARM_HWCAP_A64_JSCVT = 1 << 13,
25
@@ -XXX,XX +XXX,XX @@ The management app has the option of waiting for GUEST_PANICKED events,
29
+ ARM_HWCAP_A64_FCMA = 1 << 14,
26
and/or polling for guest-panicked RunState, to learn when the pvpanic
30
+ ARM_HWCAP_A64_LRCPC = 1 << 15,
27
device has fired a panic event.
31
+ ARM_HWCAP_A64_DCPOP = 1 << 16,
28
32
+ ARM_HWCAP_A64_SHA3 = 1 << 17,
29
+The pvpanic device can be implemented as an ISA device (using IOPORT) or as a
33
+ ARM_HWCAP_A64_SM3 = 1 << 18,
30
+PCI device.
34
+ ARM_HWCAP_A64_SM4 = 1 << 19,
31
+
35
+ ARM_HWCAP_A64_ASIMDDP = 1 << 20,
32
ISA Interface
36
+ ARM_HWCAP_A64_SHA512 = 1 << 21,
33
-------------
37
+ ARM_HWCAP_A64_SVE = 1 << 22,
34
38
};
35
@@ -XXX,XX +XXX,XX @@ bit 1: a guest panic has happened and will be handled by the guest;
39
36
the host should record it or report it, but should not affect
40
#define ELF_HWCAP get_elf_hwcap()
37
the execution of the guest.
41
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
38
42
GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1);
39
+PCI Interface
43
GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2);
40
+-------------
44
GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32);
41
+
45
+ GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3);
42
+The PCI interface is similar to the ISA interface except that it uses an MMIO
46
+ GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
43
+address space provided by its BAR0, 1 byte long. Any machine with a PCI bus
47
+ GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
44
+can enable a pvpanic device by adding '-device pvpanic-pci' to the command
48
+ GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
45
+line.
49
#undef GET_FEATURE
46
+
50
47
ACPI Interface
51
return hwcaps;
48
--------------
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
57
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
58
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
59
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
60
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
61
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
62
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
63
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
64
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
65
set_feature(&cpu->env, ARM_FEATURE_CRC);
66
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
67
--
50
--
68
2.16.1
51
2.20.1
69
52
70
53
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
Add code to emulate SNVS IP-block. Currently only the bits needed to
3
Add a test case for pvpanic-pci device. The scenario is the same as pvpanic
4
be able to emulate machine shutdown are implemented.
4
ISA device, but is using the PCI bus.
5
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
7
Cc: Jason Wang <jasowang@redhat.com>
7
Acked-by: Thomas Huth <thuth@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
9
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/misc/Makefile.objs | 1 +
12
tests/qtest/pvpanic-pci-test.c | 94 ++++++++++++++++++++++++++++++++++
19
include/hw/misc/imx7_snvs.h | 35 +++++++++++++++++++
13
tests/qtest/meson.build | 1 +
20
hw/misc/imx7_snvs.c | 83 +++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 95 insertions(+)
21
3 files changed, 119 insertions(+)
15
create mode 100644 tests/qtest/pvpanic-pci-test.c
22
create mode 100644 include/hw/misc/imx7_snvs.h
23
create mode 100644 hw/misc/imx7_snvs.c
24
16
25
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
17
diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/misc/Makefile.objs
28
+++ b/hw/misc/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_ccm.o
30
obj-$(CONFIG_IMX) += imx6_src.o
31
obj-$(CONFIG_IMX) += imx7_ccm.o
32
obj-$(CONFIG_IMX) += imx2_wdt.o
33
+obj-$(CONFIG_IMX) += imx7_snvs.o
34
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
35
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
36
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
37
diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h
38
new file mode 100644
18
new file mode 100644
39
index XXXXXXX..XXXXXXX
19
index XXXXXXX..XXXXXXX
40
--- /dev/null
20
--- /dev/null
41
+++ b/include/hw/misc/imx7_snvs.h
21
+++ b/tests/qtest/pvpanic-pci-test.c
42
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
43
+/*
23
+/*
44
+ * Copyright (c) 2017, Impinj, Inc.
24
+ * QTest testcase for PV Panic PCI device
45
+ *
25
+ *
46
+ * i.MX7 SNVS block emulation code
26
+ * Copyright (C) 2020 Oracle
47
+ *
27
+ *
48
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
28
+ * Authors:
49
+ *
29
+ * Mihai Carabas <mihai.carabas@oracle.com>
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
+ * See the COPYING file in the top-level directory.
52
+ */
53
+
54
+#ifndef IMX7_SNVS_H
55
+#define IMX7_SNVS_H
56
+
57
+#include "qemu/bitops.h"
58
+#include "hw/sysbus.h"
59
+
60
+
61
+enum IMX7SNVSRegisters {
62
+ SNVS_LPCR = 0x38,
63
+ SNVS_LPCR_TOP = BIT(6),
64
+ SNVS_LPCR_DP_EN = BIT(5)
65
+};
66
+
67
+#define TYPE_IMX7_SNVS "imx7.snvs"
68
+#define IMX7_SNVS(obj) OBJECT_CHECK(IMX7SNVSState, (obj), TYPE_IMX7_SNVS)
69
+
70
+typedef struct IMX7SNVSState {
71
+ /* <private> */
72
+ SysBusDevice parent_obj;
73
+
74
+ MemoryRegion mmio;
75
+} IMX7SNVSState;
76
+
77
+#endif /* IMX7_SNVS_H */
78
diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/hw/misc/imx7_snvs.c
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * IMX7 Secure Non-Volatile Storage
86
+ *
87
+ * Copyright (c) 2018, Impinj, Inc.
88
+ *
89
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
90
+ *
30
+ *
91
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
31
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
92
+ * See the COPYING file in the top-level directory.
32
+ * See the COPYING file in the top-level directory.
93
+ *
33
+ *
94
+ * Bare minimum emulation code needed to support being able to shut
95
+ * down linux guest gracefully.
96
+ */
34
+ */
97
+
35
+
98
+#include "qemu/osdep.h"
36
+#include "qemu/osdep.h"
99
+#include "hw/misc/imx7_snvs.h"
37
+#include "libqos/libqtest.h"
100
+#include "qemu/log.h"
38
+#include "qapi/qmp/qdict.h"
101
+#include "sysemu/sysemu.h"
39
+#include "libqos/pci.h"
40
+#include "libqos/pci-pc.h"
41
+#include "hw/pci/pci_regs.h"
102
+
42
+
103
+static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
43
+static void test_panic_nopause(void)
104
+{
44
+{
105
+ return 0;
45
+ uint8_t val;
46
+ QDict *response, *data;
47
+ QTestState *qts;
48
+ QPCIBus *pcibus;
49
+ QPCIDevice *dev;
50
+ QPCIBar bar;
51
+
52
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=none");
53
+ pcibus = qpci_new_pc(qts, NULL);
54
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
55
+ qpci_device_enable(dev);
56
+ bar = qpci_iomap(dev, 0, NULL);
57
+
58
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
59
+ g_assert_cmpuint(val, ==, 3);
60
+
61
+ val = 1;
62
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
63
+
64
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
65
+ g_assert(qdict_haskey(response, "data"));
66
+ data = qdict_get_qdict(response, "data");
67
+ g_assert(qdict_haskey(data, "action"));
68
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "run");
69
+ qobject_unref(response);
70
+
71
+ qtest_quit(qts);
106
+}
72
+}
107
+
73
+
108
+static void imx7_snvs_write(void *opaque, hwaddr offset,
74
+static void test_panic(void)
109
+ uint64_t v, unsigned size)
110
+{
75
+{
111
+ const uint32_t value = v;
76
+ uint8_t val;
112
+ const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
77
+ QDict *response, *data;
78
+ QTestState *qts;
79
+ QPCIBus *pcibus;
80
+ QPCIDevice *dev;
81
+ QPCIBar bar;
113
+
82
+
114
+ if (offset == SNVS_LPCR && ((value & mask) == mask)) {
83
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=pause");
115
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
84
+ pcibus = qpci_new_pc(qts, NULL);
116
+ }
85
+ dev = qpci_device_find(pcibus, QPCI_DEVFN(0x4, 0x0));
86
+ qpci_device_enable(dev);
87
+ bar = qpci_iomap(dev, 0, NULL);
88
+
89
+ qpci_memread(dev, bar, 0, &val, sizeof(val));
90
+ g_assert_cmpuint(val, ==, 3);
91
+
92
+ val = 1;
93
+ qpci_memwrite(dev, bar, 0, &val, sizeof(val));
94
+
95
+ response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
96
+ g_assert(qdict_haskey(response, "data"));
97
+ data = qdict_get_qdict(response, "data");
98
+ g_assert(qdict_haskey(data, "action"));
99
+ g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause");
100
+ qobject_unref(response);
101
+
102
+ qtest_quit(qts);
117
+}
103
+}
118
+
104
+
119
+static const struct MemoryRegionOps imx7_snvs_ops = {
105
+int main(int argc, char **argv)
120
+ .read = imx7_snvs_read,
106
+{
121
+ .write = imx7_snvs_write,
107
+ int ret;
122
+ .endianness = DEVICE_NATIVE_ENDIAN,
123
+ .impl = {
124
+ /*
125
+ * Our device would not work correctly if the guest was doing
126
+ * unaligned access. This might not be a limitation on the real
127
+ * device but in practice there is no reason for a guest to access
128
+ * this device unaligned.
129
+ */
130
+ .min_access_size = 4,
131
+ .max_access_size = 4,
132
+ .unaligned = false,
133
+ },
134
+};
135
+
108
+
136
+static void imx7_snvs_init(Object *obj)
109
+ g_test_init(&argc, &argv, NULL);
137
+{
110
+ qtest_add_func("/pvpanic-pci/panic", test_panic);
138
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
111
+ qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause);
139
+ IMX7SNVSState *s = IMX7_SNVS(obj);
140
+
112
+
141
+ memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
113
+ ret = g_test_run();
142
+ TYPE_IMX7_SNVS, 0x1000);
143
+
114
+
144
+ sysbus_init_mmio(sd, &s->mmio);
115
+ return ret;
145
+}
116
+}
146
+
117
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
147
+static void imx7_snvs_class_init(ObjectClass *klass, void *data)
118
index XXXXXXX..XXXXXXX 100644
148
+{
119
--- a/tests/qtest/meson.build
149
+ DeviceClass *dc = DEVICE_CLASS(klass);
120
+++ b/tests/qtest/meson.build
150
+
121
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
151
+ dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
122
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
152
+}
123
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
153
+
124
(config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
154
+static const TypeInfo imx7_snvs_info = {
125
+ (config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \
155
+ .name = TYPE_IMX7_SNVS,
126
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
156
+ .parent = TYPE_SYS_BUS_DEVICE,
127
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
157
+ .instance_size = sizeof(IMX7SNVSState),
128
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
158
+ .instance_init = imx7_snvs_init,
159
+ .class_init = imx7_snvs_class_init,
160
+};
161
+
162
+static void imx7_snvs_register_type(void)
163
+{
164
+ type_register_static(&imx7_snvs_info);
165
+}
166
+type_init(imx7_snvs_register_type)
167
--
129
--
168
2.16.1
130
2.20.1
169
131
170
132
diff view generated by jsdifflib
1
In order to support derived exceptions (exceptions generated in
1
The ptimer API currently provides two methods for setting the period:
2
the course of trying to take an exception), we need to be able
2
ptimer_set_period(), which takes a period in nanoseconds, and
3
to handle prioritizing whether to take the original exception
3
ptimer_set_freq(), which takes a frequency in Hz. Neither of these
4
or the derived exception.
4
lines up nicely with the Clock API, because although both the Clock
5
and the ptimer track the frequency using a representation of whole
6
and fractional nanoseconds, conversion via either period-in-ns or
7
frequency-in-Hz will introduce a rounding error.
5
8
6
We do this by introducing a new function
9
Add a new function ptimer_set_period_from_clock() which takes the
7
armv7m_nvic_set_pending_derived() which the exception-taking code in
10
Clock object directly to avoid the rounding issues. This includes a
8
helper.c will call when a derived exception occurs. Derived
11
facility for the user to specify that there is a frequency divider
9
exceptions are dealt with mostly like normal pending exceptions, so
12
between the Clock proper and the timer, as some timer devices like
10
we share the implementation with the armv7m_nvic_set_pending()
13
the CMSDK APB dualtimer need this.
11
function.
12
14
13
Note that the way we structure this is significantly different
15
To avoid having to drag in clock.h from ptimer.h we add the Clock
14
from the v8M Arm ARM pseudocode: that does all the prioritization
16
type to typedefs.h.
15
logic in the DerivedLateArrival() function, whereas we choose to
16
let the existing "identify highest priority exception" logic
17
do the prioritization for us. The effect is the same, though.
18
17
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
21
Message-id: 1517324542-6607-2-git-send-email-peter.maydell@linaro.org
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Message-id: 20210128114145.20536-2-peter.maydell@linaro.org
23
Message-id: 20210121190622.22000-2-peter.maydell@linaro.org
22
---
24
---
23
target/arm/cpu.h | 13 ++++++++++
25
include/hw/ptimer.h | 22 ++++++++++++++++++++++
24
hw/intc/armv7m_nvic.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--
26
include/qemu/typedefs.h | 1 +
25
hw/intc/trace-events | 2 +-
27
hw/core/ptimer.c | 34 ++++++++++++++++++++++++++++++++++
26
3 files changed, 80 insertions(+), 3 deletions(-)
28
3 files changed, 57 insertions(+)
27
29
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
29
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
32
--- a/include/hw/ptimer.h
31
+++ b/target/arm/cpu.h
33
+++ b/include/hw/ptimer.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
34
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
33
* of architecturally banked exceptions.
34
*/
35
*/
35
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
36
void ptimer_set_period(ptimer_state *s, int64_t period);
37
36
+/**
38
+/**
37
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
39
+ * ptimer_set_period_from_clock - Set counter increment from a Clock
38
+ * @opaque: the NVIC
40
+ * @s: ptimer to configure
39
+ * @irq: the exception number to mark pending
41
+ * @clk: pointer to Clock object to take period from
40
+ * @secure: false for non-banked exceptions or for the nonsecure
42
+ * @divisor: value to scale the clock frequency down by
41
+ * version of a banked exception, true for the secure version of a banked
42
+ * exception.
43
+ *
43
+ *
44
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
44
+ * If the ptimer is being driven from a Clock, this is the preferred
45
+ * exceptions (exceptions generated in the course of trying to take
45
+ * way to tell the ptimer about the period, because it avoids any
46
+ * a different exception).
46
+ * possible rounding errors that might happen if the internal
47
+ * representation of the Clock period was converted to either a period
48
+ * in ns or a frequency in Hz.
49
+ *
50
+ * If the ptimer should run at the same frequency as the clock,
51
+ * pass 1 as the @divisor; if the ptimer should run at half the
52
+ * frequency, pass 2, and so on.
53
+ *
54
+ * This function will assert if it is called outside a
55
+ * ptimer_transaction_begin/commit block.
47
+ */
56
+ */
48
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
57
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clock,
58
+ unsigned int divisor);
59
+
49
/**
60
/**
50
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
61
* ptimer_set_freq - Set counter frequency in Hz
51
* @opaque: the NVIC
62
* @s: ptimer to configure
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
63
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
53
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
65
--- a/include/qemu/typedefs.h
55
+++ b/hw/intc/armv7m_nvic.c
66
+++ b/include/qemu/typedefs.h
56
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
67
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriverState BlockDriverState;
68
typedef struct BusClass BusClass;
69
typedef struct BusState BusState;
70
typedef struct Chardev Chardev;
71
+typedef struct Clock Clock;
72
typedef struct CompatProperty CompatProperty;
73
typedef struct CoMutex CoMutex;
74
typedef struct CPUAddressSpace CPUAddressSpace;
75
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/core/ptimer.c
78
+++ b/hw/core/ptimer.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "sysemu/qtest.h"
81
#include "block/aio.h"
82
#include "sysemu/cpus.h"
83
+#include "hw/clock.h"
84
85
#define DELTA_ADJUST 1
86
#define DELTA_NO_ADJUST -1
87
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period)
57
}
88
}
58
}
89
}
59
90
60
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
91
+/* Set counter increment interval from a Clock */
61
+static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
92
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clk,
62
+ bool derived)
93
+ unsigned int divisor)
63
{
94
+{
64
+ /* Pend an exception, including possibly escalating it to HardFault.
95
+ /*
65
+ *
96
+ * The raw clock period is a 64-bit value in units of 2^-32 ns;
66
+ * This function handles both "normal" pending of interrupts and
97
+ * put another way it's a 32.32 fixed-point ns value. Our internal
67
+ * exceptions, and also derived exceptions (ones which occur as
98
+ * representation of the period is 64.32 fixed point ns, so
68
+ * a result of trying to take some other exception).
99
+ * the conversion is simple.
69
+ *
70
+ * If derived == true, the caller guarantees that we are part way through
71
+ * trying to take an exception (but have not yet called
72
+ * armv7m_nvic_acknowledge_irq() to make it active), and so:
73
+ * - s->vectpending is the "original exception" we were trying to take
74
+ * - irq is the "derived exception"
75
+ * - nvic_exec_prio(s) gives the priority before exception entry
76
+ * Here we handle the prioritization logic which the pseudocode puts
77
+ * in the DerivedLateArrival() function.
78
+ */
100
+ */
101
+ uint64_t raw_period = clock_get(clk);
102
+ uint64_t period_frac;
79
+
103
+
80
NVICState *s = (NVICState *)opaque;
104
+ assert(s->in_transaction);
81
bool banked = exc_is_banked(irq);
105
+ s->delta = ptimer_get_count(s);
82
VecInfo *vec;
106
+ s->period = extract64(raw_period, 32, 32);
83
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
107
+ period_frac = extract64(raw_period, 0, 32);
84
108
+ /*
85
vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
109
+ * divisor specifies a possible frequency divisor between the
86
110
+ * clock and the timer, so it is a multiplier on the period.
87
- trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio);
111
+ * We do the multiply after splitting the raw period out into
88
+ trace_nvic_set_pending(irq, secure, derived, vec->enabled, vec->prio);
112
+ * period and frac to avoid having to do a 32*64->96 multiply.
113
+ */
114
+ s->period *= divisor;
115
+ period_frac *= divisor;
116
+ s->period += extract64(period_frac, 32, 32);
117
+ s->period_frac = (uint32_t)period_frac;
89
+
118
+
90
+ if (derived) {
119
+ if (s->enabled) {
91
+ /* Derived exceptions are always synchronous. */
120
+ s->need_reload = true;
92
+ assert(irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV);
93
+
94
+ if (irq == ARMV7M_EXCP_DEBUG &&
95
+ exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) {
96
+ /* DebugMonitorFault, but its priority is lower than the
97
+ * preempted exception priority: just ignore it.
98
+ */
99
+ return;
100
+ }
101
+
102
+ if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) {
103
+ /* If this is a terminal exception (one which means we cannot
104
+ * take the original exception, like a failure to read its
105
+ * vector table entry), then we must take the derived exception.
106
+ * If the derived exception can't take priority over the
107
+ * original exception, then we go into Lockup.
108
+ *
109
+ * For QEMU, we rely on the fact that a derived exception is
110
+ * terminal if and only if it's reported to us as HardFault,
111
+ * which saves having to have an extra argument is_terminal
112
+ * that we'd only use in one place.
113
+ */
114
+ cpu_abort(&s->cpu->parent_obj,
115
+ "Lockup: can't take terminal derived exception "
116
+ "(original exception priority %d)\n",
117
+ s->vectpending_prio);
118
+ }
119
+ /* We now continue with the same code as for a normal pending
120
+ * exception, which will cause us to pend the derived exception.
121
+ * We'll then take either the original or the derived exception
122
+ * based on which is higher priority by the usual mechanism
123
+ * for selecting the highest priority pending interrupt.
124
+ */
125
+ }
121
+ }
126
127
if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
128
/* If a synchronous exception is pending then it may be
129
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
130
}
131
}
132
133
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
134
+{
135
+ do_armv7m_nvic_set_pending(opaque, irq, secure, false);
136
+}
122
+}
137
+
123
+
138
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
124
/* Set counter frequency in Hz. */
139
+{
125
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
140
+ do_armv7m_nvic_set_pending(opaque, irq, secure, true);
141
+}
142
+
143
/* Make pending IRQ active. */
144
bool armv7m_nvic_acknowledge_irq(void *opaque)
145
{
126
{
146
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/intc/trace-events
149
+++ b/hw/intc/trace-events
150
@@ -XXX,XX +XXX,XX @@ nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %
151
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
152
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
153
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
154
-nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
155
+nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
156
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
157
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
158
nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
159
--
127
--
160
2.16.1
128
2.20.1
161
129
162
130
diff view generated by jsdifflib
New patch
1
Add a function for checking whether a clock has a source. This is
2
useful for devices which have input clocks that must be wired up by
3
the board as it allows them to fail in realize rather than ploughing
4
on with a zero-period clock.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210128114145.20536-3-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-3-peter.maydell@linaro.org
12
---
13
docs/devel/clocks.rst | 16 ++++++++++++++++
14
include/hw/clock.h | 15 +++++++++++++++
15
2 files changed, 31 insertions(+)
16
17
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/devel/clocks.rst
20
+++ b/docs/devel/clocks.rst
21
@@ -XXX,XX +XXX,XX @@ object during device instance init. For example:
22
/* set initial value to 10ns / 100MHz */
23
clock_set_ns(clk, 10);
24
25
+To enforce that the clock is wired up by the board code, you can
26
+call ``clock_has_source()`` in your device's realize method:
27
+
28
+.. code-block:: c
29
+
30
+ if (!clock_has_source(s->clk)) {
31
+ error_setg(errp, "MyDevice: clk input must be connected");
32
+ return;
33
+ }
34
+
35
+Note that this only checks that the clock has been wired up; it is
36
+still possible that the output clock connected to it is disabled
37
+or has not yet been configured, in which case the period will be
38
+zero. You should use the clock callback to find out when the clock
39
+period changes.
40
+
41
Fetching clock frequency/period
42
-------------------------------
43
44
diff --git a/include/hw/clock.h b/include/hw/clock.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/clock.h
47
+++ b/include/hw/clock.h
48
@@ -XXX,XX +XXX,XX @@ void clock_clear_callback(Clock *clk);
49
*/
50
void clock_set_source(Clock *clk, Clock *src);
51
52
+/**
53
+ * clock_has_source:
54
+ * @clk: the clock
55
+ *
56
+ * Returns true if the clock has a source clock connected to it.
57
+ * This is useful for devices which have input clocks which must
58
+ * be connected by the board/SoC code which creates them. The
59
+ * device code can use this to check in its realize method that
60
+ * the clock has been connected.
61
+ */
62
+static inline bool clock_has_source(const Clock *clk)
63
+{
64
+ return clk->source != NULL;
65
+}
66
+
67
/**
68
* clock_set:
69
* @clk: the clock to initialize.
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
1
The documentation for the generic loader claims that you can
1
Add a simple test of the CMSDK APB timer, since we're about to do
2
set the PC for a CPU with an option of the form
2
some refactoring of how it is clocked.
3
-device loader,cpu-num=0,addr=0x10000004
4
5
However if you try this QEMU complains:
6
cpu_num must be specified when setting a program counter
7
8
This is because we were testing against 0 rather than CPU_NONE.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180205150426.20542-1-peter.maydell@linaro.org
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-4-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-4-peter.maydell@linaro.org
14
---
10
---
15
hw/core/generic-loader.c | 2 +-
11
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++++++++++++++++++
16
1 file changed, 1 insertion(+), 1 deletion(-)
12
MAINTAINERS | 1 +
13
tests/qtest/meson.build | 1 +
14
3 files changed, 77 insertions(+)
15
create mode 100644 tests/qtest/cmsdk-apb-timer-test.c
17
16
18
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
17
diff --git a/tests/qtest/cmsdk-apb-timer-test.c b/tests/qtest/cmsdk-apb-timer-test.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qtest/cmsdk-apb-timer-test.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QTest testcase for the CMSDK APB timer device
25
+ *
26
+ * Copyright (c) 2021 Linaro Limited
27
+ *
28
+ * This program is free software; you can redistribute it and/or modify it
29
+ * under the terms of the GNU General Public License as published by the
30
+ * Free Software Foundation; either version 2 of the License, or
31
+ * (at your option) any later version.
32
+ *
33
+ * This program is distributed in the hope that it will be useful, but WITHOUT
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36
+ * for more details.
37
+ */
38
+
39
+#include "qemu/osdep.h"
40
+#include "libqtest-single.h"
41
+
42
+/* IoTKit/ARMSSE-200 timer0; driven at 25MHz in mps2-an385, so 40ns per tick */
43
+#define TIMER_BASE 0x40000000
44
+
45
+#define CTRL 0
46
+#define VALUE 4
47
+#define RELOAD 8
48
+#define INTSTATUS 0xc
49
+
50
+static void test_timer(void)
51
+{
52
+ g_assert_true(readl(TIMER_BASE + INTSTATUS) == 0);
53
+
54
+ /* Start timer: will fire after 40 * 1000 == 40000 ns */
55
+ writel(TIMER_BASE + RELOAD, 1000);
56
+ writel(TIMER_BASE + CTRL, 9);
57
+
58
+ /* Step to just past the 500th tick and check VALUE */
59
+ clock_step(40 * 500 + 1);
60
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
61
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 500);
62
+
63
+ /* Just past the 1000th tick: timer should have fired */
64
+ clock_step(40 * 500);
65
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
66
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 0);
67
+
68
+ /* VALUE reloads at the following tick */
69
+ clock_step(40);
70
+ g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 1000);
71
+
72
+ /* Check write-1-to-clear behaviour of INTSTATUS */
73
+ writel(TIMER_BASE + INTSTATUS, 0);
74
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1);
75
+ writel(TIMER_BASE + INTSTATUS, 1);
76
+ g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0);
77
+
78
+ /* Turn off the timer */
79
+ writel(TIMER_BASE + CTRL, 0);
80
+}
81
+
82
+int main(int argc, char **argv)
83
+{
84
+ int r;
85
+
86
+ g_test_init(&argc, &argv, NULL);
87
+
88
+ qtest_start("-machine mps2-an385");
89
+
90
+ qtest_add_func("/cmsdk-apb-timer/timer", test_timer);
91
+
92
+ r = g_test_run();
93
+
94
+ qtest_end();
95
+
96
+ return r;
97
+}
98
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/core/generic-loader.c
100
--- a/MAINTAINERS
21
+++ b/hw/core/generic-loader.c
101
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
102
@@ -XXX,XX +XXX,XX @@ F: include/hw/rtc/pl031.h
23
error_setg(errp, "data can not be specified when setting a "
103
F: include/hw/arm/primecell.h
24
"program counter");
104
F: hw/timer/cmsdk-apb-timer.c
25
return;
105
F: include/hw/timer/cmsdk-apb-timer.h
26
- } else if (!s->cpu_num) {
106
+F: tests/qtest/cmsdk-apb-timer-test.c
27
+ } else if (s->cpu_num == CPU_NONE) {
107
F: hw/timer/cmsdk-apb-dualtimer.c
28
error_setg(errp, "cpu_num must be specified when setting a "
108
F: include/hw/timer/cmsdk-apb-dualtimer.h
29
"program counter");
109
F: hw/char/cmsdk-apb-uart.c
30
return;
110
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qtest/meson.build
113
+++ b/tests/qtest/meson.build
114
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
115
'npcm7xx_timer-test',
116
'npcm7xx_watchdog_timer-test']
117
qtests_arm = \
118
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
119
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
120
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
121
['arm-cpu-features',
31
--
122
--
32
2.16.1
123
2.20.1
33
124
34
125
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Add a simple test of the CMSDK watchdog, since we're about to do some
2
refactoring of how it is clocked.
2
3
3
Add minimal code needed to allow upstream Linux guest to boot.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-5-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-5-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
12
tests/qtest/cmsdk-apb-watchdog-test.c | 79 +++++++++++++++++++++++++++
13
MAINTAINERS | 1 +
14
tests/qtest/meson.build | 1 +
15
3 files changed, 81 insertions(+)
16
create mode 100644 tests/qtest/cmsdk-apb-watchdog-test.c
4
17
5
Cc: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
6
Cc: Jason Wang <jasowang@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/intc/Makefile.objs | 2 +-
18
include/hw/intc/imx_gpcv2.h | 22 ++++++++
19
hw/intc/imx_gpcv2.c | 125 ++++++++++++++++++++++++++++++++++++++++++++
20
3 files changed, 148 insertions(+), 1 deletion(-)
21
create mode 100644 include/hw/intc/imx_gpcv2.h
22
create mode 100644 hw/intc/imx_gpcv2.c
23
24
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/Makefile.objs
27
+++ b/hw/intc/Makefile.objs
28
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o
29
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o
30
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o
31
common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
32
-common-obj-$(CONFIG_IMX) += imx_avic.o
33
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
34
common-obj-$(CONFIG_LM32) += lm32_pic.o
35
common-obj-$(CONFIG_REALVIEW) += realview_gic.o
36
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
37
diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h
38
new file mode 100644
19
new file mode 100644
39
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
40
--- /dev/null
21
--- /dev/null
41
+++ b/include/hw/intc/imx_gpcv2.h
22
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
42
@@ -XXX,XX +XXX,XX @@
43
+#ifndef IMX_GPCV2_H
44
+#define IMX_GPCV2_H
45
+
46
+#include "hw/sysbus.h"
47
+
48
+enum IMXGPCv2Registers {
49
+ GPC_NUM = 0xE00 / sizeof(uint32_t),
50
+};
51
+
52
+typedef struct IMXGPCv2State {
53
+ /*< private >*/
54
+ SysBusDevice parent_obj;
55
+
56
+ /*< public >*/
57
+ MemoryRegion iomem;
58
+ uint32_t regs[GPC_NUM];
59
+} IMXGPCv2State;
60
+
61
+#define TYPE_IMX_GPCV2 "imx-gpcv2"
62
+#define IMX_GPCV2(obj) OBJECT_CHECK(IMXGPCv2State, (obj), TYPE_IMX_GPCV2)
63
+
64
+#endif /* IMX_GPCV2_H */
65
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
66
new file mode 100644
67
index XXXXXXX..XXXXXXX
68
--- /dev/null
69
+++ b/hw/intc/imx_gpcv2.c
70
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
71
+/*
24
+/*
72
+ * Copyright (c) 2018, Impinj, Inc.
25
+ * QTest testcase for the CMSDK APB watchdog device
73
+ *
26
+ *
74
+ * i.MX7 GPCv2 block emulation code
27
+ * Copyright (c) 2021 Linaro Limited
75
+ *
28
+ *
76
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
29
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms of the GNU General Public License as published by the
31
+ * Free Software Foundation; either version 2 of the License, or
32
+ * (at your option) any later version.
77
+ *
33
+ *
78
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
34
+ * This program is distributed in the hope that it will be useful, but WITHOUT
79
+ * See the COPYING file in the top-level directory.
35
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37
+ * for more details.
80
+ */
38
+ */
81
+
39
+
82
+#include "qemu/osdep.h"
40
+#include "qemu/osdep.h"
83
+#include "hw/intc/imx_gpcv2.h"
41
+#include "libqtest-single.h"
84
+#include "qemu/log.h"
85
+
42
+
86
+#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
43
+/*
87
+#define GPC_PU_PGC_SW_PDN_REQ 0x104
44
+ * lm3s811evb watchdog; at board startup this runs at 200MHz / 16 == 12.5MHz,
45
+ * which is 80ns per tick.
46
+ */
47
+#define WDOG_BASE 0x40000000
88
+
48
+
89
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
49
+#define WDOGLOAD 0
90
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
50
+#define WDOGVALUE 4
91
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
51
+#define WDOGCONTROL 8
92
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
52
+#define WDOGINTCLR 0xc
93
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
53
+#define WDOGRIS 0x10
54
+#define WDOGMIS 0x14
55
+#define WDOGLOCK 0xc00
94
+
56
+
57
+static void test_watchdog(void)
58
+{
59
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
95
+
60
+
96
+static void imx_gpcv2_reset(DeviceState *dev)
61
+ writel(WDOG_BASE + WDOGCONTROL, 1);
97
+{
62
+ writel(WDOG_BASE + WDOGLOAD, 1000);
98
+ IMXGPCv2State *s = IMX_GPCV2(dev);
99
+
63
+
100
+ memset(s->regs, 0, sizeof(s->regs));
64
+ /* Step to just past the 500th tick */
65
+ clock_step(500 * 80 + 1);
66
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
67
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
68
+
69
+ /* Just past the 1000th tick: timer should have fired */
70
+ clock_step(500 * 80);
71
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
73
+
74
+ /* VALUE reloads at following tick */
75
+ clock_step(80);
76
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
77
+
78
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
79
+ clock_step(500 * 80);
80
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
81
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
82
+ writel(WDOG_BASE + WDOGINTCLR, 0);
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
84
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
101
+}
85
+}
102
+
86
+
103
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
87
+int main(int argc, char **argv)
104
+ unsigned size)
105
+{
88
+{
106
+ IMXGPCv2State *s = opaque;
89
+ int r;
107
+
90
+
108
+ return s->regs[offset / sizeof(uint32_t)];
91
+ g_test_init(&argc, &argv, NULL);
92
+
93
+ qtest_start("-machine lm3s811evb");
94
+
95
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
96
+
97
+ r = g_test_run();
98
+
99
+ qtest_end();
100
+
101
+ return r;
109
+}
102
+}
110
+
103
diff --git a/MAINTAINERS b/MAINTAINERS
111
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
104
index XXXXXXX..XXXXXXX 100644
112
+ uint64_t value, unsigned size)
105
--- a/MAINTAINERS
113
+{
106
+++ b/MAINTAINERS
114
+ IMXGPCv2State *s = opaque;
107
@@ -XXX,XX +XXX,XX @@ F: hw/char/cmsdk-apb-uart.c
115
+ const size_t idx = offset / sizeof(uint32_t);
108
F: include/hw/char/cmsdk-apb-uart.h
116
+
109
F: hw/watchdog/cmsdk-apb-watchdog.c
117
+ s->regs[idx] = value;
110
F: include/hw/watchdog/cmsdk-apb-watchdog.h
118
+
111
+F: tests/qtest/cmsdk-apb-watchdog-test.c
119
+ /*
112
F: hw/misc/tz-ppc.c
120
+ * Real HW will clear those bits once as a way to indicate that
113
F: include/hw/misc/tz-ppc.h
121
+ * power up request is complete
114
F: hw/misc/tz-mpc.c
122
+ */
115
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
123
+ if (offset == GPC_PU_PGC_SW_PUP_REQ ||
116
index XXXXXXX..XXXXXXX 100644
124
+ offset == GPC_PU_PGC_SW_PDN_REQ) {
117
--- a/tests/qtest/meson.build
125
+ s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
118
+++ b/tests/qtest/meson.build
126
+ USB_OTG2_PHY_SW_Pxx_REQ |
119
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
127
+ USB_OTG1_PHY_SW_Pxx_REQ |
120
'npcm7xx_watchdog_timer-test']
128
+ PCIE_PHY_SW_Pxx_REQ |
121
qtests_arm = \
129
+ MIPI_PHY_SW_Pxx_REQ);
122
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
130
+ }
123
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
131
+}
124
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
132
+
125
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
133
+static const struct MemoryRegionOps imx_gpcv2_ops = {
126
['arm-cpu-features',
134
+ .read = imx_gpcv2_read,
135
+ .write = imx_gpcv2_write,
136
+ .endianness = DEVICE_NATIVE_ENDIAN,
137
+ .impl = {
138
+ /*
139
+ * Our device would not work correctly if the guest was doing
140
+ * unaligned access. This might not be a limitation on the real
141
+ * device but in practice there is no reason for a guest to access
142
+ * this device unaligned.
143
+ */
144
+ .min_access_size = 4,
145
+ .max_access_size = 4,
146
+ .unaligned = false,
147
+ },
148
+};
149
+
150
+static void imx_gpcv2_init(Object *obj)
151
+{
152
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
153
+ IMXGPCv2State *s = IMX_GPCV2(obj);
154
+
155
+ memory_region_init_io(&s->iomem,
156
+ obj,
157
+ &imx_gpcv2_ops,
158
+ s,
159
+ TYPE_IMX_GPCV2 ".iomem",
160
+ sizeof(s->regs));
161
+ sysbus_init_mmio(sd, &s->iomem);
162
+}
163
+
164
+static const VMStateDescription vmstate_imx_gpcv2 = {
165
+ .name = TYPE_IMX_GPCV2,
166
+ .version_id = 1,
167
+ .minimum_version_id = 1,
168
+ .fields = (VMStateField[]) {
169
+ VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
170
+ VMSTATE_END_OF_LIST()
171
+ },
172
+};
173
+
174
+static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
175
+{
176
+ DeviceClass *dc = DEVICE_CLASS(klass);
177
+
178
+ dc->reset = imx_gpcv2_reset;
179
+ dc->vmsd = &vmstate_imx_gpcv2;
180
+ dc->desc = "i.MX GPCv2 Module";
181
+}
182
+
183
+static const TypeInfo imx_gpcv2_info = {
184
+ .name = TYPE_IMX_GPCV2,
185
+ .parent = TYPE_SYS_BUS_DEVICE,
186
+ .instance_size = sizeof(IMXGPCv2State),
187
+ .instance_init = imx_gpcv2_init,
188
+ .class_init = imx_gpcv2_class_init,
189
+};
190
+
191
+static void imx_gpcv2_register_type(void)
192
+{
193
+ type_register_static(&imx_gpcv2_info);
194
+}
195
+type_init(imx_gpcv2_register_type)
196
--
127
--
197
2.16.1
128
2.20.1
198
129
199
130
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Add a simple test of the CMSDK dual timer, since we're about to do
2
some refactoring of how it is clocked.
2
3
3
Add enough code to emulate i.MX2 watchdog IP block so it would be
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
possible to reboot the machine running Linux Guest.
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20210128114145.20536-6-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-6-peter.maydell@linaro.org
10
---
11
tests/qtest/cmsdk-apb-dualtimer-test.c | 130 +++++++++++++++++++++++++
12
MAINTAINERS | 1 +
13
tests/qtest/meson.build | 1 +
14
3 files changed, 132 insertions(+)
15
create mode 100644 tests/qtest/cmsdk-apb-dualtimer-test.c
5
16
6
Cc: Peter Maydell <peter.maydell@linaro.org>
17
diff --git a/tests/qtest/cmsdk-apb-dualtimer-test.c b/tests/qtest/cmsdk-apb-dualtimer-test.c
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/misc/Makefile.objs | 1 +
20
include/hw/misc/imx2_wdt.h | 33 +++++++++++++++++
21
hw/misc/imx2_wdt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
22
3 files changed, 123 insertions(+)
23
create mode 100644 include/hw/misc/imx2_wdt.h
24
create mode 100644 hw/misc/imx2_wdt.c
25
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
29
+++ b/hw/misc/Makefile.objs
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx25_ccm.o
31
obj-$(CONFIG_IMX) += imx6_ccm.o
32
obj-$(CONFIG_IMX) += imx6_src.o
33
obj-$(CONFIG_IMX) += imx7_ccm.o
34
+obj-$(CONFIG_IMX) += imx2_wdt.o
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
38
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
39
new file mode 100644
18
new file mode 100644
40
index XXXXXXX..XXXXXXX
19
index XXXXXXX..XXXXXXX
41
--- /dev/null
20
--- /dev/null
42
+++ b/include/hw/misc/imx2_wdt.h
21
+++ b/tests/qtest/cmsdk-apb-dualtimer-test.c
43
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
44
+/*
23
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
24
+ * QTest testcase for the CMSDK APB dualtimer device
46
+ *
25
+ *
47
+ * i.MX2 Watchdog IP block
26
+ * Copyright (c) 2021 Linaro Limited
48
+ *
27
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
28
+ * This program is free software; you can redistribute it and/or modify it
29
+ * under the terms of the GNU General Public License as published by the
30
+ * Free Software Foundation; either version 2 of the License, or
31
+ * (at your option) any later version.
50
+ *
32
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
33
+ * This program is distributed in the hope that it will be useful, but WITHOUT
52
+ * See the COPYING file in the top-level directory.
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
53
+ */
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
54
+
36
+ * for more details.
55
+#ifndef IMX2_WDT_H
56
+#define IMX2_WDT_H
57
+
58
+#include "hw/sysbus.h"
59
+
60
+#define TYPE_IMX2_WDT "imx2.wdt"
61
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
62
+
63
+enum IMX2WdtRegisters {
64
+ IMX2_WDT_WCR = 0x0000,
65
+ IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
66
+};
67
+
68
+
69
+typedef struct IMX2WdtState {
70
+ /* <private> */
71
+ SysBusDevice parent_obj;
72
+
73
+ MemoryRegion mmio;
74
+} IMX2WdtState;
75
+
76
+#endif /* IMX7_SNVS_H */
77
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
78
new file mode 100644
79
index XXXXXXX..XXXXXXX
80
--- /dev/null
81
+++ b/hw/misc/imx2_wdt.c
82
@@ -XXX,XX +XXX,XX @@
83
+/*
84
+ * Copyright (c) 2018, Impinj, Inc.
85
+ *
86
+ * i.MX2 Watchdog IP block
87
+ *
88
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
37
+ */
93
+
38
+
94
+#include "qemu/osdep.h"
39
+#include "qemu/osdep.h"
95
+#include "qemu/bitops.h"
40
+#include "libqtest-single.h"
96
+#include "sysemu/watchdog.h"
97
+
41
+
98
+#include "hw/misc/imx2_wdt.h"
42
+/* IoTKit/ARMSSE dualtimer; driven at 25MHz in mps2-an385, so 40ns per tick */
43
+#define TIMER_BASE 0x40002000
99
+
44
+
100
+#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
45
+#define TIMER1LOAD 0
101
+#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
46
+#define TIMER1VALUE 4
47
+#define TIMER1CONTROL 8
48
+#define TIMER1INTCLR 0xc
49
+#define TIMER1RIS 0x10
50
+#define TIMER1MIS 0x14
51
+#define TIMER1BGLOAD 0x18
102
+
52
+
103
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
53
+#define TIMER2LOAD 0x20
104
+ unsigned int size)
54
+#define TIMER2VALUE 0x24
55
+#define TIMER2CONTROL 0x28
56
+#define TIMER2INTCLR 0x2c
57
+#define TIMER2RIS 0x30
58
+#define TIMER2MIS 0x34
59
+#define TIMER2BGLOAD 0x38
60
+
61
+#define CTRL_ENABLE (1 << 7)
62
+#define CTRL_PERIODIC (1 << 6)
63
+#define CTRL_INTEN (1 << 5)
64
+#define CTRL_PRESCALE_1 (0 << 2)
65
+#define CTRL_PRESCALE_16 (1 << 2)
66
+#define CTRL_PRESCALE_256 (2 << 2)
67
+#define CTRL_32BIT (1 << 1)
68
+#define CTRL_ONESHOT (1 << 0)
69
+
70
+static void test_dualtimer(void)
105
+{
71
+{
106
+ return 0;
72
+ g_assert_true(readl(TIMER_BASE + TIMER1RIS) == 0);
73
+
74
+ /* Start timer: will fire after 40000 ns */
75
+ writel(TIMER_BASE + TIMER1LOAD, 1000);
76
+ /* enable in free-running, wrapping, interrupt mode */
77
+ writel(TIMER_BASE + TIMER1CONTROL, CTRL_ENABLE | CTRL_INTEN);
78
+
79
+ /* Step to just past the 500th tick and check VALUE */
80
+ clock_step(500 * 40 + 1);
81
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
82
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 500);
83
+
84
+ /* Just past the 1000th tick: timer should have fired */
85
+ clock_step(500 * 40);
86
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 1);
87
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0);
88
+
89
+ /*
90
+ * We are in free-running wrapping 16-bit mode, so on the following
91
+ * tick VALUE should have wrapped round to 0xffff.
92
+ */
93
+ clock_step(40);
94
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0xffff);
95
+
96
+ /* Check that any write to INTCLR clears interrupt */
97
+ writel(TIMER_BASE + TIMER1INTCLR, 1);
98
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
99
+
100
+ /* Turn off the timer */
101
+ writel(TIMER_BASE + TIMER1CONTROL, 0);
107
+}
102
+}
108
+
103
+
109
+static void imx2_wdt_write(void *opaque, hwaddr addr,
104
+static void test_prescale(void)
110
+ uint64_t value, unsigned int size)
111
+{
105
+{
112
+ if (addr == IMX2_WDT_WCR &&
106
+ g_assert_true(readl(TIMER_BASE + TIMER2RIS) == 0);
113
+ (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
107
+
114
+ watchdog_perform_action();
108
+ /* Start timer: will fire after 40 * 256 * 1000 == 1024000 ns */
115
+ }
109
+ writel(TIMER_BASE + TIMER2LOAD, 1000);
110
+ /* enable in periodic, wrapping, interrupt mode, prescale 256 */
111
+ writel(TIMER_BASE + TIMER2CONTROL,
112
+ CTRL_ENABLE | CTRL_INTEN | CTRL_PERIODIC | CTRL_PRESCALE_256);
113
+
114
+ /* Step to just past the 500th tick and check VALUE */
115
+ clock_step(40 * 256 * 501);
116
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
117
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 500);
118
+
119
+ /* Just past the 1000th tick: timer should have fired */
120
+ clock_step(40 * 256 * 500);
121
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 1);
122
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 0);
123
+
124
+ /* In periodic mode the tick VALUE now reloads */
125
+ clock_step(40 * 256);
126
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2VALUE), ==, 1000);
127
+
128
+ /* Check that any write to INTCLR clears interrupt */
129
+ writel(TIMER_BASE + TIMER2INTCLR, 1);
130
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER2RIS), ==, 0);
131
+
132
+ /* Turn off the timer */
133
+ writel(TIMER_BASE + TIMER2CONTROL, 0);
116
+}
134
+}
117
+
135
+
118
+static const MemoryRegionOps imx2_wdt_ops = {
136
+int main(int argc, char **argv)
119
+ .read = imx2_wdt_read,
137
+{
120
+ .write = imx2_wdt_write,
138
+ int r;
121
+ .endianness = DEVICE_NATIVE_ENDIAN,
122
+ .impl = {
123
+ /*
124
+ * Our device would not work correctly if the guest was doing
125
+ * unaligned access. This might not be a limitation on the
126
+ * real device but in practice there is no reason for a guest
127
+ * to access this device unaligned.
128
+ */
129
+ .min_access_size = 4,
130
+ .max_access_size = 4,
131
+ .unaligned = false,
132
+ },
133
+};
134
+
139
+
135
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
140
+ g_test_init(&argc, &argv, NULL);
136
+{
137
+ IMX2WdtState *s = IMX2_WDT(dev);
138
+
141
+
139
+ memory_region_init_io(&s->mmio, OBJECT(dev),
142
+ qtest_start("-machine mps2-an385");
140
+ &imx2_wdt_ops, s,
143
+
141
+ TYPE_IMX2_WDT".mmio",
144
+ qtest_add_func("/cmsdk-apb-dualtimer/dualtimer", test_dualtimer);
142
+ IMX2_WDT_REG_NUM * sizeof(uint16_t));
145
+ qtest_add_func("/cmsdk-apb-dualtimer/prescale", test_prescale);
143
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
146
+
147
+ r = g_test_run();
148
+
149
+ qtest_end();
150
+
151
+ return r;
144
+}
152
+}
145
+
153
diff --git a/MAINTAINERS b/MAINTAINERS
146
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
154
index XXXXXXX..XXXXXXX 100644
147
+{
155
--- a/MAINTAINERS
148
+ DeviceClass *dc = DEVICE_CLASS(klass);
156
+++ b/MAINTAINERS
149
+
157
@@ -XXX,XX +XXX,XX @@ F: include/hw/timer/cmsdk-apb-timer.h
150
+ dc->realize = imx2_wdt_realize;
158
F: tests/qtest/cmsdk-apb-timer-test.c
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
159
F: hw/timer/cmsdk-apb-dualtimer.c
152
+}
160
F: include/hw/timer/cmsdk-apb-dualtimer.h
153
+
161
+F: tests/qtest/cmsdk-apb-dualtimer-test.c
154
+static const TypeInfo imx2_wdt_info = {
162
F: hw/char/cmsdk-apb-uart.c
155
+ .name = TYPE_IMX2_WDT,
163
F: include/hw/char/cmsdk-apb-uart.h
156
+ .parent = TYPE_SYS_BUS_DEVICE,
164
F: hw/watchdog/cmsdk-apb-watchdog.c
157
+ .instance_size = sizeof(IMX2WdtState),
165
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
158
+ .class_init = imx2_wdt_class_init,
166
index XXXXXXX..XXXXXXX 100644
159
+};
167
--- a/tests/qtest/meson.build
160
+
168
+++ b/tests/qtest/meson.build
161
+static WatchdogTimerModel model = {
169
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
162
+ .wdt_name = "imx2-watchdog",
170
'npcm7xx_timer-test',
163
+ .wdt_description = "i.MX2 Watchdog",
171
'npcm7xx_watchdog_timer-test']
164
+};
172
qtests_arm = \
165
+
173
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
166
+static void imx2_wdt_register_type(void)
174
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
167
+{
175
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
168
+ watchdog_add_model(&model);
176
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
169
+ type_register_static(&imx2_wdt_info);
170
+}
171
+type_init(imx2_wdt_register_type)
172
--
177
--
173
2.16.1
178
2.20.1
174
179
175
180
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The state struct for the CMSDK APB timer device doesn't follow our
2
usual naming convention of camelcase -- "CMSDK" and "APB" are both
3
acronyms, but "TIMER" is not so should not be all-uppercase.
4
Globally rename the struct to "CMSDKAPBTimer" (bringing it into line
5
with CMSDKAPBWatchdog and CMSDKAPBDualTimer; CMSDKAPBUART remains
6
as-is because "UART" is an acronym).
2
7
3
Save the high parts of the Zregs and all of the Pregs.
8
Commit created with:
4
The ZCR_ELx registers are migrated via the CP mechanism.
9
perl -p -i -e 's/CMSDKAPBTIMER/CMSDKAPBTimer/g' hw/timer/cmsdk-apb-timer.c include/hw/arm/armsse.h include/hw/timer/cmsdk-apb-timer.h
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180123035349.24538-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20210128114145.20536-7-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-7-peter.maydell@linaro.org
11
---
17
---
12
target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
18
include/hw/arm/armsse.h | 6 +++---
13
1 file changed, 53 insertions(+)
19
include/hw/timer/cmsdk-apb-timer.h | 4 ++--
20
hw/timer/cmsdk-apb-timer.c | 28 ++++++++++++++--------------
21
3 files changed, 19 insertions(+), 19 deletions(-)
14
22
15
diff --git a/target/arm/machine.c b/target/arm/machine.c
23
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/machine.c
25
--- a/include/hw/arm/armsse.h
18
+++ b/target/arm/machine.c
26
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
27
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
28
TZPPC apb_ppc0;
29
TZPPC apb_ppc1;
30
TZMPC mpc[IOTS_NUM_MPC];
31
- CMSDKAPBTIMER timer0;
32
- CMSDKAPBTIMER timer1;
33
- CMSDKAPBTIMER s32ktimer;
34
+ CMSDKAPBTimer timer0;
35
+ CMSDKAPBTimer timer1;
36
+ CMSDKAPBTimer s32ktimer;
37
qemu_or_irq ppc_irq_orgate;
38
SplitIRQ sec_resp_splitter;
39
SplitIRQ ppc_irq_splitter[NUM_PPCS];
40
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/timer/cmsdk-apb-timer.h
43
+++ b/include/hw/timer/cmsdk-apb-timer.h
44
@@ -XXX,XX +XXX,XX @@
45
#include "qom/object.h"
46
47
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
48
-OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTIMER, CMSDK_APB_TIMER)
49
+OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
50
51
-struct CMSDKAPBTIMER {
52
+struct CMSDKAPBTimer {
53
/*< private >*/
54
SysBusDevice parent_obj;
55
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
60
@@ -XXX,XX +XXX,XX @@ static const int timer_id[] = {
61
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
62
};
63
64
-static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
65
+static void cmsdk_apb_timer_update(CMSDKAPBTimer *s)
66
{
67
qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
68
}
69
70
static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
71
{
72
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
73
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
74
uint64_t r;
75
76
switch (offset) {
77
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
78
static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
79
unsigned size)
80
{
81
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
82
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
83
84
trace_cmsdk_apb_timer_write(offset, value, size);
85
86
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cmsdk_apb_timer_ops = {
87
88
static void cmsdk_apb_timer_tick(void *opaque)
89
{
90
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
91
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
92
93
if (s->ctrl & R_CTRL_IRQEN_MASK) {
94
s->intstatus |= R_INTSTATUS_IRQ_MASK;
95
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_tick(void *opaque)
96
97
static void cmsdk_apb_timer_reset(DeviceState *dev)
98
{
99
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
100
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
101
102
trace_cmsdk_apb_timer_reset();
103
s->ctrl = 0;
104
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
105
static void cmsdk_apb_timer_init(Object *obj)
106
{
107
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
108
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);
109
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(obj);
110
111
memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
112
s, "cmsdk-apb-timer", 0x1000);
113
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
114
115
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
116
{
117
- CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
118
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
119
120
if (s->pclk_frq == 0) {
121
error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
122
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
123
.version_id = 1,
124
.minimum_version_id = 1,
125
.fields = (VMStateField[]) {
126
- VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
127
- VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
128
- VMSTATE_UINT32(value, CMSDKAPBTIMER),
129
- VMSTATE_UINT32(reload, CMSDKAPBTIMER),
130
- VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
131
+ VMSTATE_PTIMER(timer, CMSDKAPBTimer),
132
+ VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
133
+ VMSTATE_UINT32(value, CMSDKAPBTimer),
134
+ VMSTATE_UINT32(reload, CMSDKAPBTimer),
135
+ VMSTATE_UINT32(intstatus, CMSDKAPBTimer),
136
VMSTATE_END_OF_LIST()
20
}
137
}
21
};
138
};
22
139
23
+#ifdef TARGET_AARCH64
140
static Property cmsdk_apb_timer_properties[] = {
24
+/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
141
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
25
+ * and ARMPredicateReg is actively empty. This triggers errors
142
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
26
+ * in the expansion of the VMSTATE macros.
143
DEFINE_PROP_END_OF_LIST(),
27
+ */
144
};
28
+
145
29
+static bool sve_needed(void *opaque)
146
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
30
+{
147
static const TypeInfo cmsdk_apb_timer_info = {
31
+ ARMCPU *cpu = opaque;
148
.name = TYPE_CMSDK_APB_TIMER,
32
+ CPUARMState *env = &cpu->env;
149
.parent = TYPE_SYS_BUS_DEVICE,
33
+
150
- .instance_size = sizeof(CMSDKAPBTIMER),
34
+ return arm_feature(env, ARM_FEATURE_SVE);
151
+ .instance_size = sizeof(CMSDKAPBTimer),
35
+}
152
.instance_init = cmsdk_apb_timer_init,
36
+
153
.class_init = cmsdk_apb_timer_class_init,
37
+/* The first two words of each Zreg is stored in VFP state. */
38
+static const VMStateDescription vmstate_zreg_hi_reg = {
39
+ .name = "cpu/sve/zreg_hi",
40
+ .version_id = 1,
41
+ .minimum_version_id = 1,
42
+ .fields = (VMStateField[]) {
43
+ VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
44
+ VMSTATE_END_OF_LIST()
45
+ }
46
+};
47
+
48
+static const VMStateDescription vmstate_preg_reg = {
49
+ .name = "cpu/sve/preg",
50
+ .version_id = 1,
51
+ .minimum_version_id = 1,
52
+ .fields = (VMStateField[]) {
53
+ VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
54
+ VMSTATE_END_OF_LIST()
55
+ }
56
+};
57
+
58
+static const VMStateDescription vmstate_sve = {
59
+ .name = "cpu/sve",
60
+ .version_id = 1,
61
+ .minimum_version_id = 1,
62
+ .needed = sve_needed,
63
+ .fields = (VMStateField[]) {
64
+ VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0,
65
+ vmstate_zreg_hi_reg, ARMVectorReg),
66
+ VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0,
67
+ vmstate_preg_reg, ARMPredicateReg),
68
+ VMSTATE_END_OF_LIST()
69
+ }
70
+};
71
+#endif /* AARCH64 */
72
+
73
static bool m_needed(void *opaque)
74
{
75
ARMCPU *cpu = opaque;
76
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
77
&vmstate_pmsav7,
78
&vmstate_pmsav8,
79
&vmstate_m_security,
80
+#ifdef TARGET_AARCH64
81
+ &vmstate_sve,
82
+#endif
83
NULL
84
}
85
};
154
};
86
--
155
--
87
2.16.1
156
2.20.1
88
157
89
158
diff view generated by jsdifflib
New patch
1
As the first step in converting the CMSDK_APB_TIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the pclk-frq
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
1
6
7
Since the device doesn't already have a doc comment for its "QEMU
8
interface", we add one including the new Clock.
9
10
This is a migration compatibility break for machines mps2-an505,
11
mps2-an521, musca-a, musca-b1.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20210128114145.20536-8-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-8-peter.maydell@linaro.org
19
---
20
include/hw/timer/cmsdk-apb-timer.h | 9 +++++++++
21
hw/timer/cmsdk-apb-timer.c | 7 +++++--
22
2 files changed, 14 insertions(+), 2 deletions(-)
23
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/timer/cmsdk-apb-timer.h
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
28
@@ -XXX,XX +XXX,XX @@
29
#include "hw/qdev-properties.h"
30
#include "hw/sysbus.h"
31
#include "hw/ptimer.h"
32
+#include "hw/clock.h"
33
#include "qom/object.h"
34
35
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
36
OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
37
38
+/*
39
+ * QEMU interface:
40
+ * + QOM property "pclk-frq": frequency at which the timer is clocked
41
+ * + Clock input "pclk": clock for the timer
42
+ * + sysbus MMIO region 0: the register bank
43
+ * + sysbus IRQ 0: timer interrupt TIMERINT
44
+ */
45
struct CMSDKAPBTimer {
46
/*< private >*/
47
SysBusDevice parent_obj;
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
49
qemu_irq timerint;
50
uint32_t pclk_frq;
51
struct ptimer_state *timer;
52
+ Clock *pclk;
53
54
uint32_t ctrl;
55
uint32_t value;
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-timer.c
59
+++ b/hw/timer/cmsdk-apb-timer.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/sysbus.h"
62
#include "hw/irq.h"
63
#include "hw/registerfields.h"
64
+#include "hw/qdev-clock.h"
65
#include "hw/timer/cmsdk-apb-timer.h"
66
#include "migration/vmstate.h"
67
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
69
s, "cmsdk-apb-timer", 0x1000);
70
sysbus_init_mmio(sbd, &s->iomem);
71
sysbus_init_irq(sbd, &s->timerint);
72
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
73
}
74
75
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
77
78
static const VMStateDescription cmsdk_apb_timer_vmstate = {
79
.name = "cmsdk-apb-timer",
80
- .version_id = 1,
81
- .minimum_version_id = 1,
82
+ .version_id = 2,
83
+ .minimum_version_id = 2,
84
.fields = (VMStateField[]) {
85
VMSTATE_PTIMER(timer, CMSDKAPBTimer),
86
+ VMSTATE_CLOCK(pclk, CMSDKAPBTimer),
87
VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
88
VMSTATE_UINT32(value, CMSDKAPBTimer),
89
VMSTATE_UINT32(reload, CMSDKAPBTimer),
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
New patch
1
As the first step in converting the CMSDK_APB_DUALTIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the pclk-frq
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
1
6
7
We take the opportunity to correct the name of the clock input to
8
match the hardware -- the dual timer names the clock which drives the
9
timers TIMCLK. (It does also have a 'pclk' input, which is used only
10
for the register and APB bus logic; on the SSE-200 these clocks are
11
both connected together.)
12
13
This is a migration compatibility break for machines mps2-an385,
14
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
15
musca-b1.
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210128114145.20536-9-peter.maydell@linaro.org
22
Message-id: 20210121190622.22000-9-peter.maydell@linaro.org
23
---
24
include/hw/timer/cmsdk-apb-dualtimer.h | 3 +++
25
hw/timer/cmsdk-apb-dualtimer.c | 7 +++++--
26
2 files changed, 8 insertions(+), 2 deletions(-)
27
28
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
31
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
32
@@ -XXX,XX +XXX,XX @@
33
*
34
* QEMU interface:
35
* + QOM property "pclk-frq": frequency at which the timer is clocked
36
+ * + Clock input "TIMCLK": clock (for both timers)
37
* + sysbus MMIO region 0: the register bank
38
* + sysbus IRQ 0: combined timer interrupt TIMINTC
39
* + sysbus IRO 1: timer block 1 interrupt TIMINT1
40
@@ -XXX,XX +XXX,XX @@
41
42
#include "hw/sysbus.h"
43
#include "hw/ptimer.h"
44
+#include "hw/clock.h"
45
#include "qom/object.h"
46
47
#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
49
MemoryRegion iomem;
50
qemu_irq timerintc;
51
uint32_t pclk_frq;
52
+ Clock *timclk;
53
54
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
55
uint32_t timeritcr;
56
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/timer/cmsdk-apb-dualtimer.c
59
+++ b/hw/timer/cmsdk-apb-dualtimer.c
60
@@ -XXX,XX +XXX,XX @@
61
#include "hw/irq.h"
62
#include "hw/qdev-properties.h"
63
#include "hw/registerfields.h"
64
+#include "hw/qdev-clock.h"
65
#include "hw/timer/cmsdk-apb-dualtimer.h"
66
#include "migration/vmstate.h"
67
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
69
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
70
sysbus_init_irq(sbd, &s->timermod[i].timerint);
71
}
72
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
73
}
74
75
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_dualtimermod_vmstate = {
77
78
static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
79
.name = "cmsdk-apb-dualtimer",
80
- .version_id = 1,
81
- .minimum_version_id = 1,
82
+ .version_id = 2,
83
+ .minimum_version_id = 2,
84
.fields = (VMStateField[]) {
85
+ VMSTATE_CLOCK(timclk, CMSDKAPBDualTimer),
86
VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
87
CMSDK_APB_DUALTIMER_NUM_MODULES,
88
1, cmsdk_dualtimermod_vmstate,
89
--
90
2.20.1
91
92
diff view generated by jsdifflib
New patch
1
As the first step in converting the CMSDK_APB_TIMER device to the
2
Clock framework, add a Clock input. For the moment we do nothing
3
with this clock; we will change the behaviour from using the
4
wdogclk-frq property to using the Clock once all the users of this
5
device have been converted to wire up the Clock.
1
6
7
This is a migration compatibility break for machines mps2-an385,
8
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
9
musca-b1, lm3s811evb, lm3s6965evb.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20210128114145.20536-10-peter.maydell@linaro.org
16
Message-id: 20210121190622.22000-10-peter.maydell@linaro.org
17
---
18
include/hw/watchdog/cmsdk-apb-watchdog.h | 3 +++
19
hw/watchdog/cmsdk-apb-watchdog.c | 7 +++++--
20
2 files changed, 8 insertions(+), 2 deletions(-)
21
22
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
25
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
26
@@ -XXX,XX +XXX,XX @@
27
*
28
* QEMU interface:
29
* + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
30
+ * + Clock input "WDOGCLK": clock for the watchdog's timer
31
* + sysbus MMIO region 0: the register bank
32
* + sysbus IRQ 0: watchdog interrupt
33
*
34
@@ -XXX,XX +XXX,XX @@
35
36
#include "hw/sysbus.h"
37
#include "hw/ptimer.h"
38
+#include "hw/clock.h"
39
#include "qom/object.h"
40
41
#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
42
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
43
uint32_t wdogclk_frq;
44
bool is_luminary;
45
struct ptimer_state *timer;
46
+ Clock *wdogclk;
47
48
uint32_t control;
49
uint32_t intstatus;
50
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/watchdog/cmsdk-apb-watchdog.c
53
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
54
@@ -XXX,XX +XXX,XX @@
55
#include "hw/irq.h"
56
#include "hw/qdev-properties.h"
57
#include "hw/registerfields.h"
58
+#include "hw/qdev-clock.h"
59
#include "hw/watchdog/cmsdk-apb-watchdog.h"
60
#include "migration/vmstate.h"
61
62
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
63
s, "cmsdk-apb-watchdog", 0x1000);
64
sysbus_init_mmio(sbd, &s->iomem);
65
sysbus_init_irq(sbd, &s->wdogint);
66
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
67
68
s->is_luminary = false;
69
s->id = cmsdk_apb_watchdog_id;
70
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
71
72
static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
73
.name = "cmsdk-apb-watchdog",
74
- .version_id = 1,
75
- .minimum_version_id = 1,
76
+ .version_id = 2,
77
+ .minimum_version_id = 2,
78
.fields = (VMStateField[]) {
79
+ VMSTATE_CLOCK(wdogclk, CMSDKAPBWatchdog),
80
VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
81
VMSTATE_UINT32(control, CMSDKAPBWatchdog),
82
VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
While we transition the ARMSSE code from integer properties
2
specifying clock frequencies to Clock objects, we want to have the
3
device provide both at once. We want the final name of the main
4
input Clock to be "MAINCLK", following the hardware name.
5
Unfortunately creating an input Clock with a name X creates an
6
under-the-hood QOM property X; for "MAINCLK" this clashes with the
7
existing UINT32 property of that name.
2
8
3
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
9
Rename the UINT32 property to MAINCLK_FRQ so it can coexist with the
4
with.
10
MAINCLK Clock; once the transition is complete MAINCLK_FRQ will be
11
deleted.
5
12
6
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Commit created with:
7
Cc: Jason Wang <jasowang@redhat.com>
14
perl -p -i -e 's/MAINCLK/MAINCLK_FRQ/g' hw/arm/{armsse,mps2-tz,musca}.c include/hw/arm/armsse.h
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20210128114145.20536-11-peter.maydell@linaro.org
21
Message-id: 20210121190622.22000-11-peter.maydell@linaro.org
17
---
22
---
18
hw/arm/fsl-imx6.c | 2 +-
23
include/hw/arm/armsse.h | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
24
hw/arm/armsse.c | 6 +++---
25
hw/arm/mps2-tz.c | 2 +-
26
hw/arm/musca.c | 2 +-
27
4 files changed, 6 insertions(+), 6 deletions(-)
20
28
21
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
29
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
22
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/fsl-imx6.c
31
--- a/include/hw/arm/armsse.h
24
+++ b/hw/arm/fsl-imx6.c
32
+++ b/include/hw/arm/armsse.h
25
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
33
@@ -XXX,XX +XXX,XX @@
34
* QEMU interface:
35
* + QOM property "memory" is a MemoryRegion containing the devices provided
36
* by the board model.
37
- * + QOM property "MAINCLK" is the frequency of the main system clock
38
+ * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
39
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
40
* (In hardware, the SSE-200 permits the number of expansion interrupts
41
* for the two CPUs to be configured separately, but we restrict it to
42
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/armsse.c
45
+++ b/hw/arm/armsse.c
46
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
47
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
48
MemoryRegion *),
49
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
50
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
51
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
52
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
53
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
54
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
55
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
56
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
57
MemoryRegion *),
58
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
59
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
60
+ DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
61
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
62
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
63
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
26
}
65
}
27
66
28
for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
67
if (!s->mainclk_frq) {
29
- object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
68
- error_setg(errp, "MAINCLK property was not set");
30
+ object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
69
+ error_setg(errp, "MAINCLK_FRQ property was not set");
31
qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
70
return;
32
snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
71
}
33
object_property_add_child(obj, name, OBJECT(&s->esdhc[i]), NULL);
72
73
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/arm/mps2-tz.c
76
+++ b/hw/arm/mps2-tz.c
77
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
78
object_property_set_link(OBJECT(&mms->iotkit), "memory",
79
OBJECT(system_memory), &error_abort);
80
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
81
- qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
82
+ qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
83
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
84
85
/*
86
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/musca.c
89
+++ b/hw/arm/musca.c
90
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
91
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
92
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
93
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
94
- qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
95
+ qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
96
/*
97
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
98
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
34
--
99
--
35
2.16.1
100
2.20.1
36
101
37
102
diff view generated by jsdifflib
New patch
1
Create two input clocks on the ARMSSE devices, one for the normal
2
MAINCLK, and one for the 32KHz S32KCLK, and wire these up to the
3
appropriate devices. The old property-based clock frequency setting
4
will remain in place until conversion is complete.
1
5
6
This is a migration compatibility break for machines mps2-an505,
7
mps2-an521, musca-a, musca-b1.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Luc Michel <luc@lmichel.fr>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210128114145.20536-12-peter.maydell@linaro.org
14
Message-id: 20210121190622.22000-12-peter.maydell@linaro.org
15
---
16
include/hw/arm/armsse.h | 6 ++++++
17
hw/arm/armsse.c | 17 +++++++++++++++--
18
2 files changed, 21 insertions(+), 2 deletions(-)
19
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/armsse.h
23
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@
25
* per-CPU identity and control register blocks
26
*
27
* QEMU interface:
28
+ * + Clock input "MAINCLK": clock for CPUs and most peripherals
29
+ * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
30
* + QOM property "memory" is a MemoryRegion containing the devices provided
31
* by the board model.
32
* + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
33
@@ -XXX,XX +XXX,XX @@
34
#include "hw/misc/armsse-mhu.h"
35
#include "hw/misc/unimp.h"
36
#include "hw/or-irq.h"
37
+#include "hw/clock.h"
38
#include "hw/core/split-irq.h"
39
#include "hw/cpu/cluster.h"
40
#include "qom/object.h"
41
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
42
43
uint32_t nsccfg;
44
45
+ Clock *mainclk;
46
+ Clock *s32kclk;
47
+
48
/* Properties */
49
MemoryRegion *board_memory;
50
uint32_t exp_numirq;
51
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/armsse.c
54
+++ b/hw/arm/armsse.c
55
@@ -XXX,XX +XXX,XX @@
56
#include "hw/arm/armsse.h"
57
#include "hw/arm/boot.h"
58
#include "hw/irq.h"
59
+#include "hw/qdev-clock.h"
60
61
/* Format of the System Information block SYS_CONFIG register */
62
typedef enum SysConfigFormat {
63
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
64
assert(info->sram_banks <= MAX_SRAM_BANKS);
65
assert(info->num_cpus <= SSE_MAX_CPUS);
66
67
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
68
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
69
+
70
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
71
72
for (i = 0; i < info->num_cpus; i++) {
73
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
* map its upstream ends to the right place in the container.
75
*/
76
qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
77
+ qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
79
return;
80
}
81
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
82
&error_abort);
83
84
qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
85
+ qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
86
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
87
return;
88
}
89
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
90
&error_abort);
91
92
qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
93
+ qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
94
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
95
return;
96
}
97
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
98
* 0x4002f000: S32K timer
99
*/
100
qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
101
+ qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
102
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
103
return;
104
}
105
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
106
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
107
108
qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
109
+ qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
110
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
111
return;
112
}
113
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
114
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
115
116
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
117
+ qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
118
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
119
return;
120
}
121
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
122
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
123
124
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
125
+ qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
126
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
127
return;
128
}
129
@@ -XXX,XX +XXX,XX @@ static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
130
131
static const VMStateDescription armsse_vmstate = {
132
.name = "iotkit",
133
- .version_id = 1,
134
- .minimum_version_id = 1,
135
+ .version_id = 2,
136
+ .minimum_version_id = 2,
137
.fields = (VMStateField[]) {
138
+ VMSTATE_CLOCK(mainclk, ARMSSE),
139
+ VMSTATE_CLOCK(s32kclk, ARMSSE),
140
VMSTATE_UINT32(nsccfg, ARMSSE),
141
VMSTATE_END_OF_LIST()
142
}
143
--
144
2.20.1
145
146
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
The old-style convenience function cmsdk_apb_timer_create() for
2
creating CMSDK_APB_TIMER objects is used in only two places in
3
mps2.c. Most of the rest of the code in that file uses the new
4
"initialize in place" coding style.
2
5
3
This implements emulation of the new SM4 instructions that have
6
We want to connect up a Clock object which should be done between the
4
been added as an optional extension to the ARMv8 Crypto Extensions
7
object creation and realization; rather than adding a Clock* argument
5
in ARM v8.2.
8
to the convenience function, convert the timer creation code in
9
mps2.c to the same style as is used already for the watchdog,
10
dualtimer and other devices, and delete the now-unused convenience
11
function.
6
12
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
8
Message-id: 20180207111729.15737-5-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20210128114145.20536-13-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-13-peter.maydell@linaro.org
11
---
19
---
12
target/arm/cpu.h | 1 +
20
include/hw/timer/cmsdk-apb-timer.h | 21 ---------------------
13
target/arm/helper.h | 3 ++
21
hw/arm/mps2.c | 18 ++++++++++++++++--
14
target/arm/crypto_helper.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
22
2 files changed, 16 insertions(+), 23 deletions(-)
15
target/arm/translate-a64.c | 8 ++++
16
4 files changed, 103 insertions(+)
17
23
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
26
--- a/include/hw/timer/cmsdk-apb-timer.h
21
+++ b/target/arm/cpu.h
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
28
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
29
uint32_t intstatus;
24
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
25
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
26
+ ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
27
};
30
};
28
31
29
static inline int arm_feature(CPUARMState *env, int feature)
32
-/**
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
33
- * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
34
- * @addr: location in system memory to map registers
35
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
36
- */
37
-static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
38
- qemu_irq timerint,
39
- uint32_t pclk_frq)
40
-{
41
- DeviceState *dev;
42
- SysBusDevice *s;
43
-
44
- dev = qdev_new(TYPE_CMSDK_APB_TIMER);
45
- s = SYS_BUS_DEVICE(dev);
46
- qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
47
- sysbus_realize_and_unref(s, &error_fatal);
48
- sysbus_mmio_map(s, 0, addr);
49
- sysbus_connect_irq(s, 0, timerint);
50
- return dev;
51
-}
52
-
53
#endif
54
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
31
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
56
--- a/hw/arm/mps2.c
33
+++ b/target/arm/helper.h
57
+++ b/hw/arm/mps2.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
58
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
35
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
59
/* CMSDK APB subsystem */
36
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
60
CMSDKAPBDualTimer dualtimer;
37
61
CMSDKAPBWatchdog watchdog;
38
+DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
62
+ CMSDKAPBTimer timer[2];
39
+DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
63
};
64
65
#define TYPE_MPS2_MACHINE "mps2"
66
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
67
}
68
69
/* CMSDK APB subsystem */
70
- cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
71
- cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
72
+ for (i = 0; i < ARRAY_SIZE(mms->timer); i++) {
73
+ g_autofree char *name = g_strdup_printf("timer%d", i);
74
+ hwaddr base = 0x40000000 + i * 0x1000;
75
+ int irqno = 8 + i;
76
+ SysBusDevice *sbd;
40
+
77
+
41
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
78
+ object_initialize_child(OBJECT(mms), name, &mms->timer[i],
42
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
79
+ TYPE_CMSDK_APB_TIMER);
43
DEF_HELPER_2(dc_zva, void, env, i64)
80
+ sbd = SYS_BUS_DEVICE(&mms->timer[i]);
44
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
81
+ qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
45
index XXXXXXX..XXXXXXX 100644
82
+ sysbus_realize_and_unref(sbd, &error_fatal);
46
--- a/target/arm/crypto_helper.c
83
+ sysbus_mmio_map(sbd, 0, base);
47
+++ b/target/arm/crypto_helper.c
84
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
48
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
49
rd[0] = d.l[0];
50
rd[1] = d.l[1];
51
}
52
+
53
+static uint8_t const sm4_sbox[] = {
54
+ 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
55
+ 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
56
+ 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
57
+ 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
58
+ 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
59
+ 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
60
+ 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
61
+ 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
62
+ 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
63
+ 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
64
+ 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
65
+ 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
66
+ 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
67
+ 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
68
+ 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
69
+ 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
70
+ 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
71
+ 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
72
+ 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
73
+ 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
74
+ 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
75
+ 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
76
+ 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
77
+ 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
78
+ 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
79
+ 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
80
+ 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
81
+ 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
82
+ 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
83
+ 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
84
+ 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
85
+ 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
86
+};
87
+
88
+void HELPER(crypto_sm4e)(void *vd, void *vn)
89
+{
90
+ uint64_t *rd = vd;
91
+ uint64_t *rn = vn;
92
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
93
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
94
+ uint32_t t, i;
95
+
96
+ for (i = 0; i < 4; i++) {
97
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
98
+ CR_ST_WORD(d, (i + 2) % 4) ^
99
+ CR_ST_WORD(d, (i + 3) % 4) ^
100
+ CR_ST_WORD(n, i);
101
+
102
+ t = sm4_sbox[t & 0xff] |
103
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
104
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
105
+ sm4_sbox[(t >> 24) & 0xff] << 24;
106
+
107
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
108
+ rol32(t, 24);
109
+ }
85
+ }
110
+
86
+
111
+ rd[0] = d.l[0];
87
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
112
+ rd[1] = d.l[1];
88
TYPE_CMSDK_APB_DUALTIMER);
113
+}
89
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
114
+
115
+void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
116
+{
117
+ uint64_t *rd = vd;
118
+ uint64_t *rn = vn;
119
+ uint64_t *rm = vm;
120
+ union CRYPTO_STATE d;
121
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
122
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
123
+ uint32_t t, i;
124
+
125
+ d = n;
126
+ for (i = 0; i < 4; i++) {
127
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
128
+ CR_ST_WORD(d, (i + 2) % 4) ^
129
+ CR_ST_WORD(d, (i + 3) % 4) ^
130
+ CR_ST_WORD(m, i);
131
+
132
+ t = sm4_sbox[t & 0xff] |
133
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
134
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
135
+ sm4_sbox[(t >> 24) & 0xff] << 24;
136
+
137
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
138
+ }
139
+
140
+ rd[0] = d.l[0];
141
+ rd[1] = d.l[1];
142
+}
143
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-a64.c
146
+++ b/target/arm/translate-a64.c
147
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
148
feature = ARM_FEATURE_V8_SM3;
149
genfn = gen_helper_crypto_sm3partw2;
150
break;
151
+ case 2: /* SM4EKEY */
152
+ feature = ARM_FEATURE_V8_SM4;
153
+ genfn = gen_helper_crypto_sm4ekey;
154
+ break;
155
default:
156
unallocated_encoding(s);
157
return;
158
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
159
feature = ARM_FEATURE_V8_SHA512;
160
genfn = gen_helper_crypto_sha512su0;
161
break;
162
+ case 1: /* SM4E */
163
+ feature = ARM_FEATURE_V8_SM4;
164
+ genfn = gen_helper_crypto_sm4e;
165
+ break;
166
default:
167
unallocated_encoding(s);
168
return;
169
--
90
--
170
2.16.1
91
2.20.1
171
92
172
93
diff view generated by jsdifflib
New patch
1
Create a fixed-frequency Clock object to be the SYSCLK, and wire it
2
up to the devices that require it.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-14-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-14-peter.maydell@linaro.org
10
---
11
hw/arm/mps2.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
17
+++ b/hw/arm/mps2.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/net/lan9118.h"
20
#include "net/net.h"
21
#include "hw/watchdog/cmsdk-apb-watchdog.h"
22
+#include "hw/qdev-clock.h"
23
#include "qom/object.h"
24
25
typedef enum MPS2FPGAType {
26
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
27
CMSDKAPBDualTimer dualtimer;
28
CMSDKAPBWatchdog watchdog;
29
CMSDKAPBTimer timer[2];
30
+ Clock *sysclk;
31
};
32
33
#define TYPE_MPS2_MACHINE "mps2"
34
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
35
exit(EXIT_FAILURE);
36
}
37
38
+ /* This clock doesn't need migration because it is fixed-frequency */
39
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
40
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
41
+
42
/* The FPGA images have an odd combination of different RAMs,
43
* because in hardware they are different implementations and
44
* connected to different buses, giving varying performance/size
45
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
46
TYPE_CMSDK_APB_TIMER);
47
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
48
qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
49
+ qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
50
sysbus_realize_and_unref(sbd, &error_fatal);
51
sysbus_mmio_map(sbd, 0, base);
52
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
53
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
54
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
55
TYPE_CMSDK_APB_DUALTIMER);
56
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
57
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
58
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
59
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
60
qdev_get_gpio_in(armv7m, 10));
61
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
62
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
63
TYPE_CMSDK_APB_WATCHDOG);
64
qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
65
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
67
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
68
qdev_get_gpio_in_named(armv7m, "NMI", 0));
69
--
70
2.20.1
71
72
diff view generated by jsdifflib
New patch
1
Create and connect the two clocks needed by the ARMSSE.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210128114145.20536-15-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-15-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 13 +++++++++++++
11
1 file changed, 13 insertions(+)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/net/lan9118.h"
19
#include "net/net.h"
20
#include "hw/core/split-irq.h"
21
+#include "hw/qdev-clock.h"
22
#include "qom/object.h"
23
24
#define MPS2TZ_NUMIRQ 92
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
qemu_or_irq uart_irq_orgate;
27
DeviceState *lan9118;
28
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
29
+ Clock *sysclk;
30
+ Clock *s32kclk;
31
};
32
33
#define TYPE_MPS2TZ_MACHINE "mps2tz"
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
35
36
/* Main SYSCLK frequency in Hz */
37
#define SYSCLK_FRQ 20000000
38
+/* Slow 32Khz S32KCLK frequency in Hz */
39
+#define S32KCLK_FRQ (32 * 1000)
40
41
/* Create an alias of an entire original MemoryRegion @orig
42
* located at @base in the memory map.
43
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
44
exit(EXIT_FAILURE);
45
}
46
47
+ /* These clocks don't need migration because they are fixed-frequency */
48
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
49
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
50
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
51
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
52
+
53
object_initialize_child(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
54
mmc->armsse_type);
55
iotkitdev = DEVICE(&mms->iotkit);
56
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
57
OBJECT(system_memory), &error_abort);
58
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
59
qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
60
+ qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
61
+ qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
62
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
63
64
/*
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Create and connect the two clocks needed by the ARMSSE.
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20180123035349.24538-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210128114145.20536-16-peter.maydell@linaro.org
8
Message-id: 20210121190622.22000-16-peter.maydell@linaro.org
8
---
9
---
9
target/arm/cpu.h | 12 ++++++++++++
10
hw/arm/musca.c | 12 ++++++++++++
10
1 file changed, 12 insertions(+)
11
1 file changed, 12 insertions(+)
11
12
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
--- a/hw/arm/musca.c
15
+++ b/target/arm/cpu.h
16
+++ b/hw/arm/musca.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
17
@@ -XXX,XX +XXX,XX @@
17
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
18
#include "hw/misc/tz-ppc.h"
18
} ARMVectorReg;
19
#include "hw/misc/unimp.h"
19
20
#include "hw/rtc/pl031.h"
20
+/* In AArch32 mode, predicate registers do not exist at all. */
21
+#include "hw/qdev-clock.h"
21
+#ifdef TARGET_AARCH64
22
#include "qom/object.h"
22
+typedef struct ARMPredicateReg {
23
23
+ uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
24
#define MUSCA_NUMIRQ_MAX 96
24
+} ARMPredicateReg;
25
@@ -XXX,XX +XXX,XX @@ struct MuscaMachineState {
25
+#endif
26
UnimplementedDeviceState sdio;
27
UnimplementedDeviceState gpio;
28
UnimplementedDeviceState cryptoisland;
29
+ Clock *sysclk;
30
+ Clock *s32kclk;
31
};
32
33
#define TYPE_MUSCA_MACHINE "musca"
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MuscaMachineState, MuscaMachineClass, MUSCA_MACHINE)
35
* don't model that in our SSE-200 model yet.
36
*/
37
#define SYSCLK_FRQ 40000000
38
+/* Slow 32Khz S32KCLK frequency in Hz */
39
+#define S32KCLK_FRQ (32 * 1000)
40
41
static qemu_irq get_sse_irq_in(MuscaMachineState *mms, int irqno)
42
{
43
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
44
exit(1);
45
}
46
47
+ mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
48
+ clock_set_hz(mms->sysclk, SYSCLK_FRQ);
49
+ mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
50
+ clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
26
+
51
+
27
52
object_initialize_child(OBJECT(machine), "sse-200", &mms->sse,
28
typedef struct CPUARMState {
53
TYPE_SSE200);
29
/* Regs for current mode. */
54
ssedev = DEVICE(&mms->sse);
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
55
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
31
struct {
56
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
32
ARMVectorReg zregs[32];
57
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
33
58
qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
34
+#ifdef TARGET_AARCH64
59
+ qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
35
+ /* Store FFR as pregs[16] to make it easier to treat as any other. */
60
+ qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
36
+ ARMPredicateReg pregs[17];
61
/*
37
+#endif
62
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
38
+
63
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
39
uint32_t xregs[16];
40
/* We store these fpcsr fields separately for convenience. */
41
int vec_len;
42
--
64
--
43
2.16.1
65
2.20.1
44
66
45
67
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Convert the SSYS code in the Stellaris boards (which encapsulates the
2
2
system registers) to a proper QOM device. This will provide us with
3
IP block found on several generations of i.MX family does not use
3
somewhere to put the output Clock whose frequency depends on the
4
vanilla SDHCI implementation and it comes with a number of quirks.
4
setting of the PLL configuration registers.
5
5
6
Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
6
This is a migration compatibility break for lm3s811evb, lm3s6965evb.
7
support unmodified Linux guest driver.
7
8
8
We use 3-phase reset here because the Clock will need to propagate
9
Cc: Peter Maydell <peter.maydell@linaro.org>
9
its value in the hold phase.
10
Cc: Jason Wang <jasowang@redhat.com>
10
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
For the moment we reset the device during the board creation so that
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
12
the system_clock_scale global gets set; this will be removed in a
13
Cc: Michael S. Tsirkin <mst@redhat.com>
13
subsequent commit.
14
Cc: qemu-devel@nongnu.org
14
15
Cc: qemu-arm@nongnu.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Cc: yurovsky@gmail.com
16
Reviewed-by: Luc Michel <luc@lmichel.fr>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
[PMM: define and use ESDHC_UNDOCUMENTED_REG27]
19
Message-id: 20210128114145.20536-17-peter.maydell@linaro.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20210121190622.22000-17-peter.maydell@linaro.org
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
---
22
---
23
hw/sd/sdhci-internal.h | 23 +++++
23
hw/arm/stellaris.c | 132 ++++++++++++++++++++++++++++++++++++---------
24
include/hw/sd/sdhci.h | 13 +++
24
1 file changed, 107 insertions(+), 25 deletions(-)
25
hw/sd/sdhci.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++-
25
26
3 files changed, 265 insertions(+), 1 deletion(-)
26
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
27
28
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
29
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci-internal.h
28
--- a/hw/arm/stellaris.c
31
+++ b/hw/sd/sdhci-internal.h
29
+++ b/hw/arm/stellaris.c
32
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
33
31
34
/* R/W Host control Register 0x0 */
32
/* System controller. */
35
#define SDHC_HOSTCTL 0x28
33
36
+#define SDHC_CTRL_LED 0x01
34
-typedef struct {
37
#define SDHC_CTRL_DMA_CHECK_MASK 0x18
35
+#define TYPE_STELLARIS_SYS "stellaris-sys"
38
#define SDHC_CTRL_SDMA 0x00
36
+OBJECT_DECLARE_SIMPLE_TYPE(ssys_state, STELLARIS_SYS)
39
#define SDHC_CTRL_ADMA1_32 0x08
37
+
40
#define SDHC_CTRL_ADMA2_32 0x10
38
+struct ssys_state {
41
#define SDHC_CTRL_ADMA2_64 0x18
39
+ SysBusDevice parent_obj;
42
#define SDHC_DMA_TYPE(x) ((x) & SDHC_CTRL_DMA_CHECK_MASK)
40
+
43
+#define SDHC_CTRL_4BITBUS 0x02
41
MemoryRegion iomem;
44
+#define SDHC_CTRL_8BITBUS 0x20
42
uint32_t pborctl;
45
+#define SDHC_CTRL_CDTEST_INS 0x40
43
uint32_t ldopctl;
46
+#define SDHC_CTRL_CDTEST_EN 0x80
44
@@ -XXX,XX +XXX,XX @@ typedef struct {
47
+
45
uint32_t dcgc[3];
48
46
uint32_t clkvclr;
49
/* R/W Power Control Register 0x0 */
47
uint32_t ldoarst;
50
#define SDHC_PWRCON 0x29
48
+ qemu_irq irq;
51
@@ -XXX,XX +XXX,XX @@ enum {
49
+ /* Properties (all read-only registers) */
52
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
50
uint32_t user0;
51
uint32_t user1;
52
- qemu_irq irq;
53
- stellaris_board_info *board;
54
-} ssys_state;
55
+ uint32_t did0;
56
+ uint32_t did1;
57
+ uint32_t dc0;
58
+ uint32_t dc1;
59
+ uint32_t dc2;
60
+ uint32_t dc3;
61
+ uint32_t dc4;
62
+};
63
64
static void ssys_update(ssys_state *s)
65
{
66
@@ -XXX,XX +XXX,XX @@ static uint32_t pllcfg_fury[16] = {
67
68
static int ssys_board_class(const ssys_state *s)
69
{
70
- uint32_t did0 = s->board->did0;
71
+ uint32_t did0 = s->did0;
72
switch (did0 & DID0_VER_MASK) {
73
case DID0_VER_0:
74
return DID0_CLASS_SANDSTORM;
75
@@ -XXX,XX +XXX,XX @@ static uint64_t ssys_read(void *opaque, hwaddr offset,
76
77
switch (offset) {
78
case 0x000: /* DID0 */
79
- return s->board->did0;
80
+ return s->did0;
81
case 0x004: /* DID1 */
82
- return s->board->did1;
83
+ return s->did1;
84
case 0x008: /* DC0 */
85
- return s->board->dc0;
86
+ return s->dc0;
87
case 0x010: /* DC1 */
88
- return s->board->dc1;
89
+ return s->dc1;
90
case 0x014: /* DC2 */
91
- return s->board->dc2;
92
+ return s->dc2;
93
case 0x018: /* DC3 */
94
- return s->board->dc3;
95
+ return s->dc3;
96
case 0x01c: /* DC4 */
97
- return s->board->dc4;
98
+ return s->dc4;
99
case 0x030: /* PBORCTL */
100
return s->pborctl;
101
case 0x034: /* LDOPCTL */
102
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ssys_ops = {
103
.endianness = DEVICE_NATIVE_ENDIAN,
53
};
104
};
54
105
55
+extern const VMStateDescription sdhci_vmstate;
106
-static void ssys_reset(void *opaque)
56
+
107
+static void stellaris_sys_reset_enter(Object *obj, ResetType type)
57
+
108
{
58
+#define ESDHC_MIX_CTRL 0x48
109
- ssys_state *s = (ssys_state *)opaque;
59
+#define ESDHC_VENDOR_SPEC 0xc0
110
+ ssys_state *s = STELLARIS_SYS(obj);
60
+#define ESDHC_DLL_CTRL 0x60
111
61
+
112
s->pborctl = 0x7ffd;
62
+#define ESDHC_TUNING_CTRL 0xcc
113
s->rcc = 0x078e3ac0;
63
+#define ESDHC_TUNE_CTRL_STATUS 0x68
114
@@ -XXX,XX +XXX,XX @@ static void ssys_reset(void *opaque)
64
+#define ESDHC_WTMK_LVL 0x44
115
s->rcgc[0] = 1;
65
+
116
s->scgc[0] = 1;
66
+/* Undocumented register used by guests working around erratum ERR004536 */
117
s->dcgc[0] = 1;
67
+#define ESDHC_UNDOCUMENTED_REG27 0x6c
118
+}
68
+
119
+
69
+#define ESDHC_CTRL_4BITBUS (0x1 << 1)
120
+static void stellaris_sys_reset_hold(Object *obj)
70
+#define ESDHC_CTRL_8BITBUS (0x2 << 1)
121
+{
71
+
122
+ ssys_state *s = STELLARIS_SYS(obj);
72
#endif
123
+
73
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
124
ssys_calculate_system_clock(s);
74
index XXXXXXX..XXXXXXX 100644
75
--- a/include/hw/sd/sdhci.h
76
+++ b/include/hw/sd/sdhci.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
78
AddressSpace sysbus_dma_as;
79
AddressSpace *dma_as;
80
MemoryRegion *dma_mr;
81
+ const MemoryRegionOps *io_ops;
82
83
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
84
QEMUTimer *transfer_timer;
85
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
86
87
/* Configurable properties */
88
bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
89
+ uint32_t quirks;
90
} SDHCIState;
91
92
+/*
93
+ * Controller does not provide transfer-complete interrupt when not
94
+ * busy.
95
+ *
96
+ * NOTE: This definition is taken out of Linux kernel and so the
97
+ * original bit number is preserved
98
+ */
99
+#define SDHCI_QUIRK_NO_BUSY_IRQ BIT(14)
100
+
101
#define TYPE_PCI_SDHCI "sdhci-pci"
102
#define PCI_SDHCI(obj) OBJECT_CHECK(SDHCIState, (obj), TYPE_PCI_SDHCI)
103
104
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
105
#define SYSBUS_SDHCI(obj) \
106
OBJECT_CHECK(SDHCIState, (obj), TYPE_SYSBUS_SDHCI)
107
108
+#define TYPE_IMX_USDHC "imx-usdhc"
109
+
110
#endif /* SDHCI_H */
111
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/sd/sdhci.c
114
+++ b/hw/sd/sdhci.c
115
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
116
}
117
}
118
119
- if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
120
+ if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
121
+ (s->norintstsen & SDHC_NISEN_TRSCMP) &&
122
(s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
123
s->norintsts |= SDHC_NIS_TRSCMP;
124
}
125
@@ -XXX,XX +XXX,XX @@ static void sdhci_initfn(SDHCIState *s)
126
127
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
128
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
129
+
130
+ s->io_ops = &sdhci_mmio_ops;
131
}
125
}
132
126
133
static void sdhci_uninitfn(SDHCIState *s)
127
+static void stellaris_sys_reset_exit(Object *obj)
134
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
128
+{
129
+}
130
+
131
static int stellaris_sys_post_load(void *opaque, int version_id)
132
{
133
ssys_state *s = opaque;
134
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
135
}
135
}
136
136
};
137
sysbus_init_irq(sbd, &s->irq);
137
138
+
138
+static Property stellaris_sys_properties[] = {
139
+ memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
139
+ DEFINE_PROP_UINT32("user0", ssys_state, user0, 0),
140
+ SDHC_REGISTERS_MAP_SIZE);
140
+ DEFINE_PROP_UINT32("user1", ssys_state, user1, 0),
141
+
141
+ DEFINE_PROP_UINT32("did0", ssys_state, did0, 0),
142
sysbus_init_mmio(sbd, &s->iomem);
142
+ DEFINE_PROP_UINT32("did1", ssys_state, did1, 0),
143
+ DEFINE_PROP_UINT32("dc0", ssys_state, dc0, 0),
144
+ DEFINE_PROP_UINT32("dc1", ssys_state, dc1, 0),
145
+ DEFINE_PROP_UINT32("dc2", ssys_state, dc2, 0),
146
+ DEFINE_PROP_UINT32("dc3", ssys_state, dc3, 0),
147
+ DEFINE_PROP_UINT32("dc4", ssys_state, dc4, 0),
148
+ DEFINE_PROP_END_OF_LIST()
149
+};
150
+
151
+static void stellaris_sys_instance_init(Object *obj)
152
+{
153
+ ssys_state *s = STELLARIS_SYS(obj);
154
+ SysBusDevice *sbd = SYS_BUS_DEVICE(s);
155
+
156
+ memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
157
+ sysbus_init_mmio(sbd, &s->iomem);
158
+ sysbus_init_irq(sbd, &s->irq);
159
+}
160
+
161
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
162
stellaris_board_info * board,
163
uint8_t *macaddr)
164
{
165
- ssys_state *s;
166
+ DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
167
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
168
169
- s = g_new0(ssys_state, 1);
170
- s->irq = irq;
171
- s->board = board;
172
/* Most devices come preprogrammed with a MAC address in the user data. */
173
- s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
174
- s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
175
+ qdev_prop_set_uint32(dev, "user0",
176
+ macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16));
177
+ qdev_prop_set_uint32(dev, "user1",
178
+ macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16));
179
+ qdev_prop_set_uint32(dev, "did0", board->did0);
180
+ qdev_prop_set_uint32(dev, "did1", board->did1);
181
+ qdev_prop_set_uint32(dev, "dc0", board->dc0);
182
+ qdev_prop_set_uint32(dev, "dc1", board->dc1);
183
+ qdev_prop_set_uint32(dev, "dc2", board->dc2);
184
+ qdev_prop_set_uint32(dev, "dc3", board->dc3);
185
+ qdev_prop_set_uint32(dev, "dc4", board->dc4);
186
+
187
+ sysbus_realize_and_unref(sbd, &error_fatal);
188
+ sysbus_mmio_map(sbd, 0, base);
189
+ sysbus_connect_irq(sbd, 0, irq);
190
+
191
+ /*
192
+ * Normally we should not be resetting devices like this during
193
+ * board creation. For the moment we need to do so, because
194
+ * system_clock_scale will only get set when the STELLARIS_SYS
195
+ * device is reset, and we need its initial value to pass to
196
+ * the watchdog device. This hack can be removed once the
197
+ * watchdog has been converted to use a Clock input instead.
198
+ */
199
+ device_cold_reset(dev);
200
201
- memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
202
- memory_region_add_subregion(get_system_memory(), base, &s->iomem);
203
- ssys_reset(s);
204
- vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s);
205
return 0;
143
}
206
}
144
207
145
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_bus_info = {
208
-
146
.class_init = sdhci_bus_class_init,
209
/* I2C controller. */
210
211
#define TYPE_STELLARIS_I2C "stellaris-i2c"
212
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_adc_info = {
213
.class_init = stellaris_adc_class_init,
147
};
214
};
148
215
149
+static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
216
+static void stellaris_sys_class_init(ObjectClass *klass, void *data)
150
+{
217
+{
151
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
218
+ DeviceClass *dc = DEVICE_CLASS(klass);
152
+ uint32_t ret;
219
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
153
+ uint16_t hostctl;
220
+
154
+
221
+ dc->vmsd = &vmstate_stellaris_sys;
155
+ switch (offset) {
222
+ rc->phases.enter = stellaris_sys_reset_enter;
156
+ default:
223
+ rc->phases.hold = stellaris_sys_reset_hold;
157
+ return sdhci_read(opaque, offset, size);
224
+ rc->phases.exit = stellaris_sys_reset_exit;
158
+
225
+ device_class_set_props(dc, stellaris_sys_properties);
159
+ case SDHC_HOSTCTL:
226
+}
160
+ /*
227
+
161
+ * For a detailed explanation on the following bit
228
+static const TypeInfo stellaris_sys_info = {
162
+ * manipulation code see comments in a similar part of
229
+ .name = TYPE_STELLARIS_SYS,
163
+ * usdhc_write()
230
+ .parent = TYPE_SYS_BUS_DEVICE,
164
+ */
231
+ .instance_size = sizeof(ssys_state),
165
+ hostctl = SDHC_DMA_TYPE(s->hostctl) << (8 - 3);
232
+ .instance_init = stellaris_sys_instance_init,
166
+
233
+ .class_init = stellaris_sys_class_init,
167
+ if (s->hostctl & SDHC_CTRL_8BITBUS) {
168
+ hostctl |= ESDHC_CTRL_8BITBUS;
169
+ }
170
+
171
+ if (s->hostctl & SDHC_CTRL_4BITBUS) {
172
+ hostctl |= ESDHC_CTRL_4BITBUS;
173
+ }
174
+
175
+ ret = hostctl;
176
+ ret |= (uint32_t)s->blkgap << 16;
177
+ ret |= (uint32_t)s->wakcon << 24;
178
+
179
+ break;
180
+
181
+ case ESDHC_DLL_CTRL:
182
+ case ESDHC_TUNE_CTRL_STATUS:
183
+ case ESDHC_UNDOCUMENTED_REG27:
184
+ case ESDHC_TUNING_CTRL:
185
+ case ESDHC_VENDOR_SPEC:
186
+ case ESDHC_MIX_CTRL:
187
+ case ESDHC_WTMK_LVL:
188
+ ret = 0;
189
+ break;
190
+ }
191
+
192
+ return ret;
193
+}
194
+
195
+static void
196
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
197
+{
198
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
199
+ uint8_t hostctl;
200
+ uint32_t value = (uint32_t)val;
201
+
202
+ switch (offset) {
203
+ case ESDHC_DLL_CTRL:
204
+ case ESDHC_TUNE_CTRL_STATUS:
205
+ case ESDHC_UNDOCUMENTED_REG27:
206
+ case ESDHC_TUNING_CTRL:
207
+ case ESDHC_WTMK_LVL:
208
+ case ESDHC_VENDOR_SPEC:
209
+ break;
210
+
211
+ case SDHC_HOSTCTL:
212
+ /*
213
+ * Here's What ESDHCI has at offset 0x28 (SDHC_HOSTCTL)
214
+ *
215
+ * 7 6 5 4 3 2 1 0
216
+ * |-----------+--------+--------+-----------+----------+---------|
217
+ * | Card | Card | Endian | DATA3 | Data | Led |
218
+ * | Detect | Detect | Mode | as Card | Transfer | Control |
219
+ * | Signal | Test | | Detection | Width | |
220
+ * | Selection | Level | | Pin | | |
221
+ * |-----------+--------+--------+-----------+----------+---------|
222
+ *
223
+ * and 0x29
224
+ *
225
+ * 15 10 9 8
226
+ * |----------+------|
227
+ * | Reserved | DMA |
228
+ * | | Sel. |
229
+ * | | |
230
+ * |----------+------|
231
+ *
232
+ * and here's what SDCHI spec expects those offsets to be:
233
+ *
234
+ * 0x28 (Host Control Register)
235
+ *
236
+ * 7 6 5 4 3 2 1 0
237
+ * |--------+--------+----------+------+--------+----------+---------|
238
+ * | Card | Card | Extended | DMA | High | Data | LED |
239
+ * | Detect | Detect | Data | Sel. | Speed | Transfer | Control |
240
+ * | Signal | Test | Transfer | | Enable | Width | |
241
+ * | Sel. | Level | Width | | | | |
242
+ * |--------+--------+----------+------+--------+----------+---------|
243
+ *
244
+ * and 0x29 (Power Control Register)
245
+ *
246
+ * |----------------------------------|
247
+ * | Power Control Register |
248
+ * | |
249
+ * | Description omitted, |
250
+ * | since it has no analog in ESDHCI |
251
+ * | |
252
+ * |----------------------------------|
253
+ *
254
+ * Since offsets 0x2A and 0x2B should be compatible between
255
+ * both IP specs we only need to reconcile least 16-bit of the
256
+ * word we've been given.
257
+ */
258
+
259
+ /*
260
+ * First, save bits 7 6 and 0 since they are identical
261
+ */
262
+ hostctl = value & (SDHC_CTRL_LED |
263
+ SDHC_CTRL_CDTEST_INS |
264
+ SDHC_CTRL_CDTEST_EN);
265
+ /*
266
+ * Second, split "Data Transfer Width" from bits 2 and 1 in to
267
+ * bits 5 and 1
268
+ */
269
+ if (value & ESDHC_CTRL_8BITBUS) {
270
+ hostctl |= SDHC_CTRL_8BITBUS;
271
+ }
272
+
273
+ if (value & ESDHC_CTRL_4BITBUS) {
274
+ hostctl |= ESDHC_CTRL_4BITBUS;
275
+ }
276
+
277
+ /*
278
+ * Third, move DMA select from bits 9 and 8 to bits 4 and 3
279
+ */
280
+ hostctl |= SDHC_DMA_TYPE(value >> (8 - 3));
281
+
282
+ /*
283
+ * Now place the corrected value into low 16-bit of the value
284
+ * we are going to give standard SDHCI write function
285
+ *
286
+ * NOTE: This transformation should be the inverse of what can
287
+ * be found in drivers/mmc/host/sdhci-esdhc-imx.c in Linux
288
+ * kernel
289
+ */
290
+ value &= ~UINT16_MAX;
291
+ value |= hostctl;
292
+ value |= (uint16_t)s->pwrcon << 8;
293
+
294
+ sdhci_write(opaque, offset, value, size);
295
+ break;
296
+
297
+ case ESDHC_MIX_CTRL:
298
+ /*
299
+ * So, when SD/MMC stack in Linux tries to write to "Transfer
300
+ * Mode Register", ESDHC i.MX quirk code will translate it
301
+ * into a write to ESDHC_MIX_CTRL, so we do the opposite in
302
+ * order to get where we started
303
+ *
304
+ * Note that Auto CMD23 Enable bit is located in a wrong place
305
+ * on i.MX, but since it is not used by QEMU we do not care.
306
+ *
307
+ * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
308
+ * here becuase it will result in a call to
309
+ * sdhci_send_command(s) which we don't want.
310
+ *
311
+ */
312
+ s->trnmod = value & UINT16_MAX;
313
+ break;
314
+ case SDHC_TRNMOD:
315
+ /*
316
+ * Similar to above, but this time a write to "Command
317
+ * Register" will be translated into a 4-byte write to
318
+ * "Transfer Mode register" where lower 16-bit of value would
319
+ * be set to zero. So what we do is fill those bits with
320
+ * cached value from s->trnmod and let the SDHCI
321
+ * infrastructure handle the rest
322
+ */
323
+ sdhci_write(opaque, offset, val | s->trnmod, size);
324
+ break;
325
+ case SDHC_BLKSIZE:
326
+ /*
327
+ * ESDHCI does not implement "Host SDMA Buffer Boundary", and
328
+ * Linux driver will try to zero this field out which will
329
+ * break the rest of SDHCI emulation.
330
+ *
331
+ * Linux defaults to maximum possible setting (512K boundary)
332
+ * and it seems to be the only option that i.MX IP implements,
333
+ * so we artificially set it to that value.
334
+ */
335
+ val |= 0x7 << 12;
336
+ /* FALLTHROUGH */
337
+ default:
338
+ sdhci_write(opaque, offset, val, size);
339
+ break;
340
+ }
341
+}
342
+
343
+
344
+static const MemoryRegionOps usdhc_mmio_ops = {
345
+ .read = usdhc_read,
346
+ .write = usdhc_write,
347
+ .valid = {
348
+ .min_access_size = 1,
349
+ .max_access_size = 4,
350
+ .unaligned = false
351
+ },
352
+ .endianness = DEVICE_LITTLE_ENDIAN,
353
+};
234
+};
354
+
235
+
355
+static void imx_usdhc_init(Object *obj)
236
static void stellaris_register_types(void)
356
+{
237
{
357
+ SDHCIState *s = SYSBUS_SDHCI(obj);
238
type_register_static(&stellaris_i2c_info);
358
+
239
type_register_static(&stellaris_gptm_info);
359
+ s->io_ops = &usdhc_mmio_ops;
240
type_register_static(&stellaris_adc_info);
360
+ s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
241
+ type_register_static(&stellaris_sys_info);
361
+}
362
+
363
+static const TypeInfo imx_usdhc_info = {
364
+ .name = TYPE_IMX_USDHC,
365
+ .parent = TYPE_SYSBUS_SDHCI,
366
+ .instance_init = imx_usdhc_init,
367
+};
368
+
369
static void sdhci_register_types(void)
370
{
371
type_register_static(&sdhci_pci_info);
372
type_register_static(&sdhci_sysbus_info);
373
type_register_static(&sdhci_bus_info);
374
+ type_register_static(&imx_usdhc_info);
375
}
242
}
376
243
377
type_init(sdhci_register_types)
244
type_init(stellaris_register_types)
378
--
245
--
379
2.16.1
246
2.20.1
380
247
381
248
diff view generated by jsdifflib
1
In the v8M architecture, if the process of taking an exception
1
Create and connect the Clock input for the watchdog device on the
2
results in a further exception this is called a derived exception
2
Stellaris boards. Because the Stellaris boards model the ability to
3
(for example, an MPU exception when writing the exception frame to
3
change the clock rate by programming PLL registers, we have to create
4
memory). If the derived exception happens while pushing the initial
4
an output Clock on the ssys_state device and wire it up to the
5
stack frame, we must ignore any subsequent possible exception
5
watchdog.
6
pushing the callee-saves registers.
7
6
8
In preparation for making the stack writes check for exceptions,
7
Note that the old comment on ssys_calculate_system_clock() got the
9
add a return value from v7m_push_stack() and a new parameter to
8
units wrong -- system_clock_scale is in nanoseconds, not
10
v7m_exception_taken(), so that the former can tell the latter that
9
milliseconds. Improve the commentary to clarify how we are
11
it needs to ignore failures to write to the stack. We also plumb
10
calculating the period.
12
the argument through to v7m_push_callee_stack(), which is where
13
the code to ignore the failures will be.
14
15
(Note that the v8M ARM pseudocode structures this slightly differently:
16
derived exceptions cause the attempt to process the original
17
exception to be abandoned; then at the top level it calls
18
DerivedLateArrival to prioritize the derived exception and call
19
TakeException from there. We choose to let the NVIC do the prioritization
20
and continue forward with a call to TakeException which will then
21
take either the original or the derived exception. The effect is
22
the same, but this structure works better for QEMU because we don't
23
have a convenient top level place to do the abandon-and-retry logic.)
24
11
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Luc Michel <luc@lmichel.fr>
27
Message-id: 1517324542-6607-4-git-send-email-peter.maydell@linaro.org
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210128114145.20536-18-peter.maydell@linaro.org
17
Message-id: 20210121190622.22000-18-peter.maydell@linaro.org
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
28
---
19
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++------------
20
hw/arm/stellaris.c | 43 +++++++++++++++++++++++++++++++------------
30
1 file changed, 23 insertions(+), 12 deletions(-)
21
1 file changed, 31 insertions(+), 12 deletions(-)
31
22
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
33
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
25
--- a/hw/arm/stellaris.c
35
+++ b/target/arm/helper.c
26
+++ b/hw/arm/stellaris.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
27
@@ -XXX,XX +XXX,XX @@
37
return addr;
28
#include "hw/watchdog/cmsdk-apb-watchdog.h"
29
#include "migration/vmstate.h"
30
#include "hw/misc/unimp.h"
31
+#include "hw/qdev-clock.h"
32
#include "cpu.h"
33
#include "qom/object.h"
34
35
@@ -XXX,XX +XXX,XX @@ struct ssys_state {
36
uint32_t clkvclr;
37
uint32_t ldoarst;
38
qemu_irq irq;
39
+ Clock *sysclk;
40
/* Properties (all read-only registers) */
41
uint32_t user0;
42
uint32_t user1;
43
@@ -XXX,XX +XXX,XX @@ static bool ssys_use_rcc2(ssys_state *s)
38
}
44
}
39
45
40
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
46
/*
41
+static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
47
- * Caculate the sys. clock period in ms.
42
+ bool ignore_faults)
48
+ * Calculate the system clock period. We only want to propagate
49
+ * this change to the rest of the system if we're not being called
50
+ * from migration post-load.
51
*/
52
-static void ssys_calculate_system_clock(ssys_state *s)
53
+static void ssys_calculate_system_clock(ssys_state *s, bool propagate_clock)
43
{
54
{
44
/* For v8M, push the callee-saves register part of the stack frame.
55
+ /*
45
* Compare the v8M pseudocode PushCalleeStack().
56
+ * SYSDIV field specifies divisor: 0 == /1, 1 == /2, etc. Input
46
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
57
+ * clock is 200MHz, which is a period of 5 ns. Dividing the clock
47
*frame_sp_p = frameptr;
58
+ * frequency by X is the same as multiplying the period by X.
59
+ */
60
if (ssys_use_rcc2(s)) {
61
system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
62
} else {
63
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
64
}
65
+ clock_set_ns(s->sysclk, system_clock_scale);
66
+ if (propagate_clock) {
67
+ clock_propagate(s->sysclk);
68
+ }
48
}
69
}
49
70
50
-static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
71
static void ssys_write(void *opaque, hwaddr offset,
51
+static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
72
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
52
+ bool ignore_stackfaults)
73
s->int_status |= (1 << 6);
74
}
75
s->rcc = value;
76
- ssys_calculate_system_clock(s);
77
+ ssys_calculate_system_clock(s, true);
78
break;
79
case 0x070: /* RCC2 */
80
if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
81
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
82
s->int_status |= (1 << 6);
83
}
84
s->rcc2 = value;
85
- ssys_calculate_system_clock(s);
86
+ ssys_calculate_system_clock(s, true);
87
break;
88
case 0x100: /* RCGC0 */
89
s->rcgc[0] = value;
90
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_reset_hold(Object *obj)
53
{
91
{
54
/* Do the "take the exception" parts of exception entry,
92
ssys_state *s = STELLARIS_SYS(obj);
55
* but not the pushing of state to the stack. This is
93
56
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
94
- ssys_calculate_system_clock(s);
57
*/
95
+ /* OK to propagate clocks from the hold phase */
58
if (lr & R_V7M_EXCRET_DCRS_MASK &&
96
+ ssys_calculate_system_clock(s, true);
59
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
60
- v7m_push_callee_stack(cpu, lr, dotailchain);
61
+ v7m_push_callee_stack(cpu, lr, dotailchain,
62
+ ignore_stackfaults);
63
}
64
lr |= R_V7M_EXCRET_DCRS_MASK;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
67
env->thumb = addr & 1;
68
}
97
}
69
98
70
-static void v7m_push_stack(ARMCPU *cpu)
99
static void stellaris_sys_reset_exit(Object *obj)
71
+static bool v7m_push_stack(ARMCPU *cpu)
100
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_post_load(void *opaque, int version_id)
72
{
101
{
73
/* Do the "set up stack frame" part of exception entry,
102
ssys_state *s = opaque;
74
* similar to pseudocode PushStack().
103
75
+ * Return true if we generate a derived exception (and so
104
- ssys_calculate_system_clock(s);
76
+ * should ignore further stack faults trying to process
105
+ ssys_calculate_system_clock(s, false);
77
+ * that derived exception.)
106
107
return 0;
108
}
109
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_sys = {
110
VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
111
VMSTATE_UINT32(clkvclr, ssys_state),
112
VMSTATE_UINT32(ldoarst, ssys_state),
113
+ /* No field for sysclk -- handled in post-load instead */
114
VMSTATE_END_OF_LIST()
115
}
116
};
117
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
118
memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
119
sysbus_init_mmio(sbd, &s->iomem);
120
sysbus_init_irq(sbd, &s->irq);
121
+ s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
122
}
123
124
-static int stellaris_sys_init(uint32_t base, qemu_irq irq,
125
- stellaris_board_info * board,
126
- uint8_t *macaddr)
127
+static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
128
+ stellaris_board_info *board,
129
+ uint8_t *macaddr)
130
{
131
DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
132
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
133
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
78
*/
134
*/
79
CPUARMState *env = &cpu->env;
135
device_cold_reset(dev);
80
uint32_t xpsr = xpsr_read(env);
136
81
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
137
- return 0;
82
v7m_push(env, env->regs[2]);
138
+ return dev;
83
v7m_push(env, env->regs[1]);
84
v7m_push(env, env->regs[0]);
85
+
86
+ return false;
87
}
139
}
88
140
89
static void do_v7m_exception_exit(ARMCPU *cpu)
141
/* I2C controller. */
90
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
142
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
91
if (sfault) {
143
int flash_size;
92
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
144
I2CBus *i2c;
93
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
145
DeviceState *dev;
94
- v7m_exception_taken(cpu, excret, true);
146
+ DeviceState *ssys_dev;
95
+ v7m_exception_taken(cpu, excret, true, false);
147
int i;
96
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
148
int j;
97
"stackframe: failed EXC_RETURN.ES validity check\n");
149
98
return;
150
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
99
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
151
}
100
*/
101
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
102
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
103
- v7m_exception_taken(cpu, excret, true);
104
+ v7m_exception_taken(cpu, excret, true, false);
105
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
106
"stackframe: failed exception return integrity check\n");
107
return;
108
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
109
/* Take a SecureFault on the current stack */
110
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
111
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
112
- v7m_exception_taken(cpu, excret, true);
113
+ v7m_exception_taken(cpu, excret, true, false);
114
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
115
"stackframe: failed exception return integrity "
116
"signature check\n");
117
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
118
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
119
env->v7m.secure);
120
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
121
- v7m_exception_taken(cpu, excret, true);
122
+ v7m_exception_taken(cpu, excret, true, false);
123
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
124
"stackframe: failed exception return integrity "
125
"check\n");
126
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
127
/* Take an INVPC UsageFault by pushing the stack again;
128
* we know we're v7M so this is never a Secure UsageFault.
129
*/
130
+ bool ignore_stackfaults;
131
+
132
assert(!arm_feature(env, ARM_FEATURE_V8));
133
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false);
134
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
135
- v7m_push_stack(cpu);
136
- v7m_exception_taken(cpu, excret, false);
137
+ ignore_stackfaults = v7m_push_stack(cpu);
138
+ v7m_exception_taken(cpu, excret, false, ignore_stackfaults);
139
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
140
"failed exception return integrity check\n");
141
return;
142
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
143
ARMCPU *cpu = ARM_CPU(cs);
144
CPUARMState *env = &cpu->env;
145
uint32_t lr;
146
+ bool ignore_stackfaults;
147
148
arm_log_exception(cs->exception_index);
149
150
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
151
lr |= R_V7M_EXCRET_MODE_MASK;
152
}
152
}
153
153
154
- v7m_push_stack(cpu);
154
- stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
155
- v7m_exception_taken(cpu, lr, false);
155
- board, nd_table[0].macaddr.a);
156
+ ignore_stackfaults = v7m_push_stack(cpu);
156
+ ssys_dev = stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
157
+ v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
157
+ board, nd_table[0].macaddr.a);
158
qemu_log_mask(CPU_LOG_INT, "... as %d\n", env->v7m.exception);
158
159
}
159
160
160
if (board->dc1 & (1 << 3)) { /* watchdog present */
161
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
162
/* system_clock_scale is valid now */
163
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
164
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
165
+ qdev_connect_clock_in(dev, "WDOGCLK",
166
+ qdev_get_clock_out(ssys_dev, "SYSCLK"));
167
168
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
169
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
161
--
170
--
162
2.16.1
171
2.20.1
163
172
164
173
diff view generated by jsdifflib
1
Make the load of the exception vector from the vector table honour
1
Switch the CMSDK APB timer device over to using its Clock input; the
2
the SAU and any bus error on the load (possibly provoking a derived
2
pclk-frq property is now ignored.
3
exception), rather than simply aborting if the load fails.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 1517324542-6607-7-git-send-email-peter.maydell@linaro.org
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-19-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-19-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
11
hw/timer/cmsdk-apb-timer.c | 18 ++++++++++++++----
10
1 file changed, 55 insertions(+), 16 deletions(-)
12
1 file changed, 14 insertions(+), 4 deletions(-)
11
13
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
16
--- a/hw/timer/cmsdk-apb-timer.c
15
+++ b/target/arm/helper.c
17
+++ b/hw/timer/cmsdk-apb-timer.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
17
}
19
ptimer_transaction_commit(s->timer);
18
}
20
}
19
21
20
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
22
+static void cmsdk_apb_timer_clk_update(void *opaque)
21
+static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
23
+{
22
+ uint32_t *pvec)
24
+ CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
25
+
26
+ ptimer_transaction_begin(s->timer);
27
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
28
+ ptimer_transaction_commit(s->timer);
29
+}
30
+
31
static void cmsdk_apb_timer_init(Object *obj)
23
{
32
{
24
CPUState *cs = CPU(cpu);
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
25
CPUARMState *env = &cpu->env;
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
26
MemTxResult result;
35
s, "cmsdk-apb-timer", 0x1000);
27
- hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
36
sysbus_init_mmio(sbd, &s->iomem);
28
- uint32_t addr;
37
sysbus_init_irq(sbd, &s->timerint);
29
+ uint32_t addr = env->v7m.vecbase[targets_secure] + exc * 4;
38
- s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
30
+ uint32_t vector_entry;
39
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
31
+ MemTxAttrs attrs = {};
40
+ cmsdk_apb_timer_clk_update, s);
32
+ ARMMMUIdx mmu_idx;
33
+ bool exc_secure;
34
+
35
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
36
37
- addr = address_space_ldl(cs->as, vec,
38
- MEMTXATTRS_UNSPECIFIED, &result);
39
+ /* We don't do a get_phys_addr() here because the rules for vector
40
+ * loads are special: they always use the default memory map, and
41
+ * the default memory map permits reads from all addresses.
42
+ * Since there's no easy way to pass through to pmsav8_mpu_lookup()
43
+ * that we want this special case which would always say "yes",
44
+ * we just do the SAU lookup here followed by a direct physical load.
45
+ */
46
+ attrs.secure = targets_secure;
47
+ attrs.user = false;
48
+
49
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
50
+ V8M_SAttributes sattrs = {};
51
+
52
+ v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
53
+ if (sattrs.ns) {
54
+ attrs.secure = false;
55
+ } else if (!targets_secure) {
56
+ /* NS access to S memory */
57
+ goto load_fail;
58
+ }
59
+ }
60
+
61
+ vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
62
+ attrs, &result);
63
if (result != MEMTX_OK) {
64
- /* Architecturally this should cause a HardFault setting HSFR.VECTTBL,
65
- * which would then be immediately followed by our failing to load
66
- * the entry vector for that HardFault, which is a Lockup case.
67
- * Since we don't model Lockup, we just report this guest error
68
- * via cpu_abort().
69
- */
70
- cpu_abort(cs, "Failed to read from %s exception vector table "
71
- "entry %08x\n", targets_secure ? "secure" : "nonsecure",
72
- (unsigned)vec);
73
+ goto load_fail;
74
}
75
- return addr;
76
+ *pvec = vector_entry;
77
+ return true;
78
+
79
+load_fail:
80
+ /* All vector table fetch fails are reported as HardFault, with
81
+ * HFSR.VECTTBL and .FORCED set. (FORCED is set because
82
+ * technically the underlying exception is a MemManage or BusFault
83
+ * that is escalated to HardFault.) This is a terminal exception,
84
+ * so we will either take the HardFault immediately or else enter
85
+ * lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
86
+ */
87
+ exc_secure = targets_secure ||
88
+ !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
89
+ env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
90
+ armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
91
+ return false;
92
}
41
}
93
42
94
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
43
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
95
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
44
{
45
CMSDKAPBTimer *s = CMSDK_APB_TIMER(dev);
46
47
- if (s->pclk_frq == 0) {
48
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
49
+ if (!clock_has_source(s->pclk)) {
50
+ error_setg(errp, "CMSDK APB timer: pclk clock must be connected");
96
return;
51
return;
97
}
52
}
98
53
99
- addr = arm_v7m_load_vector(cpu, exc, targets_secure);
54
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
100
+ if (!arm_v7m_load_vector(cpu, exc, targets_secure, &addr)) {
55
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
101
+ /* Vector load failed: derived exception */
56
102
+ v7m_exception_taken(cpu, lr, true, true);
57
ptimer_transaction_begin(s->timer);
103
+ return;
58
- ptimer_set_freq(s->timer, s->pclk_frq);
104
+ }
59
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
105
60
ptimer_transaction_commit(s->timer);
106
/* Now we've done everything that might cause a derived exception
61
}
107
* we can go ahead and activate whichever exception we're going to
62
108
--
63
--
109
2.16.1
64
2.20.1
110
65
111
66
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
Switch the CMSDK APB dualtimer device over to using its Clock input;
2
the pclk-frq property is now ignored.
2
3
3
This implements emulation of the new SHA-3 instructions that have
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
been added as an optional extensions to the ARMv8 Crypto Extensions
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
5
in ARM v8.2.
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-20-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-20-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
12
hw/timer/cmsdk-apb-dualtimer.c | 42 ++++++++++++++++++++++++++++++----
13
1 file changed, 37 insertions(+), 5 deletions(-)
6
14
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
15
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
8
Message-id: 20180207111729.15737-3-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/translate-a64.c | 148 +++++++++++++++++++++++++++++++++++++++++++--
14
2 files changed, 145 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
17
--- a/hw/timer/cmsdk-apb-dualtimer.c
19
+++ b/target/arm/cpu.h
18
+++ b/hw/timer/cmsdk-apb-dualtimer.c
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
19
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
20
qemu_set_irq(s->timerintc, timintc);
22
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
24
+ ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
25
};
26
27
static inline int arm_feature(CPUARMState *env, int feature)
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
33
feature = ARM_FEATURE_V8_SHA512;
34
genfn = gen_helper_crypto_sha512su1;
35
break;
36
- default:
37
- unallocated_encoding(s);
38
- return;
39
+ case 3: /* RAX1 */
40
+ feature = ARM_FEATURE_V8_SHA3;
41
+ genfn = NULL;
42
+ break;
43
}
44
} else {
45
unallocated_encoding(s);
46
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
47
tcg_temp_free_ptr(tcg_rn_ptr);
48
tcg_temp_free_ptr(tcg_rm_ptr);
49
} else {
50
- g_assert_not_reached();
51
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
52
+ int pass;
53
+
54
+ tcg_op1 = tcg_temp_new_i64();
55
+ tcg_op2 = tcg_temp_new_i64();
56
+ tcg_res[0] = tcg_temp_new_i64();
57
+ tcg_res[1] = tcg_temp_new_i64();
58
+
59
+ for (pass = 0; pass < 2; pass++) {
60
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
61
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
62
+
63
+ tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1);
64
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
65
+ }
66
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
67
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
68
+
69
+ tcg_temp_free_i64(tcg_op1);
70
+ tcg_temp_free_i64(tcg_op2);
71
+ tcg_temp_free_i64(tcg_res[0]);
72
+ tcg_temp_free_i64(tcg_res[1]);
73
}
74
}
21
}
75
22
76
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
23
+static int cmsdk_dualtimermod_divisor(CMSDKAPBDualTimerModule *m)
77
tcg_temp_free_ptr(tcg_rn_ptr);
78
}
79
80
+/* Crypto four-register
81
+ * 31 23 22 21 20 16 15 14 10 9 5 4 0
82
+ * +-------------------+-----+------+---+------+------+------+
83
+ * | 1 1 0 0 1 1 1 0 0 | Op0 | Rm | 0 | Ra | Rn | Rd |
84
+ * +-------------------+-----+------+---+------+------+------+
85
+ */
86
+static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
87
+{
24
+{
88
+ int op0 = extract32(insn, 21, 2);
25
+ /* Return the divisor set by the current CONTROL.PRESCALE value */
89
+ int rm = extract32(insn, 16, 5);
26
+ switch (FIELD_EX32(m->control, CONTROL, PRESCALE)) {
90
+ int ra = extract32(insn, 10, 5);
27
+ case 0:
91
+ int rn = extract32(insn, 5, 5);
28
+ return 1;
92
+ int rd = extract32(insn, 0, 5);
29
+ case 1:
93
+ int feature;
30
+ return 16;
94
+
31
+ case 2:
95
+ switch (op0) {
32
+ case 3: /* UNDEFINED, we treat like 2 (and complained when it was set) */
96
+ case 0: /* EOR3 */
33
+ return 256;
97
+ case 1: /* BCAX */
98
+ feature = ARM_FEATURE_V8_SHA3;
99
+ break;
100
+ default:
34
+ default:
101
+ unallocated_encoding(s);
102
+ return;
103
+ }
104
+
105
+ if (!arm_dc_feature(s, feature)) {
106
+ unallocated_encoding(s);
107
+ return;
108
+ }
109
+
110
+ if (!fp_access_check(s)) {
111
+ return;
112
+ }
113
+
114
+ if (op0 < 2) {
115
+ TCGv_i64 tcg_op1, tcg_op2, tcg_op3, tcg_res[2];
116
+ int pass;
117
+
118
+ tcg_op1 = tcg_temp_new_i64();
119
+ tcg_op2 = tcg_temp_new_i64();
120
+ tcg_op3 = tcg_temp_new_i64();
121
+ tcg_res[0] = tcg_temp_new_i64();
122
+ tcg_res[1] = tcg_temp_new_i64();
123
+
124
+ for (pass = 0; pass < 2; pass++) {
125
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
126
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
127
+ read_vec_element(s, tcg_op3, ra, pass, MO_64);
128
+
129
+ if (op0 == 0) {
130
+ /* EOR3 */
131
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op2, tcg_op3);
132
+ } else {
133
+ /* BCAX */
134
+ tcg_gen_andc_i64(tcg_res[pass], tcg_op2, tcg_op3);
135
+ }
136
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
137
+ }
138
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
139
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
140
+
141
+ tcg_temp_free_i64(tcg_op1);
142
+ tcg_temp_free_i64(tcg_op2);
143
+ tcg_temp_free_i64(tcg_op3);
144
+ tcg_temp_free_i64(tcg_res[0]);
145
+ tcg_temp_free_i64(tcg_res[1]);
146
+ } else {
147
+ g_assert_not_reached();
35
+ g_assert_not_reached();
148
+ }
36
+ }
149
+}
37
+}
150
+
38
+
151
+/* Crypto XAR
39
static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
152
+ * 31 21 20 16 15 10 9 5 4 0
40
uint32_t newctrl)
153
+ * +-----------------------+------+--------+------+------+
41
{
154
+ * | 1 1 0 0 1 1 1 0 1 0 0 | Rm | imm6 | Rn | Rd |
42
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
155
+ * +-----------------------+------+--------+------+------+
43
default:
156
+ */
44
g_assert_not_reached();
157
+static void disas_crypto_xar(DisasContext *s, uint32_t insn)
45
}
46
- ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor);
47
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk, divisor);
48
}
49
50
if (changed & R_CONTROL_MODE_MASK) {
51
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m)
52
* limit must both be set to 0xffff, so we wrap at 16 bits.
53
*/
54
ptimer_set_limit(m->timer, 0xffff, 1);
55
- ptimer_set_freq(m->timer, m->parent->pclk_frq);
56
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
57
+ cmsdk_dualtimermod_divisor(m));
58
ptimer_transaction_commit(m->timer);
59
}
60
61
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
62
s->timeritop = 0;
63
}
64
65
+static void cmsdk_apb_dualtimer_clk_update(void *opaque)
158
+{
66
+{
159
+ int rm = extract32(insn, 16, 5);
67
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
160
+ int imm6 = extract32(insn, 10, 6);
68
+ int i;
161
+ int rn = extract32(insn, 5, 5);
162
+ int rd = extract32(insn, 0, 5);
163
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
164
+ int pass;
165
+
69
+
166
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) {
70
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
167
+ unallocated_encoding(s);
71
+ CMSDKAPBDualTimerModule *m = &s->timermod[i];
168
+ return;
72
+ ptimer_transaction_begin(m->timer);
73
+ ptimer_set_period_from_clock(m->timer, m->parent->timclk,
74
+ cmsdk_dualtimermod_divisor(m));
75
+ ptimer_transaction_commit(m->timer);
169
+ }
76
+ }
170
+
171
+ if (!fp_access_check(s)) {
172
+ return;
173
+ }
174
+
175
+ tcg_op1 = tcg_temp_new_i64();
176
+ tcg_op2 = tcg_temp_new_i64();
177
+ tcg_res[0] = tcg_temp_new_i64();
178
+ tcg_res[1] = tcg_temp_new_i64();
179
+
180
+ for (pass = 0; pass < 2; pass++) {
181
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
182
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
183
+
184
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2);
185
+ tcg_gen_rotri_i64(tcg_res[pass], tcg_res[pass], imm6);
186
+ }
187
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
188
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
189
+
190
+ tcg_temp_free_i64(tcg_op1);
191
+ tcg_temp_free_i64(tcg_op2);
192
+ tcg_temp_free_i64(tcg_res[0]);
193
+ tcg_temp_free_i64(tcg_res[1]);
194
+}
77
+}
195
+
78
+
196
/* C3.6 Data processing - SIMD, inc Crypto
79
static void cmsdk_apb_dualtimer_init(Object *obj)
197
*
80
{
198
* As the decode gets a little complex we are using a table based
81
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
199
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
82
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
200
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
83
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
201
{ 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
84
sysbus_init_irq(sbd, &s->timermod[i].timerint);
202
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
85
}
203
+ { 0xce000000, 0xff808000, disas_crypto_four_reg },
86
- s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
204
+ { 0xce800000, 0xffe00000, disas_crypto_xar },
87
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
205
{ 0x00000000, 0x00000000, NULL }
88
+ cmsdk_apb_dualtimer_clk_update, s);
206
};
89
}
90
91
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
92
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
93
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev);
94
int i;
95
96
- if (s->pclk_frq == 0) {
97
- error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
98
+ if (!clock_has_source(s->timclk)) {
99
+ error_setg(errp, "CMSDK APB dualtimer: TIMCLK clock must be connected");
100
return;
101
}
207
102
208
--
103
--
209
2.16.1
104
2.20.1
210
105
211
106
diff view generated by jsdifflib
1
Make v7m_push_callee_stack() honour the MPU by using the
1
Switch the CMSDK APB watchdog device over to using its Clock input;
2
new v7m_stack_write() function. We return a flag to indicate
2
the wdogclk_frq property is now ignored.
3
whether the pushes failed, which we can then use in
4
v7m_exception_taken() to cause us to handle the derived
5
exception correctly.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1517324542-6607-6-git-send-email-peter.maydell@linaro.org
6
Reviewed-by: Luc Michel <luc@lmichel.fr>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210128114145.20536-21-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-21-peter.maydell@linaro.org
11
---
10
---
12
target/arm/helper.c | 64 ++++++++++++++++++++++++++++++++++++++++-------------
11
hw/watchdog/cmsdk-apb-watchdog.c | 18 ++++++++++++++----
13
1 file changed, 49 insertions(+), 15 deletions(-)
12
1 file changed, 14 insertions(+), 4 deletions(-)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
18
+++ b/target/arm/helper.c
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
20
return addr;
19
ptimer_transaction_commit(s->timer);
21
}
20
}
22
21
23
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
22
+static void cmsdk_apb_watchdog_clk_update(void *opaque)
24
+static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
23
+{
25
bool ignore_faults)
24
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
25
+
26
+ ptimer_transaction_begin(s->timer);
27
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
28
+ ptimer_transaction_commit(s->timer);
29
+}
30
+
31
static void cmsdk_apb_watchdog_init(Object *obj)
26
{
32
{
27
/* For v8M, push the callee-saves register part of the stack frame.
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
28
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
29
* In the tailchaining case this may not be the current stack.
35
s, "cmsdk-apb-watchdog", 0x1000);
30
*/
36
sysbus_init_mmio(sbd, &s->iomem);
31
CPUARMState *env = &cpu->env;
37
sysbus_init_irq(sbd, &s->wdogint);
32
- CPUState *cs = CPU(cpu);
38
- s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
33
uint32_t *frame_sp_p;
39
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
34
uint32_t frameptr;
40
+ cmsdk_apb_watchdog_clk_update, s);
35
+ ARMMMUIdx mmu_idx;
41
36
+ bool stacked_ok;
42
s->is_luminary = false;
37
43
s->id = cmsdk_apb_watchdog_id;
38
if (dotailchain) {
44
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
39
- frame_sp_p = get_v7m_sp_ptr(env, true,
45
{
40
- lr & R_V7M_EXCRET_MODE_MASK,
46
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
41
+ bool mode = lr & R_V7M_EXCRET_MODE_MASK;
47
42
+ bool priv = !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_NPRIV_MASK) ||
48
- if (s->wdogclk_frq == 0) {
43
+ !mode;
49
+ if (!clock_has_source(s->wdogclk)) {
44
+
50
error_setg(errp,
45
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, priv);
51
- "CMSDK APB watchdog: wdogclk-frq property must be set");
46
+ frame_sp_p = get_v7m_sp_ptr(env, M_REG_S, mode,
52
+ "CMSDK APB watchdog: WDOGCLK clock must be connected");
47
lr & R_V7M_EXCRET_SPSEL_MASK);
53
return;
48
} else {
49
+ mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
50
frame_sp_p = &env->regs[13];
51
}
54
}
52
55
53
frameptr = *frame_sp_p - 0x28;
56
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
54
57
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
55
- stl_phys(cs->as, frameptr, 0xfefa125b);
58
56
- stl_phys(cs->as, frameptr + 0x8, env->regs[4]);
59
ptimer_transaction_begin(s->timer);
57
- stl_phys(cs->as, frameptr + 0xc, env->regs[5]);
60
- ptimer_set_freq(s->timer, s->wdogclk_frq);
58
- stl_phys(cs->as, frameptr + 0x10, env->regs[6]);
61
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
59
- stl_phys(cs->as, frameptr + 0x14, env->regs[7]);
62
ptimer_transaction_commit(s->timer);
60
- stl_phys(cs->as, frameptr + 0x18, env->regs[8]);
61
- stl_phys(cs->as, frameptr + 0x1c, env->regs[9]);
62
- stl_phys(cs->as, frameptr + 0x20, env->regs[10]);
63
- stl_phys(cs->as, frameptr + 0x24, env->regs[11]);
64
+ /* Write as much of the stack frame as we can. A write failure may
65
+ * cause us to pend a derived exception.
66
+ */
67
+ stacked_ok =
68
+ v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
69
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
70
+ ignore_faults) &&
71
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
72
+ ignore_faults) &&
73
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
74
+ ignore_faults) &&
75
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
76
+ ignore_faults) &&
77
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
78
+ ignore_faults) &&
79
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
80
+ ignore_faults) &&
81
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
82
+ ignore_faults) &&
83
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
84
+ ignore_faults);
85
86
+ /* Update SP regardless of whether any of the stack accesses failed.
87
+ * When we implement v8M stack limit checking then this attempt to
88
+ * update SP might also fail and result in a derived exception.
89
+ */
90
*frame_sp_p = frameptr;
91
+
92
+ return !stacked_ok;
93
}
63
}
94
64
95
static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
96
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
97
uint32_t addr;
98
bool targets_secure;
99
int exc;
100
+ bool push_failed = false;
101
102
armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
103
104
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
105
*/
106
if (lr & R_V7M_EXCRET_DCRS_MASK &&
107
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
108
- v7m_push_callee_stack(cpu, lr, dotailchain,
109
- ignore_stackfaults);
110
+ push_failed = v7m_push_callee_stack(cpu, lr, dotailchain,
111
+ ignore_stackfaults);
112
}
113
lr |= R_V7M_EXCRET_DCRS_MASK;
114
}
115
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
116
}
117
}
118
119
+ if (push_failed && !ignore_stackfaults) {
120
+ /* Derived exception on callee-saves register stacking:
121
+ * we might now want to take a different exception which
122
+ * targets a different security state, so try again from the top.
123
+ */
124
+ v7m_exception_taken(cpu, lr, true, true);
125
+ return;
126
+ }
127
+
128
addr = arm_v7m_load_vector(cpu, exc, targets_secure);
129
130
/* Now we've done everything that might cause a derived exception
131
--
65
--
132
2.16.1
66
2.20.1
133
67
134
68
diff view generated by jsdifflib
1
Handle possible MPU faults, SAU faults or bus errors when
1
Now that the CMSDK APB watchdog uses its Clock input, it will
2
popping register state off the stack during exception return.
2
correctly respond when the system clock frequency is changed using
3
the RCC register on in the Stellaris board system registers. Test
4
that when the RCC register is written it causes the watchdog timer to
5
change speed.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 1517324542-6607-8-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210128114145.20536-22-peter.maydell@linaro.org
12
Message-id: 20210121190622.22000-22-peter.maydell@linaro.org
7
---
13
---
8
target/arm/helper.c | 115 ++++++++++++++++++++++++++++++++++++++++++----------
14
tests/qtest/cmsdk-apb-watchdog-test.c | 52 +++++++++++++++++++++++++++
9
1 file changed, 94 insertions(+), 21 deletions(-)
15
1 file changed, 52 insertions(+)
10
16
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
19
--- a/tests/qtest/cmsdk-apb-watchdog-test.c
14
+++ b/target/arm/helper.c
20
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
15
@@ -XXX,XX +XXX,XX @@ pend_fault:
21
@@ -XXX,XX +XXX,XX @@
16
return false;
22
*/
23
24
#include "qemu/osdep.h"
25
+#include "qemu/bitops.h"
26
#include "libqtest-single.h"
27
28
/*
29
@@ -XXX,XX +XXX,XX @@
30
#define WDOGMIS 0x14
31
#define WDOGLOCK 0xc00
32
33
+#define SSYS_BASE 0x400fe000
34
+#define RCC 0x60
35
+#define SYSDIV_SHIFT 23
36
+#define SYSDIV_LENGTH 4
37
+
38
static void test_watchdog(void)
39
{
40
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
41
@@ -XXX,XX +XXX,XX @@ static void test_watchdog(void)
42
g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
17
}
43
}
18
44
19
+static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
45
+static void test_clock_change(void)
20
+ ARMMMUIdx mmu_idx)
21
+{
46
+{
22
+ CPUState *cs = CPU(cpu);
47
+ uint32_t rcc;
23
+ CPUARMState *env = &cpu->env;
24
+ MemTxAttrs attrs = {};
25
+ MemTxResult txres;
26
+ target_ulong page_size;
27
+ hwaddr physaddr;
28
+ int prot;
29
+ ARMMMUFaultInfo fi;
30
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
31
+ int exc;
32
+ bool exc_secure;
33
+ uint32_t value;
34
+
48
+
35
+ if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
49
+ /*
36
+ &attrs, &prot, &page_size, &fi, NULL)) {
50
+ * Test that writing to the stellaris board's RCC register to
37
+ /* MPU/SAU lookup failed */
51
+ * change the system clock frequency causes the watchdog
38
+ if (fi.type == ARMFault_QEMU_SFault) {
52
+ * to change the speed it counts at.
39
+ qemu_log_mask(CPU_LOG_INT,
53
+ */
40
+ "...SecureFault with SFSR.AUVIOL during unstack\n");
54
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
41
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
42
+ env->v7m.sfar = addr;
43
+ exc = ARMV7M_EXCP_SECURE;
44
+ exc_secure = false;
45
+ } else {
46
+ qemu_log_mask(CPU_LOG_INT,
47
+ "...MemManageFault with CFSR.MUNSTKERR\n");
48
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MUNSTKERR_MASK;
49
+ exc = ARMV7M_EXCP_MEM;
50
+ exc_secure = secure;
51
+ }
52
+ goto pend_fault;
53
+ }
54
+
55
+
55
+ value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
56
+ writel(WDOG_BASE + WDOGCONTROL, 1);
56
+ attrs, &txres);
57
+ writel(WDOG_BASE + WDOGLOAD, 1000);
57
+ if (txres != MEMTX_OK) {
58
+ /* BusFault trying to read the data */
59
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
60
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_UNSTKERR_MASK;
61
+ exc = ARMV7M_EXCP_BUS;
62
+ exc_secure = false;
63
+ goto pend_fault;
64
+ }
65
+
58
+
66
+ *dest = value;
59
+ /* Step to just past the 500th tick */
67
+ return true;
60
+ clock_step(80 * 500 + 1);
61
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
62
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
68
+
63
+
69
+pend_fault:
64
+ /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */
70
+ /* By pending the exception at this point we are making
65
+ rcc = readl(SSYS_BASE + RCC);
71
+ * the IMPDEF choice "overridden exceptions pended" (see the
66
+ g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf);
72
+ * MergeExcInfo() pseudocode). The other choice would be to not
67
+ rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7);
73
+ * pend them now and then make a choice about which to throw away
68
+ writel(SSYS_BASE + RCC, rcc);
74
+ * later if we have two derived exceptions.
69
+
75
+ */
70
+ /* Just past the 1000th tick: timer should have fired */
76
+ armv7m_nvic_set_pending(env->nvic, exc, exc_secure);
71
+ clock_step(40 * 500);
77
+ return false;
72
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
73
+
74
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
75
+
76
+ /* VALUE reloads at following tick */
77
+ clock_step(41);
78
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
79
+
80
+ /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
81
+ clock_step(40 * 500);
82
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
83
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
84
+ writel(WDOG_BASE + WDOGINTCLR, 0);
85
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
86
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
78
+}
87
+}
79
+
88
+
80
/* Return true if we're using the process stack pointer (not the MSP) */
89
int main(int argc, char **argv)
81
static bool v7m_using_psp(CPUARMState *env)
82
{
90
{
83
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
91
int r;
84
!return_to_handler,
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
85
return_to_sp_process);
93
qtest_start("-machine lm3s811evb");
86
uint32_t frameptr = *frame_sp_p;
94
87
+ bool pop_ok = true;
95
qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
88
+ ARMMMUIdx mmu_idx;
96
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog_clock_change",
89
+
97
+ test_clock_change);
90
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, return_to_secure,
98
91
+ !return_to_handler);
99
r = g_test_run();
92
100
93
if (!QEMU_IS_ALIGNED(frameptr, 8) &&
94
arm_feature(env, ARM_FEATURE_V8)) {
95
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
96
return;
97
}
98
99
- env->regs[4] = ldl_phys(cs->as, frameptr + 0x8);
100
- env->regs[5] = ldl_phys(cs->as, frameptr + 0xc);
101
- env->regs[6] = ldl_phys(cs->as, frameptr + 0x10);
102
- env->regs[7] = ldl_phys(cs->as, frameptr + 0x14);
103
- env->regs[8] = ldl_phys(cs->as, frameptr + 0x18);
104
- env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c);
105
- env->regs[10] = ldl_phys(cs->as, frameptr + 0x20);
106
- env->regs[11] = ldl_phys(cs->as, frameptr + 0x24);
107
+ pop_ok =
108
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
109
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
110
+ v7m_stack_read(cpu, &env->regs[5], frameptr + 0xc, mmu_idx) &&
111
+ v7m_stack_read(cpu, &env->regs[6], frameptr + 0x10, mmu_idx) &&
112
+ v7m_stack_read(cpu, &env->regs[7], frameptr + 0x14, mmu_idx) &&
113
+ v7m_stack_read(cpu, &env->regs[8], frameptr + 0x18, mmu_idx) &&
114
+ v7m_stack_read(cpu, &env->regs[9], frameptr + 0x1c, mmu_idx) &&
115
+ v7m_stack_read(cpu, &env->regs[10], frameptr + 0x20, mmu_idx) &&
116
+ v7m_stack_read(cpu, &env->regs[11], frameptr + 0x24, mmu_idx);
117
118
frameptr += 0x28;
119
}
120
121
- /* Pop registers. TODO: make these accesses use the correct
122
- * attributes and address space (S/NS, priv/unpriv) and handle
123
- * memory transaction failures.
124
- */
125
- env->regs[0] = ldl_phys(cs->as, frameptr);
126
- env->regs[1] = ldl_phys(cs->as, frameptr + 0x4);
127
- env->regs[2] = ldl_phys(cs->as, frameptr + 0x8);
128
- env->regs[3] = ldl_phys(cs->as, frameptr + 0xc);
129
- env->regs[12] = ldl_phys(cs->as, frameptr + 0x10);
130
- env->regs[14] = ldl_phys(cs->as, frameptr + 0x14);
131
- env->regs[15] = ldl_phys(cs->as, frameptr + 0x18);
132
+ /* Pop registers */
133
+ pop_ok = pop_ok &&
134
+ v7m_stack_read(cpu, &env->regs[0], frameptr, mmu_idx) &&
135
+ v7m_stack_read(cpu, &env->regs[1], frameptr + 0x4, mmu_idx) &&
136
+ v7m_stack_read(cpu, &env->regs[2], frameptr + 0x8, mmu_idx) &&
137
+ v7m_stack_read(cpu, &env->regs[3], frameptr + 0xc, mmu_idx) &&
138
+ v7m_stack_read(cpu, &env->regs[12], frameptr + 0x10, mmu_idx) &&
139
+ v7m_stack_read(cpu, &env->regs[14], frameptr + 0x14, mmu_idx) &&
140
+ v7m_stack_read(cpu, &env->regs[15], frameptr + 0x18, mmu_idx) &&
141
+ v7m_stack_read(cpu, &xpsr, frameptr + 0x1c, mmu_idx);
142
+
143
+ if (!pop_ok) {
144
+ /* v7m_stack_read() pended a fault, so take it (as a tail
145
+ * chained exception on the same stack frame)
146
+ */
147
+ v7m_exception_taken(cpu, excret, true, false);
148
+ return;
149
+ }
150
151
/* Returning from an exception with a PC with bit 0 set is defined
152
* behaviour on v8M (bit 0 is ignored), but for v7M it was specified
153
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
154
}
155
}
156
157
- xpsr = ldl_phys(cs->as, frameptr + 0x1c);
158
-
159
if (arm_feature(env, ARM_FEATURE_V8)) {
160
/* For v8M we have to check whether the xPSR exception field
161
* matches the EXCRET value for return to handler/thread
162
--
101
--
163
2.16.1
102
2.20.1
164
103
165
104
diff view generated by jsdifflib
1
Currently armv7m_nvic_acknowledge_irq() does three things:
1
Use the MAINCLK Clock input to set the system_clock_scale variable
2
* make the current highest priority pending interrupt active
2
rather than using the mainclk_frq property.
3
* return a bool indicating whether that interrupt is targeting
4
Secure or NonSecure state
5
* implicitly tell the caller which is the highest priority
6
pending interrupt by setting env->v7m.exception
7
8
We need to split these jobs, because v7m_exception_taken()
9
needs to know whether the pending interrupt targets Secure so
10
it can choose to stack callee-saves registers or not, but it
11
must not make the interrupt active until after it has done
12
that stacking, in case the stacking causes a derived exception.
13
Similarly, it needs to know the number of the pending interrupt
14
so it can read the correct vector table entry before the
15
interrupt is made active, because vector table reads might
16
also cause a derived exception.
17
18
Create a new armv7m_nvic_get_pending_irq_info() function which simply
19
returns information about the highest priority pending interrupt, and
20
use it to rearrange the v7m_exception_taken() code so we don't
21
acknowledge the exception until we've done all the things which could
22
possibly cause a derived exception.
23
3
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20210128114145.20536-23-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-23-peter.maydell@linaro.org
28
---
10
---
29
target/arm/cpu.h | 19 ++++++++++++++++---
11
hw/arm/armsse.c | 24 +++++++++++++++++++-----
30
hw/intc/armv7m_nvic.c | 30 +++++++++++++++++++++++-------
12
1 file changed, 19 insertions(+), 5 deletions(-)
31
target/arm/helper.c | 16 ++++++++++++----
32
hw/intc/trace-events | 3 ++-
33
4 files changed, 53 insertions(+), 15 deletions(-)
34
13
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
36
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
16
--- a/hw/arm/armsse.c
38
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/armsse.c
39
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
18
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
40
* a different exception).
19
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
41
*/
42
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
43
+/**
44
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
45
+ * exception, and whether it targets Secure state
46
+ * @opaque: the NVIC
47
+ * @pirq: set to pending exception number
48
+ * @ptargets_secure: set to whether pending exception targets Secure
49
+ *
50
+ * This function writes the number of the highest priority pending
51
+ * exception (the one which would be made active by
52
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
53
+ * to true if the current highest priority pending exception should
54
+ * be taken to Secure state, false for NS.
55
+ */
56
+void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
57
+ bool *ptargets_secure);
58
/**
59
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
60
* @opaque: the NVIC
61
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
62
* Move the current highest priority pending exception from the pending
63
* state to the active state, and update v7m.exception to indicate that
64
* it is the exception currently being handled.
65
- *
66
- * Returns: true if exception should be taken to Secure state, false for NS
67
*/
68
-bool armv7m_nvic_acknowledge_irq(void *opaque);
69
+void armv7m_nvic_acknowledge_irq(void *opaque);
70
/**
71
* armv7m_nvic_complete_irq: complete specified interrupt or exception
72
* @opaque: the NVIC
73
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/intc/armv7m_nvic.c
76
+++ b/hw/intc/armv7m_nvic.c
77
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
78
}
20
}
79
21
80
/* Make pending IRQ active. */
22
+static void armsse_mainclk_update(void *opaque)
81
-bool armv7m_nvic_acknowledge_irq(void *opaque)
23
+{
82
+void armv7m_nvic_acknowledge_irq(void *opaque)
24
+ ARMSSE *s = ARM_SSE(opaque);
83
{
25
+ /*
84
NVICState *s = (NVICState *)opaque;
26
+ * Set system_clock_scale from our Clock input; this is what
85
CPUARMState *env = &s->cpu->env;
27
+ * controls the tick rate of the CPU SysTick timer.
86
const int pending = s->vectpending;
28
+ */
87
const int running = nvic_exec_prio(s);
29
+ system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
88
VecInfo *vec;
89
- bool targets_secure;
90
91
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
92
93
if (s->vectpending_is_s_banked) {
94
vec = &s->sec_vectors[pending];
95
- targets_secure = true;
96
} else {
97
vec = &s->vectors[pending];
98
- targets_secure = !exc_is_banked(s->vectpending) &&
99
- exc_targets_secure(s, s->vectpending);
100
}
101
102
assert(vec->enabled);
103
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
104
105
assert(s->vectpending_prio < running);
106
107
- trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure);
108
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
109
110
vec->active = 1;
111
vec->pending = 0;
112
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
113
write_v7m_exception(env, s->vectpending);
114
115
nvic_irq_update(s);
116
+}
30
+}
117
+
31
+
118
+void armv7m_nvic_get_pending_irq_info(void *opaque,
32
static void armsse_init(Object *obj)
119
+ int *pirq, bool *ptargets_secure)
33
{
120
+{
34
ARMSSE *s = ARM_SSE(obj);
121
+ NVICState *s = (NVICState *)opaque;
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
122
+ const int pending = s->vectpending;
36
assert(info->sram_banks <= MAX_SRAM_BANKS);
123
+ bool targets_secure;
37
assert(info->num_cpus <= SSE_MAX_CPUS);
124
+
38
125
+ assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
39
- s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
126
+
40
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
127
+ if (s->vectpending_is_s_banked) {
41
+ armsse_mainclk_update, s);
128
+ targets_secure = true;
42
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
129
+ } else {
43
130
+ targets_secure = !exc_is_banked(pending) &&
44
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
131
+ exc_targets_secure(s, pending);
45
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
46
return;
47
}
48
49
- if (!s->mainclk_frq) {
50
- error_setg(errp, "MAINCLK_FRQ property was not set");
51
- return;
52
+ if (!clock_has_source(s->mainclk)) {
53
+ error_setg(errp, "MAINCLK clock was not connected");
132
+ }
54
+ }
133
+
55
+ if (!clock_has_source(s->s32kclk)) {
134
+ trace_nvic_get_pending_irq_info(pending, targets_secure);
56
+ error_setg(errp, "S32KCLK clock was not connected");
135
57
}
136
- return targets_secure;
58
137
+ *ptargets_secure = targets_secure;
59
assert(info->num_cpus <= SSE_MAX_CPUS);
138
+ *pirq = pending;
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
61
*/
62
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
63
64
- system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
65
+ /* Set initial system_clock_scale from MAINCLK */
66
+ armsse_mainclk_update(s);
139
}
67
}
140
68
141
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
69
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
142
diff --git a/target/arm/helper.c b/target/arm/helper.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/helper.c
145
+++ b/target/arm/helper.c
146
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
147
}
148
}
149
150
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, bool targets_secure)
151
+static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
152
{
153
CPUState *cs = CPU(cpu);
154
CPUARMState *env = &cpu->env;
155
MemTxResult result;
156
- hwaddr vec = env->v7m.vecbase[targets_secure] + env->v7m.exception * 4;
157
+ hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
158
uint32_t addr;
159
160
addr = address_space_ldl(cs->as, vec,
161
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
162
CPUARMState *env = &cpu->env;
163
uint32_t addr;
164
bool targets_secure;
165
+ int exc;
166
167
- targets_secure = armv7m_nvic_acknowledge_irq(env->nvic);
168
+ armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
169
170
if (arm_feature(env, ARM_FEATURE_V8)) {
171
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
172
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
173
}
174
}
175
176
+ addr = arm_v7m_load_vector(cpu, exc, targets_secure);
177
+
178
+ /* Now we've done everything that might cause a derived exception
179
+ * we can go ahead and activate whichever exception we're going to
180
+ * take (which might now be the derived exception).
181
+ */
182
+ armv7m_nvic_acknowledge_irq(env->nvic);
183
+
184
/* Switch to target security state -- must do this before writing SPSEL */
185
switch_v7m_security_state(env, targets_secure);
186
write_v7m_control_spsel(env, 0);
187
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
188
/* Clear IT bits */
189
env->condexec_bits = 0;
190
env->regs[14] = lr;
191
- addr = arm_v7m_load_vector(cpu, targets_secure);
192
env->regs[15] = addr & 0xfffffffe;
193
env->thumb = addr & 1;
194
}
195
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/intc/trace-events
198
+++ b/hw/intc/trace-events
199
@@ -XXX,XX +XXX,XX @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
200
nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
201
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
202
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
203
-nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
204
+nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
205
+nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
206
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
207
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
208
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
209
--
70
--
210
2.16.1
71
2.20.1
211
72
212
73
diff view generated by jsdifflib
1
The code where we added the TT instruction was accidentally
1
Remove all the code that sets frequency properties on the CMSDK
2
missing a 'break', which meant that after generating the code
2
timer, dualtimer and watchdog devices and on the ARMSSE SoC device:
3
to execute the TT we would fall through to 'goto illegal_op'
3
these properties are unused now that the devices rely on their Clock
4
and generate code to take an UNDEF insn.
4
inputs instead.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180206103941.13985-1-peter.maydell@linaro.org
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210128114145.20536-24-peter.maydell@linaro.org
11
Message-id: 20210121190622.22000-24-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.c | 1 +
13
hw/arm/armsse.c | 7 -------
11
1 file changed, 1 insertion(+)
14
hw/arm/mps2-tz.c | 1 -
15
hw/arm/mps2.c | 3 ---
16
hw/arm/musca.c | 1 -
17
hw/arm/stellaris.c | 3 ---
18
5 files changed, 15 deletions(-)
12
19
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
22
--- a/hw/arm/armsse.c
16
+++ b/target/arm/translate.c
23
+++ b/hw/arm/armsse.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
24
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
18
tcg_temp_free_i32(addr);
25
* it to the appropriate PPC port; then we can realize the PPC and
19
tcg_temp_free_i32(op);
26
* map its upstream ends to the right place in the container.
20
store_reg(s, rd, ttresp);
27
*/
21
+ break;
28
- qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
22
}
29
qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
23
goto illegal_op;
30
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
24
}
31
return;
32
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
33
object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
34
&error_abort);
35
36
- qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
37
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
38
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
39
return;
40
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
41
object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
42
&error_abort);
43
44
- qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
45
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
46
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
47
return;
48
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
49
/* Devices behind APB PPC1:
50
* 0x4002f000: S32K timer
51
*/
52
- qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
53
qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
54
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
55
return;
56
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
57
qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
58
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
59
60
- qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
61
qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
62
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
63
return;
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
66
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
67
68
- qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
69
qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
70
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
71
return;
72
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
73
armsse_get_common_irq_in(s, 1));
74
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
75
76
- qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
77
qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
79
return;
80
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/mps2-tz.c
83
+++ b/hw/arm/mps2-tz.c
84
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
85
object_property_set_link(OBJECT(&mms->iotkit), "memory",
86
OBJECT(system_memory), &error_abort);
87
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
88
- qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
89
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
90
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
91
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
92
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/arm/mps2.c
95
+++ b/hw/arm/mps2.c
96
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
97
object_initialize_child(OBJECT(mms), name, &mms->timer[i],
98
TYPE_CMSDK_APB_TIMER);
99
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
100
- qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
101
qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
102
sysbus_realize_and_unref(sbd, &error_fatal);
103
sysbus_mmio_map(sbd, 0, base);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
105
106
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
107
TYPE_CMSDK_APB_DUALTIMER);
108
- qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
109
qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
110
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
111
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
112
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
113
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
114
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
115
TYPE_CMSDK_APB_WATCHDOG);
116
- qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
117
qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
118
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
119
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
120
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/musca.c
123
+++ b/hw/arm/musca.c
124
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
125
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
126
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
127
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
128
- qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
129
qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
130
qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
131
/*
132
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/stellaris.c
135
+++ b/hw/arm/stellaris.c
136
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
137
if (board->dc1 & (1 << 3)) { /* watchdog present */
138
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
139
140
- /* system_clock_scale is valid now */
141
- uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
142
- qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
143
qdev_connect_clock_in(dev, "WDOGCLK",
144
qdev_get_clock_out(ssys_dev, "SYSCLK"));
145
25
--
146
--
26
2.16.1
147
2.20.1
27
148
28
149
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Now no users are setting the frq properties on the CMSDK timer,
2
dualtimer, watchdog or ARMSSE SoC devices, we can remove the
3
properties and the struct fields that back them.
2
4
3
Add minimal code needed to allow upstream Linux guest to boot.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210128114145.20536-25-peter.maydell@linaro.org
10
Message-id: 20210121190622.22000-25-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 2 --
13
include/hw/timer/cmsdk-apb-dualtimer.h | 2 --
14
include/hw/timer/cmsdk-apb-timer.h | 2 --
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 2 --
16
hw/arm/armsse.c | 2 --
17
hw/timer/cmsdk-apb-dualtimer.c | 6 ------
18
hw/timer/cmsdk-apb-timer.c | 6 ------
19
hw/watchdog/cmsdk-apb-watchdog.c | 6 ------
20
8 files changed, 28 deletions(-)
4
21
5
Cc: Peter Maydell <peter.maydell@linaro.org>
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
6
Cc: Jason Wang <jasowang@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/hw/timer/imx_gpt.h | 1 +
19
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
20
2 files changed, 26 insertions(+)
21
22
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
23
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/timer/imx_gpt.h
24
--- a/include/hw/arm/armsse.h
25
+++ b/include/hw/timer/imx_gpt.h
25
+++ b/include/hw/arm/armsse.h
26
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
27
#define TYPE_IMX25_GPT "imx25.gpt"
27
* + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
28
#define TYPE_IMX31_GPT "imx31.gpt"
28
* + QOM property "memory" is a MemoryRegion containing the devices provided
29
#define TYPE_IMX6_GPT "imx6.gpt"
29
* by the board model.
30
+#define TYPE_IMX7_GPT "imx7.gpt"
30
- * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
31
31
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
32
#define TYPE_IMX_GPT TYPE_IMX25_GPT
32
* (In hardware, the SSE-200 permits the number of expansion interrupts
33
33
* for the two CPUs to be configured separately, but we restrict it to
34
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
34
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
35
/* Properties */
36
MemoryRegion *board_memory;
37
uint32_t exp_numirq;
38
- uint32_t mainclk_frq;
39
uint32_t sram_addr_width;
40
uint32_t init_svtor;
41
bool cpu_fpu[SSE_MAX_CPUS];
42
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
35
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/timer/imx_gpt.c
44
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
37
+++ b/hw/timer/imx_gpt.c
45
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
38
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
46
@@ -XXX,XX +XXX,XX @@
39
CLK_HIGH, /* 111 reference clock */
47
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
48
*
49
* QEMU interface:
50
- * + QOM property "pclk-frq": frequency at which the timer is clocked
51
* + Clock input "TIMCLK": clock (for both timers)
52
* + sysbus MMIO region 0: the register bank
53
* + sysbus IRQ 0: combined timer interrupt TIMINTC
54
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
55
/*< public >*/
56
MemoryRegion iomem;
57
qemu_irq timerintc;
58
- uint32_t pclk_frq;
59
Clock *timclk;
60
61
CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES];
62
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/hw/timer/cmsdk-apb-timer.h
65
+++ b/include/hw/timer/cmsdk-apb-timer.h
66
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
67
68
/*
69
* QEMU interface:
70
- * + QOM property "pclk-frq": frequency at which the timer is clocked
71
* + Clock input "pclk": clock for the timer
72
* + sysbus MMIO region 0: the register bank
73
* + sysbus IRQ 0: timer interrupt TIMERINT
74
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
75
/*< public >*/
76
MemoryRegion iomem;
77
qemu_irq timerint;
78
- uint32_t pclk_frq;
79
struct ptimer_state *timer;
80
Clock *pclk;
81
82
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
83
index XXXXXXX..XXXXXXX 100644
84
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
85
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
86
@@ -XXX,XX +XXX,XX @@
87
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
88
*
89
* QEMU interface:
90
- * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
91
* + Clock input "WDOGCLK": clock for the watchdog's timer
92
* + sysbus MMIO region 0: the register bank
93
* + sysbus IRQ 0: watchdog interrupt
94
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBWatchdog {
95
/*< public >*/
96
MemoryRegion iomem;
97
qemu_irq wdogint;
98
- uint32_t wdogclk_frq;
99
bool is_luminary;
100
struct ptimer_state *timer;
101
Clock *wdogclk;
102
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/arm/armsse.c
105
+++ b/hw/arm/armsse.c
106
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
107
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
108
MemoryRegion *),
109
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
110
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
111
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
112
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
113
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
114
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
115
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
116
MemoryRegion *),
117
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
118
- DEFINE_PROP_UINT32("MAINCLK_FRQ", ARMSSE, mainclk_frq, 0),
119
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
120
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
121
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
122
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/timer/cmsdk-apb-dualtimer.c
125
+++ b/hw/timer/cmsdk-apb-dualtimer.c
126
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
127
}
40
};
128
};
41
129
42
+static const IMXClk imx7_gpt_clocks[] = {
130
-static Property cmsdk_apb_dualtimer_properties[] = {
43
+ CLK_NONE, /* 000 No clock source */
131
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
44
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
132
- DEFINE_PROP_END_OF_LIST(),
45
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
133
-};
46
+ CLK_EXT, /* 011 External clock */
134
-
47
+ CLK_32k, /* 100 ipg_clk_32k */
135
static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
48
+ CLK_HIGH, /* 101 reference clock */
49
+ CLK_NONE, /* 110 not defined */
50
+ CLK_NONE, /* 111 not defined */
51
+};
52
+
53
static void imx_gpt_set_freq(IMXGPTState *s)
54
{
136
{
55
uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
137
DeviceClass *dc = DEVICE_CLASS(klass);
56
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
138
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
57
s->clocks = imx6_gpt_clocks;
139
dc->realize = cmsdk_apb_dualtimer_realize;
140
dc->vmsd = &cmsdk_apb_dualtimer_vmstate;
141
dc->reset = cmsdk_apb_dualtimer_reset;
142
- device_class_set_props(dc, cmsdk_apb_dualtimer_properties);
58
}
143
}
59
144
60
+static void imx7_gpt_init(Object *obj)
145
static const TypeInfo cmsdk_apb_dualtimer_info = {
61
+{
146
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
62
+ IMXGPTState *s = IMX_GPT(obj);
147
index XXXXXXX..XXXXXXX 100644
63
+
148
--- a/hw/timer/cmsdk-apb-timer.c
64
+ s->clocks = imx7_gpt_clocks;
149
+++ b/hw/timer/cmsdk-apb-timer.c
65
+}
150
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
66
+
151
}
67
static const TypeInfo imx25_gpt_info = {
68
.name = TYPE_IMX25_GPT,
69
.parent = TYPE_SYS_BUS_DEVICE,
70
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
71
.instance_init = imx6_gpt_init,
72
};
152
};
73
153
74
+static const TypeInfo imx7_gpt_info = {
154
-static Property cmsdk_apb_timer_properties[] = {
75
+ .name = TYPE_IMX7_GPT,
155
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
76
+ .parent = TYPE_IMX25_GPT,
156
- DEFINE_PROP_END_OF_LIST(),
77
+ .instance_init = imx7_gpt_init,
157
-};
78
+};
158
-
79
+
159
static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
80
static void imx_gpt_register_types(void)
81
{
160
{
82
type_register_static(&imx25_gpt_info);
161
DeviceClass *dc = DEVICE_CLASS(klass);
83
type_register_static(&imx31_gpt_info);
162
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
84
type_register_static(&imx6_gpt_info);
163
dc->realize = cmsdk_apb_timer_realize;
85
+ type_register_static(&imx7_gpt_info);
164
dc->vmsd = &cmsdk_apb_timer_vmstate;
165
dc->reset = cmsdk_apb_timer_reset;
166
- device_class_set_props(dc, cmsdk_apb_timer_properties);
86
}
167
}
87
168
88
type_init(imx_gpt_register_types)
169
static const TypeInfo cmsdk_apb_timer_info = {
170
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/watchdog/cmsdk-apb-watchdog.c
173
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
174
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
175
}
176
};
177
178
-static Property cmsdk_apb_watchdog_properties[] = {
179
- DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
180
- DEFINE_PROP_END_OF_LIST(),
181
-};
182
-
183
static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
184
{
185
DeviceClass *dc = DEVICE_CLASS(klass);
186
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
187
dc->realize = cmsdk_apb_watchdog_realize;
188
dc->vmsd = &cmsdk_apb_watchdog_vmstate;
189
dc->reset = cmsdk_apb_watchdog_reset;
190
- device_class_set_props(dc, cmsdk_apb_watchdog_properties);
191
}
192
193
static const TypeInfo cmsdk_apb_watchdog_info = {
89
--
194
--
90
2.16.1
195
2.20.1
91
196
92
197
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Now that the watchdog device uses its Clock input rather than being
2
passed the value of system_clock_scale at creation time, we can
3
remove the hack where we reset the STELLARIS_SYS at board creation
4
time to force it to set system_clock_scale. Instead it will be reset
5
at the usual point in startup and will inform the watchdog of the
6
clock frequency at that point.
2
7
3
Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
The previous patches have made the change in representation
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
5
relatively painless.
10
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20210128114145.20536-26-peter.maydell@linaro.org
13
Message-id: 20210121190622.22000-26-peter.maydell@linaro.org
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
16
hw/arm/stellaris.c | 10 ----------
17
1 file changed, 10 deletions(-)
6
18
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20180123035349.24538-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 59 +++++++++++++++++++++++++++++++---------------
14
target/arm/machine.c | 35 ++++++++++++++++++++++++++-
15
target/arm/translate-a64.c | 8 +++----
16
target/arm/translate.c | 7 +++---
17
4 files changed, 81 insertions(+), 28 deletions(-)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
21
--- a/hw/arm/stellaris.c
22
+++ b/target/arm/cpu.h
22
+++ b/hw/arm/stellaris.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
@@ -XXX,XX +XXX,XX @@ static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
24
uint32_t base_mask;
24
sysbus_mmio_map(sbd, 0, base);
25
} TCR;
25
sysbus_connect_irq(sbd, 0, irq);
26
26
27
+/* Define a maximum sized vector register.
27
- /*
28
+ * For 32-bit, this is a 128-bit NEON/AdvSIMD register.
28
- * Normally we should not be resetting devices like this during
29
+ * For 64-bit, this is a 2048-bit SVE register.
29
- * board creation. For the moment we need to do so, because
30
+ *
30
- * system_clock_scale will only get set when the STELLARIS_SYS
31
+ * Note that the mapping between S, D, and Q views of the register bank
31
- * device is reset, and we need its initial value to pass to
32
+ * differs between AArch64 and AArch32.
32
- * the watchdog device. This hack can be removed once the
33
+ * In AArch32:
33
- * watchdog has been converted to use a Clock input instead.
34
+ * Qn = regs[n].d[1]:regs[n].d[0]
34
- */
35
+ * Dn = regs[n / 2].d[n & 1]
35
- device_cold_reset(dev);
36
+ * Sn = regs[n / 4].d[n % 4 / 2],
36
-
37
+ * bits 31..0 for even n, and bits 63..32 for odd n
37
return dev;
38
+ * (and regs[16] to regs[31] are inaccessible)
39
+ * In AArch64:
40
+ * Zn = regs[n].d[*]
41
+ * Qn = regs[n].d[1]:regs[n].d[0]
42
+ * Dn = regs[n].d[0]
43
+ * Sn = regs[n].d[0] bits 31..0
44
+ *
45
+ * This corresponds to the architecturally defined mapping between
46
+ * the two execution states, and means we do not need to explicitly
47
+ * map these registers when changing states.
48
+ *
49
+ * Align the data for use with TCG host vector operations.
50
+ */
51
+
52
+#ifdef TARGET_AARCH64
53
+# define ARM_MAX_VQ 16
54
+#else
55
+# define ARM_MAX_VQ 1
56
+#endif
57
+
58
+typedef struct ARMVectorReg {
59
+ uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
60
+} ARMVectorReg;
61
+
62
+
63
typedef struct CPUARMState {
64
/* Regs for current mode. */
65
uint32_t regs[16];
66
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
67
68
/* VFP coprocessor state. */
69
struct {
70
- /* VFP/Neon register state. Note that the mapping between S, D and Q
71
- * views of the register bank differs between AArch64 and AArch32:
72
- * In AArch32:
73
- * Qn = regs[2n+1]:regs[2n]
74
- * Dn = regs[n]
75
- * Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n
76
- * (and regs[32] to regs[63] are inaccessible)
77
- * In AArch64:
78
- * Qn = regs[2n+1]:regs[2n]
79
- * Dn = regs[2n]
80
- * Sn = regs[2n] bits 31..0
81
- * This corresponds to the architecturally defined mapping between
82
- * the two execution states, and means we do not need to explicitly
83
- * map these registers when changing states.
84
- */
85
- uint64_t regs[64] QEMU_ALIGNED(16);
86
+ ARMVectorReg zregs[32];
87
88
uint32_t xregs[16];
89
/* We store these fpcsr fields separately for convenience. */
90
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
91
*/
92
static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
93
{
94
- return &env->vfp.regs[regno];
95
+ return &env->vfp.zregs[regno >> 1].d[regno & 1];
96
}
38
}
97
39
98
/**
99
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
100
*/
101
static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
102
{
103
- return &env->vfp.regs[2 * regno];
104
+ return &env->vfp.zregs[regno].d[0];
105
}
106
107
/**
108
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
109
*/
110
static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
111
{
112
- return &env->vfp.regs[2 * regno];
113
+ return &env->vfp.zregs[regno].d[0];
114
}
115
116
#endif
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
122
.minimum_version_id = 3,
123
.needed = vfp_needed,
124
.fields = (VMStateField[]) {
125
- VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
126
+ /* For compatibility, store Qn out of Zn here. */
127
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[0].d, ARMCPU, 0, 2),
128
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[1].d, ARMCPU, 0, 2),
129
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[2].d, ARMCPU, 0, 2),
130
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[3].d, ARMCPU, 0, 2),
131
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[4].d, ARMCPU, 0, 2),
132
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[5].d, ARMCPU, 0, 2),
133
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[6].d, ARMCPU, 0, 2),
134
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[7].d, ARMCPU, 0, 2),
135
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[8].d, ARMCPU, 0, 2),
136
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[9].d, ARMCPU, 0, 2),
137
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[10].d, ARMCPU, 0, 2),
138
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[11].d, ARMCPU, 0, 2),
139
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[12].d, ARMCPU, 0, 2),
140
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[13].d, ARMCPU, 0, 2),
141
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[14].d, ARMCPU, 0, 2),
142
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[15].d, ARMCPU, 0, 2),
143
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[16].d, ARMCPU, 0, 2),
144
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[17].d, ARMCPU, 0, 2),
145
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[18].d, ARMCPU, 0, 2),
146
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[19].d, ARMCPU, 0, 2),
147
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[20].d, ARMCPU, 0, 2),
148
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[21].d, ARMCPU, 0, 2),
149
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[22].d, ARMCPU, 0, 2),
150
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[23].d, ARMCPU, 0, 2),
151
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[24].d, ARMCPU, 0, 2),
152
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[25].d, ARMCPU, 0, 2),
153
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[26].d, ARMCPU, 0, 2),
154
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[27].d, ARMCPU, 0, 2),
155
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[28].d, ARMCPU, 0, 2),
156
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[29].d, ARMCPU, 0, 2),
157
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[30].d, ARMCPU, 0, 2),
158
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[31].d, ARMCPU, 0, 2),
159
+
160
/* The xregs array is a little awkward because element 1 (FPSCR)
161
* requires a specific accessor, so we have to split it up in
162
* the vmstate:
163
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-a64.c
166
+++ b/target/arm/translate-a64.c
167
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
168
{
169
int offs = 0;
170
#ifdef HOST_WORDS_BIGENDIAN
171
- /* This is complicated slightly because vfp.regs[2n] is
172
- * still the low half and vfp.regs[2n+1] the high half
173
+ /* This is complicated slightly because vfp.zregs[n].d[0] is
174
+ * still the low half and vfp.zregs[n].d[1] the high half
175
* of the 128 bit vector, even on big endian systems.
176
* Calculate the offset assuming a fully bigendian 128 bits,
177
* then XOR to account for the order of the two 64 bit halves.
178
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
179
#else
180
offs += element * (1 << size);
181
#endif
182
- offs += offsetof(CPUARMState, vfp.regs[regno * 2]);
183
+ offs += offsetof(CPUARMState, vfp.zregs[regno]);
184
assert_fp_access_checked(s);
185
return offs;
186
}
187
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
188
static inline int vec_full_reg_offset(DisasContext *s, int regno)
189
{
190
assert_fp_access_checked(s);
191
- return offsetof(CPUARMState, vfp.regs[regno * 2]);
192
+ return offsetof(CPUARMState, vfp.zregs[regno]);
193
}
194
195
/* Return a newly allocated pointer to the vector register. */
196
diff --git a/target/arm/translate.c b/target/arm/translate.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/translate.c
199
+++ b/target/arm/translate.c
200
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
201
}
202
}
203
204
-static inline long
205
-vfp_reg_offset (int dp, int reg)
206
+static inline long vfp_reg_offset(bool dp, unsigned reg)
207
{
208
if (dp) {
209
- return offsetof(CPUARMState, vfp.regs[reg]);
210
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
211
} else {
212
- long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
213
+ long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
214
if (reg & 1) {
215
ofs += offsetof(CPU_DoubleU, l.upper);
216
} else {
217
--
40
--
218
2.16.1
41
2.20.1
219
42
220
43
diff view generated by jsdifflib