30 static const uint32_t NUM_PPI = 32;
33 cci::cci_param<unsigned int> p_num_cpu;
34 cci::cci_param<unsigned int> p_num_spi;
35 cci::cci_param<unsigned int> p_revision;
36 cci::cci_param<std::vector<unsigned int> > p_redist_region;
37 cci::cci_param<bool> p_has_security_extensions;
41 sc_core::sc_vector<QemuTargetSocket<> > redist_iface;
44 sc_core::sc_vector<QemuTargetSignalSocket> spi_in;
50 sc_core::sc_vector<sc_core::sc_vector<QemuTargetSignalSocket> > ppi_in;
53 sc_core::sc_vector<QemuInitiatorSignalSocket> irq_out;
54 sc_core::sc_vector<QemuInitiatorSignalSocket> fiq_out;
55 sc_core::sc_vector<QemuInitiatorSignalSocket> virq_out;
56 sc_core::sc_vector<QemuInitiatorSignalSocket> vfiq_out;
57 arm_gicv3(
const sc_core::sc_module_name& name, sc_core::sc_object*
o)
64 if (inst.is_kvm_enabled()) {
65 return "kvm-arm-gicv3";
73 , p_num_cpu(
"num_cpus",
num_cpus,
"Number of CPU interfaces")
74 , p_num_spi(
"num_spi", 0,
"Number of shared peripheral interrupts")
75 , p_revision(
"revision", 3,
"Revision of the GIC (3 -> v3, 4 -> v4)")
78 , p_redist_region(
"redist_region",
79 std::vector<unsigned int>(gs::cci_get_vector<unsigned int>(
80 cci::cci_get_broker(), std::string(sc_module::name()) +
".redist_region")),
81 "Redistributor regions configuration")
82 , p_has_security_extensions(
"has_security_extensions",
false,
"Enable security extensions")
83 , dist_iface(
"dist_iface", inst)
84 , redist_iface(
"redist_iface", p_redist_region.get_value().size(),
85 [&inst](
const char*
n,
int i) { return new QemuTargetSocket<>(n, inst); })
86 , spi_in(
"spi_in", p_num_spi)
87 , ppi_in(
"ppi_in_cpu", p_num_cpu,
88 [](
const char*
n,
size_t i) {
return new sc_core::sc_vector<QemuTargetSignalSocket>(
n, NUM_PPI); })
89 , irq_out(
"irq_out", p_num_cpu)
90 , fiq_out(
"fiq_out", p_num_cpu)
91 , virq_out(
"virq_out", p_num_cpu)
92 , vfiq_out(
"vfiq_out", p_num_cpu)
96 void before_end_of_elaboration()
98 QemuDevice::before_end_of_elaboration();
101 m_dev.set_prop_int(
"num-cpu", p_num_cpu);
102 m_dev.set_prop_int(
"num-irq", p_num_spi + NUM_PPI);
103 m_dev.set_prop_int(
"revision", p_revision);
107 m_dev.set_prop_uint_array(
"redist-region-count", p_redist_region.get_value());
110 void end_of_elaboration()
112 QemuDevice::set_sysbus_as_parent_bus();
113 QemuDevice::end_of_elaboration();
118 dist_iface.init(
sbd, 0);
120 for (
i = 0;
i < p_redist_region.get_value().size();
i++) {
121 redist_iface[
i].init(
sbd, 1 +
i);
125 for (
i = 0;
i < p_num_spi;
i++) {
126 spi_in[
i].init(m_dev,
i);
131 for (
i = 0;
i < NUM_PPI;
i++) {
139 irq_out[
cpu].init_sbd(
sbd, p_num_cpu * 0 +
cpu);
140 fiq_out[
cpu].init_sbd(
sbd, p_num_cpu * 1 +
cpu);
141 virq_out[
cpu].init_sbd(
sbd, p_num_cpu * 2 +
cpu);
142 vfiq_out[
cpu].init_sbd(
sbd, p_num_cpu * 3 +
cpu);
145 if (m_inst.is_kvm_enabled()) {
150 assert(init &&
"Failed to find global peripheral initiator");
152 m_inst.
get().lock_iothread();
154 addr = gs::cci_get<uint64_t>(cci::cci_get_broker(), std::string(dist_iface.name()) +
".address");
156 for (
i = 0;
i < p_redist_region.get_value().size();
i++) {
157 addr = gs::cci_get<uint64_t>(cci::cci_get_broker(), std::string(redist_iface[
i].name()) +
".address");
160 m_inst.
get().unlock_iothread();
sc_core::sc_object * find_sc_obj(sc_core::sc_object *m, std::string name, bool test=false)
Helper function to find a sc_object by fully qualified name throws SC_ERROR if nothing found.
Definition cciutils.cc:18