gem5  v20.1.0.0
gic_v3.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2018 Metempsy Technology Consulting
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "dev/arm/gic_v3.hh"
42 
43 #include "cpu/intr_control.hh"
44 #include "debug/GIC.hh"
45 #include "debug/Interrupt.hh"
48 #include "dev/arm/gic_v3_its.hh"
50 #include "dev/platform.hh"
51 #include "mem/packet.hh"
52 #include "mem/packet_access.hh"
53 
55  : BaseGic(p)
56 {
57 }
58 
59 void
61 {
62  distributor = new Gicv3Distributor(this, params()->it_lines);
63  int threads = sys->threads.size();
64  redistributors.resize(threads, nullptr);
65  cpuInterfaces.resize(threads, nullptr);
66 
67  panic_if(threads > params()->cpu_max,
68  "Exceeding maximum number of PEs supported by GICv3: "
69  "using %u while maximum is %u.", threads, params()->cpu_max);
70 
71  for (int i = 0; i < threads; i++) {
72  redistributors[i] = new Gicv3Redistributor(this, i);
73  cpuInterfaces[i] = new Gicv3CPUInterface(this, i);
74  }
75 
76  distRange = RangeSize(params()->dist_addr,
78 
79  redistSize = redistributors[0]->addrRangeSize;
80  redistRange = RangeSize(params()->redist_addr, redistSize * threads - 1);
81 
83 
84  distributor->init();
85 
86  for (int i = 0; i < threads; i++) {
87  redistributors[i]->init();
88  cpuInterfaces[i]->init();
89  }
90 
91  Gicv3Its *its = params()->its;
92  if (its)
93  its->setGIC(this);
94 
95  BaseGic::init();
96 }
97 
98 Tick
100 {
101  const Addr addr = pkt->getAddr();
102  const size_t size = pkt->getSize();
103  bool is_secure_access = pkt->isSecure();
104  uint64_t resp = 0;
105  Tick delay = 0;
106 
107  if (distRange.contains(addr)) {
108  const Addr daddr = addr - distRange.start();
109  panic_if(!distributor, "Distributor is null!");
110  resp = distributor->read(daddr, size, is_secure_access);
111  delay = params()->dist_pio_delay;
112  DPRINTF(GIC, "Gicv3::read(): (distributor) context_id %d register %#x "
113  "size %d is_secure_access %d (value %#x)\n",
114  pkt->req->contextId(), daddr, size, is_secure_access, resp);
115  } else if (redistRange.contains(addr)) {
116  Addr daddr = (addr - redistRange.start()) % redistSize;
117 
119  resp = redist->read(daddr, size, is_secure_access);
120 
121  delay = params()->redist_pio_delay;
122  DPRINTF(GIC, "Gicv3::read(): (redistributor %d) context_id %d "
123  "register %#x size %d is_secure_access %d (value %#x)\n",
124  redist->processorNumber(), pkt->req->contextId(), daddr, size,
125  is_secure_access, resp);
126  } else {
127  panic("Gicv3::read(): unknown address %#x\n", addr);
128  }
129 
130  pkt->setUintX(resp, ByteOrder::little);
131  pkt->makeAtomicResponse();
132  return delay;
133 }
134 
135 Tick
137 {
138  const size_t size = pkt->getSize();
139  uint64_t data = pkt->getUintX(ByteOrder::little);
140  const Addr addr = pkt->getAddr();
141  bool is_secure_access = pkt->isSecure();
142  Tick delay = 0;
143 
144  if (distRange.contains(addr)) {
145  const Addr daddr = addr - distRange.start();
146  panic_if(!distributor, "Distributor is null!");
147  DPRINTF(GIC, "Gicv3::write(): (distributor) context_id %d "
148  "register %#x size %d is_secure_access %d value %#x\n",
149  pkt->req->contextId(), daddr, size, is_secure_access, data);
150  distributor->write(daddr, data, size, is_secure_access);
151  delay = params()->dist_pio_delay;
152  } else if (redistRange.contains(addr)) {
153  Addr daddr = (addr - redistRange.start()) % redistSize;
154 
156  DPRINTF(GIC, "Gicv3::write(): (redistributor %d) context_id %d "
157  "register %#x size %d is_secure_access %d value %#x\n",
158  redist->processorNumber(), pkt->req->contextId(), daddr, size,
159  is_secure_access, data);
160 
161  redist->write(daddr, data, size, is_secure_access);
162 
163  delay = params()->redist_pio_delay;
164  } else {
165  panic("Gicv3::write(): unknown address %#x\n", addr);
166  }
167 
168  pkt->makeAtomicResponse();
169  return delay;
170 }
171 
172 void
173 Gicv3::sendInt(uint32_t int_id)
174 {
175  DPRINTF(Interrupt, "Gicv3::sendInt(): received SPI %d\n", int_id);
176  distributor->sendInt(int_id);
177 }
178 
179 void
180 Gicv3::clearInt(uint32_t int_id)
181 {
182  DPRINTF(Interrupt, "Gicv3::clearInt(): received SPI %d\n", int_id);
183  distributor->clearInt(int_id);
184 }
185 
186 void
187 Gicv3::sendPPInt(uint32_t int_id, uint32_t cpu)
188 {
189  panic_if(cpu >= redistributors.size(), "Invalid cpuID sending PPI!");
190  DPRINTF(Interrupt, "Gicv3::sendPPInt(): received PPI %d cpuTarget %#x\n",
191  int_id, cpu);
192  redistributors[cpu]->sendPPInt(int_id);
193 }
194 
195 void
196 Gicv3::clearPPInt(uint32_t int_id, uint32_t cpu)
197 {
198  panic_if(cpu >= redistributors.size(), "Invalid cpuID clearing PPI!");
199  DPRINTF(Interrupt, "Gicv3::clearPPInt(): received PPI %d cpuTarget %#x\n",
200  int_id, cpu);
201  redistributors[cpu]->clearPPInt(int_id);
202 }
203 
204 void
206 {
207  platform->intrctrl->post(cpu, int_type, 0);
209 }
210 
211 bool
213 {
214  return (version == GicVersion::GIC_V3) ||
215  (version == GicVersion::GIC_V4 && params()->gicv4);
216 }
217 
218 void
220 {
221  platform->intrctrl->clear(cpu, int_type, 0);
222 }
223 
224 void
225 Gicv3::deassertAll(uint32_t cpu)
226 {
227  platform->intrctrl->clearAll(cpu);
228 }
229 
230 bool
231 Gicv3::haveAsserted(uint32_t cpu) const
232 {
233  return platform->intrctrl->havePosted(cpu);
234 }
235 
237 Gicv3::getRedistributorByAffinity(uint32_t affinity) const
238 {
239  for (auto & redistributor : redistributors) {
240  if (redistributor->getAffinity() == affinity) {
241  return redistributor;
242  }
243  }
244 
245  return nullptr;
246 }
247 
250 {
252  "Address not pointing to a valid redistributor\n");
253 
254  const Addr daddr = addr - redistRange.start();
255  const uint32_t redistributor_id = daddr / redistSize;
256 
257  panic_if(redistributor_id >= redistributors.size(),
258  "Invalid redistributor_id!");
259  panic_if(!redistributors[redistributor_id], "Redistributor is null!");
260 
261  return redistributors[redistributor_id];
262 }
263 
264 void
266 {
267  distributor->serializeSection(cp, "distributor");
268 
269  for (uint32_t redistributor_id = 0;
270  redistributor_id < redistributors.size(); redistributor_id++)
271  redistributors[redistributor_id]->serializeSection(cp,
272  csprintf("redistributors.%i", redistributor_id));
273 
274  for (uint32_t cpu_interface_id = 0;
275  cpu_interface_id < cpuInterfaces.size(); cpu_interface_id++)
276  cpuInterfaces[cpu_interface_id]->serializeSection(cp,
277  csprintf("cpuInterface.%i", cpu_interface_id));
278 }
279 
280 void
282 {
283  getSystem()->setGIC(this);
284 
285  distributor->unserializeSection(cp, "distributor");
286 
287  for (uint32_t redistributor_id = 0;
288  redistributor_id < redistributors.size(); redistributor_id++)
289  redistributors[redistributor_id]->unserializeSection(cp,
290  csprintf("redistributors.%i", redistributor_id));
291 
292  for (uint32_t cpu_interface_id = 0;
293  cpu_interface_id < cpuInterfaces.size(); cpu_interface_id++)
294  cpuInterfaces[cpu_interface_id]->unserializeSection(cp,
295  csprintf("cpuInterface.%i", cpu_interface_id));
296 }
297 
298 Gicv3 *
299 Gicv3Params::create()
300 {
301  return new Gicv3(this);
302 }
gic_v3_cpu_interface.hh
Gicv3::cpuInterfaces
std::vector< Gicv3CPUInterface * > cpuInterfaces
Definition: gic_v3.hh:62
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1016
Serializable::unserializeSection
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:178
gic_v3_its.hh
BaseGic::Params
BaseGicParams Params
Definition: base_gic.hh:65
IntrControl::clear
void clear(int cpu_id, int int_num, int index)
Definition: intr_control.cc:55
gic_v3_redistributor.hh
Gicv3::getRedistributorByAddr
Gicv3Redistributor * getRedistributorByAddr(Addr address) const
Definition: gic_v3.cc:249
IntrControl::havePosted
bool havePosted(int cpu_id) const
Definition: intr_control.cc:71
data
const char data[]
Definition: circlebuf.test.cc:42
IntrControl::post
void post(int cpu_id, int int_num, int index)
Definition: intr_control.cc:47
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
Gicv3Redistributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:90
Gicv3::its
Gicv3Its * its
Definition: gic_v3.hh:63
sc_dt::int_type
int64 int_type
Definition: sc_nbdefs.hh:240
IntrControl::clearAll
void clearAll(int cpu_id)
Definition: intr_control.cc:63
Gicv3::redistSize
uint64_t redistSize
Definition: gic_v3.hh:67
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:435
Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:340
Gicv3Its::setGIC
void setGIC(Gicv3 *_gic)
Definition: gic_v3_its.cc:800
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
Gicv3::clearPPInt
void clearPPInt(uint32_t int_id, uint32_t cpu) override
Definition: gic_v3.cc:196
Gicv3Distributor::clearInt
void clearInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1012
Serializable::serializeSection
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:171
Gicv3::getRedistributorByAffinity
Gicv3Redistributor * getRedistributorByAffinity(uint32_t affinity) const
Definition: gic_v3.cc:237
Gicv3::params
const Params * params() const
Definition: gic_v3.hh:115
Gicv3::distributor
Gicv3Distributor * distributor
Definition: gic_v3.hh:60
Packet::isSecure
bool isSecure() const
Definition: packet.hh:783
Gicv3::addrRanges
AddrRangeList addrRanges
Definition: gic_v3.hh:66
packet.hh
PioDevice::sys
System * sys
Definition: io_device.hh:102
BaseGic::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base_gic.cc:66
Gicv3::clearInt
void clearInt(uint32_t int_id) override
Clear an interrupt from a device that is connected to the GIC.
Definition: gic_v3.cc:180
cp
Definition: cprintf.cc:40
Gicv3::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v3.cc:265
Packet::getUintX
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:350
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:638
Gicv3Its
GICv3 ITS module.
Definition: gic_v3_its.hh:74
Gicv3::deassertInt
void deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:219
ArmISA::InterruptTypes
InterruptTypes
Definition: interrupts.hh:57
Packet::setUintX
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
Definition: packet.cc:367
System::Threads::size
int size() const
Definition: system.hh:204
BaseGic::platform
Platform * platform
Platform this GIC belongs to.
Definition: base_gic.hh:114
Gicv3Distributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:137
Gicv3
Definition: gic_v3.hh:53
platform.hh
Gicv3::sendPPInt
void sendPPInt(uint32_t int_id, uint32_t cpu) override
Interface call for private peripheral interrupts.
Definition: gic_v3.cc:187
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Gicv3::deassertAll
void deassertAll(uint32_t cpu)
Definition: gic_v3.cc:225
packet_access.hh
Gicv3::Gicv3
Gicv3(const Params *p)
Definition: gic_v3.cc:54
Gicv3::redistributors
std::vector< Gicv3Redistributor * > redistributors
Definition: gic_v3.hh:61
Gicv3::Gicv3Redistributor
friend class Gicv3Redistributor
Definition: gic_v3.hh:57
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
System::threads
Threads threads
Definition: system.hh:309
Gicv3::distRange
AddrRange distRange
Definition: gic_v3.hh:64
Gicv3::postInt
void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:205
Gicv3Distributor::init
void init()
Definition: gic_v3_distributor.cc:132
ArmSystem::callClearStandByWfi
static void callClearStandByWfi(ThreadContext *tc)
Make a call to notify the power controller of STANDBYWFI deassertion.
Definition: system.cc:216
BaseGic
Definition: base_gic.hh:62
Gicv3Redistributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:385
AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:314
Gicv3::haveAsserted
bool haveAsserted(uint32_t cpu) const
Definition: gic_v3.cc:231
Gicv3Redistributor::processorNumber
uint32_t processorNumber() const
Definition: gic_v3_redistributor.hh:208
intr_control.hh
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
ArmSystem::setGIC
void setGIC(BaseGic *gic)
Sets the pointer to the GIC.
Definition: system.hh:185
Gicv3::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:99
Gicv3Distributor
Definition: gic_v3_distributor.hh:48
BaseGic::GicVersion::GIC_V3
@ GIC_V3
Platform::intrctrl
IntrControl * intrctrl
Pointer to the interrupt controller.
Definition: platform.hh:53
addr
ip6_addr_t addr
Definition: inet.hh:423
Gicv3::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: gic_v3.cc:60
Gicv3::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:136
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
BaseGic::getSystem
ArmSystem * getSystem() const
Definition: base_gic.hh:104
Gicv3::supportsVersion
bool supportsVersion(GicVersion version) override
Check if version supported.
Definition: gic_v3.cc:212
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Gicv3::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v3.cc:281
Gicv3::redistRange
AddrRange redistRange
Definition: gic_v3.hh:65
CheckpointIn
Definition: serialize.hh:67
Gicv3Distributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:506
BaseGic::GicVersion
GicVersion
Definition: base_gic.hh:66
gic_v3_distributor.hh
Gicv3Distributor::sendInt
void sendInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1000
gic_v3.hh
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
Gicv3Redistributor
Definition: gic_v3_redistributor.hh:52
BaseGic::GicVersion::GIC_V4
@ GIC_V4
Gicv3::Gicv3CPUInterface
friend class Gicv3CPUInterface
Definition: gic_v3.hh:56
Gicv3Distributor::ADDR_RANGE_SIZE
static const uint32_t ADDR_RANGE_SIZE
Definition: gic_v3_distributor.hh:171
Gicv3::sendInt
void sendInt(uint32_t int_id) override
Post an interrupt from a device that is connected to the GIC.
Definition: gic_v3.cc:173
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17