* [Qemu-devel] [PULL 01/22] target-arm: Break down TLB_LOCKDOWN
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 02/22] target-arm: Add MAIR_EL2 Peter Maydell
` (21 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Break down the overly broad wildcard definition of TLB_LOCKDOWN
down to v7 level.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-3-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1cc4993..a0b414c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -492,10 +492,16 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
.writefn = dacr_write, .raw_writefn = raw_write,
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
- /* ??? This covers not just the impdef TLB lockdown registers but also
- * some v7VMSA registers relating to TEX remap, so it is overly broad.
+ /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
+ * For v6 and v5, these mappings are overly broad.
*/
- { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = CP_ANY,
+ { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
+ .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
+ { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1,
+ .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
+ { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4,
+ .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
+ { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8,
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
/* Cache maintenance ops; some of this space may be overridden later. */
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
@@ -555,6 +561,10 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
{ .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY,
.opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write,
.type = ARM_CP_NO_RAW },
+ { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2,
+ .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
+ { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
+ .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
REGINFO_SENTINEL
};
@@ -1021,19 +1031,17 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.resetvalue = 0 },
/* For non-long-descriptor page tables these are PRRR and NMRR;
* regardless they still act as reads-as-written for QEMU.
- * The override is necessary because of the overly-broad TLB_LOCKDOWN
- * definition.
*/
/* MAIR0/1 are defined separately from their 64-bit counterpart which
* allows them to assign the correct fieldoffset based on the endianness
* handled in the field definitions.
*/
- { .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
+ { .name = "MAIR0", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
offsetof(CPUARMState, cp15.mair0_ns) },
.resetfn = arm_cp_reset_ignore },
- { .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
+ { .name = "MAIR1", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
offsetof(CPUARMState, cp15.mair1_ns) },
@@ -2088,16 +2096,14 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
};
static const ARMCPRegInfo lpae_cp_reginfo[] = {
- /* NOP AMAIR0/1: the override is because these clash with the rather
- * broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
- */
+ /* NOP AMAIR0/1 */
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
+ .access = PL1_RW, .type = ARM_CP_CONST,
.resetvalue = 0 },
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
+ .access = PL1_RW, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
.access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 02/22] target-arm: Add MAIR_EL2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 01/22] target-arm: Break down TLB_LOCKDOWN Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 03/22] target-arm: Add TCR_EL2 Peter Maydell
` (20 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-4-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a0b414c..427cfab 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2517,6 +2517,13 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
{ .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
+ .access = PL2_RW, .type = ARM_CP_CONST,
+ .resetvalue = 0 },
+ { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
+ .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -2588,6 +2595,14 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
.access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]) },
+ { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
+ .resetvalue = 0 },
+ { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
+ .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
+ .access = PL2_RW, .type = ARM_CP_ALIAS,
+ .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 03/22] target-arm: Add TCR_EL2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 01/22] target-arm: Break down TLB_LOCKDOWN Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 02/22] target-arm: Add MAIR_EL2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 04/22] target-arm: Add SCTLR_EL2 Peter Maydell
` (19 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-5-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 427cfab..7dadc8a 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2524,6 +2524,9 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
{ .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
.opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -2603,6 +2606,11 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
.access = PL2_RW, .type = ARM_CP_ALIAS,
.fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
+ { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
+ .access = PL2_RW, .writefn = vmsa_tcr_el1_write,
+ .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 04/22] target-arm: Add SCTLR_EL2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 03/22] target-arm: Add TCR_EL2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 05/22] target-arm: Add TPIDR_EL2 Peter Maydell
` (18 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-6-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7dadc8a..334e008 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2527,6 +2527,9 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
{ .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -2611,6 +2614,10 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.access = PL2_RW, .writefn = vmsa_tcr_el1_write,
.resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
+ { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 05/22] target-arm: Add TPIDR_EL2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 04/22] target-arm: Add SCTLR_EL2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 06/22] target-arm: Add TTBR0_EL2 Peter Maydell
` (17 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-7-git-send-email-edgar.iglesias@gmail.com
[PMM: reordered fields into preferred opc0/opc1/crn/crm/opc2 order]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 334e008..27cfd12 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2530,6 +2530,9 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -2618,6 +2621,10 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
.access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
.fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) },
+ { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
+ .access = PL2_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 06/22] target-arm: Add TTBR0_EL2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 05/22] target-arm: Add TPIDR_EL2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 07/22] target-arm: Add TLBI_ALLE1{IS} Peter Maydell
` (16 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-8-git-send-email-edgar.iglesias@gmail.com
[PMM: Switch to preferred opc1/crm order for 64-bit AArch32 cpregs;
drop unneeded use of vmsa_ttbr_writefn]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 27cfd12..54c7041 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2533,6 +2533,12 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
{ .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
+ .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -2625,6 +2631,14 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
.access = PL2_RW, .resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
+ { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
+ { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
+ .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
+ .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 07/22] target-arm: Add TLBI_ALLE1{IS}
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 06/22] target-arm: Add TTBR0_EL2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 08/22] target-arm: Add TLBI_ALLE2 Peter Maydell
` (15 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-9-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 54c7041..5505ba5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2368,6 +2368,14 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
.access = PL1_W, .type = ARM_CP_NOP },
/* TLBI operations */
+ { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbiall_write },
+ { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
+ .writefn = tlbiall_write },
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
.access = PL1_W, .type = ARM_CP_NO_RAW,
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 08/22] target-arm: Add TLBI_ALLE2
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 07/22] target-arm: Add TLBI_ALLE1{IS} Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 09/22] target-arm: Add TLBI_VAE2{IS} Peter Maydell
` (14 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-10-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5505ba5..f73fced 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2647,6 +2647,10 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
.resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
+ { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbiall_write },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 09/22] target-arm: Add TLBI_VAE2{IS}
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (7 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 08/22] target-arm: Add TLBI_ALLE2 Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 10/22] Revert "target-arm: Avoid g_hash_table_get_keys()" Peter Maydell
` (13 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1432881807-18164-11-git-send-email-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f73fced..7214d99 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2651,6 +2651,14 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
.type = ARM_CP_NO_RAW, .access = PL2_W,
.writefn = tlbiall_write },
+ { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbi_aa64_vaa_write },
+ { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
+ .writefn = tlbi_aa64_vaa_write },
REGINFO_SENTINEL
};
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 10/22] Revert "target-arm: Avoid g_hash_table_get_keys()"
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (8 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 09/22] target-arm: Add TLBI_VAE2{IS} Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 11/22] target-arm: Add GIC phandle to VirtBoardInfo Peter Maydell
` (12 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Markus Armbruster <armbru@redhat.com>
Since we now require GLib 2.22+ (commit f40685c), we don't have to
work around lack of g_hash_table_get_keys() anymore.
This reverts commit 82a3a11897308b606120f7235001e87809708f85.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1432749090-4698-1-git-send-email-armbru@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7214d99..0cf446e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -294,23 +294,15 @@ static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
return 0;
}
-static void cpreg_make_keylist(gpointer key, gpointer value, gpointer udata)
-{
- GList **plist = udata;
-
- *plist = g_list_prepend(*plist, key);
-}
-
void init_cpreg_list(ARMCPU *cpu)
{
/* Initialise the cpreg_tuples[] array based on the cp_regs hash.
* Note that we require cpreg_tuples[] to be sorted by key ID.
*/
- GList *keys = NULL;
+ GList *keys;
int arraylen;
- g_hash_table_foreach(cpu->cp_regs, cpreg_make_keylist, &keys);
-
+ keys = g_hash_table_get_keys(cpu->cp_regs);
keys = g_list_sort(keys, cpreg_key_compare);
cpu->cpreg_array_len = 0;
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 11/22] target-arm: Add GIC phandle to VirtBoardInfo
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (9 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 10/22] Revert "target-arm: Avoid g_hash_table_get_keys()" Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 12/22] arm_gicv2m: Add GICv2m widget to support MSIs Peter Maydell
` (11 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Christoffer Dall <christoffer.dall@linaro.org>
Instead of passing the GIC phandle around between functions, add it to
the VirtBoardInfo just like we do for the clock_phandle. We are about
to add the v2m phandle as well, and it's easier not having to pass
around a bunch of phandles, return multiple values from functions, etc.
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1432897270-7780-2-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 05db8cb..e5235ef 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -69,6 +69,7 @@ typedef struct VirtBoardInfo {
void *fdt;
int fdt_size;
uint32_t clock_phandle;
+ uint32_t gic_phandle;
} VirtBoardInfo;
typedef struct {
@@ -299,12 +300,11 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
}
}
-static uint32_t fdt_add_gic_node(const VirtBoardInfo *vbi)
+static void fdt_add_gic_node(VirtBoardInfo *vbi)
{
- uint32_t gic_phandle;
- gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
- qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
+ vbi->gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+ qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", vbi->gic_phandle);
qemu_fdt_add_subnode(vbi->fdt, "/intc");
/* 'cortex-a15-gic' means 'GIC v2' */
@@ -317,12 +317,10 @@ static uint32_t fdt_add_gic_node(const VirtBoardInfo *vbi)
2, vbi->memmap[VIRT_GIC_DIST].size,
2, vbi->memmap[VIRT_GIC_CPU].base,
2, vbi->memmap[VIRT_GIC_CPU].size);
- qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
-
- return gic_phandle;
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
}
-static uint32_t create_gic(const VirtBoardInfo *vbi, qemu_irq *pic)
+static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
{
/* We create a standalone GIC v2 */
DeviceState *gicdev;
@@ -371,7 +369,7 @@ static uint32_t create_gic(const VirtBoardInfo *vbi, qemu_irq *pic)
pic[i] = qdev_get_gpio_in(gicdev, i);
}
- return fdt_add_gic_node(vbi);
+ fdt_add_gic_node(vbi);
}
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
@@ -618,8 +616,7 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
0x7 /* PCI irq */);
}
-static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
- uint32_t gic_phandle)
+static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
{
hwaddr base_mmio = vbi->memmap[VIRT_PCIE_MMIO].base;
hwaddr size_mmio = vbi->memmap[VIRT_PCIE_MMIO].size;
@@ -685,7 +682,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
2, base_mmio, 2, size_mmio);
qemu_fdt_setprop_cell(vbi->fdt, nodename, "#interrupt-cells", 1);
- create_pcie_irq_map(vbi, gic_phandle, irq, nodename);
+ create_pcie_irq_map(vbi, vbi->gic_phandle, irq, nodename);
g_free(nodename);
}
@@ -717,7 +714,6 @@ static void machvirt_init(MachineState *machine)
VirtBoardInfo *vbi;
VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
VirtGuestInfo *guest_info = &guest_info_state->info;
- uint32_t gic_phandle;
char **cpustr;
if (!cpu_model) {
@@ -794,13 +790,13 @@ static void machvirt_init(MachineState *machine)
create_flash(vbi);
- gic_phandle = create_gic(vbi, pic);
+ create_gic(vbi, pic);
create_uart(vbi, pic);
create_rtc(vbi, pic);
- create_pcie(vbi, pic, gic_phandle);
+ create_pcie(vbi, pic);
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 12/22] arm_gicv2m: Add GICv2m widget to support MSIs
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (10 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 11/22] target-arm: Add GIC phandle to VirtBoardInfo Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 13/22] target-arm: Extend the gic node properties Peter Maydell
` (10 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Christoffer Dall <christoffer.dall@linaro.org>
The ARM GICv2m widget is a little device that handles MSI interrupt
writes to a trigger register and ties them to a range of interrupt lines
wires to the GIC. It has a few status/id registers and the interrupt wires,
and that's about it.
A board instantiates the device by setting the base SPI number and
number SPIs for the frame. The base-spi parameter is indexed in the SPI
number space only, so base-spi == 0, means IRQ number 32. When a device
(the PCI host controller) writes to the trigger register, the payload is
the GIC IRQ number, so we have to subtract 32 from that and then index
into our frame of SPIs.
When instantiating a GICv2m device, tell PCI that we have instantiated
something that can deal with MSIs. We rely on the board actually wiring
up the GICv2m to the PCI host controller.
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1432897270-7780-3-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/intc/Makefile.objs | 1 +
hw/intc/arm_gicv2m.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 191 insertions(+)
create mode 100644 hw/intc/arm_gicv2m.c
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 843864a..092d8a8 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
+common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
common-obj-$(CONFIG_OPENPIC) += openpic.o
obj-$(CONFIG_APIC) += apic.o apic_common.o
diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c
new file mode 100644
index 0000000..9f84f72
--- /dev/null
+++ b/hw/intc/arm_gicv2m.c
@@ -0,0 +1,190 @@
+/*
+ * GICv2m extension for MSI/MSI-x support with a GICv2-based system
+ *
+ * Copyright (C) 2015 Linaro, All rights reserved.
+ *
+ * Author: Christoffer Dall <christoffer.dall@linaro.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file implements an emulated GICv2m widget as described in the ARM
+ * Server Base System Architecture (SBSA) specification Version 2.2
+ * (ARM-DEN-0029 v2.2) pages 35-39 without any optional implementation defined
+ * identification registers and with a single non-secure MSI register frame.
+ */
+
+#include "hw/sysbus.h"
+#include "hw/pci/msi.h"
+
+#define TYPE_ARM_GICV2M "arm-gicv2m"
+#define ARM_GICV2M(obj) OBJECT_CHECK(ARMGICv2mState, (obj), TYPE_ARM_GICV2M)
+
+#define GICV2M_NUM_SPI_MAX 128
+
+#define V2M_MSI_TYPER 0x008
+#define V2M_MSI_SETSPI_NS 0x040
+#define V2M_MSI_IIDR 0xFCC
+#define V2M_IIDR0 0xFD0
+#define V2M_IIDR11 0xFFC
+
+#define PRODUCT_ID_QEMU 0x51 /* ASCII code Q */
+
+typedef struct ARMGICv2mState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq spi[GICV2M_NUM_SPI_MAX];
+
+ uint32_t base_spi;
+ uint32_t num_spi;
+} ARMGICv2mState;
+
+static void gicv2m_set_irq(void *opaque, int irq)
+{
+ ARMGICv2mState *s = (ARMGICv2mState *)opaque;
+
+ qemu_irq_pulse(s->spi[irq]);
+}
+
+static uint64_t gicv2m_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ ARMGICv2mState *s = (ARMGICv2mState *)opaque;
+ uint32_t val;
+
+ if (size != 4) {
+ qemu_log_mask(LOG_GUEST_ERROR, "gicv2m_read: bad size %u\n", size);
+ return 0;
+ }
+
+ switch (offset) {
+ case V2M_MSI_TYPER:
+ val = (s->base_spi + 32) << 16;
+ val |= s->num_spi;
+ return val;
+ case V2M_MSI_IIDR:
+ /* We don't have any valid implementor so we leave that field as zero
+ * and we return 0 in the arch revision as per the spec.
+ */
+ return (PRODUCT_ID_QEMU << 20);
+ case V2M_IIDR0 ... V2M_IIDR11:
+ /* We do not implement any optional identification registers and the
+ * mandatory MSI_PIDR2 register reads as 0x0, so we capture all
+ * implementation defined registers here.
+ */
+ return 0;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gicv2m_read: Bad offset %x\n", (int)offset);
+ return 0;
+ }
+}
+
+static void gicv2m_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ ARMGICv2mState *s = (ARMGICv2mState *)opaque;
+
+ if (size != 2 && size != 4) {
+ qemu_log_mask(LOG_GUEST_ERROR, "gicv2m_write: bad size %u\n", size);
+ return;
+ }
+
+ switch (offset) {
+ case V2M_MSI_SETSPI_NS: {
+ int spi;
+
+ spi = (value & 0x3ff) - (s->base_spi + 32);
+ if (spi >= 0 && spi < s->num_spi) {
+ gicv2m_set_irq(s, spi);
+ }
+ return;
+ }
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gicv2m_write: Bad offset %x\n", (int)offset);
+ }
+}
+
+static const MemoryRegionOps gicv2m_ops = {
+ .read = gicv2m_read,
+ .write = gicv2m_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void gicv2m_realize(DeviceState *dev, Error **errp)
+{
+ ARMGICv2mState *s = ARM_GICV2M(dev);
+ int i;
+
+ if (s->num_spi > GICV2M_NUM_SPI_MAX) {
+ error_setg(errp,
+ "requested %u SPIs exceeds GICv2m frame maximum %d",
+ s->num_spi, GICV2M_NUM_SPI_MAX);
+ return;
+ }
+
+ if (s->base_spi + 32 > 1020 - s->num_spi) {
+ error_setg(errp,
+ "requested base SPI %u+%u exceeds max. number 1020",
+ s->base_spi + 32, s->num_spi);
+ return;
+ }
+
+ for (i = 0; i < s->num_spi; i++) {
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->spi[i]);
+ }
+
+ msi_supported = true;
+}
+
+static void gicv2m_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ ARMGICv2mState *s = ARM_GICV2M(obj);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &gicv2m_ops, s,
+ "gicv2m", 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static Property gicv2m_properties[] = {
+ DEFINE_PROP_UINT32("base-spi", ARMGICv2mState, base_spi, 0),
+ DEFINE_PROP_UINT32("num-spi", ARMGICv2mState, num_spi, 64),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void gicv2m_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = gicv2m_properties;
+ dc->realize = gicv2m_realize;
+}
+
+static const TypeInfo gicv2m_info = {
+ .name = TYPE_ARM_GICV2M,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(ARMGICv2mState),
+ .instance_init = gicv2m_init,
+ .class_init = gicv2m_class_init,
+};
+
+static void gicv2m_register_types(void)
+{
+ type_register_static(&gicv2m_info);
+}
+
+type_init(gicv2m_register_types)
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 13/22] target-arm: Extend the gic node properties
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (11 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 12/22] arm_gicv2m: Add GICv2m widget to support MSIs Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 14/22] target-arm: Add the GICv2m to the virt board Peter Maydell
` (9 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Christoffer Dall <christoffer.dall@linaro.org>
In preparation for adding the GICv2m which requires address specifiers
and is a subnode of the gic, we extend the gic DT definition to specify
the #address-cells and #size-cells properties and add an empty ranges
property properties of the DT node, since this is required to add the
v2m node as a child of the gic node.
Note that we must also expand the irq-map to reference the gic with the
right address-cells as a consequence of this change.
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1432897270-7780-4-git-send-email-christoffer.dall@linaro.org
Suggested-by: Shanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e5235ef..387dac8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -317,6 +317,9 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi)
2, vbi->memmap[VIRT_GIC_DIST].size,
2, vbi->memmap[VIRT_GIC_CPU].base,
2, vbi->memmap[VIRT_GIC_CPU].size);
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#address-cells", 0x2);
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#size-cells", 0x2);
+ qemu_fdt_setprop(vbi->fdt, "/intc", "ranges", NULL, 0);
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
}
@@ -585,7 +588,7 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
int first_irq, const char *nodename)
{
int devfn, pin;
- uint32_t full_irq_map[4 * 4 * 8] = { 0 };
+ uint32_t full_irq_map[4 * 4 * 10] = { 0 };
uint32_t *irq_map = full_irq_map;
for (devfn = 0; devfn <= 0x18; devfn += 0x8) {
@@ -598,13 +601,13 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
uint32_t map[] = {
devfn << 8, 0, 0, /* devfn */
pin + 1, /* PCI pin */
- gic_phandle, irq_type, irq_nr, irq_level }; /* GIC irq */
+ gic_phandle, 0, 0, irq_type, irq_nr, irq_level }; /* GIC irq */
/* Convert map to big endian */
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 10; i++) {
irq_map[i] = cpu_to_be32(map[i]);
}
- irq_map += 8;
+ irq_map += 10;
}
}
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 14/22] target-arm: Add the GICv2m to the virt board
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (12 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 13/22] target-arm: Extend the gic node properties Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 15/22] pl061: fix wrong calculation of GPIOMIS register Peter Maydell
` (8 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Christoffer Dall <christoffer.dall@linaro.org>
Add a GICv2m device to the virt board to enable MSIs on the generic PCI
host controller. We allocate 64 SPIs in the IRQ space for now (this can
be increased/decreased later) and map the GICv2m right after the GIC in
the memory map.
Reviewed-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1432897270-7780-5-git-send-email-christoffer.dall@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 40 +++++++++++++++++++++++++++++++++++++++-
include/hw/arm/virt.h | 2 ++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 387dac8..4bb7175 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -70,6 +70,7 @@ typedef struct VirtBoardInfo {
int fdt_size;
uint32_t clock_phandle;
uint32_t gic_phandle;
+ uint32_t v2m_phandle;
} VirtBoardInfo;
typedef struct {
@@ -109,6 +110,7 @@ static const MemMapEntry a15memmap[] = {
/* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
[VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
[VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
+ [VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
[VIRT_UART] = { 0x09000000, 0x00001000 },
[VIRT_RTC] = { 0x09010000, 0x00001000 },
[VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
@@ -125,6 +127,7 @@ static const int a15irqmap[] = {
[VIRT_RTC] = 2,
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
+ [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
};
static VirtBoardInfo machines[] = {
@@ -300,9 +303,21 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
}
}
-static void fdt_add_gic_node(VirtBoardInfo *vbi)
+static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
{
+ vbi->v2m_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+ qemu_fdt_add_subnode(vbi->fdt, "/intc/v2m");
+ qemu_fdt_setprop_string(vbi->fdt, "/intc/v2m", "compatible",
+ "arm,gic-v2m-frame");
+ qemu_fdt_setprop(vbi->fdt, "/intc/v2m", "msi-controller", NULL, 0);
+ qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc/v2m", "reg",
+ 2, vbi->memmap[VIRT_GIC_V2M].base,
+ 2, vbi->memmap[VIRT_GIC_V2M].size);
+ qemu_fdt_setprop_cell(vbi->fdt, "/intc/v2m", "phandle", vbi->v2m_phandle);
+}
+static void fdt_add_gic_node(VirtBoardInfo *vbi)
+{
vbi->gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", vbi->gic_phandle);
@@ -323,6 +338,25 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi)
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
}
+static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ int i;
+ int irq = vbi->irqmap[VIRT_GIC_V2M];
+ DeviceState *dev;
+
+ dev = qdev_create(NULL, "arm-gicv2m");
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vbi->memmap[VIRT_GIC_V2M].base);
+ qdev_prop_set_uint32(dev, "base-spi", irq);
+ qdev_prop_set_uint32(dev, "num-spi", NUM_GICV2M_SPIS);
+ qdev_init_nofail(dev);
+
+ for (i = 0; i < NUM_GICV2M_SPIS; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
+ }
+
+ fdt_add_v2m_gic_node(vbi);
+}
+
static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
{
/* We create a standalone GIC v2 */
@@ -373,6 +407,8 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic)
}
fdt_add_gic_node(vbi);
+
+ create_v2m(vbi, pic);
}
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
@@ -676,6 +712,8 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0,
nr_pcie_buses - 1);
+ qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent", vbi->v2m_phandle);
+
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
2, base_ecam, 2, size_ecam);
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index ceec8b3..003ef29 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -32,6 +32,7 @@
#include "qemu-common.h"
+#define NUM_GICV2M_SPIS 64
#define NUM_VIRTIO_TRANSPORTS 32
#define ARCH_TIMER_VIRT_IRQ 11
@@ -53,6 +54,7 @@ enum {
VIRT_PCIE_MMIO,
VIRT_PCIE_PIO,
VIRT_PCIE_ECAM,
+ VIRT_GIC_V2M,
};
typedef struct MemMapEntry {
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 15/22] pl061: fix wrong calculation of GPIOMIS register
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (13 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 14/22] target-arm: Add the GICv2m to the virt board Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 16/22] kvm: introduce kvm_arch_msi_data_to_gsi Peter Maydell
` (7 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Victor CLEMENT <victor.clement@openwide.fr>
The masked interrupt status register should be the state of the interrupt
after masking.
There should be a logical AND instead of a logical OR between the
interrupt status and the interrupt mask.
Signed-off-by: Victor CLEMENT <victor.clement@openwide.fr>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1433154824-6927-1-git-send-email-victor.clement@openwide.fr
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/gpio/pl061.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index bd03e99..4ba730b 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -173,7 +173,7 @@ static uint64_t pl061_read(void *opaque, hwaddr offset,
case 0x414: /* Raw interrupt status */
return s->istate;
case 0x418: /* Masked interrupt status */
- return s->istate | s->im;
+ return s->istate & s->im;
case 0x420: /* Alternate function select */
return s->afsel;
case 0x500: /* 2mA drive */
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 16/22] kvm: introduce kvm_arch_msi_data_to_gsi
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (14 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 15/22] pl061: fix wrong calculation of GPIOMIS register Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 17/22] arm_gicv2m: set kvm_gsi_direct_mapping and kvm_msi_via_irqfd_allowed Peter Maydell
` (6 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
On ARM the MSI data corresponds to the shared peripheral interrupt (SPI)
ID. This latter equals to the SPI index + 32. to retrieve the SPI index,
matching the gsi, an architecture specific function is introduced.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/sysemu/kvm.h | 2 ++
kvm-all.c | 2 +-
target-arm/kvm.c | 5 +++++
target-i386/kvm.c | 5 +++++
target-mips/kvm.c | 5 +++++
target-ppc/kvm.c | 5 +++++
target-s390x/kvm.c | 5 +++++
7 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4878959..f459fbd 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -287,6 +287,8 @@ void kvm_arch_init_irq_routing(KVMState *s);
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
uint64_t address, uint32_t data);
+int kvm_arch_msi_data_to_gsi(uint32_t data);
+
int kvm_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
diff --git a/kvm-all.c b/kvm-all.c
index 17a3771..b2b1bc3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1228,7 +1228,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
int virq;
if (kvm_gsi_direct_mapping()) {
- return msg.data & 0xffff;
+ return kvm_arch_msi_data_to_gsi(msg.data);
}
if (!kvm_gsi_routing_enabled()) {
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 16abbf1..548bfd7 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -600,3 +600,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
{
return 0;
}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ return (data - 32) & 0xffff;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a26d25a..ca2da84 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2766,3 +2766,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
{
return 0;
}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ abort();
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 59eb111..948619f 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -696,3 +696,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
{
return 0;
}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ abort();
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 1da9ea8..8f7cee5 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2410,3 +2410,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
{
return 0;
}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ return data & 0xffff;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 6de7759..2740ec4 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -2216,3 +2216,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
route->u.adapter.adapter_id = pbdev->routes.adapter.adapter_id;
return 0;
}
+
+int kvm_arch_msi_data_to_gsi(uint32_t data)
+{
+ abort();
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 17/22] arm_gicv2m: set kvm_gsi_direct_mapping and kvm_msi_via_irqfd_allowed
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (15 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 16/22] kvm: introduce kvm_arch_msi_data_to_gsi Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 18/22] target-arm: Remove v8_ prefix from names of non-v8-specific cpreg arrays Peter Maydell
` (5 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
After introduction of kvm_arch_msi_data_to_gsi, kvm_gsi_direct_mapping
now can be set on ARM. Also kvm_msi_via_irqfd_allowed can be set,
depending on kernel irqfd support, hence enabling VIRTIO-PCI with
vhost back-end.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/intc/arm_gicv2m.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c
index 9f84f72..43d1976 100644
--- a/hw/intc/arm_gicv2m.c
+++ b/hw/intc/arm_gicv2m.c
@@ -148,6 +148,8 @@ static void gicv2m_realize(DeviceState *dev, Error **errp)
}
msi_supported = true;
+ kvm_gsi_direct_mapping = true;
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
}
static void gicv2m_init(Object *obj)
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 18/22] target-arm: Remove v8_ prefix from names of non-v8-specific cpreg arrays
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (16 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 17/22] arm_gicv2m: set kvm_gsi_direct_mapping and kvm_msi_via_irqfd_allowed Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 19/22] hw/arm/sysbus-fdt: helpers for platform bus nodes addition Peter Maydell
` (4 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
The ARMCPRegInfo arrays v8_el3_no_el2_cp_reginfo and v8_el2_cp_reginfo
are actually used on non-v8 CPUs as well. Remove the incorrect v8_
prefix from their names.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1433182716-6400-1-git-send-email-peter.maydell@linaro.org
---
target-arm/helper.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0cf446e..3da0c05 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2504,7 +2504,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
};
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
-static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] = {
+static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
{ .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
.access = PL2_RW,
@@ -2567,7 +2567,7 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
raw_write(env, ri, value);
}
-static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
+static const ARMCPRegInfo el2_cp_reginfo[] = {
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
@@ -3312,7 +3312,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, v8_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_EL2)) {
- define_arm_cp_regs(cpu, v8_el2_cp_reginfo);
+ define_arm_cp_regs(cpu, el2_cp_reginfo);
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
if (!arm_feature(env, ARM_FEATURE_EL3)) {
ARMCPRegInfo rvbar = {
@@ -3327,7 +3327,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
* register the no_el2 reginfos.
*/
if (arm_feature(env, ARM_FEATURE_EL3)) {
- define_arm_cp_regs(cpu, v8_el3_no_el2_cp_reginfo);
+ define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
}
}
if (arm_feature(env, ARM_FEATURE_EL3)) {
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 19/22] hw/arm/sysbus-fdt: helpers for platform bus nodes addition
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (17 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 18/22] target-arm: Remove v8_ prefix from names of non-v8-specific cpreg arrays Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier Peter Maydell
` (3 subsequent siblings)
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
This new C module will be used by ARM machine files to generate
platform bus node and their dynamic sysbus device tree nodes.
Dynamic sysbus device node addition is done in a machine init
done notifier. arm_register_platform_bus_fdt_creator does the
registration of this latter and is supposed to be called by
ARM machine files that support platform bus and their dynamic
sysbus. Addition of dynamic sysbus nodes is done only if the
user did not provide any dtb.
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 1433244554-12898-2-git-send-email-eric.auger@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Makefile.objs | 1 +
hw/arm/sysbus-fdt.c | 174 ++++++++++++++++++++++++++++++++++++++++++++
include/hw/arm/sysbus-fdt.h | 60 +++++++++++++++
3 files changed, 235 insertions(+)
create mode 100644 hw/arm/sysbus-fdt.c
create mode 100644 include/hw/arm/sysbus-fdt.h
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4b09caf..cf346c1 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,6 +5,7 @@ obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
obj-$(CONFIG_ACPI) += virt-acpi-build.o
obj-y += netduino2.o
+obj-y += sysbus-fdt.o
obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
new file mode 100644
index 0000000..3038b94
--- /dev/null
+++ b/hw/arm/sysbus-fdt.c
@@ -0,0 +1,174 @@
+/*
+ * ARM Platform Bus device tree generation helpers
+ *
+ * Copyright (c) 2014 Linaro Limited
+ *
+ * Authors:
+ * Alex Graf <agraf@suse.de>
+ * Eric Auger <eric.auger@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw/arm/sysbus-fdt.h"
+#include "qemu/error-report.h"
+#include "sysemu/device_tree.h"
+#include "hw/platform-bus.h"
+#include "sysemu/sysemu.h"
+
+/*
+ * internal struct that contains the information to create dynamic
+ * sysbus device node
+ */
+typedef struct PlatformBusFDTData {
+ void *fdt; /* device tree handle */
+ int irq_start; /* index of the first IRQ usable by platform bus devices */
+ const char *pbus_node_name; /* name of the platform bus node */
+ PlatformBusDevice *pbus;
+} PlatformBusFDTData;
+
+/*
+ * struct used when calling the machine init done notifier
+ * that constructs the fdt nodes of platform bus devices
+ */
+typedef struct PlatformBusFDTNotifierParams {
+ Notifier notifier;
+ ARMPlatformBusFDTParams *fdt_params;
+} PlatformBusFDTNotifierParams;
+
+/* struct that associates a device type name and a node creation function */
+typedef struct NodeCreationPair {
+ const char *typename;
+ int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque);
+} NodeCreationPair;
+
+/* list of supported dynamic sysbus devices */
+static const NodeCreationPair add_fdt_node_functions[] = {
+ {"", NULL}, /* last element */
+};
+
+/**
+ * add_fdt_node - add the device tree node of a dynamic sysbus device
+ *
+ * @sbdev: handle to the sysbus device
+ * @opaque: handle to the PlatformBusFDTData
+ *
+ * Checks the sysbus type belongs to the list of device types that
+ * are dynamically instantiable and if so call the node creation
+ * function.
+ */
+static int add_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) {
+ if (!strcmp(object_get_typename(OBJECT(sbdev)),
+ add_fdt_node_functions[i].typename)) {
+ ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque);
+ assert(!ret);
+ return 0;
+ }
+ }
+ error_report("Device %s can not be dynamically instantiated",
+ qdev_fw_name(DEVICE(sbdev)));
+ exit(1);
+}
+
+/**
+ * add_all_platform_bus_fdt_nodes - create all the platform bus nodes
+ *
+ * builds the parent platform bus node and all the nodes of dynamic
+ * sysbus devices attached to it.
+ */
+static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
+{
+ const char platcomp[] = "qemu,platform\0simple-bus";
+ PlatformBusDevice *pbus;
+ DeviceState *dev;
+ gchar *node;
+ uint64_t addr, size;
+ int irq_start, dtb_size;
+ struct arm_boot_info *info = fdt_params->binfo;
+ const ARMPlatformBusSystemParams *params = fdt_params->system_params;
+ const char *intc = fdt_params->intc;
+ void *fdt = info->get_dtb(info, &dtb_size);
+
+ /*
+ * If the user provided a dtb, we assume the dynamic sysbus nodes
+ * already are integrated there. This corresponds to a use case where
+ * the dynamic sysbus nodes are complex and their generation is not yet
+ * supported. In that case the user can take charge of the guest dt
+ * while qemu takes charge of the qom stuff.
+ */
+ if (info->dtb_filename) {
+ return;
+ }
+
+ assert(fdt);
+
+ node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base);
+ addr = params->platform_bus_base;
+ size = params->platform_bus_size;
+ irq_start = params->platform_bus_first_irq;
+
+ /* Create a /platform node that we can put all devices into */
+ qemu_fdt_add_subnode(fdt, node);
+ qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp));
+
+ /* Our platform bus region is less than 32bits, so 1 cell is enough for
+ * address and size
+ */
+ qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1);
+ qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1);
+ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size);
+
+ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc);
+
+ dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
+ pbus = PLATFORM_BUS_DEVICE(dev);
+
+ /* We can only create dt nodes for dynamic devices when they're ready */
+ assert(pbus->done_gathering);
+
+ PlatformBusFDTData data = {
+ .fdt = fdt,
+ .irq_start = irq_start,
+ .pbus_node_name = node,
+ .pbus = pbus,
+ };
+
+ /* Loop through all dynamic sysbus devices and create their node */
+ foreach_dynamic_sysbus_device(add_fdt_node, &data);
+
+ g_free(node);
+}
+
+static void platform_bus_fdt_notify(Notifier *notifier, void *data)
+{
+ PlatformBusFDTNotifierParams *p = DO_UPCAST(PlatformBusFDTNotifierParams,
+ notifier, notifier);
+
+ add_all_platform_bus_fdt_nodes(p->fdt_params);
+ g_free(p->fdt_params);
+ g_free(p);
+}
+
+void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params)
+{
+ PlatformBusFDTNotifierParams *p = g_new(PlatformBusFDTNotifierParams, 1);
+
+ p->fdt_params = fdt_params;
+ p->notifier.notify = platform_bus_fdt_notify;
+ qemu_add_machine_init_done_notifier(&p->notifier);
+}
diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/arm/sysbus-fdt.h
new file mode 100644
index 0000000..e15bb81
--- /dev/null
+++ b/include/hw/arm/sysbus-fdt.h
@@ -0,0 +1,60 @@
+/*
+ * Dynamic sysbus device tree node generation API
+ *
+ * Copyright Linaro Limited, 2014
+ *
+ * Authors:
+ * Alex Graf <agraf@suse.de>
+ * Eric Auger <eric.auger@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef HW_ARM_SYSBUS_FDT_H
+#define HW_ARM_SYSBUS_FDT_H
+
+#include "hw/arm/arm.h"
+#include "qemu-common.h"
+#include "hw/sysbus.h"
+
+/*
+ * struct that contains dimensioning parameters of the platform bus
+ */
+typedef struct {
+ hwaddr platform_bus_base; /* start address of the bus */
+ hwaddr platform_bus_size; /* size of the bus */
+ int platform_bus_first_irq; /* first hwirq assigned to the bus */
+ int platform_bus_num_irqs; /* number of hwirq assigned to the bus */
+} ARMPlatformBusSystemParams;
+
+/*
+ * struct that contains all relevant info to build the fdt nodes of
+ * platform bus and attached dynamic sysbus devices
+ * in the future might be augmented with additional info
+ * such as PHY, CLK handles ...
+ */
+typedef struct {
+ const ARMPlatformBusSystemParams *system_params;
+ struct arm_boot_info *binfo;
+ const char *intc; /* parent interrupt controller name */
+} ARMPlatformBusFDTParams;
+
+/**
+ * arm_register_platform_bus_fdt_creator - register a machine init done
+ * notifier that creates the device tree nodes of the platform bus and
+ * associated dynamic sysbus devices
+ */
+void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params);
+
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (18 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 19/22] hw/arm/sysbus-fdt: helpers for platform bus nodes addition Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-12 2:54 ` Peter Crosthwaite
2015-06-02 16:33 ` [Qemu-devel] [PULL 21/22] hw/arm/virt: add dynamic sysbus device support Peter Maydell
` (2 subsequent siblings)
22 siblings, 1 reply; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
Device tree nodes for the platform bus and its children dynamic sysbus
devices are added in a machine init done notifier. To load the dtb once,
after those latter nodes are built and before ROM freeze, the actual
arm_load_kernel existing code is moved into a notifier notify function,
arm_load_kernel_notify. arm_load_kernel now only registers the
corresponding notifier.
Machine files that do not support platform bus stay unchanged. Machine
files willing to support dynamic sysbus devices must call arm_load_kernel
before sysbus-fdt arm_register_platform_bus_fdt_creator to make sure
dynamic sysbus device nodes are integrated in the dtb.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 1433244554-12898-3-git-send-email-eric.auger@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/boot.c | 14 +++++++++++++-
include/hw/arm/arm.h | 28 ++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index fa69503..d036624 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -557,7 +557,7 @@ static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
fw_cfg_add_bytes(fw_cfg, data_key, data, size);
}
-void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
+static void arm_load_kernel_notify(Notifier *notifier, void *data)
{
CPUState *cs;
int kernel_size;
@@ -568,6 +568,11 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
hwaddr entry, kernel_load_offset;
int big_endian;
static const ARMInsnFixup *primary_loader;
+ ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
+ notifier, notifier);
+ ARMCPU *cpu = n->cpu;
+ struct arm_boot_info *info =
+ container_of(n, struct arm_boot_info, load_kernel_notifier);
/* CPU objects (unlike devices) are not automatically reset on system
* reset, so we must always register a handler to do so. If we're
@@ -775,3 +780,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
ARM_CPU(cs)->env.boot_info = info;
}
}
+
+void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
+{
+ info->load_kernel_notifier.cpu = cpu;
+ info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
+ qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
+}
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 5c940eb..760804c 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -13,11 +13,21 @@
#include "exec/memory.h"
#include "hw/irq.h"
+#include "qemu/notify.h"
/* armv7m.c */
qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
const char *kernel_filename, const char *cpu_model);
+/*
+ * struct used as a parameter of the arm_load_kernel machine init
+ * done notifier
+ */
+typedef struct {
+ Notifier notifier; /* actual notifier */
+ ARMCPU *cpu; /* handle to the first cpu object */
+} ArmLoadKernelNotifier;
+
/* arm_boot.c */
struct arm_boot_info {
uint64_t ram_size;
@@ -64,6 +74,8 @@ struct arm_boot_info {
* the user it should implement this hook.
*/
void (*modify_dtb)(const struct arm_boot_info *info, void *fdt);
+ /* machine init done notifier executing arm_load_dtb */
+ ArmLoadKernelNotifier load_kernel_notifier;
/* Used internally by arm_boot.c */
int is_linux;
hwaddr initrd_start;
@@ -75,6 +87,22 @@ struct arm_boot_info {
*/
bool firmware_loaded;
};
+
+/**
+ * arm_load_kernel - Loads memory with everything needed to boot
+ *
+ * @cpu: handle to the first CPU object
+ * @info: handle to the boot info struct
+ * Registers a machine init done notifier that copies to memory
+ * everything needed to boot, depending on machine and user options:
+ * kernel image, boot loaders, initrd, dtb. Also registers the CPU
+ * reset handler.
+ *
+ * In case the machine file supports the platform bus device and its
+ * dynamically instantiable sysbus devices, this function must be called
+ * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the
+ * machine init done notifiers are called in registration reverse order.
+ */
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
/* Multiplication factor to convert from system clock ticks to qemu timer
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-02 16:33 ` [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier Peter Maydell
@ 2015-06-12 2:54 ` Peter Crosthwaite
2015-06-12 8:25 ` Eric Auger
0 siblings, 1 reply; 31+ messages in thread
From: Peter Crosthwaite @ 2015-06-12 2:54 UTC (permalink / raw)
To: Peter Maydell, Eric Auger, Shannon Zhao, Alexander Graf,
Alex Bennée
Cc: qemu-devel@nongnu.org Developers
On Tue, Jun 2, 2015 at 9:33 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> From: Eric Auger <eric.auger@linaro.org>
>
> Device tree nodes for the platform bus and its children dynamic sysbus
> devices are added in a machine init done notifier. To load the dtb once,
> after those latter nodes are built and before ROM freeze, the actual
> arm_load_kernel existing code is moved into a notifier notify function,
> arm_load_kernel_notify. arm_load_kernel now only registers the
> corresponding notifier.
>
Does this work? I am experiencing a regression on this patch for
xlnx-ep108 board. I think it is because this is now delaying
arm_load_kernel_notify call until after rom_load_all. From vl.c:
if (rom_load_all() != 0) {
fprintf(stderr, "rom loading failed\n");
exit(1);
}
/* TODO: once all bus devices are qdevified, this should be done
* when bus is created by qdev.c */
qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
qemu_run_machine_init_done_notifiers();
the machine_init_done_notifiers are called after the rom_load_all()
call which does the image loading. So the image-to-load registration
is too late.
Straight revert of this patch fixes the issue for me.
Regards,
Peter
> Machine files that do not support platform bus stay unchanged. Machine
> files willing to support dynamic sysbus devices must call arm_load_kernel
> before sysbus-fdt arm_register_platform_bus_fdt_creator to make sure
> dynamic sysbus device nodes are integrated in the dtb.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
> Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
> Reviewed-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Message-id: 1433244554-12898-3-git-send-email-eric.auger@linaro.org
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> hw/arm/boot.c | 14 +++++++++++++-
> include/hw/arm/arm.h | 28 ++++++++++++++++++++++++++++
> 2 files changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index fa69503..d036624 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -557,7 +557,7 @@ static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
> fw_cfg_add_bytes(fw_cfg, data_key, data, size);
> }
>
> -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
> +static void arm_load_kernel_notify(Notifier *notifier, void *data)
> {
> CPUState *cs;
> int kernel_size;
> @@ -568,6 +568,11 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
> hwaddr entry, kernel_load_offset;
> int big_endian;
> static const ARMInsnFixup *primary_loader;
> + ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
> + notifier, notifier);
> + ARMCPU *cpu = n->cpu;
> + struct arm_boot_info *info =
> + container_of(n, struct arm_boot_info, load_kernel_notifier);
>
> /* CPU objects (unlike devices) are not automatically reset on system
> * reset, so we must always register a handler to do so. If we're
> @@ -775,3 +780,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
> ARM_CPU(cs)->env.boot_info = info;
> }
> }
> +
> +void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
> +{
> + info->load_kernel_notifier.cpu = cpu;
> + info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
> + qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
> +}
> diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
> index 5c940eb..760804c 100644
> --- a/include/hw/arm/arm.h
> +++ b/include/hw/arm/arm.h
> @@ -13,11 +13,21 @@
>
> #include "exec/memory.h"
> #include "hw/irq.h"
> +#include "qemu/notify.h"
>
> /* armv7m.c */
> qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
> const char *kernel_filename, const char *cpu_model);
>
> +/*
> + * struct used as a parameter of the arm_load_kernel machine init
> + * done notifier
> + */
> +typedef struct {
> + Notifier notifier; /* actual notifier */
> + ARMCPU *cpu; /* handle to the first cpu object */
> +} ArmLoadKernelNotifier;
> +
> /* arm_boot.c */
> struct arm_boot_info {
> uint64_t ram_size;
> @@ -64,6 +74,8 @@ struct arm_boot_info {
> * the user it should implement this hook.
> */
> void (*modify_dtb)(const struct arm_boot_info *info, void *fdt);
> + /* machine init done notifier executing arm_load_dtb */
> + ArmLoadKernelNotifier load_kernel_notifier;
> /* Used internally by arm_boot.c */
> int is_linux;
> hwaddr initrd_start;
> @@ -75,6 +87,22 @@ struct arm_boot_info {
> */
> bool firmware_loaded;
> };
> +
> +/**
> + * arm_load_kernel - Loads memory with everything needed to boot
> + *
> + * @cpu: handle to the first CPU object
> + * @info: handle to the boot info struct
> + * Registers a machine init done notifier that copies to memory
> + * everything needed to boot, depending on machine and user options:
> + * kernel image, boot loaders, initrd, dtb. Also registers the CPU
> + * reset handler.
> + *
> + * In case the machine file supports the platform bus device and its
> + * dynamically instantiable sysbus devices, this function must be called
> + * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the
> + * machine init done notifiers are called in registration reverse order.
> + */
> void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
>
> /* Multiplication factor to convert from system clock ticks to qemu timer
> --
> 1.9.1
>
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 2:54 ` Peter Crosthwaite
@ 2015-06-12 8:25 ` Eric Auger
2015-06-12 8:53 ` Eric Auger
0 siblings, 1 reply; 31+ messages in thread
From: Eric Auger @ 2015-06-12 8:25 UTC (permalink / raw)
To: Peter Crosthwaite, Peter Maydell, Shannon Zhao, Alexander Graf,
Alex Bennée
Cc: qemu-devel@nongnu.org Developers
Hi Peter,
On 06/12/2015 04:54 AM, Peter Crosthwaite wrote:
> On Tue, Jun 2, 2015 at 9:33 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> From: Eric Auger <eric.auger@linaro.org>
>>
>> Device tree nodes for the platform bus and its children dynamic sysbus
>> devices are added in a machine init done notifier. To load the dtb once,
>> after those latter nodes are built and before ROM freeze, the actual
>> arm_load_kernel existing code is moved into a notifier notify function,
>> arm_load_kernel_notify. arm_load_kernel now only registers the
>> corresponding notifier.
>>
>
> Does this work? I am experiencing a regression on this patch for
> xlnx-ep108 board.
Sorry for the inconvenience. On my side I tested it on virt board.
I am currently looking at the issue ...
Best Regards
Eric
I think it is because this is now delaying
> arm_load_kernel_notify call until after rom_load_all. From vl.c:
>
> if (rom_load_all() != 0) {
> fprintf(stderr, "rom loading failed\n");
> exit(1);
> }
>
> /* TODO: once all bus devices are qdevified, this should be done
> * when bus is created by qdev.c */
> qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
> qemu_run_machine_init_done_notifiers();
>
> the machine_init_done_notifiers are called after the rom_load_all()
> call which does the image loading. So the image-to-load registration
> is too late.
>
> Straight revert of this patch fixes the issue for me.
>
> Regards,
> Peter
>
>
>> Machine files that do not support platform bus stay unchanged. Machine
>> files willing to support dynamic sysbus devices must call arm_load_kernel
>> before sysbus-fdt arm_register_platform_bus_fdt_creator to make sure
>> dynamic sysbus device nodes are integrated in the dtb.
>>
>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>> Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
>> Reviewed-by: Alexander Graf <agraf@suse.de>
>> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>> Message-id: 1433244554-12898-3-git-send-email-eric.auger@linaro.org
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>> hw/arm/boot.c | 14 +++++++++++++-
>> include/hw/arm/arm.h | 28 ++++++++++++++++++++++++++++
>> 2 files changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
>> index fa69503..d036624 100644
>> --- a/hw/arm/boot.c
>> +++ b/hw/arm/boot.c
>> @@ -557,7 +557,7 @@ static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
>> fw_cfg_add_bytes(fw_cfg, data_key, data, size);
>> }
>>
>> -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>> +static void arm_load_kernel_notify(Notifier *notifier, void *data)
>> {
>> CPUState *cs;
>> int kernel_size;
>> @@ -568,6 +568,11 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>> hwaddr entry, kernel_load_offset;
>> int big_endian;
>> static const ARMInsnFixup *primary_loader;
>> + ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
>> + notifier, notifier);
>> + ARMCPU *cpu = n->cpu;
>> + struct arm_boot_info *info =
>> + container_of(n, struct arm_boot_info, load_kernel_notifier);
>>
>> /* CPU objects (unlike devices) are not automatically reset on system
>> * reset, so we must always register a handler to do so. If we're
>> @@ -775,3 +780,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>> ARM_CPU(cs)->env.boot_info = info;
>> }
>> }
>> +
>> +void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>> +{
>> + info->load_kernel_notifier.cpu = cpu;
>> + info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
>> + qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
>> +}
>> diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
>> index 5c940eb..760804c 100644
>> --- a/include/hw/arm/arm.h
>> +++ b/include/hw/arm/arm.h
>> @@ -13,11 +13,21 @@
>>
>> #include "exec/memory.h"
>> #include "hw/irq.h"
>> +#include "qemu/notify.h"
>>
>> /* armv7m.c */
>> qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
>> const char *kernel_filename, const char *cpu_model);
>>
>> +/*
>> + * struct used as a parameter of the arm_load_kernel machine init
>> + * done notifier
>> + */
>> +typedef struct {
>> + Notifier notifier; /* actual notifier */
>> + ARMCPU *cpu; /* handle to the first cpu object */
>> +} ArmLoadKernelNotifier;
>> +
>> /* arm_boot.c */
>> struct arm_boot_info {
>> uint64_t ram_size;
>> @@ -64,6 +74,8 @@ struct arm_boot_info {
>> * the user it should implement this hook.
>> */
>> void (*modify_dtb)(const struct arm_boot_info *info, void *fdt);
>> + /* machine init done notifier executing arm_load_dtb */
>> + ArmLoadKernelNotifier load_kernel_notifier;
>> /* Used internally by arm_boot.c */
>> int is_linux;
>> hwaddr initrd_start;
>> @@ -75,6 +87,22 @@ struct arm_boot_info {
>> */
>> bool firmware_loaded;
>> };
>> +
>> +/**
>> + * arm_load_kernel - Loads memory with everything needed to boot
>> + *
>> + * @cpu: handle to the first CPU object
>> + * @info: handle to the boot info struct
>> + * Registers a machine init done notifier that copies to memory
>> + * everything needed to boot, depending on machine and user options:
>> + * kernel image, boot loaders, initrd, dtb. Also registers the CPU
>> + * reset handler.
>> + *
>> + * In case the machine file supports the platform bus device and its
>> + * dynamically instantiable sysbus devices, this function must be called
>> + * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the
>> + * machine init done notifiers are called in registration reverse order.
>> + */
>> void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
>>
>> /* Multiplication factor to convert from system clock ticks to qemu timer
>> --
>> 1.9.1
>>
>>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 8:25 ` Eric Auger
@ 2015-06-12 8:53 ` Eric Auger
2015-06-12 10:04 ` Peter Maydell
0 siblings, 1 reply; 31+ messages in thread
From: Eric Auger @ 2015-06-12 8:53 UTC (permalink / raw)
To: Peter Crosthwaite, Peter Maydell, Shannon Zhao, Alexander Graf,
Alex Bennée
Cc: qemu-devel@nongnu.org Developers
On 06/12/2015 10:25 AM, Eric Auger wrote:
> Hi Peter,
> On 06/12/2015 04:54 AM, Peter Crosthwaite wrote:
>> On Tue, Jun 2, 2015 at 9:33 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> From: Eric Auger <eric.auger@linaro.org>
>>>
>>> Device tree nodes for the platform bus and its children dynamic sysbus
>>> devices are added in a machine init done notifier. To load the dtb once,
>>> after those latter nodes are built and before ROM freeze, the actual
>>> arm_load_kernel existing code is moved into a notifier notify function,
>>> arm_load_kernel_notify. arm_load_kernel now only registers the
>>> corresponding notifier.
>>>
>>
>> Does this work? I am experiencing a regression on this patch for
>> xlnx-ep108 board.
>
> Sorry for the inconvenience. On my side I tested it on virt board.
>
> I am currently looking at the issue ...
>
> Best Regards
>
> Eric
> I think it is because this is now delaying
>> arm_load_kernel_notify call until after rom_load_all. From vl.c:
>>
>> if (rom_load_all() != 0) {
>> fprintf(stderr, "rom loading failed\n");
>> exit(1);
>> }
>>
>> /* TODO: once all bus devices are qdevified, this should be done
>> * when bus is created by qdev.c */
>> qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
>> qemu_run_machine_init_done_notifiers();
>>
>> the machine_init_done_notifiers are called after the rom_load_all()
>> call which does the image loading.
Isn't the actual rom loading done in a reset notifier? If confirmed the
problem comes from the fact the order of registration of reset notifiers
for rom_reset and do_cpu_reset has swapped?
Best Regards
Eric
So the image-to-load registration
>> is too late.
>>
>> Straight revert of this patch fixes the issue for me.
>>
>> Regards,
>> Peter
>>
>>
>>> Machine files that do not support platform bus stay unchanged. Machine
>>> files willing to support dynamic sysbus devices must call arm_load_kernel
>>> before sysbus-fdt arm_register_platform_bus_fdt_creator to make sure
>>> dynamic sysbus device nodes are integrated in the dtb.
>>>
>>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>>> Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
>>> Reviewed-by: Alexander Graf <agraf@suse.de>
>>> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>>> Message-id: 1433244554-12898-3-git-send-email-eric.auger@linaro.org
>>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>>> ---
>>> hw/arm/boot.c | 14 +++++++++++++-
>>> include/hw/arm/arm.h | 28 ++++++++++++++++++++++++++++
>>> 2 files changed, 41 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
>>> index fa69503..d036624 100644
>>> --- a/hw/arm/boot.c
>>> +++ b/hw/arm/boot.c
>>> @@ -557,7 +557,7 @@ static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
>>> fw_cfg_add_bytes(fw_cfg, data_key, data, size);
>>> }
>>>
>>> -void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>>> +static void arm_load_kernel_notify(Notifier *notifier, void *data)
>>> {
>>> CPUState *cs;
>>> int kernel_size;
>>> @@ -568,6 +568,11 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>>> hwaddr entry, kernel_load_offset;
>>> int big_endian;
>>> static const ARMInsnFixup *primary_loader;
>>> + ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
>>> + notifier, notifier);
>>> + ARMCPU *cpu = n->cpu;
>>> + struct arm_boot_info *info =
>>> + container_of(n, struct arm_boot_info, load_kernel_notifier);
>>>
>>> /* CPU objects (unlike devices) are not automatically reset on system
>>> * reset, so we must always register a handler to do so. If we're
>>> @@ -775,3 +780,10 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>>> ARM_CPU(cs)->env.boot_info = info;
>>> }
>>> }
>>> +
>>> +void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>>> +{
>>> + info->load_kernel_notifier.cpu = cpu;
>>> + info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
>>> + qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
>>> +}
>>> diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
>>> index 5c940eb..760804c 100644
>>> --- a/include/hw/arm/arm.h
>>> +++ b/include/hw/arm/arm.h
>>> @@ -13,11 +13,21 @@
>>>
>>> #include "exec/memory.h"
>>> #include "hw/irq.h"
>>> +#include "qemu/notify.h"
>>>
>>> /* armv7m.c */
>>> qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
>>> const char *kernel_filename, const char *cpu_model);
>>>
>>> +/*
>>> + * struct used as a parameter of the arm_load_kernel machine init
>>> + * done notifier
>>> + */
>>> +typedef struct {
>>> + Notifier notifier; /* actual notifier */
>>> + ARMCPU *cpu; /* handle to the first cpu object */
>>> +} ArmLoadKernelNotifier;
>>> +
>>> /* arm_boot.c */
>>> struct arm_boot_info {
>>> uint64_t ram_size;
>>> @@ -64,6 +74,8 @@ struct arm_boot_info {
>>> * the user it should implement this hook.
>>> */
>>> void (*modify_dtb)(const struct arm_boot_info *info, void *fdt);
>>> + /* machine init done notifier executing arm_load_dtb */
>>> + ArmLoadKernelNotifier load_kernel_notifier;
>>> /* Used internally by arm_boot.c */
>>> int is_linux;
>>> hwaddr initrd_start;
>>> @@ -75,6 +87,22 @@ struct arm_boot_info {
>>> */
>>> bool firmware_loaded;
>>> };
>>> +
>>> +/**
>>> + * arm_load_kernel - Loads memory with everything needed to boot
>>> + *
>>> + * @cpu: handle to the first CPU object
>>> + * @info: handle to the boot info struct
>>> + * Registers a machine init done notifier that copies to memory
>>> + * everything needed to boot, depending on machine and user options:
>>> + * kernel image, boot loaders, initrd, dtb. Also registers the CPU
>>> + * reset handler.
>>> + *
>>> + * In case the machine file supports the platform bus device and its
>>> + * dynamically instantiable sysbus devices, this function must be called
>>> + * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the
>>> + * machine init done notifiers are called in registration reverse order.
>>> + */
>>> void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
>>>
>>> /* Multiplication factor to convert from system clock ticks to qemu timer
>>> --
>>> 1.9.1
>>>
>>>
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 8:53 ` Eric Auger
@ 2015-06-12 10:04 ` Peter Maydell
2015-06-12 18:04 ` Peter Crosthwaite
0 siblings, 1 reply; 31+ messages in thread
From: Peter Maydell @ 2015-06-12 10:04 UTC (permalink / raw)
To: Eric Auger
Cc: qemu-devel@nongnu.org Developers, Peter Crosthwaite,
Alex Bennée, Shannon Zhao, Alexander Graf
On 12 June 2015 at 09:53, Eric Auger <eric.auger@linaro.org> wrote:
> On 06/12/2015 10:25 AM, Eric Auger wrote:
>>> I think it is because this is now delaying
>>> arm_load_kernel_notify call until after rom_load_all. From vl.c:
>>>
>>> if (rom_load_all() != 0) {
>>> fprintf(stderr, "rom loading failed\n");
>>> exit(1);
>>> }
>>>
>>> /* TODO: once all bus devices are qdevified, this should be done
>>> * when bus is created by qdev.c */
>>> qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
>>> qemu_run_machine_init_done_notifiers();
>>>
>>> the machine_init_done_notifiers are called after the rom_load_all()
>>> call which does the image loading.
>
> Isn't the actual rom loading done in a reset notifier? If confirmed the
> problem comes from the fact the order of registration of reset notifiers
> for rom_reset and do_cpu_reset has swapped?
Yes, actual writing of rom data to ram happens in rom_reset_all().
This does seem to be called after arm_load_kernel_notify and
before do_cpu_reset, which is the order I would expect we require...
-- PMM
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 10:04 ` Peter Maydell
@ 2015-06-12 18:04 ` Peter Crosthwaite
2015-06-12 18:06 ` Peter Maydell
2015-06-15 13:34 ` Eric Auger
0 siblings, 2 replies; 31+ messages in thread
From: Peter Crosthwaite @ 2015-06-12 18:04 UTC (permalink / raw)
To: Peter Maydell
Cc: Alexander Graf, Shannon Zhao, Alex Bennée,
qemu-devel@nongnu.org Developers, Eric Auger
On Fri, Jun 12, 2015 at 3:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 12 June 2015 at 09:53, Eric Auger <eric.auger@linaro.org> wrote:
>> On 06/12/2015 10:25 AM, Eric Auger wrote:
>>>> I think it is because this is now delaying
>>>> arm_load_kernel_notify call until after rom_load_all. From vl.c:
>>>>
>>>> if (rom_load_all() != 0) {
>>>> fprintf(stderr, "rom loading failed\n");
>>>> exit(1);
>>>> }
>>>>
>>>> /* TODO: once all bus devices are qdevified, this should be done
>>>> * when bus is created by qdev.c */
>>>> qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
>>>> qemu_run_machine_init_done_notifiers();
>>>>
>>>> the machine_init_done_notifiers are called after the rom_load_all()
>>>> call which does the image loading.
>>
>> Isn't the actual rom loading done in a reset notifier? If confirmed the
>> problem comes from the fact the order of registration of reset notifiers
>> for rom_reset and do_cpu_reset has swapped?
>
> Yes, actual writing of rom data to ram happens in rom_reset_all().
> This does seem to be called after arm_load_kernel_notify and
> before do_cpu_reset, which is the order I would expect we require...
>
So Eric's cpu reset re-ordering patch does fix it. But I thought we
were trying to make reset ordering independent?
I think the issue I describe above wrt rom_load_all is still real
though, just with a more minor consequence. The notify patch is such
that rom_load_all is now called before arm_load_kernel_notify. Looking
at rom_load_all:
int rom_load_all(void)
{
hwaddr addr = 0;
MemoryRegionSection section;
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->fw_file) {
continue;
}
if (addr > rom->addr) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
", addr=0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->addr);
return -1;
}
addr = rom->addr;
addr += rom->romsize;
section = memory_region_find(get_system_memory(), rom->addr, 1);
rom->isrom = int128_nz(section.size) &&
memory_region_is_rom(section.mr);
memory_region_unref(section.mr);
}
qemu_register_reset(rom_reset, NULL);
return 0;
}
There is a list iterator over the ROM list doing some tweaking for the
isrom field. This iteration process is now skipped for arm_load_kernel
loading, as the rom_insert calls happen after the rom_load_all. Does
this mean the arm_load_kernel no longer works on is_rom MRs?
Regards,
Peter
> -- PMM
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 18:04 ` Peter Crosthwaite
@ 2015-06-12 18:06 ` Peter Maydell
2015-06-15 13:34 ` Eric Auger
1 sibling, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-12 18:06 UTC (permalink / raw)
To: Peter Crosthwaite
Cc: Alexander Graf, Shannon Zhao, Alex Bennée,
qemu-devel@nongnu.org Developers, Eric Auger
On 12 June 2015 at 19:04, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> So Eric's cpu reset re-ordering patch does fix it. But I thought we
> were trying to make reset ordering independent?
I think it would be more accurate to say that we hope reset
ordering is independent because we have no good way of
describing and enforcing any ordering requirements :-)
-- PMM
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier
2015-06-12 18:04 ` Peter Crosthwaite
2015-06-12 18:06 ` Peter Maydell
@ 2015-06-15 13:34 ` Eric Auger
1 sibling, 0 replies; 31+ messages in thread
From: Eric Auger @ 2015-06-15 13:34 UTC (permalink / raw)
To: Peter Crosthwaite, Peter Maydell
Cc: Alexander Graf, Alex Bennée,
qemu-devel@nongnu.org Developers, Shannon Zhao
Hi Peter,
On 06/12/2015 08:04 PM, Peter Crosthwaite wrote:
> On Fri, Jun 12, 2015 at 3:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 12 June 2015 at 09:53, Eric Auger <eric.auger@linaro.org> wrote:
>>> On 06/12/2015 10:25 AM, Eric Auger wrote:
>>>>> I think it is because this is now delaying
>>>>> arm_load_kernel_notify call until after rom_load_all. From vl.c:
>>>>>
>>>>> if (rom_load_all() != 0) {
>>>>> fprintf(stderr, "rom loading failed\n");
>>>>> exit(1);
>>>>> }
>>>>>
>>>>> /* TODO: once all bus devices are qdevified, this should be done
>>>>> * when bus is created by qdev.c */
>>>>> qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
>>>>> qemu_run_machine_init_done_notifiers();
>>>>>
>>>>> the machine_init_done_notifiers are called after the rom_load_all()
>>>>> call which does the image loading.
>>>
>>> Isn't the actual rom loading done in a reset notifier? If confirmed the
>>> problem comes from the fact the order of registration of reset notifiers
>>> for rom_reset and do_cpu_reset has swapped?
>>
>> Yes, actual writing of rom data to ram happens in rom_reset_all().
>> This does seem to be called after arm_load_kernel_notify and
>> before do_cpu_reset, which is the order I would expect we require...
>>
>
> So Eric's cpu reset re-ordering patch does fix it. But I thought we
> were trying to make reset ordering independent?
Thanks for testing & reporting.
>
> I think the issue I describe above wrt rom_load_all is still real
> though, just with a more minor consequence. The notify patch is such
> that rom_load_all is now called before arm_load_kernel_notify. Looking
> at rom_load_all:
>
> int rom_load_all(void)
> {
> hwaddr addr = 0;
> MemoryRegionSection section;
> Rom *rom;
>
> QTAILQ_FOREACH(rom, &roms, next) {
> if (rom->fw_file) {
> continue;
> }
> if (addr > rom->addr) {
> fprintf(stderr, "rom: requested regions overlap "
> "(rom %s. free=0x" TARGET_FMT_plx
> ", addr=0x" TARGET_FMT_plx ")\n",
> rom->name, addr, rom->addr);
> return -1;
> }
> addr = rom->addr;
> addr += rom->romsize;
> section = memory_region_find(get_system_memory(), rom->addr, 1);
> rom->isrom = int128_nz(section.size) &&
> memory_region_is_rom(section.mr);
> memory_region_unref(section.mr);
> }
> qemu_register_reset(rom_reset, NULL);
> return 0;
> }
>
> There is a list iterator over the ROM list doing some tweaking for the
> isrom field. This iteration process is now skipped for arm_load_kernel
> loading, as the rom_insert calls happen after the rom_load_all. Does
> this mean the arm_load_kernel no longer works on is_rom MRs?
OK I see your point. Do you think it could be acceptable to put
rom_load_all after machine init done, combined with rom_load_done, in
vl.c?
In practice, as far as I understand, rom_load_all does check whether
register ROM regions overlap and whether their associated MR is readonly
RAM. In the positive this isrom field is set.
If isrom is not correctly set this has for consequence:
- bad info reported about memory regions in monitor
- rom->data pointer not freed on rom_reset reset notifier.
As you I don't think such regressions are acceptable.
I did not see any other usage of isrom?
If the above is not sensible, due to other side effects I do not see,
the other way around to achieve my goal of building the dt at machine
init done notifier time would be to only postpone the dtb creation and
not the whole ARM load kernel. But dtb also uses rom_add_blob_fixed and
adds a ROM region which would not be dealt with rom_load_all code.
Best Regards
Eric
>
> Regards,
> Peter
>
>> -- PMM
>>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 21/22] hw/arm/virt: add dynamic sysbus device support
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (19 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 20/22] hw/arm/boot: arm_load_kernel implemented as a machine init done notifier Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-02 16:33 ` [Qemu-devel] [PULL 22/22] hw/arm/virt: change indentation in a15memmap Peter Maydell
2015-06-04 10:44 ` [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
Allows sysbus devices to be instantiated from command line by
using -device option. Machvirt creates a platform bus at init.
The dynamic sysbus devices are attached to this platform bus device.
The platform bus device registers a machine init done notifier
whose role will be to bind the dynamic sysbus devices. Indeed
dynamic sysbus devices are created after machine init.
machvirt also registers a notifier that will build the device
tree nodes for the platform bus and its children dynamic sysbus
devices.
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 1433244554-12898-4-git-send-email-eric.auger@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/arm/virt.h | 1 +
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4bb7175..02b91ba 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -45,9 +45,11 @@
#include "qemu/error-report.h"
#include "hw/pci-host/gpex.h"
#include "hw/arm/virt-acpi-build.h"
+#include "hw/arm/sysbus-fdt.h"
+#include "hw/platform-bus.h"
/* Number of external interrupt lines to configure the GIC with */
-#define NUM_IRQS 128
+#define NUM_IRQS 256
#define GIC_FDT_IRQ_TYPE_SPI 0
#define GIC_FDT_IRQ_TYPE_PPI 1
@@ -60,6 +62,10 @@
#define GIC_FDT_IRQ_PPI_CPU_START 8
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
+#define PLATFORM_BUS_NUM_IRQS 64
+
+static ARMPlatformBusSystemParams platform_bus_params;
+
typedef struct VirtBoardInfo {
struct arm_boot_info bootinfo;
const char *cpu_model;
@@ -116,6 +122,7 @@ static const MemMapEntry a15memmap[] = {
[VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
+ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
@@ -128,6 +135,7 @@ static const int a15irqmap[] = {
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
+ [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
};
static VirtBoardInfo machines[] = {
@@ -728,6 +736,47 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
g_free(nodename);
}
+static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ int i;
+ ARMPlatformBusFDTParams *fdt_params = g_new(ARMPlatformBusFDTParams, 1);
+ MemoryRegion *sysmem = get_system_memory();
+
+ platform_bus_params.platform_bus_base = vbi->memmap[VIRT_PLATFORM_BUS].base;
+ platform_bus_params.platform_bus_size = vbi->memmap[VIRT_PLATFORM_BUS].size;
+ platform_bus_params.platform_bus_first_irq = vbi->irqmap[VIRT_PLATFORM_BUS];
+ platform_bus_params.platform_bus_num_irqs = PLATFORM_BUS_NUM_IRQS;
+
+ fdt_params->system_params = &platform_bus_params;
+ fdt_params->binfo = &vbi->bootinfo;
+ fdt_params->intc = "/intc";
+ /*
+ * register a machine init done notifier that creates the device tree
+ * nodes of the platform bus and its children dynamic sysbus devices
+ */
+ arm_register_platform_bus_fdt_creator(fdt_params);
+
+ dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
+ dev->id = TYPE_PLATFORM_BUS_DEVICE;
+ qdev_prop_set_uint32(dev, "num_irqs",
+ platform_bus_params.platform_bus_num_irqs);
+ qdev_prop_set_uint32(dev, "mmio_size",
+ platform_bus_params.platform_bus_size);
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+
+ for (i = 0; i < platform_bus_params.platform_bus_num_irqs; i++) {
+ int irqn = platform_bus_params.platform_bus_first_irq + i;
+ sysbus_connect_irq(s, i, pic[irqn]);
+ }
+
+ memory_region_add_subregion(sysmem,
+ platform_bus_params.platform_bus_base,
+ sysbus_mmio_get_region(s, 0));
+}
+
static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
{
const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
@@ -865,6 +914,14 @@ static void machvirt_init(MachineState *machine)
vbi->bootinfo.get_dtb = machvirt_dtb;
vbi->bootinfo.firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
+
+ /*
+ * arm_load_kernel machine init done notifier registration must
+ * happen before the platform_bus_create call. In this latter,
+ * another notifier is registered which adds platform bus nodes.
+ * Notifiers are executed in registration reverse order.
+ */
+ create_platform_bus(vbi, pic);
}
static bool virt_get_secure(Object *obj, Error **errp)
@@ -903,6 +960,7 @@ static void virt_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM Virtual Machine",
mc->init = machvirt_init;
mc->max_cpus = 8;
+ mc->has_dynamic_sysbus = true;
}
static const TypeInfo machvirt_info = {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 003ef29..d22fd8e 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -55,6 +55,7 @@ enum {
VIRT_PCIE_PIO,
VIRT_PCIE_ECAM,
VIRT_GIC_V2M,
+ VIRT_PLATFORM_BUS,
};
typedef struct MemMapEntry {
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PULL 22/22] hw/arm/virt: change indentation in a15memmap
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (20 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 21/22] hw/arm/virt: add dynamic sysbus device support Peter Maydell
@ 2015-06-02 16:33 ` Peter Maydell
2015-06-04 10:44 ` [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-02 16:33 UTC (permalink / raw)
To: qemu-devel
From: Eric Auger <eric.auger@linaro.org>
Re-indent in a15memmap after VIRT_PLATFORM_BUS introduction
Signed-off-by: Eric Auger <eric.auger@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
Message-id: 1433244554-12898-5-git-send-email-eric.auger@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 02b91ba..0a75cc8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -111,22 +111,22 @@ typedef struct {
*/
static const MemMapEntry a15memmap[] = {
/* Space up to 0x8000000 is reserved for a boot ROM */
- [VIRT_FLASH] = { 0, 0x08000000 },
- [VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
+ [VIRT_FLASH] = { 0, 0x08000000 },
+ [VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
/* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
- [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
- [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
- [VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
- [VIRT_UART] = { 0x09000000, 0x00001000 },
- [VIRT_RTC] = { 0x09010000, 0x00001000 },
- [VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
- [VIRT_MMIO] = { 0x0a000000, 0x00000200 },
+ [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
+ [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
+ [VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
+ [VIRT_UART] = { 0x09000000, 0x00001000 },
+ [VIRT_RTC] = { 0x09010000, 0x00001000 },
+ [VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
+ [VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
- [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
- [VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
- [VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
- [VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
- [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
+ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
+ [VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
+ [VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
+ [VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
+ [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
};
static const int a15irqmap[] = {
--
1.9.1
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PULL 00/22] target-arm queue
2015-06-02 16:33 [Qemu-devel] [PULL 00/22] target-arm queue Peter Maydell
` (21 preceding siblings ...)
2015-06-02 16:33 ` [Qemu-devel] [PULL 22/22] hw/arm/virt: change indentation in a15memmap Peter Maydell
@ 2015-06-04 10:44 ` Peter Maydell
22 siblings, 0 replies; 31+ messages in thread
From: Peter Maydell @ 2015-06-04 10:44 UTC (permalink / raw)
To: QEMU Developers
On 2 June 2015 at 17:33, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> There's more stuff in the pipeline for ARM, but 22 patches
> is a respectable number, so let's drain the queue.
>
> -- PMM
>
>
> The following changes since commit 3fc827d591679f3e262b9d1f8b34528eabfca8c0:
>
> target-arm: Correct check for non-EL3 (2015-06-02 13:22:29 +0100)
>
> are available in the git repository at:
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150602
>
> for you to fetch changes up to 94edf02c4c94781fa777c459fe86b52131b83cb6:
>
> hw/arm/virt: change indentation in a15memmap (2015-06-02 16:31:18 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
> * more EL2 preparation patches
> * revert a no-longer-necessary workaround for old glib versions
> * add GICv2m support to virt board (MSI support)
> * pl061: fix wrong calculation of GPIOMIS register
> * support MSI via irqfd
> * remove a confusing v8_ prefix from some variable names
> * add dynamic sysbus device support to the virt board
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 31+ messages in thread