gem5  v21.1.0.2
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/base.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 
54 namespace gem5
55 {
56 
58  : BaseGic(p)
59 {
60 }
61 
62 void
64 {
65  distributor = new Gicv3Distributor(this, params().it_lines);
66  int threads = sys->threads.size();
67  redistributors.resize(threads, nullptr);
68  cpuInterfaces.resize(threads, nullptr);
69 
70  panic_if(threads > params().cpu_max,
71  "Exceeding maximum number of PEs supported by GICv3: "
72  "using %u while maximum is %u.", threads, params().cpu_max);
73 
74  for (int i = 0; i < threads; i++) {
75  redistributors[i] = new Gicv3Redistributor(this, i);
76  cpuInterfaces[i] = new Gicv3CPUInterface(this, i);
77  }
78 
79  distRange = RangeSize(params().dist_addr,
81 
82  redistSize = redistributors[0]->addrRangeSize;
83  redistRange = RangeSize(params().redist_addr, redistSize * threads);
84 
86 
87  distributor->init();
88 
89  for (int i = 0; i < threads; i++) {
90  redistributors[i]->init();
91  cpuInterfaces[i]->init();
92  }
93 
94  Gicv3Its *its = params().its;
95  if (its)
96  its->setGIC(this);
97 
98  BaseGic::init();
99 }
100 
101 Tick
103 {
104  const Addr addr = pkt->getAddr();
105  const size_t size = pkt->getSize();
106  bool is_secure_access = pkt->isSecure();
107  uint64_t resp = 0;
108  Tick delay = 0;
109 
110  if (distRange.contains(addr)) {
111  const Addr daddr = addr - distRange.start();
112  panic_if(!distributor, "Distributor is null!");
113  resp = distributor->read(daddr, size, is_secure_access);
114  delay = params().dist_pio_delay;
115  DPRINTF(GIC, "Gicv3::read(): (distributor) context_id %d register %#x "
116  "size %d is_secure_access %d (value %#x)\n",
117  pkt->req->contextId(), daddr, size, is_secure_access, resp);
118  } else if (redistRange.contains(addr)) {
119  Addr daddr = (addr - redistRange.start()) % redistSize;
120 
122  resp = redist->read(daddr, size, is_secure_access);
123 
124  delay = params().redist_pio_delay;
125  DPRINTF(GIC, "Gicv3::read(): (redistributor %d) context_id %d "
126  "register %#x size %d is_secure_access %d (value %#x)\n",
127  redist->processorNumber(), pkt->req->contextId(), daddr, size,
128  is_secure_access, resp);
129  } else {
130  panic("Gicv3::read(): unknown address %#x\n", addr);
131  }
132 
133  pkt->setUintX(resp, ByteOrder::little);
134  pkt->makeAtomicResponse();
135  return delay;
136 }
137 
138 Tick
140 {
141  const size_t size = pkt->getSize();
142  uint64_t data = pkt->getUintX(ByteOrder::little);
143  const Addr addr = pkt->getAddr();
144  bool is_secure_access = pkt->isSecure();
145  Tick delay = 0;
146 
147  if (distRange.contains(addr)) {
148  const Addr daddr = addr - distRange.start();
149  panic_if(!distributor, "Distributor is null!");
150  DPRINTF(GIC, "Gicv3::write(): (distributor) context_id %d "
151  "register %#x size %d is_secure_access %d value %#x\n",
152  pkt->req->contextId(), daddr, size, is_secure_access, data);
153  distributor->write(daddr, data, size, is_secure_access);
154  delay = params().dist_pio_delay;
155  } else if (redistRange.contains(addr)) {
156  Addr daddr = (addr - redistRange.start()) % redistSize;
157 
159  DPRINTF(GIC, "Gicv3::write(): (redistributor %d) context_id %d "
160  "register %#x size %d is_secure_access %d value %#x\n",
161  redist->processorNumber(), pkt->req->contextId(), daddr, size,
162  is_secure_access, data);
163 
164  redist->write(daddr, data, size, is_secure_access);
165 
166  delay = params().redist_pio_delay;
167  } else {
168  panic("Gicv3::write(): unknown address %#x\n", addr);
169  }
170 
171  pkt->makeAtomicResponse();
172  return delay;
173 }
174 
175 void
176 Gicv3::sendInt(uint32_t int_id)
177 {
178  DPRINTF(Interrupt, "Gicv3::sendInt(): received SPI %d\n", int_id);
179  distributor->sendInt(int_id);
180 }
181 
182 void
183 Gicv3::clearInt(uint32_t int_id)
184 {
185  DPRINTF(Interrupt, "Gicv3::clearInt(): received SPI %d\n", int_id);
186  distributor->clearInt(int_id);
187 }
188 
189 void
190 Gicv3::sendPPInt(uint32_t int_id, uint32_t cpu)
191 {
192  panic_if(cpu >= redistributors.size(), "Invalid cpuID sending PPI!");
193  DPRINTF(Interrupt, "Gicv3::sendPPInt(): received PPI %d cpuTarget %#x\n",
194  int_id, cpu);
195  redistributors[cpu]->sendPPInt(int_id);
196 }
197 
198 void
199 Gicv3::clearPPInt(uint32_t int_id, uint32_t cpu)
200 {
201  panic_if(cpu >= redistributors.size(), "Invalid cpuID clearing PPI!");
202  DPRINTF(Interrupt, "Gicv3::clearPPInt(): received PPI %d cpuTarget %#x\n",
203  int_id, cpu);
204  redistributors[cpu]->clearPPInt(int_id);
205 }
206 
207 void
209 {
210  auto tc = sys->threads[cpu];
211  tc->getCpuPtr()->postInterrupt(tc->threadId(), int_type, 0);
213 }
214 
215 bool
217 {
218  return (version == GicVersion::GIC_V3) ||
219  (version == GicVersion::GIC_V4 && params().gicv4);
220 }
221 
222 void
224 {
225  auto tc = sys->threads[cpu];
226  tc->getCpuPtr()->clearInterrupt(tc->threadId(), int_type, 0);
227 }
228 
229 void
230 Gicv3::deassertAll(uint32_t cpu)
231 {
232  auto tc = sys->threads[cpu];
233  tc->getCpuPtr()->clearInterrupts(tc->threadId());
234 }
235 
236 bool
237 Gicv3::haveAsserted(uint32_t cpu) const
238 {
239  auto tc = sys->threads[cpu];
240  return tc->getCpuPtr()->checkInterrupts(tc->threadId());
241 }
242 
244 Gicv3::getRedistributorByAffinity(uint32_t affinity) const
245 {
246  for (auto & redistributor : redistributors) {
247  if (redistributor->getAffinity() == affinity) {
248  return redistributor;
249  }
250  }
251 
252  return nullptr;
253 }
254 
257 {
259  "Address not pointing to a valid redistributor\n");
260 
261  const Addr daddr = addr - redistRange.start();
262  const uint32_t redistributor_id = daddr / redistSize;
263 
264  panic_if(redistributor_id >= redistributors.size(),
265  "Invalid redistributor_id!");
266  panic_if(!redistributors[redistributor_id], "Redistributor is null!");
267 
268  return redistributors[redistributor_id];
269 }
270 
271 void
273 {
274  distributor->serializeSection(cp, "distributor");
275 
276  for (uint32_t redistributor_id = 0;
277  redistributor_id < redistributors.size(); redistributor_id++)
278  redistributors[redistributor_id]->serializeSection(cp,
279  csprintf("redistributors.%i", redistributor_id));
280 
281  for (uint32_t cpu_interface_id = 0;
282  cpu_interface_id < cpuInterfaces.size(); cpu_interface_id++)
283  cpuInterfaces[cpu_interface_id]->serializeSection(cp,
284  csprintf("cpuInterface.%i", cpu_interface_id));
285 }
286 
287 void
289 {
290  getSystem()->setGIC(this);
291 
292  distributor->unserializeSection(cp, "distributor");
293 
294  for (uint32_t redistributor_id = 0;
295  redistributor_id < redistributors.size(); redistributor_id++)
296  redistributors[redistributor_id]->unserializeSection(cp,
297  csprintf("redistributors.%i", redistributor_id));
298 
299  for (uint32_t cpu_interface_id = 0;
300  cpu_interface_id < cpuInterfaces.size(); cpu_interface_id++)
301  cpuInterfaces[cpu_interface_id]->unserializeSection(cp,
302  csprintf("cpuInterface.%i", cpu_interface_id));
303 }
304 
305 } // namespace gem5
gem5::Gicv3::addrRanges
AddrRangeList addrRanges
Definition: gic_v3.hh:68
gic_v3_cpu_interface.hh
gem5::BaseGic::getSystem
ArmSystem * getSystem() const
Definition: base_gic.hh:114
gem5::Gicv3Its::setGIC
void setGIC(Gicv3 *_gic)
Definition: gic_v3_its.cc:808
gic_v3_its.hh
gem5::AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:317
gem5::System::Threads::size
int size() const
Definition: system.hh:216
gic_v3_redistributor.hh
gem5::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:334
gem5::Gicv3::haveAsserted
bool haveAsserted(uint32_t cpu) const
Definition: gic_v3.cc:237
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:661
gem5::Gicv3Redistributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:94
gem5::Gicv3Redistributor
Definition: gic_v3_redistributor.hh:55
gem5::Gicv3Distributor::init
void init()
Definition: gic_v3_distributor.cc:136
gem5::Gicv3::its
Gicv3Its * its
Definition: gic_v3.hh:65
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:438
gem5::BaseGic::GicVersion::GIC_V3
@ GIC_V3
gem5::CheckpointIn
Definition: serialize.hh:68
sc_dt::int_type
int64 int_type
Definition: sc_nbdefs.hh:240
gem5::Serializable::serializeSection
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:74
gem5::Gicv3::getRedistributorByAddr
Gicv3Redistributor * getRedistributorByAddr(Addr address) const
Definition: gic_v3.cc:256
gem5::Gicv3::deassertAll
void deassertAll(uint32_t cpu)
Definition: gic_v3.cc:230
gem5::Gicv3::clearPPInt
void clearPPInt(uint32_t int_id, uint32_t cpu) override
Definition: gic_v3.cc:199
gem5::Packet::isSecure
bool isSecure() const
Definition: packet.hh:810
gem5::Gicv3::Gicv3
Gicv3(const Params &p)
Definition: gic_v3.cc:57
gem5::csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
gem5::Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1043
gem5::Gicv3Redistributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:389
gem5::BaseGic::GicVersion::GIC_V4
@ GIC_V4
gem5::Gicv3::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:139
gem5::Gicv3::distRange
AddrRange distRange
Definition: gic_v3.hh:66
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::Gicv3::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:102
gem5::Gicv3::redistRange
AddrRange redistRange
Definition: gic_v3.hh:67
gem5::Gicv3::sendPPInt
void sendPPInt(uint32_t int_id, uint32_t cpu) override
Interface call for private peripheral interrupts.
Definition: gic_v3.cc:190
packet.hh
gem5::Gicv3::postInt
void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:208
gem5::Gicv3Distributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:513
gem5::Gicv3::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v3.cc:288
gem5::Gicv3::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v3.cc:272
gem5::Gicv3Distributor::sendInt
void sendInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1007
gem5::BaseGic
Definition: base_gic.hh:72
gem5::Serializable::unserializeSection
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:81
gem5::Gicv3::cpuInterfaces
std::vector< Gicv3CPUInterface * > cpuInterfaces
Definition: gic_v3.hh:64
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::Gicv3::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: gic_v3.cc:63
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::PioDevice::sys
System * sys
Definition: io_device.hh:105
gem5::Gicv3Redistributor::processorNumber
uint32_t processorNumber() const
Definition: gic_v3_redistributor.hh:214
gem5::Gicv3::distributor
Gicv3Distributor * distributor
Definition: gic_v3.hh:62
gem5::Gicv3::redistributors
std::vector< Gicv3Redistributor * > redistributors
Definition: gic_v3.hh:63
gem5::Gicv3::Gicv3Redistributor
friend class Gicv3Redistributor
Definition: gic_v3.hh:60
gem5::BaseGic::params
const Params & params() const
Definition: base_gic.cc:77
gem5::ArmISA::InterruptTypes
InterruptTypes
Definition: interrupts.hh:58
gem5::Gicv3::Gicv3CPUInterface
friend class Gicv3CPUInterface
Definition: gic_v3.hh:59
gem5::Gicv3Distributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:141
gem5::BaseGic::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base_gic.cc:70
gem5::BaseGic::Params
BaseGicParams Params
Definition: base_gic.hh:75
platform.hh
gem5::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:176
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::ArmSystem::callClearStandByWfi
static void callClearStandByWfi(ThreadContext *tc)
Make a call to notify the power controller of STANDBYWFI deassertion.
Definition: system.cc:219
gem5::Gicv3Distributor::clearInt
void clearInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1019
packet_access.hh
gem5::BaseGic::GicVersion
GicVersion
Definition: base_gic.hh:76
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:203
gem5::Gicv3Distributor
Definition: gic_v3_distributor.hh:51
base.hh
gem5::Gicv3Its
GICv3 ITS module.
Definition: gic_v3_its.hh:83
gem5::System::threads
Threads threads
Definition: system.hh:316
gem5::Gicv3::getRedistributorByAffinity
Gicv3Redistributor * getRedistributorByAffinity(uint32_t affinity) const
Definition: gic_v3.cc:244
gem5::ArmSystem::setGIC
void setGIC(BaseGic *gic)
Sets the pointer to the GIC.
Definition: system.hh:186
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::Gicv3::deassertInt
void deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:223
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::Gicv3Distributor::ADDR_RANGE_SIZE
static const uint32_t ADDR_RANGE_SIZE
Definition: gic_v3_distributor.hh:177
gem5::Gicv3::redistSize
uint64_t redistSize
Definition: gic_v3.hh:69
gem5::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:351
gic_v3_distributor.hh
gem5::ArmISA::Interrupt
Definition: faults.hh:557
gic_v3.hh
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
gem5::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:183
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::Gicv3::supportsVersion
bool supportsVersion(GicVersion version) override
Check if version supported.
Definition: gic_v3.cc:216
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84

Generated on Tue Sep 21 2021 12:25:11 for gem5 by doxygen 1.8.17