dtb_object.cc revision 11793
19538Satgutier@umich.edu/* 29538Satgutier@umich.edu * Copyright (c) 2013 The Regents of The University of Michigan 39538Satgutier@umich.edu * All rights reserved. 49538Satgutier@umich.edu * 59538Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 69538Satgutier@umich.edu * modification, are permitted provided that the following conditions are 79538Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 89538Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 99538Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 109538Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 119538Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 129538Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 139538Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 149538Satgutier@umich.edu * this software without specific prior written permission. 159538Satgutier@umich.edu * 169538Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179538Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189538Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199538Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209538Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219538Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229538Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239538Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249538Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259538Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269538Satgutier@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279538Satgutier@umich.edu * 289538Satgutier@umich.edu * Authors: Anthony Gutierrez 299538Satgutier@umich.edu */ 309538Satgutier@umich.edu 3111761Sbrandon.potter@amd.com#include "base/loader/dtb_object.hh" 3211761Sbrandon.potter@amd.com 339538Satgutier@umich.edu#include <sys/mman.h> 349538Satgutier@umich.edu#include <unistd.h> 359538Satgutier@umich.edu 369538Satgutier@umich.edu#include <cassert> 379538Satgutier@umich.edu 389538Satgutier@umich.edu#include "fdt.h" 399538Satgutier@umich.edu#include "libfdt.h" 4011793Sbrandon.potter@amd.com#include "sim/byteswap.hh" 419538Satgutier@umich.edu 429538Satgutier@umich.eduObjectFile * 4310880SCurtis.Dunham@arm.comDtbObject::tryFile(const std::string &fname, size_t len, uint8_t *data) 449538Satgutier@umich.edu{ 459538Satgutier@umich.edu // Check if this is a FDT file by looking for magic number 469538Satgutier@umich.edu if (fdt_magic((void*)data) == FDT_MAGIC) { 4710880SCurtis.Dunham@arm.com return new DtbObject(fname, len, data, 489538Satgutier@umich.edu ObjectFile::UnknownArch, ObjectFile::UnknownOpSys); 499538Satgutier@umich.edu } else { 509538Satgutier@umich.edu return NULL; 519538Satgutier@umich.edu } 529538Satgutier@umich.edu} 539538Satgutier@umich.edu 5410880SCurtis.Dunham@arm.comDtbObject::DtbObject(const std::string &_filename, size_t _len, uint8_t *_data, 559538Satgutier@umich.edu Arch _arch, OpSys _opSys) 5610880SCurtis.Dunham@arm.com : ObjectFile(_filename, _len, _data, _arch, _opSys) 579538Satgutier@umich.edu{ 589538Satgutier@umich.edu text.baseAddr = 0; 599538Satgutier@umich.edu text.size = len; 609538Satgutier@umich.edu text.fileImage = fileData; 619538Satgutier@umich.edu 629538Satgutier@umich.edu data.baseAddr = 0; 639538Satgutier@umich.edu data.size = 0; 649538Satgutier@umich.edu data.fileImage = NULL; 659538Satgutier@umich.edu 669538Satgutier@umich.edu bss.baseAddr = 0; 679538Satgutier@umich.edu bss.size = 0; 689538Satgutier@umich.edu bss.fileImage = NULL; 699538Satgutier@umich.edu 709538Satgutier@umich.edu fileDataMmapped = true; 719538Satgutier@umich.edu} 729538Satgutier@umich.edu 739538Satgutier@umich.eduDtbObject::~DtbObject() 749538Satgutier@umich.edu{ 759538Satgutier@umich.edu // Make sure to clean up memory properly depending 769538Satgutier@umich.edu // on how buffer was allocated. 779538Satgutier@umich.edu if (fileData && !fileDataMmapped) { 789538Satgutier@umich.edu delete [] fileData; 799538Satgutier@umich.edu fileData = NULL; 809538Satgutier@umich.edu } else if (fileData) { 819538Satgutier@umich.edu munmap(fileData, len); 829538Satgutier@umich.edu fileData = NULL; 839538Satgutier@umich.edu } 849538Satgutier@umich.edu} 859538Satgutier@umich.edu 869538Satgutier@umich.edubool 879538Satgutier@umich.eduDtbObject::addBootCmdLine(const char* _args, size_t len) 889538Satgutier@umich.edu{ 899538Satgutier@umich.edu const char* root_path = "/"; 909538Satgutier@umich.edu const char* node_name = "chosen"; 919538Satgutier@umich.edu const char* full_path_node_name = "/chosen"; 929538Satgutier@umich.edu const char* property_name = "bootargs"; 939538Satgutier@umich.edu 949538Satgutier@umich.edu // Make a new buffer that has extra space to add nodes/properties 959538Satgutier@umich.edu int newLen = 2*this->len; 969538Satgutier@umich.edu uint8_t* fdt_buf_w_space = new uint8_t[newLen]; 979538Satgutier@umich.edu // Copy and unpack flattened device tree into new buffer 989538Satgutier@umich.edu int ret = fdt_open_into((void*)fileData, (void*)fdt_buf_w_space, (newLen)); 999538Satgutier@umich.edu if (ret < 0) { 1009538Satgutier@umich.edu warn("Error resizing buffer of flattened device tree, " 1019538Satgutier@umich.edu "errno: %d\n", ret); 1029538Satgutier@umich.edu delete [] fdt_buf_w_space; 1039538Satgutier@umich.edu return false; 1049538Satgutier@umich.edu } 1059538Satgutier@umich.edu 1069538Satgutier@umich.edu // First try finding the /chosen node in the dtb 1079538Satgutier@umich.edu int offset = fdt_path_offset((void*)fdt_buf_w_space, full_path_node_name); 1089538Satgutier@umich.edu if (offset < 0) { 1099538Satgutier@umich.edu // try adding the node by walking dtb tree to proper insertion point 1109538Satgutier@umich.edu offset = fdt_path_offset((void*)fdt_buf_w_space, root_path); 1119538Satgutier@umich.edu offset = fdt_add_subnode((void*)fdt_buf_w_space, offset, node_name); 11211189Sandreas.hansson@arm.com // if we successfully add the subnode, get the offset 11311189Sandreas.hansson@arm.com if (offset >= 0) 11411189Sandreas.hansson@arm.com offset = fdt_path_offset((void*)fdt_buf_w_space, full_path_node_name); 11511189Sandreas.hansson@arm.com 1169538Satgutier@umich.edu if (offset < 0) { 1179538Satgutier@umich.edu warn("Error finding or adding \"chosen\" subnode to flattened " 1189538Satgutier@umich.edu "device tree, errno: %d\n", offset); 1199538Satgutier@umich.edu delete [] fdt_buf_w_space; 1209538Satgutier@umich.edu return false; 1219538Satgutier@umich.edu } 1229538Satgutier@umich.edu } 1239538Satgutier@umich.edu 1249538Satgutier@umich.edu // Set the bootargs property in the /chosen node 1259538Satgutier@umich.edu ret = fdt_setprop((void*)fdt_buf_w_space, offset, property_name, 1269538Satgutier@umich.edu (const void*)_args, len+1); 1279538Satgutier@umich.edu if (ret < 0) { 1289538Satgutier@umich.edu warn("Error setting \"bootargs\" property to flattened device tree, " 1299538Satgutier@umich.edu "errno: %d\n", ret); 1309538Satgutier@umich.edu delete [] fdt_buf_w_space; 1319538Satgutier@umich.edu return false; 1329538Satgutier@umich.edu } 1339538Satgutier@umich.edu 1349538Satgutier@umich.edu // Repack the dtb for kernel use 1359538Satgutier@umich.edu ret = fdt_pack((void*)fdt_buf_w_space); 1369538Satgutier@umich.edu if (ret < 0) { 1379538Satgutier@umich.edu warn("Error re-packing flattened device tree structure, " 1389538Satgutier@umich.edu "errno: %d\n", ret); 1399538Satgutier@umich.edu delete [] fdt_buf_w_space; 1409538Satgutier@umich.edu return false; 1419538Satgutier@umich.edu } 1429538Satgutier@umich.edu 1439538Satgutier@umich.edu text.size = newLen; 1449538Satgutier@umich.edu text.fileImage = fdt_buf_w_space; 1459538Satgutier@umich.edu 1469538Satgutier@umich.edu // clean up old buffer and set to new fdt blob 1479538Satgutier@umich.edu munmap(fileData, this->len); 1489538Satgutier@umich.edu fileData = fdt_buf_w_space; 1499538Satgutier@umich.edu fileDataMmapped = false; 1509538Satgutier@umich.edu this->len = newLen; 1519538Satgutier@umich.edu 1529538Satgutier@umich.edu return true; 1539538Satgutier@umich.edu} 1549538Satgutier@umich.edu 15510508SAli.Saidi@ARM.comAddr 15610508SAli.Saidi@ARM.comDtbObject::findReleaseAddr() 15710508SAli.Saidi@ARM.com{ 15810508SAli.Saidi@ARM.com void *fd = (void*)fileData; 15910508SAli.Saidi@ARM.com 16010508SAli.Saidi@ARM.com int offset = fdt_path_offset(fd, "/cpus/cpu@0"); 16110508SAli.Saidi@ARM.com int len; 16210508SAli.Saidi@ARM.com 16310508SAli.Saidi@ARM.com const void* temp = fdt_getprop(fd, offset, "cpu-release-addr", &len); 16410508SAli.Saidi@ARM.com Addr rel_addr = 0; 16510508SAli.Saidi@ARM.com 16610508SAli.Saidi@ARM.com if (len > 3) 16710508SAli.Saidi@ARM.com rel_addr = betoh(*static_cast<const uint32_t*>(temp)); 16810508SAli.Saidi@ARM.com if (len == 8) 16910508SAli.Saidi@ARM.com rel_addr = (rel_addr << 32) | betoh(*(static_cast<const uint32_t*>(temp)+1)); 17010508SAli.Saidi@ARM.com 17110508SAli.Saidi@ARM.com return rel_addr; 17210508SAli.Saidi@ARM.com} 17310508SAli.Saidi@ARM.com 17411392Sbrandon.potter@amd.combool 17511392Sbrandon.potter@amd.comDtbObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, 17611392Sbrandon.potter@amd.com Addr addr_mask) 17711392Sbrandon.potter@amd.com{ 17811392Sbrandon.potter@amd.com return false; 17911392Sbrandon.potter@amd.com} 18010508SAli.Saidi@ARM.com 1819538Satgutier@umich.edubool 18211392Sbrandon.potter@amd.comDtbObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, 18311392Sbrandon.potter@amd.com Addr addr_mask) 1849538Satgutier@umich.edu{ 1859538Satgutier@umich.edu // nothing to do here 1869538Satgutier@umich.edu return false; 1879538Satgutier@umich.edu} 1889538Satgutier@umich.edu 1899538Satgutier@umich.edubool 19011392Sbrandon.potter@amd.comDtbObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, 19111392Sbrandon.potter@amd.com Addr addr_mask) 1929538Satgutier@umich.edu{ 1939538Satgutier@umich.edu // nothing to do here 1949538Satgutier@umich.edu return false; 1959538Satgutier@umich.edu} 196