diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index ce84f4b51..cb0f4ac9c 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -187,6 +187,12 @@ output decoder {{ else ccprintf(ss, "0x%x", target); + string inst_name = mnemonic; + + if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){ + ccprintf(ss, " (r31=0x%x)",pc+8); + } + return ss.str(); } diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 58d974448..849d3311d 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -34,6 +34,20 @@ using namespace MipsISA; + +void +MipsISA::copyRegs(ExecContext *src, ExecContext *dest) +{ + /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag); + uniq = xc->readMiscReg(MipsISA::Uniq_DepTag); + lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag); + lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag); + +#if FULL_SYSTEM + copyIprs(xc); + #endif*/ +} + void MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc) { @@ -264,7 +278,7 @@ void RegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(intRegFile, NumIntRegs); - SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); //SERIALIZE_SCALAR(miscRegs.fpcr); //SERIALIZE_SCALAR(miscRegs.uniq); //SERIALIZE_SCALAR(miscRegs.lock_flag); @@ -285,7 +299,7 @@ void RegFile::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(intRegFile, NumIntRegs); - UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); //UNSERIALIZE_SCALAR(miscRegs.fpcr); //UNSERIALIZE_SCALAR(miscRegs.uniq); //UNSERIALIZE_SCALAR(miscRegs.lock_flag); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index bd56ce2cc..b4c7748ba 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -40,6 +40,7 @@ class FastCPU; class FullCPU; class Checkpoint; +class ExecContext; namespace LittleEndianGuest {}; using namespace LittleEndianGuest; @@ -119,22 +120,23 @@ namespace MipsISA const int MaxInstDestRegs = 2; // semantically meaningful register indices - const int ZeroReg = 31; // architecturally meaningful - // the rest of these depend on the ABI - const int StackPointerReg = 30; - const int GlobalPointerReg = 29; - const int ProcedureValueReg = 27; - const int ReturnAddressReg = 26; - const int ReturnValueReg = 0; - const int FramePointerReg = 15; - const int ArgumentReg0 = 16; - const int ArgumentReg1 = 17; - const int ArgumentReg2 = 18; - const int ArgumentReg3 = 19; - const int ArgumentReg4 = 20; - const int ArgumentReg5 = 21; - const int SyscallNumReg = ReturnValueReg; - const int SyscallPseudoReturnReg = ArgumentReg4; + const int ZeroReg = 0; + const int AssemblerReg = 1; + const int ReturnValueReg1 = 2; + const int ReturnValueReg2 = 3; + const int ArgumentReg0 = 4; + const int ArgumentReg1 = 5; + const int ArgumentReg2 = 6; + const int ArgumentReg3 = 7; + const int KernelReg0 = 26; + const int KernelReg1 = 27; + const int GlobalPointerReg = 28; + const int StackPointerReg = 29; + const int FramePointerReg = 30; + const int ReturnAddressReg = 31; + + const int SyscallNumReg = ReturnValueReg1; + const int SyscallPseudoReturnReg = ArgumentReg3; const int SyscallSuccessReg = 19; const int LogVMPageSize = 13; // 8K bytes @@ -162,16 +164,78 @@ namespace MipsISA typedef uint64_t IntReg; typedef IntReg IntRegFile[NumIntRegs]; - // floating point register file entry type +/* floating point register file entry type typedef union { uint64_t q; double d; - } FloatReg; + } FloatReg;*/ - typedef union { + typedef double FloatReg; + typedef uint64_t FloatRegBits; + +/*typedef union { uint64_t q[NumFloatRegs]; // integer qword view double d[NumFloatRegs]; // double-precision floating point view - } FloatRegFile; + } FloatRegFile;*/ + + class FloatRegFile + { + protected: + + FloatRegBits q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view + + public: + + FloatReg readReg(int floatReg) + { + return d[floatReg]; + } + + FloatReg readReg(int floatReg, int width) + { + return readReg(floatReg); + } + + FloatRegBits readRegBits(int floatReg) + { + return q[floatReg]; + } + + FloatRegBits readRegBits(int floatReg, int width) + { + return readRegBits(floatReg); + } + + Fault setReg(int floatReg, const FloatReg &val) + { + d[floatReg] = val; + return NoFault; + } + + Fault setReg(int floatReg, const FloatReg &val, int width) + { + return setReg(floatReg, val); + } + + Fault setRegBits(int floatReg, const FloatRegBits &val) + { + q[floatReg] = val; + return NoFault; + } + + Fault setRegBits(int floatReg, const FloatRegBits &val, int width) + { + return setRegBits(floatReg, val); + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + }; + + void copyRegs(ExecContext *src, ExecContext *dest); // cop-0/cop-1 system control register file typedef uint64_t MiscReg; @@ -524,18 +588,7 @@ extern const Addr PageOffset; static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) { - // check for error condition. SPARC syscall convention is to - // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg (). - if (return_value.successful()) { - // no error - //regs->miscRegFile.ccrFields.iccFields.c = 0; - regs->intRegFile[ReturnValueReg] = return_value.value(); - } else { - // got an error, return details - //regs->miscRegFile.ccrFields.iccFields.c = 1; - regs->intRegFile[ReturnValueReg] = -return_value.value(); - } + panic("Returning from syscall\n"); } // Machine operations diff --git a/arch/mips/process.cc b/arch/mips/process.cc index 8f8a34934..37627ac31 100644 --- a/arch/mips/process.cc +++ b/arch/mips/process.cc @@ -42,7 +42,7 @@ createProcess(const string &nm, ObjectFile * objFile, System * system, vector &argv, vector &envp) { LiveProcess * process = NULL; - if (objFile->getArch() != ObjectFile::MIPS) + if (objFile->getArch() != ObjectFile::Mips) fatal("Object file does not match architecture."); switch (objFile->getOpSys()) { case ObjectFile::Linux: diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 2925817cd..b9636b454 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -92,7 +92,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) arch = ObjectFile::SPARC; } else if (ehdr.e_machine == EM_MIPS && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { - arch = ObjectFile::MIPS; + arch = ObjectFile::Mips; } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { arch = ObjectFile::Alpha; } else { @@ -156,14 +156,49 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) section = elf_getscn(elf, ++secIdx); } // while sections } + + int32_t global_ptr; + if (arch == ObjectFile::Mips) { + Elf_Scn *section; + GElf_Shdr shdr; + Elf_Data *rdata; + int secIdx = 1; + + // Get the first section + section = elf_getscn(elf, secIdx); + + // While there are no more sections + while (section != NULL) { + gelf_getshdr(section, &shdr); + /*shdr.sh_type == SHT_MIPS_REGINFO && */ + if (!strcmp(".reginfo",elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) { + // We have found MIPS reginfo section: + // ------------------------------- + // Check the 6th 32bit word for the initialized global pointer value + // ------------------------------- + rdata = elf_rawdata(section, NULL); + assert(rdata->d_buf); + + if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB) + global_ptr = htole(((int32_t*)rdata->d_buf)[5]); + else + global_ptr = htobe(((int32_t*)rdata->d_buf)[5]); + break; + } + + section = elf_getscn(elf, ++secIdx); + } // if section found + + } + elf_end(elf); - return new ElfObject(fname, fd, len, data, arch, opSys); + return new ElfObject(fname, fd, len, data, global_ptr,arch, opSys); } } ElfObject::ElfObject(const string &_filename, int _fd, - size_t _len, uint8_t *_data, + size_t _len, uint8_t *_data,Addr global_ptr, Arch _arch, OpSys _opSys) : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys) @@ -187,6 +222,8 @@ ElfObject::ElfObject(const string &_filename, int _fd, entry = ehdr.e_entry; + globalPtr = global_ptr; + // initialize segment sizes to 0 in case they're not present text.size = data.size = bss.size = 0; diff --git a/base/loader/elf_object.hh b/base/loader/elf_object.hh index 72c265edd..d1fd32fd0 100644 --- a/base/loader/elf_object.hh +++ b/base/loader/elf_object.hh @@ -39,7 +39,7 @@ class ElfObject : public ObjectFile bool loadSomeSymbols(SymbolTable *symtab, int binding); ElfObject(const std::string &_filename, int _fd, - size_t _len, uint8_t *_data, + size_t _len, uint8_t *_data,Addr global_ptr, Arch _arch, OpSys _opSys); public: diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index 08a51863e..309089728 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -44,7 +44,7 @@ class ObjectFile UnknownArch, Alpha, SPARC, - MIPS + Mips }; enum OpSys { @@ -95,9 +95,11 @@ class ObjectFile Section bss; bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys); + void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; } public: Addr entryPoint() const { return entry; } + Addr globalPointer() const { return globalPtr; } Addr textBase() const { return text.baseAddr; } diff --git a/base/traceflags.py b/base/traceflags.py index e814a00fb..c3b878027 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -142,6 +142,7 @@ baseFlags = [ 'OoOCPU', 'HWPrefetch', 'Stack', + 'SimpleCPU', ] # diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index a135f45d6..d188074d4 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -889,6 +889,8 @@ SimpleCPU::post_interrupt(int int_num, int index) void SimpleCPU::tick() { + DPRINTF(SimpleCPU,"\n\n"); + numCycles++; traceData = NULL; @@ -961,7 +963,7 @@ SimpleCPU::tick() #define IFETCH_FLAGS(pc) 0 #endif - DPRINTF(Fetch,"Fetching PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), + DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), cpuXC->readNextPC(),cpuXC->readNextNPC()); #if SIMPLE_CPU_MEM_TIMING @@ -1033,6 +1035,9 @@ SimpleCPU::tick() traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, cpuXC->readPC()); + DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", + curStaticInst->getName(),curStaticInst->getOpcode(), curStaticInst->machInst); + #if FULL_SYSTEM cpuXC->setInst(inst); #endif // FULL_SYSTEM diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 764020577..a200e2849 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -391,6 +391,17 @@ class StaticInst : public StaticInstBase /// @retval A pointer to the corresponding StaticInst object. //This is defined as inline below. static StaticInstPtr decode(ExtMachInst mach_inst); + + //MIPS Decoder Debug Functions + int getOpcode() { return (machInst & 0xFC000000) >> 26 ; }//31..26 + int getRs() { return (machInst & 0x03E00000) >> 21; } //25...21 + int getRt() { return (machInst & 0x001F0000) >> 16; } //20...16 + int getRd() { return (machInst & 0x0000F800) >> 11; } //15...11 + int getOpname(){ return (machInst & 0x0000003F); }//5...0 + int getBranch(){ return (machInst & 0x0000FFFF); }//5...0 + int getJump(){ return (machInst & 0x03FFFFFF); }//5...0 + int getHint(){ return (machInst & 0x000007C0) >> 6; } //10...6 + std::string getName() { return mnemonic; } }; typedef RefCountingPtr StaticInstBasePtr;