diff options
author | Nathan Rossi <nathan.rossi@xilinx.com> | 2015-02-20 15:17:59 +1000 |
---|---|---|
committer | Nathan Rossi <nathan.rossi@xilinx.com> | 2015-02-24 09:49:44 +1000 |
commit | e76d7bc2baf19ea1ab7645256daaee3721fc4220 (patch) | |
tree | 7174360d12c47d5aab88a0c0472cffc02f08ee32 /recipes-devtools | |
parent | 87ba8f345f6dd5c47e460c99ffa00c1bf6d479b4 (diff) | |
download | meta-xilinx-e76d7bc2baf19ea1ab7645256daaee3721fc4220.tar.gz |
qemu: Create recipe for Zynq MP supported QEMU
* Use mainline QEMU master branch, plus patches for Zynq MP support
Signed-off-by: Nathan Rossi <nathan.rossi@xilinx.com>
Diffstat (limited to 'recipes-devtools')
16 files changed, 1730 insertions, 0 deletions
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0001-target-arm-cpu64-Factor-out-ARM-cortex-init.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0001-target-arm-cpu64-Factor-out-ARM-cortex-init.patch new file mode 100644 index 00000000..779e8c42 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0001-target-arm-cpu64-Factor-out-ARM-cortex-init.patch | |||
@@ -0,0 +1,109 @@ | |||
1 | From 17c53bfa9ce6bb75f9ff55722bc02e4050a148c1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:38 -0800 | ||
4 | Subject: [PATCH 01/15] target-arm: cpu64: Factor out ARM cortex init | ||
5 | |||
6 | In preparation for support for Cortex a53. Use "axx" to describe the | ||
7 | shareable features. Some of the CP15 registers (such as ACTLR) are | ||
8 | specific to implementation, but we currently just RAZ them so continue | ||
9 | with that as the policy for all cortex A processors under a shared | ||
10 | definition. | ||
11 | |||
12 | The cache sizes and geometeries, the L1 I-cache policy and the physical | ||
13 | address range differ between A53 and A57 so those particulars are left | ||
14 | as A57 specific. The rest are moved to the generalisation. | ||
15 | |||
16 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
17 | --- | ||
18 | target-arm/cpu64.c | 32 +++++++++++++++++++------------- | ||
19 | 1 file changed, 19 insertions(+), 13 deletions(-) | ||
20 | |||
21 | diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c | ||
22 | index 823c739..5cf3121 100644 | ||
23 | --- a/target-arm/cpu64.c | ||
24 | +++ b/target-arm/cpu64.c | ||
25 | @@ -38,22 +38,22 @@ static inline void unset_feature(CPUARMState *env, int feature) | ||
26 | } | ||
27 | |||
28 | #ifndef CONFIG_USER_ONLY | ||
29 | -static uint64_t a57_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
30 | +static uint64_t axx_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) | ||
31 | { | ||
32 | /* Number of processors is in [25:24]; otherwise we RAZ */ | ||
33 | return (smp_cpus - 1) << 24; | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | -static const ARMCPRegInfo cortexa57_cp_reginfo[] = { | ||
38 | +static const ARMCPRegInfo cortexaxx_cp_reginfo[] = { | ||
39 | #ifndef CONFIG_USER_ONLY | ||
40 | { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64, | ||
41 | .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2, | ||
42 | - .access = PL1_RW, .readfn = a57_l2ctlr_read, | ||
43 | + .access = PL1_RW, .readfn = axx_l2ctlr_read, | ||
44 | .writefn = arm_cp_write_ignore }, | ||
45 | { .name = "L2CTLR", | ||
46 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2, | ||
47 | - .access = PL1_RW, .readfn = a57_l2ctlr_read, | ||
48 | + .access = PL1_RW, .readfn = axx_l2ctlr_read, | ||
49 | .writefn = arm_cp_write_ignore }, | ||
50 | #endif | ||
51 | { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64, | ||
52 | @@ -92,10 +92,8 @@ static const ARMCPRegInfo cortexa57_cp_reginfo[] = { | ||
53 | REGINFO_SENTINEL | ||
54 | }; | ||
55 | |||
56 | -static void aarch64_a57_initfn(Object *obj) | ||
57 | +static void aarch64_axx_initfn(ARMCPU *cpu) | ||
58 | { | ||
59 | - ARMCPU *cpu = ARM_CPU(obj); | ||
60 | - | ||
61 | set_feature(&cpu->env, ARM_FEATURE_V8); | ||
62 | set_feature(&cpu->env, ARM_FEATURE_VFP4); | ||
63 | set_feature(&cpu->env, ARM_FEATURE_NEON); | ||
64 | @@ -107,13 +105,10 @@ static void aarch64_a57_initfn(Object *obj) | ||
65 | set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); | ||
66 | set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); | ||
67 | set_feature(&cpu->env, ARM_FEATURE_CRC); | ||
68 | - cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57; | ||
69 | - cpu->midr = 0x411fd070; | ||
70 | cpu->reset_fpsid = 0x41034070; | ||
71 | cpu->mvfr0 = 0x10110222; | ||
72 | cpu->mvfr1 = 0x12111111; | ||
73 | cpu->mvfr2 = 0x00000043; | ||
74 | - cpu->ctr = 0x8444c004; | ||
75 | cpu->reset_sctlr = 0x00c50838; | ||
76 | cpu->id_pfr0 = 0x00000131; | ||
77 | cpu->id_pfr1 = 0x00011011; | ||
78 | @@ -132,14 +127,25 @@ static void aarch64_a57_initfn(Object *obj) | ||
79 | cpu->id_aa64pfr0 = 0x00002222; | ||
80 | cpu->id_aa64dfr0 = 0x10305106; | ||
81 | cpu->id_aa64isar0 = 0x00011120; | ||
82 | - cpu->id_aa64mmfr0 = 0x00001124; | ||
83 | cpu->dbgdidr = 0x3516d000; | ||
84 | cpu->clidr = 0x0a200023; | ||
85 | + cpu->dcz_blocksize = 4; /* 64 bytes */ | ||
86 | + define_arm_cp_regs(cpu, cortexaxx_cp_reginfo); | ||
87 | +} | ||
88 | + | ||
89 | +static void aarch64_a57_initfn(Object *obj) | ||
90 | +{ | ||
91 | + ARMCPU *cpu = ARM_CPU(obj); | ||
92 | + | ||
93 | + aarch64_axx_initfn(cpu); | ||
94 | + | ||
95 | + cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57; | ||
96 | + cpu->midr = 0x411fd070; | ||
97 | + cpu->ctr = 0x8444c004; /* L1Ip = PIPT */ | ||
98 | + cpu->id_aa64mmfr0 = 0x00001124; /* 44 bit physical addr */ | ||
99 | cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ | ||
100 | cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */ | ||
101 | cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */ | ||
102 | - cpu->dcz_blocksize = 4; /* 64 bytes */ | ||
103 | - define_arm_cp_regs(cpu, cortexa57_cp_reginfo); | ||
104 | } | ||
105 | |||
106 | #ifdef CONFIG_USER_ONLY | ||
107 | -- | ||
108 | 2.1.1 | ||
109 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0002-target-arm-cpu64-Add-support-for-cortex-a53.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0002-target-arm-cpu64-Add-support-for-cortex-a53.patch new file mode 100644 index 00000000..4723bd2b --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0002-target-arm-cpu64-Add-support-for-cortex-a53.patch | |||
@@ -0,0 +1,51 @@ | |||
1 | From 2390e80ace413722b0d41500c1927d78b2a0154b Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:39 -0800 | ||
4 | Subject: [PATCH 02/15] target-arm: cpu64: Add support for cortex-a53 | ||
5 | |||
6 | Similar to a53, but with different L1 I cache policy, phys addr size and | ||
7 | different cache geometries. The cache sizes is implementation | ||
8 | configurable, but use these values (from Xilinx MPSoC) as a default | ||
9 | until cache size configurability is added. | ||
10 | |||
11 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
12 | --- | ||
13 | target-arm/cpu64.c | 15 +++++++++++++++ | ||
14 | 1 file changed, 15 insertions(+) | ||
15 | |||
16 | diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c | ||
17 | index 5cf3121..0b9728e 100644 | ||
18 | --- a/target-arm/cpu64.c | ||
19 | +++ b/target-arm/cpu64.c | ||
20 | @@ -148,6 +148,20 @@ static void aarch64_a57_initfn(Object *obj) | ||
21 | cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */ | ||
22 | } | ||
23 | |||
24 | +static void aarch64_a53_initfn(Object *obj) | ||
25 | +{ | ||
26 | + ARMCPU *cpu = ARM_CPU(obj); | ||
27 | + | ||
28 | + aarch64_axx_initfn(cpu); | ||
29 | + | ||
30 | + cpu->midr = 0x410fd034; | ||
31 | + cpu->ctr = 0x84448004; /* L1Ip = VIPT */ | ||
32 | + cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ | ||
33 | + cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ | ||
34 | + cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */ | ||
35 | + cpu->ccsidr[2] = 0x707fe07a; /* 1024KB L2 cache */ | ||
36 | +} | ||
37 | + | ||
38 | #ifdef CONFIG_USER_ONLY | ||
39 | static void aarch64_any_initfn(Object *obj) | ||
40 | { | ||
41 | @@ -175,6 +189,7 @@ typedef struct ARMCPUInfo { | ||
42 | |||
43 | static const ARMCPUInfo aarch64_cpus[] = { | ||
44 | { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, | ||
45 | + { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, | ||
46 | #ifdef CONFIG_USER_ONLY | ||
47 | { .name = "any", .initfn = aarch64_any_initfn }, | ||
48 | #endif | ||
49 | -- | ||
50 | 2.1.1 | ||
51 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0003-arm-Introduce-Xilinx-Zynq-MPSoC.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0003-arm-Introduce-Xilinx-Zynq-MPSoC.patch new file mode 100644 index 00000000..fdff7c17 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0003-arm-Introduce-Xilinx-Zynq-MPSoC.patch | |||
@@ -0,0 +1,143 @@ | |||
1 | From 37b74b0626d6403da8d9b946d77d29296bc47bcc Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:42 -0800 | ||
4 | Subject: [PATCH 03/15] arm: Introduce Xilinx Zynq MPSoC | ||
5 | |||
6 | With quad Cortex-A53 CPUs. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | default-configs/aarch64-softmmu.mak | 2 +- | ||
11 | hw/arm/Makefile.objs | 1 + | ||
12 | hw/arm/xlnx-zynq-mp.c | 71 +++++++++++++++++++++++++++++++++++++ | ||
13 | include/hw/arm/xlnx-zynq-mp.h | 21 +++++++++++ | ||
14 | 4 files changed, 94 insertions(+), 1 deletion(-) | ||
15 | create mode 100644 hw/arm/xlnx-zynq-mp.c | ||
16 | create mode 100644 include/hw/arm/xlnx-zynq-mp.h | ||
17 | |||
18 | diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak | ||
19 | index 6d3b5c7..a8011e0 100644 | ||
20 | --- a/default-configs/aarch64-softmmu.mak | ||
21 | +++ b/default-configs/aarch64-softmmu.mak | ||
22 | @@ -3,4 +3,4 @@ | ||
23 | # We support all the 32 bit boards so need all their config | ||
24 | include arm-softmmu.mak | ||
25 | |||
26 | -# Currently no 64-bit specific config requirements | ||
27 | +CONFIG_XLNX_ZYNQ_MP=y | ||
28 | diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs | ||
29 | index 6088e53..9bf072b 100644 | ||
30 | --- a/hw/arm/Makefile.objs | ||
31 | +++ b/hw/arm/Makefile.objs | ||
32 | @@ -8,3 +8,4 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o | ||
33 | obj-$(CONFIG_DIGIC) += digic.o | ||
34 | obj-y += omap1.o omap2.o strongarm.o | ||
35 | obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o | ||
36 | +obj-$(CONFIG_XLNX_ZYNQ_MP) += xlnx-zynq-mp.o | ||
37 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
38 | new file mode 100644 | ||
39 | index 0000000..d553fb0 | ||
40 | --- /dev/null | ||
41 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
42 | @@ -0,0 +1,71 @@ | ||
43 | +/* | ||
44 | + * Xilinx Zynq MPSoC emulation | ||
45 | + * | ||
46 | + * Copyright (C) 2015 Xilinx Inc | ||
47 | + * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
48 | + * | ||
49 | + * This program is free software; you can redistribute it and/or modify it | ||
50 | + * under the terms of the GNU General Public License as published by the | ||
51 | + * Free Software Foundation; either version 2 of the License, or | ||
52 | + * (at your option) any later version. | ||
53 | + * | ||
54 | + * This program is distributed in the hope that it will be useful, but WITHOUT | ||
55 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
56 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
57 | + * for more details. | ||
58 | + */ | ||
59 | + | ||
60 | +#include "hw/arm/xlnx-zynq-mp.h" | ||
61 | + | ||
62 | +static void xlnx_zynq_mp_init(Object *obj) | ||
63 | +{ | ||
64 | + XlnxZynqMPState *s = XLNX_ZYNQ_MP(obj); | ||
65 | + int i; | ||
66 | + | ||
67 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_CPUS; i++) { | ||
68 | + object_initialize(&s->cpu[i], sizeof(s->cpu[i]), | ||
69 | + "cortex-a53-" TYPE_ARM_CPU); | ||
70 | + object_property_add_child(obj, "cpu", OBJECT(&s->cpu[i]), NULL); | ||
71 | + } | ||
72 | +} | ||
73 | + | ||
74 | +#define ERR_PROP_CHECK_RETURN(err, errp) do { \ | ||
75 | + if (err) { \ | ||
76 | + error_propagate((errp), (err)); \ | ||
77 | + return; \ | ||
78 | + } \ | ||
79 | +} while (0) | ||
80 | + | ||
81 | +static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
82 | +{ | ||
83 | + XlnxZynqMPState *s = XLNX_ZYNQ_MP(dev); | ||
84 | + uint8_t i; | ||
85 | + Error *err = NULL; | ||
86 | + | ||
87 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_CPUS; i++) { | ||
88 | + object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); | ||
89 | + ERR_PROP_CHECK_RETURN(err, errp); | ||
90 | + } | ||
91 | +} | ||
92 | + | ||
93 | +static void xlnx_zynq_mp_class_init(ObjectClass *oc, void *data) | ||
94 | +{ | ||
95 | + DeviceClass *dc = DEVICE_CLASS(oc); | ||
96 | + | ||
97 | + dc->realize = xlnx_zynq_mp_realize; | ||
98 | +} | ||
99 | + | ||
100 | +static const TypeInfo xlnx_zynq_mp_type_info = { | ||
101 | + .name = TYPE_XLNX_ZYNQ_MP, | ||
102 | + .parent = TYPE_DEVICE, | ||
103 | + .instance_size = sizeof(XlnxZynqMPState), | ||
104 | + .instance_init = xlnx_zynq_mp_init, | ||
105 | + .class_init = xlnx_zynq_mp_class_init, | ||
106 | +}; | ||
107 | + | ||
108 | +static void xlnx_zynq_mp_register_types(void) | ||
109 | +{ | ||
110 | + type_register_static(&xlnx_zynq_mp_type_info); | ||
111 | +} | ||
112 | + | ||
113 | +type_init(xlnx_zynq_mp_register_types) | ||
114 | diff --git a/include/hw/arm/xlnx-zynq-mp.h b/include/hw/arm/xlnx-zynq-mp.h | ||
115 | new file mode 100644 | ||
116 | index 0000000..f7410dc | ||
117 | --- /dev/null | ||
118 | +++ b/include/hw/arm/xlnx-zynq-mp.h | ||
119 | @@ -0,0 +1,21 @@ | ||
120 | +#ifndef XLNX_ZYNQ_MP_H_ | ||
121 | + | ||
122 | +#include "qemu-common.h" | ||
123 | +#include "hw/arm/arm.h" | ||
124 | + | ||
125 | +#define TYPE_XLNX_ZYNQ_MP "xlnx,zynq-mp" | ||
126 | +#define XLNX_ZYNQ_MP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ | ||
127 | + TYPE_XLNX_ZYNQ_MP) | ||
128 | + | ||
129 | +#define XLNX_ZYNQ_MP_NUM_CPUS 4 | ||
130 | + | ||
131 | +typedef struct XlnxZynqMPState { | ||
132 | + /*< private >*/ | ||
133 | + DeviceState parent_obj; | ||
134 | + /*< public >*/ | ||
135 | + | ||
136 | + ARMCPU cpu[XLNX_ZYNQ_MP_NUM_CPUS]; | ||
137 | +} XlnxZynqMPState; | ||
138 | + | ||
139 | +#define XLNX_ZYNQ_MP_H_ | ||
140 | +#endif | ||
141 | -- | ||
142 | 2.1.1 | ||
143 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0004-arm-xlnx-zynq-mp-Add-GIC.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0004-arm-xlnx-zynq-mp-Add-GIC.patch new file mode 100644 index 00000000..518ca702 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0004-arm-xlnx-zynq-mp-Add-GIC.patch | |||
@@ -0,0 +1,83 @@ | |||
1 | From 307b6f846c7cc878f399a34a29a9db48f32e3432 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:43 -0800 | ||
4 | Subject: [PATCH 04/15] arm: xlnx-zynq-mp: Add GIC | ||
5 | |||
6 | And connect IRQ outputs to the CPUs. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | hw/arm/xlnx-zynq-mp.c | 19 +++++++++++++++++++ | ||
11 | include/hw/arm/xlnx-zynq-mp.h | 2 ++ | ||
12 | 2 files changed, 21 insertions(+) | ||
13 | |||
14 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
15 | index d553fb0..9cdff13 100644 | ||
16 | --- a/hw/arm/xlnx-zynq-mp.c | ||
17 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
18 | @@ -17,6 +17,11 @@ | ||
19 | |||
20 | #include "hw/arm/xlnx-zynq-mp.h" | ||
21 | |||
22 | +#define GIC_NUM_SPI_INTR 128 | ||
23 | + | ||
24 | +#define GIC_DIST_ADDR 0xf9010000 | ||
25 | +#define GIC_CPU_ADDR 0xf9020000 | ||
26 | + | ||
27 | static void xlnx_zynq_mp_init(Object *obj) | ||
28 | { | ||
29 | XlnxZynqMPState *s = XLNX_ZYNQ_MP(obj); | ||
30 | @@ -27,6 +32,9 @@ static void xlnx_zynq_mp_init(Object *obj) | ||
31 | "cortex-a53-" TYPE_ARM_CPU); | ||
32 | object_property_add_child(obj, "cpu", OBJECT(&s->cpu[i]), NULL); | ||
33 | } | ||
34 | + | ||
35 | + object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); | ||
36 | + qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); | ||
37 | } | ||
38 | |||
39 | #define ERR_PROP_CHECK_RETURN(err, errp) do { \ | ||
40 | @@ -42,9 +50,20 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
41 | uint8_t i; | ||
42 | Error *err = NULL; | ||
43 | |||
44 | + qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); | ||
45 | + qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); | ||
46 | + qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQ_MP_NUM_CPUS); | ||
47 | + object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); | ||
48 | + ERR_PROP_CHECK_RETURN(err, errp); | ||
49 | + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0, GIC_DIST_ADDR); | ||
50 | + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1, GIC_CPU_ADDR); | ||
51 | + | ||
52 | for (i = 0; i < XLNX_ZYNQ_MP_NUM_CPUS; i++) { | ||
53 | object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); | ||
54 | ERR_PROP_CHECK_RETURN(err, errp); | ||
55 | + | ||
56 | + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i, | ||
57 | + qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ)); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | diff --git a/include/hw/arm/xlnx-zynq-mp.h b/include/hw/arm/xlnx-zynq-mp.h | ||
62 | index f7410dc..22b2af0 100644 | ||
63 | --- a/include/hw/arm/xlnx-zynq-mp.h | ||
64 | +++ b/include/hw/arm/xlnx-zynq-mp.h | ||
65 | @@ -2,6 +2,7 @@ | ||
66 | |||
67 | #include "qemu-common.h" | ||
68 | #include "hw/arm/arm.h" | ||
69 | +#include "hw/intc/arm_gic.h" | ||
70 | |||
71 | #define TYPE_XLNX_ZYNQ_MP "xlnx,zynq-mp" | ||
72 | #define XLNX_ZYNQ_MP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ | ||
73 | @@ -15,6 +16,7 @@ typedef struct XlnxZynqMPState { | ||
74 | /*< public >*/ | ||
75 | |||
76 | ARMCPU cpu[XLNX_ZYNQ_MP_NUM_CPUS]; | ||
77 | + GICState gic; | ||
78 | } XlnxZynqMPState; | ||
79 | |||
80 | #define XLNX_ZYNQ_MP_H_ | ||
81 | -- | ||
82 | 2.1.1 | ||
83 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0005-arm-xlnx-zynq-mp-Connect-CPU-Timers-to-GIC.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0005-arm-xlnx-zynq-mp-Connect-CPU-Timers-to-GIC.patch new file mode 100644 index 00000000..207dbc93 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0005-arm-xlnx-zynq-mp-Connect-CPU-Timers-to-GIC.patch | |||
@@ -0,0 +1,58 @@ | |||
1 | From c2c5018da201c9eead0dba39263eb40549064511 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:44 -0800 | ||
4 | Subject: [PATCH 05/15] arm: xlnx-zynq-mp: Connect CPU Timers to GIC | ||
5 | |||
6 | Connect the GPIO outputs from the individual CPUs for the timers to the | ||
7 | GIC. | ||
8 | |||
9 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
10 | --- | ||
11 | hw/arm/xlnx-zynq-mp.c | 16 ++++++++++++++++ | ||
12 | 1 file changed, 16 insertions(+) | ||
13 | |||
14 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
15 | index 9cdff13..be82a66 100644 | ||
16 | --- a/hw/arm/xlnx-zynq-mp.c | ||
17 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
18 | @@ -19,9 +19,17 @@ | ||
19 | |||
20 | #define GIC_NUM_SPI_INTR 128 | ||
21 | |||
22 | +#define ARM_PHYS_TIMER_PPI 30 | ||
23 | +#define ARM_VIRT_TIMER_PPI 27 | ||
24 | + | ||
25 | #define GIC_DIST_ADDR 0xf9010000 | ||
26 | #define GIC_CPU_ADDR 0xf9020000 | ||
27 | |||
28 | +static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) | ||
29 | +{ | ||
30 | + return GIC_NUM_SPI_INTR + cpu_nr * 32 + ppi_index; | ||
31 | +} | ||
32 | + | ||
33 | static void xlnx_zynq_mp_init(Object *obj) | ||
34 | { | ||
35 | XlnxZynqMPState *s = XLNX_ZYNQ_MP(obj); | ||
36 | @@ -59,11 +67,19 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
37 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1, GIC_CPU_ADDR); | ||
38 | |||
39 | for (i = 0; i < XLNX_ZYNQ_MP_NUM_CPUS; i++) { | ||
40 | + qemu_irq irq; | ||
41 | + | ||
42 | object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); | ||
43 | ERR_PROP_CHECK_RETURN(err, errp); | ||
44 | |||
45 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i, | ||
46 | qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ)); | ||
47 | + irq = qdev_get_gpio_in(DEVICE(&s->gic), | ||
48 | + arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); | ||
49 | + qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 0, irq); | ||
50 | + irq = qdev_get_gpio_in(DEVICE(&s->gic), | ||
51 | + arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); | ||
52 | + qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 1, irq); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | -- | ||
57 | 2.1.1 | ||
58 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0006-net-cadence_gem-Clean-up-variable-names.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0006-net-cadence_gem-Clean-up-variable-names.patch new file mode 100644 index 00000000..c5bf07ef --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0006-net-cadence_gem-Clean-up-variable-names.patch | |||
@@ -0,0 +1,264 @@ | |||
1 | From 67513395caa586a2f6bc79e3791e26a129e6ec1c Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:45 -0800 | ||
4 | Subject: [PATCH 06/15] net: cadence_gem: Clean up variable names | ||
5 | |||
6 | In preparation for migrating the state struct and type cast macro to a public | ||
7 | header. The acronym "GEM" on it's own is not specific enough to be used in a | ||
8 | more global namespace so preface with "cadence". Fix the capitalisation of | ||
9 | "gem" in the state type while touching the typename. Also preface the | ||
10 | GEM_MAXREG macro as this will need to migrate to public header. | ||
11 | |||
12 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
13 | --- | ||
14 | hw/net/cadence_gem.c | 70 ++++++++++++++++++++++++++-------------------------- | ||
15 | 1 file changed, 35 insertions(+), 35 deletions(-) | ||
16 | |||
17 | diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c | ||
18 | index 55b6293..5994306 100644 | ||
19 | --- a/hw/net/cadence_gem.c | ||
20 | +++ b/hw/net/cadence_gem.c | ||
21 | @@ -141,7 +141,7 @@ | ||
22 | #define GEM_DESCONF6 (0x00000294/4) | ||
23 | #define GEM_DESCONF7 (0x00000298/4) | ||
24 | |||
25 | -#define GEM_MAXREG (0x00000640/4) /* Last valid GEM address */ | ||
26 | +#define CADENCE_GEM_MAXREG (0x00000640/4) /* Last valid GEM address */ | ||
27 | |||
28 | /*****************************************/ | ||
29 | #define GEM_NWCTRL_TXSTART 0x00000200 /* Transmit Enable */ | ||
30 | @@ -350,9 +350,9 @@ static inline void rx_desc_set_sar(unsigned *desc, int sar_idx) | ||
31 | } | ||
32 | |||
33 | #define TYPE_CADENCE_GEM "cadence_gem" | ||
34 | -#define GEM(obj) OBJECT_CHECK(GemState, (obj), TYPE_CADENCE_GEM) | ||
35 | +#define CADENCE_GEM(obj) OBJECT_CHECK(CadenceGEMState, (obj), TYPE_CADENCE_GEM) | ||
36 | |||
37 | -typedef struct GemState { | ||
38 | +typedef struct CadenceGEMState { | ||
39 | SysBusDevice parent_obj; | ||
40 | |||
41 | MemoryRegion iomem; | ||
42 | @@ -361,15 +361,15 @@ typedef struct GemState { | ||
43 | qemu_irq irq; | ||
44 | |||
45 | /* GEM registers backing store */ | ||
46 | - uint32_t regs[GEM_MAXREG]; | ||
47 | + uint32_t regs[CADENCE_GEM_MAXREG]; | ||
48 | /* Mask of register bits which are write only */ | ||
49 | - uint32_t regs_wo[GEM_MAXREG]; | ||
50 | + uint32_t regs_wo[CADENCE_GEM_MAXREG]; | ||
51 | /* Mask of register bits which are read only */ | ||
52 | - uint32_t regs_ro[GEM_MAXREG]; | ||
53 | + uint32_t regs_ro[CADENCE_GEM_MAXREG]; | ||
54 | /* Mask of register bits which are clear on read */ | ||
55 | - uint32_t regs_rtc[GEM_MAXREG]; | ||
56 | + uint32_t regs_rtc[CADENCE_GEM_MAXREG]; | ||
57 | /* Mask of register bits which are write 1 to clear */ | ||
58 | - uint32_t regs_w1c[GEM_MAXREG]; | ||
59 | + uint32_t regs_w1c[CADENCE_GEM_MAXREG]; | ||
60 | |||
61 | /* PHY registers backing store */ | ||
62 | uint16_t phy_regs[32]; | ||
63 | @@ -385,7 +385,7 @@ typedef struct GemState { | ||
64 | unsigned rx_desc[2]; | ||
65 | |||
66 | bool sar_active[4]; | ||
67 | -} GemState; | ||
68 | +} CadenceGEMState; | ||
69 | |||
70 | /* The broadcast MAC address: 0xFFFFFFFFFFFF */ | ||
71 | static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
72 | @@ -395,7 +395,7 @@ static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
73 | * One time initialization. | ||
74 | * Set masks to identify which register bits have magical clear properties | ||
75 | */ | ||
76 | -static void gem_init_register_masks(GemState *s) | ||
77 | +static void gem_init_register_masks(CadenceGEMState *s) | ||
78 | { | ||
79 | /* Mask of register bits which are read only */ | ||
80 | memset(&s->regs_ro[0], 0, sizeof(s->regs_ro)); | ||
81 | @@ -430,7 +430,7 @@ static void gem_init_register_masks(GemState *s) | ||
82 | * phy_update_link: | ||
83 | * Make the emulated PHY link state match the QEMU "interface" state. | ||
84 | */ | ||
85 | -static void phy_update_link(GemState *s) | ||
86 | +static void phy_update_link(CadenceGEMState *s) | ||
87 | { | ||
88 | DB_PRINT("down %d\n", qemu_get_queue(s->nic)->link_down); | ||
89 | |||
90 | @@ -450,7 +450,7 @@ static void phy_update_link(GemState *s) | ||
91 | |||
92 | static int gem_can_receive(NetClientState *nc) | ||
93 | { | ||
94 | - GemState *s; | ||
95 | + CadenceGEMState *s; | ||
96 | |||
97 | s = qemu_get_nic_opaque(nc); | ||
98 | |||
99 | @@ -483,7 +483,7 @@ static int gem_can_receive(NetClientState *nc) | ||
100 | * gem_update_int_status: | ||
101 | * Raise or lower interrupt based on current status. | ||
102 | */ | ||
103 | -static void gem_update_int_status(GemState *s) | ||
104 | +static void gem_update_int_status(CadenceGEMState *s) | ||
105 | { | ||
106 | if (s->regs[GEM_ISR]) { | ||
107 | DB_PRINT("asserting int. (0x%08x)\n", s->regs[GEM_ISR]); | ||
108 | @@ -495,7 +495,7 @@ static void gem_update_int_status(GemState *s) | ||
109 | * gem_receive_updatestats: | ||
110 | * Increment receive statistics. | ||
111 | */ | ||
112 | -static void gem_receive_updatestats(GemState *s, const uint8_t *packet, | ||
113 | +static void gem_receive_updatestats(CadenceGEMState *s, const uint8_t *packet, | ||
114 | unsigned bytes) | ||
115 | { | ||
116 | uint64_t octets; | ||
117 | @@ -586,7 +586,7 @@ static unsigned calc_mac_hash(const uint8_t *mac) | ||
118 | * GEM_RM_PROMISCUOUS_ACCEPT, GEM_RX_BROADCAST_ACCEPT, | ||
119 | * GEM_RX_MULTICAST_HASH_ACCEPT or GEM_RX_UNICAST_HASH_ACCEPT | ||
120 | */ | ||
121 | -static int gem_mac_address_filter(GemState *s, const uint8_t *packet) | ||
122 | +static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet) | ||
123 | { | ||
124 | uint8_t *gem_spaddr; | ||
125 | int i; | ||
126 | @@ -636,7 +636,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet) | ||
127 | return GEM_RX_REJECT; | ||
128 | } | ||
129 | |||
130 | -static void gem_get_rx_desc(GemState *s) | ||
131 | +static void gem_get_rx_desc(CadenceGEMState *s) | ||
132 | { | ||
133 | DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr); | ||
134 | /* read current descriptor */ | ||
135 | @@ -660,7 +660,7 @@ static void gem_get_rx_desc(GemState *s) | ||
136 | */ | ||
137 | static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) | ||
138 | { | ||
139 | - GemState *s; | ||
140 | + CadenceGEMState *s; | ||
141 | unsigned rxbufsize, bytes_to_copy; | ||
142 | unsigned rxbuf_offset; | ||
143 | uint8_t rxbuf[2048]; | ||
144 | @@ -810,7 +810,7 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) | ||
145 | * gem_transmit_updatestats: | ||
146 | * Increment transmit statistics. | ||
147 | */ | ||
148 | -static void gem_transmit_updatestats(GemState *s, const uint8_t *packet, | ||
149 | +static void gem_transmit_updatestats(CadenceGEMState *s, const uint8_t *packet, | ||
150 | unsigned bytes) | ||
151 | { | ||
152 | uint64_t octets; | ||
153 | @@ -856,7 +856,7 @@ static void gem_transmit_updatestats(GemState *s, const uint8_t *packet, | ||
154 | * gem_transmit: | ||
155 | * Fish packets out of the descriptor ring and feed them to QEMU | ||
156 | */ | ||
157 | -static void gem_transmit(GemState *s) | ||
158 | +static void gem_transmit(CadenceGEMState *s) | ||
159 | { | ||
160 | unsigned desc[2]; | ||
161 | hwaddr packet_desc_addr; | ||
162 | @@ -976,7 +976,7 @@ static void gem_transmit(GemState *s) | ||
163 | } | ||
164 | } | ||
165 | |||
166 | -static void gem_phy_reset(GemState *s) | ||
167 | +static void gem_phy_reset(CadenceGEMState *s) | ||
168 | { | ||
169 | memset(&s->phy_regs[0], 0, sizeof(s->phy_regs)); | ||
170 | s->phy_regs[PHY_REG_CONTROL] = 0x1140; | ||
171 | @@ -1004,7 +1004,7 @@ static void gem_phy_reset(GemState *s) | ||
172 | static void gem_reset(DeviceState *d) | ||
173 | { | ||
174 | int i; | ||
175 | - GemState *s = GEM(d); | ||
176 | + CadenceGEMState *s = CADENCE_GEM(d); | ||
177 | |||
178 | DB_PRINT("\n"); | ||
179 | |||
180 | @@ -1032,13 +1032,13 @@ static void gem_reset(DeviceState *d) | ||
181 | gem_update_int_status(s); | ||
182 | } | ||
183 | |||
184 | -static uint16_t gem_phy_read(GemState *s, unsigned reg_num) | ||
185 | +static uint16_t gem_phy_read(CadenceGEMState *s, unsigned reg_num) | ||
186 | { | ||
187 | DB_PRINT("reg: %d value: 0x%04x\n", reg_num, s->phy_regs[reg_num]); | ||
188 | return s->phy_regs[reg_num]; | ||
189 | } | ||
190 | |||
191 | -static void gem_phy_write(GemState *s, unsigned reg_num, uint16_t val) | ||
192 | +static void gem_phy_write(CadenceGEMState *s, unsigned reg_num, uint16_t val) | ||
193 | { | ||
194 | DB_PRINT("reg: %d value: 0x%04x\n", reg_num, val); | ||
195 | |||
196 | @@ -1072,10 +1072,10 @@ static void gem_phy_write(GemState *s, unsigned reg_num, uint16_t val) | ||
197 | */ | ||
198 | static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) | ||
199 | { | ||
200 | - GemState *s; | ||
201 | + CadenceGEMState *s; | ||
202 | uint32_t retval; | ||
203 | |||
204 | - s = (GemState *)opaque; | ||
205 | + s = (CadenceGEMState *)opaque; | ||
206 | |||
207 | offset >>= 2; | ||
208 | retval = s->regs[offset]; | ||
209 | @@ -1120,7 +1120,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) | ||
210 | static void gem_write(void *opaque, hwaddr offset, uint64_t val, | ||
211 | unsigned size) | ||
212 | { | ||
213 | - GemState *s = (GemState *)opaque; | ||
214 | + CadenceGEMState *s = (CadenceGEMState *)opaque; | ||
215 | uint32_t readonly; | ||
216 | |||
217 | DB_PRINT("offset: 0x%04x write: 0x%08x ", (unsigned)offset, (unsigned)val); | ||
218 | @@ -1226,7 +1226,7 @@ static NetClientInfo net_gem_info = { | ||
219 | static int gem_init(SysBusDevice *sbd) | ||
220 | { | ||
221 | DeviceState *dev = DEVICE(sbd); | ||
222 | - GemState *s = GEM(dev); | ||
223 | + CadenceGEMState *s = CADENCE_GEM(dev); | ||
224 | |||
225 | DB_PRINT("\n"); | ||
226 | |||
227 | @@ -1248,18 +1248,18 @@ static const VMStateDescription vmstate_cadence_gem = { | ||
228 | .version_id = 2, | ||
229 | .minimum_version_id = 2, | ||
230 | .fields = (VMStateField[]) { | ||
231 | - VMSTATE_UINT32_ARRAY(regs, GemState, GEM_MAXREG), | ||
232 | - VMSTATE_UINT16_ARRAY(phy_regs, GemState, 32), | ||
233 | - VMSTATE_UINT8(phy_loop, GemState), | ||
234 | - VMSTATE_UINT32(rx_desc_addr, GemState), | ||
235 | - VMSTATE_UINT32(tx_desc_addr, GemState), | ||
236 | - VMSTATE_BOOL_ARRAY(sar_active, GemState, 4), | ||
237 | + VMSTATE_UINT32_ARRAY(regs, CadenceGEMState, CADENCE_GEM_MAXREG), | ||
238 | + VMSTATE_UINT16_ARRAY(phy_regs, CadenceGEMState, 32), | ||
239 | + VMSTATE_UINT8(phy_loop, CadenceGEMState), | ||
240 | + VMSTATE_UINT32(rx_desc_addr, CadenceGEMState), | ||
241 | + VMSTATE_UINT32(tx_desc_addr, CadenceGEMState), | ||
242 | + VMSTATE_BOOL_ARRAY(sar_active, CadenceGEMState, 4), | ||
243 | VMSTATE_END_OF_LIST(), | ||
244 | } | ||
245 | }; | ||
246 | |||
247 | static Property gem_properties[] = { | ||
248 | - DEFINE_NIC_PROPERTIES(GemState, conf), | ||
249 | + DEFINE_NIC_PROPERTIES(CadenceGEMState, conf), | ||
250 | DEFINE_PROP_END_OF_LIST(), | ||
251 | }; | ||
252 | |||
253 | @@ -1277,7 +1277,7 @@ static void gem_class_init(ObjectClass *klass, void *data) | ||
254 | static const TypeInfo gem_info = { | ||
255 | .name = TYPE_CADENCE_GEM, | ||
256 | .parent = TYPE_SYS_BUS_DEVICE, | ||
257 | - .instance_size = sizeof(GemState), | ||
258 | + .instance_size = sizeof(CadenceGEMState), | ||
259 | .class_init = gem_class_init, | ||
260 | }; | ||
261 | |||
262 | -- | ||
263 | 2.1.1 | ||
264 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0007-net-cadence_gem-Split-state-struct-and-type-into-hea.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0007-net-cadence_gem-Split-state-struct-and-type-into-hea.patch new file mode 100644 index 00000000..be4b30cf --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0007-net-cadence_gem-Split-state-struct-and-type-into-hea.patch | |||
@@ -0,0 +1,142 @@ | |||
1 | From 3acfa69c02afc5c8f84c4e5b528a18959ddd8c1b Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:46 -0800 | ||
4 | Subject: [PATCH 07/15] net: cadence_gem: Split state struct and type into | ||
5 | header | ||
6 | |||
7 | To allow using the device with modern SoC programming conventions. The | ||
8 | state struct needs to be visible to embed the device in SoC containers. | ||
9 | |||
10 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
11 | --- | ||
12 | hw/net/cadence_gem.c | 43 +------------------------------------- | ||
13 | include/hw/net/cadence_gem.h | 49 ++++++++++++++++++++++++++++++++++++++++++++ | ||
14 | 2 files changed, 50 insertions(+), 42 deletions(-) | ||
15 | create mode 100644 include/hw/net/cadence_gem.h | ||
16 | |||
17 | diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c | ||
18 | index 5994306..dafe914 100644 | ||
19 | --- a/hw/net/cadence_gem.c | ||
20 | +++ b/hw/net/cadence_gem.c | ||
21 | @@ -24,8 +24,7 @@ | ||
22 | |||
23 | #include <zlib.h> /* For crc32 */ | ||
24 | |||
25 | -#include "hw/sysbus.h" | ||
26 | -#include "net/net.h" | ||
27 | +#include "hw/net/cadence_gem.h" | ||
28 | #include "net/checksum.h" | ||
29 | |||
30 | #ifdef CADENCE_GEM_ERR_DEBUG | ||
31 | @@ -141,8 +140,6 @@ | ||
32 | #define GEM_DESCONF6 (0x00000294/4) | ||
33 | #define GEM_DESCONF7 (0x00000298/4) | ||
34 | |||
35 | -#define CADENCE_GEM_MAXREG (0x00000640/4) /* Last valid GEM address */ | ||
36 | - | ||
37 | /*****************************************/ | ||
38 | #define GEM_NWCTRL_TXSTART 0x00000200 /* Transmit Enable */ | ||
39 | #define GEM_NWCTRL_TXENA 0x00000008 /* Transmit Enable */ | ||
40 | @@ -349,44 +346,6 @@ static inline void rx_desc_set_sar(unsigned *desc, int sar_idx) | ||
41 | desc[1] |= R_DESC_1_RX_SAR_MATCH; | ||
42 | } | ||
43 | |||
44 | -#define TYPE_CADENCE_GEM "cadence_gem" | ||
45 | -#define CADENCE_GEM(obj) OBJECT_CHECK(CadenceGEMState, (obj), TYPE_CADENCE_GEM) | ||
46 | - | ||
47 | -typedef struct CadenceGEMState { | ||
48 | - SysBusDevice parent_obj; | ||
49 | - | ||
50 | - MemoryRegion iomem; | ||
51 | - NICState *nic; | ||
52 | - NICConf conf; | ||
53 | - qemu_irq irq; | ||
54 | - | ||
55 | - /* GEM registers backing store */ | ||
56 | - uint32_t regs[CADENCE_GEM_MAXREG]; | ||
57 | - /* Mask of register bits which are write only */ | ||
58 | - uint32_t regs_wo[CADENCE_GEM_MAXREG]; | ||
59 | - /* Mask of register bits which are read only */ | ||
60 | - uint32_t regs_ro[CADENCE_GEM_MAXREG]; | ||
61 | - /* Mask of register bits which are clear on read */ | ||
62 | - uint32_t regs_rtc[CADENCE_GEM_MAXREG]; | ||
63 | - /* Mask of register bits which are write 1 to clear */ | ||
64 | - uint32_t regs_w1c[CADENCE_GEM_MAXREG]; | ||
65 | - | ||
66 | - /* PHY registers backing store */ | ||
67 | - uint16_t phy_regs[32]; | ||
68 | - | ||
69 | - uint8_t phy_loop; /* Are we in phy loopback? */ | ||
70 | - | ||
71 | - /* The current DMA descriptor pointers */ | ||
72 | - uint32_t rx_desc_addr; | ||
73 | - uint32_t tx_desc_addr; | ||
74 | - | ||
75 | - uint8_t can_rx_state; /* Debug only */ | ||
76 | - | ||
77 | - unsigned rx_desc[2]; | ||
78 | - | ||
79 | - bool sar_active[4]; | ||
80 | -} CadenceGEMState; | ||
81 | - | ||
82 | /* The broadcast MAC address: 0xFFFFFFFFFFFF */ | ||
83 | static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
84 | |||
85 | diff --git a/include/hw/net/cadence_gem.h b/include/hw/net/cadence_gem.h | ||
86 | new file mode 100644 | ||
87 | index 0000000..e6413ff | ||
88 | --- /dev/null | ||
89 | +++ b/include/hw/net/cadence_gem.h | ||
90 | @@ -0,0 +1,49 @@ | ||
91 | +#ifndef CADENCE_GEM_H_ | ||
92 | + | ||
93 | +#define TYPE_CADENCE_GEM "cadence_gem" | ||
94 | +#define CADENCE_GEM(obj) OBJECT_CHECK(CadenceGEMState, (obj), TYPE_CADENCE_GEM) | ||
95 | + | ||
96 | +#include "net/net.h" | ||
97 | +#include "hw/sysbus.h" | ||
98 | + | ||
99 | +#define CADENCE_GEM_MAXREG (0x00000640/4) /* Last valid GEM address */ | ||
100 | + | ||
101 | +typedef struct CadenceGEMState { | ||
102 | + /*< private >*/ | ||
103 | + SysBusDevice parent_obj; | ||
104 | + /*< public >*/ | ||
105 | + | ||
106 | + MemoryRegion iomem; | ||
107 | + NICState *nic; | ||
108 | + NICConf conf; | ||
109 | + qemu_irq irq; | ||
110 | + | ||
111 | + /* GEM registers backing store */ | ||
112 | + uint32_t regs[CADENCE_GEM_MAXREG]; | ||
113 | + /* Mask of register bits which are write only */ | ||
114 | + uint32_t regs_wo[CADENCE_GEM_MAXREG]; | ||
115 | + /* Mask of register bits which are read only */ | ||
116 | + uint32_t regs_ro[CADENCE_GEM_MAXREG]; | ||
117 | + /* Mask of register bits which are clear on read */ | ||
118 | + uint32_t regs_rtc[CADENCE_GEM_MAXREG]; | ||
119 | + /* Mask of register bits which are write 1 to clear */ | ||
120 | + uint32_t regs_w1c[CADENCE_GEM_MAXREG]; | ||
121 | + | ||
122 | + /* PHY registers backing store */ | ||
123 | + uint16_t phy_regs[32]; | ||
124 | + | ||
125 | + uint8_t phy_loop; /* Are we in phy loopback? */ | ||
126 | + | ||
127 | + /* The current DMA descriptor pointers */ | ||
128 | + uint32_t rx_desc_addr; | ||
129 | + uint32_t tx_desc_addr; | ||
130 | + | ||
131 | + uint8_t can_rx_state; /* Debug only */ | ||
132 | + | ||
133 | + unsigned rx_desc[2]; | ||
134 | + | ||
135 | + bool sar_active[4]; | ||
136 | +} CadenceGEMState; | ||
137 | + | ||
138 | +#define CADENCE_GEM_H_ | ||
139 | +#endif | ||
140 | -- | ||
141 | 2.1.1 | ||
142 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0008-arm-xilinx-zynq-mp-Add-GEM-support.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0008-arm-xilinx-zynq-mp-Add-GEM-support.patch new file mode 100644 index 00000000..0cb42127 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0008-arm-xilinx-zynq-mp-Add-GEM-support.patch | |||
@@ -0,0 +1,107 @@ | |||
1 | From eed690e857579901b4571a250af0259e5051692f Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:48 -0800 | ||
4 | Subject: [PATCH 08/15] arm: xilinx-zynq-mp: Add GEM support | ||
5 | |||
6 | There are 4x Cadence GEMs in Zynq MP. Add them. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | hw/arm/xlnx-zynq-mp.c | 32 ++++++++++++++++++++++++++++++++ | ||
11 | include/hw/arm/xlnx-zynq-mp.h | 3 +++ | ||
12 | 2 files changed, 35 insertions(+) | ||
13 | |||
14 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
15 | index be82a66..2ef57d9 100644 | ||
16 | --- a/hw/arm/xlnx-zynq-mp.c | ||
17 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
18 | @@ -25,6 +25,14 @@ | ||
19 | #define GIC_DIST_ADDR 0xf9010000 | ||
20 | #define GIC_CPU_ADDR 0xf9020000 | ||
21 | |||
22 | +static const uint64_t gem_addr[XLNX_ZYNQ_MP_NUM_GEMS] = { | ||
23 | + 0xFF0B0000, 0xFF0C0000, 0xFF0D0000, 0xFF0E0000, | ||
24 | +}; | ||
25 | + | ||
26 | +static const int gem_intr[XLNX_ZYNQ_MP_NUM_GEMS] = { | ||
27 | + 57, 59, 61, 63, | ||
28 | +}; | ||
29 | + | ||
30 | static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) | ||
31 | { | ||
32 | return GIC_NUM_SPI_INTR + cpu_nr * 32 + ppi_index; | ||
33 | @@ -43,6 +51,11 @@ static void xlnx_zynq_mp_init(Object *obj) | ||
34 | |||
35 | object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); | ||
36 | qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); | ||
37 | + | ||
38 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_GEMS; i++) { | ||
39 | + object_initialize(&s->gem[i], sizeof(s->gem[i]), TYPE_CADENCE_GEM); | ||
40 | + qdev_set_parent_bus(DEVICE(&s->gem[i]), sysbus_get_default()); | ||
41 | + } | ||
42 | } | ||
43 | |||
44 | #define ERR_PROP_CHECK_RETURN(err, errp) do { \ | ||
45 | @@ -56,6 +69,7 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
46 | { | ||
47 | XlnxZynqMPState *s = XLNX_ZYNQ_MP(dev); | ||
48 | uint8_t i; | ||
49 | + qemu_irq gic_spi[GIC_NUM_SPI_INTR]; | ||
50 | Error *err = NULL; | ||
51 | |||
52 | qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); | ||
53 | @@ -81,6 +95,24 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
54 | arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); | ||
55 | qdev_connect_gpio_out(DEVICE(&s->cpu[i]), 1, irq); | ||
56 | } | ||
57 | + | ||
58 | + for (i = 0; i < GIC_NUM_SPI_INTR; i++) { | ||
59 | + gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); | ||
60 | + } | ||
61 | + | ||
62 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_GEMS; i++) { | ||
63 | + NICInfo *nd = &nd_table[i]; | ||
64 | + | ||
65 | + if (nd->used) { | ||
66 | + qemu_check_nic_model(nd, TYPE_CADENCE_GEM); | ||
67 | + qdev_set_nic_properties(DEVICE(&s->gem[i]), nd); | ||
68 | + } | ||
69 | + object_property_set_bool(OBJECT(&s->gem[i]), true, "realized", &err); | ||
70 | + ERR_PROP_CHECK_RETURN(err, errp); | ||
71 | + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem[i]), 0, gem_addr[i]); | ||
72 | + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 0, | ||
73 | + gic_spi[gem_intr[i]]); | ||
74 | + } | ||
75 | } | ||
76 | |||
77 | static void xlnx_zynq_mp_class_init(ObjectClass *oc, void *data) | ||
78 | diff --git a/include/hw/arm/xlnx-zynq-mp.h b/include/hw/arm/xlnx-zynq-mp.h | ||
79 | index 22b2af0..470503c 100644 | ||
80 | --- a/include/hw/arm/xlnx-zynq-mp.h | ||
81 | +++ b/include/hw/arm/xlnx-zynq-mp.h | ||
82 | @@ -3,12 +3,14 @@ | ||
83 | #include "qemu-common.h" | ||
84 | #include "hw/arm/arm.h" | ||
85 | #include "hw/intc/arm_gic.h" | ||
86 | +#include "hw/net/cadence_gem.h" | ||
87 | |||
88 | #define TYPE_XLNX_ZYNQ_MP "xlnx,zynq-mp" | ||
89 | #define XLNX_ZYNQ_MP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ | ||
90 | TYPE_XLNX_ZYNQ_MP) | ||
91 | |||
92 | #define XLNX_ZYNQ_MP_NUM_CPUS 4 | ||
93 | +#define XLNX_ZYNQ_MP_NUM_GEMS 4 | ||
94 | |||
95 | typedef struct XlnxZynqMPState { | ||
96 | /*< private >*/ | ||
97 | @@ -17,6 +19,7 @@ typedef struct XlnxZynqMPState { | ||
98 | |||
99 | ARMCPU cpu[XLNX_ZYNQ_MP_NUM_CPUS]; | ||
100 | GICState gic; | ||
101 | + CadenceGEMState gem[XLNX_ZYNQ_MP_NUM_GEMS]; | ||
102 | } XlnxZynqMPState; | ||
103 | |||
104 | #define XLNX_ZYNQ_MP_H_ | ||
105 | -- | ||
106 | 2.1.1 | ||
107 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0009-char-cadence_uart-Clean-up-variable-names.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0009-char-cadence_uart-Clean-up-variable-names.patch new file mode 100644 index 00000000..b864f470 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0009-char-cadence_uart-Clean-up-variable-names.patch | |||
@@ -0,0 +1,324 @@ | |||
1 | From 246128b68939e7cede11cf60cffbbc194e7643ed Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:49 -0800 | ||
4 | Subject: [PATCH 09/15] char: cadence_uart: Clean up variable names | ||
5 | |||
6 | In preparation for migrating the state struct and type cast macro to a public | ||
7 | header. The acronym "UART" on it's own is not specific enough to be used in a | ||
8 | more global namespace so preface with "cadence". Fix the capitalisation of | ||
9 | "uart" in the state type while touching the typename. Preface macros | ||
10 | used by the state struct itself with CADENCE_UART so they don't conflict | ||
11 | in namespace either. | ||
12 | |||
13 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
14 | --- | ||
15 | hw/char/cadence_uart.c | 100 ++++++++++++++++++++++++++----------------------- | ||
16 | 1 file changed, 53 insertions(+), 47 deletions(-) | ||
17 | |||
18 | diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c | ||
19 | index 7044b35..23f548d 100644 | ||
20 | --- a/hw/char/cadence_uart.c | ||
21 | +++ b/hw/char/cadence_uart.c | ||
22 | @@ -85,8 +85,8 @@ | ||
23 | #define LOCAL_LOOPBACK (0x2 << UART_MR_CHMODE_SH) | ||
24 | #define REMOTE_LOOPBACK (0x3 << UART_MR_CHMODE_SH) | ||
25 | |||
26 | -#define RX_FIFO_SIZE 16 | ||
27 | -#define TX_FIFO_SIZE 16 | ||
28 | +#define CADENCE_UART_RX_FIFO_SIZE 16 | ||
29 | +#define CADENCE_UART_TX_FIFO_SIZE 16 | ||
30 | #define UART_INPUT_CLK 50000000 | ||
31 | |||
32 | #define R_CR (0x00/4) | ||
33 | @@ -108,10 +108,11 @@ | ||
34 | #define R_PWID (0x40/4) | ||
35 | #define R_TTRIG (0x44/4) | ||
36 | |||
37 | -#define R_MAX (R_TTRIG + 1) | ||
38 | +#define CADENCE_UART_R_MAX (0x48/4) | ||
39 | |||
40 | #define TYPE_CADENCE_UART "cadence_uart" | ||
41 | -#define CADENCE_UART(obj) OBJECT_CHECK(UartState, (obj), TYPE_CADENCE_UART) | ||
42 | +#define CADENCE_UART(obj) OBJECT_CHECK(CadenceUARTState, (obj), \ | ||
43 | + TYPE_CADENCE_UART) | ||
44 | |||
45 | typedef struct { | ||
46 | /*< private >*/ | ||
47 | @@ -119,9 +120,9 @@ typedef struct { | ||
48 | /*< public >*/ | ||
49 | |||
50 | MemoryRegion iomem; | ||
51 | - uint32_t r[R_MAX]; | ||
52 | - uint8_t rx_fifo[RX_FIFO_SIZE]; | ||
53 | - uint8_t tx_fifo[TX_FIFO_SIZE]; | ||
54 | + uint32_t r[CADENCE_UART_R_MAX]; | ||
55 | + uint8_t rx_fifo[CADENCE_UART_RX_FIFO_SIZE]; | ||
56 | + uint8_t tx_fifo[CADENCE_UART_TX_FIFO_SIZE]; | ||
57 | uint32_t rx_wpos; | ||
58 | uint32_t rx_count; | ||
59 | uint32_t tx_count; | ||
60 | @@ -129,17 +130,19 @@ typedef struct { | ||
61 | CharDriverState *chr; | ||
62 | qemu_irq irq; | ||
63 | QEMUTimer *fifo_trigger_handle; | ||
64 | -} UartState; | ||
65 | +} CadenceUARTState; | ||
66 | |||
67 | -static void uart_update_status(UartState *s) | ||
68 | +static void uart_update_status(CadenceUARTState *s) | ||
69 | { | ||
70 | s->r[R_SR] = 0; | ||
71 | |||
72 | - s->r[R_SR] |= s->rx_count == RX_FIFO_SIZE ? UART_SR_INTR_RFUL : 0; | ||
73 | + s->r[R_SR] |= s->rx_count == CADENCE_UART_RX_FIFO_SIZE ? UART_SR_INTR_RFUL | ||
74 | + : 0; | ||
75 | s->r[R_SR] |= !s->rx_count ? UART_SR_INTR_REMPTY : 0; | ||
76 | s->r[R_SR] |= s->rx_count >= s->r[R_RTRIG] ? UART_SR_INTR_RTRIG : 0; | ||
77 | |||
78 | - s->r[R_SR] |= s->tx_count == TX_FIFO_SIZE ? UART_SR_INTR_TFUL : 0; | ||
79 | + s->r[R_SR] |= s->tx_count == CADENCE_UART_TX_FIFO_SIZE ? UART_SR_INTR_TFUL | ||
80 | + : 0; | ||
81 | s->r[R_SR] |= !s->tx_count ? UART_SR_INTR_TEMPTY : 0; | ||
82 | s->r[R_SR] |= s->tx_count >= s->r[R_TTRIG] ? UART_SR_TTRIG : 0; | ||
83 | |||
84 | @@ -150,14 +153,14 @@ static void uart_update_status(UartState *s) | ||
85 | |||
86 | static void fifo_trigger_update(void *opaque) | ||
87 | { | ||
88 | - UartState *s = (UartState *)opaque; | ||
89 | + CadenceUARTState *s = opaque; | ||
90 | |||
91 | s->r[R_CISR] |= UART_INTR_TIMEOUT; | ||
92 | |||
93 | uart_update_status(s); | ||
94 | } | ||
95 | |||
96 | -static void uart_rx_reset(UartState *s) | ||
97 | +static void uart_rx_reset(CadenceUARTState *s) | ||
98 | { | ||
99 | s->rx_wpos = 0; | ||
100 | s->rx_count = 0; | ||
101 | @@ -166,12 +169,12 @@ static void uart_rx_reset(UartState *s) | ||
102 | } | ||
103 | } | ||
104 | |||
105 | -static void uart_tx_reset(UartState *s) | ||
106 | +static void uart_tx_reset(CadenceUARTState *s) | ||
107 | { | ||
108 | s->tx_count = 0; | ||
109 | } | ||
110 | |||
111 | -static void uart_send_breaks(UartState *s) | ||
112 | +static void uart_send_breaks(CadenceUARTState *s) | ||
113 | { | ||
114 | int break_enabled = 1; | ||
115 | |||
116 | @@ -181,7 +184,7 @@ static void uart_send_breaks(UartState *s) | ||
117 | } | ||
118 | } | ||
119 | |||
120 | -static void uart_parameters_setup(UartState *s) | ||
121 | +static void uart_parameters_setup(CadenceUARTState *s) | ||
122 | { | ||
123 | QEMUSerialSetParams ssp; | ||
124 | unsigned int baud_rate, packet_size; | ||
125 | @@ -236,20 +239,20 @@ static void uart_parameters_setup(UartState *s) | ||
126 | |||
127 | static int uart_can_receive(void *opaque) | ||
128 | { | ||
129 | - UartState *s = (UartState *)opaque; | ||
130 | - int ret = MAX(RX_FIFO_SIZE, TX_FIFO_SIZE); | ||
131 | + CadenceUARTState *s = opaque; | ||
132 | + int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE); | ||
133 | uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE; | ||
134 | |||
135 | if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) { | ||
136 | - ret = MIN(ret, RX_FIFO_SIZE - s->rx_count); | ||
137 | + ret = MIN(ret, CADENCE_UART_RX_FIFO_SIZE - s->rx_count); | ||
138 | } | ||
139 | if (ch_mode == REMOTE_LOOPBACK || ch_mode == ECHO_MODE) { | ||
140 | - ret = MIN(ret, TX_FIFO_SIZE - s->tx_count); | ||
141 | + ret = MIN(ret, CADENCE_UART_TX_FIFO_SIZE - s->tx_count); | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | -static void uart_ctrl_update(UartState *s) | ||
147 | +static void uart_ctrl_update(CadenceUARTState *s) | ||
148 | { | ||
149 | if (s->r[R_CR] & UART_CR_TXRST) { | ||
150 | uart_tx_reset(s); | ||
151 | @@ -268,7 +271,7 @@ static void uart_ctrl_update(UartState *s) | ||
152 | |||
153 | static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size) | ||
154 | { | ||
155 | - UartState *s = (UartState *)opaque; | ||
156 | + CadenceUARTState *s = opaque; | ||
157 | uint64_t new_rx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | ||
158 | int i; | ||
159 | |||
160 | @@ -276,12 +279,12 @@ static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size) | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | - if (s->rx_count == RX_FIFO_SIZE) { | ||
165 | + if (s->rx_count == CADENCE_UART_RX_FIFO_SIZE) { | ||
166 | s->r[R_CISR] |= UART_INTR_ROVR; | ||
167 | } else { | ||
168 | for (i = 0; i < size; i++) { | ||
169 | s->rx_fifo[s->rx_wpos] = buf[i]; | ||
170 | - s->rx_wpos = (s->rx_wpos + 1) % RX_FIFO_SIZE; | ||
171 | + s->rx_wpos = (s->rx_wpos + 1) % CADENCE_UART_RX_FIFO_SIZE; | ||
172 | s->rx_count++; | ||
173 | } | ||
174 | timer_mod(s->fifo_trigger_handle, new_rx_time + | ||
175 | @@ -293,7 +296,7 @@ static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size) | ||
176 | static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, | ||
177 | void *opaque) | ||
178 | { | ||
179 | - UartState *s = opaque; | ||
180 | + CadenceUARTState *s = opaque; | ||
181 | int ret; | ||
182 | |||
183 | /* instant drain the fifo when there's no back-end */ | ||
184 | @@ -320,14 +323,15 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, | ||
185 | return FALSE; | ||
186 | } | ||
187 | |||
188 | -static void uart_write_tx_fifo(UartState *s, const uint8_t *buf, int size) | ||
189 | +static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf, | ||
190 | + int size) | ||
191 | { | ||
192 | if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) { | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | - if (size > TX_FIFO_SIZE - s->tx_count) { | ||
197 | - size = TX_FIFO_SIZE - s->tx_count; | ||
198 | + if (size > CADENCE_UART_TX_FIFO_SIZE - s->tx_count) { | ||
199 | + size = CADENCE_UART_TX_FIFO_SIZE - s->tx_count; | ||
200 | /* | ||
201 | * This can only be a guest error via a bad tx fifo register push, | ||
202 | * as can_receive() should stop remote loop and echo modes ever getting | ||
203 | @@ -345,7 +349,7 @@ static void uart_write_tx_fifo(UartState *s, const uint8_t *buf, int size) | ||
204 | |||
205 | static void uart_receive(void *opaque, const uint8_t *buf, int size) | ||
206 | { | ||
207 | - UartState *s = (UartState *)opaque; | ||
208 | + CadenceUARTState *s = opaque; | ||
209 | uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE; | ||
210 | |||
211 | if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) { | ||
212 | @@ -358,7 +362,7 @@ static void uart_receive(void *opaque, const uint8_t *buf, int size) | ||
213 | |||
214 | static void uart_event(void *opaque, int event) | ||
215 | { | ||
216 | - UartState *s = (UartState *)opaque; | ||
217 | + CadenceUARTState *s = opaque; | ||
218 | uint8_t buf = '\0'; | ||
219 | |||
220 | if (event == CHR_EVENT_BREAK) { | ||
221 | @@ -368,15 +372,15 @@ static void uart_event(void *opaque, int event) | ||
222 | uart_update_status(s); | ||
223 | } | ||
224 | |||
225 | -static void uart_read_rx_fifo(UartState *s, uint32_t *c) | ||
226 | +static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c) | ||
227 | { | ||
228 | if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) { | ||
229 | return; | ||
230 | } | ||
231 | |||
232 | if (s->rx_count) { | ||
233 | - uint32_t rx_rpos = | ||
234 | - (RX_FIFO_SIZE + s->rx_wpos - s->rx_count) % RX_FIFO_SIZE; | ||
235 | + uint32_t rx_rpos = (CADENCE_UART_RX_FIFO_SIZE + s->rx_wpos - | ||
236 | + s->rx_count) % CADENCE_UART_RX_FIFO_SIZE; | ||
237 | *c = s->rx_fifo[rx_rpos]; | ||
238 | s->rx_count--; | ||
239 | |||
240 | @@ -393,7 +397,7 @@ static void uart_read_rx_fifo(UartState *s, uint32_t *c) | ||
241 | static void uart_write(void *opaque, hwaddr offset, | ||
242 | uint64_t value, unsigned size) | ||
243 | { | ||
244 | - UartState *s = (UartState *)opaque; | ||
245 | + CadenceUARTState *s = opaque; | ||
246 | |||
247 | DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value); | ||
248 | offset >>= 2; | ||
249 | @@ -437,11 +441,11 @@ static void uart_write(void *opaque, hwaddr offset, | ||
250 | static uint64_t uart_read(void *opaque, hwaddr offset, | ||
251 | unsigned size) | ||
252 | { | ||
253 | - UartState *s = (UartState *)opaque; | ||
254 | + CadenceUARTState *s = opaque; | ||
255 | uint32_t c = 0; | ||
256 | |||
257 | offset >>= 2; | ||
258 | - if (offset >= R_MAX) { | ||
259 | + if (offset >= CADENCE_UART_R_MAX) { | ||
260 | c = 0; | ||
261 | } else if (offset == R_TX_RX) { | ||
262 | uart_read_rx_fifo(s, &c); | ||
263 | @@ -461,7 +465,7 @@ static const MemoryRegionOps uart_ops = { | ||
264 | |||
265 | static void cadence_uart_reset(DeviceState *dev) | ||
266 | { | ||
267 | - UartState *s = CADENCE_UART(dev); | ||
268 | + CadenceUARTState *s = CADENCE_UART(dev); | ||
269 | |||
270 | s->r[R_CR] = 0x00000128; | ||
271 | s->r[R_IMR] = 0; | ||
272 | @@ -478,7 +482,7 @@ static void cadence_uart_reset(DeviceState *dev) | ||
273 | |||
274 | static int cadence_uart_init(SysBusDevice *dev) | ||
275 | { | ||
276 | - UartState *s = CADENCE_UART(dev); | ||
277 | + CadenceUARTState *s = CADENCE_UART(dev); | ||
278 | |||
279 | memory_region_init_io(&s->iomem, OBJECT(s), &uart_ops, s, "uart", 0x1000); | ||
280 | sysbus_init_mmio(dev, &s->iomem); | ||
281 | @@ -501,7 +505,7 @@ static int cadence_uart_init(SysBusDevice *dev) | ||
282 | |||
283 | static int cadence_uart_post_load(void *opaque, int version_id) | ||
284 | { | ||
285 | - UartState *s = opaque; | ||
286 | + CadenceUARTState *s = opaque; | ||
287 | |||
288 | uart_parameters_setup(s); | ||
289 | uart_update_status(s); | ||
290 | @@ -514,13 +518,15 @@ static const VMStateDescription vmstate_cadence_uart = { | ||
291 | .minimum_version_id = 2, | ||
292 | .post_load = cadence_uart_post_load, | ||
293 | .fields = (VMStateField[]) { | ||
294 | - VMSTATE_UINT32_ARRAY(r, UartState, R_MAX), | ||
295 | - VMSTATE_UINT8_ARRAY(rx_fifo, UartState, RX_FIFO_SIZE), | ||
296 | - VMSTATE_UINT8_ARRAY(tx_fifo, UartState, RX_FIFO_SIZE), | ||
297 | - VMSTATE_UINT32(rx_count, UartState), | ||
298 | - VMSTATE_UINT32(tx_count, UartState), | ||
299 | - VMSTATE_UINT32(rx_wpos, UartState), | ||
300 | - VMSTATE_TIMER_PTR(fifo_trigger_handle, UartState), | ||
301 | + VMSTATE_UINT32_ARRAY(r, CadenceUARTState, CADENCE_UART_R_MAX), | ||
302 | + VMSTATE_UINT8_ARRAY(rx_fifo, CadenceUARTState, | ||
303 | + CADENCE_UART_RX_FIFO_SIZE), | ||
304 | + VMSTATE_UINT8_ARRAY(tx_fifo, CadenceUARTState, | ||
305 | + CADENCE_UART_TX_FIFO_SIZE), | ||
306 | + VMSTATE_UINT32(rx_count, CadenceUARTState), | ||
307 | + VMSTATE_UINT32(tx_count, CadenceUARTState), | ||
308 | + VMSTATE_UINT32(rx_wpos, CadenceUARTState), | ||
309 | + VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState), | ||
310 | VMSTATE_END_OF_LIST() | ||
311 | } | ||
312 | }; | ||
313 | @@ -538,7 +544,7 @@ static void cadence_uart_class_init(ObjectClass *klass, void *data) | ||
314 | static const TypeInfo cadence_uart_info = { | ||
315 | .name = TYPE_CADENCE_UART, | ||
316 | .parent = TYPE_SYS_BUS_DEVICE, | ||
317 | - .instance_size = sizeof(UartState), | ||
318 | + .instance_size = sizeof(CadenceUARTState), | ||
319 | .class_init = cadence_uart_class_init, | ||
320 | }; | ||
321 | |||
322 | -- | ||
323 | 2.1.1 | ||
324 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0010-char-cadence_uart-Split-state-struct-and-type-into-h.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0010-char-cadence_uart-Split-state-struct-and-type-into-h.patch new file mode 100644 index 00000000..6fe3f98a --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0010-char-cadence_uart-Split-state-struct-and-type-into-h.patch | |||
@@ -0,0 +1,114 @@ | |||
1 | From 33e66004378aa203562e5b051282c1a7ffb8ee3b Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:50 -0800 | ||
4 | Subject: [PATCH 10/15] char: cadence_uart: Split state struct and type into | ||
5 | header | ||
6 | |||
7 | To allow using the device with modern SoC programming conventions. The | ||
8 | state struct needs to be visible to embed the device in SoC containers. | ||
9 | |||
10 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
11 | --- | ||
12 | hw/char/cadence_uart.c | 29 +---------------------------- | ||
13 | include/hw/char/cadence_uart.h | 35 +++++++++++++++++++++++++++++++++++ | ||
14 | 2 files changed, 36 insertions(+), 28 deletions(-) | ||
15 | create mode 100644 include/hw/char/cadence_uart.h | ||
16 | |||
17 | diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c | ||
18 | index 23f548d..4509e01 100644 | ||
19 | --- a/hw/char/cadence_uart.c | ||
20 | +++ b/hw/char/cadence_uart.c | ||
21 | @@ -16,9 +16,7 @@ | ||
22 | * with this program; if not, see <http://www.gnu.org/licenses/>. | ||
23 | */ | ||
24 | |||
25 | -#include "hw/sysbus.h" | ||
26 | -#include "sysemu/char.h" | ||
27 | -#include "qemu/timer.h" | ||
28 | +#include "hw/char/cadence_uart.h" | ||
29 | |||
30 | #ifdef CADENCE_UART_ERR_DEBUG | ||
31 | #define DB_PRINT(...) do { \ | ||
32 | @@ -85,8 +83,6 @@ | ||
33 | #define LOCAL_LOOPBACK (0x2 << UART_MR_CHMODE_SH) | ||
34 | #define REMOTE_LOOPBACK (0x3 << UART_MR_CHMODE_SH) | ||
35 | |||
36 | -#define CADENCE_UART_RX_FIFO_SIZE 16 | ||
37 | -#define CADENCE_UART_TX_FIFO_SIZE 16 | ||
38 | #define UART_INPUT_CLK 50000000 | ||
39 | |||
40 | #define R_CR (0x00/4) | ||
41 | @@ -108,29 +104,6 @@ | ||
42 | #define R_PWID (0x40/4) | ||
43 | #define R_TTRIG (0x44/4) | ||
44 | |||
45 | -#define CADENCE_UART_R_MAX (0x48/4) | ||
46 | - | ||
47 | -#define TYPE_CADENCE_UART "cadence_uart" | ||
48 | -#define CADENCE_UART(obj) OBJECT_CHECK(CadenceUARTState, (obj), \ | ||
49 | - TYPE_CADENCE_UART) | ||
50 | - | ||
51 | -typedef struct { | ||
52 | - /*< private >*/ | ||
53 | - SysBusDevice parent_obj; | ||
54 | - /*< public >*/ | ||
55 | - | ||
56 | - MemoryRegion iomem; | ||
57 | - uint32_t r[CADENCE_UART_R_MAX]; | ||
58 | - uint8_t rx_fifo[CADENCE_UART_RX_FIFO_SIZE]; | ||
59 | - uint8_t tx_fifo[CADENCE_UART_TX_FIFO_SIZE]; | ||
60 | - uint32_t rx_wpos; | ||
61 | - uint32_t rx_count; | ||
62 | - uint32_t tx_count; | ||
63 | - uint64_t char_tx_time; | ||
64 | - CharDriverState *chr; | ||
65 | - qemu_irq irq; | ||
66 | - QEMUTimer *fifo_trigger_handle; | ||
67 | -} CadenceUARTState; | ||
68 | |||
69 | static void uart_update_status(CadenceUARTState *s) | ||
70 | { | ||
71 | diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h | ||
72 | new file mode 100644 | ||
73 | index 0000000..0404785 | ||
74 | --- /dev/null | ||
75 | +++ b/include/hw/char/cadence_uart.h | ||
76 | @@ -0,0 +1,35 @@ | ||
77 | +#ifndef CADENCE_UART_H_ | ||
78 | + | ||
79 | +#include "hw/sysbus.h" | ||
80 | +#include "sysemu/char.h" | ||
81 | +#include "qemu/timer.h" | ||
82 | + | ||
83 | +#define CADENCE_UART_RX_FIFO_SIZE 16 | ||
84 | +#define CADENCE_UART_TX_FIFO_SIZE 16 | ||
85 | + | ||
86 | +#define CADENCE_UART_R_MAX (0x48/4) | ||
87 | + | ||
88 | +#define TYPE_CADENCE_UART "cadence_uart" | ||
89 | +#define CADENCE_UART(obj) OBJECT_CHECK(CadenceUARTState, (obj), \ | ||
90 | + TYPE_CADENCE_UART) | ||
91 | + | ||
92 | +typedef struct { | ||
93 | + /*< private >*/ | ||
94 | + SysBusDevice parent_obj; | ||
95 | + /*< public >*/ | ||
96 | + | ||
97 | + MemoryRegion iomem; | ||
98 | + uint32_t r[CADENCE_UART_R_MAX]; | ||
99 | + uint8_t rx_fifo[CADENCE_UART_RX_FIFO_SIZE]; | ||
100 | + uint8_t tx_fifo[CADENCE_UART_TX_FIFO_SIZE]; | ||
101 | + uint32_t rx_wpos; | ||
102 | + uint32_t rx_count; | ||
103 | + uint32_t tx_count; | ||
104 | + uint64_t char_tx_time; | ||
105 | + CharDriverState *chr; | ||
106 | + qemu_irq irq; | ||
107 | + QEMUTimer *fifo_trigger_handle; | ||
108 | +} CadenceUARTState; | ||
109 | + | ||
110 | +#define CADENCE_UART_H_ | ||
111 | +#endif | ||
112 | -- | ||
113 | 2.1.1 | ||
114 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0011-arm-xilinx-zynq-mp-Add-UART-support.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0011-arm-xilinx-zynq-mp-Add-UART-support.patch new file mode 100644 index 00000000..166aa129 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0011-arm-xilinx-zynq-mp-Add-UART-support.patch | |||
@@ -0,0 +1,90 @@ | |||
1 | From ef634b1cf1766a5798868d1299a9a4ae2e87bcc9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:51 -0800 | ||
4 | Subject: [PATCH 11/15] arm: xilinx-zynq-mp: Add UART support | ||
5 | |||
6 | There are 2x Cadence UARTSs in Zynq MP. Add them. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | hw/arm/xlnx-zynq-mp.c | 21 +++++++++++++++++++++ | ||
11 | include/hw/arm/xlnx-zynq-mp.h | 3 +++ | ||
12 | 2 files changed, 24 insertions(+) | ||
13 | |||
14 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
15 | index 2ef57d9..9d7e834 100644 | ||
16 | --- a/hw/arm/xlnx-zynq-mp.c | ||
17 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
18 | @@ -33,6 +33,14 @@ static const int gem_intr[XLNX_ZYNQ_MP_NUM_GEMS] = { | ||
19 | 57, 59, 61, 63, | ||
20 | }; | ||
21 | |||
22 | +static const uint64_t uart_addr[XLNX_ZYNQ_MP_NUM_UARTS] = { | ||
23 | + 0xFF000000, 0xFF010000, | ||
24 | +}; | ||
25 | + | ||
26 | +static const int uart_intr[XLNX_ZYNQ_MP_NUM_UARTS] = { | ||
27 | + 21, 22, | ||
28 | +}; | ||
29 | + | ||
30 | static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) | ||
31 | { | ||
32 | return GIC_NUM_SPI_INTR + cpu_nr * 32 + ppi_index; | ||
33 | @@ -56,6 +64,11 @@ static void xlnx_zynq_mp_init(Object *obj) | ||
34 | object_initialize(&s->gem[i], sizeof(s->gem[i]), TYPE_CADENCE_GEM); | ||
35 | qdev_set_parent_bus(DEVICE(&s->gem[i]), sysbus_get_default()); | ||
36 | } | ||
37 | + | ||
38 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_UARTS; i++) { | ||
39 | + object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_CADENCE_UART); | ||
40 | + qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default()); | ||
41 | + } | ||
42 | } | ||
43 | |||
44 | #define ERR_PROP_CHECK_RETURN(err, errp) do { \ | ||
45 | @@ -113,6 +126,14 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
46 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 0, | ||
47 | gic_spi[gem_intr[i]]); | ||
48 | } | ||
49 | + | ||
50 | + for (i = 0; i < XLNX_ZYNQ_MP_NUM_UARTS; i++) { | ||
51 | + object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err); | ||
52 | + ERR_PROP_CHECK_RETURN(err, errp); | ||
53 | + sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, uart_addr[i]); | ||
54 | + sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, | ||
55 | + gic_spi[uart_intr[i]]); | ||
56 | + } | ||
57 | } | ||
58 | |||
59 | static void xlnx_zynq_mp_class_init(ObjectClass *oc, void *data) | ||
60 | diff --git a/include/hw/arm/xlnx-zynq-mp.h b/include/hw/arm/xlnx-zynq-mp.h | ||
61 | index 470503c..c4ee658 100644 | ||
62 | --- a/include/hw/arm/xlnx-zynq-mp.h | ||
63 | +++ b/include/hw/arm/xlnx-zynq-mp.h | ||
64 | @@ -4,6 +4,7 @@ | ||
65 | #include "hw/arm/arm.h" | ||
66 | #include "hw/intc/arm_gic.h" | ||
67 | #include "hw/net/cadence_gem.h" | ||
68 | +#include "hw/char/cadence_uart.h" | ||
69 | |||
70 | #define TYPE_XLNX_ZYNQ_MP "xlnx,zynq-mp" | ||
71 | #define XLNX_ZYNQ_MP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ | ||
72 | @@ -11,6 +12,7 @@ | ||
73 | |||
74 | #define XLNX_ZYNQ_MP_NUM_CPUS 4 | ||
75 | #define XLNX_ZYNQ_MP_NUM_GEMS 4 | ||
76 | +#define XLNX_ZYNQ_MP_NUM_UARTS 2 | ||
77 | |||
78 | typedef struct XlnxZynqMPState { | ||
79 | /*< private >*/ | ||
80 | @@ -20,6 +22,7 @@ typedef struct XlnxZynqMPState { | ||
81 | ARMCPU cpu[XLNX_ZYNQ_MP_NUM_CPUS]; | ||
82 | GICState gic; | ||
83 | CadenceGEMState gem[XLNX_ZYNQ_MP_NUM_GEMS]; | ||
84 | + CadenceUARTState uart[XLNX_ZYNQ_MP_NUM_UARTS]; | ||
85 | } XlnxZynqMPState; | ||
86 | |||
87 | #define XLNX_ZYNQ_MP_H_ | ||
88 | -- | ||
89 | 2.1.1 | ||
90 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0012-arm-Add-xilinx-zynq-mp-generic-machine.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0012-arm-Add-xilinx-zynq-mp-generic-machine.patch new file mode 100644 index 00000000..4dbcc495 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0012-arm-Add-xilinx-zynq-mp-generic-machine.patch | |||
@@ -0,0 +1,87 @@ | |||
1 | From 48860a59e9fe23da638dde9c47a3665466ceefae Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:52 -0800 | ||
4 | Subject: [PATCH 12/15] arm: Add xilinx-zynq-mp-generic machine | ||
5 | |||
6 | Add a generic machine for the Xilinx Zynq MP SoC. This is a minimal | ||
7 | machine that exposes the capabilities of the raw SoC as a usable | ||
8 | machine. | ||
9 | |||
10 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
11 | --- | ||
12 | hw/arm/Makefile.objs | 2 +- | ||
13 | hw/arm/xlnx-zynq-mp-generic.c | 52 +++++++++++++++++++++++++++++++++++++++++++ | ||
14 | 2 files changed, 53 insertions(+), 1 deletion(-) | ||
15 | create mode 100644 hw/arm/xlnx-zynq-mp-generic.c | ||
16 | |||
17 | diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs | ||
18 | index 9bf072b..776fbe3 100644 | ||
19 | --- a/hw/arm/Makefile.objs | ||
20 | +++ b/hw/arm/Makefile.objs | ||
21 | @@ -8,4 +8,4 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o | ||
22 | obj-$(CONFIG_DIGIC) += digic.o | ||
23 | obj-y += omap1.o omap2.o strongarm.o | ||
24 | obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o | ||
25 | -obj-$(CONFIG_XLNX_ZYNQ_MP) += xlnx-zynq-mp.o | ||
26 | +obj-$(CONFIG_XLNX_ZYNQ_MP) += xlnx-zynq-mp.o xlnx-zynq-mp-generic.o | ||
27 | diff --git a/hw/arm/xlnx-zynq-mp-generic.c b/hw/arm/xlnx-zynq-mp-generic.c | ||
28 | new file mode 100644 | ||
29 | index 0000000..ff69b07 | ||
30 | --- /dev/null | ||
31 | +++ b/hw/arm/xlnx-zynq-mp-generic.c | ||
32 | @@ -0,0 +1,52 @@ | ||
33 | +#/* | ||
34 | + * Xilinx Zynq MPSoC emulation | ||
35 | + * | ||
36 | + * Copyright (C) 2015 Xilinx Inc | ||
37 | + * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
38 | + * | ||
39 | + * This program is free software; you can redistribute it and/or modify it | ||
40 | + * under the terms of the GNU General Public License as published by the | ||
41 | + * Free Software Foundation; either version 2 of the License, or | ||
42 | + * (at your option) any later version. | ||
43 | + * | ||
44 | + * This program is distributed in the hope that it will be useful, but WITHOUT | ||
45 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
46 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
47 | + * for more details. | ||
48 | + */ | ||
49 | + | ||
50 | +#include "hw/arm/xlnx-zynq-mp.h" | ||
51 | +#include "hw/boards.h" | ||
52 | +#include "qemu/error-report.h" | ||
53 | + | ||
54 | +typedef struct XlnxZynqMPGeneric { | ||
55 | + XlnxZynqMPState soc; | ||
56 | +} XlnxZynqMPGeneric; | ||
57 | + | ||
58 | +static void xlnx_zynq_mp_generic_init(MachineState *machine) | ||
59 | +{ | ||
60 | + XlnxZynqMPGeneric *s = g_new0(XlnxZynqMPGeneric, 1); | ||
61 | + Error *err = NULL; | ||
62 | + | ||
63 | + object_initialize(&s->soc, sizeof(s->soc), TYPE_XLNX_ZYNQ_MP); | ||
64 | + object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), NULL); | ||
65 | + | ||
66 | + object_property_set_bool(OBJECT(&s->soc), true, "realized", &err); | ||
67 | + if (err) { | ||
68 | + error_report("%s", error_get_pretty(err)); | ||
69 | + exit(1); | ||
70 | + } | ||
71 | +} | ||
72 | + | ||
73 | +static QEMUMachine xlnx_zynq_mp_generic_machine = { | ||
74 | + .name = "xlnx-zynq-mp-generic", | ||
75 | + .desc = "Xilinx Zynq MP SoC generic machine", | ||
76 | + .init = xlnx_zynq_mp_generic_init, | ||
77 | +}; | ||
78 | + | ||
79 | +static void xlnx_zynq_mp_generic_machine_init(void) | ||
80 | +{ | ||
81 | + qemu_register_machine(&xlnx_zynq_mp_generic_machine); | ||
82 | +} | ||
83 | + | ||
84 | +machine_init(xlnx_zynq_mp_generic_machine_init); | ||
85 | -- | ||
86 | 2.1.1 | ||
87 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0013-arm-xilinx-zynq-mp-generic-Add-external-RAM.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0013-arm-xilinx-zynq-mp-generic-Add-external-RAM.patch new file mode 100644 index 00000000..0af560de --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0013-arm-xilinx-zynq-mp-generic-Add-external-RAM.patch | |||
@@ -0,0 +1,43 @@ | |||
1 | From 0b155ff9a1e19f2b4ed4324e822285d3a667f02a Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:53 -0800 | ||
4 | Subject: [PATCH 13/15] arm: xilinx-zynq-mp-generic: Add external RAM | ||
5 | |||
6 | Zynq MPSoC supports external DDR RAM. Add a RAM at 0 to the model. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | hw/arm/xlnx-zynq-mp-generic.c | 7 +++++++ | ||
11 | 1 file changed, 7 insertions(+) | ||
12 | |||
13 | diff --git a/hw/arm/xlnx-zynq-mp-generic.c b/hw/arm/xlnx-zynq-mp-generic.c | ||
14 | index ff69b07..7394e82 100644 | ||
15 | --- a/hw/arm/xlnx-zynq-mp-generic.c | ||
16 | +++ b/hw/arm/xlnx-zynq-mp-generic.c | ||
17 | @@ -18,9 +18,11 @@ | ||
18 | #include "hw/arm/xlnx-zynq-mp.h" | ||
19 | #include "hw/boards.h" | ||
20 | #include "qemu/error-report.h" | ||
21 | +#include "exec/address-spaces.h" | ||
22 | |||
23 | typedef struct XlnxZynqMPGeneric { | ||
24 | XlnxZynqMPState soc; | ||
25 | + MemoryRegion ddr_ram; | ||
26 | } XlnxZynqMPGeneric; | ||
27 | |||
28 | static void xlnx_zynq_mp_generic_init(MachineState *machine) | ||
29 | @@ -36,6 +38,11 @@ static void xlnx_zynq_mp_generic_init(MachineState *machine) | ||
30 | error_report("%s", error_get_pretty(err)); | ||
31 | exit(1); | ||
32 | } | ||
33 | + | ||
34 | + memory_region_init_ram(&s->ddr_ram, NULL, "ddr-ram", machine->ram_size, | ||
35 | + &error_abort); | ||
36 | + vmstate_register_ram_global(&s->ddr_ram); | ||
37 | + memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram); | ||
38 | } | ||
39 | |||
40 | static QEMUMachine xlnx_zynq_mp_generic_machine = { | ||
41 | -- | ||
42 | 2.1.1 | ||
43 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0014-arm-xilinx-zynq-mp-generic-Add-bootloading.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0014-arm-xilinx-zynq-mp-generic-Add-bootloading.patch new file mode 100644 index 00000000..9c551bff --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0014-arm-xilinx-zynq-mp-generic-Add-bootloading.patch | |||
@@ -0,0 +1,41 @@ | |||
1 | From 8ef4b6e8f95d99dcee6ae1bae92f24cd05d1ff3a Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:54 -0800 | ||
4 | Subject: [PATCH 14/15] arm: xilinx-zynq-mp-generic: Add bootloading | ||
5 | |||
6 | Using standard ARM bootloader. | ||
7 | |||
8 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
9 | --- | ||
10 | hw/arm/xlnx-zynq-mp-generic.c | 8 ++++++++ | ||
11 | 1 file changed, 8 insertions(+) | ||
12 | |||
13 | diff --git a/hw/arm/xlnx-zynq-mp-generic.c b/hw/arm/xlnx-zynq-mp-generic.c | ||
14 | index 7394e82..a86f10d 100644 | ||
15 | --- a/hw/arm/xlnx-zynq-mp-generic.c | ||
16 | +++ b/hw/arm/xlnx-zynq-mp-generic.c | ||
17 | @@ -25,6 +25,8 @@ typedef struct XlnxZynqMPGeneric { | ||
18 | MemoryRegion ddr_ram; | ||
19 | } XlnxZynqMPGeneric; | ||
20 | |||
21 | +static struct arm_boot_info xlnx_zynq_mp_generic_binfo; | ||
22 | + | ||
23 | static void xlnx_zynq_mp_generic_init(MachineState *machine) | ||
24 | { | ||
25 | XlnxZynqMPGeneric *s = g_new0(XlnxZynqMPGeneric, 1); | ||
26 | @@ -43,6 +45,12 @@ static void xlnx_zynq_mp_generic_init(MachineState *machine) | ||
27 | &error_abort); | ||
28 | vmstate_register_ram_global(&s->ddr_ram); | ||
29 | memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram); | ||
30 | + | ||
31 | + xlnx_zynq_mp_generic_binfo.ram_size = machine->ram_size; | ||
32 | + xlnx_zynq_mp_generic_binfo.kernel_filename = machine->kernel_filename; | ||
33 | + xlnx_zynq_mp_generic_binfo.kernel_cmdline = machine->kernel_cmdline; | ||
34 | + xlnx_zynq_mp_generic_binfo.initrd_filename = machine->initrd_filename; | ||
35 | + arm_load_kernel(&s->soc.cpu[0], &xlnx_zynq_mp_generic_binfo); | ||
36 | } | ||
37 | |||
38 | static QEMUMachine xlnx_zynq_mp_generic_machine = { | ||
39 | -- | ||
40 | 2.1.1 | ||
41 | |||
diff --git a/recipes-devtools/qemu/qemu-zynqmp-mainline/0015-arm-xlnx-zynq-mp-Add-PSCI-setup.patch b/recipes-devtools/qemu/qemu-zynqmp-mainline/0015-arm-xlnx-zynq-mp-Add-PSCI-setup.patch new file mode 100644 index 00000000..e145e4b4 --- /dev/null +++ b/recipes-devtools/qemu/qemu-zynqmp-mainline/0015-arm-xlnx-zynq-mp-Add-PSCI-setup.patch | |||
@@ -0,0 +1,35 @@ | |||
1 | From 97287cf7c4f7550d298c0ef11dde88ee91c209a3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
3 | Date: Mon, 23 Feb 2015 15:04:55 -0800 | ||
4 | Subject: [PATCH 15/15] arm: xlnx-zynq-mp: Add PSCI setup | ||
5 | |||
6 | Use SMC PSCI, with the standard policy of secondaries starting in | ||
7 | power-off. | ||
8 | |||
9 | Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> | ||
10 | --- | ||
11 | hw/arm/xlnx-zynq-mp.c | 8 ++++++++ | ||
12 | 1 file changed, 8 insertions(+) | ||
13 | |||
14 | diff --git a/hw/arm/xlnx-zynq-mp.c b/hw/arm/xlnx-zynq-mp.c | ||
15 | index 9d7e834..0952221 100644 | ||
16 | --- a/hw/arm/xlnx-zynq-mp.c | ||
17 | +++ b/hw/arm/xlnx-zynq-mp.c | ||
18 | @@ -96,6 +96,14 @@ static void xlnx_zynq_mp_realize(DeviceState *dev, Error **errp) | ||
19 | for (i = 0; i < XLNX_ZYNQ_MP_NUM_CPUS; i++) { | ||
20 | qemu_irq irq; | ||
21 | |||
22 | + object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC, | ||
23 | + "psci-conduit", NULL); | ||
24 | + if (i > 0) { | ||
25 | + /* Secondary CPUs start in PSCI powered-down state */ | ||
26 | + object_property_set_bool(OBJECT(&s->cpu[i]), true, | ||
27 | + "start-powered-off", NULL); | ||
28 | + } | ||
29 | + | ||
30 | object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); | ||
31 | ERR_PROP_CHECK_RETURN(err, errp); | ||
32 | |||
33 | -- | ||
34 | 2.1.1 | ||
35 | |||
diff --git a/recipes-devtools/qemu/qemu_zynqmp.bb b/recipes-devtools/qemu/qemu_zynqmp.bb new file mode 100644 index 00000000..040147ec --- /dev/null +++ b/recipes-devtools/qemu/qemu_zynqmp.bb | |||
@@ -0,0 +1,39 @@ | |||
1 | require recipes-devtools/qemu/qemu.inc | ||
2 | |||
3 | DEFAULT_PREFERENCE = "-1" | ||
4 | |||
5 | LIC_FILES_CHKSUM = " \ | ||
6 | file://COPYING;md5=441c28d2cf86e15a37fa47e15a72fbac \ | ||
7 | file://COPYING.LIB;endline=24;md5=c04def7ae38850e7d3ef548588159913 \ | ||
8 | " | ||
9 | |||
10 | SRCREV = "cd2d5541271f1934345d8ca42f5fafff1744eee7" | ||
11 | |||
12 | PV = "2.2.0+master+zynqmp+git${SRCPV}" | ||
13 | |||
14 | SRC_URI_prepend = "git://git.qemu.org/qemu.git" | ||
15 | S = "${WORKDIR}/git" | ||
16 | |||
17 | # for base patches | ||
18 | FILESEXTRAPATHS_prepend := "${COREBASE}/meta/recipes-devtools/qemu/files:" | ||
19 | FILESEXTRAPATHS_prepend := "${COREBASE}/meta/recipes-devtools/qemu/qemu:" | ||
20 | |||
21 | FILESEXTRAPATHS_prepend := "${THISDIR}/qemu-zynqmp-mainline:" | ||
22 | SRC_URI_append += " \ | ||
23 | file://0001-target-arm-cpu64-Factor-out-ARM-cortex-init.patch \ | ||
24 | file://0002-target-arm-cpu64-Add-support-for-cortex-a53.patch \ | ||
25 | file://0003-arm-Introduce-Xilinx-Zynq-MPSoC.patch \ | ||
26 | file://0004-arm-xlnx-zynq-mp-Add-GIC.patch \ | ||
27 | file://0005-arm-xlnx-zynq-mp-Connect-CPU-Timers-to-GIC.patch \ | ||
28 | file://0006-net-cadence_gem-Clean-up-variable-names.patch \ | ||
29 | file://0007-net-cadence_gem-Split-state-struct-and-type-into-hea.patch \ | ||
30 | file://0008-arm-xilinx-zynq-mp-Add-GEM-support.patch \ | ||
31 | file://0009-char-cadence_uart-Clean-up-variable-names.patch \ | ||
32 | file://0010-char-cadence_uart-Split-state-struct-and-type-into-h.patch \ | ||
33 | file://0011-arm-xilinx-zynq-mp-Add-UART-support.patch \ | ||
34 | file://0012-arm-Add-xilinx-zynq-mp-generic-machine.patch \ | ||
35 | file://0013-arm-xilinx-zynq-mp-generic-Add-external-RAM.patch \ | ||
36 | file://0014-arm-xilinx-zynq-mp-generic-Add-bootloading.patch \ | ||
37 | file://0015-arm-xlnx-zynq-mp-Add-PSCI-setup.patch \ | ||
38 | " | ||
39 | |||