1
ARM queue for 2.10 soft freeze...
1
Hi; here's a queue of arm patches (plus a few elf2dmp changes);
2
mostly these are minor cleanups and bugfixes.
2
3
3
thanks
4
thanks
4
-- PMM
5
-- PMM
5
6
6
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
7
The following changes since commit deaca3fd30d3a8829160f8d3705d65ad83176800:
7
8
8
Merge remote-tracking branch 'remotes/famz/tags/block-and-testing-pull-request' into staging (2017-07-17 11:46:36 +0100)
9
Merge tag 'pull-vfio-20231018' of https://github.com/legoater/qemu into staging (2023-10-18 06:21:15 -0400)
9
10
10
are available in the git repository at:
11
are available in the Git repository at:
11
12
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170717
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20231019
13
14
14
for you to fetch changes up to e5a6a6e64e82a132cebef023d867085b0a2993d7:
15
for you to fetch changes up to 2a052b4ee01b3c413cef2ef49cb780cde17d4ba1:
15
16
16
MAINTAINERS: Add entries for MPS2 board (2017-07-17 13:36:09 +0100)
17
contrib/elf2dmp: Use g_malloc(), g_new() and g_free() (2023-10-19 14:32:13 +0100)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
target-arm queue:
20
target-arm queue:
20
* new model of the ARM MPS2/MPS2+ FPGA based development board
21
* hw/arm: Move raspberrypi-fw-defs.h to the include/hw/arm/ folder
21
* clean up DISAS_* exit conditions and fix various regressions
22
* hw/arm/exynos4210: Get arm_boot_info declaration from 'hw/arm/boot'
22
since commits e75449a346 8a6b28c7b5 (in particular including
23
* xlnx devices: remove deprecated device reset
23
ones which broke OP-TEE guests)
24
* xlnx-bbram: hw/nvram: Use dot in device type name
24
* make Cortex-M3 and M4 correctly default to 8 PMSA regions
25
* elf2dmp: fix coverity issues
26
* elf2dmp: convert to g_malloc, g_new and g_free
27
* target/arm: Fix CNTPCT_EL0 trapping from EL0 when HCR_EL2.E2H is 0
28
* hw/arm: refactor virt PPI logic
29
* arm/kvm: convert to kvm_set_one_reg, kvm_get_one_reg
30
* target/arm: Permit T32 LDM with single register
31
* smmuv3: Advertise SMMUv3.1-XNX
32
* target/arm: Implement FEAT_HPMN0
33
* Remove some unnecessary include lines
34
* target/arm/arm-powerctl: Correctly init CPUs when powered on to lower EL
35
* hw/timer/npcm7xx_timer: Prevent timer from counting down past zero
25
36
26
----------------------------------------------------------------
37
----------------------------------------------------------------
27
Alex Bennée (6):
38
Chris Rauer (1):
28
include/exec/exec-all: document common exit conditions
39
hw/timer/npcm7xx_timer: Prevent timer from counting down past zero
29
target/arm/translate: make DISAS_UPDATE match declared semantics
30
target/arm/translate.h: expand comment on DISAS_EXIT
31
target/arm/translate: ensure gen_goto_tb sets exit flags
32
target/arm: use gen_goto_tb for ISB handling
33
target/arm: use DISAS_EXIT for eret handling
34
40
35
Peter Maydell (12):
41
Cornelia Huck (2):
36
qdev-properties.h: Explicitly set the default value for arraylen properties
42
arm/kvm: convert to kvm_set_one_reg
37
qdev: support properties which don't set a default value
43
arm/kvm: convert to kvm_get_one_reg
38
target/arm: Make Cortex-M3 and M4 default to 8 PMSA regions
39
hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models
40
hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
41
hw/arm/mps2: Add UARTs
42
hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
43
hw/arm/mps2: Add timers
44
hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller
45
hw/arm/mps2: Add SCC
46
hw/arm/mps2: Add ethernet
47
MAINTAINERS: Add entries for MPS2 board
48
44
49
hw/arm/Makefile.objs | 1 +
45
Leif Lindholm (3):
50
hw/char/Makefile.objs | 1 +
46
{include/}hw/arm: refactor virt PPI logic
51
hw/misc/Makefile.objs | 1 +
47
include/hw/arm: move BSA definitions to bsa.h
52
hw/timer/Makefile.objs | 1 +
48
hw/arm/sbsa-ref: use bsa.h for PPI definitions
53
include/exec/exec-all.h | 29 ++-
54
include/hw/char/cmsdk-apb-uart.h | 78 +++++++
55
include/hw/misc/mps2-scc.h | 43 ++++
56
include/hw/qdev-core.h | 10 +
57
include/hw/qdev-properties.h | 21 ++
58
include/hw/timer/cmsdk-apb-timer.h | 59 ++++++
59
target/arm/translate.h | 5 +-
60
hw/arm/mps2.c | 385 +++++++++++++++++++++++++++++++++++
61
hw/char/cmsdk-apb-uart.c | 403 +++++++++++++++++++++++++++++++++++++
62
hw/core/qdev.c | 2 +-
63
hw/misc/mps2-scc.c | 310 ++++++++++++++++++++++++++++
64
hw/timer/cmsdk-apb-timer.c | 253 +++++++++++++++++++++++
65
target/arm/cpu.c | 12 +-
66
target/arm/translate-a64.c | 19 +-
67
target/arm/translate.c | 22 +-
68
MAINTAINERS | 14 +-
69
default-configs/arm-softmmu.mak | 6 +
70
hw/char/trace-events | 9 +
71
hw/misc/trace-events | 8 +
72
hw/timer/trace-events | 5 +
73
24 files changed, 1673 insertions(+), 24 deletions(-)
74
create mode 100644 include/hw/char/cmsdk-apb-uart.h
75
create mode 100644 include/hw/misc/mps2-scc.h
76
create mode 100644 include/hw/timer/cmsdk-apb-timer.h
77
create mode 100644 hw/arm/mps2.c
78
create mode 100644 hw/char/cmsdk-apb-uart.c
79
create mode 100644 hw/misc/mps2-scc.c
80
create mode 100644 hw/timer/cmsdk-apb-timer.c
81
49
50
Michal Orzel (1):
51
target/arm: Fix CNTPCT_EL0 trapping from EL0 when HCR_EL2.E2H is 0
52
53
Peter Maydell (8):
54
target/arm: Permit T32 LDM with single register
55
hw/arm/smmuv3: Update ID register bit field definitions
56
hw/arm/smmuv3: Sort ID register setting into field order
57
hw/arm/smmuv3: Advertise SMMUv3.1-XNX feature
58
target/arm: Implement FEAT_HPMN0
59
target/arm/kvm64.c: Remove unused include
60
target/arm/common-semi-target.h: Remove unnecessary boot.h include
61
target/arm/arm-powerctl: Correctly init CPUs when powered on to lower EL
62
63
Philippe Mathieu-Daudé (1):
64
hw/arm/exynos4210: Get arm_boot_info declaration from 'hw/arm/boot.h'
65
66
Suraj Shirvankar (1):
67
contrib/elf2dmp: Use g_malloc(), g_new() and g_free()
68
69
Thomas Huth (1):
70
hw/arm: Move raspberrypi-fw-defs.h to the include/hw/arm/ folder
71
72
Tong Ho (4):
73
xlnx-bbram: hw/nvram: Remove deprecated device reset
74
xlnx-zynqmp-efuse: hw/nvram: Remove deprecated device reset
75
xlnx-versal-efuse: hw/nvram: Remove deprecated device reset
76
xlnx-bbram: hw/nvram: Use dot in device type name
77
78
Viktor Prutyanov (2):
79
elf2dmp: limit print length for sign_rsds
80
elf2dmp: check array bounds in pdb_get_file_size
81
82
MAINTAINERS | 2 +-
83
docs/system/arm/emulation.rst | 1 +
84
hw/arm/smmuv3-internal.h | 38 ++++++++
85
include/hw/arm/bsa.h | 35 +++++++
86
include/hw/arm/exynos4210.h | 2 +-
87
include/hw/{misc => arm}/raspberrypi-fw-defs.h | 0
88
include/hw/arm/virt.h | 12 +--
89
include/hw/nvram/xlnx-bbram.h | 2 +-
90
target/arm/common-semi-target.h | 4 +-
91
target/arm/cpu-qom.h | 2 -
92
target/arm/cpu.h | 22 +++++
93
contrib/elf2dmp/addrspace.c | 7 +-
94
contrib/elf2dmp/main.c | 11 +--
95
contrib/elf2dmp/pdb.c | 32 ++++---
96
contrib/elf2dmp/qemu_elf.c | 7 +-
97
hw/arm/boot.c | 95 +++++--------------
98
hw/arm/sbsa-ref.c | 21 ++---
99
hw/arm/smmuv3.c | 8 +-
100
hw/arm/virt-acpi-build.c | 12 +--
101
hw/arm/virt.c | 24 +++--
102
hw/misc/bcm2835_property.c | 2 +-
103
hw/nvram/xlnx-bbram.c | 8 +-
104
hw/nvram/xlnx-versal-efuse-ctrl.c | 8 +-
105
hw/nvram/xlnx-zynqmp-efuse.c | 8 +-
106
hw/timer/npcm7xx_timer.c | 3 +
107
target/arm/arm-powerctl.c | 53 +----------
108
target/arm/cpu.c | 95 +++++++++++++++++++
109
target/arm/helper.c | 19 +---
110
target/arm/kvm.c | 28 ++----
111
target/arm/kvm64.c | 124 +++++++------------------
112
target/arm/tcg/cpu32.c | 4 +
113
target/arm/tcg/cpu64.c | 1 +
114
target/arm/tcg/translate.c | 37 +++++---
115
33 files changed, 368 insertions(+), 359 deletions(-)
116
create mode 100644 include/hw/arm/bsa.h
117
rename include/hw/{misc => arm}/raspberrypi-fw-defs.h (100%)
118
diff view generated by jsdifflib
1
Add entries to the MAINTAINERS file for the new MPS2
1
From: Thomas Huth <thuth@redhat.com>
2
board and devices.
3
2
4
Since the CMSDK devices are not specific to the MPS2 board,
3
The file is obviously related to the raspberrypi machine, so
5
extend the existing 'PrimeCell' section to cover CMSDK
4
it should reside in hw/arm/ instead of hw/misc/. And while we're
6
devices as well; in both cases these are devices implemented
5
at it, also adjust the wildcard in MAINTAINERS so that it covers
7
by ARM and provided as RTL that may be used in multiple
6
this file, too.
8
SoCs and boards.
9
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Acked-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20231012073458.860187-1-thuth@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 1500029487-14822-10-git-send-email-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
---
13
---
15
MAINTAINERS | 14 +++++++++++++-
14
MAINTAINERS | 2 +-
16
1 file changed, 13 insertions(+), 1 deletion(-)
15
include/hw/{misc => arm}/raspberrypi-fw-defs.h | 0
16
hw/misc/bcm2835_property.c | 2 +-
17
3 files changed, 2 insertions(+), 2 deletions(-)
18
rename include/hw/{misc => arm}/raspberrypi-fw-defs.h (100%)
17
19
18
diff --git a/MAINTAINERS b/MAINTAINERS
20
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/MAINTAINERS
22
--- a/MAINTAINERS
21
+++ b/MAINTAINERS
23
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ F: hw/*/allwinner*
24
@@ -XXX,XX +XXX,XX @@ S: Odd Fixes
23
F: include/hw/*/allwinner*
25
F: hw/arm/raspi.c
24
F: hw/arm/cubieboard.c
26
F: hw/arm/raspi_platform.h
25
27
F: hw/*/bcm283*
26
-ARM PrimeCell
28
-F: include/hw/arm/raspi*
27
+ARM PrimeCell and CMSDK devices
29
+F: include/hw/arm/rasp*
28
M: Peter Maydell <peter.maydell@linaro.org>
30
F: include/hw/*/bcm283*
29
L: qemu-arm@nongnu.org
31
F: docs/system/arm/raspi.rst
30
S: Maintained
32
31
@@ -XXX,XX +XXX,XX @@ F: hw/intc/pl190.c
33
diff --git a/include/hw/misc/raspberrypi-fw-defs.h b/include/hw/arm/raspberrypi-fw-defs.h
32
F: hw/sd/pl181.c
34
similarity index 100%
33
F: hw/timer/pl031.c
35
rename from include/hw/misc/raspberrypi-fw-defs.h
34
F: include/hw/arm/primecell.h
36
rename to include/hw/arm/raspberrypi-fw-defs.h
35
+F: hw/timer/cmsdk-apb-timer.c
37
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
36
+F: include/hw/timer/cmsdk-apb-timer.h
38
index XXXXXXX..XXXXXXX 100644
37
+F: hw/char/cmsdk-apb-uart.c
39
--- a/hw/misc/bcm2835_property.c
38
+F: include/hw/char/cmsdk-apb-uart.h
40
+++ b/hw/misc/bcm2835_property.c
39
41
@@ -XXX,XX +XXX,XX @@
40
ARM cores
42
#include "migration/vmstate.h"
41
M: Peter Maydell <peter.maydell@linaro.org>
43
#include "hw/irq.h"
42
@@ -XXX,XX +XXX,XX @@ S: Maintained
44
#include "hw/misc/bcm2835_mbox_defs.h"
43
F: hw/arm/integratorcp.c
45
-#include "hw/misc/raspberrypi-fw-defs.h"
44
F: hw/misc/arm_integrator_debug.c
46
+#include "hw/arm/raspberrypi-fw-defs.h"
45
47
#include "sysemu/dma.h"
46
+MPS2
48
#include "qemu/log.h"
47
+M: Peter Maydell <peter.maydell@linaro.org>
49
#include "qemu/module.h"
48
+L: qemu-arm@nongnu.org
49
+S: Maintained
50
+F: hw/arm/mps2.c
51
+F: hw/misc/mps2-scc.c
52
+F: include/hw/misc/mps2-scc.h
53
+
54
Musicpal
55
M: Jan Kiszka <jan.kiszka@web.de>
56
L: qemu-arm@nongnu.org
57
--
50
--
58
2.7.4
51
2.34.1
59
52
60
53
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
While an ISB will ensure any raised IRQs happen on the next
3
struct arm_boot_info is declared in "hw/arm/boot.h".
4
instruction it doesn't cause any to get raised by itself. We can
4
By including the correct header we don't need to declare
5
therefore use a simple tb exit for ISB instructions and rely on the
5
it again in "target/arm/cpu-qom.h".
6
exit_request check at the top of each TB to deal with exiting if
7
needed.
8
6
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Richard Henderson <rth@twiddle.net>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20170713141928.25419-6-alex.bennee@linaro.org
9
Message-id: 20231013130214.95742-1-philmd@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
target/arm/translate-a64.c | 2 +-
12
include/hw/arm/exynos4210.h | 2 +-
15
target/arm/translate.c | 4 ++--
13
target/arm/cpu-qom.h | 2 --
16
2 files changed, 3 insertions(+), 3 deletions(-)
14
2 files changed, 1 insertion(+), 3 deletions(-)
17
15
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
18
--- a/include/hw/arm/exynos4210.h
21
+++ b/target/arm/translate-a64.c
19
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
20
@@ -XXX,XX +XXX,XX @@
23
* a self-modified code correctly and also to take
21
#include "hw/intc/exynos4210_gic.h"
24
* any pending interrupts immediately.
22
#include "hw/intc/exynos4210_combiner.h"
25
*/
23
#include "hw/core/split-irq.h"
26
- s->is_jmp = DISAS_UPDATE;
24
-#include "target/arm/cpu-qom.h"
27
+ gen_goto_tb(s, 0, s->pc);
25
+#include "hw/arm/boot.h"
28
return;
26
#include "qom/object.h"
29
default:
27
30
unallocated_encoding(s);
28
#define EXYNOS4210_NCPUS 2
31
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
32
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.c
31
--- a/target/arm/cpu-qom.h
34
+++ b/target/arm/translate.c
32
+++ b/target/arm/cpu-qom.h
35
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
33
@@ -XXX,XX +XXX,XX @@
36
* self-modifying code correctly and also to take
34
#include "hw/core/cpu.h"
37
* any pending interrupts immediately.
35
#include "qom/object.h"
38
*/
36
39
- gen_lookup_tb(s);
37
-struct arm_boot_info;
40
+ gen_goto_tb(s, 0, s->pc & ~1);
38
-
41
return;
39
#define TYPE_ARM_CPU "arm-cpu"
42
default:
40
43
goto illegal_op;
41
OBJECT_DECLARE_CPU_TYPE(ARMCPU, ARMCPUClass, ARM_CPU)
44
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
45
* and also to take any pending interrupts
46
* immediately.
47
*/
48
- gen_lookup_tb(s);
49
+ gen_goto_tb(s, 0, s->pc & ~1);
50
break;
51
default:
52
goto illegal_op;
53
--
42
--
54
2.7.4
43
2.34.1
55
44
56
45
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Tong Ho <tong.ho@amd.com>
2
2
3
We already have an exit condition, DISAS_UPDATE which will exit the
3
This change implements the ResettableClass interface for the device.
4
run-loop. Expand on the difference with DISAS_EXIT in the comments.
5
4
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Tong Ho <tong.ho@amd.com>
7
Reviewed-by: Richard Henderson <rth@twiddle.net>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20170713141928.25419-4-alex.bennee@linaro.org
7
Message-id: 20231003052345.199725-1-tong.ho@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/translate.h | 5 ++++-
10
hw/nvram/xlnx-bbram.c | 8 +++++---
12
1 file changed, 4 insertions(+), 1 deletion(-)
11
1 file changed, 5 insertions(+), 3 deletions(-)
13
12
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
13
diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
15
--- a/hw/nvram/xlnx-bbram.c
17
+++ b/target/arm/translate.h
16
+++ b/hw/nvram/xlnx-bbram.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
17
@@ -XXX,XX +XXX,XX @@
19
*/
18
* QEMU model of the Xilinx BBRAM Battery Backed RAM
20
#define DISAS_BX_EXCRET 11
19
*
21
/* For instructions which want an immediate exit to the main loop,
20
* Copyright (c) 2014-2021 Xilinx Inc.
22
- * as opposed to attempting to use lookup_and_goto_ptr.
21
+ * Copyright (c) 2023 Advanced Micro Devices, Inc.
23
+ * as opposed to attempting to use lookup_and_goto_ptr. Unlike
22
*
24
+ * DISAS_UPDATE this doesn't write the PC on exiting the translation
23
* Permission is hereby granted, free of charge, to any person obtaining a copy
25
+ * loop so you need to ensure something (gen_a64_set_pc_im or runtime
24
* of this software and associated documentation files (the "Software"), to deal
26
+ * helper) has done so before we reach return from cpu_tb_exec.
25
@@ -XXX,XX +XXX,XX @@ static RegisterAccessInfo bbram_ctrl_regs_info[] = {
27
*/
26
}
28
#define DISAS_EXIT 12
27
};
29
28
29
-static void bbram_ctrl_reset(DeviceState *dev)
30
+static void bbram_ctrl_reset_hold(Object *obj)
31
{
32
- XlnxBBRam *s = XLNX_BBRAM(dev);
33
+ XlnxBBRam *s = XLNX_BBRAM(obj);
34
unsigned int i;
35
36
for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
37
@@ -XXX,XX +XXX,XX @@ static Property bbram_ctrl_props[] = {
38
static void bbram_ctrl_class_init(ObjectClass *klass, void *data)
39
{
40
DeviceClass *dc = DEVICE_CLASS(klass);
41
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
42
43
- dc->reset = bbram_ctrl_reset;
44
+ rc->phases.hold = bbram_ctrl_reset_hold;
45
dc->realize = bbram_ctrl_realize;
46
dc->vmsd = &vmstate_bbram_ctrl;
47
device_class_set_props(dc, bbram_ctrl_props);
30
--
48
--
31
2.7.4
49
2.34.1
32
50
33
51
diff view generated by jsdifflib
New patch
1
From: Tong Ho <tong.ho@amd.com>
1
2
3
This change implements the ResettableClass interface for the device.
4
5
Signed-off-by: Tong Ho <tong.ho@amd.com>
6
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Message-id: 20231004055713.324009-1-tong.ho@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/nvram/xlnx-zynqmp-efuse.c | 8 +++++---
11
1 file changed, 5 insertions(+), 3 deletions(-)
12
13
diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/nvram/xlnx-zynqmp-efuse.c
16
+++ b/hw/nvram/xlnx-zynqmp-efuse.c
17
@@ -XXX,XX +XXX,XX @@
18
* QEMU model of the ZynqMP eFuse
19
*
20
* Copyright (c) 2015 Xilinx Inc.
21
+ * Copyright (c) 2023 Advanced Micro Devices, Inc.
22
*
23
* Written by Edgar E. Iglesias <edgari@xilinx.com>
24
*
25
@@ -XXX,XX +XXX,XX @@ static void zynqmp_efuse_register_reset(RegisterInfo *reg)
26
register_reset(reg);
27
}
28
29
-static void zynqmp_efuse_reset(DeviceState *dev)
30
+static void zynqmp_efuse_reset_hold(Object *obj)
31
{
32
- XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(dev);
33
+ XlnxZynqMPEFuse *s = XLNX_ZYNQMP_EFUSE(obj);
34
unsigned int i;
35
36
for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
37
@@ -XXX,XX +XXX,XX @@ static Property zynqmp_efuse_props[] = {
38
static void zynqmp_efuse_class_init(ObjectClass *klass, void *data)
39
{
40
DeviceClass *dc = DEVICE_CLASS(klass);
41
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
42
43
- dc->reset = zynqmp_efuse_reset;
44
+ rc->phases.hold = zynqmp_efuse_reset_hold;
45
dc->realize = zynqmp_efuse_realize;
46
dc->vmsd = &vmstate_efuse;
47
device_class_set_props(dc, zynqmp_efuse_props);
48
--
49
2.34.1
diff view generated by jsdifflib
1
Add the UARTs to the MPS2 board models.
1
From: Tong Ho <tong.ho@amd.com>
2
2
3
Unfortunately the details of the wiring of the interrupts through
3
This change implements the ResettableClass interface for the device.
4
various OR gates differ between AN511 and AN385 so this can't
5
be purely a data-driven difference.
6
4
5
Signed-off-by: Tong Ho <tong.ho@amd.com>
6
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Message-id: 20231004055339.323833-1-tong.ho@amd.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
9
Message-id: 1500029487-14822-4-git-send-email-peter.maydell@linaro.org
10
---
9
---
11
hw/arm/mps2.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
10
hw/nvram/xlnx-versal-efuse-ctrl.c | 8 +++++---
12
hw/char/cmsdk-apb-uart.c | 2 +-
11
1 file changed, 5 insertions(+), 3 deletions(-)
13
2 files changed, 89 insertions(+), 1 deletion(-)
14
12
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2.c
15
--- a/hw/nvram/xlnx-versal-efuse-ctrl.c
18
+++ b/hw/arm/mps2.c
16
+++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/error-report.h"
18
* QEMU model of the Versal eFuse controller
21
#include "hw/arm/arm.h"
19
*
22
#include "hw/arm/armv7m.h"
20
* Copyright (c) 2020 Xilinx Inc.
23
+#include "hw/or-irq.h"
21
+ * Copyright (c) 2023 Advanced Micro Devices, Inc.
24
#include "hw/boards.h"
22
*
25
#include "exec/address-spaces.h"
23
* Permission is hereby granted, free of charge, to any person obtaining a copy
26
+#include "sysemu/sysemu.h"
24
* of this software and associated documentation files (the "Software"), to deal
27
#include "hw/misc/unimp.h"
25
@@ -XXX,XX +XXX,XX @@ static void efuse_ctrl_register_reset(RegisterInfo *reg)
28
+#include "hw/char/cmsdk-apb-uart.h"
26
register_reset(reg);
29
30
typedef enum MPS2FPGAType {
31
FPGA_AN385,
32
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
33
create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
34
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
35
36
+ switch (mmc->fpga_type) {
37
+ case FPGA_AN385:
38
+ {
39
+ /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
40
+ * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
41
+ */
42
+ Object *orgate;
43
+ DeviceState *orgate_dev;
44
+ int i;
45
+
46
+ orgate = object_new(TYPE_OR_IRQ);
47
+ object_property_set_int(orgate, 6, "num-lines", &error_fatal);
48
+ object_property_set_bool(orgate, true, "realized", &error_fatal);
49
+ orgate_dev = DEVICE(orgate);
50
+ qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
51
+
52
+ for (i = 0; i < 5; i++) {
53
+ static const hwaddr uartbase[] = {0x40004000, 0x40005000,
54
+ 0x40006000, 0x40007000,
55
+ 0x40009000};
56
+ Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
57
+ /* RX irq number; TX irq is always one greater */
58
+ static const int uartirq[] = {0, 2, 4, 18, 20};
59
+ qemu_irq txovrint = NULL, rxovrint = NULL;
60
+
61
+ if (i < 3) {
62
+ txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
63
+ rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
64
+ }
65
+
66
+ cmsdk_apb_uart_create(uartbase[i],
67
+ qdev_get_gpio_in(armv7m, uartirq[i] + 1),
68
+ qdev_get_gpio_in(armv7m, uartirq[i]),
69
+ txovrint, rxovrint,
70
+ NULL,
71
+ uartchr, SYSCLK_FRQ);
72
+ }
73
+ break;
74
+ }
75
+ case FPGA_AN511:
76
+ {
77
+ /* The overflow IRQs for all UARTs are ORed together.
78
+ * Tx and Rx IRQs for each UART are ORed together.
79
+ */
80
+ Object *orgate;
81
+ DeviceState *orgate_dev;
82
+ int i;
83
+
84
+ orgate = object_new(TYPE_OR_IRQ);
85
+ object_property_set_int(orgate, 10, "num-lines", &error_fatal);
86
+ object_property_set_bool(orgate, true, "realized", &error_fatal);
87
+ orgate_dev = DEVICE(orgate);
88
+ qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
89
+
90
+ for (i = 0; i < 5; i++) {
91
+ /* system irq numbers for the combined tx/rx for each UART */
92
+ static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
93
+ static const hwaddr uartbase[] = {0x40004000, 0x40005000,
94
+ 0x4002c000, 0x4002d000,
95
+ 0x4002e000};
96
+ Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
97
+ Object *txrx_orgate;
98
+ DeviceState *txrx_orgate_dev;
99
+
100
+ txrx_orgate = object_new(TYPE_OR_IRQ);
101
+ object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
102
+ object_property_set_bool(txrx_orgate, true, "realized",
103
+ &error_fatal);
104
+ txrx_orgate_dev = DEVICE(txrx_orgate);
105
+ qdev_connect_gpio_out(txrx_orgate_dev, 0,
106
+ qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
107
+ cmsdk_apb_uart_create(uartbase[i],
108
+ qdev_get_gpio_in(txrx_orgate_dev, 0),
109
+ qdev_get_gpio_in(txrx_orgate_dev, 1),
110
+ qdev_get_gpio_in(orgate_dev, 0),
111
+ qdev_get_gpio_in(orgate_dev, 1),
112
+ NULL,
113
+ uartchr, SYSCLK_FRQ);
114
+ }
115
+ break;
116
+ }
117
+ default:
118
+ g_assert_not_reached();
119
+ }
120
+
121
system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
122
123
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
124
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/char/cmsdk-apb-uart.c
127
+++ b/hw/char/cmsdk-apb-uart.c
128
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
129
* an event handler to deal with CHR_EVENT_BREAK.
130
*/
131
qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
132
- NULL, s, NULL, true);
133
+ NULL, NULL, s, NULL, true);
134
}
27
}
135
28
136
static int cmsdk_apb_uart_post_load(void *opaque, int version_id)
29
-static void efuse_ctrl_reset(DeviceState *dev)
30
+static void efuse_ctrl_reset_hold(Object *obj)
31
{
32
- XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(dev);
33
+ XlnxVersalEFuseCtrl *s = XLNX_VERSAL_EFUSE_CTRL(obj);
34
unsigned int i;
35
36
for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
37
@@ -XXX,XX +XXX,XX @@ static Property efuse_ctrl_props[] = {
38
static void efuse_ctrl_class_init(ObjectClass *klass, void *data)
39
{
40
DeviceClass *dc = DEVICE_CLASS(klass);
41
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
42
43
- dc->reset = efuse_ctrl_reset;
44
+ rc->phases.hold = efuse_ctrl_reset_hold;
45
dc->realize = efuse_ctrl_realize;
46
dc->vmsd = &vmstate_efuse_ctrl;
47
device_class_set_props(dc, efuse_ctrl_props);
137
--
48
--
138
2.7.4
49
2.34.1
139
140
diff view generated by jsdifflib
New patch
1
From: Tong Ho <tong.ho@amd.com>
1
2
3
This replaces the comma (,) to dot (.) in the device type name
4
so the name can be used with the 'driver=' command line option.
5
6
Signed-off-by: Tong Ho <tong.ho@amd.com>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: 20231003052139.199665-1-tong.ho@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/nvram/xlnx-bbram.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/include/hw/nvram/xlnx-bbram.h b/include/hw/nvram/xlnx-bbram.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/nvram/xlnx-bbram.h
17
+++ b/include/hw/nvram/xlnx-bbram.h
18
@@ -XXX,XX +XXX,XX @@
19
20
#define RMAX_XLNX_BBRAM ((0x4c / 4) + 1)
21
22
-#define TYPE_XLNX_BBRAM "xlnx,bbram-ctrl"
23
+#define TYPE_XLNX_BBRAM "xlnx.bbram-ctrl"
24
OBJECT_DECLARE_SIMPLE_TYPE(XlnxBBRam, XLNX_BBRAM);
25
26
struct XlnxBBRam {
27
--
28
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Viktor Prutyanov <viktor@daynix.com>
2
2
3
DISAS_UPDATE should be used when the wider CPU state other than just
3
String sign_rsds isn't terminated, so the print length must be limited.
4
the PC has been updated and we should therefore exit the TCG runtime
5
and return to the main execution loop rather assuming DISAS_JUMP would
6
do that.
7
4
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Fixes: Coverity CID 1521598
9
Reviewed-by: Richard Henderson <rth@twiddle.net>
6
Signed-off-by: Viktor Prutyanov <viktor@daynix.com>
10
Message-id: 20170713141928.25419-3-alex.bennee@linaro.org
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Message-id: 20230930235317.11469-2-viktor@daynix.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate-a64.c | 14 +++++++-------
11
contrib/elf2dmp/main.c | 2 +-
14
target/arm/translate.c | 6 +++---
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
2 files changed, 10 insertions(+), 10 deletions(-)
16
13
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
16
--- a/contrib/elf2dmp/main.c
20
+++ b/target/arm/translate-a64.c
17
+++ b/contrib/elf2dmp/main.c
21
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
18
@@ -XXX,XX +XXX,XX @@ static bool pe_check_pdb_name(uint64_t base, void *start_addr,
22
case DISAS_NEXT:
23
gen_goto_tb(dc, 1, dc->pc);
24
break;
25
- default:
26
- case DISAS_UPDATE:
27
- gen_a64_set_pc_im(dc->pc);
28
- /* fall through */
29
case DISAS_JUMP:
30
tcg_gen_lookup_and_goto_ptr(cpu_pc);
31
break;
32
- case DISAS_EXIT:
33
- tcg_gen_exit_tb(0);
34
- break;
35
case DISAS_TB_JUMP:
36
case DISAS_EXC:
37
case DISAS_SWI:
38
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
39
*/
40
tcg_gen_exit_tb(0);
41
break;
42
+ case DISAS_UPDATE:
43
+ gen_a64_set_pc_im(dc->pc);
44
+ /* fall through */
45
+ case DISAS_EXIT:
46
+ default:
47
+ tcg_gen_exit_tb(0);
48
+ break;
49
}
50
}
19
}
51
20
52
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
if (memcmp(&rsds->Signature, sign_rsds, sizeof(sign_rsds))) {
53
index XXXXXXX..XXXXXXX 100644
22
- eprintf("CodeView signature is \'%.4s\', \'%s\' expected\n",
54
--- a/target/arm/translate.c
23
+ eprintf("CodeView signature is \'%.4s\', \'%.4s\' expected\n",
55
+++ b/target/arm/translate.c
24
rsds->Signature, sign_rsds);
56
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
25
return false;
57
case DISAS_NEXT:
26
}
58
gen_goto_tb(dc, 1, dc->pc);
59
break;
60
- case DISAS_UPDATE:
61
- gen_set_pc_im(dc, dc->pc);
62
- /* fall through */
63
case DISAS_JUMP:
64
gen_goto_ptr();
65
break;
66
+ case DISAS_UPDATE:
67
+ gen_set_pc_im(dc, dc->pc);
68
+ /* fall through */
69
default:
70
/* indicate that the hash table must be used to find the next TB */
71
tcg_gen_exit_tb(0);
72
--
27
--
73
2.7.4
28
2.34.1
74
75
diff view generated by jsdifflib
1
Implement a model of the simple "APB UART" provided in
1
From: Viktor Prutyanov <viktor@daynix.com>
2
the Cortex-M System Design Kit (CMSDK).
3
2
3
Index in file_size array must be checked against num_files, because the
4
entries we are looking for may be absent in the PDB.
5
6
Fixes: Coverity CID 1521597
7
Signed-off-by: Viktor Prutyanov <viktor@daynix.com>
8
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20230930235317.11469-3-viktor@daynix.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 1500029487-14822-3-git-send-email-peter.maydell@linaro.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
---
12
---
8
hw/char/Makefile.objs | 1 +
13
contrib/elf2dmp/pdb.c | 13 +++++++++----
9
include/hw/char/cmsdk-apb-uart.h | 78 ++++++++
14
1 file changed, 9 insertions(+), 4 deletions(-)
10
hw/char/cmsdk-apb-uart.c | 403 +++++++++++++++++++++++++++++++++++++++
11
default-configs/arm-softmmu.mak | 2 +
12
hw/char/trace-events | 9 +
13
5 files changed, 493 insertions(+)
14
create mode 100644 include/hw/char/cmsdk-apb-uart.h
15
create mode 100644 hw/char/cmsdk-apb-uart.c
16
15
17
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
16
diff --git a/contrib/elf2dmp/pdb.c b/contrib/elf2dmp/pdb.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/char/Makefile.objs
18
--- a/contrib/elf2dmp/pdb.c
20
+++ b/hw/char/Makefile.objs
19
+++ b/contrib/elf2dmp/pdb.c
21
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_DIGIC) += digic-uart.o
22
obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
23
obj-$(CONFIG_RASPI) += bcm2835_aux.o
24
25
+common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
26
common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
27
common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
28
common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
29
diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/include/hw/char/cmsdk-apb-uart.h
34
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
35
+/*
21
36
+ * ARM CMSDK APB UART emulation
22
static uint32_t pdb_get_file_size(const struct pdb_reader *r, unsigned idx)
37
+ *
23
{
38
+ * Copyright (c) 2017 Linaro Limited
24
+ if (idx >= r->ds.toc->num_files) {
39
+ * Written by Peter Maydell
25
+ return 0;
40
+ *
41
+ * This program is free software; you can redistribute it and/or modify
42
+ * it under the terms of the GNU General Public License version 2 or
43
+ * (at your option) any later version.
44
+ */
45
+
46
+#ifndef CMSDK_APB_UART_H
47
+#define CMSDK_APB_UART_H
48
+
49
+#include "hw/sysbus.h"
50
+#include "chardev/char-fe.h"
51
+
52
+#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
53
+#define CMSDK_APB_UART(obj) OBJECT_CHECK(CMSDKAPBUART, (obj), \
54
+ TYPE_CMSDK_APB_UART)
55
+
56
+typedef struct {
57
+ /*< private >*/
58
+ SysBusDevice parent_obj;
59
+
60
+ /*< public >*/
61
+ MemoryRegion iomem;
62
+ CharBackend chr;
63
+ qemu_irq txint;
64
+ qemu_irq rxint;
65
+ qemu_irq txovrint;
66
+ qemu_irq rxovrint;
67
+ qemu_irq uartint;
68
+ guint watch_tag;
69
+ uint32_t pclk_frq;
70
+
71
+ uint32_t state;
72
+ uint32_t ctrl;
73
+ uint32_t intstatus;
74
+ uint32_t bauddiv;
75
+ /* This UART has no FIFO, only a 1-character buffer for each of Tx and Rx */
76
+ uint8_t txbuf;
77
+ uint8_t rxbuf;
78
+} CMSDKAPBUART;
79
+
80
+/**
81
+ * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
82
+ * @addr: location in system memory to map registers
83
+ * @chr: Chardev backend to connect UART to, or NULL if no backend
84
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
85
+ */
86
+static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
87
+ qemu_irq txint,
88
+ qemu_irq rxint,
89
+ qemu_irq txovrint,
90
+ qemu_irq rxovrint,
91
+ qemu_irq uartint,
92
+ Chardev *chr,
93
+ uint32_t pclk_frq)
94
+{
95
+ DeviceState *dev;
96
+ SysBusDevice *s;
97
+
98
+ dev = qdev_create(NULL, TYPE_CMSDK_APB_UART);
99
+ s = SYS_BUS_DEVICE(dev);
100
+ qdev_prop_set_chr(dev, "chardev", chr);
101
+ qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
102
+ qdev_init_nofail(dev);
103
+ sysbus_mmio_map(s, 0, addr);
104
+ sysbus_connect_irq(s, 0, txint);
105
+ sysbus_connect_irq(s, 1, rxint);
106
+ sysbus_connect_irq(s, 2, txovrint);
107
+ sysbus_connect_irq(s, 3, rxovrint);
108
+ sysbus_connect_irq(s, 4, uartint);
109
+ return dev;
110
+}
111
+
112
+#endif
113
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
114
new file mode 100644
115
index XXXXXXX..XXXXXXX
116
--- /dev/null
117
+++ b/hw/char/cmsdk-apb-uart.c
118
@@ -XXX,XX +XXX,XX @@
119
+/*
120
+ * ARM CMSDK APB UART emulation
121
+ *
122
+ * Copyright (c) 2017 Linaro Limited
123
+ * Written by Peter Maydell
124
+ *
125
+ * This program is free software; you can redistribute it and/or modify
126
+ * it under the terms of the GNU General Public License version 2 or
127
+ * (at your option) any later version.
128
+ */
129
+
130
+/* This is a model of the "APB UART" which is part of the Cortex-M
131
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
132
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
133
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
134
+ */
135
+
136
+#include "qemu/osdep.h"
137
+#include "qemu/log.h"
138
+#include "qapi/error.h"
139
+#include "trace.h"
140
+#include "hw/sysbus.h"
141
+#include "hw/registerfields.h"
142
+#include "chardev/char-fe.h"
143
+#include "chardev/char-serial.h"
144
+#include "hw/char/cmsdk-apb-uart.h"
145
+
146
+REG32(DATA, 0)
147
+REG32(STATE, 4)
148
+ FIELD(STATE, TXFULL, 0, 1)
149
+ FIELD(STATE, RXFULL, 1, 1)
150
+ FIELD(STATE, TXOVERRUN, 2, 1)
151
+ FIELD(STATE, RXOVERRUN, 3, 1)
152
+REG32(CTRL, 8)
153
+ FIELD(CTRL, TX_EN, 0, 1)
154
+ FIELD(CTRL, RX_EN, 1, 1)
155
+ FIELD(CTRL, TX_INTEN, 2, 1)
156
+ FIELD(CTRL, RX_INTEN, 3, 1)
157
+ FIELD(CTRL, TXO_INTEN, 4, 1)
158
+ FIELD(CTRL, RXO_INTEN, 5, 1)
159
+ FIELD(CTRL, HSTEST, 6, 1)
160
+REG32(INTSTATUS, 0xc)
161
+ FIELD(INTSTATUS, TX, 0, 1)
162
+ FIELD(INTSTATUS, RX, 1, 1)
163
+ FIELD(INTSTATUS, TXO, 2, 1)
164
+ FIELD(INTSTATUS, RXO, 3, 1)
165
+REG32(BAUDDIV, 0x10)
166
+REG32(PID4, 0xFD0)
167
+REG32(PID5, 0xFD4)
168
+REG32(PID6, 0xFD8)
169
+REG32(PID7, 0xFDC)
170
+REG32(PID0, 0xFE0)
171
+REG32(PID1, 0xFE4)
172
+REG32(PID2, 0xFE8)
173
+REG32(PID3, 0xFEC)
174
+REG32(CID0, 0xFF0)
175
+REG32(CID1, 0xFF4)
176
+REG32(CID2, 0xFF8)
177
+REG32(CID3, 0xFFC)
178
+
179
+/* PID/CID values */
180
+static const int uart_id[] = {
181
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
182
+ 0x21, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
183
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
184
+};
185
+
186
+static bool uart_baudrate_ok(CMSDKAPBUART *s)
187
+{
188
+ /* The minimum permitted bauddiv setting is 16, so we just ignore
189
+ * settings below that (usually this means the device has just
190
+ * been reset and not yet programmed).
191
+ */
192
+ return s->bauddiv >= 16 && s->bauddiv <= s->pclk_frq;
193
+}
194
+
195
+static void uart_update_parameters(CMSDKAPBUART *s)
196
+{
197
+ QEMUSerialSetParams ssp;
198
+
199
+ /* This UART is always 8N1 but the baud rate is programmable. */
200
+ if (!uart_baudrate_ok(s)) {
201
+ return;
202
+ }
26
+ }
203
+
27
+
204
+ ssp.data_bits = 8;
28
return r->ds.toc->file_size[idx];
205
+ ssp.parity = 'N';
29
}
206
+ ssp.stop_bits = 1;
30
207
+ ssp.speed = s->pclk_frq / s->bauddiv;
31
@@ -XXX,XX +XXX,XX @@ static void *pdb_ds_read_file(struct pdb_reader* r, uint32_t file_number)
208
+ qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
32
209
+ trace_cmsdk_apb_uart_set_params(ssp.speed);
33
static int pdb_init_segments(struct pdb_reader *r)
210
+}
34
{
211
+
35
- char *segs;
212
+static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
36
unsigned stream_idx = r->segments;
213
+{
37
214
+ /* update outbound irqs, including handling the way the rxo and txo
38
- segs = pdb_ds_read_file(r, stream_idx);
215
+ * interrupt status bits are just logical AND of the overrun bit in
39
- if (!segs) {
216
+ * STATE and the overrun interrupt enable bit in CTRL.
40
+ r->segs = pdb_ds_read_file(r, stream_idx);
217
+ */
41
+ if (!r->segs) {
218
+ uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
42
return 1;
219
+ s->intstatus &= ~omask;
43
}
220
+ s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
44
221
+
45
- r->segs = segs;
222
+ qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
46
r->segs_size = pdb_get_file_size(r, stream_idx);
223
+ qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
47
+ if (!r->segs_size) {
224
+ qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
225
+ qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
226
+ qemu_set_irq(s->uartint, !!(s->intstatus));
227
+}
228
+
229
+static int uart_can_receive(void *opaque)
230
+{
231
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
232
+
233
+ /* We can take a char if RX is enabled and the buffer is empty */
234
+ if (s->ctrl & R_CTRL_RX_EN_MASK && !(s->state & R_STATE_RXFULL_MASK)) {
235
+ return 1;
48
+ return 1;
236
+ }
49
+ }
237
+ return 0;
50
238
+}
51
return 0;
239
+
52
}
240
+static void uart_receive(void *opaque, const uint8_t *buf, int size)
241
+{
242
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
243
+
244
+ trace_cmsdk_apb_uart_receive(*buf);
245
+
246
+ /* In fact uart_can_receive() ensures that we can't be
247
+ * called unless RX is enabled and the buffer is empty,
248
+ * but we include this logic as documentation of what the
249
+ * hardware does if a character arrives in these circumstances.
250
+ */
251
+ if (!(s->ctrl & R_CTRL_RX_EN_MASK)) {
252
+ /* Just drop the character on the floor */
253
+ return;
254
+ }
255
+
256
+ if (s->state & R_STATE_RXFULL_MASK) {
257
+ s->state |= R_STATE_RXOVERRUN_MASK;
258
+ }
259
+
260
+ s->rxbuf = *buf;
261
+ s->state |= R_STATE_RXFULL_MASK;
262
+ if (s->ctrl & R_CTRL_RX_INTEN_MASK) {
263
+ s->intstatus |= R_INTSTATUS_RX_MASK;
264
+ }
265
+ cmsdk_apb_uart_update(s);
266
+}
267
+
268
+static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
269
+{
270
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
271
+ uint64_t r;
272
+
273
+ switch (offset) {
274
+ case A_DATA:
275
+ r = s->rxbuf;
276
+ s->state &= ~R_STATE_RXFULL_MASK;
277
+ cmsdk_apb_uart_update(s);
278
+ break;
279
+ case A_STATE:
280
+ r = s->state;
281
+ break;
282
+ case A_CTRL:
283
+ r = s->ctrl;
284
+ break;
285
+ case A_INTSTATUS:
286
+ r = s->intstatus;
287
+ break;
288
+ case A_BAUDDIV:
289
+ r = s->bauddiv;
290
+ break;
291
+ case A_PID4 ... A_CID3:
292
+ r = uart_id[(offset - A_PID4) / 4];
293
+ break;
294
+ default:
295
+ qemu_log_mask(LOG_GUEST_ERROR,
296
+ "CMSDK APB UART read: bad offset %x\n", (int) offset);
297
+ r = 0;
298
+ break;
299
+ }
300
+ trace_cmsdk_apb_uart_read(offset, r, size);
301
+ return r;
302
+}
303
+
304
+/* Try to send tx data, and arrange to be called back later if
305
+ * we can't (ie the char backend is busy/blocking).
306
+ */
307
+static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque)
308
+{
309
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
310
+ int ret;
311
+
312
+ s->watch_tag = 0;
313
+
314
+ if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) {
315
+ return FALSE;
316
+ }
317
+
318
+ ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1);
319
+ if (ret <= 0) {
320
+ s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
321
+ uart_transmit, s);
322
+ if (!s->watch_tag) {
323
+ /* Most common reason to be here is "no chardev backend":
324
+ * just insta-drain the buffer, so the serial output
325
+ * goes into a void, rather than blocking the guest.
326
+ */
327
+ goto buffer_drained;
328
+ }
329
+ /* Transmit pending */
330
+ trace_cmsdk_apb_uart_tx_pending();
331
+ return FALSE;
332
+ }
333
+
334
+buffer_drained:
335
+ /* Character successfully sent */
336
+ trace_cmsdk_apb_uart_tx(s->txbuf);
337
+ s->state &= ~R_STATE_TXFULL_MASK;
338
+ /* Going from TXFULL set to clear triggers the tx interrupt */
339
+ if (s->ctrl & R_CTRL_TX_INTEN_MASK) {
340
+ s->intstatus |= R_INTSTATUS_TX_MASK;
341
+ }
342
+ cmsdk_apb_uart_update(s);
343
+ return FALSE;
344
+}
345
+
346
+static void uart_cancel_transmit(CMSDKAPBUART *s)
347
+{
348
+ if (s->watch_tag) {
349
+ g_source_remove(s->watch_tag);
350
+ s->watch_tag = 0;
351
+ }
352
+}
353
+
354
+static void uart_write(void *opaque, hwaddr offset, uint64_t value,
355
+ unsigned size)
356
+{
357
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
358
+
359
+ trace_cmsdk_apb_uart_write(offset, value, size);
360
+
361
+ switch (offset) {
362
+ case A_DATA:
363
+ s->txbuf = value;
364
+ if (s->state & R_STATE_TXFULL_MASK) {
365
+ /* Buffer already full -- note the overrun and let the
366
+ * existing pending transmit callback handle the new char.
367
+ */
368
+ s->state |= R_STATE_TXOVERRUN_MASK;
369
+ cmsdk_apb_uart_update(s);
370
+ } else {
371
+ s->state |= R_STATE_TXFULL_MASK;
372
+ uart_transmit(NULL, G_IO_OUT, s);
373
+ }
374
+ break;
375
+ case A_STATE:
376
+ /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
377
+ s->state &= ~(value &
378
+ (R_STATE_TXOVERRUN_MASK | R_STATE_RXOVERRUN_MASK));
379
+ cmsdk_apb_uart_update(s);
380
+ break;
381
+ case A_CTRL:
382
+ s->ctrl = value & 0x7f;
383
+ if ((s->ctrl & R_CTRL_TX_EN_MASK) && !uart_baudrate_ok(s)) {
384
+ qemu_log_mask(LOG_GUEST_ERROR,
385
+ "CMSDK APB UART: Tx enabled with invalid baudrate\n");
386
+ }
387
+ cmsdk_apb_uart_update(s);
388
+ break;
389
+ case A_INTSTATUS:
390
+ /* All bits are W1C. Clearing the overrun interrupt bits really
391
+ * clears the overrun status bits in the STATE register (which
392
+ * is then reflected into the intstatus value by the update function).
393
+ */
394
+ s->state &= ~(value & (R_INTSTATUS_TXO_MASK | R_INTSTATUS_RXO_MASK));
395
+ cmsdk_apb_uart_update(s);
396
+ break;
397
+ case A_BAUDDIV:
398
+ s->bauddiv = value & 0xFFFFF;
399
+ uart_update_parameters(s);
400
+ break;
401
+ case A_PID4 ... A_CID3:
402
+ qemu_log_mask(LOG_GUEST_ERROR,
403
+ "CMSDK APB UART write: write to RO offset 0x%x\n",
404
+ (int)offset);
405
+ break;
406
+ default:
407
+ qemu_log_mask(LOG_GUEST_ERROR,
408
+ "CMSDK APB UART write: bad offset 0x%x\n", (int) offset);
409
+ break;
410
+ }
411
+}
412
+
413
+static const MemoryRegionOps uart_ops = {
414
+ .read = uart_read,
415
+ .write = uart_write,
416
+ .endianness = DEVICE_LITTLE_ENDIAN,
417
+};
418
+
419
+static void cmsdk_apb_uart_reset(DeviceState *dev)
420
+{
421
+ CMSDKAPBUART *s = CMSDK_APB_UART(dev);
422
+
423
+ trace_cmsdk_apb_uart_reset();
424
+ uart_cancel_transmit(s);
425
+ s->state = 0;
426
+ s->ctrl = 0;
427
+ s->intstatus = 0;
428
+ s->bauddiv = 0;
429
+ s->txbuf = 0;
430
+ s->rxbuf = 0;
431
+}
432
+
433
+static void cmsdk_apb_uart_init(Object *obj)
434
+{
435
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
436
+ CMSDKAPBUART *s = CMSDK_APB_UART(obj);
437
+
438
+ memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
439
+ sysbus_init_mmio(sbd, &s->iomem);
440
+ sysbus_init_irq(sbd, &s->txint);
441
+ sysbus_init_irq(sbd, &s->rxint);
442
+ sysbus_init_irq(sbd, &s->txovrint);
443
+ sysbus_init_irq(sbd, &s->rxovrint);
444
+ sysbus_init_irq(sbd, &s->uartint);
445
+}
446
+
447
+static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
448
+{
449
+ CMSDKAPBUART *s = CMSDK_APB_UART(dev);
450
+
451
+ if (s->pclk_frq == 0) {
452
+ error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
453
+ return;
454
+ }
455
+
456
+ /* This UART has no flow control, so we do not need to register
457
+ * an event handler to deal with CHR_EVENT_BREAK.
458
+ */
459
+ qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
460
+ NULL, s, NULL, true);
461
+}
462
+
463
+static int cmsdk_apb_uart_post_load(void *opaque, int version_id)
464
+{
465
+ CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
466
+
467
+ /* If we have a pending character, arrange to resend it. */
468
+ if (s->state & R_STATE_TXFULL_MASK) {
469
+ s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
470
+ uart_transmit, s);
471
+ }
472
+ uart_update_parameters(s);
473
+ return 0;
474
+}
475
+
476
+static const VMStateDescription cmsdk_apb_uart_vmstate = {
477
+ .name = "cmsdk-apb-uart",
478
+ .version_id = 1,
479
+ .minimum_version_id = 1,
480
+ .post_load = cmsdk_apb_uart_post_load,
481
+ .fields = (VMStateField[]) {
482
+ VMSTATE_UINT32(state, CMSDKAPBUART),
483
+ VMSTATE_UINT32(ctrl, CMSDKAPBUART),
484
+ VMSTATE_UINT32(intstatus, CMSDKAPBUART),
485
+ VMSTATE_UINT32(bauddiv, CMSDKAPBUART),
486
+ VMSTATE_UINT8(txbuf, CMSDKAPBUART),
487
+ VMSTATE_UINT8(rxbuf, CMSDKAPBUART),
488
+ VMSTATE_END_OF_LIST()
489
+ }
490
+};
491
+
492
+static Property cmsdk_apb_uart_properties[] = {
493
+ DEFINE_PROP_CHR("chardev", CMSDKAPBUART, chr),
494
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0),
495
+ DEFINE_PROP_END_OF_LIST(),
496
+};
497
+
498
+static void cmsdk_apb_uart_class_init(ObjectClass *klass, void *data)
499
+{
500
+ DeviceClass *dc = DEVICE_CLASS(klass);
501
+
502
+ dc->realize = cmsdk_apb_uart_realize;
503
+ dc->vmsd = &cmsdk_apb_uart_vmstate;
504
+ dc->reset = cmsdk_apb_uart_reset;
505
+ dc->props = cmsdk_apb_uart_properties;
506
+}
507
+
508
+static const TypeInfo cmsdk_apb_uart_info = {
509
+ .name = TYPE_CMSDK_APB_UART,
510
+ .parent = TYPE_SYS_BUS_DEVICE,
511
+ .instance_size = sizeof(CMSDKAPBUART),
512
+ .instance_init = cmsdk_apb_uart_init,
513
+ .class_init = cmsdk_apb_uart_class_init,
514
+};
515
+
516
+static void cmsdk_apb_uart_register_types(void)
517
+{
518
+ type_register_static(&cmsdk_apb_uart_info);
519
+}
520
+
521
+type_init(cmsdk_apb_uart_register_types);
522
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
523
index XXXXXXX..XXXXXXX 100644
524
--- a/default-configs/arm-softmmu.mak
525
+++ b/default-configs/arm-softmmu.mak
526
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F2XX_ADC=y
527
CONFIG_STM32F2XX_SPI=y
528
CONFIG_STM32F205_SOC=y
529
530
+CONFIG_CMSDK_APB_UART=y
531
+
532
CONFIG_VERSATILE_PCI=y
533
CONFIG_VERSATILE_I2C=y
534
535
diff --git a/hw/char/trace-events b/hw/char/trace-events
536
index XXXXXXX..XXXXXXX 100644
537
--- a/hw/char/trace-events
538
+++ b/hw/char/trace-events
539
@@ -XXX,XX +XXX,XX @@ pl011_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
540
pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR %08x read_count %d returning %d"
541
pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
542
pl011_put_fifo_full(void) "FIFO now full, RXFF set"
543
+
544
+# hw/char/cmsdk_apb_uart.c
545
+cmsdk_apb_uart_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
546
+cmsdk_apb_uart_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
547
+cmsdk_apb_uart_reset(void) "CMSDK APB UART: reset"
548
+cmsdk_apb_uart_receive(uint8_t c) "CMSDK APB UART: got character 0x%x from backend"
549
+cmsdk_apb_uart_tx_pending(void) "CMSDK APB UART: character send to backend pending"
550
+cmsdk_apb_uart_tx(uint8_t c) "CMSDK APB UART: character 0x%x sent to backend"
551
+cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1"
552
--
53
--
553
2.7.4
54
2.34.1
554
55
555
56
diff view generated by jsdifflib
New patch
1
From: Michal Orzel <michal.orzel@amd.com>
1
2
3
On an attempt to access CNTPCT_EL0 from EL0 using a guest running on top
4
of Xen, a trap from EL2 was observed which is something not reproducible
5
on HW (also, Xen does not trap accesses to physical counter).
6
7
This is because gt_counter_access() checks for an incorrect bit (1
8
instead of 0) of CNTHCTL_EL2 if HCR_EL2.E2H is 0 and access is made to
9
physical counter. Refer ARM ARM DDI 0487J.a, D19.12.2:
10
When HCR_EL2.E2H is 0:
11
- EL1PCTEN, bit [0]: refers to physical counter
12
- EL1PCEN, bit [1]: refers to physical timer registers
13
14
Drop entire block "if (hcr & HCR_E2H) {...} else {...}" from EL0 case
15
and fall through to EL1 case, given that after fixing checking for the
16
correct bit, the handling is the same.
17
18
Fixes: 5bc8437136fb ("target/arm: Update timer access for VHE")
19
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
20
Tested-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
21
Message-id: 20230928094404.20802-1-michal.orzel@amd.com
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
target/arm/helper.c | 17 +----------------
26
1 file changed, 1 insertion(+), 16 deletions(-)
27
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
33
if (!extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
34
return CP_ACCESS_TRAP;
35
}
36
-
37
- /* If HCR_EL2.<E2H,TGE> == '10': check CNTHCTL_EL2.EL1PCTEN. */
38
- if (hcr & HCR_E2H) {
39
- if (timeridx == GTIMER_PHYS &&
40
- !extract32(env->cp15.cnthctl_el2, 10, 1)) {
41
- return CP_ACCESS_TRAP_EL2;
42
- }
43
- } else {
44
- /* If HCR_EL2.<E2H> == 0: check CNTHCTL_EL2.EL1PCEN. */
45
- if (has_el2 && timeridx == GTIMER_PHYS &&
46
- !extract32(env->cp15.cnthctl_el2, 1, 1)) {
47
- return CP_ACCESS_TRAP_EL2;
48
- }
49
- }
50
- break;
51
-
52
+ /* fall through */
53
case 1:
54
/* Check CNTHCTL_EL2.EL1PCTEN, which changes location based on E2H. */
55
if (has_el2 && timeridx == GTIMER_PHYS &&
56
--
57
2.34.1
diff view generated by jsdifflib
1
In some situations it's useful to have a qdev property which doesn't
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
automatically set its default value when qdev_property_add_static is
3
called (for instance when the default value is not constant).
4
2
5
Support this by adding a flag to the Property struct indicating
3
GIC Private Peripheral Interrupts (PPI) are defined as GIC INTID 16-31.
6
whether to set the default value. This replaces the existing test
4
As in, PPI0 is INTID16 .. PPI15 is INTID31.
7
for whether the PropertyInfo set_default_value function pointer is
5
Arm's Base System Architecture specification (BSA) lists the mandated and
8
NULL, and we set the .set_default field to true for all those cases
6
recommended private interrupt IDs by INTID, not by PPI index. But current
9
of struct Property which use a PropertyInfo with a non-NULL
7
definitions in virt define them by PPI index, complicating cross
10
set_default_value, so behaviour remains the same as before.
8
referencing.
11
9
12
This gives us the semantics of:
10
Meanwhile, the PPI(x) macro counterintuitively adds 16 to the input value,
13
* if .set_default is true, then .info->set_default_value must
11
converting a PPI index to an INTID.
14
be not NULL, and .defval is used as the the default value of
15
the property
16
* otherwise, the property system does not set any default, and
17
the field will retain whatever initial value it was given by
18
the device's .instance_init method
19
12
20
We define two new macros DEFINE_PROP_SIGNED_NODEFAULT and
13
Resolve this by redefining the BSA-allocated PPIs by their INTIDs,
21
DEFINE_PROP_UNSIGNED_NODEFAULT, to cover the most plausible use cases
14
and replacing the PPI(x) macro with an INTID_TO_PPI(x) one where required.
22
of wanting to set an integer property with no default value.
23
15
24
Suggested-by: Markus Armbruster <armbru@redhat.com>
16
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
17
Message-id: 20230919090229.188092-2-quic_llindhol@quicinc.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
27
Reviewed-by: Markus Armbruster <armbru@redhat.com>
28
Message-id: 1499788408-10096-3-git-send-email-peter.maydell@linaro.org
29
---
20
---
30
include/hw/qdev-core.h | 10 ++++++++++
21
include/hw/arm/virt.h | 14 +++++++-------
31
include/hw/qdev-properties.h | 20 ++++++++++++++++++++
22
hw/arm/virt-acpi-build.c | 12 ++++++------
32
hw/core/qdev.c | 2 +-
23
hw/arm/virt.c | 24 ++++++++++++++----------
33
3 files changed, 31 insertions(+), 1 deletion(-)
24
3 files changed, 27 insertions(+), 23 deletions(-)
34
25
35
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
26
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
36
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/qdev-core.h
28
--- a/include/hw/arm/virt.h
38
+++ b/include/hw/qdev-core.h
29
+++ b/include/hw/arm/virt.h
39
@@ -XXX,XX +XXX,XX @@ struct BusState {
30
@@ -XXX,XX +XXX,XX @@
40
QLIST_ENTRY(BusState) sibling;
31
#define NUM_VIRTIO_TRANSPORTS 32
41
};
32
#define NUM_SMMU_IRQS 4
42
33
43
+/**
34
-#define ARCH_GIC_MAINT_IRQ 9
44
+ * Property:
35
+#define ARCH_GIC_MAINT_IRQ 25
45
+ * @set_default: true if the default value should be set from @defval,
36
46
+ * in which case @info->set_default_value must not be NULL
37
-#define ARCH_TIMER_VIRT_IRQ 11
47
+ * (if false then no default value is set by the property system
38
-#define ARCH_TIMER_S_EL1_IRQ 13
48
+ * and the field retains whatever value it was given by instance_init).
39
-#define ARCH_TIMER_NS_EL1_IRQ 14
49
+ * @defval: default value for the property. This is used only if @set_default
40
-#define ARCH_TIMER_NS_EL2_IRQ 10
50
+ * is true.
41
+#define ARCH_TIMER_VIRT_IRQ 27
51
+ */
42
+#define ARCH_TIMER_S_EL1_IRQ 29
52
struct Property {
43
+#define ARCH_TIMER_NS_EL1_IRQ 30
53
const char *name;
44
+#define ARCH_TIMER_NS_EL2_IRQ 26
54
const PropertyInfo *info;
45
55
ptrdiff_t offset;
46
-#define VIRTUAL_PMU_IRQ 7
56
uint8_t bitnr;
47
+#define VIRTUAL_PMU_IRQ 23
57
+ bool set_default;
48
58
union {
49
-#define PPI(irq) ((irq) + 16)
59
int64_t i;
50
+#define INTID_TO_PPI(irq) ((irq) - 16)
60
uint64_t u;
51
61
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
52
/* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */
53
#define PVTIME_SIZE_PER_CPU 64
54
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
63
--- a/include/hw/qdev-properties.h
56
--- a/hw/arm/virt-acpi-build.c
64
+++ b/include/hw/qdev-properties.h
57
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_link;
58
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
.info = &(_prop), \
59
* The interrupt values are the same with the device tree when adding 16
67
.offset = offsetof(_state, _field) \
60
*/
68
+ type_check(_type,typeof_field(_state, _field)), \
61
/* Secure EL1 timer GSIV */
69
+ .set_default = true, \
62
- build_append_int_noprefix(table_data, ARCH_TIMER_S_EL1_IRQ + 16, 4);
70
.defval.i = (_type)_defval, \
63
+ build_append_int_noprefix(table_data, ARCH_TIMER_S_EL1_IRQ, 4);
64
/* Secure EL1 timer Flags */
65
build_append_int_noprefix(table_data, irqflags, 4);
66
/* Non-Secure EL1 timer GSIV */
67
- build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL1_IRQ + 16, 4);
68
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL1_IRQ, 4);
69
/* Non-Secure EL1 timer Flags */
70
build_append_int_noprefix(table_data, irqflags |
71
1UL << 2, /* Always-on Capability */
72
4);
73
/* Virtual timer GSIV */
74
- build_append_int_noprefix(table_data, ARCH_TIMER_VIRT_IRQ + 16, 4);
75
+ build_append_int_noprefix(table_data, ARCH_TIMER_VIRT_IRQ, 4);
76
/* Virtual Timer Flags */
77
build_append_int_noprefix(table_data, irqflags, 4);
78
/* Non-Secure EL2 timer GSIV */
79
- build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_IRQ + 16, 4);
80
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_IRQ, 4);
81
/* Non-Secure EL2 timer Flags */
82
build_append_int_noprefix(table_data, irqflags, 4);
83
/* CntReadBase Physical address */
84
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
85
for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
86
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
87
uint64_t physical_base_address = 0, gich = 0, gicv = 0;
88
- uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0;
89
+ uint32_t vgic_interrupt = vms->virt ? ARCH_GIC_MAINT_IRQ : 0;
90
uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ?
91
- PPI(VIRTUAL_PMU_IRQ) : 0;
92
+ VIRTUAL_PMU_IRQ : 0;
93
94
if (vms->gic_version == VIRT_GIC_VERSION_2) {
95
physical_base_address = memmap[VIRT_GIC_CPU].base;
96
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/arm/virt.c
99
+++ b/hw/arm/virt.c
100
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
101
}
102
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
103
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
104
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
105
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
106
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
107
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
108
+ GIC_FDT_IRQ_TYPE_PPI,
109
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
110
+ GIC_FDT_IRQ_TYPE_PPI,
111
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
112
+ GIC_FDT_IRQ_TYPE_PPI,
113
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
114
+ GIC_FDT_IRQ_TYPE_PPI,
115
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
116
}
117
118
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
120
*/
121
for (i = 0; i < smp_cpus; i++) {
122
DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
123
- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
124
+ int intidbase = NUM_IRQS + i * GIC_INTERNAL;
125
/* Mapping from the output timer irq lines from the CPU to the
126
* GIC PPI inputs we use for the virt board.
127
*/
128
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
129
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
130
qdev_connect_gpio_out(cpudev, irq,
131
qdev_get_gpio_in(vms->gic,
132
- ppibase + timer_irq[irq]));
133
+ intidbase + timer_irq[irq]));
71
}
134
}
72
135
73
+#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
136
if (vms->gic_version != VIRT_GIC_VERSION_2) {
74
+ .name = (_name), \
137
qemu_irq irq = qdev_get_gpio_in(vms->gic,
75
+ .info = &(_prop), \
138
- ppibase + ARCH_GIC_MAINT_IRQ);
76
+ .offset = offsetof(_state, _field) \
139
+ intidbase + ARCH_GIC_MAINT_IRQ);
77
+ + type_check(_type, typeof_field(_state, _field)), \
140
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
78
+ }
141
0, irq);
79
+
142
} else if (vms->virt) {
80
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
143
qemu_irq irq = qdev_get_gpio_in(vms->gic,
81
.name = (_name), \
144
- ppibase + ARCH_GIC_MAINT_IRQ);
82
.info = &(qdev_prop_bit), \
145
+ intidbase + ARCH_GIC_MAINT_IRQ);
83
.bitnr = (_bit), \
146
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
84
.offset = offsetof(_state, _field) \
85
+ type_check(uint32_t,typeof_field(_state, _field)), \
86
+ .set_default = true, \
87
.defval.u = (bool)_defval, \
88
}
147
}
89
148
90
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_link;
149
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
91
.info = &(_prop), \
150
- qdev_get_gpio_in(vms->gic, ppibase
92
.offset = offsetof(_state, _field) \
151
+ qdev_get_gpio_in(vms->gic, intidbase
93
+ type_check(_type, typeof_field(_state, _field)), \
152
+ VIRTUAL_PMU_IRQ));
94
+ .set_default = true, \
153
95
.defval.u = (_type)_defval, \
154
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
96
}
155
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
97
156
if (pmu) {
98
+#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
157
assert(arm_feature(&ARM_CPU(cpu)->env, ARM_FEATURE_PMU));
99
+ .name = (_name), \
158
if (kvm_irqchip_in_kernel()) {
100
+ .info = &(_prop), \
159
- kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ));
101
+ .offset = offsetof(_state, _field) \
160
+ kvm_arm_pmu_set_irq(cpu, VIRTUAL_PMU_IRQ);
102
+ + type_check(_type, typeof_field(_state, _field)), \
161
}
103
+ }
162
kvm_arm_pmu_init(cpu);
104
+
163
}
105
#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \
106
.name = (_name), \
107
.info = &(qdev_prop_bit64), \
108
.bitnr = (_bit), \
109
.offset = offsetof(_state, _field) \
110
+ type_check(uint64_t, typeof_field(_state, _field)), \
111
+ .set_default = true, \
112
.defval.u = (bool)_defval, \
113
}
114
115
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_link;
116
.info = &(qdev_prop_bool), \
117
.offset = offsetof(_state, _field) \
118
+ type_check(bool, typeof_field(_state, _field)), \
119
+ .set_default = true, \
120
.defval.u = (bool)_defval, \
121
}
122
123
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_link;
124
_arrayfield, _arrayprop, _arraytype) { \
125
.name = (PROP_ARRAY_LEN_PREFIX _name), \
126
.info = &(qdev_prop_arraylen), \
127
+ .set_default = true, \
128
.defval.u = 0, \
129
.offset = offsetof(_state, _field) \
130
+ type_check(uint32_t, typeof_field(_state, _field)), \
131
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/core/qdev.c
134
+++ b/hw/core/qdev.c
135
@@ -XXX,XX +XXX,XX @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
136
prop->info->description,
137
&error_abort);
138
139
- if (prop->info->set_default_value) {
140
+ if (prop->set_default) {
141
prop->info->set_default_value(obj, prop);
142
}
143
}
144
--
164
--
145
2.7.4
165
2.34.1
146
147
diff view generated by jsdifflib
1
Implement a model of the Serial Communication Controller (SCC) found
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
in MPS2 FPGA images.
3
2
4
The primary purpose of this device is to communicate with the
3
virt.h defines a number of IRQs that are ultimately described by Arm's
5
Motherboard Configuration Controller (MCC) which is located on
4
Base System Architecture specification. Move these to a dedicated header
6
the MPS board itself, outside the FPGA image. This is used
5
so that they can be reused by other platforms that do the same.
7
for programming the MPS clock generators. The SCC also has
6
Include that header from virt.h to minimise churn.
8
some basic ID registers and an output for the board LEDs.
9
7
8
While we're moving the definitions, sort them into numerical order,
9
and add the ARCH_TIMER_NS_EL2_VIRT_IRQ definition used by sbsa-ref
10
and which will eventually be needed by virt also.
11
12
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
13
Message-id: 20230919090229.188092-3-quic_llindhol@quicinc.com
14
[PMM: Remove unused PPI_TO_INTID macro; sort numerically;
15
add ARCH_TIMER_NS_EL2_VIRT_IRQ]
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 1500029487-14822-7-git-send-email-peter.maydell@linaro.org
13
---
18
---
14
hw/misc/Makefile.objs | 1 +
19
include/hw/arm/bsa.h | 35 +++++++++++++++++++++++++++++++++++
15
include/hw/misc/mps2-scc.h | 43 ++++++
20
include/hw/arm/virt.h | 12 +-----------
16
hw/misc/mps2-scc.c | 310 ++++++++++++++++++++++++++++++++++++++++
21
2 files changed, 36 insertions(+), 11 deletions(-)
17
default-configs/arm-softmmu.mak | 2 +
22
create mode 100644 include/hw/arm/bsa.h
18
hw/misc/trace-events | 8 ++
19
5 files changed, 364 insertions(+)
20
create mode 100644 include/hw/misc/mps2-scc.h
21
create mode 100644 hw/misc/mps2-scc.c
22
23
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
24
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/Makefile.objs
26
+++ b/hw/misc/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
31
+obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
32
33
obj-$(CONFIG_PVPANIC) += pvpanic.o
34
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
35
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
36
new file mode 100644
25
new file mode 100644
37
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
38
--- /dev/null
27
--- /dev/null
39
+++ b/include/hw/misc/mps2-scc.h
28
+++ b/include/hw/arm/bsa.h
40
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
41
+/*
30
+/*
42
+ * ARM MPS2 SCC emulation
31
+ * Common definitions for Arm Base System Architecture (BSA) platforms.
43
+ *
32
+ *
44
+ * Copyright (c) 2017 Linaro Limited
33
+ * Copyright (c) 2015 Linaro Limited
45
+ * Written by Peter Maydell
34
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
46
+ *
35
+ *
47
+ * This program is free software; you can redistribute it and/or modify
36
+ * This program is free software; you can redistribute it and/or modify it
48
+ * it under the terms of the GNU General Public License version 2 or
37
+ * under the terms and conditions of the GNU General Public License,
49
+ * (at your option) any later version.
38
+ * version 2 or later, as published by the Free Software Foundation.
39
+ *
40
+ * This program is distributed in the hope it will be useful, but WITHOUT
41
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
43
+ * more details.
44
+ *
45
+ * You should have received a copy of the GNU General Public License along with
46
+ * this program. If not, see <http://www.gnu.org/licenses/>.
47
+ *
50
+ */
48
+ */
51
+
49
+
52
+#ifndef MPS2_SCC_H
50
+#ifndef QEMU_ARM_BSA_H
53
+#define MPS2_SCC_H
51
+#define QEMU_ARM_BSA_H
54
+
52
+
55
+#include "hw/sysbus.h"
53
+/* These are architectural INTID values */
54
+#define VIRTUAL_PMU_IRQ 23
55
+#define ARCH_GIC_MAINT_IRQ 25
56
+#define ARCH_TIMER_NS_EL2_IRQ 26
57
+#define ARCH_TIMER_VIRT_IRQ 27
58
+#define ARCH_TIMER_NS_EL2_VIRT_IRQ 28
59
+#define ARCH_TIMER_S_EL1_IRQ 29
60
+#define ARCH_TIMER_NS_EL1_IRQ 30
56
+
61
+
57
+#define TYPE_MPS2_SCC "mps2-scc"
62
+#define INTID_TO_PPI(irq) ((irq) - 16)
58
+#define MPS2_SCC(obj) OBJECT_CHECK(MPS2SCC, (obj), TYPE_MPS2_SCC)
59
+
63
+
60
+#define NUM_OSCCLK 3
64
+#endif /* QEMU_ARM_BSA_H */
61
+
65
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
62
+typedef struct {
66
index XXXXXXX..XXXXXXX 100644
63
+ /*< private >*/
67
--- a/include/hw/arm/virt.h
64
+ SysBusDevice parent_obj;
68
+++ b/include/hw/arm/virt.h
65
+
66
+ /*< public >*/
67
+ MemoryRegion iomem;
68
+
69
+ uint32_t cfg0;
70
+ uint32_t cfg1;
71
+ uint32_t cfg4;
72
+ uint32_t cfgdata_rtn;
73
+ uint32_t cfgdata_out;
74
+ uint32_t cfgctrl;
75
+ uint32_t cfgstat;
76
+ uint32_t dll;
77
+ uint32_t aid;
78
+ uint32_t id;
79
+ uint32_t oscclk[NUM_OSCCLK];
80
+ uint32_t oscclk_reset[NUM_OSCCLK];
81
+} MPS2SCC;
82
+
83
+#endif
84
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/misc/mps2-scc.c
89
@@ -XXX,XX +XXX,XX @@
69
@@ -XXX,XX +XXX,XX @@
90
+/*
70
#include "qemu/notify.h"
91
+ * ARM MPS2 SCC emulation
71
#include "hw/boards.h"
92
+ *
72
#include "hw/arm/boot.h"
93
+ * Copyright (c) 2017 Linaro Limited
73
+#include "hw/arm/bsa.h"
94
+ * Written by Peter Maydell
74
#include "hw/block/flash.h"
95
+ *
75
#include "sysemu/kvm.h"
96
+ * This program is free software; you can redistribute it and/or modify
76
#include "hw/intc/arm_gicv3_common.h"
97
+ * it under the terms of the GNU General Public License version 2 or
77
@@ -XXX,XX +XXX,XX @@
98
+ * (at your option) any later version.
78
#define NUM_VIRTIO_TRANSPORTS 32
99
+ */
79
#define NUM_SMMU_IRQS 4
100
+
80
101
+/* This is a model of the SCC (Serial Communication Controller)
81
-#define ARCH_GIC_MAINT_IRQ 25
102
+ * found in the FPGA images of MPS2 development boards.
82
-
103
+ *
83
-#define ARCH_TIMER_VIRT_IRQ 27
104
+ * Documentation of it can be found in the MPS2 TRM:
84
-#define ARCH_TIMER_S_EL1_IRQ 29
105
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
85
-#define ARCH_TIMER_NS_EL1_IRQ 30
106
+ * and also in the Application Notes documenting individual FPGA images.
86
-#define ARCH_TIMER_NS_EL2_IRQ 26
107
+ */
87
-
108
+
88
-#define VIRTUAL_PMU_IRQ 23
109
+#include "qemu/osdep.h"
89
-
110
+#include "qemu/log.h"
90
-#define INTID_TO_PPI(irq) ((irq) - 16)
111
+#include "qapi/error.h"
91
-
112
+#include "trace.h"
92
/* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */
113
+#include "hw/sysbus.h"
93
#define PVTIME_SIZE_PER_CPU 64
114
+#include "hw/registerfields.h"
94
115
+#include "hw/misc/mps2-scc.h"
116
+
117
+REG32(CFG0, 0)
118
+REG32(CFG1, 4)
119
+REG32(CFG3, 0xc)
120
+REG32(CFG4, 0x10)
121
+REG32(CFGDATA_RTN, 0xa0)
122
+REG32(CFGDATA_OUT, 0xa4)
123
+REG32(CFGCTRL, 0xa8)
124
+ FIELD(CFGCTRL, DEVICE, 0, 12)
125
+ FIELD(CFGCTRL, RES1, 12, 8)
126
+ FIELD(CFGCTRL, FUNCTION, 20, 6)
127
+ FIELD(CFGCTRL, RES2, 26, 4)
128
+ FIELD(CFGCTRL, WRITE, 30, 1)
129
+ FIELD(CFGCTRL, START, 31, 1)
130
+REG32(CFGSTAT, 0xac)
131
+ FIELD(CFGSTAT, DONE, 0, 1)
132
+ FIELD(CFGSTAT, ERROR, 1, 1)
133
+REG32(DLL, 0x100)
134
+REG32(AID, 0xFF8)
135
+REG32(ID, 0xFFC)
136
+
137
+/* Handle a write via the SYS_CFG channel to the specified function/device.
138
+ * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
139
+ */
140
+static bool scc_cfg_write(MPS2SCC *s, unsigned function,
141
+ unsigned device, uint32_t value)
142
+{
143
+ trace_mps2_scc_cfg_write(function, device, value);
144
+
145
+ if (function != 1 || device >= NUM_OSCCLK) {
146
+ qemu_log_mask(LOG_GUEST_ERROR,
147
+ "MPS2 SCC config write: bad function %d device %d\n",
148
+ function, device);
149
+ return false;
150
+ }
151
+
152
+ s->oscclk[device] = value;
153
+ return true;
154
+}
155
+
156
+/* Handle a read via the SYS_CFG channel to the specified function/device.
157
+ * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit),
158
+ * or set *value on success.
159
+ */
160
+static bool scc_cfg_read(MPS2SCC *s, unsigned function,
161
+ unsigned device, uint32_t *value)
162
+{
163
+ if (function != 1 || device >= NUM_OSCCLK) {
164
+ qemu_log_mask(LOG_GUEST_ERROR,
165
+ "MPS2 SCC config read: bad function %d device %d\n",
166
+ function, device);
167
+ return false;
168
+ }
169
+
170
+ *value = s->oscclk[device];
171
+
172
+ trace_mps2_scc_cfg_read(function, device, *value);
173
+ return true;
174
+}
175
+
176
+static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
177
+{
178
+ MPS2SCC *s = MPS2_SCC(opaque);
179
+ uint64_t r;
180
+
181
+ switch (offset) {
182
+ case A_CFG0:
183
+ r = s->cfg0;
184
+ break;
185
+ case A_CFG1:
186
+ r = s->cfg1;
187
+ break;
188
+ case A_CFG3:
189
+ /* These are user-settable DIP switches on the board. We don't
190
+ * model that, so just return zeroes.
191
+ */
192
+ r = 0;
193
+ break;
194
+ case A_CFG4:
195
+ r = s->cfg4;
196
+ break;
197
+ case A_CFGDATA_RTN:
198
+ r = s->cfgdata_rtn;
199
+ break;
200
+ case A_CFGDATA_OUT:
201
+ r = s->cfgdata_out;
202
+ break;
203
+ case A_CFGCTRL:
204
+ r = s->cfgctrl;
205
+ break;
206
+ case A_CFGSTAT:
207
+ r = s->cfgstat;
208
+ break;
209
+ case A_DLL:
210
+ r = s->dll;
211
+ break;
212
+ case A_AID:
213
+ r = s->aid;
214
+ break;
215
+ case A_ID:
216
+ r = s->id;
217
+ break;
218
+ default:
219
+ qemu_log_mask(LOG_GUEST_ERROR,
220
+ "MPS2 SCC read: bad offset %x\n", (int) offset);
221
+ r = 0;
222
+ break;
223
+ }
224
+
225
+ trace_mps2_scc_read(offset, r, size);
226
+ return r;
227
+}
228
+
229
+static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
230
+ unsigned size)
231
+{
232
+ MPS2SCC *s = MPS2_SCC(opaque);
233
+
234
+ trace_mps2_scc_write(offset, value, size);
235
+
236
+ switch (offset) {
237
+ case A_CFG0:
238
+ /* TODO on some boards bit 0 controls RAM remapping */
239
+ s->cfg0 = value;
240
+ break;
241
+ case A_CFG1:
242
+ /* CFG1 bits [7:0] control the board LEDs. We don't currently have
243
+ * a mechanism for displaying this graphically, so use a trace event.
244
+ */
245
+ trace_mps2_scc_leds(value & 0x80 ? '*' : '.',
246
+ value & 0x40 ? '*' : '.',
247
+ value & 0x20 ? '*' : '.',
248
+ value & 0x10 ? '*' : '.',
249
+ value & 0x08 ? '*' : '.',
250
+ value & 0x04 ? '*' : '.',
251
+ value & 0x02 ? '*' : '.',
252
+ value & 0x01 ? '*' : '.');
253
+ s->cfg1 = value;
254
+ break;
255
+ case A_CFGDATA_OUT:
256
+ s->cfgdata_out = value;
257
+ break;
258
+ case A_CFGCTRL:
259
+ /* Writing to CFGCTRL clears SYS_CFGSTAT */
260
+ s->cfgstat = 0;
261
+ s->cfgctrl = value & ~(R_CFGCTRL_RES1_MASK |
262
+ R_CFGCTRL_RES2_MASK |
263
+ R_CFGCTRL_START_MASK);
264
+
265
+ if (value & R_CFGCTRL_START_MASK) {
266
+ /* Start bit set -- do a read or write (instantaneously) */
267
+ int device = extract32(s->cfgctrl, R_CFGCTRL_DEVICE_SHIFT,
268
+ R_CFGCTRL_DEVICE_LENGTH);
269
+ int function = extract32(s->cfgctrl, R_CFGCTRL_FUNCTION_SHIFT,
270
+ R_CFGCTRL_FUNCTION_LENGTH);
271
+
272
+ s->cfgstat = R_CFGSTAT_DONE_MASK;
273
+ if (s->cfgctrl & R_CFGCTRL_WRITE_MASK) {
274
+ if (!scc_cfg_write(s, function, device, s->cfgdata_out)) {
275
+ s->cfgstat |= R_CFGSTAT_ERROR_MASK;
276
+ }
277
+ } else {
278
+ uint32_t result;
279
+ if (!scc_cfg_read(s, function, device, &result)) {
280
+ s->cfgstat |= R_CFGSTAT_ERROR_MASK;
281
+ } else {
282
+ s->cfgdata_rtn = result;
283
+ }
284
+ }
285
+ }
286
+ break;
287
+ case A_DLL:
288
+ /* DLL stands for Digital Locked Loop.
289
+ * Bits [31:24] (DLL_LOCK_MASK) are writable, and indicate a
290
+ * mask of which of the DLL_LOCKED bits [16:23] should be ORed
291
+ * together to determine the ALL_UNMASKED_DLLS_LOCKED bit [0].
292
+ * For QEMU, our DLLs are always locked, so we can leave bit 0
293
+ * as 1 always and don't need to recalculate it.
294
+ */
295
+ s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
296
+ break;
297
+ default:
298
+ qemu_log_mask(LOG_GUEST_ERROR,
299
+ "MPS2 SCC write: bad offset 0x%x\n", (int) offset);
300
+ break;
301
+ }
302
+}
303
+
304
+static const MemoryRegionOps mps2_scc_ops = {
305
+ .read = mps2_scc_read,
306
+ .write = mps2_scc_write,
307
+ .endianness = DEVICE_LITTLE_ENDIAN,
308
+};
309
+
310
+static void mps2_scc_reset(DeviceState *dev)
311
+{
312
+ MPS2SCC *s = MPS2_SCC(dev);
313
+ int i;
314
+
315
+ trace_mps2_scc_reset();
316
+ s->cfg0 = 0;
317
+ s->cfg1 = 0;
318
+ s->cfgdata_rtn = 0;
319
+ s->cfgdata_out = 0;
320
+ s->cfgctrl = 0x100000;
321
+ s->cfgstat = 0;
322
+ s->dll = 0xffff0001;
323
+ for (i = 0; i < NUM_OSCCLK; i++) {
324
+ s->oscclk[i] = s->oscclk_reset[i];
325
+ }
326
+}
327
+
328
+static void mps2_scc_init(Object *obj)
329
+{
330
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
331
+ MPS2SCC *s = MPS2_SCC(obj);
332
+
333
+ memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
334
+ sysbus_init_mmio(sbd, &s->iomem);
335
+}
336
+
337
+static void mps2_scc_realize(DeviceState *dev, Error **errp)
338
+{
339
+}
340
+
341
+static const VMStateDescription mps2_scc_vmstate = {
342
+ .name = "mps2-scc",
343
+ .version_id = 1,
344
+ .minimum_version_id = 1,
345
+ .fields = (VMStateField[]) {
346
+ VMSTATE_UINT32(cfg0, MPS2SCC),
347
+ VMSTATE_UINT32(cfg1, MPS2SCC),
348
+ VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
349
+ VMSTATE_UINT32(cfgdata_out, MPS2SCC),
350
+ VMSTATE_UINT32(cfgctrl, MPS2SCC),
351
+ VMSTATE_UINT32(cfgstat, MPS2SCC),
352
+ VMSTATE_UINT32(dll, MPS2SCC),
353
+ VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
354
+ VMSTATE_END_OF_LIST()
355
+ }
356
+};
357
+
358
+static Property mps2_scc_properties[] = {
359
+ /* Values for various read-only ID registers (which are specific
360
+ * to the board model or FPGA image)
361
+ */
362
+ DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, aid, 0),
363
+ DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
364
+ DEFINE_PROP_UINT32("scc-id", MPS2SCC, aid, 0),
365
+ /* These are the initial settings for the source clocks on the board.
366
+ * In hardware they can be configured via a config file read by the
367
+ * motherboard configuration controller to suit the FPGA image.
368
+ * These default values are used by most of the standard FPGA images.
369
+ */
370
+ DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
371
+ DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
372
+ DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
373
+ DEFINE_PROP_END_OF_LIST(),
374
+};
375
+
376
+static void mps2_scc_class_init(ObjectClass *klass, void *data)
377
+{
378
+ DeviceClass *dc = DEVICE_CLASS(klass);
379
+
380
+ dc->realize = mps2_scc_realize;
381
+ dc->vmsd = &mps2_scc_vmstate;
382
+ dc->reset = mps2_scc_reset;
383
+ dc->props = mps2_scc_properties;
384
+}
385
+
386
+static const TypeInfo mps2_scc_info = {
387
+ .name = TYPE_MPS2_SCC,
388
+ .parent = TYPE_SYS_BUS_DEVICE,
389
+ .instance_size = sizeof(MPS2SCC),
390
+ .instance_init = mps2_scc_init,
391
+ .class_init = mps2_scc_class_init,
392
+};
393
+
394
+static void mps2_scc_register_types(void)
395
+{
396
+ type_register_static(&mps2_scc_info);
397
+}
398
+
399
+type_init(mps2_scc_register_types);
400
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
401
index XXXXXXX..XXXXXXX 100644
402
--- a/default-configs/arm-softmmu.mak
403
+++ b/default-configs/arm-softmmu.mak
404
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F205_SOC=y
405
CONFIG_CMSDK_APB_TIMER=y
406
CONFIG_CMSDK_APB_UART=y
407
408
+CONFIG_MPS2_SCC=y
409
+
410
CONFIG_VERSATILE_PCI=y
411
CONFIG_VERSATILE_I2C=y
412
413
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
414
index XXXXXXX..XXXXXXX 100644
415
--- a/hw/misc/trace-events
416
+++ b/hw/misc/trace-events
417
@@ -XXX,XX +XXX,XX @@ milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
418
419
# hw/misc/aspeed_scu.c
420
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
421
+
422
+# hw/misc/mps2_scc.c
423
+mps2_scc_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
424
+mps2_scc_write(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
425
+mps2_scc_reset(void) "MPS2 SCC: reset"
426
+mps2_scc_leds(char led7, char led6, char led5, char led4, char led3, char led2, char led1, char led0) "MPS2 SCC LEDs: %c%c%c%c%c%c%c%c"
427
+mps2_scc_cfg_write(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config write: function %d device %d data 0x%" PRIx32
428
+mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config read: function %d device %d data 0x%" PRIx32
429
--
95
--
430
2.7.4
96
2.34.1
431
432
diff view generated by jsdifflib
New patch
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
1
2
3
Use the private peripheral interrupt definitions from bsa.h instead of
4
defining them locally. Refactor to use the INTIDs defined there instead
5
of the PPI# used previously.
6
7
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Message-id: 20230919090229.188092-4-quic_llindhol@quicinc.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/sbsa-ref.c | 21 +++++++++------------
13
1 file changed, 9 insertions(+), 12 deletions(-)
14
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
18
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@
20
* ARM SBSA Reference Platform emulation
21
*
22
* Copyright (c) 2018 Linaro Limited
23
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
24
* Written by Hongbo Zhang <hongbo.zhang@linaro.org>
25
*
26
* This program is free software; you can redistribute it and/or modify it
27
@@ -XXX,XX +XXX,XX @@
28
#include "exec/hwaddr.h"
29
#include "kvm_arm.h"
30
#include "hw/arm/boot.h"
31
+#include "hw/arm/bsa.h"
32
#include "hw/arm/fdt.h"
33
#include "hw/arm/smmuv3.h"
34
#include "hw/block/flash.h"
35
@@ -XXX,XX +XXX,XX @@
36
#define NUM_SMMU_IRQS 4
37
#define NUM_SATA_PORTS 6
38
39
-#define VIRTUAL_PMU_IRQ 7
40
-#define ARCH_GIC_MAINT_IRQ 9
41
-#define ARCH_TIMER_VIRT_IRQ 11
42
-#define ARCH_TIMER_S_EL1_IRQ 13
43
-#define ARCH_TIMER_NS_EL1_IRQ 14
44
-#define ARCH_TIMER_NS_EL2_IRQ 10
45
-#define ARCH_TIMER_NS_EL2_VIRT_IRQ 12
46
-
47
enum {
48
SBSA_FLASH,
49
SBSA_MEM,
50
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
51
*/
52
for (i = 0; i < smp_cpus; i++) {
53
DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
54
- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
55
+ int intidbase = NUM_IRQS + i * GIC_INTERNAL;
56
int irq;
57
/*
58
* Mapping from the output timer irq lines from the CPU to the
59
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
60
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
61
qdev_connect_gpio_out(cpudev, irq,
62
qdev_get_gpio_in(sms->gic,
63
- ppibase + timer_irq[irq]));
64
+ intidbase + timer_irq[irq]));
65
}
66
67
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
68
- qdev_get_gpio_in(sms->gic, ppibase
69
+ qdev_get_gpio_in(sms->gic,
70
+ intidbase
71
+ ARCH_GIC_MAINT_IRQ));
72
+
73
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
74
- qdev_get_gpio_in(sms->gic, ppibase
75
+ qdev_get_gpio_in(sms->gic,
76
+ intidbase
77
+ VIRTUAL_PMU_IRQ));
78
79
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
80
--
81
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
As a precursor to later patches attempt to come up with a more
3
We can neaten the code by switching to the kvm_set_one_reg function.
4
concrete wording for what each of the common exit cases would be.
4
5
5
Reviewed-by: Gavin Shan <gshan@redhat.com>
6
CC: Emilio G. Cota <cota@braap.org>
6
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
7
CC: Richard Henderson <rth@twiddle.net>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
CC: Lluís Vilanova <vilanova@ac.upc.edu>
8
Message-id: 20231010142453.224369-2-cohuck@redhat.com
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <rth@twiddle.net>
11
Message-id: 20170713141928.25419-2-alex.bennee@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
include/exec/exec-all.h | 29 ++++++++++++++++++++++++++---
12
target/arm/kvm.c | 13 +++------
15
1 file changed, 26 insertions(+), 3 deletions(-)
13
target/arm/kvm64.c | 66 +++++++++++++---------------------------------
16
14
2 files changed, 21 insertions(+), 58 deletions(-)
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
15
16
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
18
--- a/target/arm/kvm.c
20
+++ b/include/exec/exec-all.h
19
+++ b/target/arm/kvm.c
21
@@ -XXX,XX +XXX,XX @@ typedef abi_ulong tb_page_addr_t;
20
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
22
typedef ram_addr_t tb_page_addr_t;
21
bool ok = true;
22
23
for (i = 0; i < cpu->cpreg_array_len; i++) {
24
- struct kvm_one_reg r;
25
uint64_t regidx = cpu->cpreg_indexes[i];
26
uint32_t v32;
27
int ret;
28
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
29
continue;
30
}
31
32
- r.id = regidx;
33
switch (regidx & KVM_REG_SIZE_MASK) {
34
case KVM_REG_SIZE_U32:
35
v32 = cpu->cpreg_values[i];
36
- r.addr = (uintptr_t)&v32;
37
+ ret = kvm_set_one_reg(cs, regidx, &v32);
38
break;
39
case KVM_REG_SIZE_U64:
40
- r.addr = (uintptr_t)(cpu->cpreg_values + i);
41
+ ret = kvm_set_one_reg(cs, regidx, cpu->cpreg_values + i);
42
break;
43
default:
44
g_assert_not_reached();
45
}
46
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
47
if (ret) {
48
/* We might fail for "unknown register" and also for
49
* "you tried to set a register which is constant with
50
@@ -XXX,XX +XXX,XX @@ void kvm_arm_get_virtual_time(CPUState *cs)
51
void kvm_arm_put_virtual_time(CPUState *cs)
52
{
53
ARMCPU *cpu = ARM_CPU(cs);
54
- struct kvm_one_reg reg = {
55
- .id = KVM_REG_ARM_TIMER_CNT,
56
- .addr = (uintptr_t)&cpu->kvm_vtime,
57
- };
58
int ret;
59
60
if (!cpu->kvm_vtime_dirty) {
61
return;
62
}
63
64
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
65
+ ret = kvm_set_one_reg(cs, KVM_REG_ARM_TIMER_CNT, &cpu->kvm_vtime);
66
if (ret) {
67
error_report("Failed to set KVM_REG_ARM_TIMER_CNT");
68
abort();
69
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/kvm64.c
72
+++ b/target/arm/kvm64.c
73
@@ -XXX,XX +XXX,XX @@ static int kvm_arm_sve_set_vls(CPUState *cs)
74
{
75
ARMCPU *cpu = ARM_CPU(cs);
76
uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = { cpu->sve_vq.map };
77
- struct kvm_one_reg reg = {
78
- .id = KVM_REG_ARM64_SVE_VLS,
79
- .addr = (uint64_t)&vls[0],
80
- };
81
82
assert(cpu->sve_max_vq <= KVM_ARM64_SVE_VQ_MAX);
83
84
- return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
85
+ return kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_VLS, &vls[0]);
86
}
87
88
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
89
@@ -XXX,XX +XXX,XX @@ static void kvm_inject_arm_sea(CPUState *c)
90
static int kvm_arch_put_fpsimd(CPUState *cs)
91
{
92
CPUARMState *env = &ARM_CPU(cs)->env;
93
- struct kvm_one_reg reg;
94
int i, ret;
95
96
for (i = 0; i < 32; i++) {
97
uint64_t *q = aa64_vfp_qreg(env, i);
98
#if HOST_BIG_ENDIAN
99
uint64_t fp_val[2] = { q[1], q[0] };
100
- reg.addr = (uintptr_t)fp_val;
101
+ ret = kvm_set_one_reg(cs, AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]),
102
+ fp_val);
103
#else
104
- reg.addr = (uintptr_t)q;
105
+ ret = kvm_set_one_reg(cs, AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]), q);
23
#endif
106
#endif
24
107
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
25
-/* is_jmp field values */
108
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
26
+/* DisasContext is_jmp field values
109
if (ret) {
27
+ *
110
return ret;
28
+ * is_jmp starts as DISAS_NEXT. The translator will keep processing
111
}
29
+ * instructions until an exit condition is reached. If we reach the
112
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs)
30
+ * exit condition and is_jmp is still DISAS_NEXT (because of some
113
CPUARMState *env = &cpu->env;
31
+ * other condition) we simply "jump" to the next address.
114
uint64_t tmp[ARM_MAX_VQ * 2];
32
+ * The remaining exit cases are:
115
uint64_t *r;
33
+ *
116
- struct kvm_one_reg reg;
34
+ * DISAS_JUMP - Only the PC was modified dynamically (e.g computed)
117
int n, ret;
35
+ * DISAS_TB_JUMP - Only the PC was modified statically (e.g. branch)
118
36
+ *
119
for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
37
+ * In these cases as long as the PC is updated we can chain to the
120
r = sve_bswap64(tmp, &env->vfp.zregs[n].d[0], cpu->sve_max_vq * 2);
38
+ * next TB either by exiting the loop or looking up the next TB via
121
- reg.addr = (uintptr_t)r;
39
+ * the loookup helper.
122
- reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
40
+ *
123
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
41
+ * DISAS_UPDATE - CPU State was modified dynamically
124
+ ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_ZREG(n, 0), r);
42
+ *
125
if (ret) {
43
+ * This covers any other CPU state which necessities us exiting the
126
return ret;
44
+ * TCG code to the main run-loop. Typically this includes anything
127
}
45
+ * that might change the interrupt state.
128
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs)
46
+ *
129
for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
47
+ * Individual translators may define additional exit cases to deal
130
r = sve_bswap64(tmp, r = &env->vfp.pregs[n].p[0],
48
+ * with per-target special conditions.
131
DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
49
+ */
132
- reg.addr = (uintptr_t)r;
50
#define DISAS_NEXT 0 /* next instruction can be analyzed */
133
- reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
51
#define DISAS_JUMP 1 /* only pc was modified dynamically */
134
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
52
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
135
+ ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_PREG(n, 0), r);
53
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
136
if (ret) {
54
+#define DISAS_TB_JUMP 2 /* only pc was modified statically */
137
return ret;
55
+#define DISAS_UPDATE 3 /* cpu state was modified dynamically */
138
}
56
139
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs)
57
#include "qemu/log.h"
140
58
141
r = sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0],
142
DIV_ROUND_UP(cpu->sve_max_vq * 2, 8));
143
- reg.addr = (uintptr_t)r;
144
- reg.id = KVM_REG_ARM64_SVE_FFR(0);
145
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
146
+ ret = kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r);
147
if (ret) {
148
return ret;
149
}
150
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_put_sve(CPUState *cs)
151
152
int kvm_arch_put_registers(CPUState *cs, int level)
153
{
154
- struct kvm_one_reg reg;
155
uint64_t val;
156
uint32_t fpr;
157
int i, ret;
158
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
159
}
160
161
for (i = 0; i < 31; i++) {
162
- reg.id = AARCH64_CORE_REG(regs.regs[i]);
163
- reg.addr = (uintptr_t) &env->xregs[i];
164
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
165
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(regs.regs[i]),
166
+ &env->xregs[i]);
167
if (ret) {
168
return ret;
169
}
170
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
171
*/
172
aarch64_save_sp(env, 1);
173
174
- reg.id = AARCH64_CORE_REG(regs.sp);
175
- reg.addr = (uintptr_t) &env->sp_el[0];
176
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
177
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(regs.sp), &env->sp_el[0]);
178
if (ret) {
179
return ret;
180
}
181
182
- reg.id = AARCH64_CORE_REG(sp_el1);
183
- reg.addr = (uintptr_t) &env->sp_el[1];
184
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
185
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(sp_el1), &env->sp_el[1]);
186
if (ret) {
187
return ret;
188
}
189
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
190
} else {
191
val = cpsr_read(env);
192
}
193
- reg.id = AARCH64_CORE_REG(regs.pstate);
194
- reg.addr = (uintptr_t) &val;
195
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
196
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(regs.pstate), &val);
197
if (ret) {
198
return ret;
199
}
200
201
- reg.id = AARCH64_CORE_REG(regs.pc);
202
- reg.addr = (uintptr_t) &env->pc;
203
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
204
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(regs.pc), &env->pc);
205
if (ret) {
206
return ret;
207
}
208
209
- reg.id = AARCH64_CORE_REG(elr_el1);
210
- reg.addr = (uintptr_t) &env->elr_el[1];
211
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
212
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(elr_el1), &env->elr_el[1]);
213
if (ret) {
214
return ret;
215
}
216
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
217
218
/* KVM 0-4 map to QEMU banks 1-5 */
219
for (i = 0; i < KVM_NR_SPSR; i++) {
220
- reg.id = AARCH64_CORE_REG(spsr[i]);
221
- reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
222
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
223
+ ret = kvm_set_one_reg(cs, AARCH64_CORE_REG(spsr[i]),
224
+ &env->banked_spsr[i + 1]);
225
if (ret) {
226
return ret;
227
}
228
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
229
return ret;
230
}
231
232
- reg.addr = (uintptr_t)(&fpr);
233
fpr = vfp_get_fpsr(env);
234
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
235
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
236
+ ret = kvm_set_one_reg(cs, AARCH64_SIMD_CTRL_REG(fp_regs.fpsr), &fpr);
237
if (ret) {
238
return ret;
239
}
240
241
- reg.addr = (uintptr_t)(&fpr);
242
fpr = vfp_get_fpcr(env);
243
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
244
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
245
+ ret = kvm_set_one_reg(cs, AARCH64_SIMD_CTRL_REG(fp_regs.fpcr), &fpr);
246
if (ret) {
247
return ret;
248
}
59
--
249
--
60
2.7.4
250
2.34.1
61
251
62
252
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
Previously DISAS_JUMP did ensure this but with the optimisation of
3
We can neaten the code by switching the callers that work on a
4
8a6b28c7 (optimize indirect branches) we might not leave the loop.
4
CPUstate to the kvm_get_one_reg function.
5
This means if any pending interrupts are cleared by changing IRQ flags
5
6
we might never get around to servicing them. You usually notice this
6
Reviewed-by: Gavin Shan <gshan@redhat.com>
7
by seeing the lookup_tb_ptr() helper gainfully chaining TBs together
7
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
8
while cpu->interrupt_request remains high and the exit_request has not
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
been set.
9
Message-id: 20231010142453.224369-3-cohuck@redhat.com
10
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
This breaks amongst other things the OPTEE test suite which executes
12
an eret from the secure world after a non-secure world IRQ has gone
13
pending which then never gets serviced.
14
15
Instead of using the previously implied semantics of DISAS_JUMP we use
16
DISAS_EXIT which will always exit the run-loop.
17
18
CC: Etienne Carriere <etienne.carriere@linaro.org>
19
CC: Joakim Bech <joakim.bech@linaro.org>
20
CC: Jaroslaw Pelczar <j.pelczar@samsung.com>
21
CC: Peter Maydell <peter.maydell@linaro.org>
22
CC: Emilio G. Cota <cota@braap.org>
23
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
24
Reviewed-by: Richard Henderson <rth@twiddle.net>
25
Message-id: 20170713141928.25419-7-alex.bennee@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
12
---
28
target/arm/translate-a64.c | 3 ++-
13
target/arm/kvm.c | 15 +++---------
29
target/arm/translate.c | 6 ++++--
14
target/arm/kvm64.c | 57 ++++++++++++----------------------------------
30
2 files changed, 6 insertions(+), 3 deletions(-)
15
2 files changed, 18 insertions(+), 54 deletions(-)
31
16
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
33
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
19
--- a/target/arm/kvm.c
35
+++ b/target/arm/translate-a64.c
20
+++ b/target/arm/kvm.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu)
37
return;
22
bool ok = true;
38
}
23
39
gen_helper_exception_return(cpu_env);
24
for (i = 0; i < cpu->cpreg_array_len; i++) {
40
- s->is_jmp = DISAS_JUMP;
25
- struct kvm_one_reg r;
41
+ /* Must exit loop to check un-masked IRQs */
26
uint64_t regidx = cpu->cpreg_indexes[i];
42
+ s->is_jmp = DISAS_EXIT;
27
uint32_t v32;
43
return;
28
int ret;
44
case 5: /* DRPS */
29
45
if (rn != 0x1f) {
30
- r.id = regidx;
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
-
47
index XXXXXXX..XXXXXXX 100644
32
switch (regidx & KVM_REG_SIZE_MASK) {
48
--- a/target/arm/translate.c
33
case KVM_REG_SIZE_U32:
49
+++ b/target/arm/translate.c
34
- r.addr = (uintptr_t)&v32;
50
@@ -XXX,XX +XXX,XX @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
35
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
51
*/
36
+ ret = kvm_get_one_reg(cs, regidx, &v32);
52
gen_helper_cpsr_write_eret(cpu_env, cpsr);
37
if (!ret) {
53
tcg_temp_free_i32(cpsr);
38
cpu->cpreg_values[i] = v32;
54
- s->is_jmp = DISAS_JUMP;
55
+ /* Must exit loop to check un-masked IRQs */
56
+ s->is_jmp = DISAS_EXIT;
57
}
58
59
/* Generate an old-style exception return. Marks pc as dead. */
60
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
61
tmp = load_cpu_field(spsr);
62
gen_helper_cpsr_write_eret(cpu_env, tmp);
63
tcg_temp_free_i32(tmp);
64
- s->is_jmp = DISAS_JUMP;
65
+ /* Must exit loop to check un-masked IRQs */
66
+ s->is_jmp = DISAS_EXIT;
67
}
68
}
39
}
69
break;
40
break;
41
case KVM_REG_SIZE_U64:
42
- r.addr = (uintptr_t)(cpu->cpreg_values + i);
43
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
44
+ ret = kvm_get_one_reg(cs, regidx, cpu->cpreg_values + i);
45
break;
46
default:
47
g_assert_not_reached();
48
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu)
49
void kvm_arm_get_virtual_time(CPUState *cs)
50
{
51
ARMCPU *cpu = ARM_CPU(cs);
52
- struct kvm_one_reg reg = {
53
- .id = KVM_REG_ARM_TIMER_CNT,
54
- .addr = (uintptr_t)&cpu->kvm_vtime,
55
- };
56
int ret;
57
58
if (cpu->kvm_vtime_dirty) {
59
return;
60
}
61
62
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
63
+ ret = kvm_get_one_reg(cs, KVM_REG_ARM_TIMER_CNT, &cpu->kvm_vtime);
64
if (ret) {
65
error_report("Failed to get KVM_REG_ARM_TIMER_CNT");
66
abort();
67
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/kvm64.c
70
+++ b/target/arm/kvm64.c
71
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
72
static int kvm_arch_get_fpsimd(CPUState *cs)
73
{
74
CPUARMState *env = &ARM_CPU(cs)->env;
75
- struct kvm_one_reg reg;
76
int i, ret;
77
78
for (i = 0; i < 32; i++) {
79
uint64_t *q = aa64_vfp_qreg(env, i);
80
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
81
- reg.addr = (uintptr_t)q;
82
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
83
+ ret = kvm_get_one_reg(cs, AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]), q);
84
if (ret) {
85
return ret;
86
} else {
87
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs)
88
{
89
ARMCPU *cpu = ARM_CPU(cs);
90
CPUARMState *env = &cpu->env;
91
- struct kvm_one_reg reg;
92
uint64_t *r;
93
int n, ret;
94
95
for (n = 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) {
96
r = &env->vfp.zregs[n].d[0];
97
- reg.addr = (uintptr_t)r;
98
- reg.id = KVM_REG_ARM64_SVE_ZREG(n, 0);
99
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
100
+ ret = kvm_get_one_reg(cs, KVM_REG_ARM64_SVE_ZREG(n, 0), r);
101
if (ret) {
102
return ret;
103
}
104
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs)
105
106
for (n = 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) {
107
r = &env->vfp.pregs[n].p[0];
108
- reg.addr = (uintptr_t)r;
109
- reg.id = KVM_REG_ARM64_SVE_PREG(n, 0);
110
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
111
+ ret = kvm_get_one_reg(cs, KVM_REG_ARM64_SVE_PREG(n, 0), r);
112
if (ret) {
113
return ret;
114
}
115
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs)
116
}
117
118
r = &env->vfp.pregs[FFR_PRED_NUM].p[0];
119
- reg.addr = (uintptr_t)r;
120
- reg.id = KVM_REG_ARM64_SVE_FFR(0);
121
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
122
+ ret = kvm_get_one_reg(cs, KVM_REG_ARM64_SVE_FFR(0), r);
123
if (ret) {
124
return ret;
125
}
126
@@ -XXX,XX +XXX,XX @@ static int kvm_arch_get_sve(CPUState *cs)
127
128
int kvm_arch_get_registers(CPUState *cs)
129
{
130
- struct kvm_one_reg reg;
131
uint64_t val;
132
unsigned int el;
133
uint32_t fpr;
134
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
135
CPUARMState *env = &cpu->env;
136
137
for (i = 0; i < 31; i++) {
138
- reg.id = AARCH64_CORE_REG(regs.regs[i]);
139
- reg.addr = (uintptr_t) &env->xregs[i];
140
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
141
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(regs.regs[i]),
142
+ &env->xregs[i]);
143
if (ret) {
144
return ret;
145
}
146
}
147
148
- reg.id = AARCH64_CORE_REG(regs.sp);
149
- reg.addr = (uintptr_t) &env->sp_el[0];
150
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
151
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(regs.sp), &env->sp_el[0]);
152
if (ret) {
153
return ret;
154
}
155
156
- reg.id = AARCH64_CORE_REG(sp_el1);
157
- reg.addr = (uintptr_t) &env->sp_el[1];
158
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
159
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(sp_el1), &env->sp_el[1]);
160
if (ret) {
161
return ret;
162
}
163
164
- reg.id = AARCH64_CORE_REG(regs.pstate);
165
- reg.addr = (uintptr_t) &val;
166
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
167
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(regs.pstate), &val);
168
if (ret) {
169
return ret;
170
}
171
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
172
*/
173
aarch64_restore_sp(env, 1);
174
175
- reg.id = AARCH64_CORE_REG(regs.pc);
176
- reg.addr = (uintptr_t) &env->pc;
177
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
178
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(regs.pc), &env->pc);
179
if (ret) {
180
return ret;
181
}
182
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
183
aarch64_sync_64_to_32(env);
184
}
185
186
- reg.id = AARCH64_CORE_REG(elr_el1);
187
- reg.addr = (uintptr_t) &env->elr_el[1];
188
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
189
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(elr_el1), &env->elr_el[1]);
190
if (ret) {
191
return ret;
192
}
193
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
194
* KVM SPSRs 0-4 map to QEMU banks 1-5
195
*/
196
for (i = 0; i < KVM_NR_SPSR; i++) {
197
- reg.id = AARCH64_CORE_REG(spsr[i]);
198
- reg.addr = (uintptr_t) &env->banked_spsr[i + 1];
199
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
200
+ ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(spsr[i]),
201
+ &env->banked_spsr[i + 1]);
202
if (ret) {
203
return ret;
204
}
205
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
206
return ret;
207
}
208
209
- reg.addr = (uintptr_t)(&fpr);
210
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
211
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
212
+ ret = kvm_get_one_reg(cs, AARCH64_SIMD_CTRL_REG(fp_regs.fpsr), &fpr);
213
if (ret) {
214
return ret;
215
}
216
vfp_set_fpsr(env, fpr);
217
218
- reg.addr = (uintptr_t)(&fpr);
219
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
220
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
221
+ ret = kvm_get_one_reg(cs, AARCH64_SIMD_CTRL_REG(fp_regs.fpcr), &fpr);
222
if (ret) {
223
return ret;
224
}
70
--
225
--
71
2.7.4
226
2.34.1
72
227
73
228
diff view generated by jsdifflib
1
The Cortex-M3 and M4 CPUs always have 8 PMSA MPU regions (this isn't
1
For the Thumb T32 encoding of LDM, if only a single register is
2
a configurable option for the hardware). Make the default value of
2
specified in the register list this instruction is UNPREDICTABLE,
3
the pmsav7-dregion property be set per-cpu, so we don't need to have
3
with the following choices:
4
every user of these CPUs set it manually. (The existing default of
4
* instruction UNDEFs
5
16 is correct for the other PMSAv7 core, the Cortex-R5.)
5
* instruction is a NOP
6
* instruction loads a single register
7
* instruction loads an unspecified set of registers
6
8
7
This fixes a bug where we were creating the M3 and M4 with
9
Currently we choose to UNDEF (a behaviour chosen in commit
8
too many regions; most guest software would not notice or
10
4b222545dbf30 in 2019; previously we treated it as "load the
9
care, though, since it would just not use the registers
11
specified single register").
10
associated with the unexpected extra regions.
11
12
13
Unfortunately there is real world code out there (which shipped in at
14
least Android 11, 12 and 13) which incorrectly uses this
15
UNPREDICTABLE insn on the assumption that it does a single register
16
load, which is (presumably) what it happens to do on real hardware,
17
and is also what it does on the equivalent A32 encoding.
18
19
Revert to the pre-4b222545dbf30 behaviour of not UNDEFing
20
for this T32 encoding.
21
22
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1799
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
24
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 1499788408-10096-4-git-send-email-peter.maydell@linaro.org
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20230927101853.39288-1-peter.maydell@linaro.org
15
---
27
---
16
target/arm/cpu.c | 12 +++++++++++-
28
target/arm/tcg/translate.c | 37 +++++++++++++++++++++++--------------
17
1 file changed, 11 insertions(+), 1 deletion(-)
29
1 file changed, 23 insertions(+), 14 deletions(-)
18
30
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
20
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
33
--- a/target/arm/tcg/translate.c
22
+++ b/target/arm/cpu.c
34
+++ b/target/arm/tcg/translate.c
23
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_pmu_property =
35
@@ -XXX,XX +XXX,XX @@ static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
24
static Property arm_cpu_has_mpu_property =
36
}
25
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
37
}
26
38
27
+/* This is like DEFINE_PROP_UINT32 but it doesn't set the default value,
39
-static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
28
+ * because the CPU initfn will have already set cpu->pmsav7_dregion to
40
+static bool op_stm(DisasContext *s, arg_ldst_block *a)
29
+ * the right value for that particular CPU type, and we don't want
30
+ * to override that with an incorrect constant value.
31
+ */
32
static Property arm_cpu_pmsav7_dregion_property =
33
- DEFINE_PROP_UINT32("pmsav7-dregion", ARMCPU, pmsav7_dregion, 16);
34
+ DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU,
35
+ pmsav7_dregion,
36
+ qdev_prop_uint32, uint32_t);
37
38
static void arm_cpu_post_init(Object *obj)
39
{
41
{
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
42
int i, j, n, list, mem_idx;
41
set_feature(&cpu->env, ARM_FEATURE_V7);
43
bool user = a->u;
42
set_feature(&cpu->env, ARM_FEATURE_M);
44
@@ -XXX,XX +XXX,XX @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
43
cpu->midr = 0x410fc231;
45
44
+ cpu->pmsav7_dregion = 8;
46
list = a->list;
47
n = ctpop16(list);
48
- if (n < min_n || a->rn == 15) {
49
+ /*
50
+ * This is UNPREDICTABLE for n < 1 in all encodings, and we choose
51
+ * to UNDEF. In the T32 STM encoding n == 1 is also UNPREDICTABLE,
52
+ * but hardware treats it like the A32 version and implements the
53
+ * single-register-store, and some in-the-wild (buggy) software
54
+ * assumes that, so we don't UNDEF on that case.
55
+ */
56
+ if (n < 1 || a->rn == 15) {
57
unallocated_encoding(s);
58
return true;
59
}
60
@@ -XXX,XX +XXX,XX @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
61
62
static bool trans_STM(DisasContext *s, arg_ldst_block *a)
63
{
64
- /* BitCount(list) < 1 is UNPREDICTABLE */
65
- return op_stm(s, a, 1);
66
+ return op_stm(s, a);
45
}
67
}
46
68
47
static void cortex_m4_initfn(Object *obj)
69
static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
70
@@ -XXX,XX +XXX,XX @@ static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
49
set_feature(&cpu->env, ARM_FEATURE_M);
71
unallocated_encoding(s);
50
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
72
return true;
51
cpu->midr = 0x410fc240; /* r0p0 */
73
}
52
+ cpu->pmsav7_dregion = 8;
74
- /* BitCount(list) < 2 is UNPREDICTABLE */
75
- return op_stm(s, a, 2);
76
+ return op_stm(s, a);
53
}
77
}
54
static void arm_v7m_class_init(ObjectClass *oc, void *data)
78
79
-static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
80
+static bool do_ldm(DisasContext *s, arg_ldst_block *a)
55
{
81
{
56
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
82
int i, j, n, list, mem_idx;
57
cpu->id_isar4 = 0x0010142;
83
bool loaded_base;
58
cpu->id_isar5 = 0x0;
84
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
59
cpu->mp_is_up = true;
85
60
+ cpu->pmsav7_dregion = 16;
86
list = a->list;
61
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
87
n = ctpop16(list);
88
- if (n < min_n || a->rn == 15) {
89
+ /*
90
+ * This is UNPREDICTABLE for n < 1 in all encodings, and we choose
91
+ * to UNDEF. In the T32 LDM encoding n == 1 is also UNPREDICTABLE,
92
+ * but hardware treats it like the A32 version and implements the
93
+ * single-register-load, and some in-the-wild (buggy) software
94
+ * assumes that, so we don't UNDEF on that case.
95
+ */
96
+ if (n < 1 || a->rn == 15) {
97
unallocated_encoding(s);
98
return true;
99
}
100
@@ -XXX,XX +XXX,XX @@ static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
101
unallocated_encoding(s);
102
return true;
103
}
104
- /* BitCount(list) < 1 is UNPREDICTABLE */
105
- return do_ldm(s, a, 1);
106
+ return do_ldm(s, a);
62
}
107
}
63
108
109
static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
110
@@ -XXX,XX +XXX,XX @@ static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
111
unallocated_encoding(s);
112
return true;
113
}
114
- /* BitCount(list) < 2 is UNPREDICTABLE */
115
- return do_ldm(s, a, 2);
116
+ return do_ldm(s, a);
117
}
118
119
static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
120
{
121
/* Writeback is conditional on the base register not being loaded. */
122
a->w = !(a->list & (1 << a->rn));
123
- /* BitCount(list) < 1 is UNPREDICTABLE */
124
- return do_ldm(s, a, 1);
125
+ return do_ldm(s, a);
126
}
127
128
static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
64
--
129
--
65
2.7.4
130
2.34.1
66
131
67
132
diff view generated by jsdifflib
1
The MPS2 FPGA images support ethernet via a LAN9220. We use
1
Update the SMMUv3 ID register bit field definitions to the
2
QEMU's LAN9118 model, which is software compatible except
2
set in the most recent specification (IHI0700 F.a).
3
that it is missing the checksum-offload feature.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 1500029487-14822-9-git-send-email-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Mostafa Saleh <smostafa@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20230914145705.1648377-2-peter.maydell@linaro.org
9
---
9
---
10
hw/arm/mps2.c | 10 +++++++++-
10
hw/arm/smmuv3-internal.h | 38 ++++++++++++++++++++++++++++++++++++++
11
1 file changed, 9 insertions(+), 1 deletion(-)
11
1 file changed, 38 insertions(+)
12
12
13
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
13
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2.c
15
--- a/hw/arm/smmuv3-internal.h
16
+++ b/hw/arm/mps2.c
16
+++ b/hw/arm/smmuv3-internal.h
17
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ REG32(IDR0, 0x0)
18
#include "hw/char/cmsdk-apb-uart.h"
18
FIELD(IDR0, S1P, 1 , 1)
19
#include "hw/timer/cmsdk-apb-timer.h"
19
FIELD(IDR0, TTF, 2 , 2)
20
#include "hw/misc/mps2-scc.h"
20
FIELD(IDR0, COHACC, 4 , 1)
21
+#include "hw/devices.h"
21
+ FIELD(IDR0, BTM, 5 , 1)
22
+#include "net/net.h"
22
+ FIELD(IDR0, HTTU, 6 , 2)
23
23
+ FIELD(IDR0, DORMHINT, 8 , 1)
24
typedef enum MPS2FPGAType {
24
+ FIELD(IDR0, HYP, 9 , 1)
25
FPGA_AN385,
25
+ FIELD(IDR0, ATS, 10, 1)
26
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
26
+ FIELD(IDR0, NS1ATS, 11, 1)
27
create_unimplemented_device("Extra peripheral region @0x40020000",
27
FIELD(IDR0, ASID16, 12, 1)
28
0x40020000, 0x00010000);
28
+ FIELD(IDR0, MSI, 13, 1)
29
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
29
+ FIELD(IDR0, SEV, 14, 1)
30
- create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
30
+ FIELD(IDR0, ATOS, 15, 1)
31
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
31
+ FIELD(IDR0, PRI, 16, 1)
32
32
+ FIELD(IDR0, VMW, 17, 1)
33
switch (mmc->fpga_type) {
33
FIELD(IDR0, VMID16, 18, 1)
34
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
34
+ FIELD(IDR0, CD2L, 19, 1)
35
&error_fatal);
35
+ FIELD(IDR0, VATOS, 20, 1)
36
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
36
FIELD(IDR0, TTENDIAN, 21, 2)
37
37
+ FIELD(IDR0, ATSRECERR, 23, 1)
38
+ /* In hardware this is a LAN9220; the LAN9118 is software compatible
38
FIELD(IDR0, STALL_MODEL, 24, 2)
39
+ * except that it doesn't support the checksum-offload feature.
39
FIELD(IDR0, TERM_MODEL, 26, 1)
40
+ */
40
FIELD(IDR0, STLEVEL, 27, 2)
41
+ lan9118_init(&nd_table[0], 0x40200000,
41
+ FIELD(IDR0, RME_IMPL, 30, 1)
42
+ qdev_get_gpio_in(armv7m,
42
43
+ mmc->fpga_type == FPGA_AN385 ? 13 : 47));
43
REG32(IDR1, 0x4)
44
FIELD(IDR1, SIDSIZE, 0 , 6)
45
+ FIELD(IDR1, SSIDSIZE, 6 , 5)
46
+ FIELD(IDR1, PRIQS, 11, 5)
47
FIELD(IDR1, EVENTQS, 16, 5)
48
FIELD(IDR1, CMDQS, 21, 5)
49
+ FIELD(IDR1, ATTR_PERMS_OVR, 26, 1)
50
+ FIELD(IDR1, ATTR_TYPES_OVR, 27, 1)
51
+ FIELD(IDR1, REL, 28, 1)
52
+ FIELD(IDR1, QUEUES_PRESET, 29, 1)
53
+ FIELD(IDR1, TABLES_PRESET, 30, 1)
54
+ FIELD(IDR1, ECMDQ, 31, 1)
55
56
#define SMMU_IDR1_SIDSIZE 16
57
#define SMMU_CMDQS 19
58
#define SMMU_EVENTQS 19
59
60
REG32(IDR2, 0x8)
61
+ FIELD(IDR2, BA_VATOS, 0, 10)
44
+
62
+
45
system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
63
REG32(IDR3, 0xc)
46
64
FIELD(IDR3, HAD, 2, 1);
47
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
65
+ FIELD(IDR3, PBHA, 3, 1);
66
+ FIELD(IDR3, XNX, 4, 1);
67
+ FIELD(IDR3, PPS, 5, 1);
68
+ FIELD(IDR3, MPAM, 7, 1);
69
+ FIELD(IDR3, FWB, 8, 1);
70
+ FIELD(IDR3, STT, 9, 1);
71
FIELD(IDR3, RIL, 10, 1);
72
FIELD(IDR3, BBML, 11, 2);
73
+ FIELD(IDR3, E0PD, 13, 1);
74
+ FIELD(IDR3, PTWNNC, 14, 1);
75
+ FIELD(IDR3, DPT, 15, 1);
76
+
77
REG32(IDR4, 0x10)
78
+
79
REG32(IDR5, 0x14)
80
FIELD(IDR5, OAS, 0, 3);
81
FIELD(IDR5, GRAN4K, 4, 1);
82
FIELD(IDR5, GRAN16K, 5, 1);
83
FIELD(IDR5, GRAN64K, 6, 1);
84
+ FIELD(IDR5, VAX, 10, 2);
85
+ FIELD(IDR5, STALL_MAX, 16, 16);
86
87
#define SMMU_IDR5_OAS 4
88
48
--
89
--
49
2.7.4
90
2.34.1
50
51
diff view generated by jsdifflib
New patch
1
In smmuv3_init_regs() when we set the various bits in the ID
2
registers, we do this almost in order of the fields in the
3
registers, but not quite. Move the initialization of
4
SMMU_IDR3.RIL and SMMU_IDR5.OAS into their correct places.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 20230914145705.1648377-3-peter.maydell@linaro.org
11
---
12
hw/arm/smmuv3.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/smmuv3.c
18
+++ b/hw/arm/smmuv3.c
19
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
20
s->idr[1] = FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS);
21
s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS);
22
23
- s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
24
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, HAD, 1);
25
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
26
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, BBML, 2);
27
28
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
29
/* 4K, 16K and 64K granule support */
30
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
31
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
32
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
33
- s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
34
35
s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
36
s->cmdq.prod = 0;
37
--
38
2.34.1
diff view generated by jsdifflib
1
Add the CMSDK APB timers to the MPS2 board.
1
The SMMUv3.1-XNX feature is mandatory for an SMMUv3.1 if S2P is
2
supported, so we should theoretically have implemented it as part of
3
the recent S2P work. Fortunately, for us the implementation is a
4
no-op.
5
6
This feature is about interpretation of the stage 2 page table
7
descriptor XN bits, which control execute permissions.
8
9
For QEMU, the permission bits passed to an IOMMU (via MemTxAttrs and
10
IOMMUAccessFlags) only indicate read and write; we do not distinguish
11
data reads from instruction reads outside the CPU proper. In the
12
SMMU architecture's terms, our interconnect between the client device
13
and the SMMU doesn't have the ability to convey the INST attribute,
14
and we therefore use the default value of "data" for this attribute.
15
16
We also do not support the bits in the Stream Table Entry that can
17
override the on-the-bus transaction attribute permissions (we do not
18
set SMMU_IDR1.ATTR_PERMS_OVR=1).
19
20
These two things together mean that for our implementation, it never
21
has to deal with transactions with the INST attribute, and so it can
22
correctly ignore the XN bits entirely. So we already implement
23
FEAT_XNX's "XN field is now 2 bits, not 1" behaviour to the extent
24
that we need to.
25
26
Advertise the presence of the feature in SMMU_IDR3.XNX.
2
27
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1500029487-14822-6-git-send-email-peter.maydell@linaro.org
30
Reviewed-by: Mostafa Saleh <smostafa@google.com>
31
Reviewed-by: Eric Auger <eric.auger@redhat.com>
32
Message-id: 20230914145705.1648377-4-peter.maydell@linaro.org
6
---
33
---
7
hw/arm/mps2.c | 4 ++++
34
hw/arm/smmuv3.c | 4 ++++
8
1 file changed, 4 insertions(+)
35
1 file changed, 4 insertions(+)
9
36
10
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
37
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
11
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mps2.c
39
--- a/hw/arm/smmuv3.c
13
+++ b/hw/arm/mps2.c
40
+++ b/hw/arm/smmuv3.c
14
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
15
#include "sysemu/sysemu.h"
42
s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS);
16
#include "hw/misc/unimp.h"
43
17
#include "hw/char/cmsdk-apb-uart.h"
44
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, HAD, 1);
18
+#include "hw/timer/cmsdk-apb-timer.h"
45
+ if (FIELD_EX32(s->idr[0], IDR0, S2P)) {
19
46
+ /* XNX is a stage-2-specific feature */
20
typedef enum MPS2FPGAType {
47
+ s->idr[3] = FIELD_DP32(s->idr[3], IDR3, XNX, 1);
21
FPGA_AN385,
48
+ }
22
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
49
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
23
g_assert_not_reached();
50
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, BBML, 2);
24
}
51
25
26
+ cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
27
+ cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
28
+
29
system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
30
31
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
32
--
52
--
33
2.7.4
53
2.34.1
34
35
diff view generated by jsdifflib
1
Add the SCC to the MPS2 board models.
1
FEAT_HPMN0 is a small feature which defines that it is valid for
2
MDCR_EL2.HPMN to be set to 0, meaning "no PMU event counters provided
3
to an EL1 guest" (previously this setting was reserved). QEMU's
4
implementation almost gets HPMN == 0 right, but we need to fix
5
one check in pmevcntr_is_64_bit(). That is enough for us to
6
advertise the feature in the 'max' CPU.
7
8
(We don't need to make the behaviour conditional on feature
9
presence, because the FEAT_HPMN0 behaviour is within the range
10
of permitted UNPREDICTABLE behaviour for a non-FEAT_HPMN0
11
implementation.)
2
12
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1500029487-14822-8-git-send-email-peter.maydell@linaro.org
15
Message-id: 20230921185445.3339214-1-peter.maydell@linaro.org
6
---
16
---
7
hw/arm/mps2.c | 17 ++++++++++++++++-
17
docs/system/arm/emulation.rst | 1 +
8
1 file changed, 16 insertions(+), 1 deletion(-)
18
target/arm/helper.c | 2 +-
19
target/arm/tcg/cpu32.c | 4 ++++
20
target/arm/tcg/cpu64.c | 1 +
21
4 files changed, 7 insertions(+), 1 deletion(-)
9
22
10
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
11
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/mps2.c
25
--- a/docs/system/arm/emulation.rst
13
+++ b/hw/arm/mps2.c
26
+++ b/docs/system/arm/emulation.rst
14
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
15
#include "hw/misc/unimp.h"
28
- FEAT_HCX (Support for the HCRX_EL2 register)
16
#include "hw/char/cmsdk-apb-uart.h"
29
- FEAT_HPDS (Hierarchical permission disables)
17
#include "hw/timer/cmsdk-apb-timer.h"
30
- FEAT_HPDS2 (Translation table page-based hardware attributes)
18
+#include "hw/misc/mps2-scc.h"
31
+- FEAT_HPMN0 (Setting of MDCR_EL2.HPMN to zero)
19
32
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
20
typedef enum MPS2FPGAType {
33
- FEAT_IDST (ID space trap handling)
21
FPGA_AN385,
34
- FEAT_IESB (Implicit error synchronization event)
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
MachineClass parent;
36
index XXXXXXX..XXXXXXX 100644
24
MPS2FPGAType fpga_type;
37
--- a/target/arm/helper.c
25
const char *cpu_model;
38
+++ b/target/arm/helper.c
26
+ uint32_t scc_id;
39
@@ -XXX,XX +XXX,XX @@ static bool pmevcntr_is_64_bit(CPUARMState *env, int counter)
27
} MPS2MachineClass;
40
bool hlp = env->cp15.mdcr_el2 & MDCR_HLP;
28
41
int hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
29
typedef struct {
42
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
43
- if (hpmn != 0 && counter >= hpmn) {
31
MemoryRegion blockram_m2;
44
+ if (counter >= hpmn) {
32
MemoryRegion blockram_m3;
45
return hlp;
33
MemoryRegion sram;
46
}
34
+ MPS2SCC scc;
47
}
35
} MPS2MachineState;
48
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
36
49
index XXXXXXX..XXXXXXX 100644
37
#define TYPE_MPS2_MACHINE "mps2"
50
--- a/target/arm/tcg/cpu32.c
38
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
51
+++ b/target/arm/tcg/cpu32.c
39
MPS2MachineState *mms = MPS2_MACHINE(machine);
52
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
40
MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
53
t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
41
MemoryRegion *system_memory = get_system_memory();
54
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
42
- DeviceState *armv7m;
55
cpu->isar.id_dfr0 = t;
43
+ DeviceState *armv7m, *sccdev;
44
45
if (!machine->cpu_model) {
46
machine->cpu_model = mmc->cpu_model;
47
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
48
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
49
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
50
51
+ object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
52
+ sccdev = DEVICE(&mms->scc);
53
+ qdev_set_parent_bus(armv7m, sysbus_get_default());
54
+ qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
55
+ qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
56
+ qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
57
+ object_property_set_bool(OBJECT(&mms->scc), true, "realized",
58
+ &error_fatal);
59
+ sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
60
+
56
+
61
system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
57
+ t = cpu->isar.id_dfr1;
62
58
+ t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
63
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
59
+ cpu->isar.id_dfr1 = t;
64
@@ -XXX,XX +XXX,XX @@ static void mps2_an385_class_init(ObjectClass *oc, void *data)
65
mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
66
mmc->fpga_type = FPGA_AN385;
67
mmc->cpu_model = "cortex-m3";
68
+ mmc->scc_id = 0x41040000 | (385 << 4);
69
}
60
}
70
61
71
static void mps2_an511_class_init(ObjectClass *oc, void *data)
62
/* CPU models. These are not needed for the AArch64 linux-user build. */
72
@@ -XXX,XX +XXX,XX @@ static void mps2_an511_class_init(ObjectClass *oc, void *data)
63
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
73
mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
64
index XXXXXXX..XXXXXXX 100644
74
mmc->fpga_type = FPGA_AN511;
65
--- a/target/arm/tcg/cpu64.c
75
mmc->cpu_model = "cortex-m3";
66
+++ b/target/arm/tcg/cpu64.c
76
+ mmc->scc_id = 0x4104000 | (511 << 4);
67
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
77
}
68
t = cpu->isar.id_aa64dfr0;
78
69
t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
79
static const TypeInfo mps2_info = {
70
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
71
+ t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
72
cpu->isar.id_aa64dfr0 = t;
73
74
t = cpu->isar.id_aa64smfr0;
80
--
75
--
81
2.7.4
76
2.34.1
82
83
diff view generated by jsdifflib
1
Implement a model of the simple timer device found in the CMSDK.
1
The include of hw/arm/virt.h in kvm64.c is unnecessary and also a
2
layering violation since the generic KVM code shouldn't need to know
3
anything about board-specifics. The include line is an accidental
4
leftover from commit 15613357ba53a4763, where we cleaned up the code
5
to not depend on virt board internals but forgot to also remove the
6
now-redundant include line.
2
7
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Gavin Shan <gshan@redhat.com>
5
Message-id: 1500029487-14822-5-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20230925110429.3917202-1-peter.maydell@linaro.org
6
---
12
---
7
hw/timer/Makefile.objs | 1 +
13
target/arm/kvm64.c | 1 -
8
include/hw/timer/cmsdk-apb-timer.h | 59 +++++++++
14
1 file changed, 1 deletion(-)
9
hw/timer/cmsdk-apb-timer.c | 253 +++++++++++++++++++++++++++++++++++++
10
default-configs/arm-softmmu.mak | 1 +
11
hw/timer/trace-events | 5 +
12
5 files changed, 319 insertions(+)
13
create mode 100644 include/hw/timer/cmsdk-apb-timer.h
14
create mode 100644 hw/timer/cmsdk-apb-timer.c
15
15
16
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
16
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/Makefile.objs
18
--- a/target/arm/kvm64.c
19
+++ b/hw/timer/Makefile.objs
19
+++ b/target/arm/kvm64.c
20
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
21
common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
22
23
common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
24
+common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
25
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/include/hw/timer/cmsdk-apb-timer.h
30
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
31
+/*
21
#include "internals.h"
32
+ * ARM CMSDK APB timer emulation
22
#include "hw/acpi/acpi.h"
33
+ *
23
#include "hw/acpi/ghes.h"
34
+ * Copyright (c) 2017 Linaro Limited
24
-#include "hw/arm/virt.h"
35
+ * Written by Peter Maydell
25
36
+ *
26
static bool have_guest_debug;
37
+ * This program is free software; you can redistribute it and/or modify
27
38
+ * it under the terms of the GNU General Public License version 2 or
39
+ * (at your option) any later version.
40
+ */
41
+
42
+#ifndef CMSDK_APB_TIMER_H
43
+#define CMSDK_APB_TIMER_H
44
+
45
+#include "hw/sysbus.h"
46
+#include "hw/ptimer.h"
47
+
48
+#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
49
+#define CMSDK_APB_TIMER(obj) OBJECT_CHECK(CMSDKAPBTIMER, (obj), \
50
+ TYPE_CMSDK_APB_TIMER)
51
+
52
+typedef struct {
53
+ /*< private >*/
54
+ SysBusDevice parent_obj;
55
+
56
+ /*< public >*/
57
+ MemoryRegion iomem;
58
+ qemu_irq timerint;
59
+ uint32_t pclk_frq;
60
+ struct ptimer_state *timer;
61
+
62
+ uint32_t ctrl;
63
+ uint32_t value;
64
+ uint32_t reload;
65
+ uint32_t intstatus;
66
+} CMSDKAPBTIMER;
67
+
68
+/**
69
+ * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
70
+ * @addr: location in system memory to map registers
71
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
72
+ */
73
+static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
74
+ qemu_irq timerint,
75
+ uint32_t pclk_frq)
76
+{
77
+ DeviceState *dev;
78
+ SysBusDevice *s;
79
+
80
+ dev = qdev_create(NULL, TYPE_CMSDK_APB_TIMER);
81
+ s = SYS_BUS_DEVICE(dev);
82
+ qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
83
+ qdev_init_nofail(dev);
84
+ sysbus_mmio_map(s, 0, addr);
85
+ sysbus_connect_irq(s, 0, timerint);
86
+ return dev;
87
+}
88
+
89
+#endif
90
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/hw/timer/cmsdk-apb-timer.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * ARM CMSDK APB timer emulation
98
+ *
99
+ * Copyright (c) 2017 Linaro Limited
100
+ * Written by Peter Maydell
101
+ *
102
+ * This program is free software; you can redistribute it and/or modify
103
+ * it under the terms of the GNU General Public License version 2 or
104
+ * (at your option) any later version.
105
+ */
106
+
107
+/* This is a model of the "APB timer" which is part of the Cortex-M
108
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
109
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
110
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
111
+ *
112
+ * The hardware has an EXTIN input wire, which can be configured
113
+ * by the guest to act either as a 'timer enable' (timer does not run
114
+ * when EXTIN is low), or as a 'timer clock' (timer runs at frequency
115
+ * of EXTIN clock, not PCLK frequency). We don't model this.
116
+ *
117
+ * The documentation is not very clear about the exact behaviour;
118
+ * we choose to implement that the interrupt is triggered when
119
+ * the counter goes from 1 to 0, that the counter then holds at 0
120
+ * for one clock cycle before reloading from the RELOAD register,
121
+ * and that if the RELOAD register is 0 this does not cause an
122
+ * interrupt (as there is no further 1->0 transition).
123
+ */
124
+
125
+#include "qemu/osdep.h"
126
+#include "qemu/log.h"
127
+#include "qemu/main-loop.h"
128
+#include "qapi/error.h"
129
+#include "trace.h"
130
+#include "hw/sysbus.h"
131
+#include "hw/registerfields.h"
132
+#include "hw/timer/cmsdk-apb-timer.h"
133
+
134
+REG32(CTRL, 0)
135
+ FIELD(CTRL, EN, 0, 1)
136
+ FIELD(CTRL, SELEXTEN, 1, 1)
137
+ FIELD(CTRL, SELEXTCLK, 2, 1)
138
+ FIELD(CTRL, IRQEN, 3, 1)
139
+REG32(VALUE, 4)
140
+REG32(RELOAD, 8)
141
+REG32(INTSTATUS, 0xc)
142
+ FIELD(INTSTATUS, IRQ, 0, 1)
143
+REG32(PID4, 0xFD0)
144
+REG32(PID5, 0xFD4)
145
+REG32(PID6, 0xFD8)
146
+REG32(PID7, 0xFDC)
147
+REG32(PID0, 0xFE0)
148
+REG32(PID1, 0xFE4)
149
+REG32(PID2, 0xFE8)
150
+REG32(PID3, 0xFEC)
151
+REG32(CID0, 0xFF0)
152
+REG32(CID1, 0xFF4)
153
+REG32(CID2, 0xFF8)
154
+REG32(CID3, 0xFFC)
155
+
156
+/* PID/CID values */
157
+static const int timer_id[] = {
158
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
159
+ 0x22, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
160
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
161
+};
162
+
163
+static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
164
+{
165
+ qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
166
+}
167
+
168
+static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
169
+{
170
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
171
+ uint64_t r;
172
+
173
+ switch (offset) {
174
+ case A_CTRL:
175
+ r = s->ctrl;
176
+ break;
177
+ case A_VALUE:
178
+ r = ptimer_get_count(s->timer);
179
+ break;
180
+ case A_RELOAD:
181
+ r = ptimer_get_limit(s->timer);
182
+ break;
183
+ case A_INTSTATUS:
184
+ r = s->intstatus;
185
+ break;
186
+ case A_PID4 ... A_CID3:
187
+ r = timer_id[(offset - A_PID4) / 4];
188
+ break;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "CMSDK APB timer read: bad offset %x\n", (int) offset);
192
+ r = 0;
193
+ break;
194
+ }
195
+ trace_cmsdk_apb_timer_read(offset, r, size);
196
+ return r;
197
+}
198
+
199
+static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
200
+ unsigned size)
201
+{
202
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
203
+
204
+ trace_cmsdk_apb_timer_write(offset, value, size);
205
+
206
+ switch (offset) {
207
+ case A_CTRL:
208
+ if (value & 6) {
209
+ /* Bits [1] and [2] enable using EXTIN as either clock or
210
+ * an enable line. We don't model this.
211
+ */
212
+ qemu_log_mask(LOG_UNIMP,
213
+ "CMSDK APB timer: EXTIN input not supported\n");
214
+ }
215
+ s->ctrl = value & 0xf;
216
+ if (s->ctrl & R_CTRL_EN_MASK) {
217
+ ptimer_run(s->timer, 0);
218
+ } else {
219
+ ptimer_stop(s->timer);
220
+ }
221
+ break;
222
+ case A_RELOAD:
223
+ /* Writing to reload also sets the current timer value */
224
+ ptimer_set_limit(s->timer, value, 1);
225
+ break;
226
+ case A_VALUE:
227
+ ptimer_set_count(s->timer, value);
228
+ break;
229
+ case A_INTSTATUS:
230
+ /* Just one bit, which is W1C. */
231
+ value &= 1;
232
+ s->intstatus &= ~value;
233
+ cmsdk_apb_timer_update(s);
234
+ break;
235
+ case A_PID4 ... A_CID3:
236
+ qemu_log_mask(LOG_GUEST_ERROR,
237
+ "CMSDK APB timer write: write to RO offset 0x%x\n",
238
+ (int)offset);
239
+ break;
240
+ default:
241
+ qemu_log_mask(LOG_GUEST_ERROR,
242
+ "CMSDK APB timer write: bad offset 0x%x\n", (int) offset);
243
+ break;
244
+ }
245
+}
246
+
247
+static const MemoryRegionOps cmsdk_apb_timer_ops = {
248
+ .read = cmsdk_apb_timer_read,
249
+ .write = cmsdk_apb_timer_write,
250
+ .endianness = DEVICE_LITTLE_ENDIAN,
251
+};
252
+
253
+static void cmsdk_apb_timer_tick(void *opaque)
254
+{
255
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
256
+
257
+ if (s->ctrl & R_CTRL_IRQEN_MASK) {
258
+ s->intstatus |= R_INTSTATUS_IRQ_MASK;
259
+ cmsdk_apb_timer_update(s);
260
+ }
261
+}
262
+
263
+static void cmsdk_apb_timer_reset(DeviceState *dev)
264
+{
265
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
266
+
267
+ trace_cmsdk_apb_timer_reset();
268
+ s->ctrl = 0;
269
+ s->intstatus = 0;
270
+ ptimer_stop(s->timer);
271
+ /* Set the limit and the count */
272
+ ptimer_set_limit(s->timer, 0, 1);
273
+}
274
+
275
+static void cmsdk_apb_timer_init(Object *obj)
276
+{
277
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
278
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);
279
+
280
+ memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
281
+ s, "cmsdk-apb-timer", 0x1000);
282
+ sysbus_init_mmio(sbd, &s->iomem);
283
+ sysbus_init_irq(sbd, &s->timerint);
284
+}
285
+
286
+static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
287
+{
288
+ CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
289
+ QEMUBH *bh;
290
+
291
+ if (s->pclk_frq == 0) {
292
+ error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
293
+ return;
294
+ }
295
+
296
+ bh = qemu_bh_new(cmsdk_apb_timer_tick, s);
297
+ s->timer = ptimer_init(bh,
298
+ PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
299
+ PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
300
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
301
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
302
+
303
+ ptimer_set_freq(s->timer, s->pclk_frq);
304
+}
305
+
306
+static const VMStateDescription cmsdk_apb_timer_vmstate = {
307
+ .name = "cmsdk-apb-timer",
308
+ .version_id = 1,
309
+ .minimum_version_id = 1,
310
+ .fields = (VMStateField[]) {
311
+ VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
312
+ VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
313
+ VMSTATE_UINT32(value, CMSDKAPBTIMER),
314
+ VMSTATE_UINT32(reload, CMSDKAPBTIMER),
315
+ VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
316
+ VMSTATE_END_OF_LIST()
317
+ }
318
+};
319
+
320
+static Property cmsdk_apb_timer_properties[] = {
321
+ DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
322
+ DEFINE_PROP_END_OF_LIST(),
323
+};
324
+
325
+static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
326
+{
327
+ DeviceClass *dc = DEVICE_CLASS(klass);
328
+
329
+ dc->realize = cmsdk_apb_timer_realize;
330
+ dc->vmsd = &cmsdk_apb_timer_vmstate;
331
+ dc->reset = cmsdk_apb_timer_reset;
332
+ dc->props = cmsdk_apb_timer_properties;
333
+}
334
+
335
+static const TypeInfo cmsdk_apb_timer_info = {
336
+ .name = TYPE_CMSDK_APB_TIMER,
337
+ .parent = TYPE_SYS_BUS_DEVICE,
338
+ .instance_size = sizeof(CMSDKAPBTIMER),
339
+ .instance_init = cmsdk_apb_timer_init,
340
+ .class_init = cmsdk_apb_timer_class_init,
341
+};
342
+
343
+static void cmsdk_apb_timer_register_types(void)
344
+{
345
+ type_register_static(&cmsdk_apb_timer_info);
346
+}
347
+
348
+type_init(cmsdk_apb_timer_register_types);
349
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
350
index XXXXXXX..XXXXXXX 100644
351
--- a/default-configs/arm-softmmu.mak
352
+++ b/default-configs/arm-softmmu.mak
353
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F2XX_ADC=y
354
CONFIG_STM32F2XX_SPI=y
355
CONFIG_STM32F205_SOC=y
356
357
+CONFIG_CMSDK_APB_TIMER=y
358
CONFIG_CMSDK_APB_UART=y
359
360
CONFIG_VERSATILE_PCI=y
361
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
362
index XXXXXXX..XXXXXXX 100644
363
--- a/hw/timer/trace-events
364
+++ b/hw/timer/trace-events
365
@@ -XXX,XX +XXX,XX @@ systick_reload(void) "systick reload"
366
systick_timer_tick(void) "systick reload"
367
systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
368
systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
369
+
370
+# hw/char/cmsdk_apb_timer.c
371
+cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
372
+cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
373
+cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
374
--
28
--
375
2.7.4
29
2.34.1
376
30
377
31
diff view generated by jsdifflib
1
In DEFINE_PROP_ARRAY, because we use a PropertyInfo (qdev_prop_arraylen)
1
The hw/arm/boot.h include in common-semi-target.h is not actually
2
which has a .set_default_value member we will set the field to a default
2
needed, and it's a bit odd because it pulls a hw/arm header into a
3
value. That default value will be zero, by the C rule that struct
3
target/arm file.
4
initialization sets unmentioned members to zero if at least one member
4
5
is initialized. However it's clearer to state it explicitly.
5
This include was originally needed because the semihosting code used
6
the arm_boot_info struct to get the base address of the RAM in system
7
emulation, to use in a (bad) heuristic for the return values for the
8
SYS_HEAPINFO semihosting call. We've since overhauled how we
9
calculate the HEAPINFO values in system emulation, and the code no
10
longer uses the arm_boot_info struct.
11
12
Remove the now-redundant include line, and instead directly include
13
the cpu-qom.h header that we were previously getting via boot.h.
6
14
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1499788408-10096-2-git-send-email-peter.maydell@linaro.org
17
Message-id: 20230925112219.3919261-1-peter.maydell@linaro.org
10
---
18
---
11
include/hw/qdev-properties.h | 1 +
19
target/arm/common-semi-target.h | 4 +---
12
1 file changed, 1 insertion(+)
20
1 file changed, 1 insertion(+), 3 deletions(-)
13
21
14
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
22
diff --git a/target/arm/common-semi-target.h b/target/arm/common-semi-target.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/qdev-properties.h
24
--- a/target/arm/common-semi-target.h
17
+++ b/include/hw/qdev-properties.h
25
+++ b/target/arm/common-semi-target.h
18
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_link;
26
@@ -XXX,XX +XXX,XX @@
19
_arrayfield, _arrayprop, _arraytype) { \
27
#ifndef TARGET_ARM_COMMON_SEMI_TARGET_H
20
.name = (PROP_ARRAY_LEN_PREFIX _name), \
28
#define TARGET_ARM_COMMON_SEMI_TARGET_H
21
.info = &(qdev_prop_arraylen), \
29
22
+ .defval.u = 0, \
30
-#ifndef CONFIG_USER_ONLY
23
.offset = offsetof(_state, _field) \
31
-#include "hw/arm/boot.h"
24
+ type_check(uint32_t, typeof_field(_state, _field)), \
32
-#endif
25
.arrayinfo = &(_arrayprop), \
33
+#include "target/arm/cpu-qom.h"
34
35
static inline target_ulong common_semi_arg(CPUState *cs, int argno)
36
{
26
--
37
--
27
2.7.4
38
2.34.1
28
29
diff view generated by jsdifflib
1
Model the ARM MPS2/MPS2+ FPGA based development board.
1
The code for powering on a CPU in arm-powerctl.c has two separate
2
2
use cases:
3
The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
3
* emulation of a real hardware power controller
4
FPGA but is otherwise the same as the 2). Since the CPU itself
4
* emulation of firmware interfaces (primarily PSCI) with
5
and most of the devices are in the FPGA, the details of the board
5
CPU on/off APIs
6
as seen by the guest depend significantly on the FPGA image.
6
7
7
For the first case, we only need to reset the CPU and set its
8
We model the following FPGA images:
8
starting PC and X0. For the second case, because we're emulating the
9
"mps2_an385" -- Cortex-M3 as documented in ARM Application Note AN385
9
firmware we need to ensure that it's in the state that the firmware
10
"mps2_an511" -- Cortex-M3 'DesignStart' as documented in AN511
10
provides. In particular, when we reset to a lower EL than the
11
11
highest one we are emulating, we need to put the CPU into a state
12
They are fairly similar but differ in the details for some
12
that permits correct running at that lower EL. We already do a
13
peripherals.
13
little of this in arm-powerctl.c (for instance we set SCR_HCE to
14
14
enable the HVC insn) but we don't do enough of it. This means that
15
in the case where we are emulating EL3 but also providing emulated
16
PSCI the guest will crash when a secondary core tries to use a
17
feature that needs an SCR_EL3 bit to be set, such as MTE or PAuth.
18
19
The hw/arm/boot.c code also has to support this "start guest code in
20
an EL that's lower than the highest emulated EL" case in order to do
21
direct guest kernel booting; it has all the necessary initialization
22
code to set the SCR_EL3 bits. Pull the relevant boot.c code out into
23
a separate function so we can share it between there and
24
arm-powerctl.c.
25
26
This refactoring has a few code changes that look like they
27
might be behaviour changes but aren't:
28
* if info->secure_boot is false and info->secure_board_setup is
29
true, then the old code would start the first CPU in Hyp
30
mode but without changing SCR.NS and NSACR.{CP11,CP10}.
31
This was wrong behaviour because there's no such thing
32
as Secure Hyp mode. The new code will leave the CPU in SVC.
33
(There is no board which sets secure_boot to false and
34
secure_board_setup to true, so this isn't a behaviour
35
change for any of our boards.)
36
* we don't explicitly clear SCR.NS when arm-powerctl.c
37
does a CPU-on to EL3. This was a no-op because CPU reset
38
will reset to NS == 0.
39
40
And some real behaviour changes:
41
* we no longer set HCR_EL2.RW when booting into EL2: the guest
42
can and should do that themselves before dropping into their
43
EL1 code. (arm-powerctl and boot did this differently; I
44
opted to use the logic from arm-powerctl, which only sets
45
HCR_EL2.RW when it's directly starting the guest in EL1,
46
because it's more correct, and I don't expect guests to be
47
accidentally depending on our having set the RW bit for them.)
48
* if we are booting a CPU into AArch32 Secure SVC then we won't
49
set SCR.HCE any more. This affects only the vexpress-a15 and
50
raspi2b machine types. Guests booting in this case will either:
51
- be able to set SCR.HCE themselves as part of moving from
52
Secure SVC into NS Hyp mode
53
- will move from Secure SVC to NS SVC, and won't care about
54
behaviour of the HVC insn
55
- will stay in Secure SVC, and won't care about HVC
56
* on an arm-powerctl CPU-on we will now set the SCR bits for
57
pauth/mte/sve/sme/hcx/fgt features
58
59
The first two of these are very minor and I don't expect guest
60
code to trip over them, so I didn't judge it worth convoluting
61
the code in an attempt to keep exactly the same boot.c behaviour.
62
The third change fixes issue 1899.
63
64
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1899
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
65
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 1500029487-14822-2-git-send-email-peter.maydell@linaro.org
66
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
67
Message-id: 20230926155619.4028618-1-peter.maydell@linaro.org
18
---
68
---
19
hw/arm/Makefile.objs | 1 +
69
target/arm/cpu.h | 22 +++++++++
20
hw/arm/mps2.c | 270 ++++++++++++++++++++++++++++++++++++++++
70
hw/arm/boot.c | 95 ++++++++++-----------------------------
21
default-configs/arm-softmmu.mak | 1 +
71
target/arm/arm-powerctl.c | 53 +---------------------
22
3 files changed, 272 insertions(+)
72
target/arm/cpu.c | 95 +++++++++++++++++++++++++++++++++++++++
23
create mode 100644 hw/arm/mps2.c
73
4 files changed, 141 insertions(+), 124 deletions(-)
24
74
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
75
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
77
--- a/target/arm/cpu.h
28
+++ b/hw/arm/Makefile.objs
78
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
79
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
30
obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
80
int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
31
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
81
int cpuid, DumpState *s);
32
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
82
33
+obj-$(CONFIG_MPS2) += mps2.o
83
+/**
34
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
84
+ * arm_emulate_firmware_reset: Emulate firmware CPU reset handling
35
new file mode 100644
85
+ * @cpu: CPU (which must have been freshly reset)
36
index XXXXXXX..XXXXXXX
86
+ * @target_el: exception level to put the CPU into
37
--- /dev/null
87
+ * @secure: whether to put the CPU in secure state
38
+++ b/hw/arm/mps2.c
39
@@ -XXX,XX +XXX,XX @@
40
+/*
41
+ * ARM V2M MPS2 board emulation.
42
+ *
88
+ *
43
+ * Copyright (c) 2017 Linaro Limited
89
+ * When QEMU is directly running a guest kernel at a lower level than
44
+ * Written by Peter Maydell
90
+ * EL3 it implicitly emulates some aspects of the guest firmware.
91
+ * This includes that on reset we need to configure the parts of the
92
+ * CPU corresponding to EL3 so that the real guest code can run at its
93
+ * lower exception level. This function does that post-reset CPU setup,
94
+ * for when we do direct boot of a guest kernel, and for when we
95
+ * emulate PSCI and similar firmware interfaces starting a CPU at a
96
+ * lower exception level.
45
+ *
97
+ *
46
+ * This program is free software; you can redistribute it and/or modify
98
+ * @target_el must be an EL implemented by the CPU between 1 and 3.
47
+ * it under the terms of the GNU General Public License version 2 or
99
+ * We do not support dropping into a Secure EL other than 3.
48
+ * (at your option) any later version.
100
+ *
101
+ * It is the responsibility of the caller to call arm_rebuild_hflags().
49
+ */
102
+ */
50
+
103
+void arm_emulate_firmware_reset(CPUState *cpustate, int target_el);
51
+/* The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
104
+
52
+ * FPGA but is otherwise the same as the 2). Since the CPU itself
105
#ifdef TARGET_AARCH64
53
+ * and most of the devices are in the FPGA, the details of the board
106
int aarch64_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
54
+ * as seen by the guest depend significantly on the FPGA image.
107
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
55
+ * We model the following FPGA images:
108
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
56
+ * "mps2-an385" -- Cortex-M3 as documented in ARM Application Note AN385
109
index XXXXXXX..XXXXXXX 100644
57
+ * "mps2-an511" -- Cortex-M3 'DesignStart' as documented in AN511
110
--- a/hw/arm/boot.c
58
+ *
111
+++ b/hw/arm/boot.c
59
+ * Links to the TRM for the board itself and to the various Application
112
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
60
+ * Notes which document the FPGA images can be found here:
113
61
+ * https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system
114
cpu_set_pc(cs, entry);
62
+ */
115
} else {
63
+
116
- /* If we are booting Linux then we need to check whether we are
64
+#include "qemu/osdep.h"
117
- * booting into secure or non-secure state and adjust the state
65
+#include "qapi/error.h"
118
- * accordingly. Out of reset, ARM is defined to be in secure state
66
+#include "qemu/error-report.h"
119
- * (SCR.NS = 0), we change that here if non-secure boot has been
67
+#include "hw/arm/arm.h"
120
- * requested.
68
+#include "hw/arm/armv7m.h"
121
+ /*
69
+#include "hw/boards.h"
122
+ * If we are booting Linux then we might need to do so at:
70
+#include "exec/address-spaces.h"
123
+ * - AArch64 NS EL2 or NS EL1
71
+#include "hw/misc/unimp.h"
124
+ * - AArch32 Secure SVC (EL3)
72
+
125
+ * - AArch32 NS Hyp (EL2)
73
+typedef enum MPS2FPGAType {
126
+ * - AArch32 NS SVC (EL1)
74
+ FPGA_AN385,
127
+ * Configure the CPU in the way boot firmware would do to
75
+ FPGA_AN511,
128
+ * drop us down to the appropriate level.
76
+} MPS2FPGAType;
129
*/
77
+
130
- if (arm_feature(env, ARM_FEATURE_EL3)) {
78
+typedef struct {
131
- /* AArch64 is defined to come out of reset into EL3 if enabled.
79
+ MachineClass parent;
132
- * If we are booting Linux then we need to adjust our EL as
80
+ MPS2FPGAType fpga_type;
133
- * Linux expects us to be in EL2 or EL1. AArch32 resets into
81
+ const char *cpu_model;
134
- * SVC, which Linux expects, so no privilege/exception level to
82
+} MPS2MachineClass;
135
- * adjust.
83
+
136
- */
84
+typedef struct {
137
- if (env->aarch64) {
85
+ MachineState parent;
138
- env->cp15.scr_el3 |= SCR_RW;
86
+
139
- if (arm_feature(env, ARM_FEATURE_EL2)) {
87
+ ARMv7MState armv7m;
140
- env->cp15.hcr_el2 |= HCR_RW;
88
+ MemoryRegion psram;
141
- env->pstate = PSTATE_MODE_EL2h;
89
+ MemoryRegion ssram1;
142
- } else {
90
+ MemoryRegion ssram1_m;
143
- env->pstate = PSTATE_MODE_EL1h;
91
+ MemoryRegion ssram23;
144
- }
92
+ MemoryRegion ssram23_m;
145
- if (cpu_isar_feature(aa64_pauth, cpu)) {
93
+ MemoryRegion blockram;
146
- env->cp15.scr_el3 |= SCR_API | SCR_APK;
94
+ MemoryRegion blockram_m1;
147
- }
95
+ MemoryRegion blockram_m2;
148
- if (cpu_isar_feature(aa64_mte, cpu)) {
96
+ MemoryRegion blockram_m3;
149
- env->cp15.scr_el3 |= SCR_ATA;
97
+ MemoryRegion sram;
150
- }
98
+} MPS2MachineState;
151
- if (cpu_isar_feature(aa64_sve, cpu)) {
99
+
152
- env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
100
+#define TYPE_MPS2_MACHINE "mps2"
153
- env->vfp.zcr_el[3] = 0xf;
101
+#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
154
- }
102
+#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
155
- if (cpu_isar_feature(aa64_sme, cpu)) {
103
+
156
- env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
104
+#define MPS2_MACHINE(obj) \
157
- env->cp15.scr_el3 |= SCR_ENTP2;
105
+ OBJECT_CHECK(MPS2MachineState, obj, TYPE_MPS2_MACHINE)
158
- env->vfp.smcr_el[3] = 0xf;
106
+#define MPS2_MACHINE_GET_CLASS(obj) \
159
- }
107
+ OBJECT_GET_CLASS(MPS2MachineClass, obj, TYPE_MPS2_MACHINE)
160
- if (cpu_isar_feature(aa64_hcx, cpu)) {
108
+#define MPS2_MACHINE_CLASS(klass) \
161
- env->cp15.scr_el3 |= SCR_HXEN;
109
+ OBJECT_CLASS_CHECK(MPS2MachineClass, klass, TYPE_MPS2_MACHINE)
162
- }
110
+
163
- if (cpu_isar_feature(aa64_fgt, cpu)) {
111
+/* Main SYSCLK frequency in Hz */
164
- env->cp15.scr_el3 |= SCR_FGTEN;
112
+#define SYSCLK_FRQ 25000000
165
- }
113
+
166
+ int target_el = arm_feature(env, ARM_FEATURE_EL2) ? 2 : 1;
114
+/* Initialize the auxiliary RAM region @mr and map it into
167
115
+ * the memory map at @base.
168
- /* AArch64 kernels never boot in secure mode */
116
+ */
169
- assert(!info->secure_boot);
117
+static void make_ram(MemoryRegion *mr, const char *name,
170
- /* This hook is only supported for AArch32 currently:
118
+ hwaddr base, hwaddr size)
171
- * bootloader_aarch64[] will not call the hook, and
172
- * the code above has already dropped us into EL2 or EL1.
173
- */
174
- assert(!info->secure_board_setup);
175
- }
176
-
177
- if (arm_feature(env, ARM_FEATURE_EL2)) {
178
- /* If we have EL2 then Linux expects the HVC insn to work */
179
- env->cp15.scr_el3 |= SCR_HCE;
180
- }
181
-
182
- /* Set to non-secure if not a secure boot */
183
- if (!info->secure_boot &&
184
- (cs != first_cpu || !info->secure_board_setup)) {
185
- /* Linux expects non-secure state */
186
- env->cp15.scr_el3 |= SCR_NS;
187
- /* Set NSACR.{CP11,CP10} so NS can access the FPU */
188
- env->cp15.nsacr |= 3 << 10;
189
- }
190
- }
191
-
192
- if (!env->aarch64 && !info->secure_boot &&
193
- arm_feature(env, ARM_FEATURE_EL2)) {
194
+ if (env->aarch64) {
195
/*
196
- * This is an AArch32 boot not to Secure state, and
197
- * we have Hyp mode available, so boot the kernel into
198
- * Hyp mode. This is not how the CPU comes out of reset,
199
- * so we need to manually put it there.
200
+ * AArch64 kernels never boot in secure mode, and we don't
201
+ * support the secure_board_setup hook for AArch64.
202
*/
203
- cpsr_write(env, ARM_CPU_MODE_HYP, CPSR_M, CPSRWriteRaw);
204
+ assert(!info->secure_boot);
205
+ assert(!info->secure_board_setup);
206
+ } else {
207
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
208
+ (info->secure_boot ||
209
+ (info->secure_board_setup && cs == first_cpu))) {
210
+ /* Start this CPU in Secure SVC */
211
+ target_el = 3;
212
+ }
213
}
214
215
+ arm_emulate_firmware_reset(cs, target_el);
216
+
217
if (cs == first_cpu) {
218
AddressSpace *as = arm_boot_address_space(cpu, info);
219
220
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/target/arm/arm-powerctl.c
223
+++ b/target/arm/arm-powerctl.c
224
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
225
226
/* Initialize the cpu we are turning on */
227
cpu_reset(target_cpu_state);
228
+ arm_emulate_firmware_reset(target_cpu_state, info->target_el);
229
target_cpu_state->halted = 0;
230
231
- if (info->target_aa64) {
232
- if ((info->target_el < 3) && arm_feature(&target_cpu->env,
233
- ARM_FEATURE_EL3)) {
234
- /*
235
- * As target mode is AArch64, we need to set lower
236
- * exception level (the requested level 2) to AArch64
237
- */
238
- target_cpu->env.cp15.scr_el3 |= SCR_RW;
239
- }
240
-
241
- if ((info->target_el < 2) && arm_feature(&target_cpu->env,
242
- ARM_FEATURE_EL2)) {
243
- /*
244
- * As target mode is AArch64, we need to set lower
245
- * exception level (the requested level 1) to AArch64
246
- */
247
- target_cpu->env.cp15.hcr_el2 |= HCR_RW;
248
- }
249
-
250
- target_cpu->env.pstate = aarch64_pstate_mode(info->target_el, true);
251
- } else {
252
- /* We are requested to boot in AArch32 mode */
253
- static const uint32_t mode_for_el[] = { 0,
254
- ARM_CPU_MODE_SVC,
255
- ARM_CPU_MODE_HYP,
256
- ARM_CPU_MODE_SVC };
257
-
258
- cpsr_write(&target_cpu->env, mode_for_el[info->target_el], CPSR_M,
259
- CPSRWriteRaw);
260
- }
261
-
262
- if (info->target_el == 3) {
263
- /* Processor is in secure mode */
264
- target_cpu->env.cp15.scr_el3 &= ~SCR_NS;
265
- } else {
266
- /* Processor is not in secure mode */
267
- target_cpu->env.cp15.scr_el3 |= SCR_NS;
268
-
269
- /* Set NSACR.{CP11,CP10} so NS can access the FPU */
270
- target_cpu->env.cp15.nsacr |= 3 << 10;
271
-
272
- /*
273
- * If QEMU is providing the equivalent of EL3 firmware, then we need
274
- * to make sure a CPU targeting EL2 comes out of reset with a
275
- * functional HVC insn.
276
- */
277
- if (arm_feature(&target_cpu->env, ARM_FEATURE_EL3)
278
- && info->target_el == 2) {
279
- target_cpu->env.cp15.scr_el3 |= SCR_HCE;
280
- }
281
- }
282
-
283
/* We check if the started CPU is now at the correct level */
284
assert(info->target_el == arm_current_el(&target_cpu->env));
285
286
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
287
index XXXXXXX..XXXXXXX 100644
288
--- a/target/arm/cpu.c
289
+++ b/target/arm/cpu.c
290
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
291
}
292
}
293
294
+void arm_emulate_firmware_reset(CPUState *cpustate, int target_el)
119
+{
295
+{
120
+ memory_region_init_ram(mr, NULL, name, size, &error_fatal);
296
+ ARMCPU *cpu = ARM_CPU(cpustate);
121
+ memory_region_add_subregion(get_system_memory(), base, mr);
297
+ CPUARMState *env = &cpu->env;
122
+}
298
+ bool have_el3 = arm_feature(env, ARM_FEATURE_EL3);
123
+
299
+ bool have_el2 = arm_feature(env, ARM_FEATURE_EL2);
124
+/* Create an alias of an entire original MemoryRegion @orig
300
+
125
+ * located at @base in the memory map.
301
+ /*
126
+ */
302
+ * Check we have the EL we're aiming for. If that is the
127
+static void make_ram_alias(MemoryRegion *mr, const char *name,
303
+ * highest implemented EL, then cpu_reset has already done
128
+ MemoryRegion *orig, hwaddr base)
304
+ * all the work.
129
+{
130
+ memory_region_init_alias(mr, NULL, name, orig, 0,
131
+ memory_region_size(orig));
132
+ memory_region_add_subregion(get_system_memory(), base, mr);
133
+}
134
+
135
+static void mps2_common_init(MachineState *machine)
136
+{
137
+ MPS2MachineState *mms = MPS2_MACHINE(machine);
138
+ MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
139
+ MemoryRegion *system_memory = get_system_memory();
140
+ DeviceState *armv7m;
141
+
142
+ if (!machine->cpu_model) {
143
+ machine->cpu_model = mmc->cpu_model;
144
+ }
145
+
146
+ if (strcmp(machine->cpu_model, mmc->cpu_model) != 0) {
147
+ error_report("This board can only be used with CPU %s", mmc->cpu_model);
148
+ exit(1);
149
+ }
150
+
151
+ /* The FPGA images have an odd combination of different RAMs,
152
+ * because in hardware they are different implementations and
153
+ * connected to different buses, giving varying performance/size
154
+ * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
155
+ * call the 16MB our "system memory", as it's the largest lump.
156
+ *
157
+ * Common to both boards:
158
+ * 0x21000000..0x21ffffff : PSRAM (16MB)
159
+ * AN385 only:
160
+ * 0x00000000 .. 0x003fffff : ZBT SSRAM1
161
+ * 0x00400000 .. 0x007fffff : mirror of ZBT SSRAM1
162
+ * 0x20000000 .. 0x203fffff : ZBT SSRAM 2&3
163
+ * 0x20400000 .. 0x207fffff : mirror of ZBT SSRAM 2&3
164
+ * 0x01000000 .. 0x01003fff : block RAM (16K)
165
+ * 0x01004000 .. 0x01007fff : mirror of above
166
+ * 0x01008000 .. 0x0100bfff : mirror of above
167
+ * 0x0100c000 .. 0x0100ffff : mirror of above
168
+ * AN511 only:
169
+ * 0x00000000 .. 0x0003ffff : FPGA block RAM
170
+ * 0x00400000 .. 0x007fffff : ZBT SSRAM1
171
+ * 0x20000000 .. 0x2001ffff : SRAM
172
+ * 0x20400000 .. 0x207fffff : ZBT SSRAM 2&3
173
+ *
174
+ * The AN385 has a feature where the lowest 16K can be mapped
175
+ * either to the bottom of the ZBT SSRAM1 or to the block RAM.
176
+ * This is of no use for QEMU so we don't implement it (as if
177
+ * zbt_boot_ctrl is always zero).
178
+ */
305
+ */
179
+ memory_region_allocate_system_memory(&mms->psram,
306
+ switch (target_el) {
180
+ NULL, "mps.ram", 0x1000000);
307
+ case 3:
181
+ memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);
308
+ assert(have_el3);
182
+
309
+ return;
183
+ switch (mmc->fpga_type) {
310
+ case 2:
184
+ case FPGA_AN385:
311
+ assert(have_el2);
185
+ make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
312
+ if (!have_el3) {
186
+ make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
313
+ return;
187
+ make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
314
+ }
188
+ make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
189
+ &mms->ssram23, 0x20400000);
190
+ make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
191
+ make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
192
+ &mms->blockram, 0x01004000);
193
+ make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
194
+ &mms->blockram, 0x01008000);
195
+ make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
196
+ &mms->blockram, 0x0100c000);
197
+ break;
315
+ break;
198
+ case FPGA_AN511:
316
+ case 1:
199
+ make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
317
+ if (!have_el3 && !have_el2) {
200
+ make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
318
+ return;
201
+ make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
319
+ }
202
+ make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
203
+ break;
320
+ break;
204
+ default:
321
+ default:
205
+ g_assert_not_reached();
322
+ g_assert_not_reached();
206
+ }
323
+ }
207
+
324
+
208
+ object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M);
325
+ if (have_el3) {
209
+ armv7m = DEVICE(&mms->armv7m);
326
+ /*
210
+ qdev_set_parent_bus(armv7m, sysbus_get_default());
327
+ * Set the EL3 state so code can run at EL2. This should match
211
+ switch (mmc->fpga_type) {
328
+ * the requirements set by Linux in its booting spec.
212
+ case FPGA_AN385:
329
+ */
213
+ qdev_prop_set_uint32(armv7m, "num-irq", 32);
330
+ if (env->aarch64) {
214
+ break;
331
+ env->cp15.scr_el3 |= SCR_RW;
215
+ case FPGA_AN511:
332
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
216
+ qdev_prop_set_uint32(armv7m, "num-irq", 64);
333
+ env->cp15.scr_el3 |= SCR_API | SCR_APK;
217
+ break;
334
+ }
218
+ default:
335
+ if (cpu_isar_feature(aa64_mte, cpu)) {
219
+ g_assert_not_reached();
336
+ env->cp15.scr_el3 |= SCR_ATA;
337
+ }
338
+ if (cpu_isar_feature(aa64_sve, cpu)) {
339
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
340
+ env->vfp.zcr_el[3] = 0xf;
341
+ }
342
+ if (cpu_isar_feature(aa64_sme, cpu)) {
343
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
344
+ env->cp15.scr_el3 |= SCR_ENTP2;
345
+ env->vfp.smcr_el[3] = 0xf;
346
+ }
347
+ if (cpu_isar_feature(aa64_hcx, cpu)) {
348
+ env->cp15.scr_el3 |= SCR_HXEN;
349
+ }
350
+ if (cpu_isar_feature(aa64_fgt, cpu)) {
351
+ env->cp15.scr_el3 |= SCR_FGTEN;
352
+ }
353
+ }
354
+
355
+ if (target_el == 2) {
356
+ /* If the guest is at EL2 then Linux expects the HVC insn to work */
357
+ env->cp15.scr_el3 |= SCR_HCE;
358
+ }
359
+
360
+ /* Put CPU into non-secure state */
361
+ env->cp15.scr_el3 |= SCR_NS;
362
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
363
+ env->cp15.nsacr |= 3 << 10;
220
+ }
364
+ }
221
+ qdev_prop_set_string(armv7m, "cpu-model", machine->cpu_model);
365
+
222
+ object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
366
+ if (have_el2 && target_el < 2) {
223
+ "memory", &error_abort);
367
+ /* Set EL2 state so code can run at EL1. */
224
+ object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
368
+ if (env->aarch64) {
225
+ &error_fatal);
369
+ env->cp15.hcr_el2 |= HCR_RW;
226
+
370
+ }
227
+ create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
371
+ }
228
+ create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
372
+
229
+ create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
373
+ /* Set the CPU to the desired state */
230
+ create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
374
+ if (env->aarch64) {
231
+ create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
375
+ env->pstate = aarch64_pstate_mode(target_el, true);
232
+ create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
376
+ } else {
233
+ /* These three ranges all cover multiple devices; we may implement
377
+ static const uint32_t mode_for_el[] = {
234
+ * some of them below (in which case the real device takes precedence
378
+ 0,
235
+ * over the unimplemented-region mapping).
379
+ ARM_CPU_MODE_SVC,
236
+ */
380
+ ARM_CPU_MODE_HYP,
237
+ create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
381
+ ARM_CPU_MODE_SVC,
238
+ 0x40000000, 0x00010000);
382
+ };
239
+ create_unimplemented_device("CMSDK peripheral region @0x40010000",
383
+
240
+ 0x40010000, 0x00010000);
384
+ cpsr_write(env, mode_for_el[target_el], CPSR_M, CPSRWriteRaw);
241
+ create_unimplemented_device("Extra peripheral region @0x40020000",
385
+ }
242
+ 0x40020000, 0x00010000);
243
+ create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
244
+ create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
245
+ create_unimplemented_device("VGA", 0x41000000, 0x0200000);
246
+
247
+ system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
248
+
249
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
250
+ 0x400000);
251
+}
386
+}
252
+
387
+
253
+static void mps2_class_init(ObjectClass *oc, void *data)
388
+
254
+{
389
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
255
+ MachineClass *mc = MACHINE_CLASS(oc);
390
256
+
391
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
257
+ mc->init = mps2_common_init;
258
+ mc->max_cpus = 1;
259
+}
260
+
261
+static void mps2_an385_class_init(ObjectClass *oc, void *data)
262
+{
263
+ MachineClass *mc = MACHINE_CLASS(oc);
264
+ MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
265
+
266
+ mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
267
+ mmc->fpga_type = FPGA_AN385;
268
+ mmc->cpu_model = "cortex-m3";
269
+}
270
+
271
+static void mps2_an511_class_init(ObjectClass *oc, void *data)
272
+{
273
+ MachineClass *mc = MACHINE_CLASS(oc);
274
+ MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
275
+
276
+ mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
277
+ mmc->fpga_type = FPGA_AN511;
278
+ mmc->cpu_model = "cortex-m3";
279
+}
280
+
281
+static const TypeInfo mps2_info = {
282
+ .name = TYPE_MPS2_MACHINE,
283
+ .parent = TYPE_MACHINE,
284
+ .abstract = true,
285
+ .instance_size = sizeof(MPS2MachineState),
286
+ .class_size = sizeof(MPS2MachineClass),
287
+ .class_init = mps2_class_init,
288
+};
289
+
290
+static const TypeInfo mps2_an385_info = {
291
+ .name = TYPE_MPS2_AN385_MACHINE,
292
+ .parent = TYPE_MPS2_MACHINE,
293
+ .class_init = mps2_an385_class_init,
294
+};
295
+
296
+static const TypeInfo mps2_an511_info = {
297
+ .name = TYPE_MPS2_AN511_MACHINE,
298
+ .parent = TYPE_MPS2_MACHINE,
299
+ .class_init = mps2_an511_class_init,
300
+};
301
+
302
+static void mps2_machine_init(void)
303
+{
304
+ type_register_static(&mps2_info);
305
+ type_register_static(&mps2_an385_info);
306
+ type_register_static(&mps2_an511_info);
307
+}
308
+
309
+type_init(mps2_machine_init);
310
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
311
index XXXXXXX..XXXXXXX 100644
312
--- a/default-configs/arm-softmmu.mak
313
+++ b/default-configs/arm-softmmu.mak
314
@@ -XXX,XX +XXX,XX @@ CONFIG_ONENAND=y
315
CONFIG_TUSB6010=y
316
CONFIG_IMX=y
317
CONFIG_MAINSTONE=y
318
+CONFIG_MPS2=y
319
CONFIG_NSERIES=y
320
CONFIG_RASPI=y
321
CONFIG_REALVIEW=y
322
--
392
--
323
2.7.4
393
2.34.1
324
325
diff view generated by jsdifflib
New patch
1
From: Chris Rauer <crauer@google.com>
1
2
3
The counter register is only 24-bits and counts down. If the timer is
4
running but the qtimer to reset it hasn't fired off yet, there is a chance
5
the regster read can return an invalid result.
6
7
Signed-off-by: Chris Rauer <crauer@google.com>
8
Message-id: 20230922181411.2697135-1-crauer@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/timer/npcm7xx_timer.c | 3 +++
13
1 file changed, 3 insertions(+)
14
15
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/npcm7xx_timer.c
18
+++ b/hw/timer/npcm7xx_timer.c
19
@@ -XXX,XX +XXX,XX @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
20
/* Convert a time interval in nanoseconds to a timer cycle count. */
21
static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
22
{
23
+ if (ns < 0) {
24
+ return 0;
25
+ }
26
return clock_ns_to_ticks(t->ctrl->clock, ns) /
27
npcm7xx_tcsr_prescaler(t->tcsr);
28
}
29
--
30
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Suraj Shirvankar <surajshirvankar@gmail.com>
2
2
3
As the gen_goto_tb function can do both static and dynamic jumps it
3
QEMU coding style uses the glib memory allocation APIs, not
4
should also set the is_jmp field. This matches the behaviour of the
4
the raw libc malloc/free. Switch the allocation and free
5
a64 code.
5
calls in elf2dmp to use these functions (dropping the now-unneeded
6
checks for failure).
6
7
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Suraj Shirvankar <surajshirvankar@gmail.com>
8
Reviewed-by: Richard Henderson <rth@twiddle.net>
9
Message-id: 169753938460.23804.11418813007617535750-1@git.sr.ht
9
Message-id: 20170713141928.25419-5-alex.bennee@linaro.org
10
[PMM: also remove NULL checks from g_malloc() calls;
10
[tweak to multiline comment formatting]
11
beef up commit message]
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
target/arm/translate.c | 6 +++++-
15
contrib/elf2dmp/addrspace.c | 7 ++-----
14
1 file changed, 5 insertions(+), 1 deletion(-)
16
contrib/elf2dmp/main.c | 9 +++------
17
contrib/elf2dmp/pdb.c | 19 ++++++++-----------
18
contrib/elf2dmp/qemu_elf.c | 7 ++-----
19
4 files changed, 15 insertions(+), 27 deletions(-)
15
20
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
diff --git a/contrib/elf2dmp/addrspace.c b/contrib/elf2dmp/addrspace.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
23
--- a/contrib/elf2dmp/addrspace.c
19
+++ b/target/arm/translate.c
24
+++ b/contrib/elf2dmp/addrspace.c
20
@@ -XXX,XX +XXX,XX @@ static void gen_goto_ptr(void)
25
@@ -XXX,XX +XXX,XX @@ int pa_space_create(struct pa_space *ps, QEMU_Elf *qemu_elf)
21
tcg_temp_free(addr);
26
}
27
}
28
29
- ps->block = malloc(sizeof(*ps->block) * ps->block_nr);
30
- if (!ps->block) {
31
- return 1;
32
- }
33
+ ps->block = g_new(struct pa_block, ps->block_nr);
34
35
for (i = 0; i < phdr_nr; i++) {
36
if (phdr[i].p_type == PT_LOAD) {
37
@@ -XXX,XX +XXX,XX @@ int pa_space_create(struct pa_space *ps, QEMU_Elf *qemu_elf)
38
void pa_space_destroy(struct pa_space *ps)
39
{
40
ps->block_nr = 0;
41
- free(ps->block);
42
+ g_free(ps->block);
22
}
43
}
23
44
24
+/* This will end the TB but doesn't guarantee we'll return to
45
void va_space_set_dtb(struct va_space *vs, uint64_t dtb)
25
+ * cpu_loop_exec. Any live exit_requests will be processed as we
46
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
26
+ * enter the next TB.
47
index XXXXXXX..XXXXXXX 100644
27
+ */
48
--- a/contrib/elf2dmp/main.c
28
static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
49
+++ b/contrib/elf2dmp/main.c
50
@@ -XXX,XX +XXX,XX @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb,
51
}
52
}
53
54
- kdbg = malloc(kdbg_hdr.Size);
55
- if (!kdbg) {
56
- return NULL;
57
- }
58
+ kdbg = g_malloc(kdbg_hdr.Size);
59
60
if (va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) {
61
eprintf("Failed to extract entire KDBG\n");
62
- free(kdbg);
63
+ g_free(kdbg);
64
return NULL;
65
}
66
67
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
68
}
69
70
out_kdbg:
71
- free(kdbg);
72
+ g_free(kdbg);
73
out_pdb:
74
pdb_exit(&pdb);
75
out_pdb_file:
76
diff --git a/contrib/elf2dmp/pdb.c b/contrib/elf2dmp/pdb.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/contrib/elf2dmp/pdb.c
79
+++ b/contrib/elf2dmp/pdb.c
80
@@ -XXX,XX +XXX,XX @@ uint64_t pdb_resolve(uint64_t img_base, struct pdb_reader *r, const char *name)
81
82
static void pdb_reader_ds_exit(struct pdb_reader *r)
29
{
83
{
30
if (use_goto_tb(s, dest)) {
84
- free(r->ds.toc);
31
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
85
+ g_free(r->ds.toc);
32
gen_set_pc_im(s, dest);
33
gen_goto_ptr();
34
}
35
+ s->is_jmp = DISAS_TB_JUMP;
36
}
86
}
37
87
38
static inline void gen_jmp (DisasContext *s, uint32_t dest)
88
static void pdb_exit_symbols(struct pdb_reader *r)
39
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
89
{
40
gen_bx_im(s, dest);
90
- free(r->modimage);
41
} else {
91
- free(r->symbols);
42
gen_goto_tb(s, 0, dest);
92
+ g_free(r->modimage);
43
- s->is_jmp = DISAS_TB_JUMP;
93
+ g_free(r->symbols);
44
}
45
}
94
}
46
95
96
static void pdb_exit_segments(struct pdb_reader *r)
97
{
98
- free(r->segs);
99
+ g_free(r->segs);
100
}
101
102
static void *pdb_ds_read(const PDB_DS_HEADER *header,
103
@@ -XXX,XX +XXX,XX @@ static void *pdb_ds_read(const PDB_DS_HEADER *header,
104
105
nBlocks = (size + header->block_size - 1) / header->block_size;
106
107
- buffer = malloc(nBlocks * header->block_size);
108
- if (!buffer) {
109
- return NULL;
110
- }
111
+ buffer = g_malloc(nBlocks * header->block_size);
112
113
for (i = 0; i < nBlocks; i++) {
114
memcpy(buffer + i * header->block_size, (const char *)header +
115
@@ -XXX,XX +XXX,XX @@ static int pdb_init_symbols(struct pdb_reader *r)
116
return 0;
117
118
out_symbols:
119
- free(symbols);
120
+ g_free(symbols);
121
122
return err;
123
}
124
@@ -XXX,XX +XXX,XX @@ static int pdb_reader_init(struct pdb_reader *r, void *data)
125
out_sym:
126
pdb_exit_symbols(r);
127
out_root:
128
- free(r->ds.root);
129
+ g_free(r->ds.root);
130
out_ds:
131
pdb_reader_ds_exit(r);
132
133
@@ -XXX,XX +XXX,XX @@ static void pdb_reader_exit(struct pdb_reader *r)
134
{
135
pdb_exit_segments(r);
136
pdb_exit_symbols(r);
137
- free(r->ds.root);
138
+ g_free(r->ds.root);
139
pdb_reader_ds_exit(r);
140
}
141
142
diff --git a/contrib/elf2dmp/qemu_elf.c b/contrib/elf2dmp/qemu_elf.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/contrib/elf2dmp/qemu_elf.c
145
+++ b/contrib/elf2dmp/qemu_elf.c
146
@@ -XXX,XX +XXX,XX @@ static int init_states(QEMU_Elf *qe)
147
148
printf("%zu CPU states has been found\n", cpu_nr);
149
150
- qe->state = malloc(sizeof(*qe->state) * cpu_nr);
151
- if (!qe->state) {
152
- return 1;
153
- }
154
+ qe->state = g_new(QEMUCPUState*, cpu_nr);
155
156
cpu_nr = 0;
157
158
@@ -XXX,XX +XXX,XX @@ static int init_states(QEMU_Elf *qe)
159
160
static void exit_states(QEMU_Elf *qe)
161
{
162
- free(qe->state);
163
+ g_free(qe->state);
164
}
165
166
static bool check_ehdr(QEMU_Elf *qe)
47
--
167
--
48
2.7.4
168
2.34.1
49
50
diff view generated by jsdifflib