system.cc revision 9261
17585SAli.Saidi@arm.com/* 27585SAli.Saidi@arm.com * Copyright (c) 2010 ARM Limited 37585SAli.Saidi@arm.com * All rights reserved 47585SAli.Saidi@arm.com * 57585SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall 67585SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual 77585SAli.Saidi@arm.com * property including but not limited to intellectual property relating 87585SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software 97585SAli.Saidi@arm.com * licensed hereunder. You may use the software subject to the license 107585SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated 117585SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software, 127585SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form. 137585SAli.Saidi@arm.com * 147585SAli.Saidi@arm.com * Copyright (c) 2002-2006 The Regents of The University of Michigan 157585SAli.Saidi@arm.com * All rights reserved. 167585SAli.Saidi@arm.com * 177585SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 187585SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 197585SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 207585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 217585SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 227585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 237585SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 247585SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 257585SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 267585SAli.Saidi@arm.com * this software without specific prior written permission. 277585SAli.Saidi@arm.com * 287585SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297585SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307585SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317585SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327585SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337585SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347585SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357585SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367585SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377585SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387585SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397585SAli.Saidi@arm.com * 407585SAli.Saidi@arm.com * Authors: Ali Saidi 417585SAli.Saidi@arm.com */ 427585SAli.Saidi@arm.com 437585SAli.Saidi@arm.com#include "arch/arm/linux/atag.hh" 447585SAli.Saidi@arm.com#include "arch/arm/linux/system.hh" 458229Snate@binkert.org#include "arch/arm/isa_traits.hh" 467723SAli.Saidi@ARM.com#include "arch/arm/utility.hh" 477585SAli.Saidi@arm.com#include "base/loader/object_file.hh" 487585SAli.Saidi@arm.com#include "base/loader/symtab.hh" 497723SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 508245Snate@binkert.org#include "debug/Loader.hh" 518143SAli.Saidi@ARM.com#include "kern/linux/events.hh" 528706Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh" 537585SAli.Saidi@arm.com#include "mem/physical.hh" 547585SAli.Saidi@arm.com 557585SAli.Saidi@arm.comusing namespace ArmISA; 568143SAli.Saidi@ARM.comusing namespace Linux; 577585SAli.Saidi@arm.com 587585SAli.Saidi@arm.comLinuxArmSystem::LinuxArmSystem(Params *p) 597585SAli.Saidi@arm.com : ArmSystem(p) 607585SAli.Saidi@arm.com{ 618885SAli.Saidi@ARM.com#ifndef NDEBUG 628885SAli.Saidi@ARM.com kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); 638885SAli.Saidi@ARM.com if (!kernelPanicEvent) 648885SAli.Saidi@ARM.com panic("could not find kernel symbol \'panic\'"); 658885SAli.Saidi@ARM.com#endif 668885SAli.Saidi@ARM.com 678885SAli.Saidi@ARM.com // With ARM udelay() is #defined to __udelay 688885SAli.Saidi@ARM.com Addr addr = 0; 698885SAli.Saidi@ARM.com if (kernelSymtab->findAddress("__udelay", addr)) { 708885SAli.Saidi@ARM.com uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay", 718885SAli.Saidi@ARM.com fixFuncEventAddr(addr), 1000, 0); 728885SAli.Saidi@ARM.com } else { 738885SAli.Saidi@ARM.com panic("couldn't find kernel symbol \'udelay\'"); 748885SAli.Saidi@ARM.com } 758885SAli.Saidi@ARM.com 768885SAli.Saidi@ARM.com // constant arguments to udelay() have some precomputation done ahead of 778885SAli.Saidi@ARM.com // time. Constant comes from code. 788885SAli.Saidi@ARM.com if (kernelSymtab->findAddress("__const_udelay", addr)) { 798885SAli.Saidi@ARM.com constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay", 808885SAli.Saidi@ARM.com fixFuncEventAddr(addr), 1000, 107374); 818885SAli.Saidi@ARM.com } else { 828885SAli.Saidi@ARM.com panic("couldn't find kernel symbol \'udelay\'"); 838885SAli.Saidi@ARM.com } 848885SAli.Saidi@ARM.com 858885SAli.Saidi@ARM.com secDataPtrAddr = 0; 868885SAli.Saidi@ARM.com secDataAddr = 0; 878885SAli.Saidi@ARM.com penReleaseAddr = 0; 888885SAli.Saidi@ARM.com kernelSymtab->findAddress("__secondary_data", secDataPtrAddr); 898885SAli.Saidi@ARM.com kernelSymtab->findAddress("secondary_data", secDataAddr); 908885SAli.Saidi@ARM.com kernelSymtab->findAddress("pen_release", penReleaseAddr); 918885SAli.Saidi@ARM.com 928885SAli.Saidi@ARM.com secDataPtrAddr &= ~ULL(0x7F); 938885SAli.Saidi@ARM.com secDataAddr &= ~ULL(0x7F); 948885SAli.Saidi@ARM.com penReleaseAddr &= ~ULL(0x7F); 958706Sandreas.hansson@arm.com} 968706Sandreas.hansson@arm.com 978706Sandreas.hansson@arm.combool 988706Sandreas.hansson@arm.comLinuxArmSystem::adderBootUncacheable(Addr a) 998706Sandreas.hansson@arm.com{ 1008706Sandreas.hansson@arm.com Addr block = a & ~ULL(0x7F); 1018706Sandreas.hansson@arm.com if (block == secDataPtrAddr || block == secDataAddr || 1028706Sandreas.hansson@arm.com block == penReleaseAddr) 1038706Sandreas.hansson@arm.com return true; 1048706Sandreas.hansson@arm.com return false; 1058706Sandreas.hansson@arm.com} 1068706Sandreas.hansson@arm.com 1078706Sandreas.hansson@arm.comvoid 1088706Sandreas.hansson@arm.comLinuxArmSystem::initState() 1098706Sandreas.hansson@arm.com{ 1108706Sandreas.hansson@arm.com // Moved from the constructor to here since it relies on the 1118706Sandreas.hansson@arm.com // address map being resolved in the interconnect 1128706Sandreas.hansson@arm.com 1138706Sandreas.hansson@arm.com // Call the initialisation of the super class 1148706Sandreas.hansson@arm.com ArmSystem::initState(); 1158706Sandreas.hansson@arm.com 1167585SAli.Saidi@arm.com // Load symbols at physical address, we might not want 1178997Sdam.sunwoo@arm.com // to do this permanently, for but early bootup work 1188997Sdam.sunwoo@arm.com // it is helpful. 1198997Sdam.sunwoo@arm.com if (params()->early_kernel_symbols) { 1208997Sdam.sunwoo@arm.com kernel->loadGlobalSymbols(kernelSymtab, loadAddrMask); 1218997Sdam.sunwoo@arm.com kernel->loadGlobalSymbols(debugSymbolTable, loadAddrMask); 1228997Sdam.sunwoo@arm.com } 1237585SAli.Saidi@arm.com 1247585SAli.Saidi@arm.com // Setup boot data structure 1259261Sdam.sunwoo@arm.com Addr addr = 0; 1269261Sdam.sunwoo@arm.com // Check if the kernel image has a symbol that tells us it supports 1279261Sdam.sunwoo@arm.com // device trees. 1289261Sdam.sunwoo@arm.com bool kernel_has_fdt_support = 1299261Sdam.sunwoo@arm.com kernelSymtab->findAddress("unflatten_device_tree", addr); 1309261Sdam.sunwoo@arm.com bool dtb_file_specified = params()->dtb_filename != ""; 1317585SAli.Saidi@arm.com 1329261Sdam.sunwoo@arm.com if (kernel_has_fdt_support && dtb_file_specified) { 1339261Sdam.sunwoo@arm.com // Kernel supports flattened device tree and dtb file specified. 1349261Sdam.sunwoo@arm.com // Using Device Tree Blob to describe system configuration. 1359261Sdam.sunwoo@arm.com inform("Loading DTB file: %s\n", params()->dtb_filename); 1369261Sdam.sunwoo@arm.com 1379261Sdam.sunwoo@arm.com ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true); 1389261Sdam.sunwoo@arm.com if (!dtb_file) { 1399261Sdam.sunwoo@arm.com fatal("couldn't load DTB file: %s\n", params()->dtb_filename); 1409261Sdam.sunwoo@arm.com } 1419261Sdam.sunwoo@arm.com dtb_file->setTextBase(params()->atags_addr); 1429261Sdam.sunwoo@arm.com dtb_file->loadSections(physProxy); 1439261Sdam.sunwoo@arm.com delete dtb_file; 1449261Sdam.sunwoo@arm.com } else { 1459261Sdam.sunwoo@arm.com // Using ATAGS 1469261Sdam.sunwoo@arm.com // Warn if the kernel supports FDT and we haven't specified one 1479261Sdam.sunwoo@arm.com if (kernel_has_fdt_support) { 1489261Sdam.sunwoo@arm.com assert(!dtb_file_specified); 1499261Sdam.sunwoo@arm.com warn("Kernel supports device tree, but no DTB file specified\n"); 1509261Sdam.sunwoo@arm.com } 1519261Sdam.sunwoo@arm.com // Warn if the kernel doesn't support FDT and we have specified one 1529261Sdam.sunwoo@arm.com if (dtb_file_specified) { 1539261Sdam.sunwoo@arm.com assert(!kernel_has_fdt_support); 1549261Sdam.sunwoo@arm.com warn("DTB file specified, but no device tree support in kernel\n"); 1559261Sdam.sunwoo@arm.com } 1569261Sdam.sunwoo@arm.com 1579261Sdam.sunwoo@arm.com AtagCore *ac = new AtagCore; 1589261Sdam.sunwoo@arm.com ac->flags(1); // read-only 1599261Sdam.sunwoo@arm.com ac->pagesize(8192); 1609261Sdam.sunwoo@arm.com ac->rootdev(0); 1619261Sdam.sunwoo@arm.com 1629261Sdam.sunwoo@arm.com AddrRangeList atagRanges = physmem.getConfAddrRanges(); 1639261Sdam.sunwoo@arm.com if (atagRanges.size() != 1) { 1649261Sdam.sunwoo@arm.com fatal("Expected a single ATAG memory entry but got %d\n", 1659261Sdam.sunwoo@arm.com atagRanges.size()); 1669261Sdam.sunwoo@arm.com } 1679261Sdam.sunwoo@arm.com AtagMem *am = new AtagMem; 1689261Sdam.sunwoo@arm.com am->memSize(atagRanges.begin()->size()); 1699261Sdam.sunwoo@arm.com am->memStart(atagRanges.begin()->start); 1709261Sdam.sunwoo@arm.com 1719261Sdam.sunwoo@arm.com AtagCmdline *ad = new AtagCmdline; 1729261Sdam.sunwoo@arm.com ad->cmdline(params()->boot_osflags); 1739261Sdam.sunwoo@arm.com 1749261Sdam.sunwoo@arm.com DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, params()->boot_osflags.c_str()); 1759261Sdam.sunwoo@arm.com 1769261Sdam.sunwoo@arm.com AtagNone *an = new AtagNone; 1779261Sdam.sunwoo@arm.com 1789261Sdam.sunwoo@arm.com uint32_t size = ac->size() + am->size() + ad->size() + an->size(); 1799261Sdam.sunwoo@arm.com uint32_t offset = 0; 1809261Sdam.sunwoo@arm.com uint8_t *boot_data = new uint8_t[size << 2]; 1819261Sdam.sunwoo@arm.com 1829261Sdam.sunwoo@arm.com offset += ac->copyOut(boot_data + offset); 1839261Sdam.sunwoo@arm.com offset += am->copyOut(boot_data + offset); 1849261Sdam.sunwoo@arm.com offset += ad->copyOut(boot_data + offset); 1859261Sdam.sunwoo@arm.com offset += an->copyOut(boot_data + offset); 1869261Sdam.sunwoo@arm.com 1879261Sdam.sunwoo@arm.com DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2); 1889261Sdam.sunwoo@arm.com DDUMP(Loader, boot_data, size << 2); 1899261Sdam.sunwoo@arm.com 1909261Sdam.sunwoo@arm.com physProxy.writeBlob(params()->atags_addr, boot_data, size << 2); 1918931Sandreas.hansson@arm.com } 1927585SAli.Saidi@arm.com 1938286SAli.Saidi@ARM.com for (int i = 0; i < threadContexts.size(); i++) { 1948286SAli.Saidi@ARM.com threadContexts[i]->setIntReg(0, 0); 1958286SAli.Saidi@ARM.com threadContexts[i]->setIntReg(1, params()->machine_type); 1968870SAli.Saidi@ARM.com threadContexts[i]->setIntReg(2, params()->atags_addr); 1978286SAli.Saidi@ARM.com } 1987585SAli.Saidi@arm.com} 1997585SAli.Saidi@arm.com 2007585SAli.Saidi@arm.comLinuxArmSystem::~LinuxArmSystem() 2017585SAli.Saidi@arm.com{ 2028143SAli.Saidi@ARM.com if (uDelaySkipEvent) 2038143SAli.Saidi@ARM.com delete uDelaySkipEvent; 2048143SAli.Saidi@ARM.com if (constUDelaySkipEvent) 2058143SAli.Saidi@ARM.com delete constUDelaySkipEvent; 2067585SAli.Saidi@arm.com} 2077585SAli.Saidi@arm.com 2087585SAli.Saidi@arm.comLinuxArmSystem * 2097585SAli.Saidi@arm.comLinuxArmSystemParams::create() 2107585SAli.Saidi@arm.com{ 2117585SAli.Saidi@arm.com return new LinuxArmSystem(this); 2127585SAli.Saidi@arm.com} 213