diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh new file mode 100644 index 000000000..482e077e0 --- /dev/null +++ b/src/arch/sparc/asi.hh @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_SPARC_ASI_HH__ +#define __ARCH_SPARC_ASI_HH__ + +namespace SparcISA +{ + enum ASI { + /* Priveleged ASIs */ + //0x00-0x03 implementation dependent + ASI_NUCLEUS = 0x4, + ASI_N = 0x4, + //0x05-0x0B implementation dependent + ASI_NL = 0xC, + ASI_NUCLEUS_LITTLE = ASI_NL, + //0x0D-0x0F implementation dependent + ASI_AIUP = 0x10, + ASI_AS_IF_USER_PRIMARY = ASI_AIUP, + ASI_AIUS = 0x11, + ASI_AS_IF_USER_SECONDARY = ASI_AIUS, + //0x12-0x13 implementation dependent + ASI_REAL = 0x14, + ASI_REAL_IO = 0x15, + ASI_BLK_AIUP = 0x16, + ASI_BLOCK_AS_IF_USER_PRIMARY = ASI_BLK_AIUP, + ASI_BLK_AIUS = 0x17, + ASI_BLOCK_AS_IF_USER_SECONDARY = ASI_BLK_AIUS, + ASI_AIUPL = 0x18, + ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUPL, + ASI_AIUSL = 0x19, + ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUSL, + //0x1A-0x1B implementation dependent + ASI_REAL_L = 0x1C, + ASI_REAL_LITTLE = ASI_REAL_L, + ASI_REAL_IO_L = 0x1D, + ASI_REAL_IO_LITTLE = ASI_REAL_IO_L, + ASI_BLK_AIUPL = 0x1E, + ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUPL, + ASI_BLK_AIUSL = 0x1F, + ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUSL, + ASI_SCRATCHPAD = 0x20, + ASI_MMU_CONTEXTID = 0x21, + ASI_LDTX_AIUP = 0x22, + ASI_LD_TWINX_AS_IF_USER_PRIMARY = ASI_LDTX_AIUP, + ASI_LDTX_AIUS = 0x23, + ASI_LD_TWINX_AS_IF_USER_SECONDARY = ASI_LDTX_AIUS, + //0x24 implementation dependent + ASI_QUEUE = 0x25, + ASI_LDTX_REAL = 0x26, + ASI_LD_TWINX_REAL = ASI_LDTX_REAL, + ASI_LDTX_N = 0x27, + ASI_LD_TWINX_NUCLEUS = ASI_LDTX_N, + //0x28-0x29 implementation dependent + ASI_LDTX_AIUPL = 0x2A, + ASI_LD_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUPL, + ASI_LDTX_AIUSL = 0x2B, + ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUSL, + //0x2C-0x2D implementation dependent + ASI_LDTX_REAL_L = 0x2E, + ASI_LD_TWINX_REAL_LITTLE = ASI_LDTX_REAL_L, + ASI_LDTX_NL = 0x2F, + ASI_LD_TWINX_NUCLEUS_LITTLE = ASI_LDTX_NL, + //0x30-0x40 implementation dependent + ASI_CMT_SHARED = 0x41, + //0x42-0x4F implementation dependent + ASI_HYP_SCRATCHPAD = 0x4F, + ASI_IMMU = 0x50, + ASI_MMU_REAL = 0x52, + //0x53 implementation dependent + ASI_MMU = 0x54, + ASI_ITLB_DATA_ACCESS_REG = 0x55, + ASI_ITLB_TAG_READ_REG = 0x56, + ASI_IMMU_DEMAP = 0x57, + ASI_DMMU = 0x58, + ASI_UMMU = 0x58, + //0x59-0x5B reserved + ASI_DTLB_DATA_IN_REG = 0x5C, + ASI_DTLB_DATA_ACCESS_REG = 0x5D, + ASI_DTLB_TAG_READ_REG = 0x5E, + ASI_DMMU_DEMAP = 0x5F, + //0x60-62 implementation dependent + ASI_CMT_PER_STRAND = 0x63, + //0x64-0x67 implementation dependent + //0x68-0x7F reserved + + /* Unpriveleged ASIs */ + ASI_P = 0x80, + ASI_PRIMARY = ASI_P, + ASI_S = 0x81, + ASI_SECONDARY = ASI_S, + ASI_PNF = 0x82, + ASI_PRIMARY_NO_FAULT = ASI_PNF, + ASI_SNF = 0x83, + ASI_SECONDARY_NO_FAULT = ASI_SNF, + //0x84-0x87 reserved + ASI_PL = 0x88, + ASI_PRIMARY_LITTLE = ASI_PL, + ASI_SL = 0x89, + ASI_SECONDARY_LITTLE = ASI_SL, + ASI_PNFL = 0x8A, + ASI_PRIMARY_NO_FAULT_LITTLE = ASI_PNFL, + ASI_SNFL = 0x8B, + ASI_SECONDARY_NO_FAULT_LITTLE = ASI_SNFL, + //0x8C-0xBF reserved + ASI_PST8_P = 0xC0, + ASI_PST8_PRIMARY = ASI_PST8_P, + ASI_PST8_S = 0xC1, + ASI_PST8_SECONDARY = ASI_PST8_S, + ASI_PST16_P = 0xC2, + ASI_PST16_PRIMARY = ASI_PST16_P, + ASI_PST16_S = 0xC3, + ASI_PST16_SECONDARY = ASI_PST16_S, + ASI_PST32_P = 0xC4, + ASI_PST32_PRIMARY = ASI_PST32_P, + ASI_PST32_S = 0xC5, + ASI_PST32_SECONDARY = ASI_PST32_S, + //0xC6-0xC7 implementation dependent + ASI_PST8_PL = 0xC8, + ASI_PST8_PRIMARY_LITTLE = ASI_PST8_PL, + ASI_PST8_SL = 0xC9, + ASI_PST8_SECONDARY_LITTLE = ASI_PST8_SL, + ASI_PST16_PL = 0xCA, + ASI_PST16_PRIMARY_LITTLE = ASI_PST16_PL, + ASI_PST16_SL = 0xCB, + ASI_PST16_SECONDARY_LITTLE = ASI_PST16_SL, + ASI_PST32_PL = 0xCC, + ASI_PST32_PRIMARY_LITTLE = ASI_PST32_PL, + ASI_PST32_SL = 0xCD, + ASI_PST32_SECONDARY_LITTLE = ASI_PST32_SL, + //0xCE-0xCF implementation dependent + ASI_PL8_P = 0xD0, + ASI_PL8_PRIMARY = ASI_PL8_P, + ASI_PL8_S = 0xD1, + ASI_PL8_SECONDARY = ASI_PL8_S, + ASI_PL16_P = 0xD2, + ASI_PL16_PRIMARY = ASI_PL16_P, + ASI_PL16_S = 0xD3, + ASI_PL16_SECONDARY = ASI_PL16_S, + //0xD4-0xD7 implementation dependent + ASI_PL8_PL = 0xD8, + ASI_PL8_PRIMARY_LITTLE = ASI_PL8_PL, + ASI_PL8_SL = 0xD9, + ASI_PL8_SECONDARY_LITTLE = ASI_PL8_SL, + ASI_PL16_PL = 0xDA, + ASI_PL16_PRIMARY_LITTLE = ASI_PL16_PL, + ASI_PL16_SL = 0xDB, + ASI_PL16_SECONDARY_LITTLE = ASI_PL16_SL, + //0xDC-0xDF implementation dependent + //0xE0-0xE1 reserved + ASI_LDTX_P = 0xE2, + ASI_LD_TWINX_PRIMARY = ASI_LDTX_P, + ASI_LDTX_S = 0xE3, + ASI_LD_TWINX_SECONDARY = ASI_LDTX_S, + //0xE4-0xE9 implementation dependent + ASI_LDTX_PL = 0xEA, + ASI_LD_TWINX_PRIMARY_LITTLE = ASI_LDTX_PL, + ASI_LDTX_SL = 0xEB, + ASI_LD_TWINX_SECONDARY_LITTLE = ASI_LDTX_SL, + //0xEC-0xEF implementation dependent + ASI_BLK_P = 0xF0, + ASI_BLOCK_PRIMARY = ASI_BLK_P, + ASI_BLK_S = 0xF1, + ASI_BLOCK_SECONDARY = ASI_BLK_S, + //0xF2-0xF7 implementation dependent + ASI_BLK_PL = 0xF8, + ASI_BLOCK_PRIMARY_LITTLE = ASI_BLK_PL, + ASI_BLK_SL = 0xF9, + ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL + //0xFA-0xFF implementation dependent + }; +}; + +#endif // __ARCH_SPARC_TLB_HH__ diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index 3cacbb278..3afe6ef54 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -63,23 +63,28 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) //In each of these cases, we have to copy the value into a temporary //variable. This is because we may otherwise try to access an //unaligned portion of memory. + FloatReg result; switch(width) { case SingleWidth: float32_t result32; memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); - return htog(result32); + result = htog(result32); + break; case DoubleWidth: float64_t result64; memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); - return htog(result64); + result = htog(result64); + break; case QuadWidth: float128_t result128; memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - return htog(result128); + result = htog(result128); + break; default: panic("Attempted to read a %d bit floating point register!", width); } + return result; } FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) @@ -87,23 +92,28 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) //In each of these cases, we have to copy the value into a temporary //variable. This is because we may otherwise try to access an //unaligned portion of memory. + FloatRegBits result; switch(width) { case SingleWidth: uint32_t result32; memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); - return htog(result32); + result = htog(result32); + break; case DoubleWidth: uint64_t result64; memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); - return htog(result64); + result = htog(result64); + break; case QuadWidth: uint64_t result128; memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - return htog(result128); + result = htog(result128); + break; default: panic("Attempted to read a %d bit floating point register!", width); } + return result; } Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) @@ -114,7 +124,6 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) uint32_t result32; uint64_t result64; - DPRINTF(Sparc, "Setting floating point register %d\n", floatReg); switch(width) { case SingleWidth: diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 0c8d77362..1384b21a0 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -441,47 +441,39 @@ decode OP default Unknown::unknown() 0x34: decode OPF{ format BasicOperate{ 0x01: fmovs({{ - Frd.sf = Frs2.sf; + Frd.uw = Frs2.uw; //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); 0x02: fmovd({{ - Frd.df = Frs2.df; + Frd.udw = Frs2.udw; //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); 0x03: Trap::fmovq({{fault = new FpDisabled;}}); 0x05: fnegs({{ - //XXX might want to explicitly flip the sign bit - //So cases with Nan and +/-0 don't do weird things - Frd.sf = -Frs2.sf; + Frd.uw = Frs2.uw ^ (1UL << 31); //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); 0x06: fnegd({{ - //XXX might want to explicitly flip the sign bit - //So cases with Nan and +/-0 don't do weird things - Frd.df = -Frs2.df; + Frd.udw = Frs2.udw ^ (1ULL << 63); //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); 0x07: Trap::fnegq({{fault = new FpDisabled;}}); 0x09: fabss({{ - //XXX this instruction should be tested individually - //Clear the sign bit - Frd.sf = (float)(~(1 << 31) & ((uint32_t)Frs2.sf)); + Frd.uw = ((1UL << 31) - 1) & Frs2.uw; //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); }}); 0x0A: fabsd({{ - //XXX this instruction should be tested individually - //Clear the sign bit - Frd.df = (float)(~((uint64_t)1 << 63) & ((uint64_t)Frs2.df)); + Frd.udw = ((1ULL << 63) - 1) & Frs2.udw; //fsr.ftt = fsr.cexc = 0 Fsr &= ~(7 << 14); Fsr &= ~(0x1F); @@ -591,14 +583,30 @@ decode OP default Unknown::unknown() 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}}); 0x3E: Trap::pdist({{fault = new IllegalInstruction;}}); 0x48: BasicOperate::faligndata({{ - uint64_t msbX = (uint64_t)Frs1; - uint64_t lsbX = (uint64_t)Frs2; - uint64_t msbShift = Gsr<2:0> * 8; - uint64_t lsbShift = (8 - Gsr<2:0>) * 8; - uint64_t msbMask = ((uint64_t)(-1)) << msbShift; - uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift; - Frd = ((msbX << msbShift) & msbMask) | - ((lsbX << lsbShift) & lsbMask); + uint64_t msbX = Frs1.udw; + uint64_t lsbX = Frs2.udw; + //Some special cases need to be split out, first + //because they're the most likely to be used, and + //second because otherwise, we end up shifting by + //greater than the width of the type being shifted, + //namely 64, which produces undefined results according + //to the C standard. + switch(Gsr<2:0>) + { + case 0: + Frd.udw = msbX; + break; + case 8: + Frd.udw = lsbX; + break; + default: + uint64_t msbShift = Gsr<2:0> * 8; + uint64_t lsbShift = (8 - Gsr<2:0>) * 8; + uint64_t msbMask = ((uint64_t)(-1)) >> msbShift; + uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift; + Frd.udw = ((msbX & msbMask) << msbShift) | + ((lsbX & lsbMask) >> lsbShift); + } }}); 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}}); 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}}); @@ -639,12 +647,12 @@ decode OP default Unknown::unknown() 0x71: Trap::fands({{fault = new IllegalInstruction;}}); 0x72: Trap::fxnor({{fault = new IllegalInstruction;}}); 0x73: Trap::fxnors({{fault = new IllegalInstruction;}}); - 0x74: BasicOperate::fsrc1({{Frd.df = Frs1.df;}}); - 0x75: BasicOperate::fsrc1s({{Frd.sf = Frs1.sf;}}); + 0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}}); + 0x75: BasicOperate::fsrc1s({{Frd.uw = Frs1.uw;}}); 0x76: Trap::fornot2({{fault = new IllegalInstruction;}}); 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}}); - 0x78: BasicOperate::fsrc2({{Frd.df = Frs2.df;}}); - 0x79: BasicOperate::fsrc2s({{Frd.sf = Frs2.sf;}}); + 0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}}); + 0x79: BasicOperate::fsrc2s({{Frd.uw = Frs2.uw;}}); 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}}); 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}}); 0x7C: Trap::for({{fault = new IllegalInstruction;}}); @@ -825,7 +833,7 @@ decode OP default Unknown::unknown() 0x04: stw({{Mem = Rd.sw;}}, {{32}}); 0x05: stb({{Mem = Rd.sb;}}, {{8}}); 0x06: sth({{Mem = Rd.shw;}}, {{16}}); - 0x07: std({{Mem = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{64}}); + 0x07: std({{Mem = RdLow<31:0> | (RdHigh<31:0> << 32);}}, {{64}}); } format Load { 0x08: ldsw({{Rd = (int32_t)Mem;}}, {{32}}); @@ -876,28 +884,28 @@ decode OP default Unknown::unknown() Mem = temp; }}, {{32}}); format Trap { - 0x20: Load::ldf({{Frd.sf = ((float)Mem);}}, {{32}}); + 0x20: Load::ldf({{Frd.uw = Mem;}}, {{32}}); 0x21: decode X { 0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}}); 0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}}); } 0x22: ldqf({{fault = new FpDisabled;}}); - 0x23: Load::lddf({{Frd.df = ((double)Mem);}}, {{64}}); - 0x24: Store::stf({{Mem = ((int32_t)Frd.sf);}}, {{32}}); + 0x23: Load::lddf({{Frd.udw = Mem;}}, {{64}}); + 0x24: Store::stf({{Mem = Frd.uw;}}, {{32}}); 0x25: decode X { 0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}}); 0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}}); } 0x26: stqf({{fault = new FpDisabled;}}); - 0x27: Store::stdf({{Mem = ((int64_t)Frd.df);}}, {{64}}); + 0x27: Store::stdf({{Mem = Frd.udw;}}, {{64}}); 0x2D: Nop::prefetch({{ }}); - 0x30: Load::ldfa({{Frd.sf = ((float)Mem);}}, {{32}}); + 0x30: Load::ldfa({{Frd.uw = Mem;}}, {{32}}); 0x32: ldqfa({{fault = new FpDisabled;}}); - 0x33: Load::lddfa({{Frd.df = ((double)Mem);}}, {{64}}); - 0x34: Store::stfa({{Mem = ((int32_t)Frd.sf);}}, {{32}}); + 0x33: Load::lddfa({{Frd.udw = Mem;}}, {{64}}); + 0x34: Store::stfa({{Mem = Frd.uw;}}, {{32}}); 0x36: stqfa({{fault = new FpDisabled;}}); //XXX need to work in the ASI thing - 0x37: Store::stdfa({{Mem = ((uint64_t)Frd.df);}}, {{64}}); + 0x37: Store::stdfa({{Mem = Frd.udw;}}, {{64}}); 0x3C: Cas::casa({{ uint64_t val = Mem.uw; if(Rs2.uw == val) diff --git a/src/arch/sparc/isa/formats/mem.isa b/src/arch/sparc/isa/formats/mem.isa index 12dae57e5..9011c1fc6 100644 --- a/src/arch/sparc/isa/formats/mem.isa +++ b/src/arch/sparc/isa/formats/mem.isa @@ -111,10 +111,10 @@ def template MemExecute {{ DPRINTF(Sparc, "The address is 0x%x\n", EA); %(load)s; %(code)s; - %(store)s; if(fault == NoFault) { + %(store)s; //Write the resulting state to the execution context %(op_wb)s; } diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 3783051c4..f1c2bee96 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -61,6 +61,7 @@ output exec {{ #include #endif +#include "arch/sparc/asi.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 31989cfe2..a3bb0eb1a 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -190,10 +190,10 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) //The entry point to the program auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entryPoint())); //Different user and group IDs - auxv.push_back(buildAuxVect(SPARC_AT_UID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_GID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100)); + auxv.push_back(buildAuxVect(SPARC_AT_UID, uid)); + auxv.push_back(buildAuxVect(SPARC_AT_EUID, euid)); + auxv.push_back(buildAuxVect(SPARC_AT_GID, gid)); + auxv.push_back(buildAuxVect(SPARC_AT_EGID, egid)); //Whether to enable "secure mode" in the executable auxv.push_back(buildAuxVect(SPARC_AT_SECURE, 0)); } diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index d850f4b65..75a063da1 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -79,11 +79,11 @@ namespace SparcISA // and put the return value itself in the standard return value reg (). if (return_value.successful()) { // no error, clear XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF); + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE); regs->setIntReg(ReturnValueReg, return_value.value()); } else { // got an error, set XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10); + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11); regs->setIntReg(ReturnValueReg, return_value.value()); } } diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 748f66d37..8b1e60aea 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -42,6 +42,9 @@ #include "sim/param.hh" #include "sim/system.hh" +//XXX This is temporary +#include "arch/isa_specific.hh" + using namespace std; using namespace TheISA; @@ -56,43 +59,67 @@ Trace::InstRecord::dump(ostream &outs) { if (flags[PRINT_REG_DELTA]) { - outs << "PC = 0x" << setbase(16) - << setfill('0') - << setw(16) << PC << endl; - outs << setbase(10) - << setfill(' ') - << setw(0); - /* - int numSources = staticInst->numSrcRegs(); - int numDests = staticInst->numDestRegs(); - outs << "Sources:"; - for(int x = 0; x < numSources; x++) +#if THE_ISA == SPARC_ISA + static uint64_t regs[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + static uint64_t ccr = 0; + static uint64_t y = 0; + static uint64_t floats[32]; + uint64_t newVal; + static const char * prefixes[4] = {"G", "O", "L", "I"}; + + char buf[256]; + sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); + outs << buf; + sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); + outs << buf; + newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); + if(newVal != ccr) { - int sourceNum = staticInst->srcRegIdx(x); - if(sourceNum < FP_Base_DepTag) - outs << " " << getIntRegName(sourceNum); - else if(sourceNum < Ctrl_Base_DepTag) - outs << " " << getFloatRegName(sourceNum - FP_Base_DepTag); - else - outs << " " << getMiscRegName(sourceNum - Ctrl_Base_DepTag); + sprintf(buf, " CCR = 0x%016llx", newVal); + outs << buf; + ccr = newVal; + } + newVal = thread->readMiscReg(SparcISA::MISCREG_Y); + if(newVal != y) + { + sprintf(buf, " Y = 0x%016llx", newVal); + outs << buf; + y = newVal; + } + for(int y = 0; y < 4; y++) + { + for(int x = 0; x < 8; x++) + { + int index = x + 8 * y; + newVal = thread->readIntReg(index); + if(regs[index] != newVal) + { + sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); + outs << buf; + regs[index] = newVal; + } + } + } + for(int y = 0; y < 32; y++) + { + newVal = thread->readFloatRegBits(2 * y, 64); + if(floats[y] != newVal) + { + sprintf(buf, " F%d = 0x%016llx", y, newVal); + outs << buf; + floats[y] = newVal; + } } outs << endl; - outs << "Destinations:"; - for(int x = 0; x < numDests; x++) - { - int destNum = staticInst->destRegIdx(x); - if(destNum < FP_Base_DepTag) - outs << " " << getIntRegName(destNum); - else if(destNum < Ctrl_Base_DepTag) - outs << " " << getFloatRegName(destNum - FP_Base_DepTag); - else - outs << " " << getMiscRegName(destNum - Ctrl_Base_DepTag); - } - outs << endl;*/ +#endif } else if (flags[INTEL_FORMAT]) { #if FULL_SYSTEM - bool is_trace_system = (cpu->system->name() == trace_system); + bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); #else bool is_trace_system = true; #endif @@ -112,13 +139,13 @@ Trace::InstRecord::dump(ostream &outs) if (flags[PRINT_CYCLE]) ccprintf(outs, "%7d: ", cycle); - outs << cpu->name() << " "; + outs << thread->getCpuPtr()->name() << " "; if (flags[TRACE_MISSPEC]) outs << (misspeculating ? "-" : "+") << " "; if (flags[PRINT_THREAD_NUM]) - outs << "T" << thread << " : "; + outs << "T" << thread->getThreadNum() << " : "; std::string sym_str; diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh index 8cc98b777..02ea162f0 100644 --- a/src/cpu/exetrace.hh +++ b/src/cpu/exetrace.hh @@ -41,7 +41,7 @@ #include "cpu/thread_context.hh" #include "cpu/static_inst.hh" -class BaseCPU; +class ThreadContext; namespace Trace { @@ -53,13 +53,12 @@ class InstRecord : public Record // The following fields are initialized by the constructor and // thus guaranteed to be valid. - BaseCPU *cpu; + ThreadContext *thread; // need to make this ref-counted so it doesn't go away before we // dump the record StaticInstPtr staticInst; Addr PC; bool misspeculating; - unsigned thread; // The remaining fields are only valid for particular instruction // types (e.g, addresses for memory ops) or when particular @@ -95,11 +94,12 @@ class InstRecord : public Record bool regs_valid; public: - InstRecord(Tick _cycle, BaseCPU *_cpu, + InstRecord(Tick _cycle, ThreadContext *_thread, const StaticInstPtr &_staticInst, - Addr _pc, bool spec, int _thread) - : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc), - misspeculating(spec), thread(_thread) + Addr _pc, bool spec) + : Record(_cycle), thread(_thread), + staticInst(_staticInst), PC(_pc), + misspeculating(spec) { data_status = DataInvalid; addr_valid = false; @@ -174,14 +174,14 @@ InstRecord::setRegs(const IntRegFile ®s) inline InstRecord * -getInstRecord(Tick cycle, ThreadContext *tc, BaseCPU *cpu, +getInstRecord(Tick cycle, ThreadContext *tc, const StaticInstPtr staticInst, - Addr pc, int thread = 0) + Addr pc) { if (DTRACE(InstExec) && (InstRecord::traceMisspec() || !tc->misspeculating())) { - return new InstRecord(cycle, cpu, staticInst, pc, - tc->misspeculating(), thread); + return new InstRecord(cycle, tc, staticInst, pc, + tc->misspeculating()); } return NULL; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index bf9a73902..1e080181c 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1129,9 +1129,9 @@ DefaultFetch::fetch(bool &status_change) tid, instruction->staticInst->disassemble(fetch_PC)); instruction->traceData = - Trace::getInstRecord(curTick, cpu->tcBase(tid), cpu, + Trace::getInstRecord(curTick, cpu->tcBase(tid), instruction->staticInst, - instruction->readPC(),tid); + instruction->readPC()); predicted_branch = lookupAndUpdateNextPC(instruction, next_PC, next_NPC); diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index c9c5a869b..1b120460a 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -855,9 +855,9 @@ FrontEnd::getInstFromCacheline() instruction->staticInst->disassemble(PC)); instruction->traceData = - Trace::getInstRecord(curTick, tc, cpu, + Trace::getInstRecord(curTick, tc, instruction->staticInst, - instruction->readPC(), 0); + instruction->readPC()); // Increment stat of fetched instructions. ++fetchedInsts; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 22a210115..f801b93fa 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -398,7 +398,7 @@ BaseSimpleCPU::preExecute() inst = gtoh(inst); curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); - traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, + traceData = Trace::getInstRecord(curTick, tc, curStaticInst, thread->readPC()); DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", diff --git a/src/python/m5/objects/Process.py b/src/python/m5/objects/Process.py index 08f8b6bce..771ad4101 100644 --- a/src/python/m5/objects/Process.py +++ b/src/python/m5/objects/Process.py @@ -13,6 +13,12 @@ class LiveProcess(Process): cmd = VectorParam.String("command line (executable plus arguments)") env = VectorParam.String('', "environment settings") input = Param.String('cin', "filename for stdin") + uid = Param.Int(100, 'user id') + euid = Param.Int(100, 'effective user id') + gid = Param.Int(100, 'group id') + egid = Param.Int(100, 'effective group id') + pid = Param.Int(100, 'process id') + ppid = Param.Int(99, 'parent process id') class AlphaLiveProcess(LiveProcess): type = 'AlphaLiveProcess' diff --git a/src/sim/process.cc b/src/sim/process.cc index 081a25976..20f7fec2d 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -460,6 +460,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) Param output; VectorParam env; SimObjectParam system; + Param uid; + Param euid; + Param gid; + Param egid; + Param pid; + Param ppid; END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) @@ -471,7 +477,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), INIT_PARAM(env, "environment settings"), - INIT_PARAM(system, "system") + INIT_PARAM(system, "system"), + INIT_PARAM(uid, "user id"), + INIT_PARAM(euid, "effective user id"), + INIT_PARAM(gid, "group id"), + INIT_PARAM(egid, "effective group id"), + INIT_PARAM(pid, "process id"), + INIT_PARAM(ppid, "parent process id") END_INIT_SIM_OBJECT_PARAMS(LiveProcess) diff --git a/src/sim/process.hh b/src/sim/process.hh index 763deb100..d64cc3cf1 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -75,6 +75,16 @@ class Process : public SimObject // number of CPUs (esxec contexts, really) assigned to this process. unsigned int numCpus() { return threadContexts.size(); } + // Id of the owner of the process + uint64_t uid; + uint64_t euid; + uint64_t gid; + uint64_t egid; + + // pid of the process and it's parent + uint64_t pid; + uint64_t ppid; + // record of blocked context struct WaitRec { diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index cf90d8f84..fe0260223 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -414,8 +414,8 @@ getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, // fake_syscall mode, so there's no way for a process to know it's // not getting a unique value. - tc->setIntReg(SyscallPseudoReturnReg, 99); - return 100; + tc->setIntReg(SyscallPseudoReturnReg, process->ppid); + return process->pid; } @@ -427,8 +427,8 @@ getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, // simulation to be deterministic. // EUID goes in r20. - tc->setIntReg(SyscallPseudoReturnReg, 100); //EUID - return 100; // UID + tc->setIntReg(SyscallPseudoReturnReg, process->euid); //EUID + return process->uid; // UID } @@ -437,8 +437,8 @@ getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { // Get current group ID. EGID goes in r20. - tc->setIntReg(SyscallPseudoReturnReg, 100); //EGID - return 100; + tc->setIntReg(SyscallPseudoReturnReg, process->egid); //EGID + return process->gid; } @@ -459,43 +459,43 @@ getpidFunc(SyscallDesc *desc, int callnum, Process *process, // fake_syscall mode, so there's no way for a process to know it's // not getting a unique value. - tc->setIntReg(SyscallPseudoReturnReg, 99); //PID - return 100; + tc->setIntReg(SyscallPseudoReturnReg, process->ppid); //PID + return process->pid; } SyscallReturn getppidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - return 99; + return process->ppid; } SyscallReturn getuidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - return 100; // UID + return process->uid; // UID } SyscallReturn geteuidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - return 100; // UID + return process->euid; // UID } SyscallReturn getgidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - return 100; + return process->gid; } SyscallReturn getegidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - return 100; + return process->egid; }