gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
system.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2013, 2015 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 
48 #include "base/loader/symtab.hh"
49 #include "cpu/thread_context.hh"
51 #include "mem/physical.hh"
52 #include "sim/full_system.hh"
53 
54 using namespace std;
55 using namespace Linux;
56 
58  : System(p),
59  bootLoaders(), bootldr(nullptr),
60  _haveSecurity(p->have_security),
61  _haveLPAE(p->have_lpae),
62  _haveVirtualization(p->have_virtualization),
63  _genericTimer(nullptr),
64  _highestELIs64(p->highest_el_is_64),
65  _resetAddr64(p->reset_addr_64),
66  _physAddrRange64(p->phys_addr_range_64),
67  _haveLargeAsid64(p->have_large_asid_64),
68  _m5opRange(p->m5ops_base ?
69  RangeSize(p->m5ops_base, 0x10000) :
70  AddrRange(1, 0)), // Create an empty range if disabled
71  multiProc(p->multi_proc)
72 {
73  // Check if the physical address range is valid
74  if (_highestELIs64 && (
75  _physAddrRange64 < 32 ||
76  _physAddrRange64 > 48 ||
77  (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) {
78  fatal("Invalid physical address range (%d)\n", _physAddrRange64);
79  }
80 
81  bootLoaders.reserve(p->boot_loader.size());
82  for (const auto &bl : p->boot_loader) {
83  std::unique_ptr<ObjectFile> obj;
84  obj.reset(createObjectFile(bl));
85 
86  fatal_if(!obj, "Could not read bootloader: %s\n", bl);
87  bootLoaders.emplace_back(std::move(obj));
88  }
89 
90  if (kernel) {
92  } else if (!bootLoaders.empty()) {
93  // No kernel specified, default to the first boot loader
94  bootldr = bootLoaders[0].get();
95  }
96 
97  if (!bootLoaders.empty() && !bootldr)
98  fatal("Can't find a matching boot loader / kernel combination!");
99 
100  if (bootldr) {
103  warn("Highest ARM exception-level set to AArch32 but bootloader "
104  "is for AArch64. Assuming you wanted these to match.\n");
105  _highestELIs64 = true;
106  } else if ((bootldr->getArch() == ObjectFile::Arm) && _highestELIs64) {
107  warn("Highest ARM exception-level set to AArch64 but bootloader "
108  "is for AArch32. Assuming you wanted these to match.\n");
109  _highestELIs64 = false;
110  }
111  }
112 
113  debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
114 }
115 
116 void
118 {
119  // Moved from the constructor to here since it relies on the
120  // address map being resolved in the interconnect
121 
122  // Call the initialisation of the super class
124 
125  const Params* p = params();
126 
127  if (bootldr) {
129 
130  uint8_t jump_to_bl_32[] =
131  {
132  0x07, 0xf0, 0xa0, 0xe1 // branch to r7 in aarch32
133  };
134 
135  uint8_t jump_to_bl_64[] =
136  {
137  0xe0, 0x00, 0x1f, 0xd6 // instruction "br x7" in aarch64
138  };
139 
140  // write the jump to branch table into address 0
141  if (!_highestELIs64)
142  physProxy.writeBlob(0x0, jump_to_bl_32, sizeof(jump_to_bl_32));
143  else
144  physProxy.writeBlob(0x0, jump_to_bl_64, sizeof(jump_to_bl_64));
145 
146  inform("Using bootloader at address %#x\n", bootldr->entryPoint());
147 
148  // Put the address of the boot loader into r7 so we know
149  // where to branch to after the reset fault
150  // All other values needed by the boot loader to know what to do
151  if (!p->gic_cpu_addr || !p->flags_addr)
152  fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
153 
154  for (int i = 0; i < threadContexts.size(); i++) {
155  if (!_highestELIs64)
156  threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) +
158  threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
159  threadContexts[i]->setIntReg(5, params()->flags_addr);
160  threadContexts[i]->setIntReg(7, bootldr->entryPoint());
161  }
162  inform("Using kernel entry physical address at %#x\n",
164  } else {
165  // Set the initial PC to be at start of the kernel code
166  if (!_highestELIs64)
167  threadContexts[0]->pcState((kernelEntry & loadAddrMask) +
169  }
170 }
171 
172 bool
174 {
175  if (!FullSystem)
176  return false;
177 
178  ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr());
179  assert(a_sys);
180  return a_sys->haveSecurity();
181 }
182 
183 
185 {
186  if (debugPrintkEvent)
187  delete debugPrintkEvent;
188 }
189 
190 ObjectFile *
192 {
193  for (auto &bl : bootLoaders) {
194  if (bl->getArch() == obj->getArch())
195  return bl.get();
196  }
197 
198  return nullptr;
199 }
200 
201 bool
203 {
204  if (!FullSystem)
205  return false;
206 
207  ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr());
208  assert(a_sys);
209  return a_sys->haveLPAE();
210 }
211 
212 bool
214 {
215  if (!FullSystem)
216  return false;
217 
218  ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr());
219  assert(a_sys);
220  return a_sys->haveVirtualization();
221 }
222 
223 bool
225 {
226  return FullSystem ?
227  dynamic_cast<ArmSystem *>(tc->getSystemPtr())->highestELIs64() :
228  true;
229 }
230 
233 {
234  return FullSystem ?
235  dynamic_cast<ArmSystem *>(tc->getSystemPtr())->highestEL() :
236  EL1;
237 }
238 
239 Addr
241 {
242  return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->resetAddr64();
243 }
244 
245 uint8_t
247 {
248  return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->physAddrRange();
249 }
250 
251 Addr
253 {
254  return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->physAddrMask();
255 }
256 
257 bool
259 {
260  return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->haveLargeAsid64();
261 }
262 
263 ArmSystem *
264 ArmSystemParams::create()
265 {
266  return new ArmSystem(this);
267 }
268 
269 void
271 {
272  // Moved from the constructor to here since it relies on the
273  // address map being resolved in the interconnect
274 
275  // Call the initialisation of the super class
277 }
278 
280 GenericArmSystemParams::create()
281 {
282 
283  return new GenericArmSystem(this);
284 }
ObjectFile * getBootLoader(ObjectFile *const obj)
Get a boot loader that matches the kernel.
Definition: system.cc:191
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:398
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:112
virtual void initState()
Initialise the system.
Definition: system.cc:270
Bitfield< 7 > i
Definition: miscregs.hh:1378
Arch getArch() const
Definition: object_file.hh:111
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=maxAddr)=0
ExceptionLevel highestEL() const
Returns the highest implemented exception level.
Definition: system.hh:189
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:45
Definition: system.hh:83
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:210
Addr physAddrMask() const
Returns the physical address mask.
Definition: system.hh:220
const Params * params() const
Definition: system.hh:138
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:74
ExceptionLevel
Definition: types.hh:562
ArmSystem(Params *p)
Definition: system.cc:57
#define warn(...)
Definition: misc.hh:219
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:224
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:72
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: system.cc:289
std::vector< std::unique_ptr< ObjectFile > > bootLoaders
Bootloaders.
Definition: system.hh:69
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:168
bool _highestELIs64
True if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:100
This class encapsulates the types, structures, constants, functions, and syscall-number mappings spec...
Definition: linux.hh:48
Addr loadAddrMask
Mask that should be anded for binary/symbol loading.
Definition: system.hh:247
std::vector< ThreadContext * > threadContexts
Definition: system.hh:199
#define fatal(...)
Definition: misc.hh:163
Addr kernelEntry
Entry point in the kernel to start at.
Definition: system.hh:239
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:186
Linux::DebugPrintkEvent * debugPrintkEvent
PC based event to skip the dprink() call and emulate its functionality.
Definition: system.hh:66
Addr entryPoint() const
Definition: object_file.hh:134
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:164
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
virtual bool loadSections(PortProxy &mem_proxy, Addr mask=maxAddr, Addr offset=0)
Definition: object_file.cc:93
~ArmSystem()
Definition: system.cc:184
ObjectFile * kernel
Object pointer for the kernel code.
Definition: system.hh:230
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:173
ObjectFile * createObjectFile(const string &fname, bool raw)
Definition: object_file.cc:157
ArmSystemParams Params
Definition: system.hh:136
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
Definition: port_proxy.cc:58
virtual void initState()
Initialise the system.
Definition: system.cc:117
TranslatingPortProxy Object Declaration for FS.
Addr loadAddrOffset
Offset that should be used for binary/symbol loading.
Definition: system.hh:254
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
#define inform(...)
Definition: misc.hh:221
Bitfield< 0 > p
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:203
Addr resetAddr64() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:200

Generated on Fri Jun 9 2017 13:03:34 for gem5 by doxygen 1.8.6