system.cc revision 5222
1/* 2 * Copyright N) 2007 MIPS Technologies, Inc. All Rights Reserved 3 * 4 * This software is part of the M5 simulator. 5 * 6 * THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 7 * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 8 * TO THESE TERMS AND CONDITIONS. 9 * 10 * Permission is granted to use, copy, create derivative works and 11 * distribute this software and such derivative works for any purpose, 12 * so long as (1) the copyright notice above, this grant of permission, 13 * and the disclaimer below appear in all copies and derivative works 14 * made, (2) the copyright notice above is augmented as appropriate to 15 * reflect the addition of any new copyrightable work in a derivative 16 * work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3) 17 * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any 18 * advertising or publicity pertaining to the use or distribution of 19 * this software without specific, written prior authorization. 20 * 21 * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B MIPS MAKES NO WARRANTIES AND 22 * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 23 * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 25 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 26 * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 27 * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 28 * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 29 * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 30 * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 31 * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 32 * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 33 * 34 * 35 * Authors: Ali G. Saidi 36 * Nathan L. Binkert 37 * Jaidev Patwardhan 38 */ 39 40#include "arch/mips/system.hh" 41#include "arch/vtophys.hh" 42#include "base/remote_gdb.hh" 43#include "base/loader/object_file.hh" 44#include "base/loader/hex_file.hh" 45#include "base/loader/symtab.hh" 46#include "base/trace.hh" 47#include "mem/physical.hh" 48#include "params/MipsSystem.hh" 49#include "sim/byteswap.hh" 50 51 52using namespace LittleEndianGuest; 53 54MipsSystem::MipsSystem(Params *p) 55 : System(p) 56{ 57 58#if FULL_SYSTEM 59 if (p->bare_iron == true) { 60 hexFile = new HexFile(params()->hex_file_name); 61 if(!hexFile->loadSections(&functionalPort,MipsISA::LoadAddrMask)) 62 panic("Could not load hex file\n"); 63 } 64 65 Addr addr = 0; 66 /* Comment out old Alpha Based Code 67 68 Don't need the console before we start looking at booting linux */ 69 70 71 consoleSymtab = new SymbolTable; 72 73 74 /** 75 * Load the console code into memory 76 */ 77 // Load Console Code 78 console = createObjectFile(params()->console); 79 80 warn("console code is located at: %s\n", params()->console); 81 82 if (console == NULL) 83 fatal("Could not load console file %s", params()->console); 84 //Load program sections into memory 85 console->loadSections(&functionalPort, MipsISA::LoadAddrMask); 86 87 //load symbols 88 if (!console->loadGlobalSymbols(consoleSymtab)) 89 panic("could not load console symbols\n"); 90 91 if (!console->loadGlobalSymbols(debugSymbolTable)) 92 panic("could not load console symbols\n"); 93 94 95#ifndef NDEBUG 96 consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); 97#endif 98 99 /** 100 * Copy the osflags (kernel arguments) into the consoles 101 * memory. (Presently Linux does not use the console service 102 * routine to get these command line arguments, but Tru64 and 103 * others do.) 104 */ 105 if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 106 warn("writing addr starting from %#x", addr); 107 cout << "-" << endl; 108 virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), 109 strlen(params()->boot_osflags.c_str())); 110 } 111 112 /** 113 * Set the hardware reset parameter block system type and revision 114 * information to Tsunami. 115 */ 116 if (consoleSymtab->findAddress("m5_rpb", addr)) { 117 uint64_t data; 118 data = htog(params()->system_type); 119 virtPort.write(addr+0x50, data); 120 data = htog(params()->system_rev); 121 virtPort.write(addr+0x58, data); 122 } else 123 panic("could not find hwrpb\n"); 124#endif 125} 126 127MipsSystem::~MipsSystem() 128{ 129} 130#if FULL_SYSTEM 131/** 132 * This function fixes up addresses that are used to match PCs for 133 * hooking simulator events on to target function executions. 134 * 135 * Mips binaries may have multiple global offset table (GOT) 136 * sections. A function that uses the GOT starts with a 137 * two-instruction prolog which sets the global pointer (gp == r29) to 138 * the appropriate GOT section. The proper gp value is calculated 139 * based on the function address, which must be passed by the caller 140 * in the procedure value register (pv aka t12 == r27). This sequence 141 * looks like the following: 142 * 143 * opcode Ra Rb offset 144 * ldah gp,X(pv) 09 29 27 X 145 * lda gp,Y(gp) 08 29 29 Y 146 * 147 * for some constant offsets X and Y. The catch is that the linker 148 * (or maybe even the compiler, I'm not sure) may recognize that the 149 * caller and callee are using the same GOT section, making this 150 * prolog redundant, and modify the call target to skip these 151 * instructions. If we check for execution of the first instruction 152 * of a function (the one the symbol points to) to detect when to skip 153 * it, we'll miss all these modified calls. It might work to 154 * unconditionally check for the third instruction, but not all 155 * functions have this prolog, and there's some chance that those 156 * first two instructions could have undesired consequences. So we do 157 * the Right Thing and pattern-match the first two instructions of the 158 * function to decide where to patch. 159 * 160 * Eventually this code should be moved into an ISA-specific file. 161 */ 162 163Addr 164MipsSystem::fixFuncEventAddr(Addr addr) 165{ 166 /* 167 // mask for just the opcode, Ra, and Rb fields (not the offset) 168 const uint32_t inst_mask = 0xffff0000; 169 // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 170 const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); 171 // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 172 const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); 173 174 uint32_t i1 = virtPort.read<uint32_t>(addr); 175 uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(MipsISA::MachInst)); 176 177 if ((i1 & inst_mask) == gp_ldah_pattern && 178 (i2 & inst_mask) == gp_lda_pattern) { 179 Addr new_addr = addr + 2* sizeof(MipsISA::MachInst); 180 DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); 181 return new_addr; 182 } else { 183 return addr; 184 }*/ 185 return addr; 186} 187 188 189void 190MipsSystem::setMipsAccess(Addr access) 191{ 192 Addr addr = 0; 193 if (consoleSymtab->findAddress("m5MipsAccess", addr)) { 194 // virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); 195 } else 196 panic("could not find m5MipsAccess\n"); 197 } 198 199#endif 200 201bool 202MipsSystem::breakpoint() 203{ 204 return 0; 205 // return remoteGDB[0]->trap(MIPS_KENTRY_INT); 206} 207 208void 209MipsSystem::serialize(std::ostream &os) 210{ 211 System::serialize(os); 212 // consoleSymtab->serialize("console_symtab", os); 213} 214 215 216void 217MipsSystem::unserialize(Checkpoint *cp, const std::string §ion) 218{ 219 System::unserialize(cp,section); 220 // consoleSymtab->unserialize("console_symtab", cp, section); 221} 222 223MipsSystem * 224MipsSystemParams::create() 225{ 226 return new MipsSystem(this); 227} 228 229