110810Sbr@bsdpad.com/* 210810Sbr@bsdpad.com * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> 310810Sbr@bsdpad.com * All rights reserved. 410810Sbr@bsdpad.com * 510810Sbr@bsdpad.com * This software was developed by the University of Cambridge Computer 610810Sbr@bsdpad.com * Laboratory as part of the CTSRD Project, with support from the UK Higher 710810Sbr@bsdpad.com * Education Innovation Fund (HEIF). 810810Sbr@bsdpad.com * 910810Sbr@bsdpad.com * Redistribution and use in source and binary forms, with or without 1010810Sbr@bsdpad.com * modification, are permitted provided that the following conditions are 1110810Sbr@bsdpad.com * met: redistributions of source code must retain the above copyright 1210810Sbr@bsdpad.com * notice, this list of conditions and the following disclaimer; 1310810Sbr@bsdpad.com * redistributions in binary form must reproduce the above copyright 1410810Sbr@bsdpad.com * notice, this list of conditions and the following disclaimer in the 1510810Sbr@bsdpad.com * documentation and/or other materials provided with the distribution; 1610810Sbr@bsdpad.com * neither the name of the copyright holders nor the names of its 1710810Sbr@bsdpad.com * contributors may be used to endorse or promote products derived from 1810810Sbr@bsdpad.com * this software without specific prior written permission. 1910810Sbr@bsdpad.com * 2010810Sbr@bsdpad.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2110810Sbr@bsdpad.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2210810Sbr@bsdpad.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2310810Sbr@bsdpad.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2410810Sbr@bsdpad.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2510810Sbr@bsdpad.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2610810Sbr@bsdpad.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2710810Sbr@bsdpad.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2810810Sbr@bsdpad.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2910810Sbr@bsdpad.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3010810Sbr@bsdpad.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3110810Sbr@bsdpad.com */ 3210810Sbr@bsdpad.com 3310810Sbr@bsdpad.com#include "arch/arm/freebsd/system.hh" 3410810Sbr@bsdpad.com 3510810Sbr@bsdpad.com#include "arch/arm/isa_traits.hh" 3610810Sbr@bsdpad.com#include "arch/arm/utility.hh" 3710810Sbr@bsdpad.com#include "arch/generic/freebsd/threadinfo.hh" 3810810Sbr@bsdpad.com#include "base/loader/dtb_object.hh" 3910810Sbr@bsdpad.com#include "base/loader/object_file.hh" 4010810Sbr@bsdpad.com#include "base/loader/symtab.hh" 4110810Sbr@bsdpad.com#include "cpu/base.hh" 4210810Sbr@bsdpad.com#include "cpu/pc_event.hh" 4310810Sbr@bsdpad.com#include "cpu/thread_context.hh" 4410810Sbr@bsdpad.com#include "debug/Loader.hh" 4510810Sbr@bsdpad.com#include "kern/freebsd/events.hh" 4610810Sbr@bsdpad.com#include "mem/fs_translating_port_proxy.hh" 4710810Sbr@bsdpad.com#include "mem/physical.hh" 4810810Sbr@bsdpad.com#include "sim/stat_control.hh" 4910810Sbr@bsdpad.com 5010810Sbr@bsdpad.comusing namespace ArmISA; 5110810Sbr@bsdpad.comusing namespace FreeBSD; 5210810Sbr@bsdpad.com 5310810Sbr@bsdpad.comFreebsdArmSystem::FreebsdArmSystem(Params *p) 5412017Sandreas.sandberg@arm.com : GenericArmSystem(p), 5510810Sbr@bsdpad.com enableContextSwitchStatsDump(p->enable_context_switch_stats_dump), 5610822Sandreas.hansson@arm.com taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr) 5710810Sbr@bsdpad.com{ 5810810Sbr@bsdpad.com if (p->panic_on_panic) { 5910810Sbr@bsdpad.com kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>( 6010810Sbr@bsdpad.com "panic", "Kernel panic in simulated kernel"); 6110810Sbr@bsdpad.com } else { 6210810Sbr@bsdpad.com#ifndef NDEBUG 6310810Sbr@bsdpad.com kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic"); 6410810Sbr@bsdpad.com#endif 6510810Sbr@bsdpad.com } 6610810Sbr@bsdpad.com 6710810Sbr@bsdpad.com if (p->panic_on_oops) { 6810810Sbr@bsdpad.com kernelOopsEvent = addKernelFuncEventOrPanic<PanicPCEvent>( 6910810Sbr@bsdpad.com "oops_exit", "Kernel oops in guest"); 7010810Sbr@bsdpad.com } 7110810Sbr@bsdpad.com 7210810Sbr@bsdpad.com uDelaySkipEvent = addKernelFuncEvent<UDelayEvent>( 7310810Sbr@bsdpad.com "DELAY", "DELAY", 1000, 0); 7410810Sbr@bsdpad.com} 7510810Sbr@bsdpad.com 7610810Sbr@bsdpad.comvoid 7710810Sbr@bsdpad.comFreebsdArmSystem::initState() 7810810Sbr@bsdpad.com{ 7910810Sbr@bsdpad.com // Moved from the constructor to here since it relies on the 8010810Sbr@bsdpad.com // address map being resolved in the interconnect 8110810Sbr@bsdpad.com 8210810Sbr@bsdpad.com // Call the initialisation of the super class 8310810Sbr@bsdpad.com GenericArmSystem::initState(); 8410810Sbr@bsdpad.com 8510810Sbr@bsdpad.com // Load symbols at physical address, we might not want 8610810Sbr@bsdpad.com // to do this permanently, for but early bootup work 8710810Sbr@bsdpad.com // it is helpful. 8810810Sbr@bsdpad.com if (params()->early_kernel_symbols) { 8911392Sbrandon.potter@amd.com kernel->loadGlobalSymbols(kernelSymtab, 0, 0, loadAddrMask); 9011392Sbrandon.potter@amd.com kernel->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); 9110810Sbr@bsdpad.com } 9210810Sbr@bsdpad.com 9310810Sbr@bsdpad.com // Setup boot data structure 9410810Sbr@bsdpad.com Addr addr = 0; 9510810Sbr@bsdpad.com 9610810Sbr@bsdpad.com // Check if the kernel image has a symbol that tells us it supports 9710810Sbr@bsdpad.com // device trees. 9810810Sbr@bsdpad.com bool kernel_has_fdt_support = 9910810Sbr@bsdpad.com kernelSymtab->findAddress("fdt_get_range", addr); 10010810Sbr@bsdpad.com bool dtb_file_specified = params()->dtb_filename != ""; 10110810Sbr@bsdpad.com 10210810Sbr@bsdpad.com if (!dtb_file_specified) 10310810Sbr@bsdpad.com fatal("dtb file is not specified\n"); 10410810Sbr@bsdpad.com 10510810Sbr@bsdpad.com if (!kernel_has_fdt_support) 10610810Sbr@bsdpad.com fatal("kernel must have fdt support\n"); 10710810Sbr@bsdpad.com 10810810Sbr@bsdpad.com // Kernel supports flattened device tree and dtb file specified. 10910810Sbr@bsdpad.com // Using Device Tree Blob to describe system configuration. 11010810Sbr@bsdpad.com inform("Loading DTB file: %s at address %#x\n", params()->dtb_filename, 11110810Sbr@bsdpad.com params()->atags_addr + loadAddrOffset); 11210810Sbr@bsdpad.com 11310810Sbr@bsdpad.com ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true); 11410810Sbr@bsdpad.com if (!dtb_file) { 11510810Sbr@bsdpad.com fatal("couldn't load DTB file: %s\n", params()->dtb_filename); 11610810Sbr@bsdpad.com } 11710810Sbr@bsdpad.com 11810810Sbr@bsdpad.com DtbObject *_dtb_file = dynamic_cast<DtbObject*>(dtb_file); 11910810Sbr@bsdpad.com 12010810Sbr@bsdpad.com if (_dtb_file) { 12110810Sbr@bsdpad.com if (!_dtb_file->addBootCmdLine(params()->boot_osflags.c_str(), 12210810Sbr@bsdpad.com params()->boot_osflags.size())) { 12310810Sbr@bsdpad.com warn("couldn't append bootargs to DTB file: %s\n", 12410810Sbr@bsdpad.com params()->dtb_filename); 12510810Sbr@bsdpad.com } 12610810Sbr@bsdpad.com } else { 12710810Sbr@bsdpad.com warn("dtb_file cast failed; couldn't append bootargs " 12810810Sbr@bsdpad.com "to DTB file: %s\n", params()->dtb_filename); 12910810Sbr@bsdpad.com } 13010810Sbr@bsdpad.com 13110810Sbr@bsdpad.com Addr ra = _dtb_file->findReleaseAddr(); 13210810Sbr@bsdpad.com if (ra) 13310810Sbr@bsdpad.com bootReleaseAddr = ra & ~ULL(0x7F); 13410810Sbr@bsdpad.com 13510810Sbr@bsdpad.com dtb_file->setTextBase(params()->atags_addr + loadAddrOffset); 13610810Sbr@bsdpad.com dtb_file->loadSections(physProxy); 13710810Sbr@bsdpad.com delete dtb_file; 13810810Sbr@bsdpad.com 13910810Sbr@bsdpad.com // Kernel boot requirements to set up r0, r1 and r2 in ARMv7 14010810Sbr@bsdpad.com for (int i = 0; i < threadContexts.size(); i++) { 14110810Sbr@bsdpad.com threadContexts[i]->setIntReg(0, 0); 14210810Sbr@bsdpad.com threadContexts[i]->setIntReg(1, params()->machine_type); 14310810Sbr@bsdpad.com threadContexts[i]->setIntReg(2, params()->atags_addr + loadAddrOffset); 14410810Sbr@bsdpad.com } 14510810Sbr@bsdpad.com} 14610810Sbr@bsdpad.com 14710810Sbr@bsdpad.comFreebsdArmSystem::~FreebsdArmSystem() 14810810Sbr@bsdpad.com{ 14910810Sbr@bsdpad.com if (uDelaySkipEvent) 15010810Sbr@bsdpad.com delete uDelaySkipEvent; 15110810Sbr@bsdpad.com if (constUDelaySkipEvent) 15210810Sbr@bsdpad.com delete constUDelaySkipEvent; 15310810Sbr@bsdpad.com} 15410810Sbr@bsdpad.com 15510810Sbr@bsdpad.comFreebsdArmSystem * 15610810Sbr@bsdpad.comFreebsdArmSystemParams::create() 15710810Sbr@bsdpad.com{ 15810810Sbr@bsdpad.com return new FreebsdArmSystem(this); 15910810Sbr@bsdpad.com} 16010810Sbr@bsdpad.com 16110810Sbr@bsdpad.comvoid 16210810Sbr@bsdpad.comFreebsdArmSystem::startup() 16310810Sbr@bsdpad.com{ 16410810Sbr@bsdpad.com} 165