27 cci::cci_param<unsigned int> p_base_spi;
28 cci::cci_param<unsigned int> p_num_spis;
36 sc_core::sc_vector<QemuInitiatorSignalSocket> spi_out;
42 , p_base_spi(
"base_spi", 0,
"Start index of gic's spis")
43 , p_num_spis(
"num_spis", 0,
"Number of gic's spis")
44 , spi_out(
"spi_out", p_num_spis)
45 , iface(
"iface", inst)
49 unsigned int get_base_spi() {
return p_base_spi; }
51 unsigned int get_num_spis() {
return p_num_spis; }
53 void before_end_of_elaboration()
55 QemuDevice::before_end_of_elaboration();
57 m_dev.set_prop_int(
"base-spi", p_base_spi);
58 m_dev.set_prop_int(
"num-spi", p_num_spis);
61 void end_of_elaboration()
63 QemuDevice::end_of_elaboration();
70 for (
int i = 0;
i < p_num_spis;
i++) {
71 spi_out[
i].init_sbd(
sbd,
i);
79 static const uint32_t NUM_PPI = 32;
82 cci::cci_param<unsigned int> p_num_cpu;
83 cci::cci_param<unsigned int> p_num_spi;
84 cci::cci_param<unsigned int> p_revision;
85 cci::cci_param<bool> p_has_virt_extensions;
86 cci::cci_param<bool> p_has_security_extensions;
87 cci::cci_param<unsigned int> p_num_prio_bits;
88 cci::cci_param<bool> p_has_msi_support;
97 QemuTargetSocket<>::TlmTargetSocket v2m_iface;
100 sc_core::sc_vector<QemuTargetSignalSocket> spi_in;
106 sc_core::sc_vector<sc_core::sc_vector<QemuTargetSignalSocket> > ppi_in;
109 sc_core::sc_vector<QemuInitiatorSignalSocket> irq_out;
110 sc_core::sc_vector<QemuInitiatorSignalSocket> fiq_out;
111 sc_core::sc_vector<QemuInitiatorSignalSocket> virq_out;
112 sc_core::sc_vector<QemuInitiatorSignalSocket> vfiq_out;
113 sc_core::sc_vector<QemuInitiatorSignalSocket> maintenance_out;
115 arm_gicv2(
const sc_core::sc_module_name& name, sc_core::sc_object*
o)
121 , p_num_cpu(
"num_cpu", 0,
"Number of CPU interfaces")
122 , p_num_spi(
"num_spi", 0,
"Number of shared peripheral interrupts")
123 , p_revision(
"revision", 2,
"Revision of the GIC (1 -> v1, 2 -> v2, 0 -> 11MPCore)")
124 , p_has_virt_extensions(
"has_virt_extensions",
false,
125 "Enable virtualization extensions "
127 , p_has_security_extensions(
"has_security_extensions",
false,
128 "Enable security extensions "
130 , p_num_prio_bits(
"num_prio_bits", 8,
"Number of priority bits implemented by this GIC")
131 , p_has_msi_support(
"has_msi_support",
false,
"Enable gicv2m extension to support MSI")
133 , dist_iface(
"dist_iface", inst)
134 , cpu_iface(
"cpu_iface", inst)
135 , virt_iface(
"virt_iface", inst)
136 , vcpu_iface(
"vcpu_iface", inst)
137 , v2m_iface(
"v2m_iface")
138 , spi_in(
"spi_in", p_num_spi)
139 , ppi_in(
"ppi_in_cpu", p_num_cpu,
140 [](
const char*
n,
size_t i) {
return new sc_core::sc_vector<QemuTargetSignalSocket>(
n, NUM_PPI); })
141 , irq_out(
"irq_out", p_num_cpu)
142 , fiq_out(
"fiq_out", p_num_cpu)
143 , virq_out(
"virq_out", p_num_cpu)
144 , vfiq_out(
"vfiq_out", p_num_cpu)
145 , maintenance_out(
"maintenance_out", p_num_cpu)
147 if (p_has_msi_support) {
151 v2m_iface.bind(m_gicv2m->iface);
157 SCP_FATAL(
SCMOD) <<
"Gicv2 does not have enough spis for v2m config";
172 void before_end_of_elaboration()
174 QemuDevice::before_end_of_elaboration();
176 m_dev.set_prop_int(
"num-cpu", p_num_cpu);
177 m_dev.set_prop_int(
"num-irq", p_num_spi + NUM_PPI);
178 m_dev.set_prop_int(
"revision", p_revision);
179 m_dev.set_prop_bool(
"has-virtualization-extensions", p_has_virt_extensions);
180 m_dev.set_prop_bool(
"has-security-extensions", p_has_security_extensions);
181 m_dev.set_prop_int(
"num-priority-bits", p_num_prio_bits);
184 void end_of_elaboration()
186 QemuDevice::set_sysbus_as_parent_bus();
187 QemuDevice::end_of_elaboration();
192 dist_iface.init(
sbd, 0);
193 cpu_iface.init(
sbd, 1);
195 if (p_has_virt_extensions) {
196 virt_iface.init(
sbd, 2);
197 vcpu_iface.init(
sbd, 3);
201 for (
i = 0;
i < p_num_spi;
i++) {
202 spi_in[
i].init(m_dev,
i);
207 for (
i = 0;
i < NUM_PPI;
i++) {
215 irq_out[
cpu].init_sbd(
sbd, p_num_cpu * 0 +
cpu);
216 fiq_out[
cpu].init_sbd(
sbd, p_num_cpu * 1 +
cpu);
217 virq_out[
cpu].init_sbd(
sbd, p_num_cpu * 2 +
cpu);
218 vfiq_out[
cpu].init_sbd(
sbd, p_num_cpu * 3 +
cpu);
220 if (p_has_virt_extensions) {
221 maintenance_out[
cpu].init_sbd(
sbd, p_num_cpu * 4 +
cpu);