gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
gic_v3.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 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  * Authors: Jairo Balart
41  */
42 
43 #include "dev/arm/gic_v3.hh"
44 
45 #include "cpu/intr_control.hh"
46 #include "debug/GIC.hh"
47 #include "debug/Interrupt.hh"
50 #include "dev/arm/gic_v3_its.hh"
52 #include "dev/platform.hh"
53 #include "mem/packet.hh"
54 #include "mem/packet_access.hh"
55 
57  : BaseGic(p)
58 {
59 }
60 
61 void
63 {
64  distributor = new Gicv3Distributor(this, params()->it_lines);
65  redistributors.resize(sys->numContexts(), nullptr);
66  cpuInterfaces.resize(sys->numContexts(), nullptr);
67 
68  panic_if(sys->numContexts() > params()->cpu_max,
69  "Exceeding maximum number of PEs supported by GICv3: "
70  "using %u while maximum is %u\n", sys->numContexts(),
71  params()->cpu_max);
72 
73  for (int i = 0; i < sys->numContexts(); i++) {
74  redistributors[i] = new Gicv3Redistributor(this, i);
75  cpuInterfaces[i] = new Gicv3CPUInterface(this, i);
76  }
77 
78  distRange = RangeSize(params()->dist_addr,
80 
81  redistSize = redistributors[0]->addrRangeSize;
82  redistRange = RangeSize(params()->redist_addr,
83  redistSize * sys->numContexts() - 1);
84 
86 
87  distributor->init();
88 
89  for (int i = 0; i < sys->numContexts(); 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, LittleEndianByteOrder);
134  pkt->makeAtomicResponse();
135  return delay;
136 }
137 
138 Tick
140 {
141  const size_t size = pkt->getSize();
142  uint64_t data = pkt->getUintX(LittleEndianByteOrder);
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  panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
179  panic_if(int_id >= Gicv3::INTID_SECURE, "Invalid SPI!");
180  DPRINTF(Interrupt, "Gicv3::sendInt(): received SPI %d\n", int_id);
181  distributor->sendInt(int_id);
182 }
183 
184 void
185 Gicv3::clearInt(uint32_t number)
186 {
187  distributor->deassertSPI(number);
188 }
189 
190 void
191 Gicv3::sendPPInt(uint32_t int_id, uint32_t cpu)
192 {
193  panic_if(cpu >= redistributors.size(), "Invalid cpuID sending PPI!");
194  panic_if(int_id < Gicv3::SGI_MAX, "Invalid PPI!");
195  panic_if(int_id >= Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid PPI!");
196  DPRINTF(Interrupt, "Gicv3::sendPPInt(): received PPI %d cpuTarget %#x\n",
197  int_id, cpu);
198  redistributors[cpu]->sendPPInt(int_id);
199 }
200 
201 void
202 Gicv3::clearPPInt(uint32_t num, uint32_t cpu)
203 {
204 }
205 
206 void
208 {
209  platform->intrctrl->post(cpu, int_type, 0);
210 }
211 
212 bool
214 {
215  return (version == GicVersion::GIC_V3) ||
216  (version == GicVersion::GIC_V4 && params()->gicv4);
217 }
218 
219 void
221 {
222  platform->intrctrl->clear(cpu, int_type, 0);
223 }
224 
226 Gicv3::getRedistributorByAffinity(uint32_t affinity) const
227 {
228  for (auto & redistributor : redistributors) {
229  if (redistributor->getAffinity() == affinity) {
230  return redistributor;
231  }
232  }
233 
234  return nullptr;
235 }
236 
239 {
241  "Address not pointing to a valid redistributor\n");
242 
243  const Addr daddr = addr - redistRange.start();
244  const uint32_t redistributor_id = daddr / redistSize;
245 
246  panic_if(redistributor_id >= redistributors.size(),
247  "Invalid redistributor_id!");
248  panic_if(!redistributors[redistributor_id], "Redistributor is null!");
249 
250  return redistributors[redistributor_id];
251 }
252 
253 void
255 {
256  distributor->serializeSection(cp, "distributor");
257 
258  for (uint32_t redistributor_id = 0;
259  redistributor_id < redistributors.size(); redistributor_id++)
260  redistributors[redistributor_id]->serializeSection(cp,
261  csprintf("redistributors.%i", redistributor_id));
262 
263  for (uint32_t cpu_interface_id = 0;
264  cpu_interface_id < cpuInterfaces.size(); cpu_interface_id++)
265  cpuInterfaces[cpu_interface_id]->serializeSection(cp,
266  csprintf("cpuInterface.%i", cpu_interface_id));
267 }
268 
269 void
271 {
272  getSystem()->setGIC(this);
273 
274  distributor->unserializeSection(cp, "distributor");
275 
276  for (uint32_t redistributor_id = 0;
277  redistributor_id < redistributors.size(); redistributor_id++)
278  redistributors[redistributor_id]->unserializeSection(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]->unserializeSection(cp,
284  csprintf("cpuInterface.%i", cpu_interface_id));
285 }
286 
287 Gicv3 *
288 Gicv3Params::create()
289 {
290  return new Gicv3(this);
291 }
IntrControl * intrctrl
Pointer to the interrupt controller.
Definition: platform.hh:56
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:584
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:354
Platform * platform
Platform this GIC belongs to.
Definition: base_gic.hh:116
static const int PPI_MAX
Definition: gic_v3.hh:80
Definition: gic_v3.hh:54
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:176
Bitfield< 7 > i
BaseGicParams Params
Definition: base_gic.hh:67
void post(int cpu_id, int int_num, int index)
Definition: intr_control.cc:50
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:183
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:406
const Params * params() const
Definition: gic_v3.hh:116
ip6_addr_t addr
Definition: inet.hh:335
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Gicv3Its * its
Definition: gic_v3.hh:64
Gicv3Redistributor * getRedistributorByAddr(Addr address) const
Definition: gic_v3.cc:238
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: cprintf.cc:42
InterruptTypes
Definition: isa_traits.hh:104
void sendInt(uint32_t int_id)
AddrRangeList addrRanges
Definition: gic_v3.hh:67
void clearInt(uint32_t int_id) override
Clear an interrupt from a device that is connected to the GIC.
Definition: gic_v3.cc:185
void deassertSPI(uint32_t int_id)
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:337
void clearPPInt(uint32_t int_id, uint32_t cpu) override
Definition: gic_v3.cc:202
static const int SGI_MAX
Definition: gic_v3.hh:78
uint64_t redistSize
Definition: gic_v3.hh:68
Gicv3Redistributor * getRedistributorByAffinity(uint32_t affinity) const
Definition: gic_v3.cc:226
RequestPtr req
A pointer to the original request.
Definition: packet.hh:327
void deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:220
unsigned getSize() const
Definition: packet.hh:736
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:162
void makeAtomicResponse()
Definition: packet.hh:949
void sendPPInt(uint32_t int_id, uint32_t cpu) override
Interface call for private peripheral interrupts.
Definition: gic_v3.cc:191
uint64_t Tick
Tick count type.
Definition: types.hh:63
Gicv3Distributor * distributor
Definition: gic_v3.hh:61
static const uint32_t ADDR_RANGE_SIZE
int64 int_type
Definition: sc_nbdefs.hh:206
Addr getAddr() const
Definition: packet.hh:726
unsigned numContexts() const
Definition: system.hh:206
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v3.cc:254
GicVersion
Definition: base_gic.hh:68
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
System * sys
Definition: io_device.hh:105
uint32_t processorNumber() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
Gicv3(const Params *p)
Definition: gic_v3.cc:56
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:102
Generic interface for platforms.
void setGIC(BaseGic *gic)
Sets the pointer to the GIC.
Definition: system.hh:208
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v3.cc:270
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:68
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: gic_v3.cc:62
friend class Gicv3Redistributor
Definition: gic_v3.hh:58
void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:207
friend class Gicv3CPUInterface
Definition: gic_v3.hh:57
void sendInt(uint32_t int_id) override
Post an interrupt from a device that is connected to the GIC.
Definition: gic_v3.cc:176
AddrRange redistRange
Definition: gic_v3.hh:66
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:297
bool isSecure() const
Definition: packet.hh:755
std::vector< Gicv3Redistributor * > redistributors
Definition: gic_v3.hh:62
AddrRange distRange
Definition: gic_v3.hh:65
std::vector< Gicv3CPUInterface * > cpuInterfaces
Definition: gic_v3.hh:63
void clear(int cpu_id, int int_num, int index)
Definition: intr_control.cc:59
bool supportsVersion(GicVersion version) override
Check if version supported.
Definition: gic_v3.cc:213
void setGIC(Gicv3 *_gic)
Definition: gic_v3_its.cc:802
ArmSystem * getSystem() const
Definition: base_gic.hh:106
Bitfield< 0 > p
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base_gic.cc:68
const char data[]
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gic_v3.cc:139
GICv3 ITS module.
Definition: gic_v3_its.hh:76
uint64_t read(Addr addr, size_t size, bool is_secure_access)
static const int INTID_SECURE
Definition: gic_v3.hh:73

Generated on Fri Feb 28 2020 16:27:00 for gem5 by doxygen 1.8.13