system.cc revision 12531:3141027bd11a
17405SAli.Saidi@ARM.com/* 212667Schuan.zhu@arm.com * Copyright (c) 2010, 2012-2013, 2015,2017-2018 ARM Limited 37405SAli.Saidi@ARM.com * All rights reserved 47405SAli.Saidi@ARM.com * 57405SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 67405SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 77405SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 87405SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 97405SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 107405SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 117405SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 127405SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 137405SAli.Saidi@ARM.com * 147405SAli.Saidi@ARM.com * Copyright (c) 2002-2006 The Regents of The University of Michigan 157405SAli.Saidi@ARM.com * All rights reserved. 167405SAli.Saidi@ARM.com * 177405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 187405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 197405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 207405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 217405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 227405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 237405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 247405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 257405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 267405SAli.Saidi@ARM.com * this software without specific prior written permission. 277405SAli.Saidi@ARM.com * 287405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397405SAli.Saidi@ARM.com * 407405SAli.Saidi@ARM.com * Authors: Ali Saidi 417405SAli.Saidi@ARM.com */ 4210461SAndreas.Sandberg@ARM.com 439050Schander.sudanthi@arm.com#include "arch/arm/system.hh" 4412406Sgabeblack@google.com 4512605Sgiacomo.travaglini@arm.com#include <iostream> 4611793Sbrandon.potter@amd.com 478887Sgeoffrey.blake@arm.com#include "arch/arm/semihosting.hh" 488232Snate@binkert.org#include "base/loader/object_file.hh" 498232Snate@binkert.org#include "base/loader/symtab.hh" 5010844Sandreas.sandberg@arm.com#include "cpu/thread_context.hh" 5113531Sjairo.balart@metempsy.com#include "mem/fs_translating_port_proxy.hh" 5213531Sjairo.balart@metempsy.com#include "mem/physical.hh" 539384SAndreas.Sandberg@arm.com#include "sim/full_system.hh" 547678Sgblack@eecs.umich.edu 558059SAli.Saidi@ARM.comusing namespace std; 568284SAli.Saidi@ARM.comusing namespace Linux; 577405SAli.Saidi@ARM.com 587405SAli.Saidi@ARM.comArmSystem::ArmSystem(Params *p) 597405SAli.Saidi@ARM.com : System(p), 607405SAli.Saidi@ARM.com bootLoaders(), bootldr(nullptr), 619384SAndreas.Sandberg@arm.com _haveSecurity(p->have_security), 6210461SAndreas.Sandberg@ARM.com _haveLPAE(p->have_lpae), 6310461SAndreas.Sandberg@ARM.com _haveVirtualization(p->have_virtualization), 6411165SRekai.GonzalezAlberquilla@arm.com _genericTimer(nullptr), 6512109SRekai.GonzalezAlberquilla@arm.com _highestELIs64(p->highest_el_is_64), 6612714Sgiacomo.travaglini@arm.com _resetAddr64(p->auto_reset_addr_64 ? 6712714Sgiacomo.travaglini@arm.com (kernelEntry & loadAddrMask) + loadAddrOffset : 689384SAndreas.Sandberg@arm.com p->reset_addr_64), 6911770SCurtis.Dunham@arm.com _physAddrRange64(p->phys_addr_range_64), 7010037SARM gem5 Developers _haveLargeAsid64(p->have_large_asid_64), 7110461SAndreas.Sandberg@ARM.com _m5opRange(p->m5ops_base ? 7210461SAndreas.Sandberg@ARM.com RangeSize(p->m5ops_base, 0x10000) : 7310461SAndreas.Sandberg@ARM.com AddrRange(1, 0)), // Create an empty range if disabled 7410461SAndreas.Sandberg@ARM.com semihosting(p->semihosting), 7510461SAndreas.Sandberg@ARM.com multiProc(p->multi_proc) 7610461SAndreas.Sandberg@ARM.com{ 7710609Sandreas.sandberg@arm.com // Check if the physical address range is valid 7810609Sandreas.sandberg@arm.com if (_highestELIs64 && ( 7910609Sandreas.sandberg@arm.com _physAddrRange64 < 32 || 8010037SARM gem5 Developers _physAddrRange64 > 48 || 8110037SARM gem5 Developers (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) { 8210037SARM gem5 Developers fatal("Invalid physical address range (%d)\n", _physAddrRange64); 8310037SARM gem5 Developers } 8411771SCurtis.Dunham@arm.com 8510037SARM gem5 Developers bootLoaders.reserve(p->boot_loader.size()); 8610037SARM gem5 Developers for (const auto &bl : p->boot_loader) { 8713173Sgiacomo.travaglini@arm.com std::unique_ptr<ObjectFile> obj; 8810037SARM gem5 Developers obj.reset(createObjectFile(bl)); 8910037SARM gem5 Developers 9013114Sgiacomo.travaglini@arm.com fatal_if(!obj, "Could not read bootloader: %s\n", bl); 9110037SARM gem5 Developers bootLoaders.emplace_back(std::move(obj)); 9211771SCurtis.Dunham@arm.com } 9310037SARM gem5 Developers 9413499Sgiacomo.travaglini@arm.com if (kernel) { 9510037SARM gem5 Developers bootldr = getBootLoader(kernel); 9613114Sgiacomo.travaglini@arm.com } else if (!bootLoaders.empty()) { 9710037SARM gem5 Developers // No kernel specified, default to the first boot loader 9810037SARM gem5 Developers bootldr = bootLoaders[0].get(); 9913531Sjairo.balart@metempsy.com } 10013531Sjairo.balart@metempsy.com 10113531Sjairo.balart@metempsy.com if (!bootLoaders.empty() && !bootldr) 10213531Sjairo.balart@metempsy.com fatal("Can't find a matching boot loader / kernel combination!"); 10313531Sjairo.balart@metempsy.com 10413531Sjairo.balart@metempsy.com if (bootldr) { 10513531Sjairo.balart@metempsy.com bootldr->loadGlobalSymbols(debugSymbolTable); 10612477SCurtis.Dunham@arm.com if ((bootldr->getArch() == ObjectFile::Arm64) && !_highestELIs64) { 10710037SARM gem5 Developers warn("Highest ARM exception-level set to AArch32 but bootloader " 10810037SARM gem5 Developers "is for AArch64. Assuming you wanted these to match.\n"); 1099384SAndreas.Sandberg@arm.com _highestELIs64 = true; 1109384SAndreas.Sandberg@arm.com } else if ((bootldr->getArch() == ObjectFile::Arm) && _highestELIs64) { 1119384SAndreas.Sandberg@arm.com warn("Highest ARM exception-level set to AArch64 but bootloader " 11212479SCurtis.Dunham@arm.com "is for AArch32. Assuming you wanted these to match.\n"); 11312479SCurtis.Dunham@arm.com _highestELIs64 = false; 1149384SAndreas.Sandberg@arm.com } 1159384SAndreas.Sandberg@arm.com } 1169384SAndreas.Sandberg@arm.com 1179384SAndreas.Sandberg@arm.com debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); 1189384SAndreas.Sandberg@arm.com} 1199384SAndreas.Sandberg@arm.com 1207427Sgblack@eecs.umich.eduvoid 1217427Sgblack@eecs.umich.eduArmSystem::initState() 1227427Sgblack@eecs.umich.edu{ 1239385SAndreas.Sandberg@arm.com // Moved from the constructor to here since it relies on the 1249385SAndreas.Sandberg@arm.com // address map being resolved in the interconnect 1257427Sgblack@eecs.umich.edu 1267427Sgblack@eecs.umich.edu // Call the initialisation of the super class 12710037SARM gem5 Developers System::initState(); 12813114Sgiacomo.travaglini@arm.com 12910037SARM gem5 Developers const Params* p = params(); 13013114Sgiacomo.travaglini@arm.com 13113114Sgiacomo.travaglini@arm.com if (bootldr) { 13213114Sgiacomo.travaglini@arm.com bootldr->loadSections(physProxy); 13313114Sgiacomo.travaglini@arm.com 13413114Sgiacomo.travaglini@arm.com uint8_t jump_to_bl_32[] = 13512690Sgiacomo.travaglini@arm.com { 13610037SARM gem5 Developers 0x07, 0xf0, 0xa0, 0xe1 // branch to r7 in aarch32 1377427Sgblack@eecs.umich.edu }; 1387427Sgblack@eecs.umich.edu 13910037SARM gem5 Developers uint8_t jump_to_bl_64[] = 1407427Sgblack@eecs.umich.edu { 1417427Sgblack@eecs.umich.edu 0xe0, 0x00, 0x1f, 0xd6 // instruction "br x7" in aarch64 1427427Sgblack@eecs.umich.edu }; 1437427Sgblack@eecs.umich.edu 1447427Sgblack@eecs.umich.edu // write the jump to branch table into address 0 1457427Sgblack@eecs.umich.edu if (!_highestELIs64) 1467427Sgblack@eecs.umich.edu physProxy.writeBlob(0x0, jump_to_bl_32, sizeof(jump_to_bl_32)); 1477427Sgblack@eecs.umich.edu else 1487427Sgblack@eecs.umich.edu physProxy.writeBlob(0x0, jump_to_bl_64, sizeof(jump_to_bl_64)); 1497427Sgblack@eecs.umich.edu 1507427Sgblack@eecs.umich.edu inform("Using bootloader at address %#x\n", bootldr->entryPoint()); 1517427Sgblack@eecs.umich.edu 1527427Sgblack@eecs.umich.edu // Put the address of the boot loader into r7 so we know 1537427Sgblack@eecs.umich.edu // where to branch to after the reset fault 1547427Sgblack@eecs.umich.edu // All other values needed by the boot loader to know what to do 1557427Sgblack@eecs.umich.edu if (!p->gic_cpu_addr || !p->flags_addr) 1567427Sgblack@eecs.umich.edu fatal("gic_cpu_addr && flags_addr must be set with bootloader\n"); 1577427Sgblack@eecs.umich.edu 1587427Sgblack@eecs.umich.edu for (int i = 0; i < threadContexts.size(); i++) { 1597427Sgblack@eecs.umich.edu if (!_highestELIs64) 1607427Sgblack@eecs.umich.edu threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) + 1617427Sgblack@eecs.umich.edu loadAddrOffset); 1627427Sgblack@eecs.umich.edu threadContexts[i]->setIntReg(4, params()->gic_cpu_addr); 1637436Sdam.sunwoo@arm.com threadContexts[i]->setIntReg(5, params()->flags_addr); 1647436Sdam.sunwoo@arm.com threadContexts[i]->setIntReg(7, bootldr->entryPoint()); 16510037SARM gem5 Developers } 16610037SARM gem5 Developers inform("Using kernel entry physical address at %#x\n", 1677436Sdam.sunwoo@arm.com (kernelEntry & loadAddrMask) + loadAddrOffset); 1687436Sdam.sunwoo@arm.com } else { 1697436Sdam.sunwoo@arm.com // Set the initial PC to be at start of the kernel code 1707436Sdam.sunwoo@arm.com if (!_highestELIs64) 1717436Sdam.sunwoo@arm.com threadContexts[0]->pcState((kernelEntry & loadAddrMask) + 1727436Sdam.sunwoo@arm.com loadAddrOffset); 1737436Sdam.sunwoo@arm.com } 1747436Sdam.sunwoo@arm.com} 1757436Sdam.sunwoo@arm.com 1767436Sdam.sunwoo@arm.comArmSystem* 1777436Sdam.sunwoo@arm.comArmSystem::getArmSystem(ThreadContext *tc) 1787436Sdam.sunwoo@arm.com{ 17913393Sgiacomo.travaglini@arm.com ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr()); 18010037SARM gem5 Developers assert(a_sys); 1817436Sdam.sunwoo@arm.com return a_sys; 1827436Sdam.sunwoo@arm.com} 1837436Sdam.sunwoo@arm.com 1847436Sdam.sunwoo@arm.combool 1857436Sdam.sunwoo@arm.comArmSystem::haveSecurity(ThreadContext *tc) 1867436Sdam.sunwoo@arm.com{ 1877436Sdam.sunwoo@arm.com return FullSystem? getArmSystem(tc)->haveSecurity() : false; 1887436Sdam.sunwoo@arm.com} 1897436Sdam.sunwoo@arm.com 1907436Sdam.sunwoo@arm.com 1917436Sdam.sunwoo@arm.comArmSystem::~ArmSystem() 1927436Sdam.sunwoo@arm.com{ 1937436Sdam.sunwoo@arm.com if (debugPrintkEvent) 1947436Sdam.sunwoo@arm.com delete debugPrintkEvent; 1957436Sdam.sunwoo@arm.com} 1967436Sdam.sunwoo@arm.com 19713393Sgiacomo.travaglini@arm.comObjectFile * 19813393Sgiacomo.travaglini@arm.comArmSystem::getBootLoader(ObjectFile *const obj) 19913393Sgiacomo.travaglini@arm.com{ 20013393Sgiacomo.travaglini@arm.com for (auto &bl : bootLoaders) { 20113393Sgiacomo.travaglini@arm.com if (bl->getArch() == obj->getArch()) 20213393Sgiacomo.travaglini@arm.com return bl.get(); 20313393Sgiacomo.travaglini@arm.com } 20413393Sgiacomo.travaglini@arm.com 20513393Sgiacomo.travaglini@arm.com return nullptr; 20613393Sgiacomo.travaglini@arm.com} 20713393Sgiacomo.travaglini@arm.com 20813393Sgiacomo.travaglini@arm.combool 20913393Sgiacomo.travaglini@arm.comArmSystem::haveLPAE(ThreadContext *tc) 21013393Sgiacomo.travaglini@arm.com{ 21113393Sgiacomo.travaglini@arm.com return FullSystem? getArmSystem(tc)->haveLPAE() : false; 21213393Sgiacomo.travaglini@arm.com} 21313396Sgiacomo.travaglini@arm.com 21413396Sgiacomo.travaglini@arm.combool 21513396Sgiacomo.travaglini@arm.comArmSystem::haveVirtualization(ThreadContext *tc) 21613396Sgiacomo.travaglini@arm.com{ 21713393Sgiacomo.travaglini@arm.com return FullSystem? getArmSystem(tc)->haveVirtualization() : false; 21813393Sgiacomo.travaglini@arm.com} 21913393Sgiacomo.travaglini@arm.com 22013393Sgiacomo.travaglini@arm.combool 22113393Sgiacomo.travaglini@arm.comArmSystem::highestELIs64(ThreadContext *tc) 22213393Sgiacomo.travaglini@arm.com{ 22313393Sgiacomo.travaglini@arm.com return FullSystem? getArmSystem(tc)->highestELIs64() : true; 22413393Sgiacomo.travaglini@arm.com} 22513393Sgiacomo.travaglini@arm.com 22613393Sgiacomo.travaglini@arm.comExceptionLevel 22713393Sgiacomo.travaglini@arm.comArmSystem::highestEL(ThreadContext *tc) 22813393Sgiacomo.travaglini@arm.com{ 22913393Sgiacomo.travaglini@arm.com return FullSystem? getArmSystem(tc)->highestEL() : EL1; 23013393Sgiacomo.travaglini@arm.com} 23113393Sgiacomo.travaglini@arm.com 23213393Sgiacomo.travaglini@arm.combool 23313393Sgiacomo.travaglini@arm.comArmSystem::haveEL(ThreadContext *tc, ExceptionLevel el) 23413393Sgiacomo.travaglini@arm.com{ 2357644Sali.saidi@arm.com switch (el) { 2368147SAli.Saidi@ARM.com case EL0: 2379385SAndreas.Sandberg@arm.com case EL1: 2389385SAndreas.Sandberg@arm.com return true; 23910037SARM gem5 Developers case EL2: 24010037SARM gem5 Developers return haveVirtualization(tc); 24110037SARM gem5 Developers case EL3: 24210037SARM gem5 Developers return haveSecurity(tc); 24310037SARM gem5 Developers default: 24410037SARM gem5 Developers warn("Unimplemented Exception Level\n"); 24510037SARM gem5 Developers return false; 24610037SARM gem5 Developers } 24710037SARM gem5 Developers} 24810037SARM gem5 Developers 24910037SARM gem5 DevelopersAddr 25010037SARM gem5 DevelopersArmSystem::resetAddr64(ThreadContext *tc) 25110037SARM gem5 Developers{ 25210037SARM gem5 Developers return getArmSystem(tc)->resetAddr64(); 25310037SARM gem5 Developers} 25410037SARM gem5 Developers 2558147SAli.Saidi@ARM.comuint8_t 2567427Sgblack@eecs.umich.eduArmSystem::physAddrRange(ThreadContext *tc) 2577427Sgblack@eecs.umich.edu{ 2587427Sgblack@eecs.umich.edu return getArmSystem(tc)->physAddrRange(); 25910037SARM gem5 Developers} 26010037SARM gem5 Developers 26110037SARM gem5 DevelopersAddr 26210037SARM gem5 DevelopersArmSystem::physAddrMask(ThreadContext *tc) 26313396Sgiacomo.travaglini@arm.com{ 26410037SARM gem5 Developers return getArmSystem(tc)->physAddrMask(); 26510037SARM gem5 Developers} 26610037SARM gem5 Developers 26710037SARM gem5 Developersbool 26810037SARM gem5 DevelopersArmSystem::haveLargeAsid64(ThreadContext *tc) 26910037SARM gem5 Developers{ 27010037SARM gem5 Developers return getArmSystem(tc)->haveLargeAsid64(); 27110037SARM gem5 Developers} 27210037SARM gem5 Developers 27310037SARM gem5 Developersbool 27410037SARM gem5 DevelopersArmSystem::haveSemihosting(ThreadContext *tc) 27510037SARM gem5 Developers{ 27610037SARM gem5 Developers return getArmSystem(tc)->haveSemihosting(); 27710037SARM gem5 Developers} 27810037SARM gem5 Developers 27910037SARM gem5 Developersuint64_t 28010037SARM gem5 DevelopersArmSystem::callSemihosting64(ThreadContext *tc, 28110037SARM gem5 Developers uint32_t op, uint64_t param) 28210037SARM gem5 Developers{ 28310037SARM gem5 Developers ArmSystem *sys = getArmSystem(tc); 28410037SARM gem5 Developers return sys->semihosting->call64(tc, op, param); 28510037SARM gem5 Developers} 28610037SARM gem5 Developers 28710037SARM gem5 Developersuint32_t 28810037SARM gem5 DevelopersArmSystem::callSemihosting32(ThreadContext *tc, 28910037SARM gem5 Developers uint32_t op, uint32_t param) 29010037SARM gem5 Developers{ 29110037SARM gem5 Developers ArmSystem *sys = getArmSystem(tc); 29210037SARM gem5 Developers return sys->semihosting->call32(tc, op, param); 29310037SARM gem5 Developers} 29410037SARM gem5 Developers 29511770SCurtis.Dunham@arm.comArmSystem * 29610037SARM gem5 DevelopersArmSystemParams::create() 29711574SCurtis.Dunham@arm.com{ 29811770SCurtis.Dunham@arm.com return new ArmSystem(this); 29911770SCurtis.Dunham@arm.com} 30010037SARM gem5 Developers 30111770SCurtis.Dunham@arm.comvoid 30211770SCurtis.Dunham@arm.comGenericArmSystem::initState() 30310037SARM gem5 Developers{ 30410037SARM gem5 Developers // Moved from the constructor to here since it relies on the 30510037SARM gem5 Developers // address map being resolved in the interconnect 30613114Sgiacomo.travaglini@arm.com 30710037SARM gem5 Developers // Call the initialisation of the super class 30813114Sgiacomo.travaglini@arm.com ArmSystem::initState(); 30913114Sgiacomo.travaglini@arm.com} 31013114Sgiacomo.travaglini@arm.com 31113114Sgiacomo.travaglini@arm.comGenericArmSystem * 31213114Sgiacomo.travaglini@arm.comGenericArmSystemParams::create() 31313114Sgiacomo.travaglini@arm.com{ 31413114Sgiacomo.travaglini@arm.com 31513114Sgiacomo.travaglini@arm.com return new GenericArmSystem(this); 31613114Sgiacomo.travaglini@arm.com} 31713114Sgiacomo.travaglini@arm.com