1
The following changes since commit 4c41341af76cfc85b5a6c0f87de4838672ab9f89:
1
The following changes since commit 7e7eb9f852a46b51a71ae9d82590b2e4d28827ee:
2
2
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20201020' into staging (2020-10-20 11:20:36 +0100)
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-01-28' into staging (2021-01-28 22:43:18 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201020
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210129
8
8
9
for you to fetch changes up to 6358890cb939192f6169fdf7664d903bf9b1d338:
9
for you to fetch changes up to 11749122e1a86866591306d43603d2795a3dea1a:
10
10
11
tests/tcg/aarch64: Add bti smoke tests (2020-10-20 16:12:02 +0100)
11
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS (2021-01-29 10:47:29 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* Fix AArch32 SMLAD incorrect setting of Q bit
15
* Implement ID_PFR2
16
* AArch32 VCVT fixed-point to float is always round-to-nearest
16
* Conditionalize DBGDIDR
17
* strongarm: Fix 'time to transmit a char' unit comment
17
* rename xlnx-zcu102.canbusN properties
18
* Restrict APEI tables generation to the 'virt' machine
18
* provide powerdown/reset mechanism for secure firmware on 'virt' board
19
* bcm2835: minor code cleanups
19
* hw/misc: Fix arith overflow in NPCM7XX PWM module
20
* correctly flush TLBs when TBI is enabled
20
* target/arm: Replace magic value by MMU_DATA_LOAD definition
21
* tests/qtest: Add npcm7xx timer test
21
* configure: fix preadv errors on Catalina macOS with new XCode
22
* loads-stores.rst: add footnote that clarifies GETPC usage
22
* Various configure and other cleanups in preparation for iOS support
23
* Fix reported EL for mte_check_fail
23
* hvf: Add hypervisor entitlement to output binaries (needed for Big Sur)
24
* Ignore HCR_EL2.ATA when {E2H,TGE} != 11
24
* Implement pvpanic-pci device
25
* microbit_i2c: Fix coredump when dump-vmstate
25
* Convert the CMSDK timer devices to the Clock framework
26
* nseries: Fix loading kernel image on n8x0 machines
27
* Implement v8.1M low-overhead-loops
28
* linux-user: Support AArch64 BTI
29
26
30
----------------------------------------------------------------
27
----------------------------------------------------------------
31
Emanuele Giuseppe Esposito (1):
28
Alexander Graf (1):
32
loads-stores.rst: add footnote that clarifies GETPC usage
29
hvf: Add hypervisor entitlement to output binaries
33
30
34
Havard Skinnemoen (1):
31
Hao Wu (1):
35
tests/qtest: Add npcm7xx timer test
32
hw/misc: Fix arith overflow in NPCM7XX PWM module
36
33
37
Peng Liang (1):
34
Joelle van Dyne (7):
38
microbit_i2c: Fix coredump when dump-vmstate
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
39
42
40
Peter Maydell (12):
43
Maxim Uvarov (3):
41
target/arm: Fix SMLAD incorrect setting of Q bit
44
hw: gpio: implement gpio-pwr driver for qemu reset/poweroff
42
target/arm: AArch32 VCVT fixed-point to float is always round-to-nearest
45
arm-virt: refactor gpios creation
43
decodetree: Fix codegen for non-overlapping group inside overlapping group
46
arm-virt: add secure pl061 for reset/power down
44
target/arm: Implement v8.1M NOCP handling
45
target/arm: Implement v8.1M conditional-select insns
46
target/arm: Make the t32 insn[25:23]=111 group non-overlapping
47
target/arm: Don't allow BLX imm for M-profile
48
target/arm: Implement v8.1M branch-future insns (as NOPs)
49
target/arm: Implement v8.1M low-overhead-loop instructions
50
target/arm: Fix has_vfp/has_neon ID reg squashing for M-profile
51
target/arm: Allow M-profile CPUs with FP16 to set FPSCR.FP16
52
target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension
53
47
54
Philippe Mathieu-Daudé (10):
48
Mihai Carabas (4):
55
hw/arm/strongarm: Fix 'time to transmit a char' unit comment
49
hw/misc/pvpanic: split-out generic and bus dependent code
56
hw/arm: Restrict APEI tables generation to the 'virt' machine
50
hw/misc/pvpanic: add PCI interface support
57
hw/timer/bcm2835: Introduce BCM2835_SYSTIMER_COUNT definition
51
pvpanic : update pvpanic spec document
58
hw/timer/bcm2835: Rename variable holding CTRL_STATUS register
52
tests/qtest: add a test case for pvpanic-pci
59
hw/timer/bcm2835: Support the timer COMPARE registers
60
hw/arm/bcm2835_peripherals: Correctly wire the SYS_timer IRQs
61
hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers
62
hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers
63
hw/arm/nseries: Fix loading kernel image on n8x0 machines
64
linux-user/elfload: Avoid leaking interp_name using GLib memory API
65
53
66
Richard Henderson (16):
54
Paolo Bonzini (1):
67
accel/tcg: Add tlb_flush_page_bits_by_mmuidx*
55
arm: rename xlnx-zcu102.canbusN properties
68
target/arm: Use tlb_flush_page_bits_by_mmuidx*
69
target/arm: Remove redundant mmu_idx lookup
70
target/arm: Fix reported EL for mte_check_fail
71
target/arm: Ignore HCR_EL2.ATA when {E2H,TGE} != 11
72
linux-user/aarch64: Reset btype for signals
73
linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI
74
include/elf: Add defines related to GNU property notes for AArch64
75
linux-user/elfload: Fix coding style in load_elf_image
76
linux-user/elfload: Adjust iteration over phdr
77
linux-user/elfload: Move PT_INTERP detection to first loop
78
linux-user/elfload: Use Error for load_elf_image
79
linux-user/elfload: Use Error for load_elf_interp
80
linux-user/elfload: Parse NT_GNU_PROPERTY_TYPE_0 notes
81
linux-user/elfload: Parse GNU_PROPERTY_AARCH64_FEATURE_1_AND
82
tests/tcg/aarch64: Add bti smoke tests
83
56
84
docs/devel/loads-stores.rst | 8 +-
57
Peter Maydell (26):
85
default-configs/devices/arm-softmmu.mak | 1 -
58
configure: Move preadv check to meson.build
86
include/elf.h | 22 ++
59
ptimer: Add new ptimer_set_period_from_clock() function
87
include/exec/cpu-all.h | 2 +
60
clock: Add new clock_has_source() function
88
include/exec/exec-all.h | 36 ++
61
tests: Add a simple test of the CMSDK APB timer
89
include/hw/timer/bcm2835_systmr.h | 17 +-
62
tests: Add a simple test of the CMSDK APB watchdog
90
linux-user/qemu.h | 4 +
63
tests: Add a simple test of the CMSDK APB dual timer
91
linux-user/syscall_defs.h | 4 +
64
hw/timer/cmsdk-apb-timer: Rename CMSDKAPBTIMER struct to CMSDKAPBTimer
92
target/arm/cpu.h | 13 +
65
hw/timer/cmsdk-apb-timer: Add Clock input
93
target/arm/helper.h | 13 +
66
hw/timer/cmsdk-apb-dualtimer: Add Clock input
94
target/arm/internals.h | 9 +-
67
hw/watchdog/cmsdk-apb-watchdog: Add Clock input
95
target/arm/m-nocp.decode | 10 +-
68
hw/arm/armsse: Rename "MAINCLK" property to "MAINCLK_FRQ"
96
target/arm/t32.decode | 50 ++-
69
hw/arm/armsse: Wire up clocks
97
accel/tcg/cputlb.c | 275 +++++++++++++++-
70
hw/arm/mps2: Inline CMSDK_APB_TIMER creation
98
hw/arm/bcm2835_peripherals.c | 13 +-
71
hw/arm/mps2: Create and connect SYSCLK Clock
99
hw/arm/nseries.c | 1 +
72
hw/arm/mps2-tz: Create and connect ARMSSE Clocks
100
hw/arm/strongarm.c | 2 +-
73
hw/arm/musca: Create and connect ARMSSE Clocks
101
hw/i2c/microbit_i2c.c | 1 +
74
hw/arm/stellaris: Convert SSYS to QOM device
102
hw/intc/bcm2835_ic.c | 4 +-
75
hw/arm/stellaris: Create Clock input for watchdog
103
hw/intc/bcm2836_control.c | 8 +-
76
hw/timer/cmsdk-apb-timer: Convert to use Clock input
104
hw/timer/bcm2835_systmr.c | 57 ++--
77
hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
105
linux-user/aarch64/signal.c | 10 +-
78
hw/watchdog/cmsdk-apb-watchdog: Convert to use Clock input
106
linux-user/elfload.c | 326 ++++++++++++++----
79
tests/qtest/cmsdk-apb-watchdog-test: Test clock changes
107
linux-user/mmap.c | 16 +
80
hw/arm/armsse: Use Clock to set system_clock_scale
108
target/arm/cpu.c | 38 ++-
81
arm: Don't set freq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
109
target/arm/helper.c | 55 +++-
82
arm: Remove frq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
110
target/arm/mte_helper.c | 13 +-
83
hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS
111
target/arm/translate-a64.c | 6 +-
112
target/arm/translate.c | 239 +++++++++++++-
113
target/arm/vfp_helper.c | 76 +++--
114
tests/qtest/npcm7xx_timer-test.c | 562 ++++++++++++++++++++++++++++++++
115
tests/tcg/aarch64/bti-1.c | 62 ++++
116
tests/tcg/aarch64/bti-2.c | 108 ++++++
117
tests/tcg/aarch64/bti-crt.inc.c | 51 +++
118
hw/arm/Kconfig | 1 +
119
hw/intc/trace-events | 4 +
120
hw/timer/trace-events | 6 +-
121
scripts/decodetree.py | 2 +-
122
target/arm/translate-vfp.c.inc | 41 ++-
123
tests/qtest/meson.build | 1 +
124
tests/tcg/aarch64/Makefile.target | 10 +
125
tests/tcg/configure.sh | 4 +
126
42 files changed, 1973 insertions(+), 208 deletions(-)
127
create mode 100644 tests/qtest/npcm7xx_timer-test.c
128
create mode 100644 tests/tcg/aarch64/bti-1.c
129
create mode 100644 tests/tcg/aarch64/bti-2.c
130
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
131
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
Transform the prot bit to a qemu internal page bit, and save
3
This was defined at some point before ARMv8.4, and will
4
it in the page tables.
4
shortly be used by new processor descriptions.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201016184207.786698-3-richard.henderson@linaro.org
8
Message-id: 20210120204400.1056582-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/exec/cpu-all.h | 2 ++
11
target/arm/cpu.h | 1 +
12
linux-user/syscall_defs.h | 4 ++++
12
target/arm/helper.c | 4 ++--
13
target/arm/cpu.h | 5 +++++
13
target/arm/kvm64.c | 2 ++
14
linux-user/mmap.c | 16 ++++++++++++++++
14
3 files changed, 5 insertions(+), 2 deletions(-)
15
target/arm/translate-a64.c | 6 +++---
16
5 files changed, 30 insertions(+), 3 deletions(-)
17
15
18
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/cpu-all.h
21
+++ b/include/exec/cpu-all.h
22
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
23
/* FIXME: Code that sets/uses this is broken and needs to go away. */
24
#define PAGE_RESERVED 0x0020
25
#endif
26
+/* Target-specific bits that will be used via page_get_flags(). */
27
+#define PAGE_TARGET_1 0x0080
28
29
#if defined(CONFIG_USER_ONLY)
30
void page_dump(FILE *f);
31
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/linux-user/syscall_defs.h
34
+++ b/linux-user/syscall_defs.h
35
@@ -XXX,XX +XXX,XX @@ struct target_winsize {
36
#define TARGET_PROT_SEM 0x08
37
#endif
38
39
+#ifdef TARGET_AARCH64
40
+#define TARGET_PROT_BTI 0x10
41
+#endif
42
+
43
/* Common */
44
#define TARGET_MAP_SHARED    0x01        /* Share changes */
45
#define TARGET_MAP_PRIVATE    0x02        /* Changes are private */
46
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
47
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
51
#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0)
21
uint32_t id_mmfr4;
52
#define arm_tlb_mte_tagged(x) (typecheck_memtxattrs(x)->target_tlb_bit1)
22
uint32_t id_pfr0;
53
23
uint32_t id_pfr1;
54
+/*
24
+ uint32_t id_pfr2;
55
+ * AArch64 usage of the PAGE_TARGET_* bits for linux-user.
25
uint32_t mvfr0;
56
+ */
26
uint32_t mvfr1;
57
+#define PAGE_BTI PAGE_TARGET_1
27
uint32_t mvfr2;
58
+
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
/*
60
* Naming convention for isar_feature functions:
61
* Functions which test 32-bit ID registers should have _aa32_ in
62
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
63
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
64
--- a/linux-user/mmap.c
30
--- a/target/arm/helper.c
65
+++ b/linux-user/mmap.c
31
+++ b/target/arm/helper.c
66
@@ -XXX,XX +XXX,XX @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
67
*host_prot = (prot & (PROT_READ | PROT_WRITE))
33
.access = PL1_R, .type = ARM_CP_CONST,
68
| (prot & PROT_EXEC ? PROT_READ : 0);
34
.accessfn = access_aa64_tid3,
69
35
.resetvalue = 0 },
70
+#ifdef TARGET_AARCH64
36
- { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
71
+ /*
37
+ { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
72
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
38
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
73
+ * Since this is the unusual case, don't bother checking unless
39
.access = PL1_R, .type = ARM_CP_CONST,
74
+ * the bit has been requested. If set and valid, record the bit
40
.accessfn = access_aa64_tid3,
75
+ * within QEMU's page_flags.
41
- .resetvalue = 0 },
76
+ */
42
+ .resetvalue = cpu->isar.id_pfr2 },
77
+ if (prot & TARGET_PROT_BTI) {
43
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
78
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
44
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
79
+ if (cpu_isar_feature(aa64_bti, cpu)) {
45
.access = PL1_R, .type = ARM_CP_CONST,
80
+ valid |= TARGET_PROT_BTI;
46
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
81
+ page_flags |= PAGE_BTI;
82
+ }
83
+ }
84
+#endif
85
+
86
return prot & ~valid ? 0 : page_flags;
87
}
88
89
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
90
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-a64.c
48
--- a/target/arm/kvm64.c
92
+++ b/target/arm/translate-a64.c
49
+++ b/target/arm/kvm64.c
93
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
50
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
94
*/
51
ARM64_SYS_REG(3, 0, 0, 1, 0));
95
static bool is_guarded_page(CPUARMState *env, DisasContext *s)
52
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
96
{
53
ARM64_SYS_REG(3, 0, 0, 1, 1));
97
-#ifdef CONFIG_USER_ONLY
54
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
98
- return false; /* FIXME */
55
+ ARM64_SYS_REG(3, 0, 0, 3, 4));
99
-#else
56
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
100
uint64_t addr = s->base.pc_first;
57
ARM64_SYS_REG(3, 0, 0, 1, 2));
101
+#ifdef CONFIG_USER_ONLY
58
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
102
+ return page_get_flags(addr) & PAGE_BTI;
103
+#else
104
int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
105
unsigned int index = tlb_index(env, mmu_idx, addr);
106
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
107
--
59
--
108
2.20.1
60
2.20.1
109
61
110
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
Unlike many other bits in HCR_EL2, the description for this
3
Only define the register if it exists for the cpu.
4
bit does not contain the phrase "if ... this field behaves
5
as 0 for all purposes other than", so do not squash the bit
6
in arm_hcr_el2_eff.
7
4
8
Instead, replicate the E2H+TGE test in the two places that
9
require it.
10
11
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
6
Message-id: 20210120031656.737646-1-richard.henderson@linaro.org
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20201008162155.161886-4-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
9
---
18
target/arm/internals.h | 9 +++++----
10
target/arm/helper.c | 21 +++++++++++++++------
19
target/arm/helper.c | 9 +++++----
11
1 file changed, 15 insertions(+), 6 deletions(-)
20
2 files changed, 10 insertions(+), 8 deletions(-)
21
12
22
diff --git a/target/arm/internals.h b/target/arm/internals.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/internals.h
25
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
27
&& !(env->cp15.scr_el3 & SCR_ATA)) {
28
return false;
29
}
30
- if (el < 2
31
- && arm_feature(env, ARM_FEATURE_EL2)
32
- && !(arm_hcr_el2_eff(env) & HCR_ATA)) {
33
- return false;
34
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
35
+ uint64_t hcr = arm_hcr_el2_eff(env);
36
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
37
+ return false;
38
+ }
39
}
40
sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
41
return sctlr != 0;
42
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
43
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
17
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
47
{
18
*/
48
int el = arm_current_el(env);
19
int i;
49
20
int wrps, brps, ctx_cmps;
50
- if (el < 2 &&
21
- ARMCPRegInfo dbgdidr = {
51
- arm_feature(env, ARM_FEATURE_EL2) &&
22
- .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
52
- !(arm_hcr_el2_eff(env) & HCR_ATA)) {
23
- .access = PL0_R, .accessfn = access_tda,
53
- return CP_ACCESS_TRAP_EL2;
24
- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
54
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
25
- };
55
+ uint64_t hcr = arm_hcr_el2_eff(env);
26
+
56
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
27
+ /*
57
+ return CP_ACCESS_TRAP_EL2;
28
+ * The Arm ARM says DBGDIDR is optional and deprecated if EL1 cannot
58
+ }
29
+ * use AArch32. Given that bit 15 is RES1, if the value is 0 then
59
}
30
+ * the register must not exist for this cpu.
60
if (el < 3 &&
31
+ */
61
arm_feature(env, ARM_FEATURE_EL3) &&
32
+ if (cpu->isar.dbgdidr != 0) {
33
+ ARMCPRegInfo dbgdidr = {
34
+ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
35
+ .opc1 = 0, .opc2 = 0,
36
+ .access = PL0_R, .accessfn = access_tda,
37
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
38
+ };
39
+ define_one_arm_cp_reg(cpu, &dbgdidr);
40
+ }
41
42
/* Note that all these register fields hold "number of Xs minus 1". */
43
brps = arm_num_brps(cpu);
44
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
45
46
assert(ctx_cmps <= brps);
47
48
- define_one_arm_cp_reg(cpu, &dbgdidr);
49
define_arm_cp_regs(cpu, debug_cp_reginfo);
50
51
if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
62
--
52
--
63
2.20.1
53
2.20.1
64
54
65
55
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Fix an unlikely memory leak in load_elf_image().
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.
4
7
5
Fixes: bf858897b7 ("linux-user: Re-use load_elf_image for the main binary.")
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210118162537.779542-1-pbonzini@redhat.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Vikram Garhwal <fnu.vikram@xilinx.com>
8
Message-id: 20201016184207.786698-5-richard.henderson@linaro.org
9
Message-Id: <20201003174944.1972444-1-f4bug@amsat.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
linux-user/elfload.c | 8 ++++----
13
hw/arm/xlnx-zcu102.c | 4 ++--
15
1 file changed, 4 insertions(+), 4 deletions(-)
14
tests/qtest/xlnx-can-test.c | 30 +++++++++++++++---------------
15
2 files changed, 17 insertions(+), 17 deletions(-)
16
16
17
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/elfload.c
19
--- a/hw/arm/xlnx-zcu102.c
20
+++ b/linux-user/elfload.c
20
+++ b/hw/arm/xlnx-zcu102.c
21
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
22
info->brk = vaddr_em;
22
s->secure = false;
23
}
23
/* Default to virt (EL2) being disabled */
24
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
24
s->virt = false;
25
- char *interp_name;
25
- object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
26
+ g_autofree char *interp_name = NULL;
26
+ object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
27
27
(Object **)&s->canbus[0],
28
if (*pinterp_name) {
28
object_property_allow_set_link,
29
errmsg = "Multiple PT_INTERP entries";
29
0);
30
goto exit_errmsg;
30
31
}
31
- object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
32
- interp_name = malloc(eppnt->p_filesz);
32
+ object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
33
+ interp_name = g_malloc(eppnt->p_filesz);
33
(Object **)&s->canbus[1],
34
if (!interp_name) {
34
object_property_allow_set_link,
35
goto exit_perror;
35
0);
36
}
36
diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
37
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
37
index XXXXXXX..XXXXXXX 100644
38
errmsg = "Invalid PT_INTERP entry";
38
--- a/tests/qtest/xlnx-can-test.c
39
goto exit_errmsg;
39
+++ b/tests/qtest/xlnx-can-test.c
40
}
40
@@ -XXX,XX +XXX,XX @@ static void test_can_bus(void)
41
- *pinterp_name = interp_name;
41
uint8_t can_timestamp = 1;
42
+ *pinterp_name = g_steal_pointer(&interp_name);
42
43
#ifdef TARGET_MIPS
43
QTestState *qts = qtest_init("-machine xlnx-zcu102"
44
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
44
- " -object can-bus,id=canbus0"
45
Mips_elf_abiflags_v0 abiflags;
45
- " -machine xlnx-zcu102.canbus0=canbus0"
46
@@ -XXX,XX +XXX,XX @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
46
- " -machine xlnx-zcu102.canbus1=canbus0"
47
if (elf_interpreter) {
47
+ " -object can-bus,id=canbus"
48
info->load_bias = interp_info.load_bias;
48
+ " -machine canbus0=canbus"
49
info->entry = interp_info.entry;
49
+ " -machine canbus1=canbus"
50
- free(elf_interpreter);
50
);
51
+ g_free(elf_interpreter);
51
52
}
52
/* Configure the CAN0 and CAN1. */
53
53
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
54
#ifdef USE_ELF_CORE_DUMP
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. */
55
--
105
--
56
2.20.1
106
2.20.1
57
107
58
108
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
The note test requires gcc 10 for -mbranch-protection=standard.
3
Implement gpio-pwr driver to allow reboot and poweroff machine.
4
The mmap test uses PROT_BTI and does not require special compiler support.
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
Acked-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201016184207.786698-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
tests/tcg/aarch64/bti-1.c | 62 +++++++++++++++++
13
hw/gpio/gpio_pwr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
13
tests/tcg/aarch64/bti-2.c | 108 ++++++++++++++++++++++++++++++
14
hw/gpio/Kconfig | 3 ++
14
tests/tcg/aarch64/bti-crt.inc.c | 51 ++++++++++++++
15
hw/gpio/meson.build | 1 +
15
tests/tcg/aarch64/Makefile.target | 10 +++
16
3 files changed, 74 insertions(+)
16
tests/tcg/configure.sh | 4 ++
17
create mode 100644 hw/gpio/gpio_pwr.c
17
5 files changed, 235 insertions(+)
18
create mode 100644 tests/tcg/aarch64/bti-1.c
19
create mode 100644 tests/tcg/aarch64/bti-2.c
20
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
21
18
22
diff --git a/tests/tcg/aarch64/bti-1.c b/tests/tcg/aarch64/bti-1.c
19
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
23
new file mode 100644
20
new file mode 100644
24
index XXXXXXX..XXXXXXX
21
index XXXXXXX..XXXXXXX
25
--- /dev/null
22
--- /dev/null
26
+++ b/tests/tcg/aarch64/bti-1.c
23
+++ b/hw/gpio/gpio_pwr.c
27
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
28
+/*
25
+/*
29
+ * Branch target identification, basic notskip cases.
26
+ * GPIO qemu power controller
27
+ *
28
+ * Copyright (c) 2020 Linaro Limited
29
+ *
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.).
36
+ *
37
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38
+ * See the COPYING file in the top-level directory.
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
30
+ */
40
+ */
31
+
41
+
32
+#include "bti-crt.inc.c"
42
+/*
43
+ * QEMU interface:
44
+ * two named input GPIO lines:
45
+ * 'reset' : when asserted, trigger system reset
46
+ * 'shutdown' : when asserted, trigger system shutdown
47
+ */
33
+
48
+
34
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
49
+#include "qemu/osdep.h"
50
+#include "hw/sysbus.h"
51
+#include "sysemu/runstate.h"
52
+
53
+#define TYPE_GPIOPWR "gpio-pwr"
54
+OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
55
+
56
+struct GPIO_PWR_State {
57
+ SysBusDevice parent_obj;
58
+};
59
+
60
+static void gpio_pwr_reset(void *opaque, int n, int level)
35
+{
61
+{
36
+ uc->uc_mcontext.pc += 8;
62
+ if (level) {
37
+ uc->uc_mcontext.pstate = 1;
63
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
64
+ }
38
+}
65
+}
39
+
66
+
40
+#define NOP "nop"
67
+static void gpio_pwr_shutdown(void *opaque, int n, int level)
41
+#define BTI_N "hint #32"
42
+#define BTI_C "hint #34"
43
+#define BTI_J "hint #36"
44
+#define BTI_JC "hint #38"
45
+
46
+#define BTYPE_1(DEST) \
47
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: " DEST "; mov %0,#0" \
48
+ : "=r"(skipped) : : "x16")
49
+
50
+#define BTYPE_2(DEST) \
51
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: " DEST "; mov %0,#0" \
52
+ : "=r"(skipped) : : "x16", "x30")
53
+
54
+#define BTYPE_3(DEST) \
55
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: " DEST "; mov %0,#0" \
56
+ : "=r"(skipped) : : "x15")
57
+
58
+#define TEST(WHICH, DEST, EXPECT) \
59
+ do { WHICH(DEST); fail += skipped ^ EXPECT; } while (0)
60
+
61
+
62
+int main()
63
+{
68
+{
64
+ int fail = 0;
69
+ if (level) {
65
+ int skipped;
70
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
66
+
71
+ }
67
+ /* Signal-like with SA_SIGINFO. */
68
+ signal_info(SIGILL, skip2_sigill);
69
+
70
+ TEST(BTYPE_1, NOP, 1);
71
+ TEST(BTYPE_1, BTI_N, 1);
72
+ TEST(BTYPE_1, BTI_C, 0);
73
+ TEST(BTYPE_1, BTI_J, 0);
74
+ TEST(BTYPE_1, BTI_JC, 0);
75
+
76
+ TEST(BTYPE_2, NOP, 1);
77
+ TEST(BTYPE_2, BTI_N, 1);
78
+ TEST(BTYPE_2, BTI_C, 0);
79
+ TEST(BTYPE_2, BTI_J, 1);
80
+ TEST(BTYPE_2, BTI_JC, 0);
81
+
82
+ TEST(BTYPE_3, NOP, 1);
83
+ TEST(BTYPE_3, BTI_N, 1);
84
+ TEST(BTYPE_3, BTI_C, 1);
85
+ TEST(BTYPE_3, BTI_J, 0);
86
+ TEST(BTYPE_3, BTI_JC, 0);
87
+
88
+ return fail;
89
+}
90
diff --git a/tests/tcg/aarch64/bti-2.c b/tests/tcg/aarch64/bti-2.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/tests/tcg/aarch64/bti-2.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * Branch target identification, basic notskip cases.
98
+ */
99
+
100
+#include <stdio.h>
101
+#include <signal.h>
102
+#include <string.h>
103
+#include <unistd.h>
104
+#include <sys/mman.h>
105
+
106
+#ifndef PROT_BTI
107
+#define PROT_BTI 0x10
108
+#endif
109
+
110
+static void skip2_sigill(int sig, siginfo_t *info, void *vuc)
111
+{
112
+ ucontext_t *uc = vuc;
113
+ uc->uc_mcontext.pc += 8;
114
+ uc->uc_mcontext.pstate = 1;
115
+}
72
+}
116
+
73
+
117
+#define NOP "nop"
74
+static void gpio_pwr_init(Object *obj)
118
+#define BTI_N "hint #32"
75
+{
119
+#define BTI_C "hint #34"
76
+ DeviceState *dev = DEVICE(obj);
120
+#define BTI_J "hint #36"
121
+#define BTI_JC "hint #38"
122
+
77
+
123
+#define BTYPE_1(DEST) \
78
+ qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
124
+ "mov x1, #1\n\t" \
79
+ qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
125
+ "adr x16, 1f\n\t" \
126
+ "br x16\n" \
127
+"1: " DEST "\n\t" \
128
+ "mov x1, #0"
129
+
130
+#define BTYPE_2(DEST) \
131
+ "mov x1, #1\n\t" \
132
+ "adr x16, 1f\n\t" \
133
+ "blr x16\n" \
134
+"1: " DEST "\n\t" \
135
+ "mov x1, #0"
136
+
137
+#define BTYPE_3(DEST) \
138
+ "mov x1, #1\n\t" \
139
+ "adr x15, 1f\n\t" \
140
+ "br x15\n" \
141
+"1: " DEST "\n\t" \
142
+ "mov x1, #0"
143
+
144
+#define TEST(WHICH, DEST, EXPECT) \
145
+ WHICH(DEST) "\n" \
146
+ ".if " #EXPECT "\n\t" \
147
+ "eor x1, x1," #EXPECT "\n" \
148
+ ".endif\n\t" \
149
+ "add x0, x0, x1\n\t"
150
+
151
+extern char test_begin[], test_end[];
152
+
153
+asm("\n"
154
+"test_begin:\n\t"
155
+ BTI_C "\n\t"
156
+ "mov x2, x30\n\t"
157
+ "mov x0, #0\n\t"
158
+
159
+ TEST(BTYPE_1, NOP, 1)
160
+ TEST(BTYPE_1, BTI_N, 1)
161
+ TEST(BTYPE_1, BTI_C, 0)
162
+ TEST(BTYPE_1, BTI_J, 0)
163
+ TEST(BTYPE_1, BTI_JC, 0)
164
+
165
+ TEST(BTYPE_2, NOP, 1)
166
+ TEST(BTYPE_2, BTI_N, 1)
167
+ TEST(BTYPE_2, BTI_C, 0)
168
+ TEST(BTYPE_2, BTI_J, 1)
169
+ TEST(BTYPE_2, BTI_JC, 0)
170
+
171
+ TEST(BTYPE_3, NOP, 1)
172
+ TEST(BTYPE_3, BTI_N, 1)
173
+ TEST(BTYPE_3, BTI_C, 1)
174
+ TEST(BTYPE_3, BTI_J, 0)
175
+ TEST(BTYPE_3, BTI_JC, 0)
176
+
177
+ "ret x2\n"
178
+"test_end:"
179
+);
180
+
181
+int main()
182
+{
183
+ struct sigaction sa;
184
+
185
+ void *p = mmap(0, getpagesize(),
186
+ PROT_EXEC | PROT_READ | PROT_WRITE | PROT_BTI,
187
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
188
+ if (p == MAP_FAILED) {
189
+ perror("mmap");
190
+ return 1;
191
+ }
192
+
193
+ memset(&sa, 0, sizeof(sa));
194
+ sa.sa_sigaction = skip2_sigill;
195
+ sa.sa_flags = SA_SIGINFO;
196
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
197
+ perror("sigaction");
198
+ return 1;
199
+ }
200
+
201
+ memcpy(p, test_begin, test_end - test_begin);
202
+ return ((int (*)(void))p)();
203
+}
204
diff --git a/tests/tcg/aarch64/bti-crt.inc.c b/tests/tcg/aarch64/bti-crt.inc.c
205
new file mode 100644
206
index XXXXXXX..XXXXXXX
207
--- /dev/null
208
+++ b/tests/tcg/aarch64/bti-crt.inc.c
209
@@ -XXX,XX +XXX,XX @@
210
+/*
211
+ * Minimal user-environment for testing BTI.
212
+ *
213
+ * Normal libc is not (yet) built with BTI support enabled,
214
+ * and so could generate a BTI TRAP before ever reaching main.
215
+ */
216
+
217
+#include <stdlib.h>
218
+#include <signal.h>
219
+#include <ucontext.h>
220
+#include <asm/unistd.h>
221
+
222
+int main(void);
223
+
224
+void _start(void)
225
+{
226
+ exit(main());
227
+}
80
+}
228
+
81
+
229
+void exit(int ret)
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,
87
+};
88
+
89
+static void gpio_pwr_register_types(void)
230
+{
90
+{
231
+ register int x0 __asm__("x0") = ret;
91
+ type_register_static(&gpio_pwr_info);
232
+ register int x8 __asm__("x8") = __NR_exit;
233
+
234
+ asm volatile("svc #0" : : "r"(x0), "r"(x8));
235
+ __builtin_unreachable();
236
+}
92
+}
237
+
93
+
238
+/*
94
+type_init(gpio_pwr_register_types)
239
+ * Irritatingly, the user API struct sigaction does not match the
95
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
240
+ * kernel API struct sigaction. So for simplicity, isolate the
96
index XXXXXXX..XXXXXXX 100644
241
+ * kernel ABI here, and make this act like signal.
97
--- a/hw/gpio/Kconfig
242
+ */
98
+++ b/hw/gpio/Kconfig
243
+void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *))
99
@@ -XXX,XX +XXX,XX @@ config PL061
244
+{
100
config GPIO_KEY
245
+ struct kernel_sigaction {
101
bool
246
+ void (*handler)(int, siginfo_t *, ucontext_t *);
102
247
+ unsigned long flags;
103
+config GPIO_PWR
248
+ unsigned long restorer;
104
+ bool
249
+ unsigned long mask;
250
+ } sa = { fn, SA_SIGINFO, 0, 0 };
251
+
105
+
252
+ register int x0 __asm__("x0") = sig;
106
config SIFIVE_GPIO
253
+ register void *x1 __asm__("x1") = &sa;
107
bool
254
+ register void *x2 __asm__("x2") = 0;
108
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
255
+ register int x3 __asm__("x3") = sizeof(unsigned long);
256
+ register int x8 __asm__("x8") = __NR_rt_sigaction;
257
+
258
+ asm volatile("svc #0"
259
+ : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
260
+}
261
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
262
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
263
--- a/tests/tcg/aarch64/Makefile.target
110
--- a/hw/gpio/meson.build
264
+++ b/tests/tcg/aarch64/Makefile.target
111
+++ b/hw/gpio/meson.build
265
@@ -XXX,XX +XXX,XX @@ run-pauth-%: QEMU_OPTS += -cpu max
112
@@ -XXX,XX +XXX,XX @@
266
run-plugin-pauth-%: QEMU_OPTS += -cpu max
113
softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
267
endif
114
softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
268
115
+softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
269
+# BTI Tests
116
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
270
+# bti-1 tests the elf notes, so we require special compiler support.
117
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
271
+ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_BTI),)
118
softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
272
+AARCH64_TESTS += bti-1
273
+bti-1: CFLAGS += -mbranch-protection=standard
274
+bti-1: LDFLAGS += -nostdlib
275
+endif
276
+# bti-2 tests PROT_BTI, so no special compiler support required.
277
+AARCH64_TESTS += bti-2
278
+
279
# Semihosting smoke test for linux-user
280
AARCH64_TESTS += semihosting
281
run-semihosting: semihosting
282
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
283
index XXXXXXX..XXXXXXX 100755
284
--- a/tests/tcg/configure.sh
285
+++ b/tests/tcg/configure.sh
286
@@ -XXX,XX +XXX,XX @@ for target in $target_list; do
287
-march=armv8.3-a -o $TMPE $TMPC; then
288
echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak
289
fi
290
+ if do_compiler "$target_compiler" $target_compiler_cflags \
291
+ -mbranch-protection=standard -o $TMPE $TMPC; then
292
+ echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
293
+ fi
294
;;
295
esac
296
297
--
119
--
298
2.20.1
120
2.20.1
299
121
300
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
When TBI is enabled in a given regime, 56 bits of the address
3
No functional change. Just refactor code to better
4
are significant and we need to clear out any other matching
4
support secure and normal world gpios.
5
virtual addresses with differing tags.
6
5
7
The other uses of tlb_flush_page (without mmuidx) in this file
6
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
are only used by aarch32 mode.
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
9
10
Fixes: 38d931687fa1
11
Reported-by: Jordan Frank <jordanfrank@fb.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20201016210754.818257-3-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
9
---
18
target/arm/helper.c | 46 ++++++++++++++++++++++++++++++++++++++-------
10
hw/arm/virt.c | 57 ++++++++++++++++++++++++++++++++-------------------
19
1 file changed, 39 insertions(+), 7 deletions(-)
11
1 file changed, 36 insertions(+), 21 deletions(-)
20
12
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
15
--- a/hw/arm/virt.c
24
+++ b/target/arm/helper.c
16
+++ b/hw/arm/virt.c
25
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
17
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
26
#endif
27
28
static void switch_mode(CPUARMState *env, int mode);
29
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
30
31
static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
32
{
33
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
34
}
18
}
35
}
19
}
36
20
37
+/* Return 56 if TBI is enabled, 64 otherwise. */
21
-static void create_gpio(const VirtMachineState *vms)
38
+static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
22
+static void create_gpio_keys(const VirtMachineState *vms,
39
+ uint64_t addr)
23
+ DeviceState *pl061_dev,
24
+ uint32_t phandle)
40
+{
25
+{
41
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
26
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
42
+ int tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
27
+ qdev_get_gpio_in(pl061_dev, 3));
43
+ int select = extract64(addr, 55, 1);
44
+
28
+
45
+ return (tbi >> select) & 1 ? 56 : 64;
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);
46
+}
41
+}
47
+
42
+
48
+static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
43
+static void create_gpio_devices(const VirtMachineState *vms, int gpio,
49
+{
44
+ MemoryRegion *mem)
50
+ ARMMMUIdx mmu_idx;
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);
77
-
78
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
79
- qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
80
- "label", "GPIO Key Poweroff");
81
- qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
82
- KEY_POWER);
83
- qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
84
- "gpios", phandle, 3, 0);
85
g_free(nodename);
51
+
86
+
52
+ /* Only the regime of the mmu_idx below is significant. */
87
+ /* Child gpio devices */
53
+ if (arm_is_secure_below_el3(env)) {
88
+ create_gpio_keys(vms, pl061_dev, phandle);
54
+ mmu_idx = ARMMMUIdx_SE10_0;
55
+ } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
56
+ == (HCR_E2H | HCR_TGE)) {
57
+ mmu_idx = ARMMMUIdx_E20_0;
58
+ } else {
59
+ mmu_idx = ARMMMUIdx_E10_0;
60
+ }
61
+ return tlbbits_for_regime(env, mmu_idx, addr);
62
+}
63
+
64
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
uint64_t value)
66
{
67
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
68
CPUState *cs = env_cpu(env);
69
int mask = vae1_tlbmask(env);
70
uint64_t pageaddr = sextract64(value << 12, 0, 56);
71
+ int bits = vae1_tlbbits(env, pageaddr);
72
73
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
74
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
75
}
89
}
76
90
77
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
91
static void create_virtio_devices(const VirtMachineState *vms)
78
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
92
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
79
CPUState *cs = env_cpu(env);
93
if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
80
int mask = vae1_tlbmask(env);
94
vms->acpi_dev = create_acpi_ged(vms);
81
uint64_t pageaddr = sextract64(value << 12, 0, 56);
82
+ int bits = vae1_tlbbits(env, pageaddr);
83
84
if (tlb_force_broadcast(env)) {
85
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
86
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
87
} else {
95
} else {
88
- tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
96
- create_gpio(vms);
89
+ tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
97
+ create_gpio_devices(vms, VIRT_GPIO, sysmem);
90
}
98
}
91
}
99
92
100
/* connect powerdown request */
93
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
{
95
CPUState *cs = env_cpu(env);
96
uint64_t pageaddr = sextract64(value << 12, 0, 56);
97
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
98
99
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
100
- ARMMMUIdxBit_E2);
101
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
102
+ ARMMMUIdxBit_E2, bits);
103
}
104
105
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
106
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
107
{
108
CPUState *cs = env_cpu(env);
109
uint64_t pageaddr = sextract64(value << 12, 0, 56);
110
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
111
112
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
113
- ARMMMUIdxBit_SE3);
114
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
115
+ ARMMMUIdxBit_SE3, bits);
116
}
117
118
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
119
--
101
--
120
2.20.1
102
2.20.1
121
103
122
104
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
While APEI is a generic ACPI feature (usable by X86 and ARM64), only
3
Add secure pl061 for reset/power down machine from
4
the 'virt' machine uses it, by enabling the RAS Virtualization. See
4
the secure world (Arm Trusted Firmware). Connect it
5
commit 2afa8c8519: "hw/arm/virt: Introduce a RAS machine option").
5
with gpio-pwr driver.
6
6
7
Restrict the APEI tables generation code to the single user: the virt
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
machine. If another machine wants to use it, it simply has to 'select
8
Reviewed-by: Andrew Jones <drjones@redhat.com>
9
ACPI_APEI' in its Kconfig.
9
[PMM: Added mention of the new device to the documentation]
10
11
Fixes: aa16508f1d ("ACPI: Build related register address fields via hardware error fw_cfg blob")
12
Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
Reviewed-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
Acked-by: Laszlo Ersek <lersek@redhat.com>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20201008161414.2672569-1-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
default-configs/devices/arm-softmmu.mak | 1 -
12
docs/system/arm/virt.rst | 2 ++
21
hw/arm/Kconfig | 1 +
13
include/hw/arm/virt.h | 2 ++
22
2 files changed, 1 insertion(+), 1 deletion(-)
14
hw/arm/virt.c | 56 +++++++++++++++++++++++++++++++++++++++-
15
hw/arm/Kconfig | 1 +
16
4 files changed, 60 insertions(+), 1 deletion(-)
23
17
24
diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak
18
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/default-configs/devices/arm-softmmu.mak
20
--- a/docs/system/arm/virt.rst
27
+++ b/default-configs/devices/arm-softmmu.mak
21
+++ b/docs/system/arm/virt.rst
28
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX7=y
22
@@ -XXX,XX +XXX,XX @@ The virt board supports:
29
CONFIG_FSL_IMX6UL=y
23
- Secure-World-only devices if the CPU has TrustZone:
30
CONFIG_SEMIHOSTING=y
24
31
CONFIG_ALLWINNER_H3=y
25
- A second PL011 UART
32
-CONFIG_ACPI_APEI=y
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;
48
};
49
50
struct VirtMachineState {
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/virt.c
54
+++ b/hw/arm/virt.c
55
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
56
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
57
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
58
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
59
+ [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
60
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
61
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
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
69
+
70
+static void create_secure_gpio_pwr(const VirtMachineState *vms,
71
+ DeviceState *pl061_dev,
72
+ uint32_t phandle)
73
+{
74
+ DeviceState *gpio_pwr_dev;
75
+
76
+ /* gpio-pwr */
77
+ gpio_pwr_dev = sysbus_create_simple("gpio-pwr", -1, NULL);
78
+
79
+ /* connect secure pl061 to gpio-pwr */
80
+ qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_RESET,
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");
102
+}
103
+
104
static void create_gpio_devices(const VirtMachineState *vms, int gpio,
105
MemoryRegion *mem)
106
{
107
@@ -XXX,XX +XXX,XX @@ static void create_gpio_devices(const VirtMachineState *vms, int gpio,
108
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
109
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
110
111
+ if (gpio != VIRT_GPIO) {
112
+ /* Mark as not usable by the normal world */
113
+ qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
114
+ qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
115
+ }
116
g_free(nodename);
117
118
/* Child gpio devices */
119
- create_gpio_keys(vms, pl061_dev, phandle);
120
+ if (gpio == VIRT_GPIO) {
121
+ create_gpio_keys(vms, pl061_dev, phandle);
122
+ } else {
123
+ create_secure_gpio_pwr(vms, pl061_dev, phandle);
124
+ }
125
}
126
127
static void create_virtio_devices(const VirtMachineState *vms)
128
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
129
create_gpio_devices(vms, VIRT_GPIO, sysmem);
130
}
131
132
+ if (vms->secure && !vmc->no_secure_gpio) {
133
+ create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
134
+ }
135
+
136
/* connect powerdown request */
137
vms->powerdown_notifier.notify = virt_powerdown_req;
138
qemu_register_powerdown_notifier(&vms->powerdown_notifier);
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));
144
+
145
virt_machine_6_0_options(mc);
146
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
147
+ vmc->no_secure_gpio = true;
148
}
149
DEFINE_VIRT_MACHINE(5, 2)
150
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
151
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
34
index XXXXXXX..XXXXXXX 100644
152
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/Kconfig
153
--- a/hw/arm/Kconfig
36
+++ b/hw/arm/Kconfig
154
+++ b/hw/arm/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
155
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
38
select ACPI_MEMORY_HOTPLUG
156
select PL011 # UART
39
select ACPI_HW_REDUCED
157
select PL031 # RTC
40
select ACPI_NVDIMM
158
select PL061 # GPIO
41
+ select ACPI_APEI
159
+ select GPIO_PWR
42
160
select PLATFORM_BUS
43
config CHEETAH
161
select SMBIOS
44
bool
162
select VIRTIO_MMIO
45
--
163
--
46
2.20.1
164
2.20.1
47
165
48
166
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
For BTI, we need to know if the executable is static or dynamic,
3
Fix potential overflow problem when calculating pwm_duty.
4
which means looking for PT_INTERP earlier.
4
1. Ensure p->cmr and p->cnr to be from [0,65535], according to the
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.)
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Fixes: CID 1442342
7
Message-id: 20201016184207.786698-8-richard.henderson@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
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
18
---
11
linux-user/elfload.c | 60 +++++++++++++++++++++++---------------------
19
hw/misc/npcm7xx_pwm.c | 23 +++++++++++++++++++----
12
1 file changed, 31 insertions(+), 29 deletions(-)
20
tests/qtest/npcm7xx_pwm-test.c | 4 ++--
21
2 files changed, 21 insertions(+), 6 deletions(-)
13
22
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
23
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/elfload.c
25
--- a/hw/misc/npcm7xx_pwm.c
17
+++ b/linux-user/elfload.c
26
+++ b/hw/misc/npcm7xx_pwm.c
18
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
27
@@ -XXX,XX +XXX,XX @@ REG32(NPCM7XX_PWM_PWDR3, 0x50);
19
28
#define NPCM7XX_CH_INV BIT(2)
20
mmap_lock();
29
#define NPCM7XX_CH_MOD BIT(3)
21
30
22
- /* Find the maximum size of the image and allocate an appropriate
31
+#define NPCM7XX_MAX_CMR 65535
23
- amount of memory to handle that. */
32
+#define NPCM7XX_MAX_CNR 65535
24
+ /*
25
+ * Find the maximum size of the image and allocate an appropriate
26
+ * amount of memory to handle that. Locate the interpreter, if any.
27
+ */
28
loaddr = -1, hiaddr = 0;
29
info->alignment = 0;
30
for (i = 0; i < ehdr->e_phnum; ++i) {
31
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
32
}
33
++info->nsegs;
34
info->alignment |= eppnt->p_align;
35
+ } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
36
+ g_autofree char *interp_name = NULL;
37
+
33
+
38
+ if (*pinterp_name) {
34
/* Offset of each PWM channel's prescaler in the PPR register. */
39
+ errmsg = "Multiple PT_INTERP entries";
35
static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
40
+ goto exit_errmsg;
36
/* Offset of each PWM channel's clock selector in the CSR register. */
41
+ }
37
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p)
42
+ interp_name = g_malloc(eppnt->p_filesz);
38
43
+ if (!interp_name) {
39
static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
44
+ goto exit_perror;
40
{
45
+ }
41
- uint64_t duty;
46
+
42
+ uint32_t duty;
47
+ if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
43
48
+ memcpy(interp_name, bprm_buf + eppnt->p_offset,
44
if (p->running) {
49
+ eppnt->p_filesz);
45
if (p->cnr == 0) {
50
+ } else {
46
@@ -XXX,XX +XXX,XX @@ static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
51
+ retval = pread(image_fd, interp_name, eppnt->p_filesz,
47
} else if (p->cmr >= p->cnr) {
52
+ eppnt->p_offset);
48
duty = NPCM7XX_PWM_MAX_DUTY;
53
+ if (retval != eppnt->p_filesz) {
49
} else {
54
+ goto exit_perror;
50
- duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
55
+ }
51
+ duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
56
+ }
57
+ if (interp_name[eppnt->p_filesz - 1] != 0) {
58
+ errmsg = "Invalid PT_INTERP entry";
59
+ goto exit_errmsg;
60
+ }
61
+ *pinterp_name = g_steal_pointer(&interp_name);
62
}
52
}
53
} else {
54
duty = 0;
55
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
56
case A_NPCM7XX_PWM_CNR2:
57
case A_NPCM7XX_PWM_CNR3:
58
p = &s->pwm[npcm7xx_cnr_index(offset)];
59
- p->cnr = value;
60
+ if (value > NPCM7XX_MAX_CNR) {
61
+ qemu_log_mask(LOG_GUEST_ERROR,
62
+ "%s: invalid cnr value: %u", __func__, value);
63
+ p->cnr = NPCM7XX_MAX_CNR;
64
+ } else {
65
+ p->cnr = value;
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);
63
}
104
}
64
105
65
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
106
if (inverted) {
66
if (vaddr_em > info->brk) {
67
info->brk = vaddr_em;
68
}
69
- } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
70
- g_autofree char *interp_name = NULL;
71
-
72
- if (*pinterp_name) {
73
- errmsg = "Multiple PT_INTERP entries";
74
- goto exit_errmsg;
75
- }
76
- interp_name = g_malloc(eppnt->p_filesz);
77
- if (!interp_name) {
78
- goto exit_perror;
79
- }
80
-
81
- if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
82
- memcpy(interp_name, bprm_buf + eppnt->p_offset,
83
- eppnt->p_filesz);
84
- } else {
85
- retval = pread(image_fd, interp_name, eppnt->p_filesz,
86
- eppnt->p_offset);
87
- if (retval != eppnt->p_filesz) {
88
- goto exit_perror;
89
- }
90
- }
91
- if (interp_name[eppnt->p_filesz - 1] != 0) {
92
- errmsg = "Invalid PT_INTERP entry";
93
- goto exit_errmsg;
94
- }
95
- *pinterp_name = g_steal_pointer(&interp_name);
96
#ifdef TARGET_MIPS
97
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
98
Mips_elf_abiflags_v0 abiflags;
99
--
107
--
100
2.20.1
108
2.20.1
101
109
102
110
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The time to transmit a char is expressed in nanoseconds, not in ticks.
3
cpu_get_phys_page_debug() uses 'DATA LOAD' MMU access type.
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20201014213601.205222-1-f4bug@amsat.org
6
Message-id: 20210127232822.3530782-1-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@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
hw/arm/strongarm.c | 2 +-
10
target/arm/helper.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
12
13
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/strongarm.c
15
--- a/target/arm/helper.c
16
+++ b/hw/arm/strongarm.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ struct StrongARMUARTState {
17
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
18
uint8_t rx_start;
18
19
uint8_t rx_len;
19
*attrs = (MemTxAttrs) {};
20
20
21
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
21
- ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
22
+ uint64_t char_transmit_time; /* time to transmit a char in nanoseconds */
22
+ ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
23
bool wait_break_end;
23
attrs, &prot, &page_size, &fi, &cacheattrs);
24
QEMUTimer *rx_timeout_timer;
24
25
QEMUTimer *tx_timer;
25
if (ret) {
26
--
26
--
27
2.20.1
27
2.20.1
28
28
29
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
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
Use the new generic support for NT_GNU_PROPERTY_TYPE_0.
3
Build without error on hosts without a working system(). If system()
4
is called, return -1 with ENOSYS.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
6
Message-id: 20201016184207.786698-12-richard.henderson@linaro.org
7
Message-id: 20210126012457.39046-6-j@getutm.app
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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
linux-user/elfload.c | 48 ++++++++++++++++++++++++++++++++++++++++++--
11
meson.build | 1 +
11
1 file changed, 46 insertions(+), 2 deletions(-)
12
include/qemu/osdep.h | 12 ++++++++++++
13
2 files changed, 13 insertions(+)
12
14
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
15
diff --git a/meson.build b/meson.build
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/elfload.c
17
--- a/meson.build
16
+++ b/linux-user/elfload.c
18
+++ b/meson.build
17
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
19
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
18
20
config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
19
#include "elf.h"
21
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
20
22
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
21
+/* We must delay the following stanzas until after "elf.h". */
23
+config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
22
+#if defined(TARGET_AARCH64)
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 */
23
+
46
+
24
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
47
#endif
25
+ const uint32_t *data,
26
+ struct image_info *info,
27
+ Error **errp)
28
+{
29
+ if (pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
30
+ if (pr_datasz != sizeof(uint32_t)) {
31
+ error_setg(errp, "Ill-formed GNU_PROPERTY_AARCH64_FEATURE_1_AND");
32
+ return false;
33
+ }
34
+ /* We will extract GNU_PROPERTY_AARCH64_FEATURE_1_BTI later. */
35
+ info->note_flags = *data;
36
+ }
37
+ return true;
38
+}
39
+#define ARCH_USE_GNU_PROPERTY 1
40
+
41
+#else
42
+
43
static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
44
const uint32_t *data,
45
struct image_info *info,
46
@@ -XXX,XX +XXX,XX @@ static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
47
}
48
#define ARCH_USE_GNU_PROPERTY 0
49
50
+#endif
51
+
52
struct exec
53
{
54
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
55
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
56
struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
57
struct elf_phdr *phdr;
58
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
59
- int i, retval;
60
+ int i, retval, prot_exec;
61
Error *err = NULL;
62
63
/* First of all, some simple consistency checks */
64
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
65
info->brk = 0;
66
info->elf_flags = ehdr->e_flags;
67
68
+ prot_exec = PROT_EXEC;
69
+#ifdef TARGET_AARCH64
70
+ /*
71
+ * If the BTI feature is present, this indicates that the executable
72
+ * pages of the startup binary should be mapped with PROT_BTI, so that
73
+ * branch targets are enforced.
74
+ *
75
+ * The startup binary is either the interpreter or the static executable.
76
+ * The interpreter is responsible for all pages of a dynamic executable.
77
+ *
78
+ * Elf notes are backward compatible to older cpus.
79
+ * Do not enable BTI unless it is supported.
80
+ */
81
+ if ((info->note_flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
82
+ && (pinterp_name == NULL || *pinterp_name == 0)
83
+ && cpu_isar_feature(aa64_bti, ARM_CPU(thread_cpu))) {
84
+ prot_exec |= TARGET_PROT_BTI;
85
+ }
86
+#endif
87
+
88
for (i = 0; i < ehdr->e_phnum; i++) {
89
struct elf_phdr *eppnt = phdr + i;
90
if (eppnt->p_type == PT_LOAD) {
91
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
92
elf_prot |= PROT_WRITE;
93
}
94
if (eppnt->p_flags & PF_X) {
95
- elf_prot |= PROT_EXEC;
96
+ elf_prot |= prot_exec;
97
}
98
99
vaddr = load_bias + eppnt->p_vaddr;
100
--
48
--
101
2.20.1
49
2.20.1
102
50
103
51
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
Commit 7998beb9c2e removed the ram_size initialization in the
3
Meson will find CoreFoundation, IOKit, and Cocoa as needed.
4
arm_boot_info structure, however it is used by arm_load_kernel().
5
4
6
Initialize the field to fix:
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
8
$ qemu-system-arm -M n800 -append 'console=ttyS1' \
7
Message-id: 20210126012457.39046-7-j@getutm.app
9
-kernel meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0
10
qemu-system-arm: kernel 'meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0' is too large to fit in RAM (kernel size 1964608, RAM size 0)
11
12
Noticed while running the test introduced in commit 050a82f0c5b
13
("tests/acceptance: Add a test for the N800 and N810 arm machines").
14
15
Fixes: 7998beb9c2e ("arm/nseries: use memdev for RAM")
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Thomas Huth <thuth@redhat.com>
19
Message-id: 20201019095148.1602119-1-f4bug@amsat.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
9
---
22
hw/arm/nseries.c | 1 +
10
configure | 1 -
23
1 file changed, 1 insertion(+)
11
1 file changed, 1 deletion(-)
24
12
25
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
13
diff --git a/configure b/configure
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100755
27
--- a/hw/arm/nseries.c
15
--- a/configure
28
+++ b/hw/arm/nseries.c
16
+++ b/configure
29
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
17
@@ -XXX,XX +XXX,XX @@ Darwin)
30
g_free(sz);
18
fi
31
exit(EXIT_FAILURE);
19
audio_drv_list="coreaudio try-sdl"
32
}
20
audio_possible_drivers="coreaudio sdl"
33
+ binfo->ram_size = machine->ram_size;
21
- QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
34
22
# Disable attempts to use ObjectiveC features in os/object.h since they
35
memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
23
# won't work when we're compiling with gcc as a C compiler.
36
machine->ram);
24
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
37
--
25
--
38
2.20.1
26
2.20.1
39
27
40
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
These are all of the defines required to parse
3
Add objc to the Meson cross file as well as detection of Darwin.
4
GNU_PROPERTY_AARCH64_FEATURE_1_AND, copied from binutils.
5
Other missing defines related to other GNU program headers
6
and notes are elided for now.
7
4
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
10
Message-id: 20201016184207.786698-4-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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
include/elf.h | 22 ++++++++++++++++++++++
11
configure | 4 ++++
14
1 file changed, 22 insertions(+)
12
1 file changed, 4 insertions(+)
15
13
16
diff --git a/include/elf.h b/include/elf.h
14
diff --git a/configure b/configure
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100755
18
--- a/include/elf.h
16
--- a/configure
19
+++ b/include/elf.h
17
+++ b/configure
20
@@ -XXX,XX +XXX,XX @@ typedef int64_t Elf64_Sxword;
18
@@ -XXX,XX +XXX,XX @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
21
#define PT_NOTE 4
19
echo "[binaries]" >> $cross
22
#define PT_SHLIB 5
20
echo "c = [$(meson_quote $cc)]" >> $cross
23
#define PT_PHDR 6
21
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
24
+#define PT_LOOS 0x60000000
22
+test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
25
+#define PT_HIOS 0x6fffffff
23
echo "ar = [$(meson_quote $ar)]" >> $cross
26
#define PT_LOPROC 0x70000000
24
echo "nm = [$(meson_quote $nm)]" >> $cross
27
#define PT_HIPROC 0x7fffffff
25
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
28
26
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
29
+#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
27
if test "$linux" = "yes" ; then
30
+
28
echo "system = 'linux'" >> $cross
31
#define PT_MIPS_REGINFO 0x70000000
29
fi
32
#define PT_MIPS_RTPROC 0x70000001
30
+ if test "$darwin" = "yes" ; then
33
#define PT_MIPS_OPTIONS 0x70000002
31
+ echo "system = 'darwin'" >> $cross
34
@@ -XXX,XX +XXX,XX @@ typedef struct elf64_shdr {
32
+ fi
35
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
33
case "$ARCH" in
36
#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension regs */
34
i386|x86_64)
37
35
echo "cpu_family = 'x86'" >> $cross
38
+/* Defined note types for GNU systems. */
39
+
40
+#define NT_GNU_PROPERTY_TYPE_0 5 /* Program property */
41
+
42
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */
43
+
44
+#define GNU_PROPERTY_STACK_SIZE 1
45
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
46
+
47
+#define GNU_PROPERTY_LOPROC 0xc0000000
48
+#define GNU_PROPERTY_HIPROC 0xdfffffff
49
+#define GNU_PROPERTY_LOUSER 0xe0000000
50
+#define GNU_PROPERTY_HIUSER 0xffffffff
51
+
52
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
53
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1u << 0)
54
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1u << 1)
55
+
56
/*
57
* Physical entry point into the kernel.
58
*
59
--
36
--
60
2.20.1
37
2.20.1
61
38
62
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
Fixing this now will clarify following patches.
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
4
Signed-off-by: Joelle van Dyne <j@getutm.app>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210126012457.39046-9-j@getutm.app
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20201016184207.786698-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
linux-user/elfload.c | 12 +++++++++---
8
configure | 5 ++++-
11
1 file changed, 9 insertions(+), 3 deletions(-)
9
1 file changed, 4 insertions(+), 1 deletion(-)
12
10
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
11
diff --git a/configure b/configure
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100755
15
--- a/linux-user/elfload.c
13
--- a/configure
16
+++ b/linux-user/elfload.c
14
+++ b/configure
17
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
15
@@ -XXX,XX +XXX,XX @@ if test "$cross_compile" = "yes"; then
18
abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len;
16
echo "system = 'darwin'" >> $cross
19
int elf_prot = 0;
17
fi
20
18
case "$ARCH" in
21
- if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
19
- i386|x86_64)
22
- if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
20
+ i386)
23
- if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
21
echo "cpu_family = 'x86'" >> $cross
24
+ if (eppnt->p_flags & PF_R) {
22
;;
25
+ elf_prot |= PROT_READ;
23
+ x86_64)
26
+ }
24
+ echo "cpu_family = 'x86_64'" >> $cross
27
+ if (eppnt->p_flags & PF_W) {
25
+ ;;
28
+ elf_prot |= PROT_WRITE;
26
ppc64le)
29
+ }
27
echo "cpu_family = 'ppc64'" >> $cross
30
+ if (eppnt->p_flags & PF_X) {
28
;;
31
+ elf_prot |= PROT_EXEC;
32
+ }
33
34
vaddr = load_bias + eppnt->p_vaddr;
35
vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
36
--
29
--
37
2.20.1
30
2.20.1
38
31
39
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
We already have the full ARMMMUIdx as computed from the
3
On iOS there is no CoreAudio, so we should not assume Darwin always
4
function parameter.
4
has it.
5
5
6
For the purpose of regime_has_2_ranges, we can ignore any
6
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
difference between AccType_Normal and AccType_Unpriv, which
8
would be the only difference between the passed mmu_idx
9
and arm_mmu_idx_el.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
8
Message-id: 20210126012457.39046-11-j@getutm.app
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
15
Message-id: 20201008162155.161886-2-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
target/arm/mte_helper.c | 3 +--
11
configure | 35 +++++++++++++++++++++++++++++++++--
19
1 file changed, 1 insertion(+), 2 deletions(-)
12
1 file changed, 33 insertions(+), 2 deletions(-)
20
13
21
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
14
diff --git a/configure b/configure
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100755
23
--- a/target/arm/mte_helper.c
16
--- a/configure
24
+++ b/target/arm/mte_helper.c
17
+++ b/configure
25
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
18
@@ -XXX,XX +XXX,XX @@ fdt="auto"
26
19
netmap="no"
27
case 2:
20
sdl="auto"
28
/* Tag check fail causes asynchronous flag set. */
21
sdl_image="auto"
29
- mmu_idx = arm_mmu_idx_el(env, el);
22
+coreaudio="auto"
30
- if (regime_has_2_ranges(mmu_idx)) {
23
virtiofsd="auto"
31
+ if (regime_has_2_ranges(arm_mmu_idx)) {
24
virtfs="auto"
32
select = extract64(dirty_ptr, 55, 1);
25
libudev="auto"
33
} else {
26
@@ -XXX,XX +XXX,XX @@ Darwin)
34
select = 0;
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)
35
--
82
--
36
2.20.1
83
2.20.1
37
84
38
85
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
The kernel sets btype for the signal handler as if for a call.
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.
4
8
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Message-id: 20201016184207.786698-2-richard.henderson@linaro.org
11
Message-id: 20210126012457.39046-12-j@getutm.app
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
linux-user/aarch64/signal.c | 10 ++++++++--
14
configure | 11 -----------
11
1 file changed, 8 insertions(+), 2 deletions(-)
15
1 file changed, 11 deletions(-)
12
16
13
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
17
diff --git a/configure b/configure
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100755
15
--- a/linux-user/aarch64/signal.c
19
--- a/configure
16
+++ b/linux-user/aarch64/signal.c
20
+++ b/configure
17
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
21
@@ -XXX,XX +XXX,XX @@ fi
18
+ offsetof(struct target_rt_frame_record, tramp);
22
# the correct CPU with the --cpu option.
19
}
23
case $targetos in
20
env->xregs[0] = usig;
24
Darwin)
21
- env->xregs[31] = frame_addr;
25
- # on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
22
env->xregs[29] = frame_addr + fr_ofs;
26
- # run 64-bit userspace code.
23
- env->pc = ka->_sa_handler;
27
- # If the user didn't specify a CPU explicitly and the kernel says this is
24
env->xregs[30] = return_addr;
28
- # 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
25
+ env->xregs[31] = frame_addr;
29
- if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
26
+ env->pc = ka->_sa_handler;
30
- cpu="x86_64"
27
+
31
- fi
28
+ /* Invoke the signal handler as if by indirect call. */
32
HOST_DSOSUF=".dylib"
29
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
33
;;
30
+ env->btype = 2;
34
SunOS)
31
+ }
35
@@ -XXX,XX +XXX,XX @@ OpenBSD)
32
+
36
Darwin)
33
if (info) {
37
bsd="yes"
34
tswap_siginfo(&frame->info, info);
38
darwin="yes"
35
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
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
36
--
46
--
37
2.20.1
47
2.20.1
38
48
39
49
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
The SYS_timer is not directly wired to the ARM core, but to the
3
In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
4
SoC (peripheral) interrupt controller.
4
respective entitlement. Add an entitlement template and automatically self
5
sign and apply the entitlement in the build.
5
6
6
Fixes: 0e5bbd74064 ("hw/arm/bcm2835_peripherals: Use the SYS_timer")
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201010203709.3116542-5-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
hw/arm/bcm2835_peripherals.c | 13 +++++++++++--
12
meson.build | 29 +++++++++++++++++++++++++----
14
1 file changed, 11 insertions(+), 2 deletions(-)
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
15
18
16
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
19
diff --git a/meson.build b/meson.build
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/bcm2835_peripherals.c
21
--- a/meson.build
19
+++ b/hw/arm/bcm2835_peripherals.c
22
+++ b/meson.build
20
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
23
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
21
memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
24
}]
22
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
25
endif
23
sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
26
foreach exe: execs
24
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
27
- emulators += {exe['name']:
25
- INTERRUPT_ARM_TIMER));
28
- executable(exe['name'], exe['sources'],
26
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
29
- install: true,
27
+ INTERRUPT_TIMER0));
30
+ exe_name = exe['name']
28
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 1,
31
+ exe_sign = 'CONFIG_HVF' in config_target
29
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
32
+ if exe_sign
30
+ INTERRUPT_TIMER1));
33
+ exe_name += '-unsigned'
31
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 2,
34
+ endif
32
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
35
+
33
+ INTERRUPT_TIMER2));
36
+ emulator = executable(exe_name, exe['sources'],
34
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 3,
37
+ install: not exe_sign,
35
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
38
c_args: c_args,
36
+ INTERRUPT_TIMER3));
39
dependencies: arch_deps + deps + exe['dependencies'],
37
40
objects: lib.extract_all_objects(recursive: true),
38
/* UART0 */
41
@@ -XXX,XX +XXX,XX @@ foreach target : target_dirs
39
qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
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
40
--
99
--
41
2.20.1
100
2.20.1
42
101
43
102
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
This peripheral has 1 free-running timer and 4 compare registers.
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
Only the free-running timer is implemented. Add support the
5
- ISA dependent code moved to pvpanic-isa.c
6
COMPARE registers (each register is wired to an IRQ).
6
7
7
Also, rename:
8
Reference: "BCM2835 ARM Peripherals" datasheet [*]
8
- ISA_PVPANIC_DEVICE -> PVPANIC_ISA_DEVICE.
9
chapter 12 "System Timer":
9
- TYPE_PVPANIC -> TYPE_PVPANIC_ISA.
10
10
- MemoryRegion io -> mr.
11
The System Timer peripheral provides four 32-bit timer channels
11
- pvpanic_ioport_* in pvpanic_*.
12
and a single 64-bit free running counter. Each channel has an
12
13
output compare register, which is compared against the 32 least
13
Update the build system with the new files and config structure.
14
significant bits of the free running counter values. When the
14
15
two values match, the system timer peripheral generates a signal
15
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
16
to indicate a match for the appropriate channel. The match signal
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
is then fed into the interrupt controller.
18
19
This peripheral is used since Linux 3.7, commit ee4af5696720
20
("ARM: bcm2835: add system timer").
21
22
[*] https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
23
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Luc Michel <luc@lmichel.fr>
26
Message-id: 20201010203709.3116542-4-f4bug@amsat.org
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
18
---
29
include/hw/timer/bcm2835_systmr.h | 11 +++++--
19
include/hw/misc/pvpanic.h | 23 +++++++++-
30
hw/timer/bcm2835_systmr.c | 48 ++++++++++++++++++++-----------
20
hw/misc/pvpanic-isa.c | 94 +++++++++++++++++++++++++++++++++++++++
31
hw/timer/trace-events | 6 ++--
21
hw/misc/pvpanic.c | 85 +++--------------------------------
32
3 files changed, 44 insertions(+), 21 deletions(-)
22
hw/i386/Kconfig | 2 +-
33
23
hw/misc/Kconfig | 6 ++-
34
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
24
hw/misc/meson.build | 3 +-
35
index XXXXXXX..XXXXXXX 100644
25
tests/qtest/meson.build | 2 +-
36
--- a/include/hw/timer/bcm2835_systmr.h
26
7 files changed, 130 insertions(+), 85 deletions(-)
37
+++ b/include/hw/timer/bcm2835_systmr.h
27
create mode 100644 hw/misc/pvpanic-isa.c
28
29
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/misc/pvpanic.h
32
+++ b/include/hw/misc/pvpanic.h
38
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
39
34
40
#include "hw/sysbus.h"
41
#include "hw/irq.h"
42
+#include "qemu/timer.h"
43
#include "qom/object.h"
35
#include "qom/object.h"
44
36
45
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
37
-#define TYPE_PVPANIC "pvpanic"
46
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
38
+#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
47
39
48
#define BCM2835_SYSTIMER_COUNT 4
40
#define PVPANIC_IOPORT_PROP "ioport"
49
41
50
+typedef struct {
42
+/* The bit of supported pv event, TODO: include uapi header and remove this */
51
+ unsigned id;
43
+#define PVPANIC_F_PANICKED 0
52
+ QEMUTimer timer;
44
+#define PVPANIC_F_CRASHLOADED 1
53
+ qemu_irq irq;
45
+
54
+ BCM2835SystemTimerState *state;
46
+/* The pv event value */
55
+} BCM2835SystemTimerCompare;
47
+#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
56
+
48
+#define PVPANIC_CRASHLOADED (1 << PVPANIC_F_CRASHLOADED)
57
struct BCM2835SystemTimerState {
49
+
58
/*< private >*/
50
+/*
59
SysBusDevice parent_obj;
51
+ * PVPanicState for any device type
60
52
+ */
61
/*< public >*/
53
+typedef struct PVPanicState PVPanicState;
62
MemoryRegion iomem;
54
+struct PVPanicState {
63
- qemu_irq irq;
55
+ MemoryRegion mr;
64
-
56
+ uint8_t events;
65
struct {
57
+};
66
uint32_t ctrl_status;
58
+
67
uint32_t compare[BCM2835_SYSTIMER_COUNT];
59
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size);
68
} reg;
60
+
69
+ BCM2835SystemTimerCompare tmr[BCM2835_SYSTIMER_COUNT];
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
69
new file mode 100644
70
index XXXXXXX..XXXXXXX
71
--- /dev/null
72
+++ b/hw/misc/pvpanic-isa.c
73
@@ -XXX,XX +XXX,XX @@
74
+/*
75
+ * QEMU simulated pvpanic device.
76
+ *
77
+ * Copyright Fujitsu, Corp. 2013
78
+ *
79
+ * Authors:
80
+ * Wen Congyang <wency@cn.fujitsu.com>
81
+ * Hu Tao <hutao@cn.fujitsu.com>
82
+ *
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
84
+ * See the COPYING file in the top-level directory.
85
+ *
86
+ */
87
+
88
+#include "qemu/osdep.h"
89
+#include "qemu/log.h"
90
+#include "qemu/module.h"
91
+#include "sysemu/runstate.h"
92
+
93
+#include "hw/nvram/fw_cfg.h"
94
+#include "hw/qdev-properties.h"
95
+#include "hw/misc/pvpanic.h"
96
+#include "qom/object.h"
97
+#include "hw/isa/isa.h"
98
+
99
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE)
100
+
101
+/*
102
+ * PVPanicISAState for ISA device and
103
+ * use ioport.
104
+ */
105
+struct PVPanicISAState {
106
+ ISADevice parent_obj;
107
+
108
+ uint16_t ioport;
109
+ PVPanicState pvpanic;
110
+};
111
+
112
+static void pvpanic_isa_initfn(Object *obj)
113
+{
114
+ PVPanicISAState *s = PVPANIC_ISA_DEVICE(obj);
115
+
116
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 1);
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;
129
+ }
130
+
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);
137
+}
138
+
139
+static Property pvpanic_isa_properties[] = {
140
+ DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicISAState, ioport, 0x505),
141
+ DEFINE_PROP_UINT8("events", PVPanicISAState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
142
+ DEFINE_PROP_END_OF_LIST(),
143
+};
144
+
145
+static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
146
+{
147
+ DeviceClass *dc = DEVICE_CLASS(klass);
148
+
149
+ dc->realize = pvpanic_isa_realizefn;
150
+ device_class_set_props(dc, pvpanic_isa_properties);
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
152
+}
153
+
154
+static TypeInfo pvpanic_isa_info = {
155
+ .name = TYPE_PVPANIC_ISA_DEVICE,
156
+ .parent = TYPE_ISA_DEVICE,
157
+ .instance_size = sizeof(PVPanicISAState),
158
+ .instance_init = pvpanic_isa_initfn,
159
+ .class_init = pvpanic_isa_class_init,
160
+};
161
+
162
+static void pvpanic_register_types(void)
163
+{
164
+ type_register_static(&pvpanic_isa_info);
165
+}
166
+
167
+type_init(pvpanic_register_types)
168
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/misc/pvpanic.c
171
+++ b/hw/misc/pvpanic.c
172
@@ -XXX,XX +XXX,XX @@
173
#include "hw/misc/pvpanic.h"
174
#include "qom/object.h"
175
176
-/* The bit of supported pv event, TODO: include uapi header and remove this */
177
-#define PVPANIC_F_PANICKED 0
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
},
70
};
229
};
71
230
72
#endif
231
-static void pvpanic_isa_initfn(Object *obj)
73
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
232
+void pvpanic_setup_io(PVPanicState *s, DeviceState *dev, unsigned size)
74
index XXXXXXX..XXXXXXX 100644
233
{
75
--- a/hw/timer/bcm2835_systmr.c
234
- PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
76
+++ b/hw/timer/bcm2835_systmr.c
235
-
77
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE1, 0x10)
236
- memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic", 1);
78
REG32(COMPARE2, 0x14)
237
+ memory_region_init_io(&s->mr, OBJECT(dev), &pvpanic_ops, s, "pvpanic", size);
79
REG32(COMPARE3, 0x18)
238
}
80
239
-
81
-static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
240
-static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
82
+static void bcm2835_systmr_timer_expire(void *opaque)
241
-{
83
{
242
- ISADevice *d = ISA_DEVICE(dev);
84
- bool enable = !!s->reg.ctrl_status;
243
- PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
85
+ BCM2835SystemTimerCompare *tmr = opaque;
244
- FWCfgState *fw_cfg = fw_cfg_find();
86
245
- uint16_t *pvpanic_port;
87
- trace_bcm2835_systmr_irq(enable);
246
-
88
- qemu_set_irq(s->irq, enable);
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);
89
-}
257
-}
90
-
258
-
91
-static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
259
-static Property pvpanic_isa_properties[] = {
92
- unsigned timer_index)
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)
93
-{
266
-{
94
- /* TODO fow now, since neither Linux nor U-boot use these timers. */
267
- DeviceClass *dc = DEVICE_CLASS(klass);
95
- qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
268
-
96
- timer_index);
269
- dc->realize = pvpanic_isa_realizefn;
97
+ trace_bcm2835_systmr_timer_expired(tmr->id);
270
- device_class_set_props(dc, pvpanic_isa_properties);
98
+ tmr->state->reg.ctrl_status |= 1 << tmr->id;
271
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
99
+ qemu_set_irq(tmr->irq, 1);
272
-}
100
}
273
-
101
274
-static TypeInfo pvpanic_isa_info = {
102
static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
275
- .name = TYPE_PVPANIC,
103
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
276
- .parent = TYPE_ISA_DEVICE,
104
}
277
- .instance_size = sizeof(PVPanicState),
105
278
- .instance_init = pvpanic_isa_initfn,
106
static void bcm2835_systmr_write(void *opaque, hwaddr offset,
279
- .class_init = pvpanic_isa_class_init,
107
- uint64_t value, unsigned size)
280
-};
108
+ uint64_t value64, unsigned size)
281
-
109
{
282
-static void pvpanic_register_types(void)
110
BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
283
-{
111
+ int index;
284
- type_register_static(&pvpanic_isa_info);
112
+ uint32_t value = value64;
285
-}
113
+ uint32_t triggers_delay_us;
286
-
114
+ uint64_t now;
287
-type_init(pvpanic_register_types)
115
288
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
116
trace_bcm2835_systmr_write(offset, value);
289
index XXXXXXX..XXXXXXX 100644
117
switch (offset) {
290
--- a/hw/i386/Kconfig
118
case A_CTRL_STATUS:
291
+++ b/hw/i386/Kconfig
119
s->reg.ctrl_status &= ~value; /* Ack */
292
@@ -XXX,XX +XXX,XX @@ config PC
120
- bcm2835_systmr_update_irq(s);
293
imply ISA_DEBUG
121
+ for (index = 0; index < ARRAY_SIZE(s->tmr); index++) {
294
imply PARALLEL
122
+ if (extract32(value, index, 1)) {
295
imply PCI_DEVICES
123
+ trace_bcm2835_systmr_irq_ack(index);
296
- imply PVPANIC
124
+ qemu_set_irq(s->tmr[index].irq, 0);
297
+ imply PVPANIC_ISA
125
+ }
298
imply QXL
126
+ }
299
imply SEV
127
break;
300
imply SGA
128
case A_COMPARE0 ... A_COMPARE3:
301
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
129
- s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
302
index XXXXXXX..XXXXXXX 100644
130
- bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
303
--- a/hw/misc/Kconfig
131
+ index = (offset - A_COMPARE0) >> 2;
304
+++ b/hw/misc/Kconfig
132
+ s->reg.compare[index] = value;
305
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSCTL
133
+ now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
306
config IOTKIT_SYSINFO
134
+ /* Compare lower 32-bits of the free-running counter. */
307
bool
135
+ triggers_delay_us = value - now;
308
136
+ trace_bcm2835_systmr_run(index, triggers_delay_us);
309
-config PVPANIC
137
+ timer_mod(&s->tmr[index].timer, now + triggers_delay_us);
310
+config PVPANIC_COMMON
138
break;
311
+ bool
139
case A_COUNTER_LOW:
312
+
140
case A_COUNTER_HIGH:
313
+config PVPANIC_ISA
141
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
314
bool
142
memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
315
depends on ISA_BUS
143
s, "bcm2835-sys-timer", 0x20);
316
+ select PVPANIC_COMMON
144
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
317
145
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
318
config AUX
146
+
319
bool
147
+ for (size_t i = 0; i < ARRAY_SIZE(s->tmr); i++) {
320
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
148
+ s->tmr[i].id = i;
321
index XXXXXXX..XXXXXXX 100644
149
+ s->tmr[i].state = s;
322
--- a/hw/misc/meson.build
150
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->tmr[i].irq);
323
+++ b/hw/misc/meson.build
151
+ timer_init_us(&s->tmr[i].timer, QEMU_CLOCK_VIRTUAL,
324
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
152
+ bcm2835_systmr_timer_expire, &s->tmr[i]);
325
softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
153
+ }
326
softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
154
}
327
softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
155
328
+softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c'))
156
static const VMStateDescription bcm2835_systmr_vmstate = {
329
157
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
330
# ARM devices
158
index XXXXXXX..XXXXXXX 100644
331
softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c'))
159
--- a/hw/timer/trace-events
332
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_IOTKIT_SYSINFO', if_true: files('iotkit-sysinfo.c')
160
+++ b/hw/timer/trace-events
333
softmmu_ss.add(when: 'CONFIG_ARMSSE_CPUID', if_true: files('armsse-cpuid.c'))
161
@@ -XXX,XX +XXX,XX @@ nrf51_timer_write(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size
334
softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
162
nrf51_timer_set_count(uint8_t timer_id, uint8_t counter_id, uint32_t value) "timer %u counter %u count 0x%" PRIx32
335
163
336
-softmmu_ss.add(when: 'CONFIG_PVPANIC', if_true: files('pvpanic.c'))
164
# bcm2835_systmr.c
337
+softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
165
-bcm2835_systmr_irq(bool enable) "timer irq state %u"
338
softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
166
+bcm2835_systmr_timer_expired(unsigned id) "timer #%u expired"
339
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_scu.c', 'aspeed_sdmc.c', 'aspeed_xdma.c'))
167
+bcm2835_systmr_irq_ack(unsigned id) "timer #%u acked"
340
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
168
bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
341
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
169
-bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
342
index XXXXXXX..XXXXXXX 100644
170
+bcm2835_systmr_write(uint64_t offset, uint32_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx32
343
--- a/tests/qtest/meson.build
171
+bcm2835_systmr_run(unsigned id, uint64_t delay_us) "timer #%u expiring in %"PRIu64" us"
344
+++ b/tests/qtest/meson.build
172
345
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
173
# avr_timer16.c
346
(config_host.has_key('CONFIG_LINUX') and \
174
avr_timer16_read(uint8_t addr, uint8_t value) "timer16 read addr:%u value:%u"
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'] : []) + \
175
--
354
--
176
2.20.1
355
2.20.1
177
356
178
357
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
This is generic support, with the code disabled for all targets.
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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
6
Message-id: 20201016184207.786698-11-richard.henderson@linaro.org
8
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
linux-user/qemu.h | 4 ++
13
docs/specs/pci-ids.txt | 1 +
11
linux-user/elfload.c | 157 +++++++++++++++++++++++++++++++++++++++++++
14
include/hw/misc/pvpanic.h | 1 +
12
2 files changed, 161 insertions(+)
15
include/hw/pci/pci.h | 1 +
16
hw/misc/pvpanic-pci.c | 94 +++++++++++++++++++++++++++++++++++++++
17
hw/misc/Kconfig | 6 +++
18
hw/misc/meson.build | 1 +
19
6 files changed, 104 insertions(+)
20
create mode 100644 hw/misc/pvpanic-pci.c
13
21
14
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
22
diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/qemu.h
24
--- a/docs/specs/pci-ids.txt
17
+++ b/linux-user/qemu.h
25
+++ b/docs/specs/pci-ids.txt
18
@@ -XXX,XX +XXX,XX @@ struct image_info {
26
@@ -XXX,XX +XXX,XX @@ PCI devices (other than virtio):
19
abi_ulong interpreter_loadmap_addr;
27
1b36:000d PCI xhci usb host adapter
20
abi_ulong interpreter_pt_dynamic_addr;
28
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
21
struct image_info *other_info;
29
1b36:0010 PCIe NVMe device (-device nvme)
30
+1b36:0011 PCI PVPanic device (-device pvpanic-pci)
31
32
All these devices are documented in docs/specs.
33
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
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/hw/misc/pvpanic-pci.c
63
@@ -XXX,XX +XXX,XX @@
64
+/*
65
+ * QEMU simulated PCI pvpanic device.
66
+ *
67
+ * Copyright (C) 2020 Oracle
68
+ *
69
+ * Authors:
70
+ * Mihai Carabas <mihai.carabas@oracle.com>
71
+ *
72
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
73
+ * See the COPYING file in the top-level directory.
74
+ *
75
+ */
22
+
76
+
23
+ /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
77
+#include "qemu/osdep.h"
24
+ uint32_t note_flags;
78
+#include "qemu/log.h"
79
+#include "qemu/module.h"
80
+#include "sysemu/runstate.h"
25
+
81
+
26
#ifdef TARGET_MIPS
82
+#include "hw/nvram/fw_cfg.h"
27
int fp_abi;
83
+#include "hw/qdev-properties.h"
28
int interp_fp_abi;
84
+#include "migration/vmstate.h"
29
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
85
+#include "hw/misc/pvpanic.h"
30
index XXXXXXX..XXXXXXX 100644
86
+#include "qom/object.h"
31
--- a/linux-user/elfload.c
87
+#include "hw/pci/pci.h"
32
+++ b/linux-user/elfload.c
33
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
34
35
#include "elf.h"
36
37
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
38
+ const uint32_t *data,
39
+ struct image_info *info,
40
+ Error **errp)
41
+{
42
+ g_assert_not_reached();
43
+}
44
+#define ARCH_USE_GNU_PROPERTY 0
45
+
88
+
46
struct exec
89
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE)
47
{
90
+
48
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
91
+/*
49
@@ -XXX,XX +XXX,XX @@ void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
92
+ * PVPanicPCIState for PCI device
50
"@ 0x%" PRIx64 "\n", (uint64_t)guest_base);
93
+ */
51
}
94
+typedef struct PVPanicPCIState {
52
95
+ PCIDevice dev;
53
+enum {
96
+ PVPanicState pvpanic;
54
+ /* The string "GNU\0" as a magic number. */
97
+} PVPanicPCIState;
55
+ GNU0_MAGIC = const_le32('G' | 'N' << 8 | 'U' << 16),
98
+
56
+ NOTE_DATA_SZ = 1 * KiB,
99
+static const VMStateDescription vmstate_pvpanic_pci = {
57
+ NOTE_NAME_SZ = 4,
100
+ .name = "pvpanic-pci",
58
+ ELF_GNU_PROPERTY_ALIGN = ELF_CLASS == ELFCLASS32 ? 4 : 8,
101
+ .version_id = 1,
102
+ .minimum_version_id = 1,
103
+ .fields = (VMStateField[]) {
104
+ VMSTATE_PCI_DEVICE(dev, PVPanicPCIState),
105
+ VMSTATE_END_OF_LIST()
106
+ }
59
+};
107
+};
60
+
108
+
61
+/*
109
+static void pvpanic_pci_realizefn(PCIDevice *dev, Error **errp)
62
+ * Process a single gnu_property entry.
63
+ * Return false for error.
64
+ */
65
+static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
66
+ struct image_info *info, bool have_prev_type,
67
+ uint32_t *prev_type, Error **errp)
68
+{
110
+{
69
+ uint32_t pr_type, pr_datasz, step;
111
+ PVPanicPCIState *s = PVPANIC_PCI_DEVICE(dev);
112
+ PVPanicState *ps = &s->pvpanic;
70
+
113
+
71
+ if (*off > datasz || !QEMU_IS_ALIGNED(*off, ELF_GNU_PROPERTY_ALIGN)) {
114
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), 2);
72
+ goto error_data;
73
+ }
74
+ datasz -= *off;
75
+ data += *off / sizeof(uint32_t);
76
+
115
+
77
+ if (datasz < 2 * sizeof(uint32_t)) {
116
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &ps->mr);
78
+ goto error_data;
79
+ }
80
+ pr_type = data[0];
81
+ pr_datasz = data[1];
82
+ data += 2;
83
+ datasz -= 2 * sizeof(uint32_t);
84
+ step = ROUND_UP(pr_datasz, ELF_GNU_PROPERTY_ALIGN);
85
+ if (step > datasz) {
86
+ goto error_data;
87
+ }
88
+
89
+ /* Properties are supposed to be unique and sorted on pr_type. */
90
+ if (have_prev_type && pr_type <= *prev_type) {
91
+ if (pr_type == *prev_type) {
92
+ error_setg(errp, "Duplicate property in PT_GNU_PROPERTY");
93
+ } else {
94
+ error_setg(errp, "Unsorted property in PT_GNU_PROPERTY");
95
+ }
96
+ return false;
97
+ }
98
+ *prev_type = pr_type;
99
+
100
+ if (!arch_parse_elf_property(pr_type, pr_datasz, data, info, errp)) {
101
+ return false;
102
+ }
103
+
104
+ *off += 2 * sizeof(uint32_t) + step;
105
+ return true;
106
+
107
+ error_data:
108
+ error_setg(errp, "Ill-formed property in PT_GNU_PROPERTY");
109
+ return false;
110
+}
117
+}
111
+
118
+
112
+/* Process NT_GNU_PROPERTY_TYPE_0. */
119
+static Property pvpanic_pci_properties[] = {
113
+static bool parse_elf_properties(int image_fd,
120
+ DEFINE_PROP_UINT8("events", PVPanicPCIState, pvpanic.events, PVPANIC_PANICKED | PVPANIC_CRASHLOADED),
114
+ struct image_info *info,
121
+ DEFINE_PROP_END_OF_LIST(),
115
+ const struct elf_phdr *phdr,
122
+};
116
+ char bprm_buf[BPRM_BUF_SIZE],
123
+
117
+ Error **errp)
124
+static void pvpanic_pci_class_init(ObjectClass *klass, void *data)
118
+{
125
+{
119
+ union {
126
+ DeviceClass *dc = DEVICE_CLASS(klass);
120
+ struct elf_note nhdr;
127
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
121
+ uint32_t data[NOTE_DATA_SZ / sizeof(uint32_t)];
122
+ } note;
123
+
128
+
124
+ int n, off, datasz;
129
+ device_class_set_props(dc, pvpanic_pci_properties);
125
+ bool have_prev_type;
126
+ uint32_t prev_type;
127
+
130
+
128
+ /* Unless the arch requires properties, ignore them. */
131
+ pc->realize = pvpanic_pci_realizefn;
129
+ if (!ARCH_USE_GNU_PROPERTY) {
132
+ pc->vendor_id = PCI_VENDOR_ID_REDHAT;
130
+ return true;
133
+ pc->device_id = PCI_DEVICE_ID_REDHAT_PVPANIC;
131
+ }
134
+ pc->revision = 1;
135
+ pc->class_id = PCI_CLASS_SYSTEM_OTHER;
136
+ dc->vmsd = &vmstate_pvpanic_pci;
132
+
137
+
133
+ /* If the properties are crazy large, that's too bad. */
138
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
134
+ n = phdr->p_filesz;
135
+ if (n > sizeof(note)) {
136
+ error_setg(errp, "PT_GNU_PROPERTY too large");
137
+ return false;
138
+ }
139
+ if (n < sizeof(note.nhdr)) {
140
+ error_setg(errp, "PT_GNU_PROPERTY too small");
141
+ return false;
142
+ }
143
+
144
+ if (phdr->p_offset + n <= BPRM_BUF_SIZE) {
145
+ memcpy(&note, bprm_buf + phdr->p_offset, n);
146
+ } else {
147
+ ssize_t len = pread(image_fd, &note, n, phdr->p_offset);
148
+ if (len != n) {
149
+ error_setg_errno(errp, errno, "Error reading file header");
150
+ return false;
151
+ }
152
+ }
153
+
154
+ /*
155
+ * The contents of a valid PT_GNU_PROPERTY is a sequence
156
+ * of uint32_t -- swap them all now.
157
+ */
158
+#ifdef BSWAP_NEEDED
159
+ for (int i = 0; i < n / 4; i++) {
160
+ bswap32s(note.data + i);
161
+ }
162
+#endif
163
+
164
+ /*
165
+ * Note that nhdr is 3 words, and that the "name" described by namesz
166
+ * immediately follows nhdr and is thus at the 4th word. Further, all
167
+ * of the inputs to the kernel's round_up are multiples of 4.
168
+ */
169
+ if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
170
+ note.nhdr.n_namesz != NOTE_NAME_SZ ||
171
+ note.data[3] != GNU0_MAGIC) {
172
+ error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
173
+ return false;
174
+ }
175
+ off = sizeof(note.nhdr) + NOTE_NAME_SZ;
176
+
177
+ datasz = note.nhdr.n_descsz + off;
178
+ if (datasz > n) {
179
+ error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
180
+ return false;
181
+ }
182
+
183
+ have_prev_type = false;
184
+ prev_type = 0;
185
+ while (1) {
186
+ if (off == datasz) {
187
+ return true; /* end, exit ok */
188
+ }
189
+ if (!parse_elf_property(note.data, &off, datasz, info,
190
+ have_prev_type, &prev_type, errp)) {
191
+ return false;
192
+ }
193
+ have_prev_type = true;
194
+ }
195
+}
139
+}
196
+
140
+
197
/* Load an ELF image into the address space.
141
+static TypeInfo pvpanic_pci_info = {
198
142
+ .name = TYPE_PVPANIC_PCI_DEVICE,
199
IMAGE_NAME is the filename of the image, to use in error messages.
143
+ .parent = TYPE_PCI_DEVICE,
200
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
144
+ .instance_size = sizeof(PVPanicPCIState),
201
goto exit_errmsg;
145
+ .class_init = pvpanic_pci_class_init,
202
}
146
+ .interfaces = (InterfaceInfo[]) {
203
*pinterp_name = g_steal_pointer(&interp_name);
147
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
204
+ } else if (eppnt->p_type == PT_GNU_PROPERTY) {
148
+ { }
205
+ if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
149
+ }
206
+ goto exit_errmsg;
150
+};
207
+ }
151
+
208
}
152
+static void pvpanic_register_types(void)
209
}
153
+{
210
154
+ type_register_static(&pvpanic_pci_info);
155
+}
156
+
157
+type_init(pvpanic_register_types);
158
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
159
index XXXXXXX..XXXXXXX 100644
160
--- a/hw/misc/Kconfig
161
+++ b/hw/misc/Kconfig
162
@@ -XXX,XX +XXX,XX @@ config IOTKIT_SYSINFO
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
171
+
172
config PVPANIC_ISA
173
bool
174
depends on ISA_BUS
175
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
176
index XXXXXXX..XXXXXXX 100644
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'))
211
--
187
--
212
2.20.1
188
2.20.1
213
189
214
190
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
Current documentation is not too clear on the GETPC usage.
3
Add pvpanic PCI device support details in docs/specs/pvpanic.txt.
4
In particular, when used outside the top level helper function
5
it causes unexpected behavior.
6
4
7
Signed-off-by: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
5
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
8
Message-id: 20201015095147.1691-1-e.emanuelegiuseppe@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
docs/devel/loads-stores.rst | 8 +++++++-
9
docs/specs/pvpanic.txt | 13 ++++++++++++-
13
1 file changed, 7 insertions(+), 1 deletion(-)
10
1 file changed, 12 insertions(+), 1 deletion(-)
14
11
15
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
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/docs/devel/loads-stores.rst
14
--- a/docs/specs/pvpanic.txt
18
+++ b/docs/devel/loads-stores.rst
15
+++ b/docs/specs/pvpanic.txt
19
@@ -XXX,XX +XXX,XX @@ guest CPU state in case of a guest CPU exception. This is passed
16
@@ -XXX,XX +XXX,XX @@
20
to ``cpu_restore_state()``. Therefore the value should either be 0,
17
PVPANIC DEVICE
21
to indicate that the guest CPU state is already synchronized, or
18
==============
22
the result of ``GETPC()`` from the top level ``HELPER(foo)``
19
23
-function, which is a return address into the generated code.
20
-pvpanic device is a simulated ISA device, through which a guest panic
24
+function, which is a return address into the generated code [#gpc]_.
21
+pvpanic device is a simulated device, through which a guest panic
22
event is sent to qemu, and a QMP event is generated. This allows
23
management apps (e.g. libvirt) to be notified and respond to the event.
24
25
@@ -XXX,XX +XXX,XX @@ The management app has the option of waiting for GUEST_PANICKED events,
26
and/or polling for guest-panicked RunState, to learn when the pvpanic
27
device has fired a panic event.
28
29
+The pvpanic device can be implemented as an ISA device (using IOPORT) or as a
30
+PCI device.
25
+
31
+
26
+.. [#gpc] Note that ``GETPC()`` should be used with great care: calling
32
ISA Interface
27
+ it in other functions that are *not* the top level
33
-------------
28
+ ``HELPER(foo)`` will cause unexpected behavior. Instead, the
34
29
+ value of ``GETPC()`` should be read from the helper and passed
35
@@ -XXX,XX +XXX,XX @@ bit 1: a guest panic has happened and will be handled by the guest;
30
+ if needed to the functions that the helper calls.
36
the host should record it or report it, but should not affect
31
37
the execution of the guest.
32
Function names follow the pattern:
38
39
+PCI Interface
40
+-------------
41
+
42
+The PCI interface is similar to the ISA interface except that it uses an MMIO
43
+address space provided by its BAR0, 1 byte long. Any machine with a PCI bus
44
+can enable a pvpanic device by adding '-device pvpanic-pci' to the command
45
+line.
46
+
47
ACPI Interface
48
--------------
33
49
34
--
50
--
35
2.20.1
51
2.20.1
36
52
37
53
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Mihai Carabas <mihai.carabas@oracle.com>
2
2
3
The variable holding the CTRL_STATUS register is misnamed
3
Add a test case for pvpanic-pci device. The scenario is the same as pvpanic
4
'status'. Rename it 'ctrl_status' to make it more obvious
4
ISA device, but is using the PCI bus.
5
this register is also used to control the peripheral.
6
5
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
6
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Acked-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20201010203709.3116542-3-f4bug@amsat.org
9
Signed-off-by: Mihai Carabas <mihai.carabas@oracle.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/hw/timer/bcm2835_systmr.h | 2 +-
12
tests/qtest/pvpanic-pci-test.c | 94 ++++++++++++++++++++++++++++++++++
14
hw/timer/bcm2835_systmr.c | 8 ++++----
13
tests/qtest/meson.build | 1 +
15
2 files changed, 5 insertions(+), 5 deletions(-)
14
2 files changed, 95 insertions(+)
15
create mode 100644 tests/qtest/pvpanic-pci-test.c
16
16
17
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
17
diff --git a/tests/qtest/pvpanic-pci-test.c b/tests/qtest/pvpanic-pci-test.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qtest/pvpanic-pci-test.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QTest testcase for PV Panic PCI device
25
+ *
26
+ * Copyright (C) 2020 Oracle
27
+ *
28
+ * Authors:
29
+ * Mihai Carabas <mihai.carabas@oracle.com>
30
+ *
31
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
32
+ * See the COPYING file in the top-level directory.
33
+ *
34
+ */
35
+
36
+#include "qemu/osdep.h"
37
+#include "libqos/libqtest.h"
38
+#include "qapi/qmp/qdict.h"
39
+#include "libqos/pci.h"
40
+#include "libqos/pci-pc.h"
41
+#include "hw/pci/pci_regs.h"
42
+
43
+static void test_panic_nopause(void)
44
+{
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);
72
+}
73
+
74
+static void test_panic(void)
75
+{
76
+ uint8_t val;
77
+ QDict *response, *data;
78
+ QTestState *qts;
79
+ QPCIBus *pcibus;
80
+ QPCIDevice *dev;
81
+ QPCIBar bar;
82
+
83
+ qts = qtest_init("-device pvpanic-pci,addr=04.0 -action panic=pause");
84
+ pcibus = qpci_new_pc(qts, NULL);
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);
103
+}
104
+
105
+int main(int argc, char **argv)
106
+{
107
+ int ret;
108
+
109
+ g_test_init(&argc, &argv, NULL);
110
+ qtest_add_func("/pvpanic-pci/panic", test_panic);
111
+ qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause);
112
+
113
+ ret = g_test_run();
114
+
115
+ return ret;
116
+}
117
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
18
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/timer/bcm2835_systmr.h
119
--- a/tests/qtest/meson.build
20
+++ b/include/hw/timer/bcm2835_systmr.h
120
+++ b/tests/qtest/meson.build
21
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
121
@@ -XXX,XX +XXX,XX @@ qtests_i386 = \
22
qemu_irq irq;
122
config_all_devices.has_key('CONFIG_ISA_IPMI_BT') ? ['ipmi-bt-test'] : []) + \
23
123
(config_all_devices.has_key('CONFIG_WDT_IB700') ? ['wdt_ib700-test'] : []) + \
24
struct {
124
(config_all_devices.has_key('CONFIG_PVPANIC_ISA') ? ['pvpanic-test'] : []) + \
25
- uint32_t status;
125
+ (config_all_devices.has_key('CONFIG_PVPANIC_PCI') ? ['pvpanic-pci-test'] : []) + \
26
+ uint32_t ctrl_status;
126
(config_all_devices.has_key('CONFIG_HDA') ? ['intel-hda-test'] : []) + \
27
uint32_t compare[BCM2835_SYSTIMER_COUNT];
127
(config_all_devices.has_key('CONFIG_I82801B11') ? ['i82801b11-test'] : []) + \
28
} reg;
128
(config_all_devices.has_key('CONFIG_IOH3420') ? ['ioh3420-test'] : []) + \
29
};
30
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/timer/bcm2835_systmr.c
33
+++ b/hw/timer/bcm2835_systmr.c
34
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE3, 0x18)
35
36
static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
37
{
38
- bool enable = !!s->reg.status;
39
+ bool enable = !!s->reg.ctrl_status;
40
41
trace_bcm2835_systmr_irq(enable);
42
qemu_set_irq(s->irq, enable);
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
44
45
switch (offset) {
46
case A_CTRL_STATUS:
47
- r = s->reg.status;
48
+ r = s->reg.ctrl_status;
49
break;
50
case A_COMPARE0 ... A_COMPARE3:
51
r = s->reg.compare[(offset - A_COMPARE0) >> 2];
52
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_write(void *opaque, hwaddr offset,
53
trace_bcm2835_systmr_write(offset, value);
54
switch (offset) {
55
case A_CTRL_STATUS:
56
- s->reg.status &= ~value; /* Ack */
57
+ s->reg.ctrl_status &= ~value; /* Ack */
58
bcm2835_systmr_update_irq(s);
59
break;
60
case A_COMPARE0 ... A_COMPARE3:
61
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
62
.version_id = 1,
63
.minimum_version_id = 1,
64
.fields = (VMStateField[]) {
65
- VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
66
+ VMSTATE_UINT32(reg.ctrl_status, BCM2835SystemTimerState),
67
VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
68
BCM2835_SYSTIMER_COUNT),
69
VMSTATE_END_OF_LIST()
70
--
129
--
71
2.20.1
130
2.20.1
72
131
73
132
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The ptimer API currently provides two methods for setting the period:
2
ptimer_set_period(), which takes a period in nanoseconds, and
3
ptimer_set_freq(), which takes a frequency in Hz. Neither of these
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.
2
8
3
On ARM, the Top Byte Ignore feature means that only 56 bits of
9
Add a new function ptimer_set_period_from_clock() which takes the
4
the address are significant in the virtual address. We are
10
Clock object directly to avoid the rounding issues. This includes a
5
required to give the entire 64-bit address to FAR_ELx on fault,
11
facility for the user to specify that there is a frequency divider
6
which means that we do not "clean" the top byte early in TCG.
12
between the Clock proper and the timer, as some timer devices like
13
the CMSDK APB dualtimer need this.
7
14
8
This new interface allows us to flush all 256 possible aliases
15
To avoid having to drag in clock.h from ptimer.h we add the Clock
9
for a given page, currently missed by tlb_flush_page*.
16
type to typedefs.h.
10
17
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Luc Michel <luc@lmichel.fr>
20
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20210128114145.20536-2-peter.maydell@linaro.org
14
Message-id: 20201016210754.818257-2-richard.henderson@linaro.org
23
Message-id: 20210121190622.22000-2-peter.maydell@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
24
---
17
include/exec/exec-all.h | 36 ++++++
25
include/hw/ptimer.h | 22 ++++++++++++++++++++++
18
accel/tcg/cputlb.c | 275 ++++++++++++++++++++++++++++++++++++++--
26
include/qemu/typedefs.h | 1 +
19
2 files changed, 302 insertions(+), 9 deletions(-)
27
hw/core/ptimer.c | 34 ++++++++++++++++++++++++++++++++++
28
3 files changed, 57 insertions(+)
20
29
21
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
30
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
22
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
23
--- a/include/exec/exec-all.h
32
--- a/include/hw/ptimer.h
24
+++ b/include/exec/exec-all.h
33
+++ b/include/hw/ptimer.h
25
@@ -XXX,XX +XXX,XX @@ void tlb_flush_by_mmuidx_all_cpus(CPUState *cpu, uint16_t idxmap);
34
@@ -XXX,XX +XXX,XX @@ void ptimer_transaction_commit(ptimer_state *s);
26
* depend on when the guests translation ends the TB.
27
*/
35
*/
28
void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap);
36
void ptimer_set_period(ptimer_state *s, int64_t period);
29
+
37
30
+/**
38
+/**
31
+ * tlb_flush_page_bits_by_mmuidx
39
+ * ptimer_set_period_from_clock - Set counter increment from a Clock
32
+ * @cpu: CPU whose TLB should be flushed
40
+ * @s: ptimer to configure
33
+ * @addr: virtual address of page to be flushed
41
+ * @clk: pointer to Clock object to take period from
34
+ * @idxmap: bitmap of mmu indexes to flush
42
+ * @divisor: value to scale the clock frequency down by
35
+ * @bits: number of significant bits in address
36
+ *
43
+ *
37
+ * Similar to tlb_flush_page_mask, but with a bitmap of indexes.
44
+ * If the ptimer is being driven from a Clock, this is the preferred
45
+ * way to tell the ptimer about the period, because it avoids any
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.
38
+ */
56
+ */
39
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
57
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clock,
40
+ uint16_t idxmap, unsigned bits);
58
+ unsigned int divisor);
41
+
42
+/* Similarly, with broadcast and syncing. */
43
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
44
+ uint16_t idxmap, unsigned bits);
45
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
46
+ (CPUState *cpu, target_ulong addr, uint16_t idxmap, unsigned bits);
47
+
59
+
48
/**
60
/**
49
* tlb_set_page_with_attrs:
61
* ptimer_set_freq - Set counter frequency in Hz
50
* @cpu: CPU to add this TLB entry for
62
* @s: ptimer to configure
51
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
63
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
52
uint16_t idxmap)
53
{
54
}
55
+static inline void tlb_flush_page_bits_by_mmuidx(CPUState *cpu,
56
+ target_ulong addr,
57
+ uint16_t idxmap,
58
+ unsigned bits)
59
+{
60
+}
61
+static inline void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu,
62
+ target_ulong addr,
63
+ uint16_t idxmap,
64
+ unsigned bits)
65
+{
66
+}
67
+static inline void
68
+tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, target_ulong addr,
69
+ uint16_t idxmap, unsigned bits)
70
+{
71
+}
72
#endif
73
/**
74
* probe_access:
75
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
76
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
77
--- a/accel/tcg/cputlb.c
65
--- a/include/qemu/typedefs.h
78
+++ b/accel/tcg/cputlb.c
66
+++ b/include/qemu/typedefs.h
79
@@ -XXX,XX +XXX,XX @@ void tlb_flush_all_cpus_synced(CPUState *src_cpu)
67
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDriverState BlockDriverState;
80
tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, ALL_MMUIDX_BITS);
68
typedef struct BusClass BusClass;
81
}
69
typedef struct BusState BusState;
82
70
typedef struct Chardev Chardev;
83
+static bool tlb_hit_page_mask_anyprot(CPUTLBEntry *tlb_entry,
71
+typedef struct Clock Clock;
84
+ target_ulong page, target_ulong mask)
72
typedef struct CompatProperty CompatProperty;
85
+{
73
typedef struct CoMutex CoMutex;
86
+ page &= mask;
74
typedef struct CPUAddressSpace CPUAddressSpace;
87
+ mask &= TARGET_PAGE_MASK | TLB_INVALID_MASK;
75
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
88
+
76
index XXXXXXX..XXXXXXX 100644
89
+ return (page == (tlb_entry->addr_read & mask) ||
77
--- a/hw/core/ptimer.c
90
+ page == (tlb_addr_write(tlb_entry) & mask) ||
78
+++ b/hw/core/ptimer.c
91
+ page == (tlb_entry->addr_code & mask));
79
@@ -XXX,XX +XXX,XX @@
92
+}
80
#include "sysemu/qtest.h"
93
+
81
#include "block/aio.h"
94
static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
82
#include "sysemu/cpus.h"
95
target_ulong page)
83
+#include "hw/clock.h"
96
{
84
97
- return tlb_hit_page(tlb_entry->addr_read, page) ||
85
#define DELTA_ADJUST 1
98
- tlb_hit_page(tlb_addr_write(tlb_entry), page) ||
86
#define DELTA_NO_ADJUST -1
99
- tlb_hit_page(tlb_entry->addr_code, page);
87
@@ -XXX,XX +XXX,XX @@ void ptimer_set_period(ptimer_state *s, int64_t period)
100
+ return tlb_hit_page_mask_anyprot(tlb_entry, page, -1);
101
}
102
103
/**
104
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_entry_is_empty(const CPUTLBEntry *te)
105
}
106
107
/* Called with tlb_c.lock held */
108
-static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
109
- target_ulong page)
110
+static bool tlb_flush_entry_mask_locked(CPUTLBEntry *tlb_entry,
111
+ target_ulong page,
112
+ target_ulong mask)
113
{
114
- if (tlb_hit_page_anyprot(tlb_entry, page)) {
115
+ if (tlb_hit_page_mask_anyprot(tlb_entry, page, mask)) {
116
memset(tlb_entry, -1, sizeof(*tlb_entry));
117
return true;
118
}
119
return false;
120
}
121
122
+static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
123
+ target_ulong page)
124
+{
125
+ return tlb_flush_entry_mask_locked(tlb_entry, page, -1);
126
+}
127
+
128
/* Called with tlb_c.lock held */
129
-static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
130
- target_ulong page)
131
+static void tlb_flush_vtlb_page_mask_locked(CPUArchState *env, int mmu_idx,
132
+ target_ulong page,
133
+ target_ulong mask)
134
{
135
CPUTLBDesc *d = &env_tlb(env)->d[mmu_idx];
136
int k;
137
138
assert_cpu_is_self(env_cpu(env));
139
for (k = 0; k < CPU_VTLB_SIZE; k++) {
140
- if (tlb_flush_entry_locked(&d->vtable[k], page)) {
141
+ if (tlb_flush_entry_mask_locked(&d->vtable[k], page, mask)) {
142
tlb_n_used_entries_dec(env, mmu_idx);
143
}
144
}
88
}
145
}
89
}
146
90
147
+static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
91
+/* Set counter increment interval from a Clock */
148
+ target_ulong page)
92
+void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clk,
93
+ unsigned int divisor)
149
+{
94
+{
150
+ tlb_flush_vtlb_page_mask_locked(env, mmu_idx, page, -1);
95
+ /*
151
+}
96
+ * The raw clock period is a 64-bit value in units of 2^-32 ns;
97
+ * put another way it's a 32.32 fixed-point ns value. Our internal
98
+ * representation of the period is 64.32 fixed point ns, so
99
+ * the conversion is simple.
100
+ */
101
+ uint64_t raw_period = clock_get(clk);
102
+ uint64_t period_frac;
152
+
103
+
153
static void tlb_flush_page_locked(CPUArchState *env, int midx,
104
+ assert(s->in_transaction);
154
target_ulong page)
105
+ s->delta = ptimer_get_count(s);
155
{
106
+ s->period = extract64(raw_period, 32, 32);
156
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr)
107
+ period_frac = extract64(raw_period, 0, 32);
157
tlb_flush_page_by_mmuidx_all_cpus_synced(src, addr, ALL_MMUIDX_BITS);
108
+ /*
158
}
109
+ * divisor specifies a possible frequency divisor between the
159
110
+ * clock and the timer, so it is a multiplier on the period.
160
+static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
111
+ * We do the multiply after splitting the raw period out into
161
+ target_ulong page, unsigned bits)
112
+ * period and frac to avoid having to do a 32*64->96 multiply.
162
+{
113
+ */
163
+ CPUTLBDesc *d = &env_tlb(env)->d[midx];
114
+ s->period *= divisor;
164
+ CPUTLBDescFast *f = &env_tlb(env)->f[midx];
115
+ period_frac *= divisor;
165
+ target_ulong mask = MAKE_64BIT_MASK(0, bits);
116
+ s->period += extract64(period_frac, 32, 32);
117
+ s->period_frac = (uint32_t)period_frac;
166
+
118
+
167
+ /*
119
+ if (s->enabled) {
168
+ * If @bits is smaller than the tlb size, there may be multiple entries
120
+ s->need_reload = true;
169
+ * within the TLB; otherwise all addresses that match under @mask hit
170
+ * the same TLB entry.
171
+ *
172
+ * TODO: Perhaps allow bits to be a few bits less than the size.
173
+ * For now, just flush the entire TLB.
174
+ */
175
+ if (mask < f->mask) {
176
+ tlb_debug("forcing full flush midx %d ("
177
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
178
+ midx, page, mask);
179
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
180
+ return;
181
+ }
182
+
183
+ /* Check if we need to flush due to large pages. */
184
+ if ((page & d->large_page_mask) == d->large_page_addr) {
185
+ tlb_debug("forcing full flush midx %d ("
186
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
187
+ midx, d->large_page_addr, d->large_page_mask);
188
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
189
+ return;
190
+ }
191
+
192
+ if (tlb_flush_entry_mask_locked(tlb_entry(env, midx, page), page, mask)) {
193
+ tlb_n_used_entries_dec(env, midx);
194
+ }
195
+ tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
196
+}
197
+
198
+typedef struct {
199
+ target_ulong addr;
200
+ uint16_t idxmap;
201
+ uint16_t bits;
202
+} TLBFlushPageBitsByMMUIdxData;
203
+
204
+static void
205
+tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
206
+ TLBFlushPageBitsByMMUIdxData d)
207
+{
208
+ CPUArchState *env = cpu->env_ptr;
209
+ int mmu_idx;
210
+
211
+ assert_cpu_is_self(cpu);
212
+
213
+ tlb_debug("page addr:" TARGET_FMT_lx "/%u mmu_map:0x%x\n",
214
+ d.addr, d.bits, d.idxmap);
215
+
216
+ qemu_spin_lock(&env_tlb(env)->c.lock);
217
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
218
+ if ((d.idxmap >> mmu_idx) & 1) {
219
+ tlb_flush_page_bits_locked(env, mmu_idx, d.addr, d.bits);
220
+ }
221
+ }
222
+ qemu_spin_unlock(&env_tlb(env)->c.lock);
223
+
224
+ tb_flush_jmp_cache(cpu, d.addr);
225
+}
226
+
227
+static bool encode_pbm_to_runon(run_on_cpu_data *out,
228
+ TLBFlushPageBitsByMMUIdxData d)
229
+{
230
+ /* We need 6 bits to hold to hold @bits up to 63. */
231
+ if (d.idxmap <= MAKE_64BIT_MASK(0, TARGET_PAGE_BITS - 6)) {
232
+ *out = RUN_ON_CPU_TARGET_PTR(d.addr | (d.idxmap << 6) | d.bits);
233
+ return true;
234
+ }
235
+ return false;
236
+}
237
+
238
+static TLBFlushPageBitsByMMUIdxData
239
+decode_runon_to_pbm(run_on_cpu_data data)
240
+{
241
+ target_ulong addr_map_bits = (target_ulong) data.target_ptr;
242
+ return (TLBFlushPageBitsByMMUIdxData){
243
+ .addr = addr_map_bits & TARGET_PAGE_MASK,
244
+ .idxmap = (addr_map_bits & ~TARGET_PAGE_MASK) >> 6,
245
+ .bits = addr_map_bits & 0x3f
246
+ };
247
+}
248
+
249
+static void tlb_flush_page_bits_by_mmuidx_async_1(CPUState *cpu,
250
+ run_on_cpu_data runon)
251
+{
252
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, decode_runon_to_pbm(runon));
253
+}
254
+
255
+static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
256
+ run_on_cpu_data data)
257
+{
258
+ TLBFlushPageBitsByMMUIdxData *d = data.host_ptr;
259
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
260
+ g_free(d);
261
+}
262
+
263
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
264
+ uint16_t idxmap, unsigned bits)
265
+{
266
+ TLBFlushPageBitsByMMUIdxData d;
267
+ run_on_cpu_data runon;
268
+
269
+ /* If all bits are significant, this devolves to tlb_flush_page. */
270
+ if (bits >= TARGET_LONG_BITS) {
271
+ tlb_flush_page_by_mmuidx(cpu, addr, idxmap);
272
+ return;
273
+ }
274
+ /* If no page bits are significant, this devolves to tlb_flush. */
275
+ if (bits < TARGET_PAGE_BITS) {
276
+ tlb_flush_by_mmuidx(cpu, idxmap);
277
+ return;
278
+ }
279
+
280
+ /* This should already be page aligned */
281
+ d.addr = addr & TARGET_PAGE_MASK;
282
+ d.idxmap = idxmap;
283
+ d.bits = bits;
284
+
285
+ if (qemu_cpu_is_self(cpu)) {
286
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
287
+ } else if (encode_pbm_to_runon(&runon, d)) {
288
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
289
+ } else {
290
+ TLBFlushPageBitsByMMUIdxData *p
291
+ = g_new(TLBFlushPageBitsByMMUIdxData, 1);
292
+
293
+ /* Otherwise allocate a structure, freed by the worker. */
294
+ *p = d;
295
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
296
+ RUN_ON_CPU_HOST_PTR(p));
297
+ }
121
+ }
298
+}
122
+}
299
+
123
+
300
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
124
/* Set counter frequency in Hz. */
301
+ target_ulong addr,
125
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
302
+ uint16_t idxmap,
126
{
303
+ unsigned bits)
304
+{
305
+ TLBFlushPageBitsByMMUIdxData d;
306
+ run_on_cpu_data runon;
307
+
308
+ /* If all bits are significant, this devolves to tlb_flush_page. */
309
+ if (bits >= TARGET_LONG_BITS) {
310
+ tlb_flush_page_by_mmuidx_all_cpus(src_cpu, addr, idxmap);
311
+ return;
312
+ }
313
+ /* If no page bits are significant, this devolves to tlb_flush. */
314
+ if (bits < TARGET_PAGE_BITS) {
315
+ tlb_flush_by_mmuidx_all_cpus(src_cpu, idxmap);
316
+ return;
317
+ }
318
+
319
+ /* This should already be page aligned */
320
+ d.addr = addr & TARGET_PAGE_MASK;
321
+ d.idxmap = idxmap;
322
+ d.bits = bits;
323
+
324
+ if (encode_pbm_to_runon(&runon, d)) {
325
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
326
+ } else {
327
+ CPUState *dst_cpu;
328
+ TLBFlushPageBitsByMMUIdxData *p;
329
+
330
+ /* Allocate a separate data block for each destination cpu. */
331
+ CPU_FOREACH(dst_cpu) {
332
+ if (dst_cpu != src_cpu) {
333
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
334
+ *p = d;
335
+ async_run_on_cpu(dst_cpu,
336
+ tlb_flush_page_bits_by_mmuidx_async_2,
337
+ RUN_ON_CPU_HOST_PTR(p));
338
+ }
339
+ }
340
+ }
341
+
342
+ tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
343
+}
344
+
345
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
346
+ target_ulong addr,
347
+ uint16_t idxmap,
348
+ unsigned bits)
349
+{
350
+ TLBFlushPageBitsByMMUIdxData d;
351
+ run_on_cpu_data runon;
352
+
353
+ /* If all bits are significant, this devolves to tlb_flush_page. */
354
+ if (bits >= TARGET_LONG_BITS) {
355
+ tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap);
356
+ return;
357
+ }
358
+ /* If no page bits are significant, this devolves to tlb_flush. */
359
+ if (bits < TARGET_PAGE_BITS) {
360
+ tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap);
361
+ return;
362
+ }
363
+
364
+ /* This should already be page aligned */
365
+ d.addr = addr & TARGET_PAGE_MASK;
366
+ d.idxmap = idxmap;
367
+ d.bits = bits;
368
+
369
+ if (encode_pbm_to_runon(&runon, d)) {
370
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
371
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1,
372
+ runon);
373
+ } else {
374
+ CPUState *dst_cpu;
375
+ TLBFlushPageBitsByMMUIdxData *p;
376
+
377
+ /* Allocate a separate data block for each destination cpu. */
378
+ CPU_FOREACH(dst_cpu) {
379
+ if (dst_cpu != src_cpu) {
380
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
381
+ *p = d;
382
+ async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
383
+ RUN_ON_CPU_HOST_PTR(p));
384
+ }
385
+ }
386
+
387
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
388
+ *p = d;
389
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
390
+ RUN_ON_CPU_HOST_PTR(p));
391
+ }
392
+}
393
+
394
/* update the TLBs so that writes to code in the virtual page 'addr'
395
can be detected */
396
void tlb_protect_code(ram_addr_t ram_addr)
397
--
127
--
398
2.20.1
128
2.20.1
399
129
400
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
New patch
1
Add a simple test of the CMSDK APB timer, since we're about to do
2
some refactoring of how it is clocked.
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-4-peter.maydell@linaro.org
9
Message-id: 20210121190622.22000-4-peter.maydell@linaro.org
10
---
11
tests/qtest/cmsdk-apb-timer-test.c | 75 ++++++++++++++++++++++++++++++
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
16
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
99
index XXXXXXX..XXXXXXX 100644
100
--- a/MAINTAINERS
101
+++ b/MAINTAINERS
102
@@ -XXX,XX +XXX,XX @@ F: include/hw/rtc/pl031.h
103
F: include/hw/arm/primecell.h
104
F: hw/timer/cmsdk-apb-timer.c
105
F: include/hw/timer/cmsdk-apb-timer.h
106
+F: tests/qtest/cmsdk-apb-timer-test.c
107
F: hw/timer/cmsdk-apb-dualtimer.c
108
F: include/hw/timer/cmsdk-apb-dualtimer.h
109
F: hw/char/cmsdk-apb-uart.c
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',
122
--
123
2.20.1
124
125
diff view generated by jsdifflib
New patch
1
Add a simple test of the CMSDK watchdog, since we're about to do some
2
refactoring of how it is clocked.
1
3
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
17
18
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QTest testcase for the CMSDK APB watchdog device
26
+ *
27
+ * Copyright (c) 2021 Linaro Limited
28
+ *
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.
33
+ *
34
+ * This program is distributed in the hope that it will be useful, but WITHOUT
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.
38
+ */
39
+
40
+#include "qemu/osdep.h"
41
+#include "libqtest-single.h"
42
+
43
+/*
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
48
+
49
+#define WDOGLOAD 0
50
+#define WDOGVALUE 4
51
+#define WDOGCONTROL 8
52
+#define WDOGINTCLR 0xc
53
+#define WDOGRIS 0x10
54
+#define WDOGMIS 0x14
55
+#define WDOGLOCK 0xc00
56
+
57
+static void test_watchdog(void)
58
+{
59
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
60
+
61
+ writel(WDOG_BASE + WDOGCONTROL, 1);
62
+ writel(WDOG_BASE + WDOGLOAD, 1000);
63
+
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);
85
+}
86
+
87
+int main(int argc, char **argv)
88
+{
89
+ int r;
90
+
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;
102
+}
103
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/char/cmsdk-apb-uart.c
108
F: include/hw/char/cmsdk-apb-uart.h
109
F: hw/watchdog/cmsdk-apb-watchdog.c
110
F: include/hw/watchdog/cmsdk-apb-watchdog.h
111
+F: tests/qtest/cmsdk-apb-watchdog-test.c
112
F: hw/misc/tz-ppc.c
113
F: include/hw/misc/tz-ppc.h
114
F: hw/misc/tz-mpc.c
115
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
116
index XXXXXXX..XXXXXXX 100644
117
--- a/tests/qtest/meson.build
118
+++ b/tests/qtest/meson.build
119
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
120
'npcm7xx_watchdog_timer-test']
121
qtests_arm = \
122
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
123
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
124
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
125
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
126
['arm-cpu-features',
127
--
128
2.20.1
129
130
diff view generated by jsdifflib
1
From: Havard Skinnemoen <hskinnemoen@google.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
This test exercises the various modes of the npcm7xx timer. In
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
particular, it triggers the bug found by the fuzzer, as reported here:
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
https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg02992.html
17
diff --git a/tests/qtest/cmsdk-apb-dualtimer-test.c b/tests/qtest/cmsdk-apb-dualtimer-test.c
7
8
It also found several other bugs, especially related to interrupt
9
handling.
10
11
The test exercises all the timers in all the timer modules, which
12
expands to 180 test cases in total.
13
14
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
15
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
16
Message-id: 20201008232154.94221-2-hskinnemoen@google.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
tests/qtest/npcm7xx_timer-test.c | 562 +++++++++++++++++++++++++++++++
20
tests/qtest/meson.build | 1 +
21
2 files changed, 563 insertions(+)
22
create mode 100644 tests/qtest/npcm7xx_timer-test.c
23
24
diff --git a/tests/qtest/npcm7xx_timer-test.c b/tests/qtest/npcm7xx_timer-test.c
25
new file mode 100644
18
new file mode 100644
26
index XXXXXXX..XXXXXXX
19
index XXXXXXX..XXXXXXX
27
--- /dev/null
20
--- /dev/null
28
+++ b/tests/qtest/npcm7xx_timer-test.c
21
+++ b/tests/qtest/cmsdk-apb-dualtimer-test.c
29
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
30
+/*
23
+/*
31
+ * QTest testcase for the Nuvoton NPCM7xx Timer
24
+ * QTest testcase for the CMSDK APB dualtimer device
32
+ *
25
+ *
33
+ * Copyright 2020 Google LLC
26
+ * Copyright (c) 2021 Linaro Limited
34
+ *
27
+ *
35
+ * This program is free software; you can redistribute it and/or modify it
28
+ * This program is free software; you can redistribute it and/or modify it
36
+ * under the terms of the GNU General Public License as published by the
29
+ * under the terms of the GNU General Public License as published by the
37
+ * Free Software Foundation; either version 2 of the License, or
30
+ * Free Software Foundation; either version 2 of the License, or
38
+ * (at your option) any later version.
31
+ * (at your option) any later version.
...
...
42
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43
+ * for more details.
36
+ * for more details.
44
+ */
37
+ */
45
+
38
+
46
+#include "qemu/osdep.h"
39
+#include "qemu/osdep.h"
47
+#include "qemu/timer.h"
48
+#include "libqtest-single.h"
40
+#include "libqtest-single.h"
49
+
41
+
50
+#define TIM_REF_HZ (25000000)
42
+/* IoTKit/ARMSSE dualtimer; driven at 25MHz in mps2-an385, so 40ns per tick */
43
+#define TIMER_BASE 0x40002000
51
+
44
+
52
+/* Bits in TCSRx */
45
+#define TIMER1LOAD 0
53
+#define CEN BIT(30)
46
+#define TIMER1VALUE 4
54
+#define IE BIT(29)
47
+#define TIMER1CONTROL 8
55
+#define MODE_ONESHOT (0 << 27)
48
+#define TIMER1INTCLR 0xc
56
+#define MODE_PERIODIC (1 << 27)
49
+#define TIMER1RIS 0x10
57
+#define CRST BIT(26)
50
+#define TIMER1MIS 0x14
58
+#define CACT BIT(25)
51
+#define TIMER1BGLOAD 0x18
59
+#define PRESCALE(x) (x)
60
+
52
+
61
+/* Registers shared between all timers in a module. */
53
+#define TIMER2LOAD 0x20
62
+#define TISR 0x18
54
+#define TIMER2VALUE 0x24
63
+#define WTCR 0x1c
55
+#define TIMER2CONTROL 0x28
64
+# define WTCLK(x) ((x) << 10)
56
+#define TIMER2INTCLR 0x2c
57
+#define TIMER2RIS 0x30
58
+#define TIMER2MIS 0x34
59
+#define TIMER2BGLOAD 0x38
65
+
60
+
66
+/* Power-on default; used to re-initialize timers before each test. */
61
+#define CTRL_ENABLE (1 << 7)
67
+#define TCSR_DEFAULT PRESCALE(5)
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)
68
+
69
+
69
+/* Register offsets for a timer within a timer block. */
70
+static void test_dualtimer(void)
70
+typedef struct Timer {
71
+{
71
+ unsigned int tcsr_offset;
72
+ g_assert_true(readl(TIMER_BASE + TIMER1RIS) == 0);
72
+ unsigned int ticr_offset;
73
+ unsigned int tdr_offset;
74
+} Timer;
75
+
73
+
76
+/* A timer block containing 5 timers. */
74
+ /* Start timer: will fire after 40000 ns */
77
+typedef struct TimerBlock {
75
+ writel(TIMER_BASE + TIMER1LOAD, 1000);
78
+ int irq_base;
76
+ /* enable in free-running, wrapping, interrupt mode */
79
+ uint64_t base_addr;
77
+ writel(TIMER_BASE + TIMER1CONTROL, CTRL_ENABLE | CTRL_INTEN);
80
+} TimerBlock;
81
+
78
+
82
+/* Testdata for testing a particular timer within a timer block. */
79
+ /* Step to just past the 500th tick and check VALUE */
83
+typedef struct TestData {
80
+ clock_step(500 * 40 + 1);
84
+ const TimerBlock *tim;
81
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
85
+ const Timer *timer;
82
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 500);
86
+} TestData;
87
+
83
+
88
+const TimerBlock timer_block[] = {
84
+ /* Just past the 1000th tick: timer should have fired */
89
+ {
85
+ clock_step(500 * 40);
90
+ .irq_base = 32,
86
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 1);
91
+ .base_addr = 0xf0008000,
87
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0);
92
+ },
93
+ {
94
+ .irq_base = 37,
95
+ .base_addr = 0xf0009000,
96
+ },
97
+ {
98
+ .irq_base = 42,
99
+ .base_addr = 0xf000a000,
100
+ },
101
+};
102
+
88
+
103
+const Timer timer[] = {
89
+ /*
104
+ {
90
+ * We are in free-running wrapping 16-bit mode, so on the following
105
+ .tcsr_offset = 0x00,
91
+ * tick VALUE should have wrapped round to 0xffff.
106
+ .ticr_offset = 0x08,
92
+ */
107
+ .tdr_offset = 0x10,
93
+ clock_step(40);
108
+ }, {
94
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1VALUE), ==, 0xffff);
109
+ .tcsr_offset = 0x04,
110
+ .ticr_offset = 0x0c,
111
+ .tdr_offset = 0x14,
112
+ }, {
113
+ .tcsr_offset = 0x20,
114
+ .ticr_offset = 0x28,
115
+ .tdr_offset = 0x30,
116
+ }, {
117
+ .tcsr_offset = 0x24,
118
+ .ticr_offset = 0x2c,
119
+ .tdr_offset = 0x34,
120
+ }, {
121
+ .tcsr_offset = 0x40,
122
+ .ticr_offset = 0x48,
123
+ .tdr_offset = 0x50,
124
+ },
125
+};
126
+
95
+
127
+/* Returns the index of the timer block. */
96
+ /* Check that any write to INTCLR clears interrupt */
128
+static int tim_index(const TimerBlock *tim)
97
+ writel(TIMER_BASE + TIMER1INTCLR, 1);
129
+{
98
+ g_assert_cmpuint(readl(TIMER_BASE + TIMER1RIS), ==, 0);
130
+ ptrdiff_t diff = tim - timer_block;
131
+
99
+
132
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer_block));
100
+ /* Turn off the timer */
133
+
101
+ writel(TIMER_BASE + TIMER1CONTROL, 0);
134
+ return diff;
135
+}
102
+}
136
+
103
+
137
+/* Returns the index of a timer within a timer block. */
104
+static void test_prescale(void)
138
+static int timer_index(const Timer *t)
139
+{
105
+{
140
+ ptrdiff_t diff = t - timer;
106
+ g_assert_true(readl(TIMER_BASE + TIMER2RIS) == 0);
141
+
107
+
142
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer));
108
+ /* Start timer: will fire after 40 * 256 * 1000 == 1024000 ns */
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);
143
+
113
+
144
+ return diff;
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);
145
+}
134
+}
146
+
147
+/* Returns the irq line for a given timer. */
148
+static int tim_timer_irq(const TestData *td)
149
+{
150
+ return td->tim->irq_base + timer_index(td->timer);
151
+}
152
+
153
+/* Register read/write accessors. */
154
+
155
+static void tim_write(const TestData *td,
156
+ unsigned int offset, uint32_t value)
157
+{
158
+ writel(td->tim->base_addr + offset, value);
159
+}
160
+
161
+static uint32_t tim_read(const TestData *td, unsigned int offset)
162
+{
163
+ return readl(td->tim->base_addr + offset);
164
+}
165
+
166
+static void tim_write_tcsr(const TestData *td, uint32_t value)
167
+{
168
+ tim_write(td, td->timer->tcsr_offset, value);
169
+}
170
+
171
+static uint32_t tim_read_tcsr(const TestData *td)
172
+{
173
+ return tim_read(td, td->timer->tcsr_offset);
174
+}
175
+
176
+static void tim_write_ticr(const TestData *td, uint32_t value)
177
+{
178
+ tim_write(td, td->timer->ticr_offset, value);
179
+}
180
+
181
+static uint32_t tim_read_ticr(const TestData *td)
182
+{
183
+ return tim_read(td, td->timer->ticr_offset);
184
+}
185
+
186
+static uint32_t tim_read_tdr(const TestData *td)
187
+{
188
+ return tim_read(td, td->timer->tdr_offset);
189
+}
190
+
191
+/* Returns the number of nanoseconds to count the given number of cycles. */
192
+static int64_t tim_calculate_step(uint32_t count, uint32_t prescale)
193
+{
194
+ return (1000000000LL / TIM_REF_HZ) * count * (prescale + 1);
195
+}
196
+
197
+/* Returns a bitmask corresponding to the timer under test. */
198
+static uint32_t tim_timer_bit(const TestData *td)
199
+{
200
+ return BIT(timer_index(td->timer));
201
+}
202
+
203
+/* Resets all timers to power-on defaults. */
204
+static void tim_reset(const TestData *td)
205
+{
206
+ int i, j;
207
+
208
+ /* Reset all the timers, in case a previous test left a timer running. */
209
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
210
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
211
+ writel(timer_block[i].base_addr + timer[j].tcsr_offset,
212
+ CRST | TCSR_DEFAULT);
213
+ }
214
+ writel(timer_block[i].base_addr + TISR, -1);
215
+ }
216
+}
217
+
218
+/* Verifies the reset state of a timer. */
219
+static void test_reset(gconstpointer test_data)
220
+{
221
+ const TestData *td = test_data;
222
+
223
+ tim_reset(td);
224
+
225
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
226
+ g_assert_cmphex(tim_read_ticr(td), ==, 0);
227
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
228
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
229
+ g_assert_cmphex(tim_read(td, WTCR), ==, WTCLK(1));
230
+}
231
+
232
+/* Verifies that CRST wins if both CEN and CRST are set. */
233
+static void test_reset_overrides_enable(gconstpointer test_data)
234
+{
235
+ const TestData *td = test_data;
236
+
237
+ tim_reset(td);
238
+
239
+ /* CRST should force CEN to 0 */
240
+ tim_write_tcsr(td, CEN | CRST | TCSR_DEFAULT);
241
+
242
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
243
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
244
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
245
+}
246
+
247
+/* Verifies the behavior when CEN is set and then cleared. */
248
+static void test_oneshot_enable_then_disable(gconstpointer test_data)
249
+{
250
+ const TestData *td = test_data;
251
+
252
+ tim_reset(td);
253
+
254
+ /* Enable the timer with zero initial count, then disable it again. */
255
+ tim_write_tcsr(td, CEN | TCSR_DEFAULT);
256
+ tim_write_tcsr(td, TCSR_DEFAULT);
257
+
258
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
259
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
260
+ /* Timer interrupt flag should be set, but interrupts are not enabled. */
261
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
262
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
263
+}
264
+
265
+/* Verifies that a one-shot timer fires when expected with prescaler 5. */
266
+static void test_oneshot_ps5(gconstpointer test_data)
267
+{
268
+ const TestData *td = test_data;
269
+ unsigned int count = 256;
270
+ unsigned int ps = 5;
271
+
272
+ tim_reset(td);
273
+
274
+ tim_write_ticr(td, count);
275
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
276
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
277
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
278
+
279
+ clock_step(tim_calculate_step(count, ps) - 1);
280
+
281
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
282
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
283
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
284
+
285
+ clock_step(1);
286
+
287
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
288
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
289
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
290
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
291
+
292
+ /* Clear the interrupt flag. */
293
+ tim_write(td, TISR, tim_timer_bit(td));
294
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
295
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
296
+
297
+ /* Verify that this isn't a periodic timer. */
298
+ clock_step(2 * tim_calculate_step(count, ps));
299
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
300
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
301
+}
302
+
303
+/* Verifies that a one-shot timer fires when expected with prescaler 0. */
304
+static void test_oneshot_ps0(gconstpointer test_data)
305
+{
306
+ const TestData *td = test_data;
307
+ unsigned int count = 1;
308
+ unsigned int ps = 0;
309
+
310
+ tim_reset(td);
311
+
312
+ tim_write_ticr(td, count);
313
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
314
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
315
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
316
+
317
+ clock_step(tim_calculate_step(count, ps) - 1);
318
+
319
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
320
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
321
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
322
+
323
+ clock_step(1);
324
+
325
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
326
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
327
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
328
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
329
+}
330
+
331
+/* Verifies that a one-shot timer fires when expected with highest prescaler. */
332
+static void test_oneshot_ps255(gconstpointer test_data)
333
+{
334
+ const TestData *td = test_data;
335
+ unsigned int count = (1U << 24) - 1;
336
+ unsigned int ps = 255;
337
+
338
+ tim_reset(td);
339
+
340
+ tim_write_ticr(td, count);
341
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
342
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
343
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
344
+
345
+ clock_step(tim_calculate_step(count, ps) - 1);
346
+
347
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
348
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
349
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
350
+
351
+ clock_step(1);
352
+
353
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
354
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
355
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
356
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
357
+}
358
+
359
+/* Verifies that a oneshot timer fires an interrupt when expected. */
360
+static void test_oneshot_interrupt(gconstpointer test_data)
361
+{
362
+ const TestData *td = test_data;
363
+ unsigned int count = 256;
364
+ unsigned int ps = 7;
365
+
366
+ tim_reset(td);
367
+
368
+ tim_write_ticr(td, count);
369
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
370
+
371
+ clock_step_next();
372
+
373
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
374
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
375
+}
376
+
377
+/*
378
+ * Verifies that the timer can be paused and later resumed, and it still fires
379
+ * at the right moment.
380
+ */
381
+static void test_pause_resume(gconstpointer test_data)
382
+{
383
+ const TestData *td = test_data;
384
+ unsigned int count = 256;
385
+ unsigned int ps = 1;
386
+
387
+ tim_reset(td);
388
+
389
+ tim_write_ticr(td, count);
390
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
391
+
392
+ /* Pause the timer halfway to expiration. */
393
+ clock_step(tim_calculate_step(count / 2, ps));
394
+ tim_write_tcsr(td, IE | MODE_ONESHOT | PRESCALE(ps));
395
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
396
+
397
+ /* Counter should not advance during the following step. */
398
+ clock_step(2 * tim_calculate_step(count, ps));
399
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
400
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
401
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
402
+
403
+ /* Resume the timer and run _almost_ to expiration. */
404
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
405
+ clock_step(tim_calculate_step(count / 2, ps) - 1);
406
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
407
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
408
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
409
+
410
+ /* Now, run the rest of the way and verify that the interrupt fires. */
411
+ clock_step(1);
412
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
413
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
414
+}
415
+
416
+/* Verifies that the prescaler can be changed while the timer is runnin. */
417
+static void test_prescaler_change(gconstpointer test_data)
418
+{
419
+ const TestData *td = test_data;
420
+ unsigned int count = 256;
421
+ unsigned int ps = 5;
422
+
423
+ tim_reset(td);
424
+
425
+ tim_write_ticr(td, count);
426
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
427
+
428
+ /* Run a quarter of the way, and change the prescaler. */
429
+ clock_step(tim_calculate_step(count / 4, ps));
430
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
431
+ ps = 2;
432
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
433
+ /* The counter must not change. */
434
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
435
+
436
+ /* Run another quarter of the way, and change the prescaler again. */
437
+ clock_step(tim_calculate_step(count / 4, ps));
438
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
439
+ ps = 8;
440
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
441
+ /* The counter must not change. */
442
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
443
+
444
+ /* Run another quarter of the way, and change the prescaler again. */
445
+ clock_step(tim_calculate_step(count / 4, ps));
446
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
447
+ ps = 0;
448
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
449
+ /* The counter must not change. */
450
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
451
+
452
+ /* Run almost to expiration, and verify the timer didn't fire yet. */
453
+ clock_step(tim_calculate_step(count / 4, ps) - 1);
454
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
455
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
456
+
457
+ /* Now, run the rest of the way and verify that the timer fires. */
458
+ clock_step(1);
459
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
460
+}
461
+
462
+/* Verifies that a periodic timer automatically restarts after expiration. */
463
+static void test_periodic_no_interrupt(gconstpointer test_data)
464
+{
465
+ const TestData *td = test_data;
466
+ unsigned int count = 2;
467
+ unsigned int ps = 3;
468
+ int i;
469
+
470
+ tim_reset(td);
471
+
472
+ tim_write_ticr(td, count);
473
+ tim_write_tcsr(td, CEN | MODE_PERIODIC | PRESCALE(ps));
474
+
475
+ for (i = 0; i < 4; i++) {
476
+ clock_step_next();
477
+
478
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
479
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
480
+
481
+ tim_write(td, TISR, tim_timer_bit(td));
482
+
483
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
484
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
485
+ }
486
+}
487
+
488
+/* Verifies that a periodict timer fires an interrupt every time it expires. */
489
+static void test_periodic_interrupt(gconstpointer test_data)
490
+{
491
+ const TestData *td = test_data;
492
+ unsigned int count = 65535;
493
+ unsigned int ps = 2;
494
+ int i;
495
+
496
+ tim_reset(td);
497
+
498
+ tim_write_ticr(td, count);
499
+ tim_write_tcsr(td, CEN | IE | MODE_PERIODIC | PRESCALE(ps));
500
+
501
+ for (i = 0; i < 4; i++) {
502
+ clock_step_next();
503
+
504
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
505
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
506
+
507
+ tim_write(td, TISR, tim_timer_bit(td));
508
+
509
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
510
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
511
+ }
512
+}
513
+
514
+/*
515
+ * Verifies that the timer behaves correctly when disabled right before and
516
+ * exactly when it's supposed to expire.
517
+ */
518
+static void test_disable_on_expiration(gconstpointer test_data)
519
+{
520
+ const TestData *td = test_data;
521
+ unsigned int count = 8;
522
+ unsigned int ps = 255;
523
+
524
+ tim_reset(td);
525
+
526
+ tim_write_ticr(td, count);
527
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
528
+
529
+ clock_step(tim_calculate_step(count, ps) - 1);
530
+
531
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
532
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
533
+ clock_step(1);
534
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
535
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
536
+}
537
+
538
+/*
539
+ * Constructs a name that includes the timer block, timer and testcase name,
540
+ * and adds the test to the test suite.
541
+ */
542
+static void tim_add_test(const char *name, const TestData *td, GTestDataFunc fn)
543
+{
544
+ g_autofree char *full_name;
545
+
546
+ full_name = g_strdup_printf("npcm7xx_timer/tim[%d]/timer[%d]/%s",
547
+ tim_index(td->tim), timer_index(td->timer),
548
+ name);
549
+ qtest_add_data_func(full_name, td, fn);
550
+}
551
+
552
+/* Convenience macro for adding a test with a predictable function name. */
553
+#define add_test(name, td) tim_add_test(#name, td, test_##name)
554
+
135
+
555
+int main(int argc, char **argv)
136
+int main(int argc, char **argv)
556
+{
137
+{
557
+ TestData testdata[ARRAY_SIZE(timer_block) * ARRAY_SIZE(timer)];
138
+ int r;
558
+ int ret;
559
+ int i, j;
560
+
139
+
561
+ g_test_init(&argc, &argv, NULL);
140
+ g_test_init(&argc, &argv, NULL);
562
+ g_test_set_nonfatal_assertions();
563
+
141
+
564
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
142
+ qtest_start("-machine mps2-an385");
565
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
566
+ TestData *td = &testdata[i * ARRAY_SIZE(timer) + j];
567
+ td->tim = &timer_block[i];
568
+ td->timer = &timer[j];
569
+
143
+
570
+ add_test(reset, td);
144
+ qtest_add_func("/cmsdk-apb-dualtimer/dualtimer", test_dualtimer);
571
+ add_test(reset_overrides_enable, td);
145
+ qtest_add_func("/cmsdk-apb-dualtimer/prescale", test_prescale);
572
+ add_test(oneshot_enable_then_disable, td);
573
+ add_test(oneshot_ps5, td);
574
+ add_test(oneshot_ps0, td);
575
+ add_test(oneshot_ps255, td);
576
+ add_test(oneshot_interrupt, td);
577
+ add_test(pause_resume, td);
578
+ add_test(prescaler_change, td);
579
+ add_test(periodic_no_interrupt, td);
580
+ add_test(periodic_interrupt, td);
581
+ add_test(disable_on_expiration, td);
582
+ }
583
+ }
584
+
146
+
585
+ qtest_start("-machine npcm750-evb");
147
+ r = g_test_run();
586
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/a9mpcore/gic");
148
+
587
+ ret = g_test_run();
588
+ qtest_end();
149
+ qtest_end();
589
+
150
+
590
+ return ret;
151
+ return r;
591
+}
152
+}
153
diff --git a/MAINTAINERS b/MAINTAINERS
154
index XXXXXXX..XXXXXXX 100644
155
--- a/MAINTAINERS
156
+++ b/MAINTAINERS
157
@@ -XXX,XX +XXX,XX @@ F: include/hw/timer/cmsdk-apb-timer.h
158
F: tests/qtest/cmsdk-apb-timer-test.c
159
F: hw/timer/cmsdk-apb-dualtimer.c
160
F: include/hw/timer/cmsdk-apb-dualtimer.h
161
+F: tests/qtest/cmsdk-apb-dualtimer-test.c
162
F: hw/char/cmsdk-apb-uart.c
163
F: include/hw/char/cmsdk-apb-uart.h
164
F: hw/watchdog/cmsdk-apb-watchdog.c
592
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
165
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
593
index XXXXXXX..XXXXXXX 100644
166
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qtest/meson.build
167
--- a/tests/qtest/meson.build
595
+++ b/tests/qtest/meson.build
168
+++ b/tests/qtest/meson.build
596
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
169
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
597
['arm-cpu-features',
170
'npcm7xx_timer-test',
598
'microbit-test',
171
'npcm7xx_watchdog_timer-test']
599
'm25p80-test',
172
qtests_arm = \
600
+ 'npcm7xx_timer-test',
173
+ (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
601
'test-arm-mptimer',
174
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
602
'boot-serial-test',
175
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
603
'hexloader-test']
176
(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
604
--
177
--
605
2.20.1
178
2.20.1
606
179
607
180
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
Use the BCM2835_SYSTIMER_COUNT definition instead of the
8
Commit created with:
4
magic '4' value.
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
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201010203709.3116542-2-f4bug@amsat.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
include/hw/timer/bcm2835_systmr.h | 4 +++-
18
include/hw/arm/armsse.h | 6 +++---
13
hw/timer/bcm2835_systmr.c | 3 ++-
19
include/hw/timer/cmsdk-apb-timer.h | 4 ++--
14
2 files changed, 5 insertions(+), 2 deletions(-)
20
hw/timer/cmsdk-apb-timer.c | 28 ++++++++++++++--------------
21
3 files changed, 19 insertions(+), 19 deletions(-)
15
22
16
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
23
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/timer/bcm2835_systmr.h
25
--- a/include/hw/arm/armsse.h
19
+++ b/include/hw/timer/bcm2835_systmr.h
26
+++ b/include/hw/arm/armsse.h
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
20
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@
21
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
45
#include "qom/object.h"
22
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
46
23
47
#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
24
+#define BCM2835_SYSTIMER_COUNT 4
48
-OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTIMER, CMSDK_APB_TIMER)
25
+
49
+OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBTimer, CMSDK_APB_TIMER)
26
struct BCM2835SystemTimerState {
50
51
-struct CMSDKAPBTIMER {
52
+struct CMSDKAPBTimer {
27
/*< private >*/
53
/*< private >*/
28
SysBusDevice parent_obj;
54
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
55
30
56
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
31
struct {
57
index XXXXXXX..XXXXXXX 100644
32
uint32_t status;
58
--- a/hw/timer/cmsdk-apb-timer.c
33
- uint32_t compare[4];
59
+++ b/hw/timer/cmsdk-apb-timer.c
34
+ uint32_t compare[BCM2835_SYSTIMER_COUNT];
60
@@ -XXX,XX +XXX,XX @@ static const int timer_id[] = {
35
} reg;
61
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
36
};
62
};
37
63
38
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
64
-static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
39
index XXXXXXX..XXXXXXX 100644
65
+static void cmsdk_apb_timer_update(CMSDKAPBTimer *s)
40
--- a/hw/timer/bcm2835_systmr.c
66
{
41
+++ b/hw/timer/bcm2835_systmr.c
67
qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
42
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
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,
43
.minimum_version_id = 1,
124
.minimum_version_id = 1,
44
.fields = (VMStateField[]) {
125
.fields = (VMStateField[]) {
45
VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
126
- VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
46
- VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
127
- VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
47
+ VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
128
- VMSTATE_UINT32(value, CMSDKAPBTIMER),
48
+ BCM2835_SYSTIMER_COUNT),
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),
49
VMSTATE_END_OF_LIST()
136
VMSTATE_END_OF_LIST()
50
}
137
}
138
};
139
140
static Property cmsdk_apb_timer_properties[] = {
141
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
142
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
143
DEFINE_PROP_END_OF_LIST(),
144
};
145
146
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
147
static const TypeInfo cmsdk_apb_timer_info = {
148
.name = TYPE_CMSDK_APB_TIMER,
149
.parent = TYPE_SYS_BUS_DEVICE,
150
- .instance_size = sizeof(CMSDKAPBTIMER),
151
+ .instance_size = sizeof(CMSDKAPBTimer),
152
.instance_init = cmsdk_apb_timer_init,
153
.class_init = cmsdk_apb_timer_class_init,
51
};
154
};
52
--
155
--
53
2.20.1
156
2.20.1
54
157
55
158
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
2
6
3
Add trace events for GPU and CPU IRQs.
7
Since the device doesn't already have a doc comment for its "QEMU
8
interface", we add one including the new Clock.
4
9
5
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
This is a migration compatibility break for machines mps2-an505,
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
mps2-an521, musca-a, musca-b1.
7
Message-id: 20201017180731.1165871-2-f4bug@amsat.org
12
8
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-8-peter.maydell@linaro.org
18
Message-id: 20210121190622.22000-8-peter.maydell@linaro.org
9
---
19
---
10
hw/intc/bcm2835_ic.c | 4 +++-
20
include/hw/timer/cmsdk-apb-timer.h | 9 +++++++++
11
hw/intc/trace-events | 4 ++++
21
hw/timer/cmsdk-apb-timer.c | 7 +++++--
12
2 files changed, 7 insertions(+), 1 deletion(-)
22
2 files changed, 14 insertions(+), 2 deletions(-)
13
23
14
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2835_ic.c
26
--- a/include/hw/timer/cmsdk-apb-timer.h
17
+++ b/hw/intc/bcm2835_ic.c
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
18
@@ -XXX,XX +XXX,XX @@
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"
19
#include "migration/vmstate.h"
66
#include "migration/vmstate.h"
20
#include "qemu/log.h"
67
21
#include "qemu/module.h"
68
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
22
+#include "trace.h"
69
s, "cmsdk-apb-timer", 0x1000);
23
70
sysbus_init_mmio(sbd, &s->iomem);
24
#define GPU_IRQS 64
71
sysbus_init_irq(sbd, &s->timerint);
25
#define ARM_IRQS 8
72
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_update(BCM2835ICState *s)
27
set = (s->gpu_irq_level & s->gpu_irq_enable)
28
|| (s->arm_irq_level & s->arm_irq_enable);
29
qemu_set_irq(s->irq, set);
30
-
31
}
73
}
32
74
33
static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
75
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
34
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
76
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
35
BCM2835ICState *s = opaque;
77
36
78
static const VMStateDescription cmsdk_apb_timer_vmstate = {
37
assert(irq >= 0 && irq < 64);
79
.name = "cmsdk-apb-timer",
38
+ trace_bcm2835_ic_set_gpu_irq(irq, level);
80
- .version_id = 1,
39
s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
81
- .minimum_version_id = 1,
40
bcm2835_ic_update(s);
82
+ .version_id = 2,
41
}
83
+ .minimum_version_id = 2,
42
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
84
.fields = (VMStateField[]) {
43
BCM2835ICState *s = opaque;
85
VMSTATE_PTIMER(timer, CMSDKAPBTimer),
44
86
+ VMSTATE_CLOCK(pclk, CMSDKAPBTimer),
45
assert(irq >= 0 && irq < 8);
87
VMSTATE_UINT32(ctrl, CMSDKAPBTimer),
46
+ trace_bcm2835_ic_set_cpu_irq(irq, level);
88
VMSTATE_UINT32(value, CMSDKAPBTimer),
47
s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
89
VMSTATE_UINT32(reload, CMSDKAPBTimer),
48
bcm2835_ic_update(s);
49
}
50
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/intc/trace-events
53
+++ b/hw/intc/trace-events
54
@@ -XXX,XX +XXX,XX @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg wri
55
heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
56
heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
57
heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
58
+
59
+# bcm2835_ic.c
60
+bcm2835_ic_set_gpu_irq(int irq, int level) "GPU irq #%d level %d"
61
+bcm2835_ic_set_cpu_irq(int irq, int level) "CPU irq #%d level %d"
62
--
90
--
63
2.20.1
91
2.20.1
64
92
65
93
diff view generated by jsdifflib
1
For AArch32, unlike the VCVT of integer to float, which honours the
1
As the first step in converting the CMSDK_APB_DUALTIMER device to the
2
rounding mode specified by the FPSCR, VCVT of fixed-point to float is
2
Clock framework, add a Clock input. For the moment we do nothing
3
always round-to-nearest. (AArch64 fixed-point-to-float conversions
3
with this clock; we will change the behaviour from using the pclk-frq
4
always honour the FPCR rounding mode.)
4
property to using the Clock once all the users of this device have
5
been converted to wire up the Clock.
5
6
6
Implement this by providing _round_to_nearest versions of the
7
We take the opportunity to correct the name of the clock input to
7
relevant helpers which set the rounding mode temporarily when making
8
match the hardware -- the dual timer names the clock which drives the
8
the call to the underlying softfloat function.
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.)
9
12
10
We only need to change the VFP VCVT instructions, because the
13
This is a migration compatibility break for machines mps2-an385,
11
standard- FPSCR value used by the Neon VCVT is always set to
14
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
12
round-to-nearest, so we don't need to do the extra work of saving
15
musca-b1.
13
and restoring the rounding mode.
14
16
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20201013103532.13391-1-peter.maydell@linaro.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
18
---
23
---
19
target/arm/helper.h | 13 +++++++++++++
24
include/hw/timer/cmsdk-apb-dualtimer.h | 3 +++
20
target/arm/vfp_helper.c | 23 ++++++++++++++++++++++-
25
hw/timer/cmsdk-apb-dualtimer.c | 7 +++++--
21
target/arm/translate-vfp.c.inc | 24 ++++++++++++------------
26
2 files changed, 8 insertions(+), 2 deletions(-)
22
3 files changed, 47 insertions(+), 13 deletions(-)
23
27
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsdk-apb-dualtimer.h
25
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
30
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
27
+++ b/target/arm/helper.h
31
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
32
@@ -XXX,XX +XXX,XX @@
29
DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
33
*
30
DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
34
* QEMU interface:
31
35
* + QOM property "pclk-frq": frequency at which the timer is clocked
32
+DEF_HELPER_3(vfp_shtos_round_to_nearest, f32, i32, i32, ptr)
36
+ * + Clock input "TIMCLK": clock (for both timers)
33
+DEF_HELPER_3(vfp_sltos_round_to_nearest, f32, i32, i32, ptr)
37
* + sysbus MMIO region 0: the register bank
34
+DEF_HELPER_3(vfp_uhtos_round_to_nearest, f32, i32, i32, ptr)
38
* + sysbus IRQ 0: combined timer interrupt TIMINTC
35
+DEF_HELPER_3(vfp_ultos_round_to_nearest, f32, i32, i32, ptr)
39
* + sysbus IRO 1: timer block 1 interrupt TIMINT1
36
+DEF_HELPER_3(vfp_shtod_round_to_nearest, f64, i64, i32, ptr)
40
@@ -XXX,XX +XXX,XX @@
37
+DEF_HELPER_3(vfp_sltod_round_to_nearest, f64, i64, i32, ptr)
41
38
+DEF_HELPER_3(vfp_uhtod_round_to_nearest, f64, i64, i32, ptr)
42
#include "hw/sysbus.h"
39
+DEF_HELPER_3(vfp_ultod_round_to_nearest, f64, i64, i32, ptr)
43
#include "hw/ptimer.h"
40
+DEF_HELPER_3(vfp_shtoh_round_to_nearest, f16, i32, i32, ptr)
44
+#include "hw/clock.h"
41
+DEF_HELPER_3(vfp_uhtoh_round_to_nearest, f16, i32, i32, ptr)
45
#include "qom/object.h"
42
+DEF_HELPER_3(vfp_sltoh_round_to_nearest, f16, i32, i32, ptr)
46
43
+DEF_HELPER_3(vfp_ultoh_round_to_nearest, f16, i32, i32, ptr)
47
#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer"
44
+
48
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBDualTimer {
45
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
49
MemoryRegion iomem;
46
50
qemu_irq timerintc;
47
DEF_HELPER_FLAGS_3(vfp_fcvt_f16_to_f32, TCG_CALL_NO_RWG, f32, f16, ptr, i32)
51
uint32_t pclk_frq;
48
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
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
49
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/vfp_helper.c
58
--- a/hw/timer/cmsdk-apb-dualtimer.c
51
+++ b/target/arm/vfp_helper.c
59
+++ b/hw/timer/cmsdk-apb-dualtimer.c
52
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
60
@@ -XXX,XX +XXX,XX @@
53
return float64_to_float32(x, &env->vfp.fp_status);
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);
54
}
73
}
55
74
56
-/* VFP3 fixed point conversion. */
75
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
57
+/*
76
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_dualtimermod_vmstate = {
58
+ * VFP3 fixed point conversion. The AArch32 versions of fix-to-float
77
59
+ * must always round-to-nearest; the AArch64 ones honour the FPSCR
78
static const VMStateDescription cmsdk_apb_dualtimer_vmstate = {
60
+ * rounding mode. (For AArch32 Neon the standard-FPSCR is set to
79
.name = "cmsdk-apb-dualtimer",
61
+ * round-to-nearest so either helper will work.) AArch32 float-to-fix
80
- .version_id = 1,
62
+ * must round-to-zero.
81
- .minimum_version_id = 1,
63
+ */
82
+ .version_id = 2,
64
#define VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
83
+ .minimum_version_id = 2,
65
ftype HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
84
.fields = (VMStateField[]) {
66
void *fpstp) \
85
+ VMSTATE_CLOCK(timclk, CMSDKAPBDualTimer),
67
{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
86
VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer,
68
87
CMSDK_APB_DUALTIMER_NUM_MODULES,
69
+#define VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
88
1, cmsdk_dualtimermod_vmstate,
70
+ ftype HELPER(vfp_##name##to##p##_round_to_nearest)(uint##isz##_t x, \
71
+ uint32_t shift, \
72
+ void *fpstp) \
73
+ { \
74
+ ftype ret; \
75
+ float_status *fpst = fpstp; \
76
+ FloatRoundMode oldmode = fpst->float_rounding_mode; \
77
+ fpst->float_rounding_mode = float_round_nearest_even; \
78
+ ret = itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); \
79
+ fpst->float_rounding_mode = oldmode; \
80
+ return ret; \
81
+ }
82
+
83
#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, ROUND, suff) \
84
uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
85
void *fpst) \
86
@@ -XXX,XX +XXX,XX @@ uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
87
88
#define VFP_CONV_FIX(name, p, fsz, ftype, isz, itype) \
89
VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
90
+VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
91
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
92
float_round_to_zero, _round_to_zero) \
93
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
94
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/translate-vfp.c.inc
97
+++ b/target/arm/translate-vfp.c.inc
98
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
99
/* Switch on op:U:sx bits */
100
switch (a->opc) {
101
case 0:
102
- gen_helper_vfp_shtoh(vd, vd, shift, fpst);
103
+ gen_helper_vfp_shtoh_round_to_nearest(vd, vd, shift, fpst);
104
break;
105
case 1:
106
- gen_helper_vfp_sltoh(vd, vd, shift, fpst);
107
+ gen_helper_vfp_sltoh_round_to_nearest(vd, vd, shift, fpst);
108
break;
109
case 2:
110
- gen_helper_vfp_uhtoh(vd, vd, shift, fpst);
111
+ gen_helper_vfp_uhtoh_round_to_nearest(vd, vd, shift, fpst);
112
break;
113
case 3:
114
- gen_helper_vfp_ultoh(vd, vd, shift, fpst);
115
+ gen_helper_vfp_ultoh_round_to_nearest(vd, vd, shift, fpst);
116
break;
117
case 4:
118
gen_helper_vfp_toshh_round_to_zero(vd, vd, shift, fpst);
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
120
/* Switch on op:U:sx bits */
121
switch (a->opc) {
122
case 0:
123
- gen_helper_vfp_shtos(vd, vd, shift, fpst);
124
+ gen_helper_vfp_shtos_round_to_nearest(vd, vd, shift, fpst);
125
break;
126
case 1:
127
- gen_helper_vfp_sltos(vd, vd, shift, fpst);
128
+ gen_helper_vfp_sltos_round_to_nearest(vd, vd, shift, fpst);
129
break;
130
case 2:
131
- gen_helper_vfp_uhtos(vd, vd, shift, fpst);
132
+ gen_helper_vfp_uhtos_round_to_nearest(vd, vd, shift, fpst);
133
break;
134
case 3:
135
- gen_helper_vfp_ultos(vd, vd, shift, fpst);
136
+ gen_helper_vfp_ultos_round_to_nearest(vd, vd, shift, fpst);
137
break;
138
case 4:
139
gen_helper_vfp_toshs_round_to_zero(vd, vd, shift, fpst);
140
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
141
/* Switch on op:U:sx bits */
142
switch (a->opc) {
143
case 0:
144
- gen_helper_vfp_shtod(vd, vd, shift, fpst);
145
+ gen_helper_vfp_shtod_round_to_nearest(vd, vd, shift, fpst);
146
break;
147
case 1:
148
- gen_helper_vfp_sltod(vd, vd, shift, fpst);
149
+ gen_helper_vfp_sltod_round_to_nearest(vd, vd, shift, fpst);
150
break;
151
case 2:
152
- gen_helper_vfp_uhtod(vd, vd, shift, fpst);
153
+ gen_helper_vfp_uhtod_round_to_nearest(vd, vd, shift, fpst);
154
break;
155
case 3:
156
- gen_helper_vfp_ultod(vd, vd, shift, fpst);
157
+ gen_helper_vfp_ultod_round_to_nearest(vd, vd, shift, fpst);
158
break;
159
case 4:
160
gen_helper_vfp_toshd_round_to_zero(vd, vd, shift, fpst);
161
--
89
--
162
2.20.1
90
2.20.1
163
91
164
92
diff view generated by jsdifflib
1
If the M-profile low-overhead-branch extension is implemented, FPSCR
1
As the first step in converting the CMSDK_APB_TIMER device to the
2
bits [18:16] are a new field LTPSIZE. If MVE is not implemented
2
Clock framework, add a Clock input. For the moment we do nothing
3
(currently always true for us) then this field always reads as 4 and
3
with this clock; we will change the behaviour from using the
4
ignores writes.
4
wdogclk-frq property to using the Clock once all the users of this
5
device have been converted to wire up the Clock.
5
6
6
These bits used to be the vector-length field for the old
7
This is a migration compatibility break for machines mps2-an385,
7
short-vector extension, so we need to take care that they are not
8
mps2-an386, mps2-an500, mps2-an511, mps2-an505, mps2-an521, musca-a,
8
misinterpreted as setting vec_len. We do this with a rearrangement
9
musca-b1, lm3s811evb, lm3s6965evb.
9
of the vfp_set_fpscr() code that deals with vec_len, vec_stride
10
and also the QC bit; this obviates the need for the M-profile
11
only masking step that we used to have at the start of the function.
12
13
We provide a new field in CPUState for LTPSIZE, even though this
14
will always be 4, in preparation for MVE, so we don't have to
15
come back later and split it out of the vfp.xregs[FPSCR] value.
16
(This state struct field will be saved and restored as part of
17
the FPSCR value via the vmstate_fpscr in machine.c.)
18
10
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20201019151301.2046-11-peter.maydell@linaro.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
22
---
17
---
23
target/arm/cpu.h | 1 +
18
include/hw/watchdog/cmsdk-apb-watchdog.h | 3 +++
24
target/arm/cpu.c | 9 +++++++++
19
hw/watchdog/cmsdk-apb-watchdog.c | 7 +++++--
25
target/arm/vfp_helper.c | 6 ++++++
20
2 files changed, 8 insertions(+), 2 deletions(-)
26
3 files changed, 16 insertions(+)
27
21
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
29
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
24
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
31
+++ b/target/arm/cpu.h
25
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
26
@@ -XXX,XX +XXX,XX @@
33
uint32_t fpdscr[M_REG_NUM_BANKS];
27
*
34
uint32_t cpacr[M_REG_NUM_BANKS];
28
* QEMU interface:
35
uint32_t nsacr;
29
* + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
36
+ int ltpsize;
30
+ * + Clock input "WDOGCLK": clock for the watchdog's timer
37
} v7m;
31
* + sysbus MMIO region 0: the register bank
38
32
* + sysbus IRQ 0: watchdog interrupt
39
/* Information associated with an exception about to be taken:
33
*
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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
41
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu.c
52
--- a/hw/watchdog/cmsdk-apb-watchdog.c
43
+++ b/target/arm/cpu.c
53
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
54
@@ -XXX,XX +XXX,XX @@
45
uint8_t *rom;
55
#include "hw/irq.h"
46
uint32_t vecbase;
56
#include "hw/qdev-properties.h"
47
57
#include "hw/registerfields.h"
48
+ if (cpu_isar_feature(aa32_lob, cpu)) {
58
+#include "hw/qdev-clock.h"
49
+ /*
59
#include "hw/watchdog/cmsdk-apb-watchdog.h"
50
+ * LTPSIZE is constant 4 if MVE not implemented, and resets
60
#include "migration/vmstate.h"
51
+ * to an UNKNOWN value if MVE is implemented. We choose to
61
52
+ * always reset to 4.
62
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
53
+ */
63
s, "cmsdk-apb-watchdog", 0x1000);
54
+ env->v7m.ltpsize = 4;
64
sysbus_init_mmio(sbd, &s->iomem);
55
+ }
65
sysbus_init_irq(sbd, &s->wdogint);
56
+
66
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
57
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
67
58
env->v7m.secure = true;
68
s->is_luminary = false;
59
} else {
69
s->id = cmsdk_apb_watchdog_id;
60
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
70
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
61
index XXXXXXX..XXXXXXX 100644
71
62
--- a/target/arm/vfp_helper.c
72
static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
63
+++ b/target/arm/vfp_helper.c
73
.name = "cmsdk-apb-watchdog",
64
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
74
- .version_id = 1,
65
| (env->vfp.vec_len << 16)
75
- .minimum_version_id = 1,
66
| (env->vfp.vec_stride << 20);
76
+ .version_id = 2,
67
77
+ .minimum_version_id = 2,
68
+ /*
78
.fields = (VMStateField[]) {
69
+ * M-profile LTPSIZE overlaps A-profile Stride; whichever of the
79
+ VMSTATE_CLOCK(wdogclk, CMSDKAPBWatchdog),
70
+ * two is not applicable to this CPU will always be zero.
80
VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
71
+ */
81
VMSTATE_UINT32(control, CMSDKAPBWatchdog),
72
+ fpscr |= env->v7m.ltpsize << 16;
82
VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
73
+
74
fpscr |= vfp_get_fpscr_from_host(env);
75
76
i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
77
--
83
--
78
2.20.1
84
2.20.1
79
85
80
86
diff view generated by jsdifflib
1
M-profile CPUs with half-precision floating point support should
1
While we transition the ARMSSE code from integer properties
2
be able to write to FPSCR.FZ16, but an M-profile specific masking
2
specifying clock frequencies to Clock objects, we want to have the
3
of the value at the top of vfp_set_fpscr() currently prevents that.
3
device provide both at once. We want the final name of the main
4
This is not yet an active bug because we have no M-profile
4
input Clock to be "MAINCLK", following the hardware name.
5
FP16 CPUs, but needs to be fixed before we can add any.
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.
6
8
7
The bits that the masking is effectively preventing from being
9
Rename the UINT32 property to MAINCLK_FRQ so it can coexist with the
8
set are the A-profile only short-vector Len and Stride fields,
10
MAINCLK Clock; once the transition is complete MAINCLK_FRQ will be
9
plus the Neon QC bit. Rearrange the order of the function so
11
deleted.
10
that those fields are handled earlier and only under a suitable
11
guard; this allows us to drop the M-profile specific masking,
12
making FZ16 writeable.
13
12
14
This change also makes the QC bit correctly RAZ/WI for older
13
Commit created with:
15
no-Neon A-profile cores.
14
perl -p -i -e 's/MAINCLK/MAINCLK_FRQ/g' hw/arm/{armsse,mps2-tz,musca}.c include/hw/arm/armsse.h
16
17
This refactoring also paves the way for the low-overhead-branch
18
LTPSIZE field, which uses some of the bits that are used for
19
A-profile Stride and Len.
20
15
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20201019151301.2046-10-peter.maydell@linaro.org
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
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
24
---
22
---
25
target/arm/vfp_helper.c | 47 ++++++++++++++++++++++++-----------------
23
include/hw/arm/armsse.h | 2 +-
26
1 file changed, 28 insertions(+), 19 deletions(-)
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(-)
27
28
28
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
29
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
29
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/vfp_helper.c
31
--- a/include/hw/arm/armsse.h
31
+++ b/target/arm/vfp_helper.c
32
+++ b/include/hw/arm/armsse.h
32
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
33
@@ -XXX,XX +XXX,XX @@
33
val &= ~FPCR_FZ16;
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)
34
}
65
}
35
66
36
- if (arm_feature(env, ARM_FEATURE_M)) {
67
if (!s->mainclk_frq) {
37
+ vfp_set_fpscr_to_host(env, val);
68
- error_setg(errp, "MAINCLK property was not set");
38
+
69
+ error_setg(errp, "MAINCLK_FRQ property was not set");
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
70
return;
40
/*
41
- * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
42
- * and also for the trapped-exception-handling bits IxE.
43
+ * Short-vector length and stride; on M-profile these bits
44
+ * are used for different purposes.
45
+ * We can't make this conditional be "if MVFR0.FPShVec != 0",
46
+ * because in v7A no-short-vector-support cores still had to
47
+ * allow Stride/Len to be written with the only effect that
48
+ * some insns are required to UNDEF if the guest sets them.
49
+ *
50
+ * TODO: if M-profile MVE implemented, set LTPSIZE.
51
*/
52
- val &= 0xf7c0009f;
53
+ env->vfp.vec_len = extract32(val, 16, 3);
54
+ env->vfp.vec_stride = extract32(val, 20, 2);
55
}
71
}
56
72
57
- vfp_set_fpscr_to_host(env, val);
73
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
58
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
74
index XXXXXXX..XXXXXXX 100644
59
+ /*
75
--- a/hw/arm/mps2-tz.c
60
+ * The bit we set within fpscr_q is arbitrary; the register as a
76
+++ b/hw/arm/mps2-tz.c
61
+ * whole being zero/non-zero is what counts.
77
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
62
+ * TODO: M-profile MVE also has a QC bit.
78
object_property_set_link(OBJECT(&mms->iotkit), "memory",
63
+ */
79
OBJECT(system_memory), &error_abort);
64
+ env->vfp.qc[0] = val & FPCR_QC;
80
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
65
+ env->vfp.qc[1] = 0;
81
- qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
66
+ env->vfp.qc[2] = 0;
82
+ qdev_prop_set_uint32(iotkitdev, "MAINCLK_FRQ", SYSCLK_FRQ);
67
+ env->vfp.qc[3] = 0;
83
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
68
+ }
69
84
70
/*
85
/*
71
* We don't implement trapped exception handling, so the
86
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
72
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
87
index XXXXXXX..XXXXXXX 100644
73
*
88
--- a/hw/arm/musca.c
74
- * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
89
+++ b/hw/arm/musca.c
75
- * (which are stored in fp_status), and the other RES0 bits
90
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
76
- * in between, then we clear all of the low 16 bits.
91
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
77
+ * The exception flags IOC|DZC|OFC|UFC|IXC|IDC are stored in
92
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
78
+ * fp_status; QC, Len and Stride are stored separately earlier.
93
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
79
+ * Clear out all of those and the RES0 bits: only NZCV, AHP, DN,
94
- qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
80
+ * FZ, RMode and FZ16 are kept in vfp.xregs[FPSCR].
95
+ qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
81
*/
96
/*
82
env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
97
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
83
- env->vfp.vec_len = (val >> 16) & 7;
98
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
84
- env->vfp.vec_stride = (val >> 20) & 3;
85
-
86
- /*
87
- * The bit we set within fpscr_q is arbitrary; the register as a
88
- * whole being zero/non-zero is what counts.
89
- */
90
- env->vfp.qc[0] = val & FPCR_QC;
91
- env->vfp.qc[1] = 0;
92
- env->vfp.qc[2] = 0;
93
- env->vfp.qc[3] = 0;
94
}
95
96
void vfp_set_fpscr(CPUARMState *env, uint32_t val)
97
--
99
--
98
2.20.1
100
2.20.1
99
101
100
102
diff view generated by jsdifflib
1
The SMLAD instruction is supposed to:
1
Create two input clocks on the ARMSSE devices, one for the normal
2
* signed multiply Rn[15:0] * Rm[15:0]
2
MAINCLK, and one for the 32KHz S32KCLK, and wire these up to the
3
* signed multiply Rn[31:16] * Rm[31:16]
3
appropriate devices. The old property-based clock frequency setting
4
* perform a signed addition of the products and Ra
4
will remain in place until conversion is complete.
5
* set Rd to the low 32 bits of the theoretical
6
infinite-precision result
7
* set the Q flag if the sign-extension of Rd
8
would differ from the infinite-precision result
9
(ie on overflow)
10
5
11
Our current implementation doesn't quite do this, though: it performs
6
This is a migration compatibility break for machines mps2-an505,
12
an addition of the products setting Q on overflow, and then it adds
7
mps2-an521, musca-a, musca-b1.
13
Ra, again possibly setting Q. This sometimes incorrectly sets Q when
14
the architecturally mandated only-check-for-overflow-once algorithm
15
does not. For instance:
16
r1 = 0x80008000; r2 = 0x80008000; r3 = 0xffffffff
17
smlad r0, r1, r2, r3
18
This is (-32768 * -32768) + (-32768 * -32768) - 1
19
20
The products are both 0x4000_0000, so when added together as 32-bit
21
signed numbers they overflow (and QEMU sets Q), but because the
22
addition of Ra == -1 brings the total back down to 0x7fff_ffff
23
there is no overflow for the complete operation and setting Q is
24
incorrect.
25
26
Fix this edge case by resorting to 64-bit arithmetic for the
27
case where we need to add three values together.
28
8
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
31
Message-id: 20201009144712.11187-1-peter.maydell@linaro.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
32
---
15
---
33
target/arm/translate.c | 58 ++++++++++++++++++++++++++++++++++--------
16
include/hw/arm/armsse.h | 6 ++++++
34
1 file changed, 48 insertions(+), 10 deletions(-)
17
hw/arm/armsse.c | 17 +++++++++++++++--
18
2 files changed, 21 insertions(+), 2 deletions(-)
35
19
36
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
37
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate.c
22
--- a/include/hw/arm/armsse.h
39
+++ b/target/arm/translate.c
23
+++ b/include/hw/arm/armsse.h
40
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
24
@@ -XXX,XX +XXX,XX @@
41
gen_smul_dual(t1, t2);
25
* per-CPU identity and control register blocks
42
26
*
43
if (sub) {
27
* QEMU interface:
44
- /* This subtraction cannot overflow. */
28
+ * + Clock input "MAINCLK": clock for CPUs and most peripherals
45
+ /*
29
+ * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
46
+ * This subtraction cannot overflow, so we can do a simple
30
* + QOM property "memory" is a MemoryRegion containing the devices provided
47
+ * 32-bit subtraction and then a possible 32-bit saturating
31
* by the board model.
48
+ * addition of Ra.
32
* + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
49
+ */
33
@@ -XXX,XX +XXX,XX @@
50
tcg_gen_sub_i32(t1, t1, t2);
34
#include "hw/misc/armsse-mhu.h"
51
+ tcg_temp_free_i32(t2);
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;
52
+
47
+
53
+ if (a->ra != 15) {
48
/* Properties */
54
+ t2 = load_reg(s, a->ra);
49
MemoryRegion *board_memory;
55
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
50
uint32_t exp_numirq;
56
+ tcg_temp_free_i32(t2);
51
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
57
+ }
52
index XXXXXXX..XXXXXXX 100644
58
+ } else if (a->ra == 15) {
53
--- a/hw/arm/armsse.c
59
+ /* Single saturation-checking addition */
54
+++ b/hw/arm/armsse.c
60
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
55
@@ -XXX,XX +XXX,XX @@
61
+ tcg_temp_free_i32(t2);
56
#include "hw/arm/armsse.h"
62
} else {
57
#include "hw/arm/boot.h"
63
/*
58
#include "hw/irq.h"
64
- * This addition cannot overflow 32 bits; however it may
59
+#include "hw/qdev-clock.h"
65
- * overflow considered as a signed operation, in which case
60
66
- * we must set the Q flag.
61
/* Format of the System Information block SYS_CONFIG register */
67
+ * We need to add the products and Ra together and then
62
typedef enum SysConfigFormat {
68
+ * determine whether the final result overflowed. Doing
63
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
69
+ * this as two separate add-and-check-overflow steps incorrectly
64
assert(info->sram_banks <= MAX_SRAM_BANKS);
70
+ * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
65
assert(info->num_cpus <= SSE_MAX_CPUS);
71
+ * Do all the arithmetic at 64-bits and then check for overflow.
66
72
*/
67
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
73
- gen_helper_add_setq(t1, cpu_env, t1, t2);
68
+ s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
74
- }
75
- tcg_temp_free_i32(t2);
76
+ TCGv_i64 p64, q64;
77
+ TCGv_i32 t3, qf, one;
78
79
- if (a->ra != 15) {
80
- t2 = load_reg(s, a->ra);
81
- gen_helper_add_setq(t1, cpu_env, t1, t2);
82
+ p64 = tcg_temp_new_i64();
83
+ q64 = tcg_temp_new_i64();
84
+ tcg_gen_ext_i32_i64(p64, t1);
85
+ tcg_gen_ext_i32_i64(q64, t2);
86
+ tcg_gen_add_i64(p64, p64, q64);
87
+ load_reg_var(s, t2, a->ra);
88
+ tcg_gen_ext_i32_i64(q64, t2);
89
+ tcg_gen_add_i64(p64, p64, q64);
90
+ tcg_temp_free_i64(q64);
91
+
69
+
92
+ tcg_gen_extr_i64_i32(t1, t2, p64);
70
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
93
+ tcg_temp_free_i64(p64);
71
94
+ /*
72
for (i = 0; i < info->num_cpus; i++) {
95
+ * t1 is the low half of the result which goes into Rd.
73
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
96
+ * We have overflow and must set Q if the high half (t2)
74
* map its upstream ends to the right place in the container.
97
+ * is different from the sign-extension of t1.
75
*/
98
+ */
76
qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
99
+ t3 = tcg_temp_new_i32();
77
+ qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
100
+ tcg_gen_sari_i32(t3, t1, 31);
78
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
101
+ qf = load_cpu_field(QF);
79
return;
102
+ one = tcg_const_i32(1);
103
+ tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
104
+ store_cpu_field(qf, QF);
105
+ tcg_temp_free_i32(one);
106
+ tcg_temp_free_i32(t3);
107
tcg_temp_free_i32(t2);
108
}
80
}
109
store_reg(s, a->rd, t1);
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
}
110
--
143
--
111
2.20.1
144
2.20.1
112
145
113
146
diff view generated by jsdifflib
1
The BLX immediate insn in the Thumb encoding always performs
1
The old-style convenience function cmsdk_apb_timer_create() for
2
a switch from Thumb to Arm state. This would be totally useless
2
creating CMSDK_APB_TIMER objects is used in only two places in
3
in M-profile which has no Arm decoder, and so the instruction
3
mps2.c. Most of the rest of the code in that file uses the new
4
does not exist at all there. Make the encoding UNDEF for M-profile.
4
"initialize in place" coding style.
5
5
6
(This part of the encoding space is used for the branch-future
6
We want to connect up a Clock object which should be done between the
7
and low-overhead-loop insns in v8.1M.)
7
object creation and realization; rather than adding a Clock* argument
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.
8
12
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-6-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
12
---
19
---
13
target/arm/translate.c | 8 ++++++++
20
include/hw/timer/cmsdk-apb-timer.h | 21 ---------------------
14
1 file changed, 8 insertions(+)
21
hw/arm/mps2.c | 18 ++++++++++++++++--
22
2 files changed, 16 insertions(+), 23 deletions(-)
15
23
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
26
--- a/include/hw/timer/cmsdk-apb-timer.h
19
+++ b/target/arm/translate.c
27
+++ b/include/hw/timer/cmsdk-apb-timer.h
20
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
28
@@ -XXX,XX +XXX,XX @@ struct CMSDKAPBTimer {
21
{
29
uint32_t intstatus;
22
TCGv_i32 tmp;
30
};
23
31
24
+ /*
32
-/**
25
+ * BLX <imm> would be useless on M-profile; the encoding space
33
- * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
26
+ * is used for other insns from v8.1M onward, and UNDEFs before that.
34
- * @addr: location in system memory to map registers
27
+ */
35
- * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
28
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
36
- */
29
+ return false;
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
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/mps2.c
57
+++ b/hw/arm/mps2.c
58
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
59
/* CMSDK APB subsystem */
60
CMSDKAPBDualTimer dualtimer;
61
CMSDKAPBWatchdog watchdog;
62
+ CMSDKAPBTimer timer[2];
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;
77
+
78
+ object_initialize_child(OBJECT(mms), name, &mms->timer[i],
79
+ TYPE_CMSDK_APB_TIMER);
80
+ sbd = SYS_BUS_DEVICE(&mms->timer[i]);
81
+ qdev_prop_set_uint32(DEVICE(&mms->timer[i]), "pclk-frq", SYSCLK_FRQ);
82
+ sysbus_realize_and_unref(sbd, &error_fatal);
83
+ sysbus_mmio_map(sbd, 0, base);
84
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
30
+ }
85
+ }
31
+
86
+
32
/* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
87
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
33
if (s->thumb && (a->imm & 2)) {
88
TYPE_CMSDK_APB_DUALTIMER);
34
return false;
89
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
35
--
90
--
36
2.20.1
91
2.20.1
37
92
38
93
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Create a fixed-frequency Clock object to be the SYSCLK, and wire it
2
up to the devices that require it.
2
3
3
The second loop uses a loop induction variable, and the first
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
does not. Transform the first to match the second, to simplify
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
a following patch moving code between them.
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(+)
6
13
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201016184207.786698-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
linux-user/elfload.c | 9 +++++----
13
1 file changed, 5 insertions(+), 4 deletions(-)
14
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
16
--- a/hw/arm/mps2.c
18
+++ b/linux-user/elfload.c
17
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
18
@@ -XXX,XX +XXX,XX @@
20
loaddr = -1, hiaddr = 0;
19
#include "hw/net/lan9118.h"
21
info->alignment = 0;
20
#include "net/net.h"
22
for (i = 0; i < ehdr->e_phnum; ++i) {
21
#include "hw/watchdog/cmsdk-apb-watchdog.h"
23
- if (phdr[i].p_type == PT_LOAD) {
22
+#include "hw/qdev-clock.h"
24
- abi_ulong a = phdr[i].p_vaddr - phdr[i].p_offset;
23
#include "qom/object.h"
25
+ struct elf_phdr *eppnt = phdr + i;
24
26
+ if (eppnt->p_type == PT_LOAD) {
25
typedef enum MPS2FPGAType {
27
+ abi_ulong a = eppnt->p_vaddr - eppnt->p_offset;
26
@@ -XXX,XX +XXX,XX @@ struct MPS2MachineState {
28
if (a < loaddr) {
27
CMSDKAPBDualTimer dualtimer;
29
loaddr = a;
28
CMSDKAPBWatchdog watchdog;
30
}
29
CMSDKAPBTimer timer[2];
31
- a = phdr[i].p_vaddr + phdr[i].p_memsz;
30
+ Clock *sysclk;
32
+ a = eppnt->p_vaddr + eppnt->p_memsz;
31
};
33
if (a > hiaddr) {
32
34
hiaddr = a;
33
#define TYPE_MPS2_MACHINE "mps2"
35
}
34
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
36
++info->nsegs;
35
exit(EXIT_FAILURE);
37
- info->alignment |= phdr[i].p_align;
38
+ info->alignment |= eppnt->p_align;
39
}
40
}
36
}
41
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));
42
--
69
--
43
2.20.1
70
2.20.1
44
71
45
72
diff view generated by jsdifflib
1
In arm_cpu_realizefn(), if the CPU has VFP or Neon disabled then we
1
Create and connect the two clocks needed by the ARMSSE.
2
squash the ID register fields so that we don't advertise it to the
3
guest. This code was written for A-profile and needs some tweaks to
4
work correctly on M-profile:
5
2
6
* A-profile only fields should not be zeroed on M-profile:
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
- MVFR0.FPSHVEC,FPTRAP
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
- MVFR1.SIMDLS,SIMDINT,SIMDSP,SIMDHP
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
- MVFR2.SIMDMISC
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
* M-profile only fields should be zeroed on M-profile:
7
Message-id: 20210128114145.20536-15-peter.maydell@linaro.org
11
- MVFR1.FP16
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
12
13
In particular, because MVFR1.SIMDHP on A-profile is the same field as
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
MVFR1.FP16 on M-profile this code was incorrectly disabling FP16
15
support on an M-profile CPU (where has_neon is always false). This
16
isn't a visible bug yet because we don't have any M-profile CPUs with
17
FP16 support, but the change is necessary before we introduce any.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20201019151301.2046-9-peter.maydell@linaro.org
22
---
23
target/arm/cpu.c | 29 ++++++++++++++++++-----------
24
1 file changed, 18 insertions(+), 11 deletions(-)
25
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.c
15
--- a/hw/arm/mps2-tz.c
29
+++ b/target/arm/cpu.c
16
+++ b/hw/arm/mps2-tz.c
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@
31
u = cpu->isar.mvfr0;
18
#include "hw/net/lan9118.h"
32
u = FIELD_DP32(u, MVFR0, FPSP, 0);
19
#include "net/net.h"
33
u = FIELD_DP32(u, MVFR0, FPDP, 0);
20
#include "hw/core/split-irq.h"
34
- u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
21
+#include "hw/qdev-clock.h"
35
u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
22
#include "qom/object.h"
36
u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
23
37
- u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
24
#define MPS2TZ_NUMIRQ 92
38
u = FIELD_DP32(u, MVFR0, FPROUND, 0);
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
26
qemu_or_irq uart_irq_orgate;
40
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
27
DeviceState *lan9118;
41
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
28
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
42
+ }
29
+ Clock *sysclk;
43
cpu->isar.mvfr0 = u;
30
+ Clock *s32kclk;
44
31
};
45
u = cpu->isar.mvfr1;
32
46
u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
33
#define TYPE_MPS2TZ_MACHINE "mps2tz"
47
u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
34
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
48
u = FIELD_DP32(u, MVFR1, FPHP, 0);
35
49
+ if (arm_feature(env, ARM_FEATURE_M)) {
36
/* Main SYSCLK frequency in Hz */
50
+ u = FIELD_DP32(u, MVFR1, FP16, 0);
37
#define SYSCLK_FRQ 20000000
51
+ }
38
+/* Slow 32Khz S32KCLK frequency in Hz */
52
cpu->isar.mvfr1 = u;
39
+#define S32KCLK_FRQ (32 * 1000)
53
40
54
u = cpu->isar.mvfr2;
41
/* Create an alias of an entire original MemoryRegion @orig
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
42
* located at @base in the memory map.
56
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
43
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
57
cpu->isar.id_isar6 = u;
44
exit(EXIT_FAILURE);
58
59
- u = cpu->isar.mvfr1;
60
- u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
61
- u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
62
- u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
63
- u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
64
- cpu->isar.mvfr1 = u;
65
+ if (!arm_feature(env, ARM_FEATURE_M)) {
66
+ u = cpu->isar.mvfr1;
67
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
68
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
69
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
70
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
71
+ cpu->isar.mvfr1 = u;
72
73
- u = cpu->isar.mvfr2;
74
- u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
75
- cpu->isar.mvfr2 = u;
76
+ u = cpu->isar.mvfr2;
77
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
78
+ cpu->isar.mvfr2 = u;
79
+ }
80
}
45
}
81
46
82
if (!cpu->has_neon && !cpu->has_vfp) {
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
/*
83
--
65
--
84
2.20.1
66
2.20.1
85
67
86
68
diff view generated by jsdifflib
1
From: Peng Liang <liangpeng10@huawei.com>
1
Create and connect the two clocks needed by the ARMSSE.
2
2
3
VMStateDescription.fields should be end with VMSTATE_END_OF_LIST().
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
However, microbit_i2c_vmstate doesn't follow it. Let's change it.
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
9
---
10
hw/arm/musca.c | 12 ++++++++++++
11
1 file changed, 12 insertions(+)
5
12
6
Fixes: 9d68bf564e ("arm: Stub out NRF51 TWI magnetometer/accelerometer detection")
13
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
7
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20201019093401.2993833-1-liangpeng10@huawei.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/i2c/microbit_i2c.c | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/hw/i2c/microbit_i2c.c b/hw/i2c/microbit_i2c.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/i2c/microbit_i2c.c
15
--- a/hw/arm/musca.c
19
+++ b/hw/i2c/microbit_i2c.c
16
+++ b/hw/arm/musca.c
20
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription microbit_i2c_vmstate = {
17
@@ -XXX,XX +XXX,XX @@
21
.fields = (VMStateField[]) {
18
#include "hw/misc/tz-ppc.h"
22
VMSTATE_UINT32_ARRAY(regs, MicrobitI2CState, MICROBIT_I2C_NREGS),
19
#include "hw/misc/unimp.h"
23
VMSTATE_UINT32(read_idx, MicrobitI2CState),
20
#include "hw/rtc/pl031.h"
24
+ VMSTATE_END_OF_LIST()
21
+#include "hw/qdev-clock.h"
25
},
22
#include "qom/object.h"
23
24
#define MUSCA_NUMIRQ_MAX 96
25
@@ -XXX,XX +XXX,XX @@ struct MuscaMachineState {
26
UnimplementedDeviceState sdio;
27
UnimplementedDeviceState gpio;
28
UnimplementedDeviceState cryptoisland;
29
+ Clock *sysclk;
30
+ Clock *s32kclk;
26
};
31
};
27
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);
51
+
52
object_initialize_child(OBJECT(machine), "sse-200", &mms->sse,
53
TYPE_SSE200);
54
ssedev = DEVICE(&mms->sse);
55
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
56
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
57
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
58
qdev_prop_set_uint32(ssedev, "MAINCLK_FRQ", SYSCLK_FRQ);
59
+ qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
60
+ qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
61
/*
62
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
63
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
28
--
64
--
29
2.20.1
65
2.20.1
30
66
31
67
diff view generated by jsdifflib
1
From v8.1M, disabled-coprocessor handling changes slightly:
1
Convert the SSYS code in the Stellaris boards (which encapsulates the
2
* coprocessors 8, 9, 14 and 15 are also governed by the
2
system registers) to a proper QOM device. This will provide us with
3
cp10 enable bit, like cp11
3
somewhere to put the output Clock whose frequency depends on the
4
* an extra range of instruction patterns is considered
4
setting of the PLL configuration registers.
5
to be inside the coprocessor space
5
6
6
This is a migration compatibility break for lm3s811evb, lm3s6965evb.
7
We previously marked these up with TODO comments; implement the
7
8
correct behaviour.
8
We use 3-phase reset here because the Clock will need to propagate
9
9
its value in the hold phase.
10
Unfortunately there is no ID register field which indicates this
10
11
behaviour. We could in theory test an unrelated ID register which
11
For the moment we reset the device during the board creation so that
12
indicates guaranteed-to-be-in-v8.1M behaviour like ID_ISAR0.CmpBranch
12
the system_clock_scale global gets set; this will be removed in a
13
>= 3 (low-overhead-loops), but it seems better to simply define a new
13
subsequent commit.
14
ARM_FEATURE_V8_1M feature flag and use it for this and other
15
new-in-v8.1M behaviour that isn't identifiable from the ID registers.
16
14
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
Message-id: 20201019151301.2046-3-peter.maydell@linaro.org
17
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20210128114145.20536-17-peter.maydell@linaro.org
20
Message-id: 20210121190622.22000-17-peter.maydell@linaro.org
21
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
---
22
---
21
target/arm/cpu.h | 1 +
23
hw/arm/stellaris.c | 132 ++++++++++++++++++++++++++++++++++++---------
22
target/arm/m-nocp.decode | 10 ++++++----
24
1 file changed, 107 insertions(+), 25 deletions(-)
23
target/arm/translate-vfp.c.inc | 17 +++++++++++++++--
25
24
3 files changed, 22 insertions(+), 6 deletions(-)
26
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
25
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
28
--- a/hw/arm/stellaris.c
29
+++ b/target/arm/cpu.h
29
+++ b/hw/arm/stellaris.c
30
@@ -XXX,XX +XXX,XX @@ enum arm_features {
30
@@ -XXX,XX +XXX,XX @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
31
ARM_FEATURE_VBAR, /* has cp15 VBAR */
31
32
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
32
/* System controller. */
33
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
33
34
+ ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
34
-typedef struct {
35
+#define TYPE_STELLARIS_SYS "stellaris-sys"
36
+OBJECT_DECLARE_SIMPLE_TYPE(ssys_state, STELLARIS_SYS)
37
+
38
+struct ssys_state {
39
+ SysBusDevice parent_obj;
40
+
41
MemoryRegion iomem;
42
uint32_t pborctl;
43
uint32_t ldopctl;
44
@@ -XXX,XX +XXX,XX @@ typedef struct {
45
uint32_t dcgc[3];
46
uint32_t clkvclr;
47
uint32_t ldoarst;
48
+ qemu_irq irq;
49
+ /* Properties (all read-only registers) */
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,
35
};
104
};
36
105
37
static inline int arm_feature(CPUARMState *env, int feature)
106
-static void ssys_reset(void *opaque)
38
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
107
+static void stellaris_sys_reset_enter(Object *obj, ResetType type)
39
index XXXXXXX..XXXXXXX 100644
108
{
40
--- a/target/arm/m-nocp.decode
109
- ssys_state *s = (ssys_state *)opaque;
41
+++ b/target/arm/m-nocp.decode
110
+ ssys_state *s = STELLARIS_SYS(obj);
42
@@ -XXX,XX +XXX,XX @@
111
43
# If the coprocessor is not present or disabled then we will generate
112
s->pborctl = 0x7ffd;
44
# the NOCP exception; otherwise we let the insn through to the main decode.
113
s->rcc = 0x078e3ac0;
45
114
@@ -XXX,XX +XXX,XX @@ static void ssys_reset(void *opaque)
46
+&nocp cp
115
s->rcgc[0] = 1;
47
+
116
s->scgc[0] = 1;
48
{
117
s->dcgc[0] = 1;
49
# Special cases which do not take an early NOCP: VLLDM and VLSTM
118
+}
50
VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
119
+
51
# TODO: VSCCLRM (new in v8.1M) is similar:
120
+static void stellaris_sys_reset_hold(Object *obj)
52
#VSCCLRM 1110 1100 1-01 1111 ---- 1011 ---- ---0
121
+{
53
122
+ ssys_state *s = STELLARIS_SYS(obj);
54
- NOCP 111- 1110 ---- ---- ---- cp:4 ---- ----
123
+
55
- NOCP 111- 110- ---- ---- ---- cp:4 ---- ----
124
ssys_calculate_system_clock(s);
56
- # TODO: From v8.1M onwards we will also want this range to NOCP
57
- #NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- cp=10
58
+ NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
59
+ NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
60
+ # From v8.1M onwards this range will also NOCP:
61
+ NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- &nocp cp=10
62
}
125
}
63
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
126
64
index XXXXXXX..XXXXXXX 100644
127
+static void stellaris_sys_reset_exit(Object *obj)
65
--- a/target/arm/translate-vfp.c.inc
128
+{
66
+++ b/target/arm/translate-vfp.c.inc
129
+}
67
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
130
+
68
return true;
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
}
136
};
137
138
+static Property stellaris_sys_properties[] = {
139
+ DEFINE_PROP_UINT32("user0", ssys_state, user0, 0),
140
+ DEFINE_PROP_UINT32("user1", ssys_state, user1, 0),
141
+ DEFINE_PROP_UINT32("did0", ssys_state, did0, 0),
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;
69
}
206
}
70
207
71
-static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
208
-
72
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
209
/* I2C controller. */
73
{
210
74
/*
211
#define TYPE_STELLARIS_I2C "stellaris-i2c"
75
* Handle M-profile early check for disabled coprocessor:
212
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_adc_info = {
76
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
213
.class_init = stellaris_adc_class_init,
77
if (a->cp == 11) {
214
};
78
a->cp = 10;
215
79
}
216
+static void stellaris_sys_class_init(ObjectClass *klass, void *data)
80
- /* TODO: in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
217
+{
81
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
218
+ DeviceClass *dc = DEVICE_CLASS(klass);
82
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
219
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
83
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
220
+
84
+ a->cp = 10;
221
+ dc->vmsd = &vmstate_stellaris_sys;
85
+ }
222
+ rc->phases.enter = stellaris_sys_reset_enter;
86
223
+ rc->phases.hold = stellaris_sys_reset_hold;
87
if (a->cp != 10) {
224
+ rc->phases.exit = stellaris_sys_reset_exit;
88
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
225
+ device_class_set_props(dc, stellaris_sys_properties);
89
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
226
+}
90
return false;
227
+
228
+static const TypeInfo stellaris_sys_info = {
229
+ .name = TYPE_STELLARIS_SYS,
230
+ .parent = TYPE_SYS_BUS_DEVICE,
231
+ .instance_size = sizeof(ssys_state),
232
+ .instance_init = stellaris_sys_instance_init,
233
+ .class_init = stellaris_sys_class_init,
234
+};
235
+
236
static void stellaris_register_types(void)
237
{
238
type_register_static(&stellaris_i2c_info);
239
type_register_static(&stellaris_gptm_info);
240
type_register_static(&stellaris_adc_info);
241
+ type_register_static(&stellaris_sys_info);
91
}
242
}
92
243
93
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
244
type_init(stellaris_register_types)
94
+{
95
+ /* This range needs a coprocessor check for v8.1M and later only */
96
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
97
+ return false;
98
+ }
99
+ return trans_NOCP(s, a);
100
+}
101
+
102
static bool trans_VINS(DisasContext *s, arg_VINS *a)
103
{
104
TCGv_i32 rd, rm;
105
--
245
--
106
2.20.1
246
2.20.1
107
247
108
248
diff view generated by jsdifflib
1
v8.1M's "low-overhead-loop" extension has three instructions
1
Create and connect the Clock input for the watchdog device on the
2
for looping:
2
Stellaris boards. Because the Stellaris boards model the ability to
3
* DLS (start of a do-loop)
3
change the clock rate by programming PLL registers, we have to create
4
* WLS (start of a while-loop)
4
an output Clock on the ssys_state device and wire it up to the
5
* LE (end of a loop)
5
watchdog.
6
6
7
The loop-start instructions are both simple operations to start a
7
Note that the old comment on ssys_calculate_system_clock() got the
8
loop whose iteration count (if any) is in LR. The loop-end
8
units wrong -- system_clock_scale is in nanoseconds, not
9
instruction handles "decrement iteration count and jump back to loop
9
milliseconds. Improve the commentary to clarify how we are
10
start"; it also caches the information about the branch back to the
10
calculating the period.
11
start of the loop to improve performance of the branch on subsequent
12
iterations.
13
14
As with the branch-future instructions, the architecture permits an
15
implementation to discard the LO_BRANCH_INFO cache at any time, and
16
QEMU takes the IMPDEF option to never set it in the first place
17
(equivalent to discarding it immediately), because for us a "real"
18
implementation would be unnecessary complexity.
19
20
(This implementation only provides the simple looping constructs; the
21
vector extension MVE (Helium) adds some extra variants to handle
22
looping across vectors. We'll add those later when we implement
23
MVE.)
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: 20201019151301.2046-8-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/t32.decode | 8 ++++
20
hw/arm/stellaris.c | 43 +++++++++++++++++++++++++++++++------------
30
target/arm/translate.c | 93 +++++++++++++++++++++++++++++++++++++++++-
21
1 file changed, 31 insertions(+), 12 deletions(-)
31
2 files changed, 99 insertions(+), 2 deletions(-)
32
22
33
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
23
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
34
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/t32.decode
25
--- a/hw/arm/stellaris.c
36
+++ b/target/arm/t32.decode
26
+++ b/hw/arm/stellaris.c
37
@@ -XXX,XX +XXX,XX @@ BL 1111 0. .......... 11.1 ............ @branch24
27
@@ -XXX,XX +XXX,XX @@
38
BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
28
#include "hw/watchdog/cmsdk-apb-watchdog.h"
39
BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
29
#include "migration/vmstate.h"
40
]
30
#include "hw/misc/unimp.h"
41
+ [
31
+#include "hw/qdev-clock.h"
42
+ # LE and WLS immediate
32
#include "cpu.h"
43
+ %lob_imm 1:10 11:1 !function=times_2
33
#include "qom/object.h"
44
+
34
45
+ DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001
35
@@ -XXX,XX +XXX,XX @@ struct ssys_state {
46
+ WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm
36
uint32_t clkvclr;
47
+ LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
37
uint32_t ldoarst;
48
+ ]
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)
49
}
44
}
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
51
index XXXXXXX..XXXXXXX 100644
46
/*
52
--- a/target/arm/translate.c
47
- * Caculate the sys. clock period in ms.
53
+++ b/target/arm/translate.c
48
+ * Calculate the system clock period. We only want to propagate
54
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
49
+ * this change to the rest of the system if we're not being called
55
s->base.is_jmp = DISAS_NORETURN;
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)
54
{
55
+ /*
56
+ * SYSDIV field specifies divisor: 0 == /1, 1 == /2, etc. Input
57
+ * clock is 200MHz, which is a period of 5 ns. Dividing the clock
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
+ }
56
}
69
}
57
70
58
-static inline void gen_jmp (DisasContext *s, uint32_t dest)
71
static void ssys_write(void *opaque, hwaddr offset,
59
+/* Jump, specifying which TB number to use if we gen_goto_tb() */
72
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
60
+static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
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)
61
{
91
{
62
if (unlikely(is_singlestepping(s))) {
92
ssys_state *s = STELLARIS_SYS(obj);
63
/* An indirect jump so that we still trigger the debug exception. */
93
64
gen_set_pc_im(s, dest);
94
- ssys_calculate_system_clock(s);
65
s->base.is_jmp = DISAS_JUMP;
95
+ /* OK to propagate clocks from the hold phase */
66
} else {
96
+ ssys_calculate_system_clock(s, true);
67
- gen_goto_tb(s, 0, dest);
97
}
68
+ gen_goto_tb(s, tbno, dest);
98
99
static void stellaris_sys_reset_exit(Object *obj)
100
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_post_load(void *opaque, int version_id)
101
{
102
ssys_state *s = opaque;
103
104
- ssys_calculate_system_clock(s);
105
+ ssys_calculate_system_clock(s, false);
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()
69
}
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");
70
}
122
}
71
123
72
+static inline void gen_jmp(DisasContext *s, uint32_t dest)
124
-static int stellaris_sys_init(uint32_t base, qemu_irq irq,
73
+{
125
- stellaris_board_info * board,
74
+ gen_jmp_tb(s, dest, 0);
126
- uint8_t *macaddr)
75
+}
127
+static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
76
+
128
+ stellaris_board_info *board,
77
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
129
+ uint8_t *macaddr)
78
{
130
{
79
if (x)
131
DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
80
@@ -XXX,XX +XXX,XX @@ static bool trans_BF(DisasContext *s, arg_BF *a)
132
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
81
return true;
133
@@ -XXX,XX +XXX,XX @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
134
*/
135
device_cold_reset(dev);
136
137
- return 0;
138
+ return dev;
82
}
139
}
83
140
84
+static bool trans_DLS(DisasContext *s, arg_DLS *a)
141
/* I2C controller. */
85
+{
142
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
86
+ /* M-profile low-overhead loop start */
143
int flash_size;
87
+ TCGv_i32 tmp;
144
I2CBus *i2c;
88
+
145
DeviceState *dev;
89
+ if (!dc_isar_feature(aa32_lob, s)) {
146
+ DeviceState *ssys_dev;
90
+ return false;
147
int i;
91
+ }
148
int j;
92
+ if (a->rn == 13 || a->rn == 15) {
149
93
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
150
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
94
+ return false;
151
}
95
+ }
152
}
96
+
153
97
+ /* Not a while loop, no tail predication: just set LR to the count */
154
- stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
98
+ tmp = load_reg(s, a->rn);
155
- board, nd_table[0].macaddr.a);
99
+ store_reg(s, 14, tmp);
156
+ ssys_dev = stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
100
+ return true;
157
+ board, nd_table[0].macaddr.a);
101
+}
158
102
+
159
103
+static bool trans_WLS(DisasContext *s, arg_WLS *a)
160
if (board->dc1 & (1 << 3)) { /* watchdog present */
104
+{
161
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
105
+ /* M-profile low-overhead while-loop start */
162
/* system_clock_scale is valid now */
106
+ TCGv_i32 tmp;
163
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
107
+ TCGLabel *nextlabel;
164
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
108
+
165
+ qdev_connect_clock_in(dev, "WDOGCLK",
109
+ if (!dc_isar_feature(aa32_lob, s)) {
166
+ qdev_get_clock_out(ssys_dev, "SYSCLK"));
110
+ return false;
167
111
+ }
168
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
112
+ if (a->rn == 13 || a->rn == 15) {
169
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
113
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
114
+ return false;
115
+ }
116
+ if (s->condexec_mask) {
117
+ /*
118
+ * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
119
+ * we choose to UNDEF, because otherwise our use of
120
+ * gen_goto_tb(1) would clash with the use of TB exit 1
121
+ * in the dc->condjmp condition-failed codepath in
122
+ * arm_tr_tb_stop() and we'd get an assertion.
123
+ */
124
+ return false;
125
+ }
126
+ nextlabel = gen_new_label();
127
+ tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
128
+ tmp = load_reg(s, a->rn);
129
+ store_reg(s, 14, tmp);
130
+ gen_jmp_tb(s, s->base.pc_next, 1);
131
+
132
+ gen_set_label(nextlabel);
133
+ gen_jmp(s, read_pc(s) + a->imm);
134
+ return true;
135
+}
136
+
137
+static bool trans_LE(DisasContext *s, arg_LE *a)
138
+{
139
+ /*
140
+ * M-profile low-overhead loop end. The architecture permits an
141
+ * implementation to discard the LO_BRANCH_INFO cache at any time,
142
+ * and we take the IMPDEF option to never set it in the first place
143
+ * (equivalent to always discarding it immediately), because for QEMU
144
+ * a "real" implementation would be complicated and wouldn't execute
145
+ * any faster.
146
+ */
147
+ TCGv_i32 tmp;
148
+
149
+ if (!dc_isar_feature(aa32_lob, s)) {
150
+ return false;
151
+ }
152
+
153
+ if (!a->f) {
154
+ /* Not loop-forever. If LR <= 1 this is the last loop: do nothing. */
155
+ arm_gen_condlabel(s);
156
+ tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, s->condlabel);
157
+ /* Decrement LR */
158
+ tmp = load_reg(s, 14);
159
+ tcg_gen_addi_i32(tmp, tmp, -1);
160
+ store_reg(s, 14, tmp);
161
+ }
162
+ /* Jump back to the loop start */
163
+ gen_jmp(s, read_pc(s) - a->imm);
164
+ return true;
165
+}
166
+
167
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
168
{
169
TCGv_i32 addr, tmp;
170
--
170
--
171
2.20.1
171
2.20.1
172
172
173
173
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Switch the CMSDK APB timer device over to using its Clock input; the
2
pclk-frq property is now ignored.
2
3
3
This is slightly clearer than just using strerror, though
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the different forms produced by error_setg_file_open and
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
error_setg_errno isn't entirely convenient.
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
10
---
11
hw/timer/cmsdk-apb-timer.c | 18 ++++++++++++++----
12
1 file changed, 14 insertions(+), 4 deletions(-)
6
13
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201016184207.786698-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
linux-user/elfload.c | 15 ++++++++-------
13
1 file changed, 8 insertions(+), 7 deletions(-)
14
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
16
--- a/hw/timer/cmsdk-apb-timer.c
18
+++ b/linux-user/elfload.c
17
+++ b/hw/timer/cmsdk-apb-timer.c
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_interp(const char *filename, struct image_info *info,
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
20
char bprm_buf[BPRM_BUF_SIZE])
19
ptimer_transaction_commit(s->timer);
20
}
21
22
+static void cmsdk_apb_timer_clk_update(void *opaque)
23
+{
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)
21
{
32
{
22
int fd, retval;
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
23
+ Error *err = NULL;
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_init(Object *obj)
24
35
s, "cmsdk-apb-timer", 0x1000);
25
fd = open(path(filename), O_RDONLY);
36
sysbus_init_mmio(sbd, &s->iomem);
26
if (fd < 0) {
37
sysbus_init_irq(sbd, &s->timerint);
27
- goto exit_perror;
38
- s->pclk = qdev_init_clock_in(DEVICE(s), "pclk", NULL, NULL);
28
+ error_setg_file_open(&err, errno, filename);
39
+ s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
29
+ error_report_err(err);
40
+ cmsdk_apb_timer_clk_update, s);
30
+ exit(-1);
41
}
42
43
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
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");
51
return;
31
}
52
}
32
53
33
retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
54
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
34
if (retval < 0) {
55
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
35
- goto exit_perror;
56
36
+ error_setg_errno(&err, errno, "Error reading file header");
57
ptimer_transaction_begin(s->timer);
37
+ error_reportf_err(err, "%s: ", filename);
58
- ptimer_set_freq(s->timer, s->pclk_frq);
38
+ exit(-1);
59
+ ptimer_set_period_from_clock(s->timer, s->pclk, 1);
39
}
60
ptimer_transaction_commit(s->timer);
40
+
41
if (retval < BPRM_BUF_SIZE) {
42
memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
43
}
44
45
load_elf_image(filename, fd, info, NULL, bprm_buf);
46
- return;
47
-
48
- exit_perror:
49
- fprintf(stderr, "%s: %s\n", filename, strerror(errno));
50
- exit(-1);
51
}
61
}
52
62
53
static int symfind(const void *s0, const void *s1)
54
--
63
--
55
2.20.1
64
2.20.1
56
65
57
66
diff view generated by jsdifflib
1
v8.1M brings four new insns to M-profile:
1
Switch the CMSDK APB dualtimer device over to using its Clock input;
2
* CSEL : Rd = cond ? Rn : Rm
2
the pclk-frq property is now ignored.
3
* CSINC : Rd = cond ? Rn : Rm+1
4
* CSINV : Rd = cond ? Rn : ~Rm
5
* CSNEG : Rd = cond ? Rn : -Rm
6
3
7
Implement these.
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-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(-)
8
14
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-4-peter.maydell@linaro.org
12
---
13
target/arm/t32.decode | 3 +++
14
target/arm/translate.c | 60 ++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 63 insertions(+)
16
17
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/t32.decode
17
--- a/hw/timer/cmsdk-apb-dualtimer.c
20
+++ b/target/arm/t32.decode
18
+++ b/hw/timer/cmsdk-apb-dualtimer.c
21
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
19
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s)
20
qemu_set_irq(s->timerintc, timintc);
22
}
21
}
23
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
22
24
23
+static int cmsdk_dualtimermod_divisor(CMSDKAPBDualTimerModule *m)
25
+# v8.1M CSEL and friends
26
+CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
27
+
28
# Data-processing (register-shifted register)
29
30
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
31
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.c
34
+++ b/target/arm/translate.c
35
@@ -XXX,XX +XXX,XX @@ static bool trans_IT(DisasContext *s, arg_IT *a)
36
return true;
37
}
38
39
+/* v8.1M CSEL/CSINC/CSNEG/CSINV */
40
+static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
41
+{
24
+{
42
+ TCGv_i32 rn, rm, zero;
25
+ /* Return the divisor set by the current CONTROL.PRESCALE value */
43
+ DisasCompare c;
26
+ switch (FIELD_EX32(m->control, CONTROL, PRESCALE)) {
44
+
27
+ case 0:
45
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
28
+ return 1;
46
+ return false;
29
+ case 1:
47
+ }
30
+ return 16;
48
+
31
+ case 2:
49
+ if (a->rm == 13) {
32
+ case 3: /* UNDEFINED, we treat like 2 (and complained when it was set) */
50
+ /* SEE "Related encodings" (MVE shifts) */
33
+ return 256;
51
+ return false;
52
+ }
53
+
54
+ if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
55
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
56
+ return false;
57
+ }
58
+
59
+ /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
60
+ if (a->rn == 15) {
61
+ rn = tcg_const_i32(0);
62
+ } else {
63
+ rn = load_reg(s, a->rn);
64
+ }
65
+ if (a->rm == 15) {
66
+ rm = tcg_const_i32(0);
67
+ } else {
68
+ rm = load_reg(s, a->rm);
69
+ }
70
+
71
+ switch (a->op) {
72
+ case 0: /* CSEL */
73
+ break;
74
+ case 1: /* CSINC */
75
+ tcg_gen_addi_i32(rm, rm, 1);
76
+ break;
77
+ case 2: /* CSINV */
78
+ tcg_gen_not_i32(rm, rm);
79
+ break;
80
+ case 3: /* CSNEG */
81
+ tcg_gen_neg_i32(rm, rm);
82
+ break;
83
+ default:
34
+ default:
84
+ g_assert_not_reached();
35
+ g_assert_not_reached();
85
+ }
36
+ }
86
+
87
+ arm_test_cc(&c, a->fcond);
88
+ zero = tcg_const_i32(0);
89
+ tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
90
+ arm_free_cc(&c);
91
+ tcg_temp_free_i32(zero);
92
+
93
+ store_reg(s, a->rd, rn);
94
+ tcg_temp_free_i32(rm);
95
+
96
+ return true;
97
+}
37
+}
98
+
38
+
99
/*
39
static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
100
* Legacy decoder.
40
uint32_t newctrl)
101
*/
41
{
42
@@ -XXX,XX +XXX,XX @@ static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m,
43
default:
44
g_assert_not_reached();
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)
66
+{
67
+ CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
68
+ int i;
69
+
70
+ for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
71
+ CMSDKAPBDualTimerModule *m = &s->timermod[i];
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);
76
+ }
77
+}
78
+
79
static void cmsdk_apb_dualtimer_init(Object *obj)
80
{
81
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
82
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_init(Object *obj)
83
for (i = 0; i < ARRAY_SIZE(s->timermod); i++) {
84
sysbus_init_irq(sbd, &s->timermod[i].timerint);
85
}
86
- s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK", NULL, NULL);
87
+ s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
88
+ cmsdk_apb_dualtimer_clk_update, s);
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
}
102
102
--
103
--
103
2.20.1
104
2.20.1
104
105
105
106
diff view generated by jsdifflib
1
The t32 decode has a group which represents a set of insns
1
Switch the CMSDK APB watchdog device over to using its Clock input;
2
which overlap with B_cond_thumb because they have [25:23]=111
2
the wdogclk_frq property is now ignored.
3
(which is an invalid condition code field for the branch insn).
4
This group is currently defined using the {} overlap-OK syntax,
5
but it is almost entirely non-overlapping patterns. Switch
6
it over to use a non-overlapping group.
7
3
8
For this to be valid syntactically, CPS must move into the same
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
overlapping-group as the hint insns (CPS vs hints was the
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
only actual use of the overlap facility for the group).
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
10
---
11
hw/watchdog/cmsdk-apb-watchdog.c | 18 ++++++++++++++----
12
1 file changed, 14 insertions(+), 4 deletions(-)
11
13
12
The non-overlapping subgroup for CLREX/DSB/DMB/ISB/SB is no longer
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
13
necessary and so we can remove it (promoting those insns to
14
be members of the parent group).
15
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20201019151301.2046-5-peter.maydell@linaro.org
19
---
20
target/arm/t32.decode | 26 ++++++++++++--------------
21
1 file changed, 12 insertions(+), 14 deletions(-)
22
23
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/t32.decode
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
26
+++ b/target/arm/t32.decode
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
27
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
19
ptimer_transaction_commit(s->timer);
20
}
21
22
+static void cmsdk_apb_watchdog_clk_update(void *opaque)
23
+{
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)
28
{
32
{
29
# Group insn[25:23] = 111, which is cond=111x for the branch below,
33
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
30
# or unconditional, which would be illegal for the branch.
34
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
31
- {
35
s, "cmsdk-apb-watchdog", 0x1000);
32
- # Hints
36
sysbus_init_mmio(sbd, &s->iomem);
33
+ [
37
sysbus_init_irq(sbd, &s->wdogint);
34
+ # Hints, and CPS
38
- s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK", NULL, NULL);
35
{
39
+ s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
36
YIELD 1111 0011 1010 1111 1000 0000 0000 0001
40
+ cmsdk_apb_watchdog_clk_update, s);
37
WFE 1111 0011 1010 1111 1000 0000 0000 0010
41
38
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
42
s->is_luminary = false;
39
# The canonical nop ends in 0000 0000, but the whole rest
43
s->id = cmsdk_apb_watchdog_id;
40
# of the space is "reserved hint, behaves as nop".
44
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
41
NOP 1111 0011 1010 1111 1000 0000 ---- ----
45
{
42
+
46
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
43
+ # If imod == '00' && M == '0' then SEE "Hint instructions", above.
47
44
+ CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
48
- if (s->wdogclk_frq == 0) {
45
+ &cps
49
+ if (!clock_has_source(s->wdogclk)) {
50
error_setg(errp,
51
- "CMSDK APB watchdog: wdogclk-frq property must be set");
52
+ "CMSDK APB watchdog: WDOGCLK clock must be connected");
53
return;
46
}
54
}
47
55
48
- # If imod == '00' && M == '0' then SEE "Hint instructions", above.
56
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
49
- CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
57
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
50
- &cps
58
51
-
59
ptimer_transaction_begin(s->timer);
52
# Miscellaneous control
60
- ptimer_set_freq(s->timer, s->wdogclk_frq);
53
- [
61
+ ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
54
- CLREX 1111 0011 1011 1111 1000 1111 0010 1111
62
ptimer_transaction_commit(s->timer);
55
- DSB 1111 0011 1011 1111 1000 1111 0100 ----
56
- DMB 1111 0011 1011 1111 1000 1111 0101 ----
57
- ISB 1111 0011 1011 1111 1000 1111 0110 ----
58
- SB 1111 0011 1011 1111 1000 1111 0111 0000
59
- ]
60
+ CLREX 1111 0011 1011 1111 1000 1111 0010 1111
61
+ DSB 1111 0011 1011 1111 1000 1111 0100 ----
62
+ DMB 1111 0011 1011 1111 1000 1111 0101 ----
63
+ ISB 1111 0011 1011 1111 1000 1111 0110 ----
64
+ SB 1111 0011 1011 1111 1000 1111 0111 0000
65
66
# Note that the v7m insn overlaps both the normal and banked insn.
67
{
68
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
69
HVC 1111 0111 1110 .... 1000 .... .... .... \
70
&i imm=%imm16_16_0
71
UDF 1111 0111 1111 ---- 1010 ---- ---- ----
72
- }
73
+ ]
74
B_cond_thumb 1111 0. cond:4 ...... 10.0 ............ &ci imm=%imm21
75
}
63
}
76
64
77
--
65
--
78
2.20.1
66
2.20.1
79
67
80
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Now that the CMSDK APB watchdog uses its Clock input, it will
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.
2
6
3
The reporting in AArch64.TagCheckFail only depends on PSTATE.EL,
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and not the AccType of the operation. There are two guest
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
visible problems that affect LDTR and STTR because of this:
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
13
---
14
tests/qtest/cmsdk-apb-watchdog-test.c | 52 +++++++++++++++++++++++++++
15
1 file changed, 52 insertions(+)
6
16
7
(1) Selecting TCF0 vs TCF1 to decide on reporting,
17
diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c b/tests/qtest/cmsdk-apb-watchdog-test.c
8
(2) Report "data abort same el" not "data abort lower el".
9
10
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
13
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Message-id: 20201008162155.161886-3-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/mte_helper.c | 10 +++-------
18
1 file changed, 3 insertions(+), 7 deletions(-)
19
20
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/mte_helper.c
19
--- a/tests/qtest/cmsdk-apb-watchdog-test.c
23
+++ b/target/arm/mte_helper.c
20
+++ b/tests/qtest/cmsdk-apb-watchdog-test.c
24
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
21
@@ -XXX,XX +XXX,XX @@
25
reg_el = regime_el(env, arm_mmu_idx);
22
*/
26
sctlr = env->cp15.sctlr_el[reg_el];
23
27
24
#include "qemu/osdep.h"
28
- switch (arm_mmu_idx) {
25
+#include "qemu/bitops.h"
29
- case ARMMMUIdx_E10_0:
26
#include "libqtest-single.h"
30
- case ARMMMUIdx_E20_0:
27
31
- el = 0;
28
/*
32
+ el = arm_current_el(env);
29
@@ -XXX,XX +XXX,XX @@
33
+ if (el == 0) {
30
#define WDOGMIS 0x14
34
tcf = extract64(sctlr, 38, 2);
31
#define WDOGLOCK 0xc00
35
- break;
32
36
- default:
33
+#define SSYS_BASE 0x400fe000
37
- el = reg_el;
34
+#define RCC 0x60
38
+ } else {
35
+#define SYSDIV_SHIFT 23
39
tcf = extract64(sctlr, 40, 2);
36
+#define SYSDIV_LENGTH 4
40
}
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);
43
}
44
45
+static void test_clock_change(void)
46
+{
47
+ uint32_t rcc;
48
+
49
+ /*
50
+ * Test that writing to the stellaris board's RCC register to
51
+ * change the system clock frequency causes the watchdog
52
+ * to change the speed it counts at.
53
+ */
54
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
55
+
56
+ writel(WDOG_BASE + WDOGCONTROL, 1);
57
+ writel(WDOG_BASE + WDOGLOAD, 1000);
58
+
59
+ /* Step to just past the 500th tick */
60
+ clock_step(80 * 500 + 1);
61
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
62
+ g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
63
+
64
+ /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */
65
+ rcc = readl(SSYS_BASE + RCC);
66
+ g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf);
67
+ rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7);
68
+ writel(SSYS_BASE + RCC, rcc);
69
+
70
+ /* Just past the 1000th tick: timer should have fired */
71
+ clock_step(40 * 500);
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);
87
+}
88
+
89
int main(int argc, char **argv)
90
{
91
int r;
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
93
qtest_start("-machine lm3s811evb");
94
95
qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
96
+ qtest_add_func("/cmsdk-apb-watchdog/watchdog_clock_change",
97
+ test_clock_change);
98
99
r = g_test_run();
41
100
42
--
101
--
43
2.20.1
102
2.20.1
44
103
45
104
diff view generated by jsdifflib
1
v8.1M implements a new 'branch future' feature, which is a
1
Use the MAINCLK Clock input to set the system_clock_scale variable
2
set of instructions that request the CPU to perform a branch
2
rather than using the mainclk_frq property.
3
"in the future", when it reaches a particular execution address.
4
In hardware, the expected implementation is that the information
5
about the branch location and destination is cached and then
6
acted upon when execution reaches the specified address.
7
However the architecture permits an implementation to discard
8
this cached information at any point, and so guest code must
9
always include a normal branch insn at the branch point as
10
a fallback. In particular, an implementation is specifically
11
permitted to treat all BF insns as NOPs (which is equivalent
12
to discarding the cached information immediately).
13
3
14
For QEMU, implementing this caching of branch information
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
would be complicated and would not improve the speed of
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
execution at all, so we make the IMPDEF choice to implement
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
all BF insns as NOPs.
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
10
---
11
hw/arm/armsse.c | 24 +++++++++++++++++++-----
12
1 file changed, 19 insertions(+), 5 deletions(-)
18
13
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20201019151301.2046-7-peter.maydell@linaro.org
22
---
23
target/arm/cpu.h | 6 ++++++
24
target/arm/t32.decode | 13 ++++++++++++-
25
target/arm/translate.c | 20 ++++++++++++++++++++
26
3 files changed, 38 insertions(+), 1 deletion(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
16
--- a/hw/arm/armsse.c
31
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/armsse.c
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
33
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
19
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
34
}
20
}
35
21
36
+static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
22
+static void armsse_mainclk_update(void *opaque)
37
+{
23
+{
38
+ /* (M-profile) low-overhead loops and branch future */
24
+ ARMSSE *s = ARM_SSE(opaque);
39
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
25
+ /*
26
+ * Set system_clock_scale from our Clock input; this is what
27
+ * controls the tick rate of the CPU SysTick timer.
28
+ */
29
+ system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
40
+}
30
+}
41
+
31
+
42
static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
32
static void armsse_init(Object *obj)
43
{
33
{
44
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
34
ARMSSE *s = ARM_SSE(obj);
45
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
35
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
46
index XXXXXXX..XXXXXXX 100644
36
assert(info->sram_banks <= MAX_SRAM_BANKS);
47
--- a/target/arm/t32.decode
37
assert(info->num_cpus <= SSE_MAX_CPUS);
48
+++ b/target/arm/t32.decode
38
49
@@ -XXX,XX +XXX,XX @@ MRC 1110 1110 ... 1 .... .... .... ... 1 .... @mcr
39
- s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL);
50
40
+ s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
51
B 1111 0. .......... 10.1 ............ @branch24
41
+ armsse_mainclk_update, s);
52
BL 1111 0. .......... 11.1 ............ @branch24
42
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
53
-BLX_i 1111 0. .......... 11.0 ............ @branch24
43
54
+{
44
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
55
+ # BLX_i is non-M-profile only
45
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
56
+ BLX_i 1111 0. .......... 11.0 ............ @branch24
46
return;
57
+ # M-profile only: loop and branch insns
47
}
58
+ [
48
59
+ # All these BF insns have boff != 0b0000; we NOP them all
49
- if (!s->mainclk_frq) {
60
+ BF 1111 0 boff:4 ------- 1100 - ---------- 1 # BFL
50
- error_setg(errp, "MAINCLK_FRQ property was not set");
61
+ BF 1111 0 boff:4 0 ------ 1110 - ---------- 1 # BFCSEL
51
- return;
62
+ BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
52
+ if (!clock_has_source(s->mainclk)) {
63
+ BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
53
+ error_setg(errp, "MAINCLK clock was not connected");
64
+ ]
54
+ }
65
+}
55
+ if (!clock_has_source(s->s32kclk)) {
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
56
+ error_setg(errp, "S32KCLK clock was not connected");
67
index XXXXXXX..XXXXXXX 100644
57
}
68
--- a/target/arm/translate.c
58
69
+++ b/target/arm/translate.c
59
assert(info->num_cpus <= SSE_MAX_CPUS);
70
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
60
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
return true;
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);
72
}
67
}
73
68
74
+static bool trans_BF(DisasContext *s, arg_BF *a)
69
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
75
+{
76
+ /*
77
+ * M-profile branch future insns. The architecture permits an
78
+ * implementation to implement these as NOPs (equivalent to
79
+ * discarding the LO_BRANCH_INFO cache immediately), and we
80
+ * take that IMPDEF option because for QEMU a "real" implementation
81
+ * would be complicated and wouldn't execute any faster.
82
+ */
83
+ if (!dc_isar_feature(aa32_lob, s)) {
84
+ return false;
85
+ }
86
+ if (a->boff == 0) {
87
+ /* SEE "Related encodings" (loop insns) */
88
+ return false;
89
+ }
90
+ /* Handle as NOP */
91
+ return true;
92
+}
93
+
94
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
95
{
96
TCGv_i32 addr, tmp;
97
--
70
--
98
2.20.1
71
2.20.1
99
72
100
73
diff view generated by jsdifflib
1
For nested groups like:
1
Remove all the code that sets frequency properties on the CMSDK
2
timer, dualtimer and watchdog devices and on the ARMSSE SoC device:
3
these properties are unused now that the devices rely on their Clock
4
inputs instead.
2
5
3
{
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
[
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
pattern 1
8
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
pattern 2
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
]
10
Message-id: 20210128114145.20536-24-peter.maydell@linaro.org
8
pattern 3
11
Message-id: 20210121190622.22000-24-peter.maydell@linaro.org
9
}
12
---
13
hw/arm/armsse.c | 7 -------
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(-)
10
19
11
the intended behaviour is that patterns 1 and 2 must not
20
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
12
overlap with each other; if the insn matches neither then
13
we fall through to pattern 3 as the next thing in the
14
outer overlapping group.
15
16
Currently we generate incorrect code for this situation,
17
because in the code path for a failed match inside the
18
inner non-overlapping group we generate a "return" statement,
19
which causes decode to stop entirely rather than continuing
20
to the next thing in the outer group.
21
22
Generate a "break" instead, so that decode flow behaves
23
as required for this nested group case.
24
25
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Message-id: 20201019151301.2046-2-peter.maydell@linaro.org
29
---
30
scripts/decodetree.py | 2 +-
31
1 file changed, 1 insertion(+), 1 deletion(-)
32
33
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
34
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
35
--- a/scripts/decodetree.py
22
--- a/hw/arm/armsse.c
36
+++ b/scripts/decodetree.py
23
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ class Tree:
24
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
38
output(ind, ' /* ',
25
* it to the appropriate PPC port; then we can realize the PPC and
39
str_match_bits(innerbits, innermask), ' */\n')
26
* map its upstream ends to the right place in the container.
40
s.output_code(i + 4, extracted, innerbits, innermask)
27
*/
41
- output(ind, ' return false;\n')
28
- qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
42
+ output(ind, ' break;\n')
29
qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
43
output(ind, '}\n')
30
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
44
# end Tree
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"));
45
145
46
--
146
--
47
2.20.1
147
2.20.1
48
148
49
149
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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
The IRQ values are defined few lines earlier, use them instead of
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the magic numbers.
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(-)
5
21
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
7
Message-id: 20201017180731.1165871-3-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/intc/bcm2836_control.c | 8 ++++----
12
1 file changed, 4 insertions(+), 4 deletions(-)
13
14
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2836_control.c
24
--- a/include/hw/arm/armsse.h
17
+++ b/hw/intc/bcm2836_control.c
25
+++ b/include/hw/arm/armsse.h
18
@@ -XXX,XX +XXX,XX @@ static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq,
26
@@ -XXX,XX +XXX,XX @@
19
27
* + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
20
static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
28
* + QOM property "memory" is a MemoryRegion containing the devices provided
29
* by the board model.
30
- * + QOM property "MAINCLK_FRQ" is the frequency of the main system clock
31
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
32
* (In hardware, the SSE-200 permits the number of expansion interrupts
33
* for the two CPUs to be configured separately, but we restrict it to
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
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/timer/cmsdk-apb-dualtimer.h
45
+++ b/include/hw/timer/cmsdk-apb-dualtimer.h
46
@@ -XXX,XX +XXX,XX @@
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
}
128
};
129
130
-static Property cmsdk_apb_dualtimer_properties[] = {
131
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0),
132
- DEFINE_PROP_END_OF_LIST(),
133
-};
134
-
135
static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
21
{
136
{
22
- bcm2836_control_set_local_irq(opaque, core, 0, level);
137
DeviceClass *dc = DEVICE_CLASS(klass);
23
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPSIRQ, level);
138
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data)
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);
24
}
143
}
25
144
26
static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
145
static const TypeInfo cmsdk_apb_dualtimer_info = {
146
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/timer/cmsdk-apb-timer.c
149
+++ b/hw/timer/cmsdk-apb-timer.c
150
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription cmsdk_apb_timer_vmstate = {
151
}
152
};
153
154
-static Property cmsdk_apb_timer_properties[] = {
155
- DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTimer, pclk_frq, 0),
156
- DEFINE_PROP_END_OF_LIST(),
157
-};
158
-
159
static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
27
{
160
{
28
- bcm2836_control_set_local_irq(opaque, core, 1, level);
161
DeviceClass *dc = DEVICE_CLASS(klass);
29
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPNSIRQ, level);
162
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
163
dc->realize = cmsdk_apb_timer_realize;
164
dc->vmsd = &cmsdk_apb_timer_vmstate;
165
dc->reset = cmsdk_apb_timer_reset;
166
- device_class_set_props(dc, cmsdk_apb_timer_properties);
30
}
167
}
31
168
32
static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
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)
33
{
184
{
34
- bcm2836_control_set_local_irq(opaque, core, 2, level);
185
DeviceClass *dc = DEVICE_CLASS(klass);
35
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTHPIRQ, level);
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);
36
}
191
}
37
192
38
static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
193
static const TypeInfo cmsdk_apb_watchdog_info = {
39
{
40
- bcm2836_control_set_local_irq(opaque, core, 3, level);
41
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTVIRQ, level);
42
}
43
44
static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
45
--
194
--
46
2.20.1
195
2.20.1
47
196
48
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
This is a bit clearer than open-coding some of this
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
with a bare c string.
9
Reviewed-by: Luc Michel <luc@lmichel.fr>
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(-)
5
18
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20201016184207.786698-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
linux-user/elfload.c | 37 ++++++++++++++++++++-----------------
12
1 file changed, 20 insertions(+), 17 deletions(-)
13
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/elfload.c
21
--- a/hw/arm/stellaris.c
17
+++ b/linux-user/elfload.c
22
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
19
#include "qemu/guest-random.h"
24
sysbus_mmio_map(sbd, 0, base);
20
#include "qemu/units.h"
25
sysbus_connect_irq(sbd, 0, irq);
21
#include "qemu/selfmap.h"
26
22
+#include "qapi/error.h"
27
- /*
23
28
- * Normally we should not be resetting devices like this during
24
#ifdef _ARCH_PPC64
29
- * board creation. For the moment we need to do so, because
25
#undef ARCH_DLINFO
30
- * system_clock_scale will only get set when the STELLARIS_SYS
26
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
31
- * device is reset, and we need its initial value to pass to
27
struct elf_phdr *phdr;
32
- * the watchdog device. This hack can be removed once the
28
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
33
- * watchdog has been converted to use a Clock input instead.
29
int i, retval;
34
- */
30
- const char *errmsg;
35
- device_cold_reset(dev);
31
+ Error *err = NULL;
36
-
32
37
return dev;
33
/* First of all, some simple consistency checks */
34
- errmsg = "Invalid ELF image for this architecture";
35
if (!elf_check_ident(ehdr)) {
36
+ error_setg(&err, "Invalid ELF image for this architecture");
37
goto exit_errmsg;
38
}
39
bswap_ehdr(ehdr);
40
if (!elf_check_ehdr(ehdr)) {
41
+ error_setg(&err, "Invalid ELF image for this architecture");
42
goto exit_errmsg;
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
46
g_autofree char *interp_name = NULL;
47
48
if (*pinterp_name) {
49
- errmsg = "Multiple PT_INTERP entries";
50
+ error_setg(&err, "Multiple PT_INTERP entries");
51
goto exit_errmsg;
52
}
53
+
54
interp_name = g_malloc(eppnt->p_filesz);
55
- if (!interp_name) {
56
- goto exit_perror;
57
- }
58
59
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
60
memcpy(interp_name, bprm_buf + eppnt->p_offset,
61
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
62
retval = pread(image_fd, interp_name, eppnt->p_filesz,
63
eppnt->p_offset);
64
if (retval != eppnt->p_filesz) {
65
- goto exit_perror;
66
+ goto exit_read;
67
}
68
}
69
if (interp_name[eppnt->p_filesz - 1] != 0) {
70
- errmsg = "Invalid PT_INTERP entry";
71
+ error_setg(&err, "Invalid PT_INTERP entry");
72
goto exit_errmsg;
73
}
74
*pinterp_name = g_steal_pointer(&interp_name);
75
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
76
(ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
77
-1, 0);
78
if (load_addr == -1) {
79
- goto exit_perror;
80
+ goto exit_mmap;
81
}
82
load_bias = load_addr - loaddr;
83
84
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
85
image_fd, eppnt->p_offset - vaddr_po);
86
87
if (error == -1) {
88
- goto exit_perror;
89
+ goto exit_mmap;
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
94
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
95
Mips_elf_abiflags_v0 abiflags;
96
if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) {
97
- errmsg = "Invalid PT_MIPS_ABIFLAGS entry";
98
+ error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry");
99
goto exit_errmsg;
100
}
101
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
102
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
103
retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0),
104
eppnt->p_offset);
105
if (retval != sizeof(Mips_elf_abiflags_v0)) {
106
- goto exit_perror;
107
+ goto exit_read;
108
}
109
}
110
bswap_mips_abiflags(&abiflags);
111
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
112
113
exit_read:
114
if (retval >= 0) {
115
- errmsg = "Incomplete read of file header";
116
- goto exit_errmsg;
117
+ error_setg(&err, "Incomplete read of file header");
118
+ } else {
119
+ error_setg_errno(&err, errno, "Error reading file header");
120
}
121
- exit_perror:
122
- errmsg = strerror(errno);
123
+ goto exit_errmsg;
124
+ exit_mmap:
125
+ error_setg_errno(&err, errno, "Error mapping file");
126
+ goto exit_errmsg;
127
exit_errmsg:
128
- fprintf(stderr, "%s: %s\n", image_name, errmsg);
129
+ error_reportf_err(err, "%s: ", image_name);
130
exit(-1);
131
}
38
}
132
39
133
--
40
--
134
2.20.1
41
2.20.1
135
42
136
43
diff view generated by jsdifflib