quic/qbox
Loading...
Searching...
No Matches
arm-smmu.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 * Author: GreenSocs 2021
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#ifndef _LIBQBOX_COMPONENTS_MMU_ARM_SMMU_H
10#define _LIBQBOX_COMPONENTS_MMU_ARM_SMMU_H
11
12#include <string>
13#include <cassert>
14
15#include <cci_configuration>
16
17#include <module_factory_registery.h>
18
19#include <device.h>
20#include <ports/initiator.h>
21#include <ports/target.h>
22#include <ports/qemu-initiator-signal-socket.h>
23#include <ports/qemu-target-signal-socket.h>
24
26{
27 inline uint64_t get_uint64(std::string s)
28 {
29 m_broker.lock_preset_value(s);
30 m_broker.ignore_unconsumed_preset_values(
31 [s](const std::pair<std::string, cci::cci_value>& iv) -> bool { return iv.first == s; });
32 auto v = m_broker.get_preset_cci_value(s);
33 if (v.is_uint64()) {
34 return v.get_uint64();
35 } else {
36 return v.get_int64();
37 }
38 }
39
40 cci::cci_broker_handle m_broker;
41
42public:
43 cci::cci_param<uint32_t> p_pamax;
44 cci::cci_param<uint16_t> p_num_smr;
45 cci::cci_param<uint16_t> p_num_cb;
46 cci::cci_param<uint16_t> p_num_pages;
47 cci::cci_param<bool> p_ato;
48 cci::cci_param<uint8_t> p_version;
49 cci::cci_param<uint8_t> p_num_tbu;
50
51 QemuTargetSocket<> register_socket;
52 sc_core::sc_vector<QemuTargetSocket<>> upstream_socket;
53 sc_core::sc_vector<QemuInitiatorSignalSocket> irq_context;
55 sc_core::sc_vector<QemuInitiatorSocket<>> downstream_socket;
56 QemuInitiatorSocket<> dma_socket;
57
58 arm_smmu(const sc_core::sc_module_name& name, sc_core::sc_object* o)
59 : arm_smmu(name, *(dynamic_cast<QemuInstance*>(o)))
60 {
61 }
62 arm_smmu(sc_core::sc_module_name nm, QemuInstance& inst)
63 : QemuDevice(nm, inst, "arm.mmu-500")
64 , m_broker(cci::cci_get_broker())
65 , p_pamax("pamax", 48, "")
66 , p_num_smr("num_smr", 48, "")
67 , p_num_cb("num_cb", 16, "")
68 , p_num_pages("num_pages", 16, "")
69 , p_ato("ato", true, "")
70 , p_version("version", 0x21, "")
71 , p_num_tbu("num_tbu", 1, "")
72 , upstream_socket("upstream_socket", p_num_tbu,
73 [this](const char* n, size_t i) { return new QemuTargetSocket<>(n, m_inst); })
74 , register_socket("mem", m_inst)
75 , irq_global("irq_global")
76 , irq_context("irq_context", p_num_cb,
77 [this](const char* n, size_t i) { return new QemuInitiatorSignalSocket(n); })
78 , downstream_socket("downstream_socket", p_num_tbu,
79 [this](const char* n, size_t i) { return new QemuInitiatorSocket<>(n, *this, m_inst); })
80 , dma_socket("dma", *this, m_inst)
81 {
82 }
83
84 void before_end_of_elaboration() override
85 {
86 QemuDevice::before_end_of_elaboration();
87
88 m_dev.set_prop_int("pamax", p_pamax);
89 m_dev.set_prop_int("num-smr", p_num_smr);
90 m_dev.set_prop_int("num-cb", p_num_cb);
91 m_dev.set_prop_int("num-pages", p_num_pages);
92 m_dev.set_prop_bool("ato", p_ato);
93 m_dev.set_prop_int("version", p_version);
94 m_dev.set_prop_int("num-tbu", p_num_tbu);
95
96 std::string base_string = "mr-";
97
98 for (uint32_t i = 0; i < p_num_tbu; ++i) {
99 downstream_socket[i].init(m_dev, (base_string + std::to_string(i)).c_str());
100
101 {
102 std::string s = std::string(name()) + ".upstream_socket_" + std::to_string(i) + ".address";
103 if (m_broker.has_preset_value(s)) {
104 m_dev.set_prop_int(("tbu-offset-" + std::to_string(i)).c_str(), get_uint64(s));
105 }
106 }
107 {
108 std::string s = std::string(name()) + ".upstream_socket_" + std::to_string(i) + ".size";
109 if (m_broker.has_preset_value(s)) {
110 m_dev.set_prop_int(("tbu-size-" + std::to_string(i)).c_str(), get_uint64(s));
111 }
112 }
113 {
114 std::string s = std::string(name()) + ".tbu_sid_" + std::to_string(i);
115 if (m_broker.has_preset_value(s)) {
116 m_dev.set_prop_int(("tbu-sid-" + std::to_string(i)).c_str(), get_uint64(s));
117 }
118 }
119 }
120
121 dma_socket.init(m_dev, "dma");
122 }
123
124 void end_of_elaboration() override
125 {
126 int i;
127
128 QemuDevice::set_sysbus_as_parent_bus();
129 QemuDevice::end_of_elaboration();
130
131 qemu::SysBusDevice sbd(get_qemu_dev());
132 register_socket.init(qemu::SysBusDevice(m_dev), 0);
133 for (uint32_t i = 0; i < p_num_tbu; ++i) {
134 upstream_socket[i].init(qemu::SysBusDevice(m_dev), i + 1);
135 }
136
137 irq_global.init_sbd(sbd, 0);
138 for (uint32_t i = 0; i < p_num_cb; ++i) {
139 irq_context[i].init_sbd(sbd, i + 1);
140 }
141 }
142
143 /* QemuInitiatorIface */
144 virtual void initiator_customize_tlm_payload(TlmPayload& payload) override {}
145
146 virtual void initiator_tidy_tlm_payload(TlmPayload& payload) override {}
147
148 virtual sc_core::sc_time initiator_get_local_time() override { return sc_core::sc_time_stamp(); }
149
150 virtual void initiator_set_local_time(const sc_core::sc_time& t) override {}
151
152 virtual void initiator_async_run(qemu::Cpu::AsyncJobFn job) override {}
153};
154
155extern "C" void module_register();
156
157#endif
QEMU device abstraction as a SystemC module.
Definition device.h:37
Definition initiator.h:38
A QEMU output GPIO exposed as a InitiatorSignalSocket<bool>
Definition qemu-initiator-signal-socket.h:40
void init_sbd(qemu::SysBusDevice sbd, int gpio_idx)
Initialize this socket with a QEMU SysBusDevice, and a GPIO index.
Definition qemu-initiator-signal-socket.h:173
TLM-2.0 initiator socket specialisation for QEMU AddressSpace mapping.
Definition initiator.h:63
This class encapsulates a libqemu-cxx qemu::LibQemu instance. It handles QEMU parameters and instance...
Definition qemu-instance.h:89
Definition target.h:160
Definition arm-smmu.h:26
Definition libqemu-cxx.h:638