1
ARM queue for 2.10: all M profile bugfixes...
1
The following changes since commit 41fb4c14ee500125dc0ce6fb573cf84b8db29ed0:
2
2
3
thanks
3
Merge tag 'linux-user-for-7.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging (2022-01-06 11:22:42 -0800)
4
-- PMM
5
4
6
The following changes since commit 25dd0e77898c3e10796d4cbeb35e8af5ba6ce975:
5
are available in the Git repository at:
7
6
8
Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-fetch' into staging (2017-07-31 11:27:43 +0100)
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220107
9
8
10
are available in the git repository at:
9
for you to fetch changes up to b8905cc2dde95ca6be5e56d77053b1ca0b8fc182:
11
10
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170731
11
hw/arm: kudo add lm75s on bus 13 (2022-01-07 17:08:01 +0000)
13
14
for you to fetch changes up to 89cbc3778a3d61761e2231e740269218c9a8a41d:
15
16
hw/mps2_scc: fix incorrect properties (2017-07-31 13:11:56 +0100)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* fix broken properties on MPS2 SCC device
15
* Add dummy Aspeed AST2600 Display Port MCU (DPMCU)
21
* fix MPU trace handling of write vs exec
16
* Add missing FEAT_TLBIOS instructions
22
* fix MPU M profile bugs:
17
* arm_gicv3_its: Various bug fixes and cleanups
23
- not handling system space or PPB region correctly
18
* kudo-bmc: Add more devices
24
- not resetting state
25
- not migrating MPU_RNR
26
19
27
----------------------------------------------------------------
20
----------------------------------------------------------------
28
Peter Maydell (6):
21
Chris Rauer (1):
29
target/arm: Correct MPU trace handling of write vs execute
22
hw/arm: Add kudo i2c eeproms.
30
target/arm: Don't do MPU lookups for addresses in M profile PPB region
31
target/arm: Don't allow guest to make System space executable for M profile
32
target/arm: Rename cp15.c6_rgnr to pmsav7.rnr
33
target/arm: Move PMSAv7 reset into arm_cpu_reset() so M profile MPUs get reset
34
target/arm: Migrate MPU_RNR register state for M profile cores
35
23
36
Philippe Mathieu-Daudé (1):
24
Idan Horowitz (1):
37
hw/mps2_scc: fix incorrect properties
25
target/arm: Add missing FEAT_TLBIOS instructions
38
26
39
target/arm/cpu.h | 3 +--
27
Patrick Venture (2):
40
hw/intc/armv7m_nvic.c | 14 +++++-----
28
hw/arm: add i2c muxes to kudo-bmc
41
hw/misc/mps2-scc.c | 4 +--
29
hw/arm: kudo add lm75s on bus 13
42
target/arm/cpu.c | 14 ++++++++++
43
target/arm/helper.c | 71 ++++++++++++++++++++++++++++++++++-----------------
44
target/arm/machine.c | 30 +++++++++++++++++++++-
45
6 files changed, 101 insertions(+), 35 deletions(-)
46
30
31
Peter Maydell (13):
32
hw/intc/arm_gicv3_its: Correct off-by-one bounds check on rdbase
33
hw/intc/arm_gicv3_its: Remove redundant ITS_CTLR_ENABLED define
34
hw/intc/arm_gicv3_its: Remove maxids union from TableDesc
35
hw/intc/arm_gicv3_its: Don't return early in extract_table_params() loop
36
hw/intc/arm_gicv3_its: Reduce code duplication in extract_table_params()
37
hw/intc/arm_gicv3_its: Correct setting of TableDesc entry_sz
38
hw/intc/arm_gicv3_its: Don't misuse GITS_TYPE_PHYSICAL define
39
hw/intc/arm_gicv3_its: Correct handling of MAPI
40
hw/intc/arm_gicv3_its: Use FIELD macros for DTEs
41
hw/intc/arm_gicv3_its: Correct comment about CTE RDBase field size
42
hw/intc/arm_gicv3_its: Use FIELD macros for CTEs
43
hw/intc/arm_gicv3_its: Fix various off-by-one errors
44
hw/intc/arm_gicv3_its: Rename max_l2_entries to num_l2_entries
45
46
Shengtan Mao (1):
47
hw/arm: attach MMC to kudo-bmc
48
49
Troy Lee (1):
50
Add dummy Aspeed AST2600 Display Port MCU (DPMCU)
51
52
hw/intc/gicv3_internal.h | 40 +++---
53
include/hw/arm/aspeed_soc.h | 2 +
54
include/hw/intc/arm_gicv3_its_common.h | 9 +-
55
hw/arm/aspeed_ast2600.c | 8 ++
56
hw/arm/npcm7xx_boards.c | 27 ++++
57
hw/intc/arm_gicv3_its.c | 234 +++++++++++++++------------------
58
target/arm/helper.c | 32 +++++
59
7 files changed, 197 insertions(+), 155 deletions(-)
60
diff view generated by jsdifflib
New patch
1
From: Troy Lee <troy_lee@aspeedtech.com>
1
2
3
AST2600 Display Port MCU introduces 0x18000000~0x1803FFFF as it's memory
4
and io address. If guest machine try to access DPMCU memory, it will
5
cause a fatal error.
6
7
Signed-off-by: Troy Lee <troy_lee@aspeedtech.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20211210083034.726610-1-troy_lee@aspeedtech.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/aspeed_soc.h | 2 ++
14
hw/arm/aspeed_ast2600.c | 8 ++++++++
15
2 files changed, 10 insertions(+)
16
17
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/aspeed_soc.h
20
+++ b/include/hw/arm/aspeed_soc.h
21
@@ -XXX,XX +XXX,XX @@ enum {
22
ASPEED_DEV_EMMC,
23
ASPEED_DEV_KCS,
24
ASPEED_DEV_HACE,
25
+ ASPEED_DEV_DPMCU,
26
+ ASPEED_DEV_DP,
27
};
28
29
#endif /* ASPEED_SOC_H */
30
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/aspeed_ast2600.c
33
+++ b/hw/arm/aspeed_ast2600.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "sysemu/sysemu.h"
36
37
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
38
+#define ASPEED_SOC_DPMCU_SIZE 0x00040000
39
40
static const hwaddr aspeed_soc_ast2600_memmap[] = {
41
[ASPEED_DEV_SRAM] = 0x10000000,
42
+ [ASPEED_DEV_DPMCU] = 0x18000000,
43
/* 0x16000000 0x17FFFFFF : AHB BUS do LPC Bus bridge */
44
[ASPEED_DEV_IOMEM] = 0x1E600000,
45
[ASPEED_DEV_PWM] = 0x1E610000,
46
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
47
[ASPEED_DEV_SCU] = 0x1E6E2000,
48
[ASPEED_DEV_XDMA] = 0x1E6E7000,
49
[ASPEED_DEV_ADC] = 0x1E6E9000,
50
+ [ASPEED_DEV_DP] = 0x1E6EB000,
51
[ASPEED_DEV_VIDEO] = 0x1E700000,
52
[ASPEED_DEV_SDHCI] = 0x1E740000,
53
[ASPEED_DEV_EMMC] = 0x1E750000,
54
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2600_irqmap[] = {
55
[ASPEED_DEV_ETH3] = 32,
56
[ASPEED_DEV_ETH4] = 33,
57
[ASPEED_DEV_KCS] = 138, /* 138 -> 142 */
58
+ [ASPEED_DEV_DP] = 62,
59
};
60
61
static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
63
memory_region_add_subregion(get_system_memory(),
64
sc->memmap[ASPEED_DEV_SRAM], &s->sram);
65
66
+ /* DPMCU */
67
+ create_unimplemented_device("aspeed.dpmcu", sc->memmap[ASPEED_DEV_DPMCU],
68
+ ASPEED_SOC_DPMCU_SIZE);
69
+
70
/* SCU */
71
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
72
return;
73
--
74
2.25.1
75
76
diff view generated by jsdifflib
1
When the PMSAv7 implementation was originally added it was for R profile
1
From: Idan Horowitz <idan.horowitz@gmail.com>
2
CPUs only, and reset was handled using the cpreg .resetfn hooks.
3
Unfortunately for M profile cores this doesn't work, because they do
4
not register any cpregs. Move the reset handling into arm_cpu_reset(),
5
where it will work for both R profile and M profile cores.
6
2
3
Some of the instructions added by the FEAT_TLBIOS extension were forgotten
4
when the extension was originally added to QEMU.
5
6
Fixes: 7113d618505b ("target/arm: Add support for FEAT_TLBIOS")
7
Signed-off-by: Idan Horowitz <idan.horowitz@gmail.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211231103928.1455657-1-idan.horowitz@gmail.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 1501153150-19984-5-git-send-email-peter.maydell@linaro.org
10
---
11
---
11
target/arm/cpu.c | 14 ++++++++++++++
12
target/arm/helper.c | 32 ++++++++++++++++++++++++++++++++
12
target/arm/helper.c | 28 ++++++++++++----------------
13
1 file changed, 32 insertions(+)
13
2 files changed, 26 insertions(+), 16 deletions(-)
14
14
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
20
21
env->vfp.xregs[ARM_VFP_FPEXC] = 0;
22
#endif
23
+
24
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
25
+ arm_feature(env, ARM_FEATURE_V7)) {
26
+ if (cpu->pmsav7_dregion > 0) {
27
+ memset(env->pmsav7.drbar, 0,
28
+ sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
29
+ memset(env->pmsav7.drsr, 0,
30
+ sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
31
+ memset(env->pmsav7.dracr, 0,
32
+ sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
33
+ }
34
+ env->pmsav7.rnr = 0;
35
+ }
36
+
37
set_flush_to_zero(1, &env->vfp.standard_fp_status);
38
set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
39
set_default_nan_mode(1, &env->vfp.standard_fp_status);
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
43
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
44
@@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
45
*u32p = value;
20
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
46
}
21
.access = PL1_W, .type = ARM_CP_NO_RAW,
47
22
.writefn = tlbi_aa64_vmalle1is_write },
48
-static void pmsav7_reset(CPUARMState *env, const ARMCPRegInfo *ri)
23
+ { .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64,
49
-{
24
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1,
50
- ARMCPU *cpu = arm_env_get_cpu(env);
25
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
51
- uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri);
26
+ .writefn = tlbi_aa64_vae1is_write },
52
-
27
{ .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
53
- if (!u32p) {
28
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
54
- return;
29
.access = PL1_W, .type = ARM_CP_NO_RAW,
55
- }
30
.writefn = tlbi_aa64_vmalle1is_write },
56
-
31
+ { .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64,
57
- memset(u32p, 0, sizeof(*u32p) * cpu->pmsav7_dregion);
32
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3,
58
-}
33
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
59
-
34
+ .writefn = tlbi_aa64_vae1is_write },
60
static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
35
+ { .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64,
61
uint64_t value)
36
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5,
62
{
37
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
63
@@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
38
+ .writefn = tlbi_aa64_vae1is_write },
64
}
39
+ { .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64,
65
40
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7,
66
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
41
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
67
+ /* Reset for all these registers is handled in arm_cpu_reset(),
42
+ .writefn = tlbi_aa64_vae1is_write },
68
+ * because the PMSAv7 is also used by M-profile CPUs, which do
43
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
69
+ * not register cpregs but still need the state to be reset.
44
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
70
+ */
45
.access = PL2_W, .type = ARM_CP_NO_RAW,
71
{ .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0,
46
.writefn = tlbi_aa64_alle2is_write },
72
.access = PL1_RW, .type = ARM_CP_NO_RAW,
47
+ { .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64,
73
.fieldoffset = offsetof(CPUARMState, pmsav7.drbar),
48
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1,
74
- .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset },
49
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
75
+ .readfn = pmsav7_read, .writefn = pmsav7_write,
50
+ .writefn = tlbi_aa64_vae2is_write },
76
+ .resetfn = arm_cp_reset_ignore },
51
{ .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64,
77
{ .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2,
52
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4,
78
.access = PL1_RW, .type = ARM_CP_NO_RAW,
53
.access = PL2_W, .type = ARM_CP_NO_RAW,
79
.fieldoffset = offsetof(CPUARMState, pmsav7.drsr),
54
.writefn = tlbi_aa64_alle1is_write },
80
- .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset },
55
+ { .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64,
81
+ .readfn = pmsav7_read, .writefn = pmsav7_write,
56
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5,
82
+ .resetfn = arm_cp_reset_ignore },
57
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
83
{ .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4,
58
+ .writefn = tlbi_aa64_vae2is_write },
84
.access = PL1_RW, .type = ARM_CP_NO_RAW,
59
{ .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64,
85
.fieldoffset = offsetof(CPUARMState, pmsav7.dracr),
60
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6,
86
- .readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset },
61
.access = PL2_W, .type = ARM_CP_NO_RAW,
87
+ .readfn = pmsav7_read, .writefn = pmsav7_write,
62
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
88
+ .resetfn = arm_cp_reset_ignore },
63
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0,
89
{ .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
64
.access = PL3_W, .type = ARM_CP_NO_RAW,
90
.access = PL1_RW,
65
.writefn = tlbi_aa64_alle3is_write },
91
.fieldoffset = offsetof(CPUARMState, pmsav7.rnr),
66
+ { .name = "TLBI_VAE3OS", .state = ARM_CP_STATE_AA64,
92
- .writefn = pmsav7_rgnr_write },
67
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 1,
93
+ .writefn = pmsav7_rgnr_write,
68
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
94
+ .resetfn = arm_cp_reset_ignore },
69
+ .writefn = tlbi_aa64_vae3is_write },
70
+ { .name = "TLBI_VALE3OS", .state = ARM_CP_STATE_AA64,
71
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5,
72
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
73
+ .writefn = tlbi_aa64_vae3is_write },
95
REGINFO_SENTINEL
74
REGINFO_SENTINEL
96
};
75
};
97
76
98
--
77
--
99
2.7.4
78
2.25.1
100
79
101
80
diff view generated by jsdifflib
New patch
1
The checks in the ITS on the rdbase values in guest commands are
2
off-by-one: they permit the guest to pass us a value equal to
3
s->gicv3->num_cpu, but the valid values are 0...num_cpu-1. This
4
meant the guest could cause us to index off the end of the
5
s->gicv3->cpu[] array when calling gicv3_redist_process_lpi(), and we
6
would probably crash.
1
7
8
(This is not a security bug, because this code is only usable
9
with emulation, not with KVM.)
10
11
Cc: qemu-stable@nongnu.org
12
Fixes: 17fb5e36aabd4b ("hw/intc: GICv3 redistributor ITS processing")
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
---
17
hw/intc/arm_gicv3_its.c | 4 ++--
18
1 file changed, 2 insertions(+), 2 deletions(-)
19
20
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/arm_gicv3_its.c
23
+++ b/hw/intc/arm_gicv3_its.c
24
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
25
*/
26
rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U;
27
28
- if (rdbase > s->gicv3->num_cpu) {
29
+ if (rdbase >= s->gicv3->num_cpu) {
30
return result;
31
}
32
33
@@ -XXX,XX +XXX,XX @@ static bool process_mapc(GICv3ITSState *s, uint32_t offset)
34
35
valid = (value & CMD_FIELD_VALID_MASK);
36
37
- if ((icid > s->ct.maxids.max_collids) || (rdbase > s->gicv3->num_cpu)) {
38
+ if ((icid > s->ct.maxids.max_collids) || (rdbase >= s->gicv3->num_cpu)) {
39
qemu_log_mask(LOG_GUEST_ERROR,
40
"ITS MAPC: invalid collection table attributes "
41
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
42
--
43
2.25.1
44
45
diff view generated by jsdifflib
1
The PMSAv7 region number register is migrated for R profile
1
We currently define a bitmask for the GITS_CTLR ENABLED bit in
2
cores using the cpreg scheme, but M profile doesn't use
2
two ways: as ITS_CTLR_ENABLED, and via the FIELD() macro as
3
cpregs, and so we weren't migrating the MPU_RNR register state
3
R_GITS_CTLR_ENABLED_MASK. Consistently use the FIELD macro version
4
at all. Fix that by adding a migration subsection for the
4
everywhere and remove the redundant ITS_CTLR_ENABLED define.
5
M profile case.
6
5
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 1501153150-19984-6-git-send-email-peter.maydell@linaro.org
10
---
10
---
11
target/arm/machine.c | 28 ++++++++++++++++++++++++++++
11
hw/intc/gicv3_internal.h | 2 --
12
1 file changed, 28 insertions(+)
12
hw/intc/arm_gicv3_its.c | 20 ++++++++++----------
13
2 files changed, 10 insertions(+), 12 deletions(-)
13
14
14
diff --git a/target/arm/machine.c b/target/arm/machine.c
15
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/machine.c
17
--- a/hw/intc/gicv3_internal.h
17
+++ b/target/arm/machine.c
18
+++ b/hw/intc/gicv3_internal.h
18
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav7 = {
19
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
20
21
#define GITS_IDREGS 0xFFD0
22
23
-#define ITS_CTLR_ENABLED (1U) /* ITS Enabled */
24
-
25
#define GITS_BASER_RO_MASK (R_GITS_BASER_ENTRYSIZE_MASK | \
26
R_GITS_BASER_TYPE_MASK)
27
28
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/intc/arm_gicv3_its.c
31
+++ b/hw/intc/arm_gicv3_its.c
32
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
33
uint8_t cmd;
34
int i;
35
36
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
37
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
38
return;
19
}
39
}
20
};
40
21
41
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
22
+static bool pmsav7_rnr_needed(void *opaque)
42
23
+{
43
switch (offset) {
24
+ ARMCPU *cpu = opaque;
44
case GITS_TRANSLATER:
25
+ CPUARMState *env = &cpu->env;
45
- if (s->ctlr & ITS_CTLR_ENABLED) {
26
+
46
+ if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
27
+ /* For R profile cores pmsav7.rnr is migrated via the cpreg
47
devid = attrs.requester_id;
28
+ * "RGNR" definition in helper.h. For M profile we have to
48
result = process_its_cmd(s, data, devid, NONE);
29
+ * migrate it separately.
49
}
30
+ */
50
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
31
+ return arm_feature(env, ARM_FEATURE_M);
51
switch (offset) {
32
+}
52
case GITS_CTLR:
33
+
53
if (value & R_GITS_CTLR_ENABLED_MASK) {
34
+static const VMStateDescription vmstate_pmsav7_rnr = {
54
- s->ctlr |= ITS_CTLR_ENABLED;
35
+ .name = "cpu/pmsav7-rnr",
55
+ s->ctlr |= R_GITS_CTLR_ENABLED_MASK;
36
+ .version_id = 1,
56
extract_table_params(s);
37
+ .minimum_version_id = 1,
57
extract_cmdq_params(s);
38
+ .needed = pmsav7_rnr_needed,
58
s->creadr = 0;
39
+ .fields = (VMStateField[]) {
59
process_cmdq(s);
40
+ VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU),
60
} else {
41
+ VMSTATE_END_OF_LIST()
61
- s->ctlr &= ~ITS_CTLR_ENABLED;
42
+ }
62
+ s->ctlr &= ~R_GITS_CTLR_ENABLED_MASK;
43
+};
63
}
44
+
64
break;
45
static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
65
case GITS_CBASER:
46
VMStateField *field)
66
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
67
* IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
68
* already enabled
69
*/
70
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
71
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
72
s->cbaser = deposit64(s->cbaser, 0, 32, value);
73
s->creadr = 0;
74
s->cwriter = s->creadr;
75
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
76
* IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
77
* already enabled
78
*/
79
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
80
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
81
s->cbaser = deposit64(s->cbaser, 32, 32, value);
82
s->creadr = 0;
83
s->cwriter = s->creadr;
84
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
85
* IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
86
* already enabled
87
*/
88
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
89
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
90
index = (offset - GITS_BASER) / 8;
91
92
if (offset & 7) {
93
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
94
* IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
95
* already enabled
96
*/
97
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
98
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
99
index = (offset - GITS_BASER) / 8;
100
s->baser[index] &= GITS_BASER_RO_MASK;
101
s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
102
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
103
* IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
104
* already enabled
105
*/
106
- if (!(s->ctlr & ITS_CTLR_ENABLED)) {
107
+ if (!(s->ctlr & R_GITS_CTLR_ENABLED_MASK)) {
108
s->cbaser = value;
109
s->creadr = 0;
110
s->cwriter = s->creadr;
111
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_reset(DeviceState *dev)
112
113
static void gicv3_its_post_load(GICv3ITSState *s)
47
{
114
{
48
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
115
- if (s->ctlr & ITS_CTLR_ENABLED) {
49
&vmstate_iwmmxt,
116
+ if (s->ctlr & R_GITS_CTLR_ENABLED_MASK) {
50
&vmstate_m,
117
extract_table_params(s);
51
&vmstate_thumb2ee,
118
extract_cmdq_params(s);
52
+ /* pmsav7_rnr must come before pmsav7 so that we have the
53
+ * region number before we test it in the VMSTATE_VALIDATE
54
+ * in vmstate_pmsav7.
55
+ */
56
+ &vmstate_pmsav7_rnr,
57
&vmstate_pmsav7,
58
NULL
59
}
119
}
60
--
120
--
61
2.7.4
121
2.25.1
62
122
63
123
diff view generated by jsdifflib
New patch
1
The TableDesc struct defines properties of the in-guest-memory tables
2
which the guest tells us about by writing to the GITS_BASER<n>
3
registers. This struct currently has a union 'maxids', but all the
4
fields of the union have the same type (uint32_t) and do the same
5
thing (record one-greater-than the maximum ID value that can be used
6
as an index into the table).
1
7
8
We're about to add another table type (the GICv4 vPE table); rather
9
than adding another specifically-named union field for that table
10
type with the same type as the other union fields, remove the union
11
entirely and just have a 'uint32_t max_ids' struct field.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
---
17
include/hw/intc/arm_gicv3_its_common.h | 5 +----
18
hw/intc/arm_gicv3_its.c | 20 ++++++++++----------
19
2 files changed, 11 insertions(+), 14 deletions(-)
20
21
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/intc/arm_gicv3_its_common.h
24
+++ b/include/hw/intc/arm_gicv3_its_common.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
26
uint16_t entry_sz;
27
uint32_t page_sz;
28
uint32_t max_entries;
29
- union {
30
- uint32_t max_devids;
31
- uint32_t max_collids;
32
- } maxids;
33
+ uint32_t max_ids;
34
uint64_t base_addr;
35
} TableDesc;
36
37
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/arm_gicv3_its.c
40
+++ b/hw/intc/arm_gicv3_its.c
41
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
42
* In this implementation, in case of guest errors we ignore the
43
* command and move onto the next command in the queue.
44
*/
45
- if (devid > s->dt.maxids.max_devids) {
46
+ if (devid > s->dt.max_ids) {
47
qemu_log_mask(LOG_GUEST_ERROR,
48
"%s: invalid command attributes: devid %d>%d",
49
- __func__, devid, s->dt.maxids.max_devids);
50
+ __func__, devid, s->dt.max_ids);
51
52
} else if (!dte_valid || !ite_valid || !cte_valid) {
53
qemu_log_mask(LOG_GUEST_ERROR,
54
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
55
max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
56
}
57
58
- if ((devid > s->dt.maxids.max_devids) || (icid > s->ct.maxids.max_collids)
59
+ if ((devid > s->dt.max_ids) || (icid > s->ct.max_ids)
60
|| !dte_valid || (eventid > max_eventid) ||
61
(!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) ||
62
(pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) {
63
@@ -XXX,XX +XXX,XX @@ static bool process_mapc(GICv3ITSState *s, uint32_t offset)
64
65
valid = (value & CMD_FIELD_VALID_MASK);
66
67
- if ((icid > s->ct.maxids.max_collids) || (rdbase >= s->gicv3->num_cpu)) {
68
+ if ((icid > s->ct.max_ids) || (rdbase >= s->gicv3->num_cpu)) {
69
qemu_log_mask(LOG_GUEST_ERROR,
70
"ITS MAPC: invalid collection table attributes "
71
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
72
@@ -XXX,XX +XXX,XX @@ static bool process_mapd(GICv3ITSState *s, uint64_t value, uint32_t offset)
73
74
valid = (value & CMD_FIELD_VALID_MASK);
75
76
- if ((devid > s->dt.maxids.max_devids) ||
77
+ if ((devid > s->dt.max_ids) ||
78
(size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
79
qemu_log_mask(LOG_GUEST_ERROR,
80
"ITS MAPD: invalid device table attributes "
81
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
82
(page_sz / s->dt.entry_sz));
83
}
84
85
- s->dt.maxids.max_devids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
86
- DEVBITS) + 1));
87
+ s->dt.max_ids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
88
+ DEVBITS) + 1));
89
90
s->dt.base_addr = baser_base_addr(value, page_sz);
91
92
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
93
}
94
95
if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
96
- s->ct.maxids.max_collids = (1UL << (FIELD_EX64(s->typer,
97
- GITS_TYPER, CIDBITS) + 1));
98
+ s->ct.max_ids = (1UL << (FIELD_EX64(s->typer,
99
+ GITS_TYPER, CIDBITS) + 1));
100
} else {
101
/* 16-bit CollectionId supported when CIL == 0 */
102
- s->ct.maxids.max_collids = (1UL << 16);
103
+ s->ct.max_ids = (1UL << 16);
104
}
105
106
s->ct.base_addr = baser_base_addr(value, page_sz);
107
--
108
2.25.1
109
110
diff view generated by jsdifflib
1
Correct off-by-one bug in the PSMAv7 MPU tracing where it would print
1
In extract_table_params() we process each GITS_BASER<n> register. If
2
a write access as "reading", an insn fetch as "writing", and a read
2
the register's Valid bit is not set, this means there is no
3
access as "execute".
3
in-guest-memory table and so we should not try to interpret the other
4
fields in the register. This was incorrectly coded as a 'return'
5
rather than a 'break', so instead of looping round to process the
6
next GITS_BASER<n> we would stop entirely, treating any later tables
7
as being not valid also.
4
8
5
Since we have an MMUAccessType enum now, we can make the code clearer
9
This has no real guest-visible effects because (since we don't have
6
in the process by using that rather than the raw 0/1/2 values.
10
GITS_TYPER.HCC != 0) the guest must in any case set up all the
11
GITS_BASER<n> to point to valid tables, so this only happens in an
12
odd misbehaving-guest corner case.
13
14
Fix the check to 'break', so that we leave the case statement and
15
loop back around to the next GITS_BASER<n>.
7
16
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <rth@twiddle.net>
18
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 1500906792-18010-1-git-send-email-peter.maydell@linaro.org
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
20
---
12
target/arm/helper.c | 4 ++--
21
hw/intc/arm_gicv3_its.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
22
1 file changed, 2 insertions(+), 2 deletions(-)
14
23
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
26
--- a/hw/intc/arm_gicv3_its.c
18
+++ b/target/arm/helper.c
27
+++ b/hw/intc/arm_gicv3_its.c
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
28
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
20
phys_ptr, prot, fsr);
29
s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID);
21
qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32
30
22
" mmu_idx %u -> %s (prot %c%c%c)\n",
31
if (!s->dt.valid) {
23
- access_type == 1 ? "reading" :
32
- return;
24
- (access_type == 2 ? "writing" : "execute"),
33
+ break;
25
+ access_type == MMU_DATA_LOAD ? "reading" :
34
}
26
+ (access_type == MMU_DATA_STORE ? "writing" : "execute"),
35
27
(uint32_t)address, mmu_idx,
36
s->dt.page_sz = page_sz;
28
ret ? "Miss" : "Hit",
37
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
29
*prot & PAGE_READ ? 'r' : '-',
38
* hence writes are discarded if ct.valid is 0
39
*/
40
if (!s->ct.valid) {
41
- return;
42
+ break;
43
}
44
45
s->ct.page_sz = page_sz;
30
--
46
--
31
2.7.4
47
2.25.1
32
48
33
49
diff view generated by jsdifflib
New patch
1
The extract_table_params() decodes the fields in the GITS_BASER<n>
2
registers into TableDesc structs. Since the fields are the same for
3
all the GITS_BASER<n> registers, there is currently a lot of code
4
duplication within the switch (type) statement. Refactor so that the
5
cases include only what is genuinely different for each type:
6
the calculation of the number of bits in the ID value that indexes
7
into the table.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
---
14
hw/intc/arm_gicv3_its.c | 97 +++++++++++++++++------------------------
15
1 file changed, 40 insertions(+), 57 deletions(-)
16
17
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_its.c
20
+++ b/hw/intc/arm_gicv3_its.c
21
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
22
uint64_t value;
23
24
for (int i = 0; i < 8; i++) {
25
+ TableDesc *td;
26
+ int idbits;
27
+
28
value = s->baser[i];
29
30
if (!value) {
31
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
32
type = FIELD_EX64(value, GITS_BASER, TYPE);
33
34
switch (type) {
35
-
36
case GITS_BASER_TYPE_DEVICE:
37
- memset(&s->dt, 0 , sizeof(s->dt));
38
- s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID);
39
-
40
- if (!s->dt.valid) {
41
- break;
42
- }
43
-
44
- s->dt.page_sz = page_sz;
45
- s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
46
- s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
47
-
48
- if (!s->dt.indirect) {
49
- s->dt.max_entries = (num_pages * page_sz) / s->dt.entry_sz;
50
- } else {
51
- s->dt.max_entries = (((num_pages * page_sz) /
52
- L1TABLE_ENTRY_SIZE) *
53
- (page_sz / s->dt.entry_sz));
54
- }
55
-
56
- s->dt.max_ids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
57
- DEVBITS) + 1));
58
-
59
- s->dt.base_addr = baser_base_addr(value, page_sz);
60
-
61
+ td = &s->dt;
62
+ idbits = FIELD_EX64(s->typer, GITS_TYPER, DEVBITS) + 1;
63
break;
64
-
65
case GITS_BASER_TYPE_COLLECTION:
66
- memset(&s->ct, 0 , sizeof(s->ct));
67
- s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID);
68
-
69
- /*
70
- * GITS_TYPER.HCC is 0 for this implementation
71
- * hence writes are discarded if ct.valid is 0
72
- */
73
- if (!s->ct.valid) {
74
- break;
75
- }
76
-
77
- s->ct.page_sz = page_sz;
78
- s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
79
- s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
80
-
81
- if (!s->ct.indirect) {
82
- s->ct.max_entries = (num_pages * page_sz) / s->ct.entry_sz;
83
- } else {
84
- s->ct.max_entries = (((num_pages * page_sz) /
85
- L1TABLE_ENTRY_SIZE) *
86
- (page_sz / s->ct.entry_sz));
87
- }
88
-
89
+ td = &s->ct;
90
if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
91
- s->ct.max_ids = (1UL << (FIELD_EX64(s->typer,
92
- GITS_TYPER, CIDBITS) + 1));
93
+ idbits = FIELD_EX64(s->typer, GITS_TYPER, CIDBITS) + 1;
94
} else {
95
/* 16-bit CollectionId supported when CIL == 0 */
96
- s->ct.max_ids = (1UL << 16);
97
+ idbits = 16;
98
}
99
-
100
- s->ct.base_addr = baser_base_addr(value, page_sz);
101
-
102
break;
103
-
104
default:
105
- break;
106
+ /*
107
+ * GITS_BASER<n>.TYPE is read-only, so GITS_BASER_RO_MASK
108
+ * ensures we will only see type values corresponding to
109
+ * the values set up in gicv3_its_reset().
110
+ */
111
+ g_assert_not_reached();
112
}
113
+
114
+ memset(td, 0, sizeof(*td));
115
+ td->valid = FIELD_EX64(value, GITS_BASER, VALID);
116
+ /*
117
+ * If GITS_BASER<n>.Valid is 0 for any <n> then we will not process
118
+ * interrupts. (GITS_TYPER.HCC is 0 for this implementation, so we
119
+ * do not have a special case where the GITS_BASER<n>.Valid bit is 0
120
+ * for the register corresponding to the Collection table but we
121
+ * still have to process interrupts using non-memory-backed
122
+ * Collection table entries.)
123
+ */
124
+ if (!td->valid) {
125
+ continue;
126
+ }
127
+ td->page_sz = page_sz;
128
+ td->indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
129
+ td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
130
+ td->base_addr = baser_base_addr(value, page_sz);
131
+ if (!td->indirect) {
132
+ td->max_entries = (num_pages * page_sz) / td->entry_sz;
133
+ } else {
134
+ td->max_entries = (((num_pages * page_sz) /
135
+ L1TABLE_ENTRY_SIZE) *
136
+ (page_sz / td->entry_sz));
137
+ }
138
+ td->max_ids = 1ULL << idbits;
139
}
140
}
141
142
--
143
2.25.1
144
145
diff view generated by jsdifflib
New patch
1
We set the TableDesc entry_sz field from the appropriate
2
GITS_BASER.ENTRYSIZE field. That ID register field specifies the
3
number of bytes per table entry minus one. However when we use
4
td->entry_sz we assume it to be the number of bytes per table entry
5
(for instance we calculate the number of entries in a page by
6
dividing the page size by the entry size).
1
7
8
The effects of this bug are:
9
* we miscalculate the maximum number of entries in the table,
10
so our checks on guest index values are wrong (too lax)
11
* when looking up an entry in the second level of an indirect
12
table, we calculate an incorrect index into the L2 table.
13
Because we make the same incorrect calculation on both
14
reads and writes of the L2 table, the guest won't notice
15
unless it's unlucky enough to use an index value that
16
causes us to index off the end of the L2 table page and
17
cause guest memory corruption in whatever follows
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
---
23
hw/intc/arm_gicv3_its.c | 2 +-
24
1 file changed, 1 insertion(+), 1 deletion(-)
25
26
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3_its.c
29
+++ b/hw/intc/arm_gicv3_its.c
30
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
31
}
32
td->page_sz = page_sz;
33
td->indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
34
- td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
35
+ td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE) + 1;
36
td->base_addr = baser_base_addr(value, page_sz);
37
if (!td->indirect) {
38
td->max_entries = (num_pages * page_sz) / td->entry_sz;
39
--
40
2.25.1
41
42
diff view generated by jsdifflib
New patch
1
The GITS_TYPE_PHYSICAL define is the value we set the
2
GITS_TYPER.Physical field to -- this is 1 to indicate that we support
3
physical LPIs. (Support for virtual LPIs is the GITS_TYPER.Virtual
4
field.) We also use this define as the *value* that we write into an
5
interrupt translation table entry's INTTYPE field, which should be 1
6
for a physical interrupt and 0 for a virtual interrupt. Finally, we
7
use it as a *mask* when we read the interrupt translation table entry
8
INTTYPE field.
1
9
10
Untangle this confusion: define an ITE_INTTYPE_VIRTUAL and
11
ITE_INTTYPE_PHYSICAL to be the valid values of the ITE INTTYPE
12
field, and replace the ad-hoc collection of ITE_ENTRY_* defines with
13
use of the FIELD() macro to define the fields of an ITE and the
14
FIELD_EX64() and FIELD_DP64() macros to read and write them.
15
We use ITE in the new setup, rather than ITE_ENTRY, because
16
ITE stands for "Interrupt translation entry" and so the extra
17
"entry" would be redundant.
18
19
We take the opportunity to correct the name of the field that holds
20
the GICv4 'doorbell' interrupt ID (this is always the value 1023 in a
21
GICv3, which is why we were calling it the 'spurious' field).
22
23
The GITS_TYPE_PHYSICAL define is then used in only one place, where
24
we set the initial GITS_TYPER value. Since GITS_TYPER.Physical is
25
essentially a boolean, hiding the '1' value behind a macro is more
26
confusing than helpful, so expand out the macro there and remove the
27
define entirely.
28
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
---
33
hw/intc/gicv3_internal.h | 26 ++++++++++++++------------
34
hw/intc/arm_gicv3_its.c | 30 +++++++++++++-----------------
35
2 files changed, 27 insertions(+), 29 deletions(-)
36
37
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/gicv3_internal.h
40
+++ b/hw/intc/gicv3_internal.h
41
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
42
#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
43
#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
44
45
-/**
46
- * Default features advertised by this version of ITS
47
- */
48
-/* Physical LPIs supported */
49
-#define GITS_TYPE_PHYSICAL (1U << 0)
50
-
51
/*
52
* 12 bytes Interrupt translation Table Entry size
53
* as per Table 5.3 in GICv3 spec
54
* ITE Lower 8 Bytes
55
* Bits: | 49 ... 26 | 25 ... 2 | 1 | 0 |
56
- * Values: | 1023 | IntNum | IntType | Valid |
57
+ * Values: | Doorbell | IntNum | IntType | Valid |
58
* ITE Higher 4 Bytes
59
* Bits: | 31 ... 16 | 15 ...0 |
60
* Values: | vPEID | ICID |
61
+ * (When Doorbell is unused, as it always is in GICv3, it is 1023)
62
*/
63
#define ITS_ITT_ENTRY_SIZE 0xC
64
-#define ITE_ENTRY_INTTYPE_SHIFT 1
65
-#define ITE_ENTRY_INTID_SHIFT 2
66
-#define ITE_ENTRY_INTID_MASK MAKE_64BIT_MASK(2, 24)
67
-#define ITE_ENTRY_INTSP_SHIFT 26
68
-#define ITE_ENTRY_ICID_MASK MAKE_64BIT_MASK(0, 16)
69
+
70
+FIELD(ITE_L, VALID, 0, 1)
71
+FIELD(ITE_L, INTTYPE, 1, 1)
72
+FIELD(ITE_L, INTID, 2, 24)
73
+FIELD(ITE_L, DOORBELL, 26, 24)
74
+
75
+FIELD(ITE_H, ICID, 0, 16)
76
+FIELD(ITE_H, VPEID, 16, 16)
77
+
78
+/* Possible values for ITE_L INTTYPE */
79
+#define ITE_INTTYPE_VIRTUAL 0
80
+#define ITE_INTTYPE_PHYSICAL 1
81
82
/* 16 bits EventId */
83
#define ITS_IDBITS GICD_TYPER_IDBITS
84
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/intc/arm_gicv3_its.c
87
+++ b/hw/intc/arm_gicv3_its.c
88
@@ -XXX,XX +XXX,XX @@ static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
89
MEMTXATTRS_UNSPECIFIED, res);
90
91
if (*res == MEMTX_OK) {
92
- if (ite.itel & TABLE_ENTRY_VALID_MASK) {
93
- if ((ite.itel >> ITE_ENTRY_INTTYPE_SHIFT) &
94
- GITS_TYPE_PHYSICAL) {
95
- *pIntid = (ite.itel & ITE_ENTRY_INTID_MASK) >>
96
- ITE_ENTRY_INTID_SHIFT;
97
- *icid = ite.iteh & ITE_ENTRY_ICID_MASK;
98
+ if (FIELD_EX64(ite.itel, ITE_L, VALID)) {
99
+ int inttype = FIELD_EX64(ite.itel, ITE_L, INTTYPE);
100
+ if (inttype == ITE_INTTYPE_PHYSICAL) {
101
+ *pIntid = FIELD_EX64(ite.itel, ITE_L, INTID);
102
+ *icid = FIELD_EX32(ite.iteh, ITE_H, ICID);
103
status = true;
104
}
105
}
106
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
107
MemTxResult res = MEMTX_OK;
108
uint16_t icid = 0;
109
uint64_t dte = 0;
110
- IteEntry ite;
111
- uint32_t int_spurious = INTID_SPURIOUS;
112
bool result = false;
113
114
devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
115
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
116
*/
117
} else {
118
/* add ite entry to interrupt translation table */
119
- ite.itel = (dte_valid & TABLE_ENTRY_VALID_MASK) |
120
- (GITS_TYPE_PHYSICAL << ITE_ENTRY_INTTYPE_SHIFT);
121
-
122
+ IteEntry ite = {};
123
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, dte_valid);
124
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL);
125
if (ignore_pInt) {
126
- ite.itel |= (eventid << ITE_ENTRY_INTID_SHIFT);
127
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, eventid);
128
} else {
129
- ite.itel |= (pIntid << ITE_ENTRY_INTID_SHIFT);
130
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid);
131
}
132
- ite.itel |= (int_spurious << ITE_ENTRY_INTSP_SHIFT);
133
- ite.iteh = icid;
134
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, DOORBELL, INTID_SPURIOUS);
135
+ ite.iteh = FIELD_DP32(ite.iteh, ITE_H, ICID, icid);
136
137
result = update_ite(s, eventid, dte, ite);
138
}
139
@@ -XXX,XX +XXX,XX @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
140
"gicv3-its-sysmem");
141
142
/* set the ITS default features supported */
143
- s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL,
144
- GITS_TYPE_PHYSICAL);
145
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, 1);
146
s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
147
ITS_ITT_ENTRY_SIZE - 1);
148
s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS);
149
--
150
2.25.1
151
152
diff view generated by jsdifflib
New patch
1
The MAPI command takes arguments DeviceID, EventID, ICID, and is
2
defined to be equivalent to MAPTI DeviceID, EventID, EventID, ICID.
3
(That is, where MAPTI takes an explicit pINTID, MAPI uses the EventID
4
as the pINTID.)
1
5
6
We didn't quite get this right. In particular the error checks for
7
MAPI include "EventID does not specify a valid LPI identifier", which
8
is the same as MAPTI's error check for the pINTID field. QEMU's code
9
skips the pINTID error check entirely in the MAPI case.
10
11
We can fix this bug and in the process simplify the code by switching
12
to the obvious implementation of setting pIntid = eventid early
13
if ignore_pInt is true.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
---
19
hw/intc/arm_gicv3_its.c | 18 +++++++-----------
20
1 file changed, 7 insertions(+), 11 deletions(-)
21
22
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/intc/arm_gicv3_its.c
25
+++ b/hw/intc/arm_gicv3_its.c
26
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
27
28
eventid = (value & EVENTID_MASK);
29
30
- if (!ignore_pInt) {
31
+ if (ignore_pInt) {
32
+ pIntid = eventid;
33
+ } else {
34
pIntid = ((value & pINTID_MASK) >> pINTID_SHIFT);
35
}
36
37
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
38
39
max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
40
41
- if (!ignore_pInt) {
42
- max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
43
- }
44
+ max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
45
46
if ((devid > s->dt.max_ids) || (icid > s->ct.max_ids)
47
|| !dte_valid || (eventid > max_eventid) ||
48
- (!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) ||
49
- (pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) {
50
+ (((pIntid < GICV3_LPI_INTID_START) || (pIntid > max_Intid)) &&
51
+ (pIntid != INTID_SPURIOUS))) {
52
qemu_log_mask(LOG_GUEST_ERROR,
53
"%s: invalid command attributes "
54
"devid %d or icid %d or eventid %d or pIntid %d or"
55
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
56
IteEntry ite = {};
57
ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, dte_valid);
58
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL);
59
- if (ignore_pInt) {
60
- ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, eventid);
61
- } else {
62
- ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid);
63
- }
64
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid);
65
ite.itel = FIELD_DP64(ite.itel, ITE_L, DOORBELL, INTID_SPURIOUS);
66
ite.iteh = FIELD_DP32(ite.iteh, ITE_H, ICID, icid);
67
68
--
69
2.25.1
70
71
diff view generated by jsdifflib
New patch
1
Currently the ITS code that reads and writes DTEs uses open-coded
2
shift-and-mask to assemble the various fields into the 64-bit DTE
3
word. The names of the macros used for mask and shift values are
4
also somewhat inconsistent, and don't follow our usual convention
5
that a MASK macro should specify the bits in their place in the word.
6
Replace all these with use of the FIELD macro.
1
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
hw/intc/gicv3_internal.h | 7 ++++---
13
hw/intc/arm_gicv3_its.c | 20 +++++++++-----------
14
2 files changed, 13 insertions(+), 14 deletions(-)
15
16
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/gicv3_internal.h
19
+++ b/hw/intc/gicv3_internal.h
20
@@ -XXX,XX +XXX,XX @@ FIELD(ITE_H, VPEID, 16, 16)
21
* Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits
22
*/
23
#define GITS_DTE_SIZE (0x8ULL)
24
-#define GITS_DTE_ITTADDR_SHIFT 6
25
-#define GITS_DTE_ITTADDR_MASK MAKE_64BIT_MASK(GITS_DTE_ITTADDR_SHIFT, \
26
- ITTADDR_LENGTH)
27
+
28
+FIELD(DTE, VALID, 0, 1)
29
+FIELD(DTE, SIZE, 1, 5)
30
+FIELD(DTE, ITTADDR, 6, 44)
31
32
/*
33
* 8 bytes Collection Table Entry size
34
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/intc/arm_gicv3_its.c
37
+++ b/hw/intc/arm_gicv3_its.c
38
@@ -XXX,XX +XXX,XX @@ static bool update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
39
uint64_t itt_addr;
40
MemTxResult res = MEMTX_OK;
41
42
- itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
43
+ itt_addr = FIELD_EX64(dte, DTE, ITTADDR);
44
itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
45
46
address_space_stq_le(as, itt_addr + (eventid * (sizeof(uint64_t) +
47
@@ -XXX,XX +XXX,XX @@ static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
48
bool status = false;
49
IteEntry ite = {};
50
51
- itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
52
+ itt_addr = FIELD_EX64(dte, DTE, ITTADDR);
53
itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
54
55
ite.itel = address_space_ldq_le(as, itt_addr +
56
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
57
if (res != MEMTX_OK) {
58
return result;
59
}
60
- dte_valid = dte & TABLE_ENTRY_VALID_MASK;
61
+ dte_valid = FIELD_EX64(dte, DTE, VALID);
62
63
if (dte_valid) {
64
- max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
65
+ max_eventid = 1UL << (FIELD_EX64(dte, DTE, SIZE) + 1);
66
67
ite_valid = get_ite(s, eventid, dte, &icid, &pIntid, &res);
68
69
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
70
if (res != MEMTX_OK) {
71
return result;
72
}
73
- dte_valid = dte & TABLE_ENTRY_VALID_MASK;
74
-
75
- max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
76
-
77
+ dte_valid = FIELD_EX64(dte, DTE, VALID);
78
+ max_eventid = 1UL << (FIELD_EX64(dte, DTE, SIZE) + 1);
79
max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
80
81
if ((devid > s->dt.max_ids) || (icid > s->ct.max_ids)
82
@@ -XXX,XX +XXX,XX @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid,
83
if (s->dt.valid) {
84
if (valid) {
85
/* add mapping entry to device table */
86
- dte = (valid & TABLE_ENTRY_VALID_MASK) |
87
- ((size & SIZE_MASK) << 1U) |
88
- (itt_addr << GITS_DTE_ITTADDR_SHIFT);
89
+ dte = FIELD_DP64(dte, DTE, VALID, 1);
90
+ dte = FIELD_DP64(dte, DTE, SIZE, size);
91
+ dte = FIELD_DP64(dte, DTE, ITTADDR, itt_addr);
92
}
93
} else {
94
return true;
95
--
96
2.25.1
97
98
diff view generated by jsdifflib
New patch
1
The comment says that in our CTE format the RDBase field is 36 bits;
2
in fact for us it is only 16 bits, because we use the RDBase format
3
where it specifies a 16-bit CPU number. The code already uses
4
RDBASE_PROCNUM_LENGTH (16) as the field width, so fix the comment
5
to match it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
hw/intc/gicv3_internal.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/gicv3_internal.h
17
+++ b/hw/intc/gicv3_internal.h
18
@@ -XXX,XX +XXX,XX @@ FIELD(DTE, ITTADDR, 6, 44)
19
20
/*
21
* 8 bytes Collection Table Entry size
22
- * Valid = 1 bit,RDBase = 36 bits(considering max RDBASE)
23
+ * Valid = 1 bit, RDBase = 16 bits
24
*/
25
#define GITS_CTE_SIZE (0x8ULL)
26
#define GITS_CTE_RDBASE_PROCNUM_MASK MAKE_64BIT_MASK(1, RDBASE_PROCNUM_LENGTH)
27
--
28
2.25.1
29
30
diff view generated by jsdifflib
1
Almost all of the PMSAv7 state is in the pmsav7 substruct of
1
Use FIELD macros to handle CTEs, rather than ad-hoc mask-and-shift.
2
the ARM CPU state structure. The exception is the region
3
number register, which is in cp15.c6_rgnr. This exception
4
is a bit odd for M profile, which otherwise generally does
5
not store state in the cp15 substruct.
6
7
Rename cp15.c6_rgnr to pmsav7.rnr accordingly.
8
2
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 1501153150-19984-4-git-send-email-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
---
6
---
13
target/arm/cpu.h | 3 +--
7
hw/intc/gicv3_internal.h | 3 ++-
14
hw/intc/armv7m_nvic.c | 14 +++++++-------
8
hw/intc/arm_gicv3_its.c | 7 ++++---
15
target/arm/helper.c | 6 +++---
9
2 files changed, 6 insertions(+), 4 deletions(-)
16
target/arm/machine.c | 2 +-
17
4 files changed, 12 insertions(+), 13 deletions(-)
18
10
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
13
--- a/hw/intc/gicv3_internal.h
22
+++ b/target/arm/cpu.h
14
+++ b/hw/intc/gicv3_internal.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
15
@@ -XXX,XX +XXX,XX @@ FIELD(DTE, ITTADDR, 6, 44)
24
uint64_t par_el[4];
16
* Valid = 1 bit, RDBase = 16 bits
25
};
17
*/
26
18
#define GITS_CTE_SIZE (0x8ULL)
27
- uint32_t c6_rgnr;
19
-#define GITS_CTE_RDBASE_PROCNUM_MASK MAKE_64BIT_MASK(1, RDBASE_PROCNUM_LENGTH)
28
-
20
+FIELD(CTE, VALID, 0, 1)
29
uint32_t c9_insn; /* Cache lockdown registers. */
21
+FIELD(CTE, RDBASE, 1, RDBASE_PROCNUM_LENGTH)
30
uint32_t c9_data;
22
31
uint64_t c9_pmcr; /* performance monitor control register */
23
/* Special interrupt IDs */
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
#define INTID_SECURE 1020
33
uint32_t *drbar;
25
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
34
uint32_t *drsr;
35
uint32_t *dracr;
36
+ uint32_t rnr;
37
} pmsav7;
38
39
void *nvic;
40
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
41
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/intc/armv7m_nvic.c
27
--- a/hw/intc/arm_gicv3_its.c
43
+++ b/hw/intc/armv7m_nvic.c
28
+++ b/hw/intc/arm_gicv3_its.c
44
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
29
@@ -XXX,XX +XXX,XX @@ static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
45
case 0xd94: /* MPU_CTRL */
30
MEMTXATTRS_UNSPECIFIED, res);
46
return cpu->env.v7m.mpu_ctrl;
47
case 0xd98: /* MPU_RNR */
48
- return cpu->env.cp15.c6_rgnr;
49
+ return cpu->env.pmsav7.rnr;
50
case 0xd9c: /* MPU_RBAR */
51
case 0xda4: /* MPU_RBAR_A1 */
52
case 0xdac: /* MPU_RBAR_A2 */
53
case 0xdb4: /* MPU_RBAR_A3 */
54
{
55
- int region = cpu->env.cp15.c6_rgnr;
56
+ int region = cpu->env.pmsav7.rnr;
57
58
if (region >= cpu->pmsav7_dregion) {
59
return 0;
60
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
61
case 0xdb0: /* MPU_RASR_A2 */
62
case 0xdb8: /* MPU_RASR_A3 */
63
{
64
- int region = cpu->env.cp15.c6_rgnr;
65
+ int region = cpu->env.pmsav7.rnr;
66
67
if (region >= cpu->pmsav7_dregion) {
68
return 0;
69
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
70
PRIu32 "/%" PRIu32 "\n",
71
value, cpu->pmsav7_dregion);
72
} else {
73
- cpu->env.cp15.c6_rgnr = value;
74
+ cpu->env.pmsav7.rnr = value;
75
}
76
break;
77
case 0xd9c: /* MPU_RBAR */
78
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
79
region, cpu->pmsav7_dregion);
80
return;
81
}
82
- cpu->env.cp15.c6_rgnr = region;
83
+ cpu->env.pmsav7.rnr = region;
84
} else {
85
- region = cpu->env.cp15.c6_rgnr;
86
+ region = cpu->env.pmsav7.rnr;
87
}
88
89
if (region >= cpu->pmsav7_dregion) {
90
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
91
case 0xdb0: /* MPU_RASR_A2 */
92
case 0xdb8: /* MPU_RASR_A3 */
93
{
94
- int region = cpu->env.cp15.c6_rgnr;
95
+ int region = cpu->env.pmsav7.rnr;
96
97
if (region >= cpu->pmsav7_dregion) {
98
return;
99
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/helper.c
102
+++ b/target/arm/helper.c
103
@@ -XXX,XX +XXX,XX @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri)
104
return 0;
105
}
31
}
106
32
107
- u32p += env->cp15.c6_rgnr;
33
- return (*cte & TABLE_ENTRY_VALID_MASK) != 0;
108
+ u32p += env->pmsav7.rnr;
34
+ return FIELD_EX64(*cte, CTE, VALID);
109
return *u32p;
110
}
35
}
111
36
112
@@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
static bool update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
113
return;
38
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
39
* Current implementation only supports rdbase == procnum
40
* Hence rdbase physical address is ignored
41
*/
42
- rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U;
43
+ rdbase = FIELD_EX64(cte, CTE, RDBASE);
44
45
if (rdbase >= s->gicv3->num_cpu) {
46
return result;
47
@@ -XXX,XX +XXX,XX @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
48
49
if (valid) {
50
/* add mapping entry to collection table */
51
- cte = (valid & TABLE_ENTRY_VALID_MASK) | (rdbase << 1ULL);
52
+ cte = FIELD_DP64(cte, CTE, VALID, 1);
53
+ cte = FIELD_DP64(cte, CTE, RDBASE, rdbase);
114
}
54
}
115
55
116
- u32p += env->cp15.c6_rgnr;
56
/*
117
+ u32p += env->pmsav7.rnr;
118
tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
119
*u32p = value;
120
}
121
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
122
.readfn = pmsav7_read, .writefn = pmsav7_write, .resetfn = pmsav7_reset },
123
{ .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
124
.access = PL1_RW,
125
- .fieldoffset = offsetof(CPUARMState, cp15.c6_rgnr),
126
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr),
127
.writefn = pmsav7_rgnr_write },
128
REGINFO_SENTINEL
129
};
130
diff --git a/target/arm/machine.c b/target/arm/machine.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/machine.c
133
+++ b/target/arm/machine.c
134
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
135
{
136
ARMCPU *cpu = opaque;
137
138
- return cpu->env.cp15.c6_rgnr < cpu->pmsav7_dregion;
139
+ return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion;
140
}
141
142
static const VMStateDescription vmstate_pmsav7 = {
143
--
57
--
144
2.7.4
58
2.25.1
145
59
146
60
diff view generated by jsdifflib
1
The M profile PMSAv7 specification says that if the address being looked
1
The ITS code has to check whether various parameters passed in
2
up is in the PPB region (0xe0000000 - 0xe00fffff) then we do not use
2
commands are in-bounds, where the limit is defined in terms of the
3
the MPU regions but always use the default memory map. Implement this
3
number of bits that are available for the parameter. (For example,
4
(we were previously behaving like an R profile PMSAv7, which does not
4
the GITS_TYPER.Devbits ID register field specifies the number of
5
special case this).
5
DeviceID bits minus 1, and device IDs passed in the MAPTI and MAPD
6
command packets must fit in that many bits.)
7
8
Currently we have off-by-one bugs in many of these bounds checks.
9
The typical problem is that we define a max_foo as 1 << n. In
10
the Devbits example, we set
11
s->dt.max_ids = 1UL << (GITS_TYPER.Devbits + 1).
12
However later when we do the bounds check we write
13
if (devid > s->dt.max_ids) { /* command error */ }
14
which incorrectly permits a devid of 1 << n.
15
16
These bugs will not cause QEMU crashes because the ID values being
17
checked are only used for accesses into tables held in guest memory
18
which we access with address_space_*() functions, but they are
19
incorrect behaviour of our emulation.
20
21
Fix them by standardizing on this pattern:
22
* bounds limits are named num_foos and are the 2^n value
23
(equal to the number of valid foo values)
24
* bounds checks are either
25
if (fooid < num_foos) { good }
26
or
27
if (fooid >= num_foos) { bad }
28
29
In this commit we fix the handling of the number of IDs
30
in the device table and the collection table, and the number
31
of commands that will fit in the command queue.
6
32
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
34
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 1501153150-19984-2-git-send-email-peter.maydell@linaro.org
10
---
35
---
11
target/arm/helper.c | 17 ++++++++++++++++-
36
include/hw/intc/arm_gicv3_its_common.h | 6 +++---
12
1 file changed, 16 insertions(+), 1 deletion(-)
37
hw/intc/arm_gicv3_its.c | 26 +++++++++++++-------------
38
2 files changed, 16 insertions(+), 16 deletions(-)
13
39
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
15
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
42
--- a/include/hw/intc/arm_gicv3_its_common.h
17
+++ b/target/arm/helper.c
43
+++ b/include/hw/intc/arm_gicv3_its_common.h
18
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu,
44
@@ -XXX,XX +XXX,XX @@ typedef struct {
45
bool indirect;
46
uint16_t entry_sz;
47
uint32_t page_sz;
48
- uint32_t max_entries;
49
- uint32_t max_ids;
50
+ uint32_t num_entries;
51
+ uint32_t num_ids;
52
uint64_t base_addr;
53
} TableDesc;
54
55
typedef struct {
56
bool valid;
57
- uint32_t max_entries;
58
+ uint32_t num_entries;
59
uint64_t base_addr;
60
} CmdQDesc;
61
62
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/intc/arm_gicv3_its.c
65
+++ b/hw/intc/arm_gicv3_its.c
66
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
67
* In this implementation, in case of guest errors we ignore the
68
* command and move onto the next command in the queue.
69
*/
70
- if (devid > s->dt.max_ids) {
71
+ if (devid >= s->dt.num_ids) {
72
qemu_log_mask(LOG_GUEST_ERROR,
73
- "%s: invalid command attributes: devid %d>%d",
74
- __func__, devid, s->dt.max_ids);
75
+ "%s: invalid command attributes: devid %d>=%d",
76
+ __func__, devid, s->dt.num_ids);
77
78
} else if (!dte_valid || !ite_valid || !cte_valid) {
79
qemu_log_mask(LOG_GUEST_ERROR,
80
@@ -XXX,XX +XXX,XX @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
81
max_eventid = 1UL << (FIELD_EX64(dte, DTE, SIZE) + 1);
82
max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
83
84
- if ((devid > s->dt.max_ids) || (icid > s->ct.max_ids)
85
+ if ((devid >= s->dt.num_ids) || (icid >= s->ct.num_ids)
86
|| !dte_valid || (eventid > max_eventid) ||
87
(((pIntid < GICV3_LPI_INTID_START) || (pIntid > max_Intid)) &&
88
(pIntid != INTID_SPURIOUS))) {
89
@@ -XXX,XX +XXX,XX @@ static bool process_mapc(GICv3ITSState *s, uint32_t offset)
90
91
valid = (value & CMD_FIELD_VALID_MASK);
92
93
- if ((icid > s->ct.max_ids) || (rdbase >= s->gicv3->num_cpu)) {
94
+ if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) {
95
qemu_log_mask(LOG_GUEST_ERROR,
96
"ITS MAPC: invalid collection table attributes "
97
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
98
@@ -XXX,XX +XXX,XX @@ static bool process_mapd(GICv3ITSState *s, uint64_t value, uint32_t offset)
99
100
valid = (value & CMD_FIELD_VALID_MASK);
101
102
- if ((devid > s->dt.max_ids) ||
103
+ if ((devid >= s->dt.num_ids) ||
104
(size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
105
qemu_log_mask(LOG_GUEST_ERROR,
106
"ITS MAPD: invalid device table attributes "
107
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
108
109
wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET);
110
111
- if (wr_offset > s->cq.max_entries) {
112
+ if (wr_offset >= s->cq.num_entries) {
113
qemu_log_mask(LOG_GUEST_ERROR,
114
"%s: invalid write offset "
115
"%d\n", __func__, wr_offset);
116
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
117
118
rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET);
119
120
- if (rd_offset > s->cq.max_entries) {
121
+ if (rd_offset >= s->cq.num_entries) {
122
qemu_log_mask(LOG_GUEST_ERROR,
123
"%s: invalid read offset "
124
"%d\n", __func__, rd_offset);
125
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
126
}
127
if (result) {
128
rd_offset++;
129
- rd_offset %= s->cq.max_entries;
130
+ rd_offset %= s->cq.num_entries;
131
s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset);
132
} else {
133
/*
134
@@ -XXX,XX +XXX,XX @@ static void extract_table_params(GICv3ITSState *s)
135
td->entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE) + 1;
136
td->base_addr = baser_base_addr(value, page_sz);
137
if (!td->indirect) {
138
- td->max_entries = (num_pages * page_sz) / td->entry_sz;
139
+ td->num_entries = (num_pages * page_sz) / td->entry_sz;
140
} else {
141
- td->max_entries = (((num_pages * page_sz) /
142
+ td->num_entries = (((num_pages * page_sz) /
143
L1TABLE_ENTRY_SIZE) *
144
(page_sz / td->entry_sz));
145
}
146
- td->max_ids = 1ULL << idbits;
147
+ td->num_ids = 1ULL << idbits;
19
}
148
}
20
}
149
}
21
150
22
+static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
151
@@ -XXX,XX +XXX,XX @@ static void extract_cmdq_params(GICv3ITSState *s)
23
+{
152
s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID);
24
+ /* True if address is in the M profile PPB region 0xe0000000 - 0xe00fffff */
153
25
+ return arm_feature(env, ARM_FEATURE_M) &&
154
if (s->cq.valid) {
26
+ extract32(address, 20, 12) == 0xe00;
155
- s->cq.max_entries = (num_pages * GITS_PAGE_SIZE_4K) /
27
+}
156
+ s->cq.num_entries = (num_pages * GITS_PAGE_SIZE_4K) /
28
+
157
GITS_CMDQ_ENTRY_SIZE;
29
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
158
s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR);
30
int access_type, ARMMMUIdx mmu_idx,
159
s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT;
31
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
32
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
33
*phys_ptr = address;
34
*prot = 0;
35
36
- if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
37
+ if (regime_translation_disabled(env, mmu_idx) ||
38
+ m_is_ppb_region(env, address)) {
39
+ /* MPU disabled or M profile PPB access: use default memory map.
40
+ * The other case which uses the default memory map in the
41
+ * v7M ARM ARM pseudocode is exception vector reads from the vector
42
+ * table. In QEMU those accesses are done in arm_v7m_load_vector(),
43
+ * which always does a direct read using address_space_ldl(), rather
44
+ * than going via this function, so we don't need to check that here.
45
+ */
46
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
47
} else { /* MPU enabled */
48
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
49
--
160
--
50
2.7.4
161
2.25.1
51
162
52
163
diff view generated by jsdifflib
New patch
1
In several places we have a local variable max_l2_entries which is
2
the number of entries which will fit in a level 2 table. The
3
calculations done on this value are correct; rename it to
4
num_l2_entries to fit the convention we're using in this code.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
---
11
hw/intc/arm_gicv3_its.c | 24 ++++++++++++------------
12
1 file changed, 12 insertions(+), 12 deletions(-)
13
14
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_its.c
17
+++ b/hw/intc/arm_gicv3_its.c
18
@@ -XXX,XX +XXX,XX @@ static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
19
uint64_t value;
20
bool valid_l2t;
21
uint32_t l2t_id;
22
- uint32_t max_l2_entries;
23
+ uint32_t num_l2_entries;
24
25
if (s->ct.indirect) {
26
l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE);
27
@@ -XXX,XX +XXX,XX @@ static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
28
valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
29
30
if (valid_l2t) {
31
- max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
32
+ num_l2_entries = s->ct.page_sz / s->ct.entry_sz;
33
34
l2t_addr = value & ((1ULL << 51) - 1);
35
36
*cte = address_space_ldq_le(as, l2t_addr +
37
- ((icid % max_l2_entries) * GITS_CTE_SIZE),
38
+ ((icid % num_l2_entries) * GITS_CTE_SIZE),
39
MEMTXATTRS_UNSPECIFIED, res);
40
}
41
}
42
@@ -XXX,XX +XXX,XX @@ static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res)
43
uint64_t value;
44
bool valid_l2t;
45
uint32_t l2t_id;
46
- uint32_t max_l2_entries;
47
+ uint32_t num_l2_entries;
48
49
if (s->dt.indirect) {
50
l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE);
51
@@ -XXX,XX +XXX,XX @@ static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res)
52
valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
53
54
if (valid_l2t) {
55
- max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
56
+ num_l2_entries = s->dt.page_sz / s->dt.entry_sz;
57
58
l2t_addr = value & ((1ULL << 51) - 1);
59
60
value = address_space_ldq_le(as, l2t_addr +
61
- ((devid % max_l2_entries) * GITS_DTE_SIZE),
62
+ ((devid % num_l2_entries) * GITS_DTE_SIZE),
63
MEMTXATTRS_UNSPECIFIED, res);
64
}
65
}
66
@@ -XXX,XX +XXX,XX @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
67
uint64_t l2t_addr;
68
bool valid_l2t;
69
uint32_t l2t_id;
70
- uint32_t max_l2_entries;
71
+ uint32_t num_l2_entries;
72
uint64_t cte = 0;
73
MemTxResult res = MEMTX_OK;
74
75
@@ -XXX,XX +XXX,XX @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
76
valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
77
78
if (valid_l2t) {
79
- max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
80
+ num_l2_entries = s->ct.page_sz / s->ct.entry_sz;
81
82
l2t_addr = value & ((1ULL << 51) - 1);
83
84
address_space_stq_le(as, l2t_addr +
85
- ((icid % max_l2_entries) * GITS_CTE_SIZE),
86
+ ((icid % num_l2_entries) * GITS_CTE_SIZE),
87
cte, MEMTXATTRS_UNSPECIFIED, &res);
88
}
89
} else {
90
@@ -XXX,XX +XXX,XX @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid,
91
uint64_t l2t_addr;
92
bool valid_l2t;
93
uint32_t l2t_id;
94
- uint32_t max_l2_entries;
95
+ uint32_t num_l2_entries;
96
uint64_t dte = 0;
97
MemTxResult res = MEMTX_OK;
98
99
@@ -XXX,XX +XXX,XX @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid,
100
valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
101
102
if (valid_l2t) {
103
- max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
104
+ num_l2_entries = s->dt.page_sz / s->dt.entry_sz;
105
106
l2t_addr = value & ((1ULL << 51) - 1);
107
108
address_space_stq_le(as, l2t_addr +
109
- ((devid % max_l2_entries) * GITS_DTE_SIZE),
110
+ ((devid % num_l2_entries) * GITS_DTE_SIZE),
111
dte, MEMTXATTRS_UNSPECIFIED, &res);
112
}
113
} else {
114
--
115
2.25.1
116
117
diff view generated by jsdifflib
1
For an M profile v7PMSA, the system space (0xe0000000 - 0xffffffff) can
1
From: Chris Rauer <crauer@google.com>
2
never be executable, even if the guest tries to set the MPU registers
3
up that way. Enforce this restriction.
4
2
3
Signed-off-by: Chris Rauer <crauer@google.com>
4
Reviewed-by: Hao Wu <wuhaotsh@google.com>
5
Reviewed-by: Patrick Venture <venture@google.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20220102215844.2888833-2-venture@google.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 1501153150-19984-3-git-send-email-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper.c | 16 +++++++++++++++-
10
hw/arm/npcm7xx_boards.c | 8 ++++++++
10
1 file changed, 15 insertions(+), 1 deletion(-)
11
1 file changed, 8 insertions(+)
11
12
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
--- a/hw/arm/npcm7xx_boards.c
15
+++ b/target/arm/helper.c
16
+++ b/hw/arm/npcm7xx_boards.c
16
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
17
@@ -XXX,XX +XXX,XX @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
17
extract32(address, 20, 12) == 0xe00;
18
*/
18
}
19
}
19
20
20
+static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
21
+static void kudo_bmc_i2c_init(NPCM7xxState *soc)
21
+{
22
+{
22
+ /* True if address is in the M profile system region
23
+ at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
23
+ * 0xe0000000 - 0xffffffff
24
+ at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
24
+ */
25
+ /* TODO: Add remaining i2c devices. */
25
+ return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7;
26
+}
26
+}
27
+
27
+
28
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
28
static void npcm750_evb_init(MachineState *machine)
29
int access_type, ARMMMUIdx mmu_idx,
29
{
30
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
30
NPCM7xxState *soc;
31
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
31
@@ -XXX,XX +XXX,XX @@ static void kudo_bmc_init(MachineState *machine)
32
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
32
npcm7xx_connect_flash(&soc->fiu[1], 0, "mx66u51235f",
33
} else { /* a MPU hit! */
33
drive_get(IF_MTD, 3, 0));
34
uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
34
35
+ uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
35
+ kudo_bmc_i2c_init(soc);
36
+
36
npcm7xx_load_kernel(machine, soc);
37
+ if (m_is_system_region(env, address)) {
37
}
38
+ /* System space is always execute never */
38
39
+ xn = 1;
40
+ }
41
42
if (is_user) { /* User mode AP bit decoding */
43
switch (ap) {
44
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
45
}
46
47
/* execute never */
48
- if (env->pmsav7.dracr[n] & (1 << 12)) {
49
+ if (xn) {
50
*prot &= ~PAGE_EXEC;
51
}
52
}
53
--
39
--
54
2.7.4
40
2.25.1
55
41
56
42
diff view generated by jsdifflib
New patch
1
From: Shengtan Mao <stmao@google.com>
1
2
3
Signed-off-by: Shengtan Mao <stmao@google.com>
4
Reviewed-by: Hao Wu <wuhaotsh@google.com>
5
Reviewed-by: Chris Rauer <crauer@google.com>
6
Message-id: 20220102215844.2888833-3-venture@google.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/npcm7xx_boards.c | 1 +
10
1 file changed, 1 insertion(+)
11
12
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/npcm7xx_boards.c
15
+++ b/hw/arm/npcm7xx_boards.c
16
@@ -XXX,XX +XXX,XX @@ static void kudo_bmc_init(MachineState *machine)
17
drive_get(IF_MTD, 3, 0));
18
19
kudo_bmc_i2c_init(soc);
20
+ sdhci_attach_drive(&soc->mmc.sdhci, 0);
21
npcm7xx_load_kernel(machine, soc);
22
}
23
24
--
25
2.25.1
26
27
diff view generated by jsdifflib
New patch
1
From: Patrick Venture <venture@google.com>
1
2
3
Signed-off-by: Patrick Venture <venture@google.com>
4
Reviewed-by: Hao Wu <wuhaotsh@google.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20220102215844.2888833-4-venture@google.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/npcm7xx_boards.c | 9 +++++++++
10
1 file changed, 9 insertions(+)
11
12
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/npcm7xx_boards.c
15
+++ b/hw/arm/npcm7xx_boards.c
16
@@ -XXX,XX +XXX,XX @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
17
18
static void kudo_bmc_i2c_init(NPCM7xxState *soc)
19
{
20
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), TYPE_PCA9548, 0x75);
21
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), TYPE_PCA9548, 0x77);
22
+
23
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
24
+
25
at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
26
+
27
+ i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13), TYPE_PCA9548, 0x77);
28
+
29
at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
30
+
31
/* TODO: Add remaining i2c devices. */
32
}
33
34
--
35
2.25.1
36
37
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Add the four lm75s behind the mux on bus 13.
4
Message-id: 20170729234930.725-1-f4bug@amsat.org
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Tested by booting the firmware:
6
lm75 42-0048: hwmon0: sensor 'lm75'
7
lm75 43-0049: supply vs not found, using dummy regulator
8
lm75 43-0049: hwmon1: sensor 'lm75'
9
lm75 44-0048: supply vs not found, using dummy regulator
10
lm75 44-0048: hwmon2: sensor 'lm75'
11
lm75 45-0049: supply vs not found, using dummy regulator
12
lm75 45-0049: hwmon3: sensor 'lm75'
13
14
Signed-off-by: Patrick Venture <venture@google.com>
15
Reviewed-by: Titus Rwantare <titusr@google.com>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20220102215844.2888833-5-venture@google.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
19
---
8
hw/misc/mps2-scc.c | 4 ++--
20
hw/arm/npcm7xx_boards.c | 11 ++++++++++-
9
1 file changed, 2 insertions(+), 2 deletions(-)
21
1 file changed, 10 insertions(+), 1 deletion(-)
10
22
11
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
23
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/misc/mps2-scc.c
25
--- a/hw/arm/npcm7xx_boards.c
14
+++ b/hw/misc/mps2-scc.c
26
+++ b/hw/arm/npcm7xx_boards.c
15
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
27
@@ -XXX,XX +XXX,XX @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
16
/* Values for various read-only ID registers (which are specific
28
17
* to the board model or FPGA image)
29
static void kudo_bmc_i2c_init(NPCM7xxState *soc)
18
*/
30
{
19
- DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, aid, 0),
31
+ I2CSlave *i2c_mux;
20
+ DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
32
+
21
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
33
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), TYPE_PCA9548, 0x75);
22
- DEFINE_PROP_UINT32("scc-id", MPS2SCC, aid, 0),
34
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), TYPE_PCA9548, 0x77);
23
+ DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
35
24
/* These are the initial settings for the source clocks on the board.
36
@@ -XXX,XX +XXX,XX @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
25
* In hardware they can be configured via a config file read by the
37
26
* motherboard configuration controller to suit the FPGA image.
38
at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
39
40
- i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13), TYPE_PCA9548, 0x77);
41
+ i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
42
+ TYPE_PCA9548, 0x77);
43
+
44
+ /* tmp105 is compatible with the lm75 */
45
+ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 2), "tmp105", 0x48);
46
+ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 3), "tmp105", 0x49);
47
+ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
48
+ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
49
50
at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
51
27
--
52
--
28
2.7.4
53
2.25.1
29
54
30
55
diff view generated by jsdifflib