gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
system.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2013, 2015,2017-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) 2002-2006 The Regents of The University of Michigan
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: Ali Saidi
41  */
42 
43 #include "arch/arm/system.hh"
44 
45 #include <iostream>
46 
47 #include "arch/arm/faults.hh"
48 #include "arch/arm/semihosting.hh"
50 #include "base/loader/symtab.hh"
51 #include "cpu/thread_context.hh"
52 #include "dev/arm/gic_v2.hh"
54 #include "mem/physical.hh"
55 #include "sim/full_system.hh"
56 
57 using namespace std;
58 using namespace Linux;
59 
61  : System(p),
62  bootLoaders(), bootldr(nullptr),
63  _haveSecurity(p->have_security),
64  _haveLPAE(p->have_lpae),
65  _haveVirtualization(p->have_virtualization),
66  _haveCrypto(p->have_crypto),
67  _genericTimer(nullptr),
68  _gic(nullptr),
69  _resetAddr(p->auto_reset_addr ?
70  (kernelEntry & loadAddrMask) + loadAddrOffset :
71  p->reset_addr),
72  _highestELIs64(p->highest_el_is_64),
73  _physAddrRange64(p->phys_addr_range_64),
74  _haveLargeAsid64(p->have_large_asid_64),
75  _haveSVE(p->have_sve),
76  _sveVL(p->sve_vl),
77  _haveLSE(p->have_lse),
78  _havePAN(p->have_pan),
79  semihosting(p->semihosting),
80  multiProc(p->multi_proc)
81 {
82  // Check if the physical address range is valid
83  if (_highestELIs64 && (
84  _physAddrRange64 < 32 ||
85  _physAddrRange64 > 48 ||
86  (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) {
87  fatal("Invalid physical address range (%d)\n", _physAddrRange64);
88  }
89 
90  bootLoaders.reserve(p->boot_loader.size());
91  for (const auto &bl : p->boot_loader) {
92  std::unique_ptr<ObjectFile> obj;
93  obj.reset(createObjectFile(bl));
94 
95  fatal_if(!obj, "Could not read bootloader: %s\n", bl);
96  bootLoaders.emplace_back(std::move(obj));
97  }
98 
99  if (kernel) {
101  } else if (!bootLoaders.empty()) {
102  // No kernel specified, default to the first boot loader
103  bootldr = bootLoaders[0].get();
104  }
105 
106  if (!bootLoaders.empty() && !bootldr)
107  fatal("Can't find a matching boot loader / kernel combination!");
108 
109  if (bootldr) {
111 
113  "Bootloader entry point %#x overriding reset address %#x",
115  const_cast<Addr&>(_resetAddr) = bootldr->entryPoint();
116 
118  warn("Highest ARM exception-level set to AArch32 but bootloader "
119  "is for AArch64. Assuming you wanted these to match.\n");
120  _highestELIs64 = true;
121  } else if ((bootldr->getArch() == ObjectFile::Arm) && _highestELIs64) {
122  warn("Highest ARM exception-level set to AArch64 but bootloader "
123  "is for AArch32. Assuming you wanted these to match.\n");
124  _highestELIs64 = false;
125  }
126  }
127 
128  debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
129 }
130 
131 void
133 {
134  // Moved from the constructor to here since it relies on the
135  // address map being resolved in the interconnect
136 
137  // Call the initialisation of the super class
139 
140  // Reset CP15?? What does that mean -- ali
141 
142  // FPEXC.EN = 0
143 
144  for (auto *tc: threadContexts) {
145  Reset().invoke(tc);
146  tc->activate();
147  }
148 
149  const Params* p = params();
150 
151  if (bootldr) {
152  bool is_gic_v2 =
155 
156  inform("Using bootloader at address %#x\n", bootldr->entryPoint());
157 
158  // Put the address of the boot loader into r7 so we know
159  // where to branch to after the reset fault
160  // All other values needed by the boot loader to know what to do
161  if (!p->flags_addr)
162  fatal("flags_addr must be set with bootloader\n");
163 
164  if (!p->gic_cpu_addr && is_gic_v2)
165  fatal("gic_cpu_addr must be set with bootloader\n");
166 
167  for (int i = 0; i < threadContexts.size(); i++) {
168  if (!_highestELIs64)
169  threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) +
171  if (is_gic_v2)
172  threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
173  threadContexts[i]->setIntReg(5, params()->flags_addr);
174  }
175  inform("Using kernel entry physical address at %#x\n",
177  } else {
178  // Set the initial PC to be at start of the kernel code
179  if (!_highestELIs64)
180  threadContexts[0]->pcState((kernelEntry & loadAddrMask) +
182  }
183 }
184 
185 ArmSystem *
187 {
188  ArmSystem *a_sys = dynamic_cast<ArmSystem *>(sys);
189  assert(a_sys);
190  return a_sys;
191 }
192 
193 ArmSystem*
195 {
196  ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr());
197  assert(a_sys);
198  return a_sys;
199 }
200 
201 bool
203 {
204  return FullSystem? getArmSystem(tc)->haveSecurity() : false;
205 }
206 
207 
209 {
210  if (debugPrintkEvent)
211  delete debugPrintkEvent;
212 }
213 
214 ObjectFile *
216 {
217  for (auto &bl : bootLoaders) {
218  if (bl->getArch() == obj->getArch())
219  return bl.get();
220  }
221 
222  return nullptr;
223 }
224 
225 bool
227 {
228  return FullSystem? getArmSystem(tc)->haveLPAE() : false;
229 }
230 
231 bool
233 {
234  return FullSystem? getArmSystem(tc)->haveVirtualization() : false;
235 }
236 
237 bool
239 {
240  return FullSystem? getArmSystem(tc)->highestELIs64() : true;
241 }
242 
245 {
246  return FullSystem? getArmSystem(tc)->highestEL() : EL1;
247 }
248 
249 bool
251 {
252  switch (el) {
253  case EL0:
254  case EL1:
255  return true;
256  case EL2:
257  return haveVirtualization(tc);
258  case EL3:
259  return haveSecurity(tc);
260  default:
261  warn("Unimplemented Exception Level\n");
262  return false;
263  }
264 }
265 
266 Addr
268 {
269  return getArmSystem(tc)->resetAddr();
270 }
271 
272 uint8_t
274 {
275  return getArmSystem(tc)->physAddrRange();
276 }
277 
278 Addr
280 {
281  return getArmSystem(tc)->physAddrMask();
282 }
283 
284 bool
286 {
287  return getArmSystem(tc)->haveLargeAsid64();
288 }
289 
290 bool
292 {
293  return FullSystem && getArmSystem(tc)->haveSemihosting();
294 }
295 
296 uint64_t
298  uint32_t op, uint64_t param)
299 {
300  ArmSystem *sys = getArmSystem(tc);
301  return sys->semihosting->call64(tc, op, param);
302 }
303 
304 uint32_t
306  uint32_t op, uint32_t param)
307 {
308  ArmSystem *sys = getArmSystem(tc);
309  return sys->semihosting->call32(tc, op, param);
310 }
311 
312 ArmSystem *
313 ArmSystemParams::create()
314 {
315  return new ArmSystem(this);
316 }
317 
318 void
320 {
321  // Moved from the constructor to here since it relies on the
322  // address map being resolved in the interconnect
323 
324  // Call the initialisation of the super class
326 }
327 
329 GenericArmSystemParams::create()
330 {
331 
332  return new GenericArmSystem(this);
333 }
ObjectFile * getBootLoader(ObjectFile *const obj)
Get a boot loader that matches the kernel.
Definition: system.cc:215
virtual System * getSystemPtr()=0
const uint8_t _physAddrRange64
Supported physical address range in bits if the highest implemented exception level is 64 bits (ARMv8...
Definition: system.hh:118
virtual void initState()
Initialise the system.
Definition: system.cc:319
Arch getArch() const
Definition: object_file.hh:124
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:175
Addr physAddrMask() const
Returns the physical address mask.
Definition: system.hh:267
Bitfield< 7 > i
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:185
bool write(const PortProxy &proxy) const
Definition: memory_image.cc:50
ObjectFile * createObjectFile(const std::string &fname, bool raw)
Definition: object_file.cc:64
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:221
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:136
const Addr _resetAddr
Reset address (ARMv8)
Definition: system.hh:106
static uint64_t callSemihosting64(ThreadContext *tc, uint32_t op, uint64_t param)
Make a Semihosting call from aarch64.
Definition: system.cc:297
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:45
Definition: system.hh:77
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
ThreadContext is the external interface to all thread state for anything outside of the CPU...
ObjectFile * bootldr
Pointer to the bootloader object.
Definition: system.hh:75
ExceptionLevel
Definition: types.hh:585
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition: system.cc:250
ArmSystem(Params *p)
Definition: system.cc:60
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:218
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: system.cc:349
virtual MemoryImage buildImage() const =0
#define inform(...)
Definition: logging.hh:213
Bitfield< 3, 2 > el
std::vector< std::unique_ptr< ObjectFile > > bootLoaders
Bootloaders.
Definition: system.hh:70
bool _highestELIs64
True if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:112
Addr loadAddrMask
Mask that should be anded for binary/symbol loading.
Definition: system.hh:245
static ArmSystem * getArmSystem(System *sys)
Casts the provided System object into a valid ArmSystem, it fails otherwise.
Definition: system.cc:186
BaseGic * getGIC() const
Get a pointer to the system&#39;s GIC.
Definition: system.hh:217
uint32_t call32(ThreadContext *tc, uint32_t op, uint32_t param)
Perform an Arm Semihosting call from aarch32 code.
Definition: semihosting.cc:194
static uint32_t callSemihosting32(ThreadContext *tc, uint32_t op, uint32_t param)
Make a Semihosting call from aarch32.
Definition: system.cc:305
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:228
std::vector< ThreadContext * > threadContexts
Definition: system.hh:190
Addr kernelEntry
Entry point in the kernel to start at.
Definition: system.hh:237
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
Linux::DebugPrintkEvent * debugPrintkEvent
PC based event to skip the dprink() call and emulate its functionality.
Definition: system.hh:67
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:194
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
~ArmSystem()
Definition: system.cc:208
ObjectFile * kernel
Object pointer for the kernel code.
Definition: system.hh:224
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:257
ExceptionLevel highestEL() const
Returns the highest implemented exception level.
Definition: system.hh:224
ArmSemihosting *const semihosting
True if the Semihosting interface is enabled.
Definition: system.hh:144
ArmSystemParams Params
Definition: system.hh:157
Implementation of a GICv2.
virtual void initState()
Initialise the system.
Definition: system.cc:132
TranslatingPortProxy Object Declaration for FS.
Addr entryPoint() const
Definition: object_file.hh:131
#define warn(...)
Definition: logging.hh:212
Bitfield< 4 > op
Definition: types.hh:80
Addr loadAddrOffset
Offset that should be used for binary/symbol loading.
Definition: system.hh:252
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:238
bool haveSemihosting() const
Is Arm Semihosting support enabled?
Definition: system.hh:273
Bitfield< 0 > p
const Params * params() const
Definition: system.hh:159
Addr resetAddr() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:235
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=MaxAddr)
Definition: object_file.hh:90
uint64_t call64(ThreadContext *tc, uint32_t op, uint64_t param)
Perform an Arm Semihosting call from aarch64 code.
Definition: semihosting.cc:159
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:189
virtual bool supportsVersion(GicVersion version)=0
Check if version supported.

Generated on Fri Feb 28 2020 16:26:56 for gem5 by doxygen 1.8.13