system.cc revision 10846:751aa8add0bc
1695SN/A/* 21762SN/A * Copyright (c) 2010, 2012-2013 ARM Limited 3695SN/A * All rights reserved 4695SN/A * 5695SN/A * The license below extends only to copyright in the software and shall 6695SN/A * not be construed as granting a license to any other intellectual 7695SN/A * property including but not limited to intellectual property relating 8695SN/A * to a hardware implementation of the functionality of the software 9695SN/A * licensed hereunder. You may use the software subject to the license 10695SN/A * terms below provided that you ensure that this notice is replicated 11695SN/A * unmodified and in its entirety in all distributions of the software, 12695SN/A * modified or unmodified, in source code or in binary form. 13695SN/A * 14695SN/A * Copyright (c) 2002-2006 The Regents of The University of Michigan 15695SN/A * All rights reserved. 16695SN/A * 17695SN/A * Redistribution and use in source and binary forms, with or without 18695SN/A * modification, are permitted provided that the following conditions are 19695SN/A * met: redistributions of source code must retain the above copyright 20695SN/A * notice, this list of conditions and the following disclaimer; 21695SN/A * redistributions in binary form must reproduce the above copyright 22695SN/A * notice, this list of conditions and the following disclaimer in the 23695SN/A * documentation and/or other materials provided with the distribution; 24695SN/A * neither the name of the copyright holders nor the names of its 25695SN/A * contributors may be used to endorse or promote products derived from 26695SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38695SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39695SN/A * 40695SN/A * Authors: Ali Saidi 41695SN/A */ 42695SN/A 43695SN/A#include <iostream> 441717SN/A 45695SN/A#include "arch/arm/system.hh" 46695SN/A#include "base/loader/object_file.hh" 47695SN/A#include "base/loader/symtab.hh" 481696SN/A#include "cpu/thread_context.hh" 49695SN/A#include "mem/physical.hh" 50695SN/A#include "mem/fs_translating_port_proxy.hh" 51695SN/A#include "sim/full_system.hh" 52729SN/A 53729SN/Ausing namespace std; 54729SN/Ausing namespace Linux; 55729SN/A 56695SN/AArmSystem::ArmSystem(Params *p) 57729SN/A : System(p), bootldr(NULL), _haveSecurity(p->have_security), 58729SN/A _haveLPAE(p->have_lpae), 59729SN/A _haveVirtualization(p->have_virtualization), 60729SN/A _genericTimer(nullptr), 61695SN/A _highestELIs64(p->highest_el_is_64), 62729SN/A _resetAddr64(p->reset_addr_64), 63695SN/A _physAddrRange64(p->phys_addr_range_64), 64695SN/A _haveLargeAsid64(p->have_large_asid_64), 65695SN/A multiProc(p->multi_proc) 661953SN/A{ 67695SN/A // Check if the physical address range is valid 68695SN/A if (_highestELIs64 && ( 69695SN/A _physAddrRange64 < 32 || 70695SN/A _physAddrRange64 > 48 || 71695SN/A (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) { 72695SN/A fatal("Invalid physical address range (%d)\n", _physAddrRange64); 73695SN/A } 74695SN/A 75695SN/A if (p->boot_loader != "") { 76695SN/A bootldr = createObjectFile(p->boot_loader); 77695SN/A 78695SN/A if (!bootldr) 79695SN/A fatal("Could not read bootloader: %s\n", p->boot_loader); 80695SN/A 81695SN/A if ((bootldr->getArch() == ObjectFile::Arm64) && !_highestELIs64) { 82695SN/A warn("Highest ARM exception-level set to AArch32 but bootloader " 83695SN/A "is for AArch64. Assuming you wanted these to match.\n"); 84695SN/A _highestELIs64 = true; 85695SN/A } else if ((bootldr->getArch() == ObjectFile::Arm) && _highestELIs64) { 861020SN/A warn("Highest ARM exception-level set to AArch64 but bootloader " 871020SN/A "is for AArch32. Assuming you wanted these to match.\n"); 881020SN/A _highestELIs64 = false; 891020SN/A } 901020SN/A 911020SN/A bootldr->loadGlobalSymbols(debugSymbolTable); 92695SN/A 93695SN/A } 94695SN/A debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); 95695SN/A} 96695SN/A 97695SN/Avoid 98707SN/AArmSystem::initState() 99695SN/A{ 100695SN/A // Moved from the constructor to here since it relies on the 101695SN/A // address map being resolved in the interconnect 102695SN/A 103695SN/A // Call the initialisation of the super class 104695SN/A System::initState(); 105695SN/A 106695SN/A const Params* p = params(); 107695SN/A 108695SN/A if (bootldr) { 109695SN/A bootldr->loadSections(physProxy); 110707SN/A 1111609SN/A uint8_t jump_to_bl_32[] = 112707SN/A { 113707SN/A 0x07, 0xf0, 0xa0, 0xe1 // branch to r7 in aarch32 114707SN/A }; 115707SN/A 116695SN/A uint8_t jump_to_bl_64[] = 1171020SN/A { 118695SN/A 0xe0, 0x00, 0x1f, 0xd6 // instruction "br x7" in aarch64 119695SN/A }; 120695SN/A 121695SN/A // write the jump to branch table into address 0 122695SN/A if (!_highestELIs64) 123695SN/A physProxy.writeBlob(0x0, jump_to_bl_32, sizeof(jump_to_bl_32)); 124695SN/A else 125695SN/A physProxy.writeBlob(0x0, jump_to_bl_64, sizeof(jump_to_bl_64)); 126695SN/A 127695SN/A inform("Using bootloader at address %#x\n", bootldr->entryPoint()); 128695SN/A 129695SN/A // Put the address of the boot loader into r7 so we know 130707SN/A // where to branch to after the reset fault 131695SN/A // All other values needed by the boot loader to know what to do 132695SN/A if (!p->gic_cpu_addr || !p->flags_addr) 133695SN/A fatal("gic_cpu_addr && flags_addr must be set with bootloader\n"); 134695SN/A 135695SN/A for (int i = 0; i < threadContexts.size(); i++) { 136695SN/A if (!_highestELIs64) 137707SN/A threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) + 138695SN/A loadAddrOffset); 139695SN/A threadContexts[i]->setIntReg(4, params()->gic_cpu_addr); 140695SN/A threadContexts[i]->setIntReg(5, params()->flags_addr); 141695SN/A threadContexts[i]->setIntReg(7, bootldr->entryPoint()); 142695SN/A } 143695SN/A inform("Using kernel entry physical address at %#x\n", 144695SN/A (kernelEntry & loadAddrMask) + loadAddrOffset); 145695SN/A } else { 146695SN/A // Set the initial PC to be at start of the kernel code 147695SN/A if (!_highestELIs64) 148695SN/A threadContexts[0]->pcState((kernelEntry & loadAddrMask) + 149707SN/A loadAddrOffset); 150695SN/A } 151695SN/A} 152695SN/A 153695SN/Abool 154695SN/AArmSystem::haveSecurity(ThreadContext *tc) 155695SN/A{ 156695SN/A if (!FullSystem) 157695SN/A return false; 158695SN/A 159695SN/A ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr()); 160695SN/A assert(a_sys); 161695SN/A return a_sys->haveSecurity(); 162695SN/A} 163695SN/A 164695SN/A 165695SN/AArmSystem::~ArmSystem() 166695SN/A{ 167695SN/A if (debugPrintkEvent) 168695SN/A delete debugPrintkEvent; 169695SN/A} 170695SN/A 171695SN/Abool 172695SN/AArmSystem::haveLPAE(ThreadContext *tc) 173695SN/A{ 174695SN/A if (!FullSystem) 175695SN/A return false; 176695SN/A 177695SN/A ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr()); 178695SN/A assert(a_sys); 179695SN/A return a_sys->haveLPAE(); 180695SN/A} 181695SN/A 182695SN/Abool 183695SN/AArmSystem::haveVirtualization(ThreadContext *tc) 184695SN/A{ 185729SN/A if (!FullSystem) 186695SN/A return false; 187695SN/A 188729SN/A ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr()); 189695SN/A assert(a_sys); 190695SN/A return a_sys->haveVirtualization(); 191695SN/A} 192695SN/A 193695SN/Abool 194695SN/AArmSystem::highestELIs64(ThreadContext *tc) 195695SN/A{ 196695SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->highestELIs64(); 197695SN/A} 198695SN/A 199695SN/AExceptionLevel 2001953SN/AArmSystem::highestEL(ThreadContext *tc) 2011953SN/A{ 2021953SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->highestEL(); 2031953SN/A} 2041953SN/A 205695SN/AAddr 206695SN/AArmSystem::resetAddr64(ThreadContext *tc) 207695SN/A{ 208695SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->resetAddr64(); 209695SN/A} 210695SN/A 211695SN/Auint8_t 212695SN/AArmSystem::physAddrRange(ThreadContext *tc) 213695SN/A{ 214695SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->physAddrRange(); 215695SN/A} 216695SN/A 217695SN/AAddr 218695SN/AArmSystem::physAddrMask(ThreadContext *tc) 219695SN/A{ 220695SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->physAddrMask(); 221695SN/A} 222729SN/A 223695SN/Abool 224695SN/AArmSystem::haveLargeAsid64(ThreadContext *tc) 225695SN/A{ 226695SN/A return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->haveLargeAsid64(); 227729SN/A} 228695SN/A 229695SN/AArmSystem * 230ArmSystemParams::create() 231{ 232 return new ArmSystem(this); 233} 234 235void 236GenericArmSystem::initState() 237{ 238 // Moved from the constructor to here since it relies on the 239 // address map being resolved in the interconnect 240 241 // Call the initialisation of the super class 242 ArmSystem::initState(); 243} 244 245GenericArmSystem * 246GenericArmSystemParams::create() 247{ 248 249 return new GenericArmSystem(this); 250} 251