1
First arm pullreq of 5.0!
1
Hi; this is the latest target-arm queue. Most of the patches
2
here are RTH's FEAT_HAFDBS finally landing. I've also included
3
the RNG-seed randomization patches from Jason, as well as a few
4
more minor things. The patches include a couple of regression
5
fixes:
6
* the resettable patch fixes a SCSI reset regression
7
* the 'do not re-randomize on snapshot load' patches fix
8
record-and-replay regressions
2
9
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
10
thanks
11
-- PMM
4
12
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
13
The following changes since commit e750a7ace492f0b450653d4ad368a77d6f660fb8:
14
15
Merge tag 'pull-9p-20221024' of https://github.com/cschoenebeck/qemu into staging (2022-10-24 14:27:12 -0400)
6
16
7
are available in the Git repository at:
17
are available in the Git repository at:
8
18
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
19
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221025
10
20
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
21
for you to fetch changes up to e2114f701c78f76246e4b1872639dad94a6bdd21:
12
22
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
23
rx: re-randomize rng-seed on reboot (2022-10-25 17:32:24 +0100)
14
24
15
----------------------------------------------------------------
25
----------------------------------------------------------------
16
target-arm queue:
26
target-arm queue:
17
* Add support for Cortex-M7 CPU
27
* Implement FEAT_E0PD
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
28
* Implement FEAT_HAFDBS
19
* aspeed: Various minor bug fixes and improvements
29
* honor HCR_E2H and HCR_TGE in arm_excp_unmasked()
20
* aspeed: Add support for the tacoma-bmc board
30
* hw/arm/virt: Fix devicetree warnings about the virtio-iommu node
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
31
* hw/core/resettable: fix reset level counting
22
* Handle trapping to EL2 of AArch32 VMRS instructions
32
* hw/hyperv/hyperv.c: Use device_cold_reset() instead of device_legacy_reset()
23
* Handle AArch32 CP15 trapping via HSTR_EL2
33
* imx: reload cmp timer outside of the reload ptimer transaction
24
* Add support for missing Jazelle system registers
34
* x86: do not re-randomize RNG seed on snapshot load
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
35
* m68k/virt: do not re-randomize RNG seed on snapshot load
26
* Add support for DC CVAP & DC CVADP instructions
36
* m68k/q800: do not re-randomize RNG seed on snapshot load
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
37
* arm: re-randomize rng-seed on reboot
28
* enable SHPC native hot plug in arm ACPI
38
* riscv: re-randomize rng-seed on reboot
39
* mips/boston: re-randomize rng-seed on reboot
40
* openrisc: re-randomize rng-seed on reboot
41
* rx: re-randomize rng-seed on reboot
29
42
30
----------------------------------------------------------------
43
----------------------------------------------------------------
31
Alex Bennée (1):
44
Ake Koomsin (1):
32
target/arm: ensure we use current exception state after SCR update
45
target/arm: honor HCR_E2H and HCR_TGE in arm_excp_unmasked()
33
46
34
Beata Michalska (4):
47
Axel Heider (1):
35
tcg: cputlb: Add probe_read
48
target/imx: reload cmp timer outside of the reload ptimer transaction
36
Memory: Enable writeback for given memory region
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
39
49
40
Christophe Lyon (1):
50
Damien Hedde (1):
41
target/arm: Add support for cortex-m7 CPU
51
hw/core/resettable: fix reset level counting
42
52
43
Cédric Le Goater (12):
53
Jason A. Donenfeld (10):
44
aspeed/i2c: Add support for pool buffer transfers
54
reset: allow registering handlers that aren't called by snapshot loading
45
aspeed/i2c: Check SRAM enablement on AST2500
55
device-tree: add re-randomization helper function
46
aspeed: Add a DRAM memory region at the SoC level
56
x86: do not re-randomize RNG seed on snapshot load
47
aspeed/i2c: Add support for DMA transfers
57
arm: re-randomize rng-seed on reboot
48
aspeed/i2c: Add trace events
58
riscv: re-randomize rng-seed on reboot
49
aspeed/smc: Restore default AHB window mapping at reset
59
m68k/virt: do not re-randomize RNG seed on snapshot load
50
aspeed/smc: Do not map disabled segment on the AST2600
60
m68k/q800: do not re-randomize RNG seed on snapshot load
51
aspeed/smc: Add AST2600 timings registers
61
mips/boston: re-randomize rng-seed on reboot
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
62
openrisc: re-randomize rng-seed on reboot
53
aspeed: Add support for the tacoma-bmc board
63
rx: re-randomize rng-seed on reboot
54
aspeed: Change the "scu" property definition
55
aspeed: Change the "nic" property definition
56
64
57
David Gibson (1):
65
Jean-Philippe Brucker (1):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
66
hw/arm/virt: Fix devicetree warnings about the virtio-iommu node
59
67
60
Heyi Guo (2):
68
Peter Maydell (2):
61
hw/arm/acpi: simplify AML bit and/or statement
69
target/arm: Implement FEAT_E0PD
62
hw/arm/acpi: enable SHPC native hot plug
70
hw/hyperv/hyperv.c: Use device_cold_reset() instead of device_legacy_reset()
63
71
64
Joel Stanley (4):
72
Richard Henderson (14):
65
aspeed/sdmc: Make ast2600 default 1G
73
target/arm: Introduce regime_is_stage2
66
aspeed/scu: Fix W1C behavior
74
target/arm: Add ptw_idx to S1Translate
67
watchdog/aspeed: Improve watchdog timeout message
75
target/arm: Add isar predicates for FEAT_HAFDBS
68
watchdog/aspeed: Fix AST2600 frequency behaviour
76
target/arm: Extract HA and HD in aa64_va_parameters
77
target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw
78
target/arm: Add ARMFault_UnsuppAtomicUpdate
79
target/arm: Remove loop from get_phys_addr_lpae
80
target/arm: Fix fault reporting in get_phys_addr_lpae
81
target/arm: Don't shift attrs in get_phys_addr_lpae
82
target/arm: Consider GP an attribute in get_phys_addr_lpae
83
target/arm: Tidy merging of attributes from descriptor and table
84
target/arm: Implement FEAT_HAFDBS, access flag portion
85
target/arm: Implement FEAT_HAFDBS, dirty bit portion
86
target/arm: Use the max page size in a 2-stage ptw
69
87
70
Marc Zyngier (5):
88
docs/devel/reset.rst | 8 +-
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
89
docs/system/arm/emulation.rst | 2 +
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
90
qapi/run-state.json | 6 +-
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
91
include/hw/boards.h | 2 +-
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
92
include/sysemu/device_tree.h | 9 +
75
target/arm: Add support for missing Jazelle system registers
93
include/sysemu/reset.h | 5 +-
76
94
target/arm/cpu.h | 15 ++
77
Niek Linnenbank (1):
95
target/arm/internals.h | 30 +++
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
96
hw/arm/aspeed.c | 4 +-
79
97
hw/arm/boot.c | 2 +
80
PanNengyuan (1):
98
hw/arm/mps2-tz.c | 4 +-
81
gpio: fix memory leak in aspeed_gpio_init()
99
hw/arm/virt.c | 5 +-
82
100
hw/core/reset.c | 17 +-
83
Philippe Mathieu-Daudé (2):
101
hw/core/resettable.c | 3 +-
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
102
hw/hppa/machine.c | 4 +-
85
hw/arm/virt: Simplify by moving the gic in the machine state
103
hw/hyperv/hyperv.c | 2 +-
86
104
hw/i386/microvm.c | 4 +-
87
include/exec/exec-all.h | 6 +
105
hw/i386/pc.c | 6 +-
88
include/exec/memory.h | 6 +
106
hw/i386/x86.c | 2 +-
89
include/exec/ram_addr.h | 8 +
107
hw/m68k/q800.c | 33 ++-
90
include/hw/arm/aspeed.h | 24 +--
108
hw/m68k/virt.c | 20 +-
91
include/hw/arm/aspeed_soc.h | 1 +
109
hw/mips/boston.c | 3 +
92
include/hw/arm/virt.h | 1 +
110
hw/openrisc/boot.c | 3 +
93
include/hw/i2c/aspeed_i2c.h | 16 ++
111
hw/ppc/pegasos2.c | 4 +-
94
include/hw/ssi/aspeed_smc.h | 1 +
112
hw/ppc/pnv.c | 4 +-
95
include/hw/watchdog/wdt_aspeed.h | 1 +
113
hw/ppc/spapr.c | 4 +-
96
include/qemu/cutils.h | 1 +
114
hw/riscv/boot.c | 3 +
97
target/arm/cpu.h | 20 +-
115
hw/rx/rx-gdbsim.c | 3 +
98
target/arm/helper.h | 3 +
116
hw/s390x/s390-virtio-ccw.c | 4 +-
99
target/arm/translate.h | 2 +
117
hw/timer/imx_epit.c | 9 +-
100
exec.c | 36 ++++
118
migration/savevm.c | 2 +-
101
hw/arm/aspeed.c | 271 +++++++++++++----------
119
softmmu/device_tree.c | 21 ++
102
hw/arm/aspeed_ast2600.c | 25 ++-
120
softmmu/runstate.c | 11 +-
103
hw/arm/aspeed_soc.c | 22 +-
121
target/arm/cpu.c | 24 +-
104
hw/arm/sbsa-ref.c | 86 ++++----
122
target/arm/cpu64.c | 2 +
105
hw/arm/virt-acpi-build.c | 21 +-
123
target/arm/helper.c | 31 ++-
106
hw/arm/virt.c | 109 +++++-----
124
target/arm/ptw.c | 524 +++++++++++++++++++++++++++---------------
107
hw/gpio/aspeed_gpio.c | 1 +
125
37 files changed, 572 insertions(+), 263 deletions(-)
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
109
hw/intc/exynos4210_gic.c | 9 +-
110
hw/misc/aspeed_scu.c | 19 +-
111
hw/misc/aspeed_sdmc.c | 6 +-
112
hw/net/ftgmac100.c | 19 +-
113
hw/ssi/aspeed_smc.c | 63 ++++--
114
hw/timer/aspeed_timer.c | 17 +-
115
hw/watchdog/wdt_aspeed.c | 41 ++--
116
linux-user/elfload.c | 2 +
117
memory.c | 12 ++
118
migration/ram.c | 5 +-
119
target/arm/arm-powerctl.c | 3 +
120
target/arm/cpu.c | 33 +++
121
target/arm/cpu64.c | 1 +
122
target/arm/helper.c | 170 ++++++++++++++-
123
target/arm/op_helper.c | 22 ++
124
target/arm/translate-vfp.inc.c | 20 +-
125
target/arm/translate.c | 9 +-
126
target/arm/vfp_helper.c | 29 +++
127
util/cutils.c | 38 ++++
128
hw/i2c/trace-events | 9 +
129
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
130
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
131
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
132
45 files changed, 1273 insertions(+), 354 deletions(-)
133
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
FEAT_E0PD adds new bits E0PD0 and E0PD1 to TCR_EL1, which allow the
2
OS to forbid EL0 access to half of the address space. Since this is
3
an EL0-specific variation on the existing TCR_ELx.{EPD0,EPD1}, we can
4
implement it entirely in aa64_va_parameters().
2
5
3
ARMv8.2 introduced support for Data Cache Clean instructions
6
This requires moving the existing regime_is_user() to internals.h
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
7
so that the code in helper.c can get at it.
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
6
that are to reach them are considered persistent.
7
The support provided considers both to be actually the same so there is no
8
distinction between the two. If none is available (there is no backing store
9
for given memory) both will result in Data Cache Clean up to the point of
10
coherency. Otherwise sync for the specified range shall be performed.
11
8
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20221021160131.3531787-1-peter.maydell@linaro.org
16
---
12
---
17
target/arm/cpu.h | 10 ++++++++
13
docs/system/arm/emulation.rst | 1 +
18
linux-user/elfload.c | 2 ++
14
target/arm/cpu.h | 5 +++++
19
target/arm/cpu64.c | 1 +
15
target/arm/internals.h | 19 +++++++++++++++++++
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
16
target/arm/cpu64.c | 1 +
21
4 files changed, 69 insertions(+)
17
target/arm/helper.c | 9 +++++++++
18
target/arm/ptw.c | 19 -------------------
19
6 files changed, 35 insertions(+), 19 deletions(-)
22
20
21
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
22
index XXXXXXX..XXXXXXX 100644
23
--- a/docs/system/arm/emulation.rst
24
+++ b/docs/system/arm/emulation.rst
25
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
26
- FEAT_Debugv8p4 (Debug changes for v8.4)
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
28
- FEAT_DoubleFault (Double Fault Extension)
29
+- FEAT_E0PD (Preventing EL0 access to halves of address maps)
30
- FEAT_ETS (Enhanced Translation Synchronization)
31
- FEAT_FCMA (Floating-point complex number instructions)
32
- FEAT_FHM (Floating-point half-precision multiplication instructions)
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
37
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
38
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
29
}
39
}
30
40
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
41
+static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
32
+{
42
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
43
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
34
+}
44
+}
35
+
45
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
46
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
47
{
48
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
49
diff --git a/target/arm/internals.h b/target/arm/internals.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/internals.h
52
+++ b/target/arm/internals.h
53
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
54
}
55
}
56
57
+static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
37
+{
58
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
59
+ switch (mmu_idx) {
60
+ case ARMMMUIdx_E20_0:
61
+ case ARMMMUIdx_Stage1_E0:
62
+ case ARMMMUIdx_MUser:
63
+ case ARMMMUIdx_MSUser:
64
+ case ARMMMUIdx_MUserNegPri:
65
+ case ARMMMUIdx_MSUserNegPri:
66
+ return true;
67
+ default:
68
+ return false;
69
+ case ARMMMUIdx_E10_0:
70
+ case ARMMMUIdx_E10_1:
71
+ case ARMMMUIdx_E10_1_PAN:
72
+ g_assert_not_reached();
73
+ }
39
+}
74
+}
40
+
75
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
76
/* Return the SCTLR value which controls this address translation regime */
77
static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
42
{
78
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
54
return hwcaps;
55
}
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
uint32_t hwcaps = 0;
59
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
79
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
81
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
82
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
84
t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */
70
85
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
71
t = cpu->isar.id_aa64isar1;
86
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
87
+ t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
88
cpu->isar.id_aa64mmfr2 = t;
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
89
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
90
t = cpu->isar.id_aa64zfr0;
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
92
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
93
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
94
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
95
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
81
.access = PL0_R, .readfn = rndr_readfn },
96
ps = extract32(tcr, 16, 3);
82
REGINFO_SENTINEL
97
ds = extract64(tcr, 32, 1);
83
};
98
} else {
99
+ bool e0pd;
84
+
100
+
85
+#ifndef CONFIG_USER_ONLY
101
/*
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
102
* Bit 55 is always between the two regions, and is canonical for
87
+ uint64_t value)
103
* determining if address tagging is enabled.
88
+{
104
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
89
+ ARMCPU *cpu = env_archcpu(env);
105
epd = extract32(tcr, 7, 1);
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
106
sh = extract32(tcr, 12, 2);
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
107
hpd = extract64(tcr, 41, 1);
92
+ uint64_t vaddr_in = (uint64_t) value;
108
+ e0pd = extract64(tcr, 55, 1);
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
109
} else {
94
+ void *haddr;
110
tsz = extract32(tcr, 16, 6);
95
+ int mem_idx = cpu_mmu_index(env, false);
111
gran = tg1_to_gran_size(extract32(tcr, 30, 2));
112
epd = extract32(tcr, 23, 1);
113
sh = extract32(tcr, 28, 2);
114
hpd = extract64(tcr, 42, 1);
115
+ e0pd = extract64(tcr, 56, 1);
116
}
117
ps = extract64(tcr, 32, 3);
118
ds = extract64(tcr, 59, 1);
96
+
119
+
97
+ /* This won't be crossing page boundaries */
120
+ if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) &&
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
121
+ regime_is_user(env, mmu_idx)) {
99
+ if (haddr) {
122
+ epd = true;
100
+
101
+ ram_addr_t offset;
102
+ MemoryRegion *mr;
103
+
104
+ /* RCU lock is already being held */
105
+ mr = memory_region_from_host(haddr, &offset);
106
+
107
+ if (mr) {
108
+ memory_region_do_writeback(mr, offset, dline_size);
109
+ }
123
+ }
110
+ }
111
+}
112
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
118
+ REGINFO_SENTINEL
119
+};
120
+
121
+static const ARMCPRegInfo dcpodp_reg[] = {
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
126
+ REGINFO_SENTINEL
127
+};
128
+#endif /*CONFIG_USER_ONLY*/
129
+
130
#endif
131
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
if (cpu_isar_feature(aa64_rndr, cpu)) {
135
define_arm_cp_regs(cpu, rndr_reginfo);
136
}
124
}
137
+#ifndef CONFIG_USER_ONLY
125
138
+ /* Data Cache clean instructions up to PoP */
126
gran = sanitize_gran_size(cpu, gran, stage2);
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
127
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
128
index XXXXXXX..XXXXXXX 100644
141
+
129
--- a/target/arm/ptw.c
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
130
+++ b/target/arm/ptw.c
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
131
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
144
+ }
132
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
145
+ }
133
}
146
+#endif /*CONFIG_USER_ONLY*/
134
147
#endif
135
-static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
148
136
-{
149
/*
137
- switch (mmu_idx) {
138
- case ARMMMUIdx_E20_0:
139
- case ARMMMUIdx_Stage1_E0:
140
- case ARMMMUIdx_MUser:
141
- case ARMMMUIdx_MSUser:
142
- case ARMMMUIdx_MUserNegPri:
143
- case ARMMMUIdx_MSUserNegPri:
144
- return true;
145
- default:
146
- return false;
147
- case ARMMMUIdx_E10_0:
148
- case ARMMMUIdx_E10_1:
149
- case ARMMMUIdx_E10_1_PAN:
150
- g_assert_not_reached();
151
- }
152
-}
153
-
154
/* Return the TTBR associated with this translation regime */
155
static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
156
{
150
--
157
--
151
2.20.1
158
2.25.1
152
153
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
The "PCI Bus Binding to: IEEE Std 1275-1994" defines the compatible
4
an array of qemu_irq and passing it around, directly call
4
string for a PCIe bus or endpoint as "pci<vendorid>,<deviceid>" or
5
qdev_get_gpio_in() on the gic field.
5
similar. Since the initial binding for PCI virtio-iommu didn't follow
6
this rule, it was modified to accept both strings and ensure backward
7
compatibility. Also, the unit-name for the node should be
8
"device,function".
6
9
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Fix corresponding dt-validate and dtc warnings:
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
12
pcie@10000000: virtio_iommu@16:compatible: ['virtio,pci-iommu'] does not contain items matching the given schema
13
pcie@10000000: Unevaluated properties are not allowed (... 'virtio_iommu@16' were unexpected)
14
From schema: linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml
15
virtio_iommu@16: compatible: 'oneOf' conditional failed, one must be fixed:
16
['virtio,pci-iommu'] is too short
17
'pci1af4,1057' was expected
18
From schema: dtschema/schemas/pci/pci-bus.yaml
19
20
Warning (pci_device_reg): /pcie@10000000/virtio_iommu@16: PCI unit address format error, expected "2,0"
21
22
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
25
---
13
include/hw/arm/virt.h | 1 +
26
hw/arm/virt.c | 5 +++--
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
27
1 file changed, 3 insertions(+), 2 deletions(-)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
28
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
20
+++ b/include/hw/arm/virt.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
uint32_t iommu_phandle;
23
int psci_conduit;
24
hwaddr highest_gpa;
25
+ DeviceState *gic;
26
DeviceState *acpi_dev;
27
Notifier powerdown_notifier;
28
} VirtMachineState;
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
30
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
31
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
33
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms,
34
}
34
35
}
35
static void create_virtio_iommu_dt_bindings(VirtMachineState *vms)
36
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
39
{
36
{
40
DeviceState *dev;
37
- const char compat[] = "virtio,pci-iommu";
38
+ const char compat[] = "virtio,pci-iommu\0pci1af4,1057";
39
uint16_t bdf = vms->virtio_iommu_bdf;
41
MachineState *ms = MACHINE(vms);
40
MachineState *ms = MACHINE(vms);
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
43
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
48
49
qdev_init_nofail(dev);
50
51
return dev;
52
}
53
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
55
+static void create_its(VirtMachineState *vms)
56
{
57
const char *itsclass = its_class_name();
58
DeviceState *dev;
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
60
61
dev = qdev_create(NULL, itsclass);
62
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
65
&error_abort);
66
qdev_init_nofail(dev);
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
69
fdt_add_its_gic_node(vms);
70
}
71
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
73
+static void create_v2m(VirtMachineState *vms)
74
{
75
int i;
76
int irq = vms->irqmap[VIRT_GIC_V2M];
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
78
qdev_init_nofail(dev);
79
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
82
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
83
+ qdev_get_gpio_in(vms->gic, irq + i));
84
}
85
86
fdt_add_v2m_gic_node(vms);
87
}
88
89
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
90
+static void create_gic(VirtMachineState *vms)
91
{
92
MachineState *ms = MACHINE(vms);
93
/* We create a standalone GIC */
94
- DeviceState *gicdev;
95
SysBusDevice *gicbusdev;
96
const char *gictype;
97
int type = vms->gic_version, i;
98
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
99
100
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
101
102
- gicdev = qdev_create(NULL, gictype);
103
- qdev_prop_set_uint32(gicdev, "revision", type);
104
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
105
+ vms->gic = qdev_create(NULL, gictype);
106
+ qdev_prop_set_uint32(vms->gic, "revision", type);
107
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
108
/* Note that the num-irq property counts both internal and external
109
* interrupts; there are always 32 of the former (mandated by GIC spec).
110
*/
111
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
112
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
113
if (!kvm_irqchip_in_kernel()) {
114
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
115
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
116
}
117
118
if (type == 3) {
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
120
121
nb_redist_regions = virt_gicv3_redist_region_count(vms);
122
123
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
124
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
125
nb_redist_regions);
126
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
127
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
128
129
if (nb_redist_regions == 2) {
130
uint32_t redist1_capacity =
131
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
132
133
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
134
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
135
MIN(smp_cpus - redist0_count, redist1_capacity));
136
}
137
} else {
138
if (!kvm_irqchip_in_kernel()) {
139
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
140
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
141
vms->virt);
142
}
143
}
144
- qdev_init_nofail(gicdev);
145
- gicbusdev = SYS_BUS_DEVICE(gicdev);
146
+ qdev_init_nofail(vms->gic);
147
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
148
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
149
if (type == 3) {
150
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
151
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
152
153
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
154
qdev_connect_gpio_out(cpudev, irq,
155
- qdev_get_gpio_in(gicdev,
156
+ qdev_get_gpio_in(vms->gic,
157
ppibase + timer_irq[irq]));
158
}
159
160
if (type == 3) {
161
- qemu_irq irq = qdev_get_gpio_in(gicdev,
162
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
163
ppibase + ARCH_GIC_MAINT_IRQ);
164
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
165
0, irq);
166
} else if (vms->virt) {
167
- qemu_irq irq = qdev_get_gpio_in(gicdev,
168
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
169
ppibase + ARCH_GIC_MAINT_IRQ);
170
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
171
}
172
173
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
174
- qdev_get_gpio_in(gicdev, ppibase
175
+ qdev_get_gpio_in(vms->gic, ppibase
176
+ VIRTUAL_PMU_IRQ));
177
178
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
180
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
181
}
182
183
- for (i = 0; i < NUM_IRQS; i++) {
184
- pic[i] = qdev_get_gpio_in(gicdev, i);
185
- }
186
-
187
fdt_add_gic_node(vms);
188
189
if (type == 3 && vms->its) {
190
- create_its(vms, gicdev);
191
+ create_its(vms);
192
} else if (type == 2) {
193
- create_v2m(vms, pic);
194
+ create_v2m(vms);
195
}
196
}
197
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
199
+static void create_uart(const VirtMachineState *vms, int uart,
200
MemoryRegion *mem, Chardev *chr)
201
{
202
char *nodename;
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
204
qdev_init_nofail(dev);
205
memory_region_add_subregion(mem, base,
206
sysbus_mmio_get_region(s, 0));
207
- sysbus_connect_irq(s, 0, pic[irq]);
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
209
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
211
qemu_fdt_add_subnode(vms->fdt, nodename);
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
213
g_free(nodename);
214
}
215
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
217
+static void create_rtc(const VirtMachineState *vms)
218
{
219
char *nodename;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
222
int irq = vms->irqmap[VIRT_RTC];
223
const char compat[] = "arm,pl031\0arm,primecell";
224
225
- sysbus_create_simple("pl031", base, pic[irq]);
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
227
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
229
qemu_fdt_add_subnode(vms->fdt, nodename);
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
231
}
232
}
233
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
235
+static void create_gpio(const VirtMachineState *vms)
236
{
237
char *nodename;
238
DeviceState *pl061_dev;
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
240
int irq = vms->irqmap[VIRT_GPIO];
241
const char compat[] = "arm,pl061\0arm,primecell";
242
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
244
+ pl061_dev = sysbus_create_simple("pl061", base,
245
+ qdev_get_gpio_in(vms->gic, irq));
246
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
250
g_free(nodename);
251
}
252
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
254
+static void create_virtio_devices(const VirtMachineState *vms)
255
{
256
int i;
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
259
int irq = vms->irqmap[VIRT_MMIO] + i;
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
261
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
263
+ sysbus_create_simple("virtio-mmio", base,
264
+ qdev_get_gpio_in(vms->gic, irq));
265
}
266
267
/* We add dtb nodes in reverse order so that they appear in the finished
268
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
269
0x7 /* PCI irq */);
270
}
271
272
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
273
+static void create_smmu(const VirtMachineState *vms,
274
PCIBus *bus)
275
{
276
char *node;
41
char *node;
277
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
42
278
qdev_init_nofail(dev);
43
vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
279
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
44
280
for (i = 0; i < NUM_SMMU_IRQS; i++) {
45
- node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf);
281
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
46
+ node = g_strdup_printf("%s/virtio_iommu@%x,%x", vms->pciehb_nodename,
282
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
47
+ PCI_SLOT(bdf), PCI_FUNC(bdf));
283
+ qdev_get_gpio_in(vms->gic, irq + i));
48
qemu_fdt_add_subnode(ms->fdt, node);
284
}
49
qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat));
285
50
qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg",
286
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
287
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
288
g_free(node);
289
}
290
291
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
292
+static void create_pcie(VirtMachineState *vms)
293
{
294
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
295
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
296
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
297
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
298
299
for (i = 0; i < GPEX_NUM_IRQS; i++) {
300
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
301
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
302
+ qdev_get_gpio_in(vms->gic, irq + i));
303
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
304
}
305
306
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
307
if (vms->iommu) {
308
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
309
310
- create_smmu(vms, pic, pci->bus);
311
+ create_smmu(vms, pci->bus);
312
313
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
314
0x0, vms->iommu_phandle, 0x0, 0x10000);
315
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
316
g_free(nodename);
317
}
318
319
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
320
+static void create_platform_bus(VirtMachineState *vms)
321
{
322
DeviceState *dev;
323
SysBusDevice *s;
324
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
325
326
s = SYS_BUS_DEVICE(dev);
327
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
328
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
329
- sysbus_connect_irq(s, i, pic[irqn]);
330
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
331
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
332
}
333
334
memory_region_add_subregion(sysmem,
335
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
336
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
337
MachineClass *mc = MACHINE_GET_CLASS(machine);
338
const CPUArchIdList *possible_cpus;
339
- qemu_irq pic[NUM_IRQS];
340
MemoryRegion *sysmem = get_system_memory();
341
MemoryRegion *secure_sysmem = NULL;
342
int n, virt_max_cpus;
343
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
344
345
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
346
347
- create_gic(vms, pic);
348
+ create_gic(vms);
349
350
fdt_add_pmu_nodes(vms);
351
352
- create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
353
+ create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
354
355
if (vms->secure) {
356
create_secure_ram(vms, secure_sysmem);
357
- create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
358
+ create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
359
}
360
361
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
362
363
- create_rtc(vms, pic);
364
+ create_rtc(vms);
365
366
- create_pcie(vms, pic);
367
+ create_pcie(vms);
368
369
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
370
- vms->acpi_dev = create_acpi_ged(vms, pic);
371
+ vms->acpi_dev = create_acpi_ged(vms);
372
} else {
373
- create_gpio(vms, pic);
374
+ create_gpio(vms);
375
}
376
377
/* connect powerdown request */
378
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
379
* (which will be automatically plugged in to the transports). If
380
* no backend is created the transport will just sit harmlessly idle.
381
*/
382
- create_virtio_devices(vms, pic);
383
+ create_virtio_devices(vms);
384
385
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
386
rom_set_fw(vms->fw_cfg);
387
388
- create_platform_bus(vms, pic);
389
+ create_platform_bus(vms);
390
391
vms->bootinfo.ram_size = machine->ram_size;
392
vms->bootinfo.nb_cpus = smp_cpus;
393
--
51
--
394
2.20.1
52
2.25.1
395
396
diff view generated by jsdifflib
1
From: Christophe Lyon <christophe.lyon@linaro.org>
1
From: Ake Koomsin <ake@igel.co.jp>
2
2
3
This is derived from cortex-m4 description, adding DP support and FPv5
3
An exception targeting EL2 from lower EL is actually maskable when
4
instructions with the corresponding flags in isar and mvfr2.
4
HCR_E2H and HCR_TGE are both set. This applies to both secure and
5
non-secure Security state.
5
6
6
Checked that it could successfully execute
7
We can remove the conditions that try to suppress masking of
7
vrinta.f32 s15, s15
8
interrupts when we are Secure and the exception targets EL2 and
8
while cortex-m4 emulation rejects it with "illegal instruction".
9
Secure EL2 is disabled. This is OK because in that situation
10
arm_phys_excp_target_el() will never return 2 as the target EL. The
11
'not if secure' check in this function was originally written before
12
arm_hcr_el2_eff(), and back then the target EL returned by
13
arm_phys_excp_target_el() could be 2 even if we were in Secure
14
EL0/EL1; but it is no longer needed.
9
15
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
16
Signed-off-by: Ake Koomsin <ake@igel.co.jp>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20221017092432.546881-1-ake@igel.co.jp
18
[PMM: Add commit message paragraph explaining why it's OK to
19
remove the checks on secure and SCR_EEL2]
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20191025090841.10299-1-christophe.lyon@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
22
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 24 +++++++++++++++++-------
17
1 file changed, 33 insertions(+)
24
1 file changed, 17 insertions(+), 7 deletions(-)
18
25
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
28
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
30
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24
cpu->isar.id_isar6 = 0x00000000;
31
if ((target_el > cur_el) && (target_el != 1)) {
25
}
32
/* Exceptions targeting a higher EL may not be maskable */
26
33
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
27
+static void cortex_m7_initfn(Object *obj)
34
- /*
28
+{
35
- * 64-bit masking rules are simple: exceptions to EL3
29
+ ARMCPU *cpu = ARM_CPU(obj);
36
- * can't be masked, and exceptions to EL2 can only be
30
+
37
- * masked from Secure state. The HCR and SCR settings
31
+ set_feature(&cpu->env, ARM_FEATURE_V7);
38
- * don't affect the masking logic, only the interrupt routing.
32
+ set_feature(&cpu->env, ARM_FEATURE_M);
39
- */
33
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
40
- if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) {
34
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
41
+ switch (target_el) {
35
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
42
+ case 2:
36
+ cpu->midr = 0x411fc272; /* r1p2 */
43
+ /*
37
+ cpu->pmsav7_dregion = 8;
44
+ * According to ARM DDI 0487H.a, an interrupt can be masked
38
+ cpu->isar.mvfr0 = 0x10110221;
45
+ * when HCR_E2H and HCR_TGE are both set regardless of the
39
+ cpu->isar.mvfr1 = 0x12000011;
46
+ * current Security state. Note that we need to revisit this
40
+ cpu->isar.mvfr2 = 0x00000040;
47
+ * part again once we need to support NMI.
41
+ cpu->id_pfr0 = 0x00000030;
48
+ */
42
+ cpu->id_pfr1 = 0x00000200;
49
+ if ((hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
43
+ cpu->id_dfr0 = 0x00100000;
50
+ unmasked = true;
44
+ cpu->id_afr0 = 0x00000000;
51
+ }
45
+ cpu->id_mmfr0 = 0x00100030;
52
+ break;
46
+ cpu->id_mmfr1 = 0x00000000;
53
+ case 3:
47
+ cpu->id_mmfr2 = 0x01000000;
54
+ /* Interrupt cannot be masked when the target EL is 3 */
48
+ cpu->id_mmfr3 = 0x00000000;
55
unmasked = true;
49
+ cpu->isar.id_isar0 = 0x01101110;
56
+ break;
50
+ cpu->isar.id_isar1 = 0x02112000;
57
+ default:
51
+ cpu->isar.id_isar2 = 0x20232231;
58
+ g_assert_not_reached();
52
+ cpu->isar.id_isar3 = 0x01111131;
59
}
53
+ cpu->isar.id_isar4 = 0x01310132;
60
} else {
54
+ cpu->isar.id_isar5 = 0x00000000;
61
/*
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+}
57
+
58
static void cortex_m33_initfn(Object *obj)
59
{
60
ARMCPU *cpu = ARM_CPU(obj);
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
64
.class_init = arm_v7m_class_init },
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
66
+ .class_init = arm_v7m_class_init },
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
68
.class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
--
62
--
71
2.20.1
63
2.25.1
72
73
diff view generated by jsdifflib
Deleted patch
1
From: David Gibson <david@gibson.dropbear.id.au>
2
1
3
exynos4210_gic_realize() prints the number of cpus into some temporary
4
buffers, but it only allows 3 bytes space for it. That's plenty:
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
6
(2). But the compiler can't always figure that out, so some[*] gcc9
7
versions emit -Wformat-truncation warnings.
8
9
We can fix that by hinting the constraint to the compiler with a
10
suitably placed assert().
11
12
[*] The bizarre thing here, is that I've long gotten these warnings
13
compiling in a 32-bit x86 container as host - Fedora 30 with
14
gcc-9.2.1-1.fc30.i686 - but it compiles just fine on my normal
15
x86_64 host - Fedora 30 with and gcc-9.2.1-1.fc30.x86_64.
16
17
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
[PMM: deleted stray blank line]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
24
1 file changed, 8 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
29
+++ b/hw/intc/exynos4210_gic.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
33
SysBusDevice *gicbusdev;
34
+ uint32_t n = s->num_cpu;
35
uint32_t i;
36
37
s->gic = qdev_create(NULL, "arm_gic");
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
41
42
- for (i = 0; i < s->num_cpu; i++) {
43
+ /*
44
+ * This clues in gcc that our on-stack buffers do, in fact have
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
47
+ */
48
+ assert(n <= EXYNOS4210_NCPUS);
49
+ for (i = 0; i < n; i++) {
50
/* Map CPU interface per SMP Core */
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
52
memory_region_init_alias(&s->cpu_alias[i], obj,
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed I2C controller can operate in different transfer modes :
4
5
- Byte Buffer mode, using a dedicated register to transfer a
6
byte. This is what the model supports today.
7
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
32
2 files changed, 186 insertions(+), 19 deletions(-)
33
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
38
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
40
41
#define ASPEED_I2C_NR_BUSSES 16
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
43
44
struct AspeedI2CState;
45
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
47
uint32_t intr_status;
48
uint32_t cmd;
49
uint32_t buf;
50
+ uint32_t pool_ctrl;
51
} AspeedI2CBus;
52
53
typedef struct AspeedI2CState {
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
55
qemu_irq irq;
56
57
uint32_t intr_status;
58
+ MemoryRegion pool_iomem;
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
60
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
62
} AspeedI2CState;
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
64
uint8_t reg_size;
65
uint8_t gap;
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
67
+
68
+ uint64_t pool_size;
69
+ hwaddr pool_base;
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
71
} AspeedI2CClass;
72
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
77
+++ b/hw/i2c/aspeed_i2c.c
78
@@ -XXX,XX +XXX,XX @@
79
/* I2C Device (Bus) Register */
80
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
83
-#define I2CD_BUFF_SEL(x) (x << 20)
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
88
@@ -XXX,XX +XXX,XX @@
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
91
#define I2CD_S_ALT_EN (0x1 << 10)
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
94
95
/* Command Bit */
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
100
#define I2CD_M_STOP_CMD (0x1 << 5)
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
102
#define I2CD_M_RX_CMD (0x1 << 3)
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_M_START_CMD (0x1)
105
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
117
return bus->intr_ctrl;
118
case I2CD_INTR_STS_REG:
119
return bus->intr_status;
120
+ case I2CD_POOL_CTRL_REG:
121
+ return bus->pool_ctrl;
122
case I2CD_BYTE_BUF_REG:
123
return bus->buf;
124
case I2CD_CMD_REG:
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
127
}
128
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
130
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
132
+ int ret = -1;
133
+ int i;
134
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
138
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
140
+ if (ret) {
141
+ break;
142
+ }
143
+ }
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
145
+ } else {
146
+ ret = i2c_send(bus->bus, bus->buf);
147
+ }
148
+
149
+ return ret;
150
+}
151
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
153
+{
154
+ AspeedI2CState *s = bus->controller;
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
156
+ uint8_t data;
157
+ int i;
158
+
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
161
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
163
+ pool_base[i] = i2c_recv(bus->bus);
164
+ }
165
+
166
+ /* Update RX count */
167
+ bus->pool_ctrl &= ~(0xff << 24);
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
170
+ } else {
171
+ data = i2c_recv(bus->bus);
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
173
+ }
174
+}
175
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
177
{
178
- uint8_t ret;
179
-
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
181
- ret = i2c_recv(bus->bus);
182
+ aspeed_i2c_bus_recv(bus);
183
bus->intr_status |= I2CD_INTR_RX_DONE;
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
186
i2c_nack(bus->bus);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
191
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
193
+{
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
195
+
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
198
+
199
+ return pool_base[0];
200
+ } else {
201
+ return bus->buf;
202
+ }
203
+}
204
+
205
/*
206
* The state machine needs some refinement. It is only used to track
207
* invalid STOP commands for the moment.
208
*/
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
210
{
211
+ uint8_t pool_start = 0;
212
+
213
bus->cmd &= ~0xFFFF;
214
bus->cmd |= value & 0xFFFF;
215
216
if (bus->cmd & I2CD_M_START_CMD) {
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
218
I2CD_MSTARTR : I2CD_MSTART;
219
+ uint8_t addr;
220
221
aspeed_i2c_set_state(bus, state);
222
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
224
- extract32(bus->buf, 0, 1))) {
225
+ addr = aspeed_i2c_get_addr(bus);
226
+
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
228
+ extract32(addr, 0, 1))) {
229
bus->intr_status |= I2CD_INTR_TX_NAK;
230
} else {
231
bus->intr_status |= I2CD_INTR_TX_ACK;
232
}
233
234
- /* START command is also a TX command, as the slave address is
235
- * sent on the bus */
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
237
+ bus->cmd &= ~I2CD_M_START_CMD;
238
+
239
+ /*
240
+ * The START command is also a TX command, as the slave
241
+ * address is sent on the bus. Drop the TX flag if nothing
242
+ * else needs to be sent in this sequence.
243
+ */
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
247
+ } else {
248
+ /*
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
254
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
256
+ }
257
258
/* No slave found */
259
if (!i2c_bus_busy(bus->bus)) {
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
261
262
if (bus->cmd & I2CD_M_TX_CMD) {
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
264
- if (i2c_send(bus->bus, bus->buf)) {
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
267
i2c_end_transfer(bus->bus);
268
} else {
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
271
__func__);
272
break;
273
+ case I2CD_POOL_CTRL_REG:
274
+ bus->pool_ctrl &= ~0xffffff;
275
+ bus->pool_ctrl |= (value & 0xffffff);
276
+ break;
277
+
278
case I2CD_BYTE_BUF_REG:
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
280
break;
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
282
.endianness = DEVICE_LITTLE_ENDIAN,
283
};
284
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
286
+ unsigned size)
287
+{
288
+ AspeedI2CState *s = opaque;
289
+ uint64_t ret = 0;
290
+ int i;
291
+
292
+ for (i = 0; i < size; i++) {
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
294
+ }
295
+
296
+ return ret;
297
+}
298
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
300
+ uint64_t value, unsigned size)
301
+{
302
+ AspeedI2CState *s = opaque;
303
+ int i;
304
+
305
+ for (i = 0; i < size; i++) {
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
307
+ }
308
+}
309
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
311
+ .read = aspeed_i2c_pool_read,
312
+ .write = aspeed_i2c_pool_write,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
315
+ .min_access_size = 1,
316
+ .max_access_size = 4,
317
+ },
318
+};
319
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
321
.name = TYPE_ASPEED_I2C,
322
- .version_id = 1,
323
- .minimum_version_id = 1,
324
+ .version_id = 2,
325
+ .minimum_version_id = 2,
326
.fields = (VMStateField[]) {
327
VMSTATE_UINT8(id, AspeedI2CBus),
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
332
VMSTATE_UINT32(buf, AspeedI2CBus),
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
334
VMSTATE_END_OF_LIST()
335
}
336
};
337
338
static const VMStateDescription aspeed_i2c_vmstate = {
339
.name = TYPE_ASPEED_I2C,
340
- .version_id = 1,
341
- .minimum_version_id = 1,
342
+ .version_id = 2,
343
+ .minimum_version_id = 2,
344
.fields = (VMStateField[]) {
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
348
AspeedI2CBus),
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
350
VMSTATE_END_OF_LIST()
351
}
352
};
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
355
&s->busses[i].mr);
356
}
357
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
359
+ "aspeed.i2c-pool", aic->pool_size);
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
361
}
362
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
365
return bus->controller->irq;
366
}
367
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
369
+{
370
+ uint8_t *pool_page =
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
372
+
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
374
+}
375
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
377
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
380
aic->reg_size = 0x40;
381
aic->gap = 7;
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
383
+ aic->pool_size = 0x800;
384
+ aic->pool_base = 0x800;
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
386
}
387
388
static const TypeInfo aspeed_2400_i2c_info = {
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
390
return bus->controller->irq;
391
}
392
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
394
+{
395
+ return &bus->controller->pool[bus->id * 0x10];
396
+}
397
+
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
399
{
400
DeviceClass *dc = DEVICE_CLASS(klass);
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
402
aic->reg_size = 0x40;
403
aic->gap = 7;
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
405
+ aic->pool_size = 0x100;
406
+ aic->pool_base = 0x200;
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
408
}
409
410
static const TypeInfo aspeed_2500_i2c_info = {
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
412
return bus->irq;
413
}
414
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
416
+{
417
+ return &bus->controller->pool[bus->id * 0x20];
418
+}
419
+
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
421
{
422
DeviceClass *dc = DEVICE_CLASS(klass);
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
424
aic->reg_size = 0x80;
425
aic->gap = -1; /* no gap */
426
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
427
+ aic->pool_size = 0x200;
428
+ aic->pool_base = 0xC00;
429
+ aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
430
}
431
432
static const TypeInfo aspeed_2600_i2c_info = {
433
--
434
2.20.1
435
436
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Damien Hedde <damien.hedde@greensocs.com>
2
2
3
The last argument of AML bit and/or statement is the target variable,
3
The code for handling the reset level count in the Resettable code
4
so we don't need to use a NULL target and then an additional store
4
has two issues:
5
operation; using just aml_and() or aml_or() statement is enough.
6
5
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
6
The reset count is only decremented for the 1->0 case. This means
7
that if there's ever a nested reset that takes the count to 2 then it
8
will never again be decremented. Eventually the count will exceed
9
the '50' limit in resettable_phase_enter() and QEMU will trip over
10
the assertion failure. The repro case in issue 1266 is an example of
11
this that happens now the SCSI subsystem uses three-phase reset.
8
12
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
13
Secondly, the count is decremented only after the exit phase handler
10
Cc: Peter Maydell <peter.maydell@linaro.org>
14
is called. Moving the reset count decrement from "just after" to
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
15
"just before" calling the exit phase handler allows
12
Cc: Igor Mammedov <imammedo@redhat.com>
16
resettable_is_in_reset() to return false during the handler
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
17
execution.
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
18
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
19
This simplifies reset handling in resettable devices. Typically, a
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
20
function that updates the device state will just need to read the
21
current reset state and not anymore treat the "in a reset-exit
22
transition" as a special case.
23
24
Note that the semantics change to the *_is_in_reset() functions
25
will have no effect on the current codebase, because only two
26
devices (hw/char/cadence_uart.c and hw/misc/zynq_sclr.c) currently
27
call those functions, and in neither case do they do it from the
28
device's exit phase methed.
29
30
Fixes: 4a5fc890 ("scsi: Use device_cold_reset() and bus_cold_reset()")
31
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1266
32
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Reported-by: Michael Peter <michael.peter@hensoldt-cyber.com>
35
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
36
Message-id: 20221020142749.3357951-1-peter.maydell@linaro.org
37
Buglink: https://bugs.launchpad.net/qemu/+bug/1905297
38
Reported-by: Michael Peter <michael.peter@hensoldt-cyber.com>
39
[PMM: adjust the docs paragraph changed to get the name of the
40
'enter' phase right and to clarify exactly when the count is
41
adjusted; rewrite the commit message]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
43
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
44
docs/devel/reset.rst | 8 +++++---
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
45
hw/core/resettable.c | 3 +--
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
46
2 files changed, 6 insertions(+), 5 deletions(-)
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
24
47
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
48
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
26
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
50
--- a/docs/devel/reset.rst
28
+++ b/hw/arm/virt-acpi-build.c
51
+++ b/docs/devel/reset.rst
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
52
@@ -XXX,XX +XXX,XX @@ Polling the reset state
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
53
Resettable interface provides the ``resettable_is_in_reset()`` function.
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
54
This function returns true if the object parameter is currently under reset.
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
55
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
56
-An object is under reset from the beginning of the *init* phase to the end of
34
- aml_name("CTRL")));
57
-the *exit* phase. During all three phases, the function will return that the
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
58
-object is in reset.
36
+ aml_name("CTRL")));
59
+An object is under reset from the beginning of the *enter* phase (before
37
60
+either its children or its own enter method is called) to the *exit*
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
61
+phase. During *enter* and *hold* phase only, the function will return that the
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
62
+object is in reset. The state is changed after the *exit* is propagated to
40
- aml_name("CDW1")));
63
+its children and just before calling the object's own *exit* method.
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
64
42
+ aml_name("CDW1")));
65
This function may be used if the object behavior has to be adapted
43
aml_append(ifctx, ifctx1);
66
while in reset state. For example if a device has an irq input,
44
67
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
45
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
46
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
47
- aml_name("CDW1")));
48
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
49
+ aml_name("CDW1")));
50
aml_append(ifctx, ifctx1);
51
52
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
53
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
aml_append(method, ifctx);
55
56
elsectx = aml_else();
57
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
58
- aml_name("CDW1")));
59
+ aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
60
+ aml_name("CDW1")));
61
aml_append(elsectx, aml_return(aml_arg(3)));
62
aml_append(method, elsectx);
63
aml_append(dev, method);
64
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
65
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
66
GIT binary patch
69
--- a/hw/core/resettable.c
67
delta 133
70
+++ b/hw/core/resettable.c
68
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
71
@@ -XXX,XX +XXX,XX @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
69
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
72
resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type);
70
MAmS{W8QoPG0j8@bzW@LL
73
71
74
assert(s->count > 0);
72
delta 141
75
- if (s->count == 1) {
73
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
76
+ if (--s->count == 0) {
74
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
77
trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit);
75
R$zCV`m0@An{L@X95dZ+BD!u>!
78
if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) {
76
79
rc->phases.exit(obj);
77
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
80
}
78
index XXXXXXX..XXXXXXX 100644
81
- s->count = 0;
79
GIT binary patch
82
}
80
delta 132
83
s->exit_phase_in_progress = false;
81
zcmcaVi}Cs_MlP3NmymE@1_ma@iCof*O&is^IGH-{Zr;SX-A2HTGu}VgnWZb6!PzC;
84
trace_resettable_phase_exit_end(obj, obj_typename, s->count);
82
zaDm6<N;gaQYUhw3A1+xCxj<mj<V?m|kR%reSc%xA$w1l|Bnc4~00|d>_#p8m*$ep~
83
L;w+mP-Q(B*s{AMU
84
85
delta 140
86
zcmcaUi}C&}MlP3Nmymd01_maViCof*T^rT9IGGynZQjJW-A2HVGu}VgnWZb6!PzC;
87
zaDm_CN;gaYf@<fGARjJS1`xGCXwu|N#)4XqJQoK<nZ%^YK&~-J8Y&?GmM8#;fMk|r
88
QFBE{vurO@?=@!QZ00dYn_y7O^
89
90
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
91
index XXXXXXX..XXXXXXX 100644
92
GIT binary patch
93
delta 133
94
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
95
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
96
MAmS{W8QoPG0j8@bzW@LL
97
98
delta 141
99
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
100
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
101
R$zCV`m0@An{L@X95dZ+BD!u>!
102
103
--
85
--
104
2.20.1
86
2.25.1
105
87
106
88
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
The semantic difference between the deprecated device_legacy_reset()
2
function and the newer device_cold_reset() function is that the new
3
function resets both the device itself and any qbuses it owns,
4
whereas the legacy function resets just the device itself and nothing
5
else. In hyperv_synic_reset() we reset a SynICState, which has no
6
qbuses, so for this purpose the two functions behave identically and
7
we can stop using the deprecated one.
2
8
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
11
Message-id: 20221013171817.1447562-1-peter.maydell@linaro.org
12
---
13
hw/hyperv/hyperv.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
4
15
5
Reported-by: Euler Robot <euler.robot@huawei.com>
16
diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-16-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
18
--- a/hw/hyperv/hyperv.c
18
+++ b/hw/gpio/aspeed_gpio.c
19
+++ b/hw/hyperv/hyperv.c
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ void hyperv_synic_reset(CPUState *cs)
20
pin_idx % GPIOS_PER_GROUP);
21
SynICState *synic = get_synic(cs);
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
22
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
23
if (synic) {
23
+ g_free(name);
24
- device_legacy_reset(DEVICE(synic));
25
+ device_cold_reset(DEVICE(synic));
24
}
26
}
25
}
27
}
26
28
27
--
29
--
28
2.20.1
30
2.25.1
29
30
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Switch to ram block writeback for pmem migration.
3
When running seL4 tests (https://docs.sel4.systems/projects/sel4test)
4
on the sabrelight platform, the timer tests fail. The arm/imx6 EPIT
5
timer interrupt does not fire properly, instead of a e.g. second in
6
can take up to a minute to finally see the interrupt.
4
7
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1263
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
11
Message-id: 166663118138.13362.1229967229046092876-0@git.sr.ht
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
migration/ram.c | 5 +----
15
hw/timer/imx_epit.c | 9 +++++++--
13
1 file changed, 1 insertion(+), 4 deletions(-)
16
1 file changed, 7 insertions(+), 2 deletions(-)
14
17
15
diff --git a/migration/ram.c b/migration/ram.c
18
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
20
--- a/hw/timer/imx_epit.c
18
+++ b/migration/ram.c
21
+++ b/hw/timer/imx_epit.c
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
20
#include "qemu/bitops.h"
23
/* If IOVW bit is set then set the timer value */
21
#include "qemu/bitmap.h"
24
ptimer_set_count(s->timer_reload, s->lr);
22
#include "qemu/main-loop.h"
25
}
23
-#include "qemu/pmem.h"
26
-
24
#include "xbzrle.h"
27
+ /*
25
#include "ram.h"
28
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
26
#include "migration.h"
29
+ * the timer interrupt may not fire properly. The commit must happen
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
30
+ * before calling imx_epit_reload_compare_timer(), which reads
28
RAMBlock *rb;
31
+ * s->timer_reload internally again.
29
32
+ */
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
33
+ ptimer_transaction_commit(s->timer_reload);
31
- if (ramblock_is_pmem(rb)) {
34
imx_epit_reload_compare_timer(s);
32
- pmem_persist(rb->host, rb->used_length);
35
ptimer_transaction_commit(s->timer_cmp);
33
- }
36
- ptimer_transaction_commit(s->timer_reload);
34
+ qemu_ram_block_writeback(rb);
37
break;
35
}
38
36
39
case 3: /* CMP */
37
xbzrle_load_cleanup();
38
--
40
--
39
2.20.1
41
2.25.1
40
41
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
QEMU lacks the minimum Jazelle implementation that is required
3
Reduce the amount of typing required for this check.
4
by the architecture (everything is RAZ or RAZ/WI). Add it
5
together with the HCR_EL2.TID0 trapping that goes with it.
6
4
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
8
Message-id: 20221024051851.3074715-2-richard.henderson@linaro.org
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
12
'static global', moved new condition down in
13
register_cp_regs_for_features() to go with other feature
14
things rather than up with the v6/v7/v8 stuff]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
11
target/arm/internals.h | 5 +++++
18
1 file changed, 27 insertions(+)
12
target/arm/helper.c | 14 +++++---------
13
target/arm/ptw.c | 14 ++++++--------
14
3 files changed, 16 insertions(+), 17 deletions(-)
19
15
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
21
}
22
}
23
24
+static inline bool regime_is_stage2(ARMMMUIdx mmu_idx)
25
+{
26
+ return mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
27
+}
28
+
29
/* Return the exception level which controls this address translation regime */
30
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
31
{
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
34
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
35
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
36
@@ -XXX,XX +XXX,XX @@ int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
25
return CP_ACCESS_OK;
37
{
38
if (regime_has_2_ranges(mmu_idx)) {
39
return extract64(tcr, 37, 2);
40
- } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
41
+ } else if (regime_is_stage2(mmu_idx)) {
42
return 0; /* VTCR_EL2 */
43
} else {
44
/* Replicate the single TBI bit so we always have 2 bits. */
45
@@ -XXX,XX +XXX,XX @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
46
{
47
if (regime_has_2_ranges(mmu_idx)) {
48
return extract64(tcr, 51, 2);
49
- } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
50
+ } else if (regime_is_stage2(mmu_idx)) {
51
return 0; /* VTCR_EL2 */
52
} else {
53
/* Replicate the single TBID bit so we always have 2 bits. */
54
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
55
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
56
ARMGranuleSize gran;
57
ARMCPU *cpu = env_archcpu(env);
58
- bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
59
+ bool stage2 = regime_is_stage2(mmu_idx);
60
61
if (!regime_has_2_ranges(mmu_idx)) {
62
select = 0;
63
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
64
}
65
ds = false;
66
} else if (ds) {
67
- switch (mmu_idx) {
68
- case ARMMMUIdx_Stage2:
69
- case ARMMMUIdx_Stage2_S:
70
+ if (regime_is_stage2(mmu_idx)) {
71
if (gran == Gran16K) {
72
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
73
} else {
74
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
75
}
76
- break;
77
- default:
78
+ } else {
79
if (gran == Gran16K) {
80
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
81
} else {
82
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
83
}
84
- break;
85
}
86
if (ds) {
87
min_tsz = 12;
88
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/ptw.c
91
+++ b/target/arm/ptw.c
92
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
93
bool have_wxn;
94
int wxn = 0;
95
96
- assert(mmu_idx != ARMMMUIdx_Stage2);
97
- assert(mmu_idx != ARMMMUIdx_Stage2_S);
98
+ assert(!regime_is_stage2(mmu_idx));
99
100
user_rw = simple_ap_to_rw_prot_is_user(ap, true);
101
if (is_user) {
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
103
goto do_fault;
104
}
105
106
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
107
+ if (!regime_is_stage2(mmu_idx)) {
108
/*
109
* The starting level depends on the virtual address size (which can
110
* be up to 48 bits) and the translation granule size. It indicates
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
112
attrs = extract64(descriptor, 2, 10)
113
| (extract64(descriptor, 52, 12) << 10);
114
115
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
116
+ if (regime_is_stage2(mmu_idx)) {
117
/* Stage 2 table descriptors do not include any attribute fields */
118
break;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
121
122
ap = extract32(attrs, 4, 2);
123
124
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
125
+ if (regime_is_stage2(mmu_idx)) {
126
ns = mmu_idx == ARMMMUIdx_Stage2;
127
xn = extract32(attrs, 11, 2);
128
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
130
result->f.guarded = guarded;
131
}
132
133
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
134
+ if (regime_is_stage2(mmu_idx)) {
135
result->cacheattrs.is_s2_format = true;
136
result->cacheattrs.attrs = extract32(attrs, 0, 4);
137
} else {
138
@@ -XXX,XX +XXX,XX @@ do_fault:
139
fi->type = fault_type;
140
fi->level = level;
141
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
142
- fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
143
- mmu_idx == ARMMMUIdx_Stage2_S);
144
+ fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
145
fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
146
return true;
26
}
147
}
27
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
39
+ { .name = "JIDR",
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
41
+ .access = PL1_R, .accessfn = access_jazelle,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
43
+ { .name = "JOSCR",
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ { .name = "JMCR",
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ REGINFO_SENTINEL
50
+};
51
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
53
{
54
/* Register all the coprocessor registers based on feature bits */
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
58
}
59
+ if (cpu_isar_feature(jazelle, cpu)) {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
61
+ }
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
64
* be read-only (ie write causes UNDEF exception).
65
--
148
--
66
2.20.1
149
2.25.1
67
150
68
151
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
AspeedBoardConfig is a redundant way to define class attributes and it
3
Hoist the computation of the mmu_idx for the ptw up to
4
complexifies the machine definition and initialization.
4
get_phys_addr_with_struct and get_phys_addr_twostage.
5
This removes the duplicate check for stage2 disabled
6
from the middle of the walk, performing it only once.
5
7
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
11
Message-id: 20221024051851.3074715-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/arm/aspeed.h | 24 ++--
14
target/arm/ptw.c | 71 ++++++++++++++++++++++++++++++++++++------------
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
15
1 file changed, 54 insertions(+), 17 deletions(-)
14
2 files changed, 143 insertions(+), 124 deletions(-)
15
16
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
19
--- a/target/arm/ptw.c
19
+++ b/include/hw/arm/aspeed.h
20
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
21
22
22
typedef struct AspeedBoardState AspeedBoardState;
23
typedef struct S1Translate {
23
24
ARMMMUIdx in_mmu_idx;
24
-typedef struct AspeedBoardConfig {
25
+ ARMMMUIdx in_ptw_idx;
25
- const char *name;
26
bool in_secure;
26
- const char *desc;
27
bool in_debug;
27
- const char *soc_name;
28
bool out_secure;
28
- uint32_t hw_strap1;
29
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
29
- uint32_t hw_strap2;
30
{
30
- const char *fmc_model;
31
bool is_secure = ptw->in_secure;
31
- const char *spi_model;
32
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
32
- uint32_t num_cs;
33
- ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
33
- void (*i2c_init)(AspeedBoardState *bmc);
34
- bool s2_phys = false;
34
- uint32_t ram;
35
+ ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
35
-} AspeedBoardConfig;
36
uint8_t pte_attrs;
37
bool pte_secure;
38
39
- if (!arm_mmu_idx_is_stage1_of_2(mmu_idx)
40
- || regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
41
- s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
42
- s2_phys = true;
43
- }
36
-
44
-
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
45
if (unlikely(ptw->in_debug)) {
38
#define ASPEED_MACHINE(obj) \
46
/*
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
47
* From gdbstub, do not use softmmu so that we don't modify the
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
48
* state of the cpu at all, including softmmu tlb contents.
41
49
*/
42
typedef struct AspeedMachineClass {
50
- if (s2_phys) {
43
MachineClass parent_obj;
51
- ptw->out_phys = addr;
44
- const AspeedBoardConfig *board;
52
- pte_attrs = 0;
53
- pte_secure = is_secure;
54
- } else {
55
+ if (regime_is_stage2(s2_mmu_idx)) {
56
S1Translate s2ptw = {
57
.in_mmu_idx = s2_mmu_idx,
58
+ .in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS,
59
.in_secure = is_secure,
60
.in_debug = true,
61
};
62
GetPhysAddrResult s2 = { };
45
+
63
+
46
+ const char *name;
64
if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
47
+ const char *desc;
65
false, &s2, fi)) {
48
+ const char *soc_name;
66
goto fail;
49
+ uint32_t hw_strap1;
67
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
50
+ uint32_t hw_strap2;
68
ptw->out_phys = s2.f.phys_addr;
51
+ const char *fmc_model;
69
pte_attrs = s2.cacheattrs.attrs;
52
+ const char *spi_model;
70
pte_secure = s2.f.attrs.secure;
53
+ uint32_t num_cs;
71
+ } else {
54
+ void (*i2c_init)(AspeedBoardState *bmc);
72
+ /* Regime is physical. */
55
} AspeedMachineClass;
73
+ ptw->out_phys = addr;
56
74
+ pte_attrs = 0;
57
75
+ pte_secure = is_secure;
58
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
76
}
59
index XXXXXXX..XXXXXXX 100644
77
ptw->out_host = NULL;
60
--- a/hw/arm/aspeed.c
78
} else {
61
+++ b/hw/arm/aspeed.c
79
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
80
pte_secure = full->attrs.secure;
63
}
81
}
64
}
82
65
83
- if (!s2_phys) {
66
-static void aspeed_board_init(MachineState *machine,
84
+ if (regime_is_stage2(s2_mmu_idx)) {
67
- const AspeedBoardConfig *cfg)
85
uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
68
+static void aspeed_machine_init(MachineState *machine)
86
87
if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) {
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
89
descaddr |= (address >> (stride * (4 - level))) & indexmask;
90
descaddr &= ~7ULL;
91
nstable = extract32(tableattrs, 4, 1);
92
- ptw->in_secure = !nstable;
93
+ if (!nstable) {
94
+ /*
95
+ * Stage2_S -> Stage2 or Phys_S -> Phys_NS
96
+ * Assert that the non-secure idx are even, and relative order.
97
+ */
98
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
99
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
100
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
101
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
102
+ ptw->in_ptw_idx &= ~1;
103
+ ptw->in_secure = false;
104
+ }
105
descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
106
if (fi->type != ARMFault_None) {
107
goto do_fault;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
109
110
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
111
ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
112
+ ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
113
ptw->in_secure = s2walk_secure;
114
115
/*
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
117
ARMMMUFaultInfo *fi)
69
{
118
{
70
AspeedBoardState *bmc;
119
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
120
- ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
72
AspeedSoCClass *sc;
121
bool is_secure = ptw->in_secure;
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
122
+ ARMMMUIdx s1_mmu_idx;
74
ram_addr_t max_ram_size;
123
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
124
- if (mmu_idx != s1_mmu_idx) {
76
UINT32_MAX);
125
+ switch (mmu_idx) {
77
126
+ case ARMMMUIdx_Phys_S:
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
127
+ case ARMMMUIdx_Phys_NS:
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
128
+ /* Checking Phys early avoids special casing later vs regime_el. */
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
129
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
81
NULL);
130
+ is_secure, result, fi);
82
131
+
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
132
+ case ARMMMUIdx_Stage1_E0:
84
133
+ case ARMMMUIdx_Stage1_E1:
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
134
+ case ARMMMUIdx_Stage1_E1_PAN:
86
&error_abort);
135
+ /* First stage lookup uses second stage for ptw. */
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
136
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
137
+ break;
89
&error_abort);
138
+
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
139
+ case ARMMMUIdx_E10_0:
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
140
+ s1_mmu_idx = ARMMMUIdx_Stage1_E0;
92
&error_abort);
141
+ goto do_twostage;
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
142
+ case ARMMMUIdx_E10_1:
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
143
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1;
95
&error_abort);
144
+ goto do_twostage;
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
145
+ case ARMMMUIdx_E10_1_PAN:
97
&error_abort);
146
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
147
+ do_twostage:
99
"max_ram", max_ram_size - ram_size);
148
/*
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
149
* Call ourselves recursively to do the stage 1 and then stage 2
101
150
* translations if mmu_idx is a two-stage regime, and EL2 present.
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
151
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
152
return get_phys_addr_twostage(env, ptw, address, access_type,
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
153
result, fi);
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
154
}
106
155
+ /* fall through */
107
/* Install first FMC flash content as a boot rom. */
156
+
108
if (drive0) {
157
+ default:
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
158
+ /* Single stage and second stage uses physical for ptw. */
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
159
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
160
+ break;
112
113
- if (cfg->i2c_init) {
114
- cfg->i2c_init(bmc);
115
+ if (amc->i2c_init) {
116
+ amc->i2c_init(bmc);
117
}
161
}
118
162
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
163
/*
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
121
0x60);
122
}
123
124
-static void aspeed_machine_init(MachineState *machine)
125
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
127
-
128
- aspeed_board_init(machine, amc->board);
129
-}
130
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
132
{
133
MachineClass *mc = MACHINE_CLASS(oc);
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
164
--
363
2.20.1
165
2.25.1
364
166
365
167
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A write to the SCR can change the effective EL by droppping the system
3
The MMFR1 field may indicate support for hardware update of
4
from secure to non-secure mode. However if we use a cached current_el
4
access flag alone, or access flag and dirty bit.
5
from before the change we'll rebuild the flags incorrectly. To fix
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
7
should be used when recomputing the flags.
8
5
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221024051851.3074715-4-richard.henderson@linaro.org
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Message-Id: <20191209143723.6368-1-alex.bennee@linaro.org>
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
target/arm/cpu.h | 8 ++++++--
11
target/arm/cpu.h | 10 ++++++++++
19
target/arm/helper.h | 1 +
12
1 file changed, 10 insertions(+)
20
target/arm/helper.c | 14 +++++++++++++-
21
target/arm/translate.c | 6 +++++-
22
4 files changed, 25 insertions(+), 4 deletions(-)
23
13
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
27
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
29
* RAISES_EXC is for when the read or write hook might raise an exception;
19
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
30
* the generated code will synchronize the CPU state before calling the hook
31
* so that it is safe for the hook to call raise_exception().
32
+ * NEWEL is for writes to registers that might change the exception
33
+ * level - typically on older ARM chips. For those cases we need to
34
+ * re-read the new el when recomputing the translation flags.
35
*/
36
#define ARM_CP_SPECIAL 0x0001
37
#define ARM_CP_CONST 0x0002
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
39
#define ARM_CP_SVE 0x2000
40
#define ARM_CP_NO_GDB 0x4000
41
#define ARM_CP_RAISES_EXC 0x8000
42
+#define ARM_CP_NEWEL 0x10000
43
/* Used only as a terminator for ARMCPRegInfo lists */
44
-#define ARM_CP_SENTINEL 0xffff
45
+#define ARM_CP_SENTINEL 0xfffff
46
/* Mask of only the flag bits in a type field */
47
-#define ARM_CP_FLAG_MASK 0xf0ff
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
49
50
/* Valid values for ARMCPRegInfo state field, indicating which of
51
* the AArch32 and AArch64 execution states this register is visible in.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.h
55
+++ b/target/arm/helper.h
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
58
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
63
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
67
+++ b/target/arm/helper.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
71
.resetvalue = 0, .writefn = scr_write },
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
79
}
20
}
80
21
81
+/*
22
+static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
82
+ * If we have triggered a EL state change we can't rely on the
83
+ * translator having passed it too us, we need to recompute.
84
+ */
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
86
+{
23
+{
87
+ int el = arm_current_el(env);
24
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
88
+ int fp_el = fp_exception_el(env, el);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
91
+}
25
+}
92
+
26
+
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
27
+static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
28
+{
29
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
30
+}
31
+
32
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
94
{
33
{
95
int fp_el = fp_exception_el(env, el);
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
103
} else {
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
105
+ if (ri->type & ARM_CP_NEWEL) {
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
107
+ } else {
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
109
+ }
110
}
111
tcg_temp_free_i32(tcg_el);
112
/*
113
--
35
--
114
2.20.1
36
2.25.1
115
116
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
virtualize the HW (though to be fair, no known hypervisor actually
6
Message-id: 20221024051851.3074715-5-richard.henderson@linaro.org
7
cares).
8
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
9
target/arm/internals.h | 2 ++
18
1 file changed, 32 insertions(+), 4 deletions(-)
10
target/arm/helper.c | 8 +++++++-
11
2 files changed, 9 insertions(+), 1 deletion(-)
19
12
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
16
+++ b/target/arm/internals.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
18
bool hpd : 1;
19
bool tsz_oob : 1; /* tsz has been clamped to legal range */
20
bool ds : 1;
21
+ bool ha : 1;
22
+ bool hd : 1;
23
ARMGranuleSize gran : 2;
24
} ARMVAParameters;
25
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
28
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
29
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
30
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
25
return ret;
31
ARMMMUIdx mmu_idx, bool data)
32
{
33
uint64_t tcr = regime_tcr(env, mmu_idx);
34
- bool epd, hpd, tsz_oob, ds;
35
+ bool epd, hpd, tsz_oob, ds, ha, hd;
36
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
37
ARMGranuleSize gran;
38
ARMCPU *cpu = env_archcpu(env);
39
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
40
epd = false;
41
sh = extract32(tcr, 12, 2);
42
ps = extract32(tcr, 16, 3);
43
+ ha = extract32(tcr, 21, 1) && cpu_isar_feature(aa64_hafs, cpu);
44
+ hd = extract32(tcr, 22, 1) && cpu_isar_feature(aa64_hdbs, cpu);
45
ds = extract64(tcr, 32, 1);
46
} else {
47
bool e0pd;
48
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
49
e0pd = extract64(tcr, 56, 1);
50
}
51
ps = extract64(tcr, 32, 3);
52
+ ha = extract64(tcr, 39, 1) && cpu_isar_feature(aa64_hafs, cpu);
53
+ hd = extract64(tcr, 40, 1) && cpu_isar_feature(aa64_hdbs, cpu);
54
ds = extract64(tcr, 59, 1);
55
56
if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) &&
57
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
58
.hpd = hpd,
59
.tsz_oob = tsz_oob,
60
.ds = ds,
61
+ .ha = ha,
62
+ .hd = ha && hd,
63
.gran = gran,
64
};
26
}
65
}
27
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
39
+ bool isread)
40
+{
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
42
+ return access_aa64_tid1(env, ri, isread);
43
+ }
44
+
45
+ return CP_ACCESS_OK;
46
+}
47
+
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
*/
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
56
+ .access = PL1_R, .type = ARM_CP_CONST,
57
+ .accessfn = access_aa64_tid1,
58
+ .resetvalue = 0 },
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
60
* choose to RAZ/WI for all cores.
61
*/
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
.access = PL1_R, .resetvalue = cpu->midr },
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
67
+ .access = PL1_R,
68
+ .accessfn = access_aa64_tid1,
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
70
REGINFO_SENTINEL
71
};
72
ARMCPRegInfo id_cp_reginfo[] = {
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
75
{ .name = "TCMTR",
76
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
77
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ .access = PL1_R,
79
+ .accessfn = access_aa32_tid1,
80
+ .type = ARM_CP_CONST, .resetvalue = 0 },
81
REGINFO_SENTINEL
82
};
83
/* TLBTR is specific to VMSA */
84
ARMCPRegInfo id_tlbtr_reginfo = {
85
.name = "TLBTR",
86
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
87
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
88
+ .access = PL1_R,
89
+ .accessfn = access_aa32_tid1,
90
+ .type = ARM_CP_CONST, .resetvalue = 0,
91
};
92
/* MPUIR is specific to PMSA V6+ */
93
ARMCPRegInfo id_mpuir_reginfo = {
94
--
66
--
95
2.20.1
67
2.25.1
96
68
97
69
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add probe_read alongside the write probing equivalent.
3
Separate S1 translation from the actual lookup.
4
Will enable lpae hardware updates.
4
5
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221024051851.3074715-6-richard.henderson@linaro.org
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/exec/exec-all.h | 6 ++++++
11
target/arm/ptw.c | 41 ++++++++++++++++++++++-------------------
12
1 file changed, 6 insertions(+)
12
1 file changed, 22 insertions(+), 19 deletions(-)
13
13
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
16
--- a/target/arm/ptw.c
17
+++ b/include/exec/exec-all.h
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
20
}
19
}
21
20
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
21
/* All loads done in the course of a page table walk go through here. */
23
+ int mmu_idx, uintptr_t retaddr)
22
-static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
24
+{
23
+static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
24
ARMMMUFaultInfo *fi)
26
+}
25
{
27
+
26
CPUState *cs = env_cpu(env);
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
27
uint32_t data;
29
28
30
/* Estimated block size for TB allocation. */
29
- if (!S1_ptw_translate(env, ptw, addr, fi)) {
30
- /* Failure. */
31
- assert(fi->s1ptw);
32
- return 0;
33
- }
34
-
35
if (likely(ptw->out_host)) {
36
/* Page tables are in RAM, and we have the host address. */
37
if (ptw->out_be) {
38
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
39
return data;
40
}
41
42
-static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
43
+static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
44
ARMMMUFaultInfo *fi)
45
{
46
CPUState *cs = env_cpu(env);
47
uint64_t data;
48
49
- if (!S1_ptw_translate(env, ptw, addr, fi)) {
50
- /* Failure. */
51
- assert(fi->s1ptw);
52
- return 0;
53
- }
54
-
55
if (likely(ptw->out_host)) {
56
/* Page tables are in RAM, and we have the host address. */
57
if (ptw->out_be) {
58
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
59
fi->type = ARMFault_Translation;
60
goto do_fault;
61
}
62
- desc = arm_ldl_ptw(env, ptw, table, fi);
63
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
64
+ goto do_fault;
65
+ }
66
+ desc = arm_ldl_ptw(env, ptw, fi);
67
if (fi->type != ARMFault_None) {
68
goto do_fault;
69
}
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
71
/* Fine pagetable. */
72
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
73
}
74
- desc = arm_ldl_ptw(env, ptw, table, fi);
75
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
76
+ goto do_fault;
77
+ }
78
+ desc = arm_ldl_ptw(env, ptw, fi);
79
if (fi->type != ARMFault_None) {
80
goto do_fault;
81
}
82
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
83
fi->type = ARMFault_Translation;
84
goto do_fault;
85
}
86
- desc = arm_ldl_ptw(env, ptw, table, fi);
87
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
88
+ goto do_fault;
89
+ }
90
+ desc = arm_ldl_ptw(env, ptw, fi);
91
if (fi->type != ARMFault_None) {
92
goto do_fault;
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
95
ns = extract32(desc, 3, 1);
96
/* Lookup l2 entry. */
97
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
98
- desc = arm_ldl_ptw(env, ptw, table, fi);
99
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
100
+ goto do_fault;
101
+ }
102
+ desc = arm_ldl_ptw(env, ptw, fi);
103
if (fi->type != ARMFault_None) {
104
goto do_fault;
105
}
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
107
ptw->in_ptw_idx &= ~1;
108
ptw->in_secure = false;
109
}
110
- descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
111
+ if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
112
+ goto do_fault;
113
+ }
114
+ descriptor = arm_ldq_ptw(env, ptw, fi);
115
if (fi->type != ARMFault_None) {
116
goto do_fault;
117
}
31
--
118
--
32
2.20.1
119
2.25.1
33
34
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
3
This fault type is to be used with FEAT_HAFDBS when
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
4
the guest enables hw updates, but places the tables
5
In order to handle this, introduce a new TCG helper function that
5
in memory where atomic updates are unsupported.
6
checks for these control bits before executing the VMRC instruction.
7
6
8
Tested with a hacked-up version of KVM/arm64 that sets the control
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
bits for 32bit guests.
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20221024051851.3074715-7-richard.henderson@linaro.org
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
target/arm/helper.h | 2 ++
13
target/arm/internals.h | 4 ++++
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
14
1 file changed, 4 insertions(+)
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
22
3 files changed, 47 insertions(+), 4 deletions(-)
23
15
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
18
--- a/target/arm/internals.h
27
+++ b/target/arm/helper.h
19
+++ b/target/arm/internals.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
20
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
21
ARMFault_AsyncExternal,
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
22
ARMFault_Debug,
31
23
ARMFault_TLBConflict,
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
24
+ ARMFault_UnsuppAtomicUpdate,
33
+
25
ARMFault_Lockdown,
34
/* neon_helper.c */
26
ARMFault_Exclusive,
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
27
ARMFault_ICacheMaint,
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
29
case ARMFault_TLBConflict:
38
index XXXXXXX..XXXXXXX 100644
30
fsc = 0x30;
39
--- a/target/arm/translate-vfp.inc.c
31
break;
40
+++ b/target/arm/translate-vfp.inc.c
32
+ case ARMFault_UnsuppAtomicUpdate:
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
33
+ fsc = 0x31;
42
if (a->l) {
43
/* VMRS, move VFP special register to gp register */
44
switch (a->reg) {
45
- case ARM_VFP_FPSID:
46
- case ARM_VFP_FPEXC:
47
- case ARM_VFP_FPINST:
48
- case ARM_VFP_FPINST2:
49
case ARM_VFP_MVFR0:
50
case ARM_VFP_MVFR1:
51
case ARM_VFP_MVFR2:
52
+ case ARM_VFP_FPSID:
53
+ if (s->current_el == 1) {
54
+ TCGv_i32 tcg_reg, tcg_rt;
55
+
56
+ gen_set_condexec(s);
57
+ gen_set_pc_im(s, s->pc_curr);
58
+ tcg_reg = tcg_const_i32(a->reg);
59
+ tcg_rt = tcg_const_i32(a->rt);
60
+ gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
61
+ tcg_temp_free_i32(tcg_reg);
62
+ tcg_temp_free_i32(tcg_rt);
63
+ }
64
+ /* fall through */
65
+ case ARM_VFP_FPEXC:
66
+ case ARM_VFP_FPINST:
67
+ case ARM_VFP_FPINST2:
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
69
break;
70
case ARM_VFP_FPSCR:
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
76
return frint_d(f, fpst, 64);
77
}
78
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
80
+{
81
+ uint32_t syndrome;
82
+
83
+ switch (reg) {
84
+ case ARM_VFP_MVFR0:
85
+ case ARM_VFP_MVFR1:
86
+ case ARM_VFP_MVFR2:
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
88
+ return;
89
+ }
90
+ break;
34
+ break;
91
+ case ARM_VFP_FPSID:
35
case ARMFault_Lockdown:
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
36
fsc = 0x34;
93
+ return;
37
break;
94
+ }
95
+ break;
96
+ default:
97
+ g_assert_not_reached();
98
+ }
99
+
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
101
+ | ARM_EL_IL
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
103
+ | (reg << 10) | (rt << 5) | 1);
104
+
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
106
+}
107
+
108
#endif
109
--
38
--
110
2.20.1
39
2.25.1
111
40
112
41
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
3
The unconditional loop was used both to iterate over levels
4
we will also have SHPC controller on ARM, so just enable SHPC native
4
and to control parsing of attributes. Use an explicit goto
5
hot plug.
5
in both cases.
6
6
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
7
While this appears less clean for iterating over levels, we
8
8
will need to jump back into the middle of this loop for
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
9
atomic updates, which is even uglier.
10
Cc: Peter Maydell <peter.maydell@linaro.org>
10
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Cc: Igor Mammedov <imammedo@redhat.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
13
Message-id: 20221024051851.3074715-8-richard.henderson@linaro.org
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-3-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
15
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
16
target/arm/ptw.c | 192 +++++++++++++++++++++++------------------------
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
17
1 file changed, 96 insertions(+), 96 deletions(-)
21
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 19799 bytes
18
22
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 18462 bytes
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
23
4 files changed, 6 insertions(+), 1 deletion(-)
24
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
21
--- a/target/arm/ptw.c
28
+++ b/hw/arm/virt-acpi-build.c
22
+++ b/target/arm/ptw.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
24
uint64_t descaddrmask;
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
25
bool aarch64 = arm_el_is_aa64(env, el);
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
26
bool guarded = false;
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
27
+ uint64_t descriptor;
28
+ bool nstable;
29
30
/* TODO: This code does not support shareability levels. */
31
if (aarch64) {
32
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
33
* bits at each step.
34
*/
35
tableattrs = is_secure ? 0 : (1 << 4);
36
- for (;;) {
37
- uint64_t descriptor;
38
- bool nstable;
39
-
40
- descaddr |= (address >> (stride * (4 - level))) & indexmask;
41
- descaddr &= ~7ULL;
42
- nstable = extract32(tableattrs, 4, 1);
43
- if (!nstable) {
44
- /*
45
- * Stage2_S -> Stage2 or Phys_S -> Phys_NS
46
- * Assert that the non-secure idx are even, and relative order.
47
- */
48
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
49
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
50
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
51
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
52
- ptw->in_ptw_idx &= ~1;
53
- ptw->in_secure = false;
54
- }
55
- if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
56
- goto do_fault;
57
- }
58
- descriptor = arm_ldq_ptw(env, ptw, fi);
59
- if (fi->type != ARMFault_None) {
60
- goto do_fault;
61
- }
62
-
63
- if (!(descriptor & 1) ||
64
- (!(descriptor & 2) && (level == 3))) {
65
- /* Invalid, or the Reserved level 3 encoding */
66
- goto do_fault;
67
- }
68
-
69
- descaddr = descriptor & descaddrmask;
70
71
+ next_level:
72
+ descaddr |= (address >> (stride * (4 - level))) & indexmask;
73
+ descaddr &= ~7ULL;
74
+ nstable = extract32(tableattrs, 4, 1);
75
+ if (!nstable) {
76
/*
77
- * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
78
- * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
79
- * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
80
- * raise AddressSizeFault.
81
+ * Stage2_S -> Stage2 or Phys_S -> Phys_NS
82
+ * Assert that the non-secure idx are even, and relative order.
83
*/
84
- if (outputsize > 48) {
85
- if (param.ds) {
86
- descaddr |= extract64(descriptor, 8, 2) << 50;
87
- } else {
88
- descaddr |= extract64(descriptor, 12, 4) << 48;
89
- }
90
- } else if (descaddr >> outputsize) {
91
- fault_type = ARMFault_AddressSize;
92
- goto do_fault;
93
- }
94
-
95
- if ((descriptor & 2) && (level < 3)) {
96
- /*
97
- * Table entry. The top five bits are attributes which may
98
- * propagate down through lower levels of the table (and
99
- * which are all arranged so that 0 means "no effect", so
100
- * we can gather them up by ORing in the bits at each level).
101
- */
102
- tableattrs |= extract64(descriptor, 59, 5);
103
- level++;
104
- indexmask = indexmask_grainsize;
105
- continue;
106
- }
107
- /*
108
- * Block entry at level 1 or 2, or page entry at level 3.
109
- * These are basically the same thing, although the number
110
- * of bits we pull in from the vaddr varies. Note that although
111
- * descaddrmask masks enough of the low bits of the descriptor
112
- * to give a correct page or table address, the address field
113
- * in a block descriptor is smaller; so we need to explicitly
114
- * clear the lower bits here before ORing in the low vaddr bits.
115
- */
116
- page_size = (1ULL << ((stride * (4 - level)) + 3));
117
- descaddr &= ~(hwaddr)(page_size - 1);
118
- descaddr |= (address & (page_size - 1));
119
- /* Extract attributes from the descriptor */
120
- attrs = extract64(descriptor, 2, 10)
121
- | (extract64(descriptor, 52, 12) << 10);
122
-
123
- if (regime_is_stage2(mmu_idx)) {
124
- /* Stage 2 table descriptors do not include any attribute fields */
125
- break;
126
- }
127
- /* Merge in attributes from table descriptors */
128
- attrs |= nstable << 3; /* NS */
129
- guarded = extract64(descriptor, 50, 1); /* GP */
130
- if (param.hpd) {
131
- /* HPD disables all the table attributes except NSTable. */
132
- break;
133
- }
134
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
135
- /*
136
- * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
137
- * means "force PL1 access only", which means forcing AP[1] to 0.
138
- */
139
- attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
140
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
141
- break;
142
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
143
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
144
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
145
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
146
+ ptw->in_ptw_idx &= ~1;
147
+ ptw->in_secure = false;
148
}
149
+ if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
150
+ goto do_fault;
151
+ }
152
+ descriptor = arm_ldq_ptw(env, ptw, fi);
153
+ if (fi->type != ARMFault_None) {
154
+ goto do_fault;
155
+ }
156
+
157
+ if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
158
+ /* Invalid, or the Reserved level 3 encoding */
159
+ goto do_fault;
160
+ }
161
+
162
+ descaddr = descriptor & descaddrmask;
34
+
163
+
35
+ /*
164
+ /*
36
+ * Allow OS control for all 5 features:
165
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
166
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
167
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
168
+ * raise AddressSizeFault.
38
+ */
169
+ */
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
170
+ if (outputsize > 48) {
40
aml_name("CTRL")));
171
+ if (param.ds) {
41
172
+ descaddr |= extract64(descriptor, 8, 2) << 50;
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
173
+ } else {
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
174
+ descaddr |= extract64(descriptor, 12, 4) << 48;
44
index XXXXXXX..XXXXXXX 100644
175
+ }
45
GIT binary patch
176
+ } else if (descaddr >> outputsize) {
46
delta 28
177
+ fault_type = ARMFault_AddressSize;
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
178
+ goto do_fault;
48
179
+ }
49
delta 28
180
+
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
181
+ if ((descriptor & 2) && (level < 3)) {
51
182
+ /*
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
183
+ * Table entry. The top five bits are attributes which may
53
index XXXXXXX..XXXXXXX 100644
184
+ * propagate down through lower levels of the table (and
54
GIT binary patch
185
+ * which are all arranged so that 0 means "no effect", so
55
delta 28
186
+ * we can gather them up by ORing in the bits at each level).
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
187
+ */
57
188
+ tableattrs |= extract64(descriptor, 59, 5);
58
delta 28
189
+ level++;
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
190
+ indexmask = indexmask_grainsize;
60
191
+ goto next_level;
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
192
+ }
62
index XXXXXXX..XXXXXXX 100644
193
+
63
GIT binary patch
194
+ /*
64
delta 28
195
+ * Block entry at level 1 or 2, or page entry at level 3.
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
196
+ * These are basically the same thing, although the number
66
197
+ * of bits we pull in from the vaddr varies. Note that although
67
delta 28
198
+ * descaddrmask masks enough of the low bits of the descriptor
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
199
+ * to give a correct page or table address, the address field
69
200
+ * in a block descriptor is smaller; so we need to explicitly
201
+ * clear the lower bits here before ORing in the low vaddr bits.
202
+ */
203
+ page_size = (1ULL << ((stride * (4 - level)) + 3));
204
+ descaddr &= ~(hwaddr)(page_size - 1);
205
+ descaddr |= (address & (page_size - 1));
206
+ /* Extract attributes from the descriptor */
207
+ attrs = extract64(descriptor, 2, 10)
208
+ | (extract64(descriptor, 52, 12) << 10);
209
+
210
+ if (regime_is_stage2(mmu_idx)) {
211
+ /* Stage 2 table descriptors do not include any attribute fields */
212
+ goto skip_attrs;
213
+ }
214
+ /* Merge in attributes from table descriptors */
215
+ attrs |= nstable << 3; /* NS */
216
+ guarded = extract64(descriptor, 50, 1); /* GP */
217
+ if (param.hpd) {
218
+ /* HPD disables all the table attributes except NSTable. */
219
+ goto skip_attrs;
220
+ }
221
+ attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
222
+ /*
223
+ * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
224
+ * means "force PL1 access only", which means forcing AP[1] to 0.
225
+ */
226
+ attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
227
+ attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
228
+ skip_attrs:
229
+
230
/*
231
* Here descaddr is the final physical address, and attributes
232
* are all in attrs.
70
--
233
--
71
2.20.1
234
2.25.1
72
73
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
3
Always overriding fi->type was incorrect, as we would not properly
4
controller model of the machine.
4
propagate the fault type from S1_ptw_translate, or arm_ldq_ptw.
5
Simplify things by providing a new label for a translation fault.
6
For other faults, store into fi directly.
5
7
6
Change the "scu" property definition so that it explicitly sets the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
pointer. The property isn't optional : not being able to set the link
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
is a bug and QEMU should rather abort than exit in this case.
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
11
Message-id: 20221024051851.3074715-9-richard.henderson@linaro.org
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-17-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
14
target/arm/ptw.c | 31 +++++++++++++------------------
18
hw/arm/aspeed_soc.c | 8 ++++----
15
1 file changed, 13 insertions(+), 18 deletions(-)
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
16
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
19
--- a/target/arm/ptw.c
26
+++ b/hw/arm/aspeed_ast2600.c
20
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
22
ARMCPU *cpu = env_archcpu(env);
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
23
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
30
sizeof(s->timerctrl), typename);
24
bool is_secure = ptw->in_secure;
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
25
- /* Read an LPAE long-descriptor translation table. */
32
- OBJECT(&s->scu), &error_abort);
26
- ARMFaultType fault_type = ARMFault_Translation;
33
27
uint32_t level;
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
28
ARMVAParameters param;
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
29
uint64_t ttbr;
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
31
* so our choice is to always raise the fault.
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
32
*/
39
sizeof(s->wdt[i]), typename);
33
if (param.tsz_oob) {
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
34
- fault_type = ARMFault_Translation;
41
- OBJECT(&s->scu), &error_abort);
35
- goto do_fault;
36
+ goto do_translation_fault;
37
}
38
39
addrsize = 64 - 8 * param.tbi;
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
41
addrsize - inputsize);
42
if (-top_bits != param.select) {
43
/* The gap between the two regions is a Translation fault */
44
- fault_type = ARMFault_Translation;
45
- goto do_fault;
46
+ goto do_translation_fault;
47
}
42
}
48
}
43
49
44
for (i = 0; i < sc->macs_num; i++) {
50
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
51
* Translation table walk disabled => Translation fault on TLB miss
46
aspeed_soc_get_irq(s, ASPEED_RTC));
52
* Note: This is always 0 on 64-bit EL2 and EL3.
47
53
*/
48
/* Timer */
54
- goto do_fault;
49
+ object_property_set_link(OBJECT(&s->timerctrl),
55
+ goto do_translation_fault;
50
+ OBJECT(&s->scu), "scu", &error_abort);
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
52
if (err) {
53
error_propagate(errp, err);
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
55
for (i = 0; i < sc->wdts_num; i++) {
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
57
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
59
+ OBJECT(&s->scu), "scu", &error_abort);
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
61
if (err) {
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
70
sizeof(s->timerctrl), typename);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
72
- OBJECT(&s->scu), &error_abort);
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
56
}
83
57
84
for (i = 0; i < sc->macs_num; i++) {
58
if (!regime_is_stage2(mmu_idx)) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
59
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
86
aspeed_soc_get_irq(s, ASPEED_RTC));
60
if (param.ds && stride == 9 && sl2) {
87
61
if (sl0 != 0) {
88
/* Timer */
62
level = 0;
89
+ object_property_set_link(OBJECT(&s->timerctrl),
63
- fault_type = ARMFault_Translation;
90
+ OBJECT(&s->scu), "scu", &error_abort);
64
- goto do_fault;
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
65
+ goto do_translation_fault;
92
if (err) {
66
}
93
error_propagate(errp, err);
67
startlevel = -1;
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
68
} else if (!aarch64 || stride == 9) {
95
for (i = 0; i < sc->wdts_num; i++) {
69
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
70
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
97
71
inputsize, stride, outputsize);
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
72
if (!ok) {
99
+ OBJECT(&s->scu), "scu", &error_abort);
73
- fault_type = ARMFault_Translation;
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
74
- goto do_fault;
101
if (err) {
75
+ goto do_translation_fault;
102
error_propagate(errp, err);
76
}
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
77
level = startlevel;
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/timer/aspeed_timer.c
106
+++ b/hw/timer/aspeed_timer.c
107
@@ -XXX,XX +XXX,XX @@
108
#include "qemu/timer.h"
109
#include "qemu/log.h"
110
#include "qemu/module.h"
111
+#include "hw/qdev-properties.h"
112
#include "trace.h"
113
114
#define TIMER_NR_REGS 4
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
116
int i;
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
119
- Object *obj;
120
- Error *err = NULL;
121
122
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
123
- if (!obj) {
124
- error_propagate_prepend(errp, err, "required link 'scu' not found: ");
125
- return;
126
- }
127
- s->scu = ASPEED_SCU(obj);
128
+ assert(s->scu);
129
130
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
131
aspeed_init_one_timer(s, i);
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_timer_state = {
133
}
78
}
134
};
79
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
135
80
descaddr |= extract64(ttbr, 2, 4) << 48;
136
+static Property aspeed_timer_properties[] = {
81
} else if (descaddr >> outputsize) {
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
82
level = 0;
138
+ AspeedSCUState *),
83
- fault_type = ARMFault_AddressSize;
139
+ DEFINE_PROP_END_OF_LIST(),
84
+ fi->type = ARMFault_AddressSize;
140
+};
85
goto do_fault;
141
+
86
}
142
static void timer_class_init(ObjectClass *klass, void *data)
87
143
{
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
144
DeviceClass *dc = DEVICE_CLASS(klass);
89
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
90
if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
146
dc->reset = aspeed_timer_reset;
91
/* Invalid, or the Reserved level 3 encoding */
147
dc->desc = "ASPEED Timer";
92
- goto do_fault;
148
dc->vmsd = &vmstate_aspeed_timer_state;
93
+ goto do_translation_fault;
149
+ dc->props = aspeed_timer_properties;
94
}
150
}
95
151
96
descaddr = descriptor & descaddrmask;
152
static const TypeInfo aspeed_timer_info = {
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
98
descaddr |= extract64(descriptor, 12, 4) << 48;
154
index XXXXXXX..XXXXXXX 100644
99
}
155
--- a/hw/watchdog/wdt_aspeed.c
100
} else if (descaddr >> outputsize) {
156
+++ b/hw/watchdog/wdt_aspeed.c
101
- fault_type = ARMFault_AddressSize;
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
102
+ fi->type = ARMFault_AddressSize;
158
{
103
goto do_fault;
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
104
}
160
AspeedWDTState *s = ASPEED_WDT(dev);
105
161
- Error *err = NULL;
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
162
- Object *obj;
107
* Here descaddr is the final physical address, and attributes
163
108
* are all in attrs.
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
109
*/
165
- if (!obj) {
110
- fault_type = ARMFault_AccessFlag;
166
- error_propagate(errp, err);
111
if ((attrs & (1 << 8)) == 0) {
167
- error_prepend(errp, "required link 'scu' not found: ");
112
/* Access flag */
168
- return;
113
+ fi->type = ARMFault_AccessFlag;
169
- }
114
goto do_fault;
170
- s->scu = ASPEED_SCU(obj);
115
}
171
+ assert(s->scu);
116
172
117
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
118
result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
174
119
}
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
120
176
sysbus_init_mmio(sbd, &s->iomem);
121
- fault_type = ARMFault_Permission;
177
}
122
if (!(result->f.prot & (1 << access_type))) {
178
123
+ fi->type = ARMFault_Permission;
179
+static Property aspeed_wdt_properties[] = {
124
goto do_fault;
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
125
}
181
+ AspeedSCUState *),
126
182
+ DEFINE_PROP_END_OF_LIST(),
127
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
183
+};
128
result->f.lg_page_size = ctz64(page_size);
184
+
129
return false;
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
130
186
{
131
-do_fault:
187
DeviceClass *dc = DEVICE_CLASS(klass);
132
- fi->type = fault_type;
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
133
+ do_translation_fault:
189
dc->reset = aspeed_wdt_reset;
134
+ fi->type = ARMFault_Translation;
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
135
+ do_fault:
191
dc->vmsd = &vmstate_aspeed_wdt;
136
fi->level = level;
192
+ dc->props = aspeed_wdt_properties;
137
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
193
}
138
fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
194
195
static const TypeInfo aspeed_wdt_info = {
196
--
139
--
197
2.20.1
140
2.25.1
198
141
199
142
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
3
Leave the upper and lower attributes in the place they originate
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
4
from in the descriptor. Shifting them around is confusing, since
5
completely ignores it, making it impossible for hypervisors to
5
one cannot read the bit numbers out of the manual. Also, new
6
virtualize the cache hierarchy.
6
attributes have been added which would alter the shifts.
7
7
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20221024051851.3074715-10-richard.henderson@linaro.org
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
14
target/arm/ptw.c | 31 +++++++++++++++----------------
17
1 file changed, 27 insertions(+), 4 deletions(-)
15
1 file changed, 15 insertions(+), 16 deletions(-)
18
16
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
19
--- a/target/arm/ptw.c
22
+++ b/target/arm/helper.c
20
+++ b/target/arm/ptw.c
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
24
raw_write(env, ri, value);
22
hwaddr descaddr, indexmask, indexmask_grainsize;
25
}
23
uint32_t tableattrs;
26
24
target_ulong page_size;
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
25
- uint32_t attrs;
28
+ const ARMCPRegInfo *ri,
26
+ uint64_t attrs;
29
+ bool isread)
27
int32_t stride;
30
+{
28
int addrsize, inputsize, outputsize;
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
29
uint64_t tcr = regime_tcr(env, mmu_idx);
32
+ return CP_ACCESS_TRAP_EL2;
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
33
+ }
31
descaddr &= ~(hwaddr)(page_size - 1);
34
+
32
descaddr |= (address & (page_size - 1));
35
+ return CP_ACCESS_OK;
33
/* Extract attributes from the descriptor */
36
+}
34
- attrs = extract64(descriptor, 2, 10)
37
+
35
- | (extract64(descriptor, 52, 12) << 10);
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
36
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12));
39
{
37
40
ARMCPU *cpu = env_archcpu(env);
38
if (regime_is_stage2(mmu_idx)) {
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
39
/* Stage 2 table descriptors do not include any attribute fields */
42
.writefn = pmintenclr_write },
40
goto skip_attrs;
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
46
+ .access = PL1_R,
47
+ .accessfn = access_aa64_tid2,
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
52
+ .access = PL1_RW,
53
+ .accessfn = access_aa64_tid2,
54
+ .writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
60
return CP_ACCESS_TRAP;
61
}
41
}
62
+
42
/* Merge in attributes from table descriptors */
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
43
- attrs |= nstable << 3; /* NS */
64
+ return CP_ACCESS_TRAP_EL2;
44
+ attrs |= nstable << 5; /* NS */
65
+ }
45
guarded = extract64(descriptor, 50, 1); /* GP */
66
+
46
if (param.hpd) {
67
return CP_ACCESS_OK;
47
/* HPD disables all the table attributes except NSTable. */
68
}
48
goto skip_attrs;
69
49
}
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
50
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
71
ARMCPRegInfo clidr = {
51
+ attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
52
/*
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
53
* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
54
* means "force PL1 access only", which means forcing AP[1] to 0.
75
+ .access = PL1_R, .type = ARM_CP_CONST,
55
*/
76
+ .accessfn = access_aa64_tid2,
56
- attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
77
+ .resetvalue = cpu->clidr
57
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
78
};
58
+ attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
79
define_one_arm_cp_reg(cpu, &clidr);
59
+ attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
60
skip_attrs:
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
61
82
/* These are common to v8 and pre-v8 */
62
/*
83
{ .name = "CTR",
63
* Here descaddr is the final physical address, and attributes
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
64
* are all in attrs.
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
65
*/
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
66
- if ((attrs & (1 << 8)) == 0) {
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
67
+ if ((attrs & (1 << 10)) == 0) {
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
68
/* Access flag */
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
69
fi->type = ARMFault_AccessFlag;
90
.access = PL0_R, .accessfn = ctr_el0_access,
70
goto do_fault;
71
}
72
73
- ap = extract32(attrs, 4, 2);
74
+ ap = extract32(attrs, 6, 2);
75
76
if (regime_is_stage2(mmu_idx)) {
77
ns = mmu_idx == ARMMMUIdx_Stage2;
78
- xn = extract32(attrs, 11, 2);
79
+ xn = extract64(attrs, 53, 2);
80
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
81
} else {
82
- ns = extract32(attrs, 3, 1);
83
- xn = extract32(attrs, 12, 1);
84
- pxn = extract32(attrs, 11, 1);
85
+ ns = extract32(attrs, 5, 1);
86
+ xn = extract64(attrs, 54, 1);
87
+ pxn = extract64(attrs, 53, 1);
88
result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
92
93
if (regime_is_stage2(mmu_idx)) {
94
result->cacheattrs.is_s2_format = true;
95
- result->cacheattrs.attrs = extract32(attrs, 0, 4);
96
+ result->cacheattrs.attrs = extract32(attrs, 2, 4);
97
} else {
98
/* Index into MAIR registers for cache attributes */
99
- uint8_t attrindx = extract32(attrs, 0, 3);
100
+ uint8_t attrindx = extract32(attrs, 2, 3);
101
uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
102
assert(attrindx <= 7);
103
result->cacheattrs.is_s2_format = false;
104
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
105
if (param.ds) {
106
result->cacheattrs.shareability = param.sh;
107
} else {
108
- result->cacheattrs.shareability = extract32(attrs, 6, 2);
109
+ result->cacheattrs.shareability = extract32(attrs, 8, 2);
110
}
111
112
result->f.phys_addr = descaddr;
91
--
113
--
92
2.20.1
114
2.25.1
93
115
94
116
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The current model only restores the Segment Register values but leaves
3
Both GP and DBM are in the upper attribute block.
4
the previous CS mapping behind. Introduce a helper setting the
4
Extend the computation of attrs to include them,
5
register value and mapping the region at the requested address. Use
5
then simplify the setting of guarded.
6
this helper when a Segment register is set and at reset.
7
6
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20221024051851.3074715-11-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
14
target/arm/ptw.c | 6 ++----
15
1 file changed, 21 insertions(+), 11 deletions(-)
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
16
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
19
--- a/target/arm/ptw.c
20
+++ b/hw/ssi/aspeed_smc.c
20
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
22
return false;
22
uint32_t el = regime_el(env, mmu_idx);
23
}
23
uint64_t descaddrmask;
24
24
bool aarch64 = arm_el_is_aa64(env, el);
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
25
- bool guarded = false;
26
+ uint64_t regval)
26
uint64_t descriptor;
27
+{
27
bool nstable;
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
28
29
+ AspeedSegments seg;
29
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
+
30
descaddr &= ~(hwaddr)(page_size - 1);
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
31
descaddr |= (address & (page_size - 1));
32
+
32
/* Extract attributes from the descriptor */
33
+ memory_region_transaction_begin();
33
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12));
34
+ memory_region_set_size(&fl->mmio, seg.size);
34
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
35
36
+ memory_region_set_enabled(&fl->mmio, true);
36
if (regime_is_stage2(mmu_idx)) {
37
+ memory_region_transaction_commit();
37
/* Stage 2 table descriptors do not include any attribute fields */
38
+
38
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
40
+}
41
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
43
uint64_t new)
44
{
45
- AspeedSMCFlash *fl = &s->flashes[cs];
46
AspeedSegments seg;
47
48
s->ctrl->reg_to_segment(s, new, &seg);
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
aspeed_smc_flash_overlap(s, &seg, cs);
51
52
/* All should be fine now to move the region */
53
- memory_region_transaction_begin();
54
- memory_region_set_size(&fl->mmio, seg.size);
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
56
- memory_region_set_enabled(&fl->mmio, true);
57
- memory_region_transaction_commit();
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
61
}
62
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
65
qemu_set_irq(s->cs_lines[i], true);
66
}
39
}
67
40
/* Merge in attributes from table descriptors */
68
- /* setup default segment register values for all */
41
attrs |= nstable << 5; /* NS */
69
+ /* setup the default segment register values and regions for all */
42
- guarded = extract64(descriptor, 50, 1); /* GP */
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
43
if (param.hpd) {
71
- s->regs[R_SEG_ADDR0 + i] =
44
/* HPD disables all the table attributes except NSTable. */
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
45
goto skip_attrs;
73
+ aspeed_smc_flash_set_segment_region(s, i,
46
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
47
48
/* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */
49
if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) {
50
- result->f.guarded = guarded;
51
+ result->f.guarded = extract64(attrs, 50, 1); /* GP */
75
}
52
}
76
53
77
/* HW strapping flash type for the AST2600 controllers */
54
if (regime_is_stage2(mmu_idx)) {
78
--
55
--
79
2.20.1
56
2.25.1
80
57
81
58
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
Replace some gotos with some nested if statements.
4
accesses to EL2, and it looks like this register is completely
5
ignored by QEMU.
6
4
7
To avoid adding extra .accessfn filters all over the place (which
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
would have a direct performance impact), let's add a new TB flag
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
7
Message-id: 20221024051851.3074715-12-richard.henderson@linaro.org
10
a context where this trap has a chance to apply, and only generate
11
the extra access check if the hypervisor is actively using this feature.
12
13
Tested with a hand-crafted KVM guest accessing CBAR.
14
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20191201122018.25808-5-maz@kernel.org
18
[PMM: use is_a64(); fix comment syntax]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
9
---
21
target/arm/cpu.h | 2 ++
10
target/arm/ptw.c | 34 ++++++++++++++++------------------
22
target/arm/translate.h | 2 ++
11
1 file changed, 16 insertions(+), 18 deletions(-)
23
target/arm/helper.c | 6 ++++++
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
12
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
15
--- a/target/arm/ptw.c
31
+++ b/target/arm/cpu.h
16
+++ b/target/arm/ptw.c
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
18
page_size = (1ULL << ((stride * (4 - level)) + 3));
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
19
descaddr &= ~(hwaddr)(page_size - 1);
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
20
descaddr |= (address & (page_size - 1));
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
21
- /* Extract attributes from the descriptor */
37
+
22
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
38
/* For M profile only, set if FPCCR.LSPACT is set */
23
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
24
- if (regime_is_stage2(mmu_idx)) {
40
/* For M profile only, set if we must create a new FP context */
25
- /* Stage 2 table descriptors do not include any attribute fields */
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
26
- goto skip_attrs;
42
index XXXXXXX..XXXXXXX 100644
27
- }
43
--- a/target/arm/translate.h
28
- /* Merge in attributes from table descriptors */
44
+++ b/target/arm/translate.h
29
- attrs |= nstable << 5; /* NS */
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
30
- if (param.hpd) {
46
bool pauth_active;
31
- /* HPD disables all the table attributes except NSTable. */
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
32
- goto skip_attrs;
48
bool bt;
33
- }
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
34
- attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
50
+ bool hstr_active;
51
/*
35
/*
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
36
- * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
53
* < 0, set by the current instruction.
37
- * means "force PL1 access only", which means forcing AP[1] to 0.
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
+ * Extract attributes from the descriptor, and apply table descriptors.
55
index XXXXXXX..XXXXXXX 100644
39
+ * Stage 2 table descriptors do not include any attribute fields.
56
--- a/target/arm/helper.c
40
+ * HPD disables all the table attributes except NSTable.
57
+++ b/target/arm/helper.c
41
*/
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
42
- attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
59
if (arm_el_is_aa64(env, 1)) {
43
- attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
44
- skip_attrs:
61
}
45
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
62
+
46
+ if (!regime_is_stage2(mmu_idx)) {
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
47
+ attrs |= nstable << 5; /* NS */
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
48
+ if (!param.hpd) {
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
49
+ attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
66
+ }
50
+ /*
67
+
51
+ * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
52
+ * means "force PL1 access only", which means forcing AP[1] to 0.
69
}
53
+ */
70
54
+ attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
55
+ attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/op_helper.c
74
+++ b/target/arm/op_helper.c
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
77
}
78
79
+ /*
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
82
+ */
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
85
+ uint32_t mask = 1 << ri->crn;
86
+
87
+ if (ri->type & ARM_CP_64BIT) {
88
+ mask = 1 << ri->crm;
89
+ }
90
+
91
+ /* T4 and T14 are RES0 */
92
+ mask &= ~((1 << 4) | (1 << 14));
93
+
94
+ if (env->cp15.hstr_el2 & mask) {
95
+ target_el = 2;
96
+ goto exept;
97
+ }
56
+ }
98
+ }
57
+ }
99
+
58
100
if (!ri->accessfn) {
59
/*
101
return;
60
* Here descaddr is the final physical address, and attributes
102
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
104
g_assert_not_reached();
105
}
106
107
+exept:
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
109
}
110
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
116
return 1;
117
}
118
119
- if (ri->accessfn ||
120
+ if (s->hstr_active || ri->accessfn ||
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
122
/* Emit code to perform further access permissions checks at
123
* runtime; this may result in an exception.
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
125
!arm_el_is_aa64(env, 3);
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
131
dc->condexec_mask = (condexec & 0xf) << 1;
132
--
61
--
133
2.20.1
62
2.25.1
134
63
135
64
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
3
Perform the atomic update for hardware management of the access flag.
4
mode. This is not required on other SoCs.
5
4
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
7
Message-id: 20221024051851.3074715-13-richard.henderson@linaro.org
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191119141211.25716-3-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
10
docs/system/arm/emulation.rst | 1 +
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
11
target/arm/cpu64.c | 1 +
15
2 files changed, 40 insertions(+)
12
target/arm/ptw.c | 176 +++++++++++++++++++++++++++++-----
13
3 files changed, 156 insertions(+), 22 deletions(-)
16
14
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
15
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
17
--- a/docs/system/arm/emulation.rst
20
+++ b/include/hw/i2c/aspeed_i2c.h
18
+++ b/docs/system/arm/emulation.rst
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
19
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
qemu_irq irq;
20
- FEAT_FlagM (Flag manipulation instructions v2)
23
21
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
24
uint32_t intr_status;
22
- FEAT_GTG (Guest translation granule size)
25
+ uint32_t ctrl_global;
23
+- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state)
26
MemoryRegion pool_iomem;
24
- FEAT_HCX (Support for the HCRX_EL2 register)
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
25
- FEAT_HPDS (Hierarchical permission disables)
28
26
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
30
uint64_t pool_size;
31
hwaddr pool_base;
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
33
+ bool check_sram;
34
+
35
} AspeedI2CClass;
36
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
39
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
29
--- a/target/arm/cpu64.c
41
+++ b/hw/i2c/aspeed_i2c.c
30
+++ b/target/arm/cpu64.c
42
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
32
cpu->isar.id_aa64mmfr0 = t;
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
33
45
Assignment */
34
t = cpu->isar.id_aa64mmfr1;
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
35
+ t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */
47
+#define I2C_CTRL_SRAM_EN BIT(0)
36
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
48
37
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
49
/* I2C Device (Bus) Register */
38
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
50
39
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/ptw.c
42
+++ b/target/arm/ptw.c
43
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
44
bool in_secure;
45
bool in_debug;
46
bool out_secure;
47
+ bool out_rw;
48
bool out_be;
49
+ hwaddr out_virt;
50
hwaddr out_phys;
51
void *out_host;
52
} S1Translate;
53
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
54
uint8_t pte_attrs;
55
bool pte_secure;
56
57
+ ptw->out_virt = addr;
58
+
59
if (unlikely(ptw->in_debug)) {
60
/*
61
* From gdbstub, do not use softmmu so that we don't modify the
62
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
63
pte_secure = is_secure;
64
}
65
ptw->out_host = NULL;
66
+ ptw->out_rw = false;
67
} else {
68
CPUTLBEntryFull *full;
69
int flags;
70
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
71
goto fail;
72
}
73
ptw->out_phys = full->phys_addr;
74
+ ptw->out_rw = full->prot & PROT_WRITE;
75
pte_attrs = full->pte_attrs;
76
pte_secure = full->attrs.secure;
52
}
77
}
78
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
79
ARMMMUFaultInfo *fi)
80
{
81
CPUState *cs = env_cpu(env);
82
+ void *host = ptw->out_host;
83
uint32_t data;
84
85
- if (likely(ptw->out_host)) {
86
+ if (likely(host)) {
87
/* Page tables are in RAM, and we have the host address. */
88
+ data = qatomic_read((uint32_t *)host);
89
if (ptw->out_be) {
90
- data = ldl_be_p(ptw->out_host);
91
+ data = be32_to_cpu(data);
92
} else {
93
- data = ldl_le_p(ptw->out_host);
94
+ data = le32_to_cpu(data);
95
}
96
} else {
97
/* Page tables are in MMIO. */
98
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
99
ARMMMUFaultInfo *fi)
100
{
101
CPUState *cs = env_cpu(env);
102
+ void *host = ptw->out_host;
103
uint64_t data;
104
105
- if (likely(ptw->out_host)) {
106
+ if (likely(host)) {
107
/* Page tables are in RAM, and we have the host address. */
108
+#ifdef CONFIG_ATOMIC64
109
+ data = qatomic_read__nocheck((uint64_t *)host);
110
if (ptw->out_be) {
111
- data = ldq_be_p(ptw->out_host);
112
+ data = be64_to_cpu(data);
113
} else {
114
- data = ldq_le_p(ptw->out_host);
115
+ data = le64_to_cpu(data);
116
}
117
+#else
118
+ if (ptw->out_be) {
119
+ data = ldq_be_p(host);
120
+ } else {
121
+ data = ldq_le_p(host);
122
+ }
123
+#endif
124
} else {
125
/* Page tables are in MMIO. */
126
MemTxAttrs attrs = { .secure = ptw->out_secure };
127
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
128
return data;
53
}
129
}
54
130
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
131
+static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
132
+ uint64_t new_val, S1Translate *ptw,
133
+ ARMMMUFaultInfo *fi)
56
+{
134
+{
57
+ AspeedI2CState *s = bus->controller;
135
+ uint64_t cur_val;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
136
+ void *host = ptw->out_host;
59
+
137
+
60
+ if (!aic->check_sram) {
138
+ if (unlikely(!host)) {
61
+ return true;
139
+ fi->type = ARMFault_UnsuppAtomicUpdate;
140
+ fi->s1ptw = true;
141
+ return 0;
62
+ }
142
+ }
63
+
143
+
64
+ /*
144
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
145
+ * Raising a stage2 Protection fault for an atomic update to a read-only
66
+ * DMA mode.
146
+ * page is delayed until it is certain that there is a change to make.
67
+ */
147
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
148
+ if (unlikely(!ptw->out_rw)) {
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
149
+ int flags;
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
150
+ void *discard;
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
151
+
72
+ return false;
152
+ env->tlb_fi = fi;
73
+ }
153
+ flags = probe_access_flags(env, ptw->out_virt, MMU_DATA_STORE,
74
+
154
+ arm_to_core_mmu_idx(ptw->in_ptw_idx),
75
+ return true;
155
+ true, &discard, 0);
156
+ env->tlb_fi = NULL;
157
+
158
+ if (unlikely(flags & TLB_INVALID_MASK)) {
159
+ assert(fi->type != ARMFault_None);
160
+ fi->s2addr = ptw->out_virt;
161
+ fi->stage2 = true;
162
+ fi->s1ptw = true;
163
+ fi->s1ns = !ptw->in_secure;
164
+ return 0;
165
+ }
166
+
167
+ /* In case CAS mismatches and we loop, remember writability. */
168
+ ptw->out_rw = true;
169
+ }
170
+
171
+#ifdef CONFIG_ATOMIC64
172
+ if (ptw->out_be) {
173
+ old_val = cpu_to_be64(old_val);
174
+ new_val = cpu_to_be64(new_val);
175
+ cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
176
+ cur_val = be64_to_cpu(cur_val);
177
+ } else {
178
+ old_val = cpu_to_le64(old_val);
179
+ new_val = cpu_to_le64(new_val);
180
+ cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
181
+ cur_val = le64_to_cpu(cur_val);
182
+ }
183
+#else
184
+ /*
185
+ * We can't support the full 64-bit atomic cmpxchg on the host.
186
+ * Because this is only used for FEAT_HAFDBS, which is only for AA64,
187
+ * we know that TCG_OVERSIZED_GUEST is set, which means that we are
188
+ * running in round-robin mode and could only race with dma i/o.
189
+ */
190
+#ifndef TCG_OVERSIZED_GUEST
191
+# error "Unexpected configuration"
192
+#endif
193
+ bool locked = qemu_mutex_iothread_locked();
194
+ if (!locked) {
195
+ qemu_mutex_lock_iothread();
196
+ }
197
+ if (ptw->out_be) {
198
+ cur_val = ldq_be_p(host);
199
+ if (cur_val == old_val) {
200
+ stq_be_p(host, new_val);
201
+ }
202
+ } else {
203
+ cur_val = ldq_le_p(host);
204
+ if (cur_val == old_val) {
205
+ stq_le_p(host, new_val);
206
+ }
207
+ }
208
+ if (!locked) {
209
+ qemu_mutex_unlock_iothread();
210
+ }
211
+#endif
212
+
213
+ return cur_val;
76
+}
214
+}
77
+
215
+
78
/*
216
static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
79
* The state machine needs some refinement. It is only used to track
217
uint32_t *table, uint32_t address)
80
* invalid STOP commands for the moment.
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
82
bus->cmd &= ~0xFFFF;
83
bus->cmd |= value & 0xFFFF;
84
85
+ if (!aspeed_i2c_check_sram(bus)) {
86
+ return;
87
+ }
88
+
89
if (bus->cmd & I2CD_M_START_CMD) {
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
91
I2CD_MSTARTR : I2CD_MSTART;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
93
switch (offset) {
94
case I2C_CTRL_STATUS:
95
return s->intr_status;
96
+ case I2C_CTRL_GLOBAL:
97
+ return s->ctrl_global;
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
100
__func__, offset);
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
103
uint64_t value, unsigned size)
104
{
218
{
105
+ AspeedI2CState *s = opaque;
219
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
106
+
220
uint32_t el = regime_el(env, mmu_idx);
107
switch (offset) {
221
uint64_t descaddrmask;
108
+ case I2C_CTRL_GLOBAL:
222
bool aarch64 = arm_el_is_aa64(env, el);
109
+ s->ctrl_global = value;
223
- uint64_t descriptor;
110
+ break;
224
+ uint64_t descriptor, new_descriptor;
111
case I2C_CTRL_STATUS:
225
bool nstable;
112
default:
226
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
227
/* TODO: This code does not support shareability levels. */
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
228
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
115
aic->pool_size = 0x100;
229
if (fi->type != ARMFault_None) {
116
aic->pool_base = 0x200;
230
goto do_fault;
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
231
}
118
+ aic->check_sram = true;
232
+ new_descriptor = descriptor;
119
}
233
120
234
+ restart_atomic_update:
121
static const TypeInfo aspeed_2500_i2c_info = {
235
if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
236
/* Invalid, or the Reserved level 3 encoding */
237
goto do_translation_fault;
238
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
239
* to give a correct page or table address, the address field
240
* in a block descriptor is smaller; so we need to explicitly
241
* clear the lower bits here before ORing in the low vaddr bits.
242
+ *
243
+ * Afterward, descaddr is the final physical address.
244
*/
245
page_size = (1ULL << ((stride * (4 - level)) + 3));
246
descaddr &= ~(hwaddr)(page_size - 1);
247
descaddr |= (address & (page_size - 1));
248
249
+ if (likely(!ptw->in_debug)) {
250
+ /*
251
+ * Access flag.
252
+ * If HA is enabled, prepare to update the descriptor below.
253
+ * Otherwise, pass the access fault on to software.
254
+ */
255
+ if (!(descriptor & (1 << 10))) {
256
+ if (param.ha) {
257
+ new_descriptor |= 1 << 10; /* AF */
258
+ } else {
259
+ fi->type = ARMFault_AccessFlag;
260
+ goto do_fault;
261
+ }
262
+ }
263
+ }
264
+
265
/*
266
- * Extract attributes from the descriptor, and apply table descriptors.
267
- * Stage 2 table descriptors do not include any attribute fields.
268
- * HPD disables all the table attributes except NSTable.
269
+ * Extract attributes from the (modified) descriptor, and apply
270
+ * table descriptors. Stage 2 table descriptors do not include
271
+ * any attribute fields. HPD disables all the table attributes
272
+ * except NSTable.
273
*/
274
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
275
+ attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
276
if (!regime_is_stage2(mmu_idx)) {
277
attrs |= nstable << 5; /* NS */
278
if (!param.hpd) {
279
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
280
}
281
}
282
283
- /*
284
- * Here descaddr is the final physical address, and attributes
285
- * are all in attrs.
286
- */
287
- if ((attrs & (1 << 10)) == 0) {
288
- /* Access flag */
289
- fi->type = ARMFault_AccessFlag;
290
- goto do_fault;
291
- }
292
-
293
ap = extract32(attrs, 6, 2);
294
-
295
if (regime_is_stage2(mmu_idx)) {
296
ns = mmu_idx == ARMMMUIdx_Stage2;
297
xn = extract64(attrs, 53, 2);
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
299
goto do_fault;
300
}
301
302
+ /* If FEAT_HAFDBS has made changes, update the PTE. */
303
+ if (new_descriptor != descriptor) {
304
+ new_descriptor = arm_casq_ptw(env, descriptor, new_descriptor, ptw, fi);
305
+ if (fi->type != ARMFault_None) {
306
+ goto do_fault;
307
+ }
308
+ /*
309
+ * I_YZSVV says that if the in-memory descriptor has changed,
310
+ * then we must use the information in that new value
311
+ * (which might include a different output address, different
312
+ * attributes, or generate a fault).
313
+ * Restart the handling of the descriptor value from scratch.
314
+ */
315
+ if (new_descriptor != descriptor) {
316
+ descriptor = new_descriptor;
317
+ goto restart_atomic_update;
318
+ }
319
+ }
320
+
321
if (ns) {
322
/*
323
* The NS bit will (as required by the architecture) have no effect if
122
--
324
--
123
2.20.1
325
2.25.1
124
125
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
3
Perform the atomic update for hardware management of the dirty bit.
4
NIC in the machine.
5
4
6
Change the "nic" property definition so that it explicitly sets the
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
pointer. The property isn't optional : not being able to set the link
6
Message-id: 20221024051851.3074715-14-richard.henderson@linaro.org
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-18-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
hw/arm/aspeed_ast2600.c | 5 ++---
9
target/arm/cpu64.c | 2 +-
18
hw/net/ftgmac100.c | 19 +++++++++----------
10
target/arm/ptw.c | 16 ++++++++++++++++
19
2 files changed, 11 insertions(+), 13 deletions(-)
11
2 files changed, 17 insertions(+), 1 deletion(-)
20
12
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
15
--- a/target/arm/cpu64.c
24
+++ b/hw/arm/aspeed_ast2600.c
16
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
18
cpu->isar.id_aa64mmfr0 = t;
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
19
28
TYPE_ASPEED_MII);
20
t = cpu->isar.id_aa64mmfr1;
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
21
- t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */
30
- OBJECT(&s->ftgmac100[i]),
22
+ t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
31
- &error_abort);
23
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
24
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
25
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/ptw.c
29
+++ b/target/arm/ptw.c
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
31
goto do_fault;
32
}
33
}
34
+
35
+ /*
36
+ * Dirty Bit.
37
+ * If HD is enabled, pre-emptively set/clear the appropriate AP/S2AP
38
+ * bit for writeback. The actual write protection test may still be
39
+ * overridden by tableattrs, to be merged below.
40
+ */
41
+ if (param.hd
42
+ && extract64(descriptor, 51, 1) /* DBM */
43
+ && access_type == MMU_DATA_STORE) {
44
+ if (regime_is_stage2(mmu_idx)) {
45
+ new_descriptor |= 1ull << 7; /* set S2AP[1] */
46
+ } else {
47
+ new_descriptor &= ~(1ull << 7); /* clear AP[2] */
48
+ }
49
+ }
32
}
50
}
33
51
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
52
/*
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
38
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
40
+ "nic", &error_abort);
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
42
&err);
43
if (err) {
44
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/ftgmac100.c
47
+++ b/hw/net/ftgmac100.c
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp)
49
{
50
AspeedMiiState *s = ASPEED_MII(dev);
51
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52
- Object *obj;
53
- Error *local_err = NULL;
54
55
- obj = object_property_get_link(OBJECT(dev), "nic", &local_err);
56
- if (!obj) {
57
- error_propagate(errp, local_err);
58
- error_prepend(errp, "required link 'nic' not found: ");
59
- return;
60
- }
61
-
62
- s->nic = FTGMAC100(obj);
63
+ assert(s->nic);
64
65
memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s,
66
TYPE_ASPEED_MII, 0x8);
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_mii = {
68
VMSTATE_END_OF_LIST()
69
}
70
};
71
+
72
+static Property aspeed_mii_properties[] = {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
74
+ FTGMAC100State *),
75
+ DEFINE_PROP_END_OF_LIST(),
76
+};
77
+
78
static void aspeed_mii_class_init(ObjectClass *klass, void *data)
79
{
80
DeviceClass *dc = DEVICE_CLASS(klass);
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data)
82
dc->reset = aspeed_mii_reset;
83
dc->realize = aspeed_mii_realize;
84
dc->desc = "Aspeed MII controller";
85
+ dc->props = aspeed_mii_properties;
86
}
87
88
static const TypeInfo aspeed_mii_info = {
89
--
53
--
90
2.20.1
54
2.25.1
91
92
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
We had only been reporting the stage2 page size. This causes
4
transfers to and from DRAM.
4
problems if stage1 is using a larger page size (16k, 2M, etc),
5
but stage2 is using a smaller page size, because cputlb does
6
not set large_page_{addr,mask} properly.
5
7
6
A pair of registers defines the buffer address and the length of the
8
Fix by using the max of the two page sizes.
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
8
length should not exceed 4K. The receive or transmit DMA transfer can
9
then be initiated with specific bits in the Command/Status register of
10
the controller.
11
9
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Reported-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Message-id: 20221024051851.3074715-15-richard.henderson@linaro.org
16
Message-id: 20191119141211.25716-5-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
15
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
16
target/arm/ptw.c | 11 ++++++++++-
20
hw/arm/aspeed_ast2600.c | 5 ++
17
1 file changed, 10 insertions(+), 1 deletion(-)
21
hw/arm/aspeed_soc.c | 5 ++
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
23
4 files changed, 138 insertions(+), 3 deletions(-)
24
18
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
21
--- a/target/arm/ptw.c
28
+++ b/include/hw/i2c/aspeed_i2c.h
22
+++ b/target/arm/ptw.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
30
uint32_t cmd;
24
ARMMMUFaultInfo *fi)
31
uint32_t buf;
25
{
32
uint32_t pool_ctrl;
26
hwaddr ipa;
33
+ uint32_t dma_addr;
27
- int s1_prot;
34
+ uint32_t dma_len;
28
+ int s1_prot, s1_lgpgsz;
35
} AspeedI2CBus;
29
bool is_secure = ptw->in_secure;
36
30
bool ret, ipa_secure, s2walk_secure;
37
typedef struct AspeedI2CState {
31
ARMCacheAttrs cacheattrs1;
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
32
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
33
* Save the stage1 results so that we may merge prot and cacheattrs later.
40
34
*/
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
35
s1_prot = result->f.prot;
42
+ MemoryRegion *dram_mr;
36
+ s1_lgpgsz = result->f.lg_page_size;
43
+ AddressSpace dram_as;
37
cacheattrs1 = result->cacheattrs;
44
} AspeedI2CState;
38
memset(result, 0, sizeof(*result));
45
39
46
#define ASPEED_I2C_CLASS(klass) \
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
41
return ret;
48
hwaddr pool_base;
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
50
bool check_sram;
51
+ bool has_dma;
52
53
} AspeedI2CClass;
54
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
58
+++ b/hw/arm/aspeed_ast2600.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
60
}
42
}
61
43
62
/* I2C */
44
+ /*
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
45
+ * Use the maximum of the S1 & S2 page size, so that invalidation
64
+ if (err) {
46
+ * of pages > TARGET_PAGE_SIZE works correctly.
65
+ error_propagate(errp, err);
47
+ */
66
+ return;
48
+ if (result->f.lg_page_size < s1_lgpgsz) {
67
+ }
49
+ result->f.lg_page_size = s1_lgpgsz;
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
69
if (err) {
70
error_propagate(errp, err);
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/arm/aspeed_soc.c
74
+++ b/hw/arm/aspeed_soc.c
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
76
}
77
78
/* I2C */
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
85
if (err) {
86
error_propagate(errp, err);
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/i2c/aspeed_i2c.c
90
+++ b/hw/i2c/aspeed_i2c.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "migration/vmstate.h"
93
#include "qemu/log.h"
94
#include "qemu/module.h"
95
+#include "qemu/error-report.h"
96
+#include "qapi/error.h"
97
#include "hw/i2c/aspeed_i2c.h"
98
#include "hw/irq.h"
99
+#include "hw/qdev-properties.h"
100
101
/* I2C Global Register */
102
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_BYTE_BUF_TX_MASK 0xff
105
#define I2CD_BYTE_BUF_RX_SHIFT 8
106
#define I2CD_BYTE_BUF_RX_MASK 0xff
107
-
108
+#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */
109
+#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */
110
111
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
112
{
113
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
114
unsigned size)
115
{
116
AspeedI2CBus *bus = opaque;
117
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
118
119
switch (offset) {
120
case I2CD_FUN_CTRL_REG:
121
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
122
return bus->buf;
123
case I2CD_CMD_REG:
124
return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
125
+ case I2CD_DMA_ADDR:
126
+ if (!aic->has_dma) {
127
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
+ return -1;
129
+ }
130
+ return bus->dma_addr;
131
+ case I2CD_DMA_LEN:
132
+ if (!aic->has_dma) {
133
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
134
+ return -1;
135
+ }
136
+ return bus->dma_len;
137
default:
138
qemu_log_mask(LOG_GUEST_ERROR,
139
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
140
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
141
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
142
}
143
144
+static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
145
+{
146
+ MemTxResult result;
147
+ AspeedI2CState *s = bus->controller;
148
+
149
+ result = address_space_read(&s->dram_as, bus->dma_addr,
150
+ MEMTXATTRS_UNSPECIFIED, data, 1);
151
+ if (result != MEMTX_OK) {
152
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
153
+ __func__, bus->dma_addr);
154
+ return -1;
155
+ }
50
+ }
156
+
51
+
157
+ bus->dma_addr++;
52
/* Combine the S1 and S2 cache attributes. */
158
+ bus->dma_len--;
53
hcr = arm_hcr_el2_eff_secstate(env, is_secure);
159
+ return 0;
54
if (hcr & HCR_DC) {
160
+}
161
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
163
{
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
166
}
167
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
170
+ while (bus->dma_len) {
171
+ uint8_t data;
172
+ aspeed_i2c_dma_read(bus, &data);
173
+ ret = i2c_send(bus->bus, data);
174
+ if (ret) {
175
+ break;
176
+ }
177
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
179
} else {
180
ret = i2c_send(bus->bus, bus->buf);
181
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
183
bus->pool_ctrl &= ~(0xff << 24);
184
bus->pool_ctrl |= (i & 0xff) << 24;
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
187
+ uint8_t data;
188
+
189
+ while (bus->dma_len) {
190
+ MemTxResult result;
191
+
192
+ data = i2c_recv(bus->bus);
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
195
+ if (result != MEMTX_OK) {
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
197
+ __func__, bus->dma_addr);
198
+ return;
199
+ }
200
+ bus->dma_addr++;
201
+ bus->dma_len--;
202
+ }
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
204
} else {
205
data = i2c_recv(bus->bus);
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
208
uint8_t *pool_base = aic->bus_pool_base(bus);
209
210
return pool_base[0];
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
212
+ uint8_t data;
213
+
214
+ aspeed_i2c_dma_read(bus, &data);
215
+ return data;
216
} else {
217
return bus->buf;
218
}
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
220
*/
221
pool_start++;
222
}
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
224
+ if (bus->dma_len == 0) {
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
226
+ }
227
} else {
228
bus->cmd &= ~I2CD_M_TX_CMD;
229
}
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
231
break;
232
}
233
234
+ if (!aic->has_dma &&
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
237
+ break;
238
+ }
239
+
240
aspeed_i2c_bus_handle_cmd(bus, value);
241
aspeed_i2c_bus_raise_interrupt(bus);
242
break;
243
+ case I2CD_DMA_ADDR:
244
+ if (!aic->has_dma) {
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
246
+ break;
247
+ }
248
+
249
+ bus->dma_addr = value & 0xfffffffc;
250
+ break;
251
+
252
+ case I2CD_DMA_LEN:
253
+ if (!aic->has_dma) {
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
255
+ break;
256
+ }
257
+
258
+ bus->dma_len = value & 0xfff;
259
+ if (!bus->dma_len) {
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
261
+ }
262
+ break;
263
264
default:
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
267
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
269
.name = TYPE_ASPEED_I2C,
270
- .version_id = 2,
271
- .minimum_version_id = 2,
272
+ .version_id = 3,
273
+ .minimum_version_id = 3,
274
.fields = (VMStateField[]) {
275
VMSTATE_UINT8(id, AspeedI2CBus),
276
VMSTATE_UINT32(ctrl, AspeedI2CBus),
277
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
278
VMSTATE_UINT32(cmd, AspeedI2CBus),
279
VMSTATE_UINT32(buf, AspeedI2CBus),
280
VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
281
+ VMSTATE_UINT32(dma_addr, AspeedI2CBus),
282
+ VMSTATE_UINT32(dma_len, AspeedI2CBus),
283
VMSTATE_END_OF_LIST()
284
}
285
};
286
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_reset(DeviceState *dev)
287
s->busses[i].intr_status = 0;
288
s->busses[i].cmd = 0;
289
s->busses[i].buf = 0;
290
+ s->busses[i].dma_addr = 0;
291
+ s->busses[i].dma_len = 0;
292
i2c_end_transfer(s->busses[i].bus);
293
}
294
}
295
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
296
memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
297
"aspeed.i2c-pool", aic->pool_size);
298
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
299
+
300
+ if (aic->has_dma) {
301
+ if (!s->dram_mr) {
302
+ error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set");
303
+ return;
304
+ }
305
+
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
307
+ }
308
}
309
310
+static Property aspeed_i2c_properties[] = {
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
313
+ DEFINE_PROP_END_OF_LIST(),
314
+};
315
+
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
317
{
318
DeviceClass *dc = DEVICE_CLASS(klass);
319
320
dc->vmsd = &aspeed_i2c_vmstate;
321
dc->reset = aspeed_i2c_reset;
322
+ dc->props = aspeed_i2c_properties;
323
dc->realize = aspeed_i2c_realize;
324
dc->desc = "Aspeed I2C Controller";
325
}
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
327
aic->pool_base = 0x200;
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
329
aic->check_sram = true;
330
+ aic->has_dma = true;
331
}
332
333
static const TypeInfo aspeed_2500_i2c_info = {
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
335
aic->pool_size = 0x200;
336
aic->pool_base = 0xC00;
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
338
+ aic->has_dma = true;
339
}
340
341
static const TypeInfo aspeed_2600_i2c_info = {
342
--
55
--
343
2.20.1
56
2.25.1
344
345
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
3
Snapshot loading only expects to call deterministic handlers, not
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
4
non-deterministic ones. So introduce a way of registering handlers that
5
I2C layout is the same as it controls the same main board. Used for HW
5
won't be called when reseting for snapshots.
6
bringup.
7
6
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20221025004327.568476-2-Jason@zx2c4.com
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
[PMM: updated json doc comment with Markus' text; fixed
11
Message-id: 20191119141211.25716-15-clg@kaod.org
10
checkpatch style nit]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
14
qapi/run-state.json | 6 +++++-
15
1 file changed, 28 insertions(+)
15
include/hw/boards.h | 2 +-
16
include/sysemu/reset.h | 5 ++++-
17
hw/arm/aspeed.c | 4 ++--
18
hw/arm/mps2-tz.c | 4 ++--
19
hw/core/reset.c | 17 ++++++++++++++++-
20
hw/hppa/machine.c | 4 ++--
21
hw/i386/microvm.c | 4 ++--
22
hw/i386/pc.c | 6 +++---
23
hw/ppc/pegasos2.c | 4 ++--
24
hw/ppc/pnv.c | 4 ++--
25
hw/ppc/spapr.c | 4 ++--
26
hw/s390x/s390-virtio-ccw.c | 4 ++--
27
migration/savevm.c | 2 +-
28
softmmu/runstate.c | 11 ++++++++---
29
15 files changed, 54 insertions(+), 27 deletions(-)
16
30
31
diff --git a/qapi/run-state.json b/qapi/run-state.json
32
index XXXXXXX..XXXXXXX 100644
33
--- a/qapi/run-state.json
34
+++ b/qapi/run-state.json
35
@@ -XXX,XX +XXX,XX @@
36
# ignores --no-reboot. This is useful for sanitizing
37
# hypercalls on s390 that are used during kexec/kdump/boot
38
#
39
+# @snapshot-load: A snapshot is being loaded by the record & replay
40
+# subsystem. This value is used only within QEMU. It
41
+# doesn't occur in QMP. (since 7.2)
42
+#
43
##
44
{ 'enum': 'ShutdownCause',
45
# Beware, shutdown_caused_by_guest() depends on enumeration order
46
'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset',
47
'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset',
48
- 'guest-panic', 'subsystem-reset'] }
49
+ 'guest-panic', 'subsystem-reset', 'snapshot-load'] }
50
51
##
52
# @StatusInfo:
53
diff --git a/include/hw/boards.h b/include/hw/boards.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/hw/boards.h
56
+++ b/include/hw/boards.h
57
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
58
const char *deprecation_reason;
59
60
void (*init)(MachineState *state);
61
- void (*reset)(MachineState *state);
62
+ void (*reset)(MachineState *state, ShutdownCause reason);
63
void (*wakeup)(MachineState *state);
64
int (*kvm_type)(MachineState *machine, const char *arg);
65
66
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/sysemu/reset.h
69
+++ b/include/sysemu/reset.h
70
@@ -XXX,XX +XXX,XX @@
71
#ifndef QEMU_SYSEMU_RESET_H
72
#define QEMU_SYSEMU_RESET_H
73
74
+#include "qapi/qapi-events-run-state.h"
75
+
76
typedef void QEMUResetHandler(void *opaque);
77
78
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
79
+void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
80
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
81
-void qemu_devices_reset(void);
82
+void qemu_devices_reset(ShutdownCause reason);
83
84
#endif
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
85
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
18
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
87
--- a/hw/arm/aspeed.c
20
+++ b/hw/arm/aspeed.c
88
+++ b/hw/arm/aspeed.c
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
89
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
90
aspeed_soc_num_cpus(amc->soc_name);
23
#define AST2600_EVB_HW_STRAP2 0x00000003
91
}
24
92
25
+/* Tacoma hardware value */
93
-static void fby35_reset(MachineState *state)
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
94
+static void fby35_reset(MachineState *state, ShutdownCause reason)
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
95
{
96
AspeedMachineState *bmc = ASPEED_MACHINE(state);
97
AspeedGPIOState *gpio = &bmc->soc.gpio;
98
99
- qemu_devices_reset();
100
+ qemu_devices_reset(reason);
101
102
/* Board ID: 7 (Class-1, 4 slots) */
103
object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
104
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/mps2-tz.c
107
+++ b/hw/arm/mps2-tz.c
108
@@ -XXX,XX +XXX,XX @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp)
109
}
110
}
111
112
-static void mps2_machine_reset(MachineState *machine)
113
+static void mps2_machine_reset(MachineState *machine, ShutdownCause reason)
114
{
115
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
116
117
@@ -XXX,XX +XXX,XX @@ static void mps2_machine_reset(MachineState *machine)
118
* reset see the correct mapping.
119
*/
120
remap_memory(mms, mms->remap);
121
- qemu_devices_reset();
122
+ qemu_devices_reset(reason);
123
}
124
125
static void mps2tz_class_init(ObjectClass *oc, void *data)
126
diff --git a/hw/core/reset.c b/hw/core/reset.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/core/reset.c
129
+++ b/hw/core/reset.c
130
@@ -XXX,XX +XXX,XX @@ typedef struct QEMUResetEntry {
131
QTAILQ_ENTRY(QEMUResetEntry) entry;
132
QEMUResetHandler *func;
133
void *opaque;
134
+ bool skip_on_snapshot_load;
135
} QEMUResetEntry;
136
137
static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
138
@@ -XXX,XX +XXX,XX @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
139
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
140
}
141
142
+void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
143
+{
144
+ QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
28
+
145
+
29
/*
146
+ re->func = func;
30
* The max ram region is for firmwares that scan the address space
147
+ re->opaque = opaque;
31
* with load/store to guess how much RAM the SoC has.
148
+ re->skip_on_snapshot_load = true;
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
149
+ QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
33
AspeedSoCState *soc = &bmc->soc;
150
+}
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
35
36
+ /* Bus 3: TODO bmp280@77 */
37
+ /* Bus 3: TODO max31785@52 */
38
+ /* Bus 3: TODO dps310@76 */
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
40
0x60);
41
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
43
eeprom_buf);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
45
0x60);
46
+ /* Bus 11: TODO ucd90160@64 */
47
}
48
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
50
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
51
mc->default_ram_size = 1 * GiB;
52
};
53
54
+static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
55
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
58
+
151
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
152
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
60
+ amc->soc_name = "ast2600-a0";
153
{
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
154
QEMUResetEntry *re;
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
155
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
63
+ amc->fmc_model = "mx66l1g45g";
156
}
64
+ amc->spi_model = "mx66l1g45g";
157
}
65
+ amc->num_cs = 2;
158
66
+ amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
159
-void qemu_devices_reset(void)
67
+ mc->default_ram_size = 1 * GiB;
160
+void qemu_devices_reset(ShutdownCause reason)
68
+};
161
{
69
+
162
QEMUResetEntry *re, *nre;
70
static const TypeInfo aspeed_machine_types[] = {
163
71
{
164
/* reset all devices */
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
165
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
166
+ if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
167
+ re->skip_on_snapshot_load) {
75
.parent = TYPE_ASPEED_MACHINE,
168
+ continue;
76
.class_init = aspeed_machine_ast2600_evb_class_init,
169
+ }
77
+ }, {
170
re->func(re->opaque);
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
171
}
79
+ .parent = TYPE_ASPEED_MACHINE,
172
}
80
+ .class_init = aspeed_machine_tacoma_class_init,
173
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
81
}, {
174
index XXXXXXX..XXXXXXX 100644
82
.name = TYPE_ASPEED_MACHINE,
175
--- a/hw/hppa/machine.c
83
.parent = TYPE_MACHINE,
176
+++ b/hw/hppa/machine.c
177
@@ -XXX,XX +XXX,XX @@ static void machine_hppa_init(MachineState *machine)
178
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
179
}
180
181
-static void hppa_machine_reset(MachineState *ms)
182
+static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
183
{
184
unsigned int smp_cpus = ms->smp.cpus;
185
int i;
186
187
- qemu_devices_reset();
188
+ qemu_devices_reset(reason);
189
190
/* Start all CPUs at the firmware entry point.
191
* Monarch CPU will initialize firmware, secondary CPUs
192
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/i386/microvm.c
195
+++ b/hw/i386/microvm.c
196
@@ -XXX,XX +XXX,XX @@ static void microvm_machine_state_init(MachineState *machine)
197
microvm_devices_init(mms);
198
}
199
200
-static void microvm_machine_reset(MachineState *machine)
201
+static void microvm_machine_reset(MachineState *machine, ShutdownCause reason)
202
{
203
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
204
CPUState *cs;
205
@@ -XXX,XX +XXX,XX @@ static void microvm_machine_reset(MachineState *machine)
206
mms->kernel_cmdline_fixed = true;
207
}
208
209
- qemu_devices_reset();
210
+ qemu_devices_reset(reason);
211
212
CPU_FOREACH(cs) {
213
cpu = X86_CPU(cs);
214
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/i386/pc.c
217
+++ b/hw/i386/pc.c
218
@@ -XXX,XX +XXX,XX @@ static void pc_machine_initfn(Object *obj)
219
cxl_machine_init(obj, &pcms->cxl_devices_state);
220
}
221
222
-static void pc_machine_reset(MachineState *machine)
223
+static void pc_machine_reset(MachineState *machine, ShutdownCause reason)
224
{
225
CPUState *cs;
226
X86CPU *cpu;
227
228
- qemu_devices_reset();
229
+ qemu_devices_reset(reason);
230
231
/* Reset APIC after devices have been reset to cancel
232
* any changes that qemu_devices_reset() might have done.
233
@@ -XXX,XX +XXX,XX @@ static void pc_machine_reset(MachineState *machine)
234
static void pc_machine_wakeup(MachineState *machine)
235
{
236
cpu_synchronize_all_states();
237
- pc_machine_reset(machine);
238
+ pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE);
239
cpu_synchronize_all_post_reset();
240
}
241
242
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/ppc/pegasos2.c
245
+++ b/hw/ppc/pegasos2.c
246
@@ -XXX,XX +XXX,XX @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
247
pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
248
}
249
250
-static void pegasos2_machine_reset(MachineState *machine)
251
+static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
252
{
253
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
254
void *fdt;
255
uint64_t d[2];
256
int sz;
257
258
- qemu_devices_reset();
259
+ qemu_devices_reset(reason);
260
if (!pm->vof) {
261
return; /* Firmware should set up machine so nothing to do */
262
}
263
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/ppc/pnv.c
266
+++ b/hw/ppc/pnv.c
267
@@ -XXX,XX +XXX,XX @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
268
}
269
}
270
271
-static void pnv_reset(MachineState *machine)
272
+static void pnv_reset(MachineState *machine, ShutdownCause reason)
273
{
274
PnvMachineState *pnv = PNV_MACHINE(machine);
275
IPMIBmc *bmc;
276
void *fdt;
277
278
- qemu_devices_reset();
279
+ qemu_devices_reset(reason);
280
281
/*
282
* The machine should provide by default an internal BMC simulator.
283
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/ppc/spapr.c
286
+++ b/hw/ppc/spapr.c
287
@@ -XXX,XX +XXX,XX @@ void spapr_check_mmu_mode(bool guest_radix)
288
}
289
}
290
291
-static void spapr_machine_reset(MachineState *machine)
292
+static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
293
{
294
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
295
PowerPCCPU *first_ppc_cpu;
296
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_reset(MachineState *machine)
297
spapr_setup_hpt(spapr);
298
}
299
300
- qemu_devices_reset();
301
+ qemu_devices_reset(reason);
302
303
spapr_ovec_cleanup(spapr->ov5_cas);
304
spapr->ov5_cas = spapr_ovec_new();
305
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
306
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/s390x/s390-virtio-ccw.c
308
+++ b/hw/s390x/s390-virtio-ccw.c
309
@@ -XXX,XX +XXX,XX @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
310
s390_pv_prep_reset();
311
}
312
313
-static void s390_machine_reset(MachineState *machine)
314
+static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
315
{
316
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
317
enum s390_reset reset_type;
318
@@ -XXX,XX +XXX,XX @@ static void s390_machine_reset(MachineState *machine)
319
s390_machine_unprotect(ms);
320
}
321
322
- qemu_devices_reset();
323
+ qemu_devices_reset(reason);
324
s390_crypto_reset();
325
326
/* configure and start the ipl CPU only */
327
diff --git a/migration/savevm.c b/migration/savevm.c
328
index XXXXXXX..XXXXXXX 100644
329
--- a/migration/savevm.c
330
+++ b/migration/savevm.c
331
@@ -XXX,XX +XXX,XX @@ bool load_snapshot(const char *name, const char *vmstate,
332
goto err_drain;
333
}
334
335
- qemu_system_reset(SHUTDOWN_CAUSE_NONE);
336
+ qemu_system_reset(SHUTDOWN_CAUSE_SNAPSHOT_LOAD);
337
mis->from_src_file = f;
338
339
if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
340
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
341
index XXXXXXX..XXXXXXX 100644
342
--- a/softmmu/runstate.c
343
+++ b/softmmu/runstate.c
344
@@ -XXX,XX +XXX,XX @@ void qemu_system_reset(ShutdownCause reason)
345
cpu_synchronize_all_states();
346
347
if (mc && mc->reset) {
348
- mc->reset(current_machine);
349
+ mc->reset(current_machine, reason);
350
} else {
351
- qemu_devices_reset();
352
+ qemu_devices_reset(reason);
353
}
354
- if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
355
+ switch (reason) {
356
+ case SHUTDOWN_CAUSE_NONE:
357
+ case SHUTDOWN_CAUSE_SUBSYSTEM_RESET:
358
+ case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
359
+ break;
360
+ default:
361
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
362
}
363
cpu_synchronize_all_post_reset();
84
--
364
--
85
2.20.1
365
2.25.1
86
87
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Add an option to trigger memory writeback to sync given memory region
3
When the system reboots, the rng-seed that the FDT has should be
4
with the corresponding backing store, case one is available.
4
re-randomized, so that the new boot gets a new seed. Several
5
This extends the support for persistent memory, allowing syncing on-demand.
5
architectures require this functionality, so export a function for
6
injecting a new seed into the given FDT.
6
7
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
8
Cc: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Cc: David Gibson <david@gibson.dropbear.id.au>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20221025004327.568476-3-Jason@zx2c4.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
include/exec/memory.h | 6 ++++++
15
include/sysemu/device_tree.h | 9 +++++++++
13
include/exec/ram_addr.h | 8 ++++++++
16
softmmu/device_tree.c | 21 +++++++++++++++++++++
14
include/qemu/cutils.h | 1 +
17
2 files changed, 30 insertions(+)
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
16
memory.c | 12 ++++++++++++
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
18
6 files changed, 101 insertions(+)
19
18
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
19
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
21
--- a/include/sysemu/device_tree.h
23
+++ b/include/exec/memory.h
22
+++ b/include/sysemu/device_tree.h
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
23
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
25
*/
24
qdt_tmp); \
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
25
})
27
Error **errp);
26
27
+
28
+/**
28
+/**
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
29
+ * qemu_fdt_randomize_seeds:
30
+ * [addr, addr + size]
30
+ * @fdt: device tree blob
31
+ *
31
+ *
32
+ * Re-randomize all "rng-seed" properties with new seeds.
32
+ */
33
+ */
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
34
+void qemu_fdt_randomize_seeds(void *fdt);
34
35
+
35
/**
36
#define FDT_PCI_RANGE_RELOCATABLE 0x80000000
36
* memory_region_set_log: Turn dirty logging on or off for a region.
37
#define FDT_PCI_RANGE_PREFETCHABLE 0x40000000
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
38
#define FDT_PCI_RANGE_ALIASED 0x20000000
39
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
38
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
41
--- a/softmmu/device_tree.c
40
+++ b/include/exec/ram_addr.h
42
+++ b/softmmu/device_tree.c
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
43
@@ -XXX,XX +XXX,XX @@
42
44
#include "qemu/option.h"
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
45
#include "qemu/bswap.h"
44
46
#include "qemu/cutils.h"
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
47
+#include "qemu/guest-random.h"
48
#include "sysemu/device_tree.h"
49
#include "hw/loader.h"
50
#include "hw/boards.h"
51
@@ -XXX,XX +XXX,XX @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
52
53
info_report("dtb dumped to %s", filename);
54
}
46
+
55
+
47
+/* Clear whole block of mem */
56
+void qemu_fdt_randomize_seeds(void *fdt)
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
49
+{
57
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
58
+ int noffset, poffset, len;
51
+}
59
+ const char *name;
60
+ uint8_t *data;
52
+
61
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
62
+ for (noffset = fdt_next_node(fdt, 0, NULL);
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
63
+ noffset >= 0;
55
64
+ noffset = fdt_next_node(fdt, noffset, NULL)) {
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
65
+ for (poffset = fdt_first_property_offset(fdt, noffset);
57
index XXXXXXX..XXXXXXX 100644
66
+ poffset >= 0;
58
--- a/include/qemu/cutils.h
67
+ poffset = fdt_next_property_offset(fdt, poffset)) {
59
+++ b/include/qemu/cutils.h
68
+ data = (uint8_t *)fdt_getprop_by_offset(fdt, poffset, &name, &len);
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
69
+ if (!data || strcmp(name, "rng-seed"))
61
#endif
70
+ continue;
62
time_t mktimegm(struct tm *tm);
71
+ qemu_guest_getrandom_nofail(data, len);
63
int qemu_fdatasync(int fd);
64
+int qemu_msync(void *addr, size_t length, int fd);
65
int fcntl_setfl(int fd, int flag);
66
int qemu_parse_fd(const char *param);
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
68
diff --git a/exec.c b/exec.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/exec.c
71
+++ b/exec.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "exec/ram_addr.h"
74
#include "exec/log.h"
75
76
+#include "qemu/pmem.h"
77
+
78
#include "migration/vmstate.h"
79
80
#include "qemu/range.h"
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
82
return 0;
83
}
84
85
+/*
86
+ * Trigger sync on the given ram block for range [start, start + length]
87
+ * with the backing store if one is available.
88
+ * Otherwise no-op.
89
+ * @Note: this is supposed to be a synchronous op.
90
+ */
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
92
+{
93
+ void *addr = ramblock_ptr(block, start);
94
+
95
+ /* The requested range should fit in within the block range */
96
+ g_assert((start + length) <= block->used_length);
97
+
98
+#ifdef CONFIG_LIBPMEM
99
+ /* The lack of support for pmem should not block the sync */
100
+ if (ramblock_is_pmem(block)) {
101
+ pmem_persist(addr, length);
102
+ return;
103
+ }
104
+#endif
105
+ if (block->fd >= 0) {
106
+ /**
107
+ * Case there is no support for PMEM or the memory has not been
108
+ * specified as persistent (or is not one) - use the msync.
109
+ * Less optimal but still achieves the same goal
110
+ */
111
+ if (qemu_msync(addr, length, block->fd)) {
112
+ warn_report("%s: failed to sync memory range: start: "
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
114
+ __func__, start, length);
115
+ }
72
+ }
116
+ }
73
+ }
117
+}
74
+}
118
+
119
/* Called with ram_list.mutex held */
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
121
ram_addr_t new_ram_size)
122
diff --git a/memory.c b/memory.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/memory.c
125
+++ b/memory.c
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
127
qemu_ram_resize(mr->ram_block, newsize, errp);
128
}
129
130
+
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
132
+{
133
+ /*
134
+ * Might be extended case needed to cover
135
+ * different types of memory regions
136
+ */
137
+ if (mr->ram_block && mr->dirty_log_mask) {
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
139
+ }
140
+}
141
+
142
/*
143
* Call proper memory listeners about the change on the newly
144
* added/removed CoalescedMemoryRange.
145
diff --git a/util/cutils.c b/util/cutils.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
148
+++ b/util/cutils.c
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
150
#endif
151
}
152
153
+/**
154
+ * Sync changes made to the memory mapped file back to the backing
155
+ * storage. For POSIX compliant systems this will fallback
156
+ * to regular msync call. Otherwise it will trigger whole file sync
157
+ * (including the metadata case there is no support to skip that otherwise)
158
+ *
159
+ * @addr - start of the memory area to be synced
160
+ * @length - length of the are to be synced
161
+ * @fd - file descriptor for the file to be synced
162
+ * (mandatory only for POSIX non-compliant systems)
163
+ */
164
+int qemu_msync(void *addr, size_t length, int fd)
165
+{
166
+#ifdef CONFIG_POSIX
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
168
+
169
+ /**
170
+ * There are no strict reqs as per the length of mapping
171
+ * to be synced. Still the length needs to follow the address
172
+ * alignment changes. Additionally - round the size to the multiple
173
+ * of PAGE_SIZE
174
+ */
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
176
+ length = (length + ~align_mask) & align_mask;
177
+
178
+ addr = (void *)((uintptr_t)addr & align_mask);
179
+
180
+ return msync(addr, length, MS_SYNC);
181
+#else /* CONFIG_POSIX */
182
+ /**
183
+ * Perform the sync based on the file descriptor
184
+ * The sync range will most probably be wider than the one
185
+ * requested - but it will still get the job done
186
+ */
187
+ return qemu_fdatasync(fd);
188
+#endif /* CONFIG_POSIX */
189
+}
190
+
191
#ifndef _WIN32
192
/* Sets a specific flag */
193
int fcntl_setfl(int fd, int flag)
194
--
75
--
195
2.20.1
76
2.25.1
196
197
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
The segments can be disabled on the AST2600 (zero register value).
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
CS0 is open by default but not the other CS. This is closing the
4
re-randomize the various seeds used.
5
access to the flash device in user mode and forbids scanning.
6
5
7
In the model, check the segment size and disable the associated region
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
8
when the value is zero.
7
Message-id: 20221025004327.568476-4-Jason@zx2c4.com
9
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
11
hw/i386/x86.c | 2 +-
18
1 file changed, 11 insertions(+), 5 deletions(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
19
13
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
14
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/ssi/aspeed_smc.c
16
--- a/hw/i386/x86.c
23
+++ b/hw/ssi/aspeed_smc.c
17
+++ b/hw/i386/x86.c
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
18
@@ -XXX,XX +XXX,XX @@ void x86_load_linux(X86MachineState *x86ms,
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
19
setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
20
setup_data->len = cpu_to_le32(RNG_SEED_LENGTH);
27
21
qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
22
- qemu_register_reset(reset_rng_seed, setup_data);
29
- seg->size = end_offset + MiB - start_offset;
23
+ qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data);
30
+ if (reg) {
24
fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL,
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
25
setup_data, kernel, kernel_size, true);
32
+ seg->size = end_offset + MiB - start_offset;
26
} else {
33
+ } else {
34
+ seg->addr = s->ctrl->flash_window_base;
35
+ seg->size = 0;
36
+ }
37
}
38
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
41
memory_region_transaction_begin();
42
memory_region_set_size(&fl->mmio, seg.size);
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
44
- memory_region_set_enabled(&fl->mmio, true);
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
46
memory_region_transaction_commit();
47
48
s->regs[R_SEG_ADDR0 + cs] = regval;
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
}
51
52
/* Keep the segment in the overall flash window */
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
55
+ if (seg.size &&
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
61
--
27
--
62
2.20.1
28
2.25.1
63
64
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
When the system reboots, the rng-seed that the FDT has should be
4
through a property alias at the SoC level. The I2C model will need a
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
similar region for DMA support, add a DRAM region property at the SoC
5
the ROM region at this point, we add a hook right after the ROM has been
6
level for both model to use.
6
added, so that we have a pointer to that copy of the FDT.
7
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
9
Cc: qemu-arm@nongnu.org
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20221025004327.568476-5-Jason@zx2c4.com
12
Message-id: 20191119141211.25716-4-clg@kaod.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
14
---
15
include/hw/arm/aspeed_soc.h | 1 +
15
hw/arm/boot.c | 2 ++
16
hw/arm/aspeed_ast2600.c | 7 +++++--
16
1 file changed, 2 insertions(+)
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
17
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
20
--- a/hw/arm/boot.c
23
+++ b/include/hw/arm/aspeed_soc.h
21
+++ b/hw/arm/boot.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
22
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
25
ARMCPU cpu[ASPEED_CPUS_NUM];
23
* the DTB is copied again upon reset, even if addr points into RAM.
26
uint32_t num_cpus;
24
*/
27
A15MPPrivState a7mpcore;
25
rom_add_blob_fixed_as("dtb", fdt, size, addr, as);
28
+ MemoryRegion *dram_mr;
26
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
29
MemoryRegion sram;
27
+ rom_ptr_for_as(as, addr, size));
30
AspeedVICState vic;
28
31
AspeedRtcState rtc;
29
g_free(fdt);
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/aspeed_ast2600.c
35
+++ b/hw/arm/aspeed_ast2600.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
typename);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
39
&error_abort);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
41
- &error_abort);
42
43
for (i = 0; i < sc->spis_num; i++) {
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
}
47
48
/* FMC, The number of CS is set at the board level */
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
50
+ if (err) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
55
"sdram-base", &err);
56
if (err) {
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/aspeed_soc.c
60
+++ b/hw/arm/aspeed_soc.c
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
62
typename);
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
64
&error_abort);
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
66
- &error_abort);
67
68
for (i = 0; i < sc->spis_num; i++) {
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
71
aspeed_soc_get_irq(s, ASPEED_I2C));
72
73
/* FMC, The number of CS is set at the board level */
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
80
"sdram-base", &err);
81
if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
83
}
84
static Property aspeed_soc_properties[] = {
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
87
+ MemoryRegion *),
88
DEFINE_PROP_END_OF_LIST(),
89
};
90
30
91
--
31
--
92
2.20.1
32
2.25.1
93
94
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
3
When the system reboots, the rng-seed that the FDT has should be
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
the ROM region at this point, we add a hook right after the ROM has been
6
added, so that we have a pointer to that copy of the FDT.
4
7
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Cc: Palmer Dabbelt <palmer@dabbelt.com>
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
9
Cc: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Cc: Bin Meng <bin.meng@windriver.com>
8
Message-id: 20191119141211.25716-13-clg@kaod.org
11
Cc: qemu-riscv@nongnu.org
12
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20221025004327.568476-6-Jason@zx2c4.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
include/hw/ssi/aspeed_smc.h | 1 +
17
hw/riscv/boot.c | 3 +++
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
18
1 file changed, 3 insertions(+)
13
2 files changed, 15 insertions(+), 3 deletions(-)
14
19
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
20
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
22
--- a/hw/riscv/boot.c
18
+++ b/include/hw/ssi/aspeed_smc.h
23
+++ b/hw/riscv/boot.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
20
uint8_t r_ce_ctrl;
21
uint8_t r_ctrl0;
22
uint8_t r_timings;
23
+ uint8_t nregs_timings;
24
uint8_t conf_enable_w0;
25
uint8_t max_slaves;
26
const AspeedSegments *segments;
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
30
+++ b/hw/ssi/aspeed_smc.c
31
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
32
/* Checksum Calculation Result */
25
#include "sysemu/device_tree.h"
33
#define R_DMA_CHECKSUM (0x90 / 4)
26
#include "sysemu/qtest.h"
34
27
#include "sysemu/kvm.h"
35
-/* Misc Control Register #2 */
28
+#include "sysemu/reset.h"
36
+/* Read Timing Compensation Register */
29
37
#define R_TIMINGS (0x94 / 4)
30
#include <libfdt.h>
38
31
39
/* SPI controller registers and bits (AST2400) */
32
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
33
41
.r_ce_ctrl = R_CE_CTRL,
34
rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
42
.r_ctrl0 = R_CTRL0,
35
&address_space_memory);
43
.r_timings = R_TIMINGS,
36
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
44
+ .nregs_timings = 1,
37
+ rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
45
.conf_enable_w0 = CONF_ENABLE_W0,
38
46
.max_slaves = 5,
39
return fdt_addr;
47
.segments = aspeed_segments_legacy,
40
}
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
49
.r_ce_ctrl = R_CE_CTRL,
50
.r_ctrl0 = R_CTRL0,
51
.r_timings = R_TIMINGS,
52
+ .nregs_timings = 1,
53
.conf_enable_w0 = CONF_ENABLE_W0,
54
.max_slaves = 5,
55
.segments = aspeed_segments_fmc,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
57
.r_ce_ctrl = 0xff,
58
.r_ctrl0 = R_SPI_CTRL0,
59
.r_timings = R_SPI_TIMINGS,
60
+ .nregs_timings = 1,
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
62
.max_slaves = 1,
63
.segments = aspeed_segments_spi,
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
65
.r_ce_ctrl = R_CE_CTRL,
66
.r_ctrl0 = R_CTRL0,
67
.r_timings = R_TIMINGS,
68
+ .nregs_timings = 1,
69
.conf_enable_w0 = CONF_ENABLE_W0,
70
.max_slaves = 3,
71
.segments = aspeed_segments_ast2500_fmc,
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
73
.r_ce_ctrl = R_CE_CTRL,
74
.r_ctrl0 = R_CTRL0,
75
.r_timings = R_TIMINGS,
76
+ .nregs_timings = 1,
77
.conf_enable_w0 = CONF_ENABLE_W0,
78
.max_slaves = 2,
79
.segments = aspeed_segments_ast2500_spi1,
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
81
.r_ce_ctrl = R_CE_CTRL,
82
.r_ctrl0 = R_CTRL0,
83
.r_timings = R_TIMINGS,
84
+ .nregs_timings = 1,
85
.conf_enable_w0 = CONF_ENABLE_W0,
86
.max_slaves = 2,
87
.segments = aspeed_segments_ast2500_spi2,
88
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
89
.r_ce_ctrl = R_CE_CTRL,
90
.r_ctrl0 = R_CTRL0,
91
.r_timings = R_TIMINGS,
92
+ .nregs_timings = 1,
93
.conf_enable_w0 = CONF_ENABLE_W0,
94
.max_slaves = 3,
95
.segments = aspeed_segments_ast2600_fmc,
96
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
97
.r_ce_ctrl = R_CE_CTRL,
98
.r_ctrl0 = R_CTRL0,
99
.r_timings = R_TIMINGS,
100
+ .nregs_timings = 2,
101
.conf_enable_w0 = CONF_ENABLE_W0,
102
.max_slaves = 2,
103
.segments = aspeed_segments_ast2600_spi1,
104
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
105
.r_ce_ctrl = R_CE_CTRL,
106
.r_ctrl0 = R_CTRL0,
107
.r_timings = R_TIMINGS,
108
+ .nregs_timings = 3,
109
.conf_enable_w0 = CONF_ENABLE_W0,
110
.max_slaves = 3,
111
.segments = aspeed_segments_ast2600_spi2,
112
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
113
addr >>= 2;
114
115
if (addr == s->r_conf ||
116
- addr == s->r_timings ||
117
+ (addr >= s->r_timings &&
118
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
119
addr == s->r_ce_ctrl ||
120
addr == R_INTR_CTRL ||
121
addr == R_DUMMY_DATA ||
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
123
addr >>= 2;
124
125
if (addr == s->r_conf ||
126
- addr == s->r_timings ||
127
+ (addr >= s->r_timings &&
128
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
129
addr == s->r_ce_ctrl) {
130
s->regs[addr] = value;
131
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
132
--
41
--
133
2.20.1
42
2.25.1
134
135
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
The AST2600 control register sneakily changed the meaning of bit 4
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
4
re-randomize the various seeds used.
5
select, and instead always runs at 1MHz.
6
5
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
8
only. We can model both using the same fixed 1MHz calculation.
7
Message-id: 20221025004327.568476-7-Jason@zx2c4.com
9
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
11
hw/m68k/virt.c | 20 +++++++++++---------
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
12
1 file changed, 11 insertions(+), 9 deletions(-)
20
2 files changed, 18 insertions(+), 4 deletions(-)
21
13
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
14
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
16
--- a/hw/m68k/virt.c
25
+++ b/include/hw/watchdog/wdt_aspeed.h
17
+++ b/hw/m68k/virt.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
27
uint32_t ext_pulse_width_mask;
19
M68kCPU *cpu;
28
uint32_t reset_ctrl_reg;
20
hwaddr initial_pc;
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
21
hwaddr initial_stack;
30
+ void (*wdt_reload)(AspeedWDTState *s);
22
- struct bi_record *rng_seed;
31
} AspeedWDTClass;
23
} ResetInfo;
32
24
33
#endif /* WDT_ASPEED_H */
25
static void main_cpu_reset(void *opaque)
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
26
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
35
index XXXXXXX..XXXXXXX 100644
27
M68kCPU *cpu = reset_info->cpu;
36
--- a/hw/watchdog/wdt_aspeed.c
28
CPUState *cs = CPU(cpu);
37
+++ b/hw/watchdog/wdt_aspeed.c
29
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
30
- if (reset_info->rng_seed) {
39
31
- qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2,
32
- be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data));
33
- }
34
-
35
cpu_reset(cs);
36
cpu->env.aregs[7] = reset_info->initial_stack;
37
cpu->env.pc = reset_info->initial_pc;
40
}
38
}
41
39
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
40
+static void rerandomize_rng_seed(void *opaque)
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
41
+{
42
+ struct bi_record *rng_seed = opaque;
43
+ qemu_guest_getrandom_nofail((void *)rng_seed->data + 2,
44
+ be16_to_cpu(*(uint16_t *)rng_seed->data));
45
+}
46
+
47
static void virt_init(MachineState *machine)
44
{
48
{
45
uint64_t reload;
49
M68kCPU *cpu = NULL;
46
50
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
47
- if (pclk) {
51
BOOTINFO0(param_ptr, BI_LAST);
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
52
rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
53
parameters_base, cs->as);
50
s->pclk_freq);
54
- reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base,
51
} else {
55
- param_ptr - param_blob) +
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
56
- (param_rng_seed - param_blob);
57
+ qemu_register_reset_nosnapshotload(rerandomize_rng_seed,
58
+ rom_ptr_for_as(cs->as, parameters_base,
59
+ param_ptr - param_blob) +
60
+ (param_rng_seed - param_blob));
61
g_free(param_blob);
53
}
62
}
54
}
63
}
55
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
57
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
59
+
60
+ if (aspeed_wdt_is_enabled(s)) {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
62
+ }
63
+}
64
+
65
+
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
67
unsigned size)
68
{
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
70
case WDT_RESTART:
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
74
+ awc->wdt_reload(s);
75
}
76
break;
77
case WDT_CTRL:
78
if (enable && !aspeed_wdt_is_enabled(s)) {
79
s->regs[WDT_CTRL] = data;
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
81
+ awc->wdt_reload(s);
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
83
s->regs[WDT_CTRL] = data;
84
timer_del(s->timer);
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
86
awc->offset = 0x20;
87
awc->ext_pulse_width_mask = 0xff;
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
89
+ awc->wdt_reload = aspeed_wdt_reload;
90
}
91
92
static const TypeInfo aspeed_2400_wdt_info = {
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
94
awc->ext_pulse_width_mask = 0xfffff;
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
98
}
99
100
static const TypeInfo aspeed_2500_wdt_info = {
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
106
}
107
108
static const TypeInfo aspeed_2600_wdt_info = {
109
--
64
--
110
2.20.1
65
2.25.1
111
112
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
4
re-randomize the various seeds used.
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 20221025004327.568476-8-Jason@zx2c4.com
8
Message-id: 20191119141211.25716-6-clg@kaod.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
11
hw/m68k/q800.c | 33 +++++++++++++--------------------
12
hw/i2c/trace-events | 9 +++++
12
1 file changed, 13 insertions(+), 20 deletions(-)
13
2 files changed, 89 insertions(+), 13 deletions(-)
14
13
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
14
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
16
--- a/hw/m68k/q800.c
18
+++ b/hw/i2c/aspeed_i2c.c
17
+++ b/hw/m68k/q800.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static const TypeInfo glue_info = {
20
#include "hw/i2c/aspeed_i2c.h"
19
},
21
#include "hw/irq.h"
20
};
22
#include "hw/qdev-properties.h"
21
23
+#include "trace.h"
22
-typedef struct {
24
23
- M68kCPU *cpu;
25
/* I2C Global Register */
24
- struct bi_record *rng_seed;
26
25
-} ResetInfo;
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
26
-
27
static void main_cpu_reset(void *opaque)
28
{
28
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
29
- ResetInfo *reset_info = opaque;
30
30
- M68kCPU *cpu = reset_info->cpu;
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
31
+ M68kCPU *cpu = opaque;
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
32
CPUState *cs = CPU(cpu);
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
33
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
34
- if (reset_info->rng_seed) {
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
35
- qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2,
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
36
- be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data));
37
+
37
- }
38
bus->intr_status &= bus->intr_ctrl;
38
-
39
if (bus->intr_status) {
39
cpu_reset(cs);
40
bus->controller->intr_status |= 1 << bus->id;
40
cpu->env.aregs[7] = ldl_phys(cs->as, 0);
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
41
cpu->env.pc = ldl_phys(cs->as, 4);
42
{
43
AspeedI2CBus *bus = opaque;
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
45
+ uint64_t value = -1;
46
47
switch (offset) {
48
case I2CD_FUN_CTRL_REG:
49
- return bus->ctrl;
50
+ value = bus->ctrl;
51
+ break;
52
case I2CD_AC_TIMING_REG1:
53
- return bus->timing[0];
54
+ value = bus->timing[0];
55
+ break;
56
case I2CD_AC_TIMING_REG2:
57
- return bus->timing[1];
58
+ value = bus->timing[1];
59
+ break;
60
case I2CD_INTR_CTRL_REG:
61
- return bus->intr_ctrl;
62
+ value = bus->intr_ctrl;
63
+ break;
64
case I2CD_INTR_STS_REG:
65
- return bus->intr_status;
66
+ value = bus->intr_status;
67
+ break;
68
case I2CD_POOL_CTRL_REG:
69
- return bus->pool_ctrl;
70
+ value = bus->pool_ctrl;
71
+ break;
72
case I2CD_BYTE_BUF_REG:
73
- return bus->buf;
74
+ value = bus->buf;
75
+ break;
76
case I2CD_CMD_REG:
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
79
+ break;
80
case I2CD_DMA_ADDR:
81
if (!aic->has_dma) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
83
- return -1;
84
+ break;
85
}
86
- return bus->dma_addr;
87
+ value = bus->dma_addr;
88
+ break;
89
case I2CD_DMA_LEN:
90
if (!aic->has_dma) {
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
92
- return -1;
93
+ break;
94
}
95
- return bus->dma_len;
96
+ value = bus->dma_len;
97
+ break;
98
+
99
default:
100
qemu_log_mask(LOG_GUEST_ERROR,
101
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
102
- return -1;
103
+ value = -1;
104
+ break;
105
}
106
+
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
108
+ return value;
109
}
42
}
110
43
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
44
+static void rerandomize_rng_seed(void *opaque)
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
114
uint8_t *pool_base = aic->bus_pool_base(bus);
115
116
+ trace_aspeed_i2c_bus_send("BUF", i + 1,
117
+ I2CD_POOL_TX_COUNT(bus->pool_ctrl),
118
+ pool_base[i]);
119
ret = i2c_send(bus->bus, pool_base[i]);
120
if (ret) {
121
break;
122
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
123
while (bus->dma_len) {
124
uint8_t data;
125
aspeed_i2c_dma_read(bus, &data);
126
+ trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data);
127
ret = i2c_send(bus->bus, data);
128
if (ret) {
129
break;
130
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
131
}
132
bus->cmd &= ~I2CD_TX_DMA_ENABLE;
133
} else {
134
+ trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf);
135
ret = i2c_send(bus->bus, bus->buf);
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
139
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
141
pool_base[i] = i2c_recv(bus->bus);
142
+ trace_aspeed_i2c_bus_recv("BUF", i + 1,
143
+ I2CD_POOL_RX_SIZE(bus->pool_ctrl),
144
+ pool_base[i]);
145
}
146
147
/* Update RX count */
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
149
MemTxResult result;
150
151
data = i2c_recv(bus->bus);
152
+ trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data);
153
result = address_space_write(&s->dram_as, bus->dma_addr,
154
MEMTXATTRS_UNSPECIFIED, &data, 1);
155
if (result != MEMTX_OK) {
156
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
157
bus->cmd &= ~I2CD_RX_DMA_ENABLE;
158
} else {
159
data = i2c_recv(bus->bus);
160
+ trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf);
161
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
162
}
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
165
return true;
166
}
167
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
169
+{
45
+{
170
+ g_autofree char *cmd_flags;
46
+ struct bi_record *rng_seed = opaque;
171
+ uint32_t count;
47
+ qemu_guest_getrandom_nofail((void *)rng_seed->data + 2,
172
+
48
+ be16_to_cpu(*(uint16_t *)rng_seed->data));
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
176
+ count = bus->dma_len;
177
+ } else { /* BYTE mode */
178
+ count = 1;
179
+ }
180
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
191
+
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
193
+}
49
+}
194
+
50
+
195
/*
51
static uint8_t fake_mac_rom[] = {
196
* The state machine needs some refinement. It is only used to track
52
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197
* invalid STOP commands for the moment.
53
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
54
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
199
return;
55
NubusBus *nubus;
56
DeviceState *glue;
57
DriveInfo *dinfo;
58
- ResetInfo *reset_info;
59
uint8_t rng_seed[32];
60
61
linux_boot = (kernel_filename != NULL);
62
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
63
exit(1);
200
}
64
}
201
65
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
66
- reset_info = g_new0(ResetInfo, 1);
203
+ aspeed_i2c_bus_cmd_dump(bus);
67
-
204
+ }
68
/* init CPUs */
205
+
69
cpu = M68K_CPU(cpu_create(machine->cpu_type));
206
if (bus->cmd & I2CD_M_START_CMD) {
70
- reset_info->cpu = cpu;
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
71
- qemu_register_reset(main_cpu_reset, reset_info);
208
I2CD_MSTARTR : I2CD_MSTART;
72
+ qemu_register_reset(main_cpu_reset, cpu);
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
73
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
74
/* RAM */
211
bool handle_rx;
75
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
212
76
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
77
BOOTINFO0(param_ptr, BI_LAST);
214
+
78
rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
215
switch (offset) {
79
parameters_base, cs->as);
216
case I2CD_FUN_CTRL_REG:
80
- reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base,
217
if (value & I2CD_SLAVE_EN) {
81
- param_ptr - param_blob) +
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
82
- (param_rng_seed - param_blob);
219
index XXXXXXX..XXXXXXX 100644
83
+ qemu_register_reset_nosnapshotload(rerandomize_rng_seed,
220
--- a/hw/i2c/trace-events
84
+ rom_ptr_for_as(cs->as, parameters_base,
221
+++ b/hw/i2c/trace-events
85
+ param_ptr - param_blob) +
222
@@ -XXX,XX +XXX,XX @@
86
+ (param_rng_seed - param_blob));
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
87
g_free(param_blob);
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
88
} else {
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
89
uint8_t *ptr;
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
90
--
236
2.20.1
91
2.25.1
237
238
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Most boards have this much.
4
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
18
+++ b/hw/misc/aspeed_sdmc.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
20
}
21
22
/* use a common default */
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
25
s->ram_size);
26
- s->ram_size = 512 << 20;
27
- return ASPEED_SDMC_AST2600_512MB;
28
+ s->ram_size = 1024 << 20;
29
+ return ASPEED_SDMC_AST2600_1024MB;
30
}
31
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This models the clock write one to clear registers, and fixes up some
4
incorrect behavior in all of the write to clear registers.
5
6
There was also a typo in one of the register definitions.
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
23
+++ b/hw/misc/aspeed_scu.c
24
@@ -XXX,XX +XXX,XX @@
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
32
#define AST2600_HPLL_EXT TO_REG(0x204)
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
34
return s->regs[reg];
35
}
36
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
38
- unsigned size)
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
40
+ uint64_t data64, unsigned size)
41
{
42
AspeedSCUState *s = ASPEED_SCU(opaque);
43
int reg = TO_REG(offset);
44
+ /* Truncate here so bitwise operations below behave as expected */
45
+ uint32_t data = data64;
46
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
48
qemu_log_mask(LOG_GUEST_ERROR,
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
50
/* fall through */
51
case AST2600_SYS_RST_CTRL:
52
case AST2600_SYS_RST_CTRL2:
53
+ case AST2600_CLK_STOP_CTRL:
54
+ case AST2600_CLK_STOP_CTRL2:
55
/* W1S (Write 1 to set) registers */
56
s->regs[reg] |= data;
57
return;
58
case AST2600_SYS_RST_CTRL_CLR:
59
case AST2600_SYS_RST_CTRL2_CLR:
60
+ case AST2600_CLK_STOP_CTRL_CLR:
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
When the system reboots, the rng-seed that the FDT has should be
4
an array of qemu_irq and passing it around, directly call
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
qdev_get_gpio_in() on the gic field.
5
the ROM region at this point, we add a hook right after the ROM has been
6
added, so that we have a pointer to that copy of the FDT.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Cc: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
9
Cc: Paul Burton <paulburton@kernel.org>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
12
Message-id: 20221025004327.568476-9-Jason@zx2c4.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
16
hw/mips/boston.c | 3 +++
13
1 file changed, 42 insertions(+), 44 deletions(-)
17
1 file changed, 3 insertions(+)
14
18
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
19
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
21
--- a/hw/mips/boston.c
18
+++ b/hw/arm/sbsa-ref.c
22
+++ b/hw/mips/boston.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
@@ -XXX,XX +XXX,XX @@
20
void *fdt;
24
#include "sysemu/sysemu.h"
21
int fdt_size;
25
#include "sysemu/qtest.h"
22
int psci_conduit;
26
#include "sysemu/runstate.h"
23
+ DeviceState *gic;
27
+#include "sysemu/reset.h"
24
PFlashCFI01 *flash[2];
28
25
} SBSAMachineState;
29
#include <libfdt.h>
26
30
#include "qom/object.h"
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
31
@@ -XXX,XX +XXX,XX @@ static void boston_mach_init(MachineState *machine)
28
memory_region_add_subregion(secure_sysmem, base, secram);
32
/* Calculate real fdt size after filter */
29
}
33
dt_size = fdt_totalsize(dtb_load_data);
30
34
rom_add_blob_fixed("dtb", dtb_load_data, dt_size, dtb_paddr);
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
35
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
32
+static void create_gic(SBSAMachineState *sms)
36
+ rom_ptr(dtb_paddr, dt_size));
33
{
37
} else {
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
38
/* Try to load file as FIT */
35
- DeviceState *gicdev;
39
fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
36
SysBusDevice *gicbusdev;
37
const char *gictype;
38
uint32_t redist0_capacity, redist0_count;
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
40
41
gictype = gicv3_class_name();
42
43
- gicdev = qdev_create(NULL, gictype);
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
46
+ sms->gic = qdev_create(NULL, gictype);
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
49
/*
50
* Note that the num-irq property counts both internal and external
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
52
*/
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
57
58
redist0_capacity =
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
60
redist0_count = MIN(smp_cpus, redist0_capacity);
61
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
66
67
- qdev_init_nofail(gicdev);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
69
+ qdev_init_nofail(sms->gic);
70
+ gicbusdev = SYS_BUS_DEVICE(sms->gic);
71
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
72
sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
73
74
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
75
76
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
77
qdev_connect_gpio_out(cpudev, irq,
78
- qdev_get_gpio_in(gicdev,
79
+ qdev_get_gpio_in(sms->gic,
80
ppibase + timer_irq[irq]));
81
}
82
83
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
84
- qdev_get_gpio_in(gicdev, ppibase
85
+ qdev_get_gpio_in(sms->gic, ppibase
86
+ ARCH_GIC_MAINT_IRQ));
87
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
88
- qdev_get_gpio_in(gicdev, ppibase
89
+ qdev_get_gpio_in(sms->gic, ppibase
90
+ VIRTUAL_PMU_IRQ));
91
92
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
93
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
94
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
95
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
96
}
97
-
98
- for (i = 0; i < NUM_IRQS; i++) {
99
- pic[i] = qdev_get_gpio_in(gicdev, i);
100
- }
101
}
102
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
104
+static void create_uart(const SBSAMachineState *sms, int uart,
105
MemoryRegion *mem, Chardev *chr)
106
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
109
qdev_init_nofail(dev);
110
memory_region_add_subregion(mem, base,
111
sysbus_mmio_get_region(s, 0));
112
- sysbus_connect_irq(s, 0, pic[irq]);
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
114
}
115
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
164
}
165
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
167
+static void create_ehci(const SBSAMachineState *sms)
168
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
171
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
173
+ sysbus_create_simple("platform-ehci-usb", base,
174
+ qdev_get_gpio_in(sms->gic, irq));
175
}
176
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
178
- PCIBus *bus)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
180
{
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
184
qdev_init_nofail(dev);
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
192
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
40
--
258
2.20.1
41
2.25.1
259
42
260
43
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Users benefit from knowing which watchdog timer has expired. The address
3
When the system reboots, the rng-seed that the FDT has should be
4
of the watchdog's registers unambiguously indicates which has expired,
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
so log that.
5
the ROM region at this point, we add a hook right after the ROM has been
6
added, so that we have a pointer to that copy of the FDT.
6
7
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Cc: Stafford Horne <shorne@gmail.com>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Message-id: 20221025004327.568476-11-Jason@zx2c4.com
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
14
hw/openrisc/boot.c | 3 +++
15
1 file changed, 2 insertions(+), 1 deletion(-)
15
1 file changed, 3 insertions(+)
16
16
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
17
diff --git a/hw/openrisc/boot.c b/hw/openrisc/boot.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
19
--- a/hw/openrisc/boot.c
20
+++ b/hw/watchdog/wdt_aspeed.c
20
+++ b/hw/openrisc/boot.c
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
21
@@ -XXX,XX +XXX,XX @@
22
return;
22
#include "hw/openrisc/boot.h"
23
}
23
#include "sysemu/device_tree.h"
24
24
#include "sysemu/qtest.h"
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
25
+#include "sysemu/reset.h"
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
26
27
+ s->iomem.addr);
27
#include <libfdt.h>
28
watchdog_perform_action();
28
29
timer_del(s->timer);
29
@@ -XXX,XX +XXX,XX @@ uint32_t openrisc_load_fdt(void *fdt, hwaddr load_start,
30
31
rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
32
&address_space_memory);
33
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
34
+ rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
35
36
return fdt_addr;
30
}
37
}
31
--
38
--
32
2.20.1
39
2.25.1
33
34
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
When the system reboots, the rng-seed that the FDT has should be
4
when the CPU core is reset using the arm_set_cpu_on() function call.
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
The NSACR.{CP11,CP10} bits define the exception level required to
5
the ROM region at this point, we add a hook right after the ROM has been
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
6
added, so that we have a pointer to that copy of the FDT.
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
7
10
This is necessary because in this power-control codepath QEMU
8
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
11
is effectively emulating a bit of EL3 firmware, and has to set
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
12
the CPU up as the EL3 firmware would.
10
Message-id: 20221025004327.568476-12-Jason@zx2c4.com
13
14
Fixes: fc1120a7f5
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
[PMM: added clarifying para to commit message]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
13
---
21
target/arm/arm-powerctl.c | 3 +++
14
hw/rx/rx-gdbsim.c | 3 +++
22
1 file changed, 3 insertions(+)
15
1 file changed, 3 insertions(+)
23
16
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
17
diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
19
--- a/hw/rx/rx-gdbsim.c
27
+++ b/target/arm/arm-powerctl.c
20
+++ b/hw/rx/rx-gdbsim.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
21
@@ -XXX,XX +XXX,XX @@
29
/* Processor is not in secure mode */
22
#include "hw/rx/rx62n.h"
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
23
#include "sysemu/qtest.h"
31
24
#include "sysemu/device_tree.h"
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
25
+#include "sysemu/reset.h"
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
26
#include "hw/boards.h"
34
+
27
#include "qom/object.h"
35
/*
28
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
29
@@ -XXX,XX +XXX,XX @@ static void rx_gdbsim_init(MachineState *machine)
37
* to make sure a CPU targeting EL2 comes out of reset with a
30
dtb_offset = ROUND_DOWN(machine->ram_size - dtb_size, 16);
31
rom_add_blob_fixed("dtb", dtb, dtb_size,
32
SDRAM_BASE + dtb_offset);
33
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
34
+ rom_ptr(SDRAM_BASE + dtb_offset, dtb_size));
35
/* Set dtb address to R1 */
36
RX_CPU(first_cpu)->env.regs[1] = SDRAM_BASE + dtb_offset;
37
}
38
--
38
--
39
2.20.1
39
2.25.1
40
41
diff view generated by jsdifflib