diff options
Diffstat (limited to 'src/arch/sparc')
-rw-r--r-- | src/arch/sparc/intregfile.cc | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 2 | ||||
-rw-r--r-- | src/arch/sparc/process.cc | 66 |
4 files changed, 57 insertions, 27 deletions
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 0cc0a886a..bef62f6ae 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -60,9 +60,9 @@ void IntRegFile::clear() { int x; for (x = 0; x < MaxGL; x++) - memset(regGlobals[x], 0, sizeof(regGlobals[x])); + memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); for(int x = 0; x < 2 * NWindows; x++) - bzero(regSegments[x], sizeof(regSegments[x])); + bzero(regSegments[x], sizeof(IntReg) * RegsPerFrame); } IntRegFile::IntRegFile() @@ -84,8 +84,10 @@ IntReg IntRegFile::readReg(int intReg) Fault IntRegFile::setReg(int intReg, const IntReg &val) { if(intReg) + { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + } return NoFault; } diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 304c97f2f..3c5236661 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -106,7 +106,7 @@ decode OP default Unknown::unknown() } } //SETHI (or NOP if rd == 0 and imm == 0) - 0x4: SetHi::sethi({{Rd = imm;}}); + 0x4: SetHi::sethi({{Rd.udw = imm;}}); 0x5: Trap::fbpfcc({{fault = new FpDisabled;}}); 0x6: Trap::fbfcc({{fault = new FpDisabled;}}); } @@ -535,15 +535,15 @@ decode OP default Unknown::unknown() 0x10: Trap::array8({{fault = new IllegalInstruction;}}); 0x12: Trap::array16({{fault = new IllegalInstruction;}}); 0x14: Trap::array32({{fault = new IllegalInstruction;}}); - 0x18: BasicOperate::alignaddress({{ + 0x18: BasicOperate::alignaddr({{ uint64_t sum = Rs1 + Rs2; - Frd = sum & ~7; + Rd = sum & ~7; Gsr = (Gsr & ~7) | (sum & 7); }}); 0x19: Trap::bmask({{fault = new IllegalInstruction;}}); 0x1A: BasicOperate::alignaddresslittle({{ uint64_t sum = Rs1 + Rs2; - Frd = sum & ~7; + Rd = sum & ~7; Gsr = (Gsr & ~7) | ((~sum + 1) & 7); }}); 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}}); diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index 27616216e..83c7e6958 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -67,7 +67,7 @@ output header {{ { } - int32_t imm; + int64_t imm; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 150664148..31989cfe2 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -56,11 +56,11 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile, // Set up stack. On SPARC Linux, stack goes from the top of memory // downward, less the hole for the kernel address space. - stack_base = ((Addr)0x80000000000ULL); + stack_base = (Addr)0x80000000000ULL; // Set up region for mmaps. Tru64 seems to start just above 0 and // grow up from there. - mmap_start = mmap_end = 0x800000; + mmap_start = mmap_end = 0xfffff80000000000ULL; // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); @@ -110,6 +110,12 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) { Process::startup(); + string filename; + if(argv.size() < 1) + filename = ""; + else + filename = argv[0]; + Addr alignmentMask = ~(intSize - 1); // load object file into target memory @@ -194,8 +200,13 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) //Figure out how big the initial stack needs to be - //Each auxilliary vector is two 8 byte words - int aux_data_size = 2 * intSize * auxv.size(); + // The unaccounted for 0 at the top of the stack + int mysterious_size = intSize; + + //This is the name of the file which is present on the initial stack + //It's purpose is to let the user space linker examine the original file. + int file_name_size = filename.size() + 1; + int env_data_size = 0; for (int i = 0; i < envp.size(); ++i) { env_data_size += envp[i].size() + 1; @@ -205,27 +216,33 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) arg_data_size += argv[i].size() + 1; } - int aux_array_size = intSize * 2 * (auxv.size() + 1); - - int argv_array_size = intSize * (argv.size() + 1); - int envp_array_size = intSize * (envp.size() + 1); - - int argc_size = intSize; - int window_save_size = intSize * 16; - + //The info_block needs to be padded so it's size is a multiple of the + //alignment mask. Also, it appears that there needs to be at least some + //padding, so if the size is already a multiple, we need to increase it + //anyway. int info_block_size = - (aux_data_size + + (file_name_size + env_data_size + arg_data_size + - ~alignmentMask) & alignmentMask; + intSize) & alignmentMask; int info_block_padding = info_block_size - - aux_data_size - + file_name_size - env_data_size - arg_data_size; + //Each auxilliary vector is two 8 byte words + int aux_array_size = intSize * 2 * (auxv.size() + 1); + + int envp_array_size = intSize * (envp.size() + 1); + int argv_array_size = intSize * (argv.size() + 1); + + int argc_size = intSize; + int window_save_size = intSize * 16; + int space_needed = + mysterious_size + info_block_size + aux_array_size + envp_array_size + @@ -242,10 +259,11 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) roundUp(stack_size, pageSize)); // map out initial stack contents - Addr aux_data_base = stack_base - aux_data_size - info_block_padding; - Addr env_data_base = aux_data_base - env_data_size; + Addr mysterious_base = stack_base - mysterious_size; + Addr file_name_base = mysterious_base - file_name_size; + Addr env_data_base = file_name_base - env_data_size; Addr arg_data_base = env_data_base - arg_data_size; - Addr auxv_array_base = arg_data_base - aux_array_size; + Addr auxv_array_base = arg_data_base - aux_array_size - info_block_padding; Addr envp_array_base = auxv_array_base - envp_array_size; Addr argv_array_base = envp_array_base - argv_array_size; Addr argc_base = argv_array_base - argc_size; @@ -255,7 +273,7 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) #endif DPRINTF(Sparc, "The addresses of items on the initial stack:\n"); - DPRINTF(Sparc, "0x%x - aux data\n", aux_data_base); + DPRINTF(Sparc, "0x%x - file name\n", file_name_base); DPRINTF(Sparc, "0x%x - env data\n", env_data_base); DPRINTF(Sparc, "0x%x - arg data\n", arg_data_base); DPRINTF(Sparc, "0x%x - auxv array\n", auxv_array_base); @@ -266,9 +284,19 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) DPRINTF(Sparc, "0x%x - stack min\n", stack_min); // write contents to stack + + // figure out argc uint64_t argc = argv.size(); uint64_t guestArgc = TheISA::htog(argc); + //Write out the mysterious 0 + uint64_t mysterious_zero = 0; + initVirtMem->writeBlob(mysterious_base, + (uint8_t*)&mysterious_zero, mysterious_size); + + //Write the file name + initVirtMem->writeString(file_name_base, filename.c_str()); + //Copy the aux stuff for(int x = 0; x < auxv.size(); x++) { |