2 * Copyright (c) 2013 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Anthony Gutierrez
31 #include "base/loader/dtb_object.hh"
38 #include "sim/byteswap.hh"
43 DtbObject::tryFile(const std::string
&fname
, size_t len
, uint8_t *data
)
45 // Check if this is a FDT file by looking for magic number
46 if (fdt_magic((void*)data
) == FDT_MAGIC
) {
47 return new DtbObject(fname
, len
, data
,
48 ObjectFile::UnknownArch
, ObjectFile::UnknownOpSys
);
54 DtbObject::DtbObject(const std::string
&_filename
, size_t _len
, uint8_t *_data
,
55 Arch _arch
, OpSys _opSys
)
56 : ObjectFile(_filename
, _len
, _data
, _arch
, _opSys
)
60 text
.fileImage
= fileData
;
64 data
.fileImage
= NULL
;
70 fileDataMmapped
= true;
73 DtbObject::~DtbObject()
75 // Make sure to clean up memory properly depending
76 // on how buffer was allocated.
77 if (fileData
&& !fileDataMmapped
) {
80 } else if (fileData
) {
81 munmap(fileData
, len
);
87 DtbObject::addBootCmdLine(const char* _args
, size_t len
)
89 const char* root_path
= "/";
90 const char* node_name
= "chosen";
91 const char* full_path_node_name
= "/chosen";
92 const char* property_name
= "bootargs";
94 // Make a new buffer that has extra space to add nodes/properties
95 int newLen
= 2*this->len
;
96 uint8_t* fdt_buf_w_space
= new uint8_t[newLen
];
97 // Copy and unpack flattened device tree into new buffer
98 int ret
= fdt_open_into((void*)fileData
, (void*)fdt_buf_w_space
, (newLen
));
100 warn("Error resizing buffer of flattened device tree, "
102 delete [] fdt_buf_w_space
;
106 // First try finding the /chosen node in the dtb
107 int offset
= fdt_path_offset((void*)fdt_buf_w_space
, full_path_node_name
);
109 // try adding the node by walking dtb tree to proper insertion point
110 offset
= fdt_path_offset((void*)fdt_buf_w_space
, root_path
);
111 offset
= fdt_add_subnode((void*)fdt_buf_w_space
, offset
, node_name
);
112 // if we successfully add the subnode, get the offset
114 offset
= fdt_path_offset((void*)fdt_buf_w_space
, full_path_node_name
);
117 warn("Error finding or adding \"chosen\" subnode to flattened "
118 "device tree, errno: %d\n", offset
);
119 delete [] fdt_buf_w_space
;
124 // Set the bootargs property in the /chosen node
125 ret
= fdt_setprop((void*)fdt_buf_w_space
, offset
, property_name
,
126 (const void*)_args
, len
+1);
128 warn("Error setting \"bootargs\" property to flattened device tree, "
130 delete [] fdt_buf_w_space
;
134 // Repack the dtb for kernel use
135 ret
= fdt_pack((void*)fdt_buf_w_space
);
137 warn("Error re-packing flattened device tree structure, "
139 delete [] fdt_buf_w_space
;
144 text
.fileImage
= fdt_buf_w_space
;
146 // clean up old buffer and set to new fdt blob
147 munmap(fileData
, this->len
);
148 fileData
= fdt_buf_w_space
;
149 fileDataMmapped
= false;
156 DtbObject::findReleaseAddr()
158 void *fd
= (void*)fileData
;
160 int offset
= fdt_path_offset(fd
, "/cpus/cpu@0");
163 const void* temp
= fdt_getprop(fd
, offset
, "cpu-release-addr", &len
);
167 rel_addr
= betoh(*static_cast<const uint32_t*>(temp
));
169 rel_addr
= (rel_addr
<< 32) | betoh(*(static_cast<const uint32_t*>(temp
)+1));
175 DtbObject::loadAllSymbols(SymbolTable
*symtab
, Addr base
, Addr offset
,
182 DtbObject::loadGlobalSymbols(SymbolTable
*symtab
, Addr base
, Addr offset
,
185 // nothing to do here
190 DtbObject::loadLocalSymbols(SymbolTable
*symtab
, Addr base
, Addr offset
,
193 // nothing to do here