From 592f35ac0ff8d525fad2dc606b53b4cd8b84fd69 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 2 Feb 2007 18:04:42 -0500 Subject: fix mostly floating point related src/arch/sparc/floatregfile.cc: fix fp read/writing to registers... looking for suggestions on cleaner ways if anyone has them src/arch/sparc/isa/decoder.isa: fix some fp implementations src/arch/sparc/isa/formats/basic.isa: add new fp op class that 0 cexec in fsr and sets rounding mode for the up comming op src/arch/sparc/isa/includes.isa: include the appropriate header files for the rounding code src/arch/sparc/miscregfile.cc: print fsr out when it's read/written and the Sparc traceflgas in on src/cpu/exetrace.cc: fix printing of float registers --HG-- extra : convert_revision : 49faab27f2e786a8455f9ca0f3f0132380c9d992 --- src/arch/sparc/floatregfile.cc | 38 ++++++++++-------- src/arch/sparc/isa/decoder.isa | 78 +++++++++++++++++++++--------------- src/arch/sparc/isa/formats/basic.isa | 39 ++++++++++++++++++ src/arch/sparc/isa/includes.isa | 9 ++++- src/arch/sparc/miscregfile.cc | 6 +-- src/cpu/exetrace.cc | 9 ++--- 6 files changed, 118 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index 585782ddb..e1b5ea7c8 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -69,22 +69,25 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) switch(width) { case SingleWidth: - float32_t result32; + uint32_t result32; + float32_t fresult32; memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); - result = htog(result32); - DPRINTF(Sparc, "Read FP32 register %d = 0x%x\n", floatReg, result); + result32 = htog(result32); + memcpy(&fresult32, &result32, sizeof(result32)); + result = fresult32; + DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32); break; case DoubleWidth: - float64_t result64; + uint64_t result64; + float64_t fresult64; memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); - result = htog(result64); - DPRINTF(Sparc, "Read FP64 register %d = 0x%x\n", floatReg, result); + result64 = htog(result64); + memcpy(&fresult64, &result64, sizeof(result64)); + result = fresult64; + DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64); break; case QuadWidth: - float128_t result128; - memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - result = htog(result128); - DPRINTF(Sparc, "Read FP128 register %d = 0x%x\n", floatReg, result); + panic("Quad width FP not implemented."); break; default: panic("Attempted to read a %d bit floating point register!", width); @@ -113,10 +116,7 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result); break; case QuadWidth: - uint64_t result128; - memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - result = htog(result128); - DPRINTF(Sparc, "Read FP128 bits register %d = 0x%x\n", floatReg, result); + panic("Quad width FP not implemented."); break; default: panic("Attempted to read a %d bit floating point register!", width); @@ -132,15 +132,21 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) uint32_t result32; uint64_t result64; + float32_t fresult32; + float64_t fresult64; switch(width) { case SingleWidth: - result32 = gtoh((uint32_t)val); + fresult32 = val; + memcpy(&result32, &fresult32, sizeof(result32)); + result32 = gtoh(result32); memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32); break; case DoubleWidth: - result64 = gtoh((uint64_t)val); + fresult64 = val; + memcpy(&result64, &fresult64, sizeof(result64)); + result64 = gtoh(result64); memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64); break; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 81443fecb..57e0857f1 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -718,7 +718,7 @@ decode OP default Unknown::unknown() 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}}); } 0x34: decode OPF{ - format BasicOperate{ + format FpBasic{ 0x01: fmovs({{ Frds.uw = Frs2s.uw; //fsr.ftt = fsr.cexc = 0 @@ -765,7 +765,7 @@ decode OP default Unknown::unknown() 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}}); 0x43: FpUnimpl::faddq(); 0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}}); - 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}}); + 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df; }}); 0x47: FpUnimpl::fsubq(); 0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}}); 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}}); @@ -776,26 +776,26 @@ decode OP default Unknown::unknown() 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}}); 0x6E: FpUnimpl::fdmulq(); 0x81: fstox({{ - Frd.df = (double)static_cast(Frs2s.sf); + Frd.sdw = static_cast(Frs2s.sf); }}); 0x82: fdtox({{ - Frd.df = (double)static_cast(Frs2.df); + Frd.sdw = static_cast(Frs2.df); }}); 0x83: FpUnimpl::fqtox(); 0x84: fxtos({{ - Frds.sf = static_cast((int64_t)Frs2.df); + Frds.sf = static_cast(Frs2.sdw); }}); 0x88: fxtod({{ - Frd.df = static_cast((int64_t)Frs2.df); + Frd.df = static_cast(Frs2.sdw); }}); 0x8C: FpUnimpl::fxtoq(); 0xC4: fitos({{ - Frds.sf = static_cast((int32_t)Frs2s.sf); + Frds.sf = static_cast(Frs2s.sw); }}); 0xC6: fdtos({{Frds.sf = Frs2.df;}}); 0xC7: FpUnimpl::fqtos(); 0xC8: fitod({{ - Frd.df = static_cast((int32_t)Frs2s.sf); + Frd.df = static_cast(Frs2s.sw); }}); 0xC9: fstod({{Frd.df = Frs2s.sf;}}); 0xCB: FpUnimpl::fqtod(); @@ -803,17 +803,25 @@ decode OP default Unknown::unknown() 0xCD: FpUnimpl::fstoq(); 0xCE: FpUnimpl::fdtoq(); 0xD1: fstoi({{ - Frds.sf = (float)static_cast(Frs2s.sf); + Frds.sw = static_cast(Frs2s.sf); + float t = Frds.sw; + if (t != Frs2s.sf) + Fsr = insertBits(Fsr, 4,0, 0x01); + Fsr |= Fsr<4:0> << 5; }}); 0xD2: fdtoi({{ - Frds.sf = (float)static_cast(Frs2.df); + Frds.sw = static_cast(Frs2.df); + double t = Frds.sw; + if (t != Frs2.df) + Fsr = insertBits(Fsr, 4,0, 0x01); + Fsr |= Fsr<4:0> << 5; }}); 0xD3: FpUnimpl::fqtoi(); default: FailUnimpl::fpop1(); } } 0x35: decode OPF{ - format BasicOperate{ + format FpBasic{ 0x51: fcmps({{ uint8_t fcc; if(isnan(Frs1s) || isnan(Frs2s)) @@ -831,11 +839,11 @@ decode OP default Unknown::unknown() }}); 0x52: fcmpd({{ uint8_t fcc; - if(isnan(Frs1s) || isnan(Frs2s)) + if(isnan(Frs1) || isnan(Frs2)) fcc = 3; - else if(Frs1s < Frs2s) + else if(Frs1 < Frs2) fcc = 1; - else if(Frs1s > Frs2s) + else if(Frs1 > Frs2) fcc = 2; else fcc = 0; @@ -860,11 +868,11 @@ decode OP default Unknown::unknown() }}); 0x56: fcmped({{ uint8_t fcc = 0; - if(isnan(Frs1s) || isnan(Frs2s)) + if(isnan(Frs1) || isnan(Frs2)) fault = new FpExceptionIEEE754; - if(Frs1s < Frs2s) + if(Frs1 < Frs2) fcc = 1; - else if(Frs1s > Frs2s) + else if(Frs1 > Frs2) fcc = 2; uint8_t firstbit = 10; if(FCMPCC) @@ -960,24 +968,24 @@ decode OP default Unknown::unknown() 0x55: FailUnimpl::fpsub16s(); 0x56: FailUnimpl::fpsub32(); 0x57: FailUnimpl::fpsub32s(); - 0x60: BasicOperate::fzero({{Frd.df = 0;}}); - 0x61: BasicOperate::fzeros({{Frds.sf = 0;}}); + 0x60: FpBasic::fzero({{Frd.df = 0;}}); + 0x61: FpBasic::fzeros({{Frds.sf = 0;}}); 0x62: FailUnimpl::fnor(); 0x63: FailUnimpl::fnors(); 0x64: FailUnimpl::fandnot2(); 0x65: FailUnimpl::fandnot2s(); - 0x66: BasicOperate::fnot2({{ + 0x66: FpBasic::fnot2({{ Frd.df = (double)(~((uint64_t)Frs2.df)); }}); - 0x67: BasicOperate::fnot2s({{ + 0x67: FpBasic::fnot2s({{ Frds.sf = (float)(~((uint32_t)Frs2s.sf)); }}); 0x68: FailUnimpl::fandnot1(); 0x69: FailUnimpl::fandnot1s(); - 0x6A: BasicOperate::fnot1({{ + 0x6A: FpBasic::fnot1({{ Frd.df = (double)(~((uint64_t)Frs1.df)); }}); - 0x6B: BasicOperate::fnot1s({{ + 0x6B: FpBasic::fnot1s({{ Frds.sf = (float)(~((uint32_t)Frs1s.sf)); }}); 0x6C: FailUnimpl::fxor(); @@ -988,18 +996,18 @@ decode OP default Unknown::unknown() 0x71: FailUnimpl::fands(); 0x72: FailUnimpl::fxnor(); 0x73: FailUnimpl::fxnors(); - 0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}}); - 0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}}); + 0x74: FpBasic::fsrc1({{Frd.udw = Frs1.udw;}}); + 0x75: FpBasic::fsrc1s({{Frds.uw = Frs1s.uw;}}); 0x76: FailUnimpl::fornot2(); 0x77: FailUnimpl::fornot2s(); - 0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}}); - 0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}}); + 0x78: FpBasic::fsrc2({{Frd.udw = Frs2.udw;}}); + 0x79: FpBasic::fsrc2s({{Frds.uw = Frs2s.uw;}}); 0x7A: FailUnimpl::fornot1(); 0x7B: FailUnimpl::fornot1s(); 0x7C: FailUnimpl::for(); 0x7D: FailUnimpl::fors(); - 0x7E: BasicOperate::fone({{Frd.udw = std::numeric_limits::max();}}); - 0x7F: BasicOperate::fones({{Frds.uw = std::numeric_limits::max();}}); + 0x7E: FpBasic::fone({{Frd.udw = std::numeric_limits::max();}}); + 0x7F: FpBasic::fones({{Frds.uw = std::numeric_limits::max();}}); 0x80: Trap::shutdown({{fault = new IllegalInstruction;}}); 0x81: FailUnimpl::siam(); } @@ -1236,16 +1244,20 @@ decode OP default Unknown::unknown() Rd.uw = uReg0;}}, {{EXT_ASI}}); format Trap { 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); - 0x21: decode X { + 0x21: decode RD { 0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}}); 0x1: Load::ldxfsr({{Fsr = Mem.udw;}}); + default: FailUnimpl::ldfsrOther(); } 0x22: ldqf({{fault = new FpDisabled;}}); 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 0x24: Store::stf({{Mem.uw = Frds.uw;}}); - 0x25: decode X { - 0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}}); - 0x1: Store::stxfsr({{Mem.udw = Fsr;}}); + 0x25: decode RD { + 0x0: Store::stfsr({{Mem.uw = Fsr<31:0>; + Fsr = insertBits(Fsr,16,14,0);}}); + 0x1: Store::stxfsr({{Mem.udw = Fsr; + Fsr = insertBits(Fsr,16,14,0);}}); + default: FailUnimpl::stfsrOther(); } 0x26: stqf({{fault = new FpDisabled;}}); 0x27: Store::stdf({{Mem.udw = Frd.udw;}}); diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index e8762a205..fac523aeb 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -103,3 +103,42 @@ def format BasicOperate(code, *flags) {{ decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; + +def format FpBasic(code, *flags) {{ + fp_code = """ + Fsr = insertBits(Fsr,4,0,0); +#if defined(__sun) || defined (__OpenBSD__) + fp_rnd newrnd = FP_RN; + switch (Fsr<31:30>) { + case 0: newrnd = FP_RN; break; + case 1: newrnd = FP_RZ; break; + case 2: newrnd = FP_RP; break; + case 3: newrnd = FP_RM; break; + } + fp_rnd oldrnd = fpsetround(newrnd); +#else + int newrnd = FE_TONEAREST; + switch (Fsr<31:30>) { + case 0: newrnd = FE_TONEAREST; break; + case 1: newrnd = FE_TOWARDZERO; break; + case 2: newrnd = FE_UPWARD; break; + case 3: newrnd = FE_DOWNWARD; break; + } + int oldrnd = fegetround(); + fesetround(newrnd); +#endif +""" + fp_code += code + fp_code += """ +#if defined(__sun) || defined (__OpenBSD__) + fpsetround(oldrnd); +#else + fesetround(oldrnd); +#endif +""" + iop = InstObjParams(name, Name, 'SparcStaticInst', fp_code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index a6dca9bf1..d2ef67154 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -53,7 +53,7 @@ output decoder {{ #include "cpu/thread_context.hh" // for Jump::branchTarget() #include "mem/packet.hh" -#if defined(linux) +#if defined(linux) || defined(__APPLE__) #include #endif #include @@ -62,9 +62,14 @@ using namespace SparcISA; }}; output exec {{ -#if defined(linux) +#if defined(linux) || defined(__APPLE__) #include #endif + +#if defined(__sun) || defined (__OpenBSD__) +#include +#endif + #include #include diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 0fe3e96b2..8b612e8b4 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -232,6 +232,7 @@ MiscReg MiscRegFile::readReg(int miscReg) /** Floating Point Status Register */ case MISCREG_FSR: + DPRINTF(Sparc, "FSR read as: %#x\n", fsr); return fsr; case MISCREG_MMU_P_CONTEXT: @@ -337,10 +338,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) case MISCREG_PCR: case MISCREG_PIC: panic("Performance Instrumentation not impl\n"); - /** Floating Point Status Register */ - case MISCREG_FSR: - warn("Reading FSR Floating Point not implemented\n"); - break; case MISCREG_SOFTINT_CLR: case MISCREG_SOFTINT_SET: panic("Can read from softint clr/set\n"); @@ -488,6 +485,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) /** Floating Point Status Register */ case MISCREG_FSR: fsr = val; + DPRINTF(Sparc, "FSR written with: %#x\n", fsr); break; case MISCREG_MMU_P_CONTEXT: diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index e34ae3731..672b06eaf 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -450,16 +450,13 @@ Trace::InstRecord::dump(ostream &outs) diffTlb = true; } - if ((diffPC || diffCC || diffInst || diffIntRegs || + if (diffPC || diffCC || diffInst || diffIntRegs || diffFpRegs || diffTpc || diffTnpc || diffTstate || diffTt || diffHpstate || diffHtstate || diffHtba || diffPstate || diffY || diffCcr || diffTl || diffFsr || diffGl || diffAsi || diffPil || diffCwp || diffCansave || diffCanrestore || diffOtherwin || diffCleanwin || diffTlb) - && !((staticInst->machInst & 0xC1F80000) == 0x81D00000) - && !(((staticInst->machInst & 0xC0000000) == 0xC0000000) - && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1) - ) { + { outs << "Differences found between M5 and Legion:"; if (diffPC) @@ -639,7 +636,7 @@ Trace::InstRecord::dump(ostream &outs) char label[8]; sprintf(label, "%%f%d", x); printRegPair(outs, label, - thread->readFloatRegBits(x,FloatRegFile::DoubleWidth), + thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth), shared_data->fpregs[x]); } } -- cgit v1.2.3 From 665ddde57a2f6de6cafd5046f3ee00297e992ce0 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 2 Feb 2007 18:05:21 -0500 Subject: make interrupt code serialize itself and fix indenting --HG-- extra : convert_revision : d0bb23c7922568586b640084ac719e809cc8422f --- src/arch/sparc/interrupts.hh | 254 ++++++++++++++++++++++--------------------- 1 file changed, 129 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 99ddb4919..42bbfc5cf 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -46,161 +46,165 @@ enum interrupts_t { num_interrupt_types }; - class Interrupts - { +class Interrupts +{ - private: + private: - bool interrupts[num_interrupt_types]; - int numPosted; + bool interrupts[num_interrupt_types]; + int numPosted; - public: - Interrupts() - { - for (int i = 0; i < num_interrupt_types; ++i) { - interrupts[i] = false; - } - numPosted = 0; - } - - void post(int int_type) - { - if (int_type < 0 || int_type >= num_interrupt_types) - panic("posting unknown interrupt!\n"); - interrupts[int_type] = true; - ++numPosted; + public: + Interrupts() + { + for (int i = 0; i < num_interrupt_types; ++i) { + interrupts[i] = false; } + numPosted = 0; + } - void post(int int_num, int index) - { + void post(int int_type) + { + if (int_type < 0 || int_type >= num_interrupt_types) + panic("posting unknown interrupt!\n"); + interrupts[int_type] = true; + ++numPosted; + } - } + void post(int int_num, int index) + { - void clear(int int_num, int index) - { + } - } + void clear(int int_num, int index) + { - void clear_all() - { + } - } + void clear_all() + { - bool check_interrupts(ThreadContext * tc) const - { - if (numPosted) - return true; - else - return false; - } + } - Fault getInterrupt(ThreadContext * tc) - { - int hpstate = tc->readMiscReg(MISCREG_HPSTATE); - int pstate = tc->readMiscReg(MISCREG_PSTATE); - bool ie = pstate & PSTATE::ie; - - // THESE ARE IN ORDER OF PRIORITY - // since there are early returns, and the highest - // priority interrupts should get serviced, - // it is v. important that new interrupts are inserted - // in the right order of processing - if (hpstate & HPSTATE::hpriv) { - if (ie) { - if (interrupts[hstick_match]) { - if (tc->readMiscReg(MISCREG_HINTP) & 1) { - interrupts[hstick_match] = false; - --numPosted; - return new HstickMatch; - } - } - if (interrupts[interrupt_vector]) { - interrupts[interrupt_vector] = false; - --numPosted; - //HAVEN'T IMPLed THIS YET - return NoFault; - } - } else { - if (interrupts[hstick_match]) { - return NoFault; - } + bool check_interrupts(ThreadContext * tc) const + { + if (numPosted) + return true; + else + return false; + } - } - } else { - if (interrupts[trap_level_zero]) { - if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { - interrupts[trap_level_zero] = false; - --numPosted; - return new TrapLevelZero; - } - } + Fault getInterrupt(ThreadContext * tc) + { + int hpstate = tc->readMiscReg(MISCREG_HPSTATE); + int pstate = tc->readMiscReg(MISCREG_PSTATE); + bool ie = pstate & PSTATE::ie; + + // THESE ARE IN ORDER OF PRIORITY + // since there are early returns, and the highest + // priority interrupts should get serviced, + // it is v. important that new interrupts are inserted + // in the right order of processing + if (hpstate & HPSTATE::hpriv) { + if (ie) { if (interrupts[hstick_match]) { if (tc->readMiscReg(MISCREG_HINTP) & 1) { interrupts[hstick_match] = false; --numPosted; return new HstickMatch; - } - } - if (ie) { - if (interrupts[cpu_mondo]) { - interrupts[cpu_mondo] = false; - --numPosted; - return new CpuMondo; } - if (interrupts[dev_mondo]) { - interrupts[dev_mondo] = false; - --numPosted; - return new DevMondo; + } + if (interrupts[interrupt_vector]) { + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed THIS YET + return NoFault; + } + } else { + if (interrupts[hstick_match]) { + return NoFault; + } + + } + } else { + if (interrupts[trap_level_zero]) { + if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { + interrupts[trap_level_zero] = false; + --numPosted; + return new TrapLevelZero; + } + } + if (interrupts[hstick_match]) { + if (tc->readMiscReg(MISCREG_HINTP) & 1) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; } - if (interrupts[soft_interrupt]) { - int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); - // it seems that interrupt vectors are right in - // the middle of interrupt levels with regard to - // priority, so have to check - if ((il < 6) && - interrupts[interrupt_vector]) { - // may require more details here since there - // may be lots of interrupts embedded in an - // platform interrupt vector - interrupts[interrupt_vector] = false; + } + if (ie) { + if (interrupts[cpu_mondo]) { + interrupts[cpu_mondo] = false; + --numPosted; + return new CpuMondo; + } + if (interrupts[dev_mondo]) { + interrupts[dev_mondo] = false; + --numPosted; + return new DevMondo; + } + if (interrupts[soft_interrupt]) { + int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); + // it seems that interrupt vectors are right in + // the middle of interrupt levels with regard to + // priority, so have to check + if ((il < 6) && + interrupts[interrupt_vector]) { + // may require more details here since there + // may be lots of interrupts embedded in an + // platform interrupt vector + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed YET + return NoFault; + } else { + if (il > tc->readMiscReg(MISCREG_PIL)) { + uint64_t si = tc->readMiscReg(MISCREG_SOFTINT); + uint64_t more = si & ~(1 << (il + 1)); + if (!InterruptLevel(more)) { + interrupts[soft_interrupt] = false; --numPosted; - //HAVEN'T IMPLed YET - return NoFault; - } else { - if (il > tc->readMiscReg(MISCREG_PIL)) { - uint64_t si = tc->readMiscReg(MISCREG_SOFTINT); - uint64_t more = si & ~(1 << (il + 1)); - if (!InterruptLevel(more)) { - interrupts[soft_interrupt] = false; - --numPosted; - } - return new InterruptLevelN(il); } + return new InterruptLevelN(il); } } - if (interrupts[resumable_error]) { - interrupts[resumable_error] = false; - --numPosted; - return new ResumableError; - } + } + if (interrupts[resumable_error]) { + interrupts[resumable_error] = false; + --numPosted; + return new ResumableError; } } - return NoFault; } + return NoFault; + } - void updateIntrInfo(ThreadContext * tc) - { + void updateIntrInfo(ThreadContext * tc) + { - } + } - void serialize(std::ostream &os) - { - } + void serialize(std::ostream &os) + { + SERIALIZE_ARRAY(interrupts,num_interrupt_types); + SERIALIZE_SCALAR(numPosted); + } - void unserialize(Checkpoint *cp, const std::string §ion) - { - } - }; -} + void unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(interrupts,num_interrupt_types); + UNSERIALIZE_SCALAR(numPosted); + } +}; +} // namespace SPARC_ISA #endif // __ARCH_SPARC_INTERRUPT_HH__ -- cgit v1.2.3 From ecef27f172523503eb64fc7b2d5e82c2f83b5210 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 2 Feb 2007 19:02:27 -0500 Subject: more sparc fixes src/arch/sparc/isa/decoder.isa: fix rdgsr fault check src/arch/sparc/tlb.cc: block asis are now supported --HG-- extra : convert_revision : cf55d648d2c5184fab03b6fe057d0e33c1dfc393 --- src/arch/sparc/isa/decoder.isa | 8 ++++---- src/arch/sparc/tlb.cc | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 57e0857f1..e56e9d81d 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -479,10 +479,10 @@ decode OP default Unknown::unknown() 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); //0x12 should cause an illegal instruction exception 0x13: NoPriv::rdgsr({{ - if(Fprs<2:> == 0 || Pstate<4:> == 0) - Rd = Gsr; - else - fault = new FpDisabled; + fault = checkFpEnableFault(xc); + if (fault) + return fault; + Rd = Gsr; }}); //0x14-0x15 should cause an illegal instruction exception 0x16: Priv::rdsoftint({{Rd = Softint;}}); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index ebc8c0e7a..293f667d6 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -668,8 +668,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (!implicit && asi != ASI_P && asi != ASI_S) { if (AsiIsLittle(asi)) panic("Little Endian ASIs not supported\n"); - if (AsiIsBlock(asi)) - panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); @@ -688,7 +686,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) goto handleSparcErrorRegAccess; if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) && - !AsiIsTwin(asi)) + !AsiIsTwin(asi) && !AsiIsBlock(asi)) panic("Accessing ASI %#X. Should we?\n", asi); } -- cgit v1.2.3 From ebb6972dd3a6b9343c79fd022756523a2992a264 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 6 Feb 2007 15:52:33 -0500 Subject: more fp fixes fix unaligned accesses in mmaped disk device src/arch/sparc/isa/decoder.isa: get (ld|st)fsr ops working right. In reality the fp enable check needs to go higher up in the emitted code src/arch/sparc/isa/formats/basic.isa: move the cexec into the aexec field src/cpu/exetrace.cc: copy the exception state from legion when we get it wrong. We aren't going to get it right without an fp emulation layer src/dev/sparc/mm_disk.cc: src/dev/sparc/mm_disk.hh: fix unaligned accesses in the memory mapped disk device --HG-- extra : convert_revision : aaa33096b08cf0563fe291d984a87493a117e528 --- src/arch/sparc/isa/decoder.isa | 24 +++++--- src/arch/sparc/isa/formats/basic.isa | 4 ++ src/cpu/exetrace.cc | 10 +++- src/dev/sparc/mm_disk.cc | 103 +++++++++++++++++++++++++++++------ src/dev/sparc/mm_disk.hh | 7 +-- 5 files changed, 119 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e56e9d81d..fb606c7cc 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -807,14 +807,12 @@ decode OP default Unknown::unknown() float t = Frds.sw; if (t != Frs2s.sf) Fsr = insertBits(Fsr, 4,0, 0x01); - Fsr |= Fsr<4:0> << 5; }}); 0xD2: fdtoi({{ Frds.sw = static_cast(Frs2.df); double t = Frds.sw; if (t != Frs2.df) Fsr = insertBits(Fsr, 4,0, 0x01); - Fsr |= Fsr<4:0> << 5; }}); 0xD3: FpUnimpl::fqtoi(); default: FailUnimpl::fpop1(); @@ -1245,18 +1243,30 @@ decode OP default Unknown::unknown() format Trap { 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); 0x21: decode RD { - 0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}}); - 0x1: Load::ldxfsr({{Fsr = Mem.udw;}}); + 0x0: Load::ldfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Fsr = Mem.uw | Fsr<63:32>;}}); + 0x1: Load::ldxfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Fsr = Mem.udw;}}); default: FailUnimpl::ldfsrOther(); } 0x22: ldqf({{fault = new FpDisabled;}}); 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 0x24: Store::stf({{Mem.uw = Frds.uw;}}); 0x25: decode RD { - 0x0: Store::stfsr({{Mem.uw = Fsr<31:0>; - Fsr = insertBits(Fsr,16,14,0);}}); - 0x1: Store::stxfsr({{Mem.udw = Fsr; + 0x0: Store::stfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.uw = Fsr<31:0>; Fsr = insertBits(Fsr,16,14,0);}}); + 0x1: Store::stxfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.udw = Fsr; + Fsr = insertBits(Fsr,16,14,0);}}); default: FailUnimpl::stfsrOther(); } 0x26: stqf({{fault = new FpDisabled;}}); diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index fac523aeb..017f43780 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -106,6 +106,7 @@ def format BasicOperate(code, *flags) {{ def format FpBasic(code, *flags) {{ fp_code = """ + Fsr |= bits(Fsr,4,0) << 5; Fsr = insertBits(Fsr,4,0,0); #if defined(__sun) || defined (__OpenBSD__) fp_rnd newrnd = FP_RN; @@ -128,7 +129,10 @@ def format FpBasic(code, *flags) {{ fesetround(newrnd); #endif """ + fp_code += code + + fp_code += """ #if defined(__sun) || defined (__OpenBSD__) fpsetround(oldrnd); diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 672b06eaf..5108d7338 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -411,8 +411,14 @@ Trace::InstRecord::dump(ostream &outs) if(shared_data->y != thread->readIntReg(NumIntArchRegs + 1)) diffY = true; - if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR)) + if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR)) { diffFsr = true; + if (mbits(shared_data->fsr, 63,10) == + mbits(thread->readMiscReg(MISCREG_FSR), 63,10)) { + thread->setMiscReg(MISCREG_FSR, shared_data->fsr); + diffFsr = false; + } + } //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) if(shared_data->ccr != thread->readIntReg(NumIntArchRegs + 2)) @@ -664,7 +670,7 @@ Trace::InstRecord::dump(ostream &outs) } diffcount++; - if (diffcount > 2) + if (diffcount > 3) fatal("Differences found between Legion and M5\n"); } else diffcount = 0; diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc index 018415f6c..b8cabd0cf 100644 --- a/src/dev/sparc/mm_disk.cc +++ b/src/dev/sparc/mm_disk.cc @@ -47,7 +47,7 @@ MmDisk::MmDisk(Params *p) : BasicPioDevice(p), image(p->image), curSector((uint64_t)-1), dirty(false) { - std::memset(&bytes, 0, SectorSize); + std::memset(&diskData, 0, SectorSize); pioSize = image->size() * SectorSize; } @@ -57,9 +57,9 @@ MmDisk::read(PacketPtr pkt) Addr accessAddr; off_t sector; off_t bytes_read; - uint16_t *d16; - uint32_t *d32; - uint64_t *d64; + uint16_t d16; + uint32_t d32; + uint64_t d64; assert(pkt->result == Packet::Unknown); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); @@ -68,26 +68,34 @@ MmDisk::read(PacketPtr pkt) sector = accessAddr / SectorSize; if (sector != curSector) { - if (dirty) - bytes_read = image->write(bytes, curSector); - bytes_read = image->read(bytes, sector); + if (dirty) { + bytes_read = image->write(diskData, curSector); + assert(bytes_read == SectorSize); + } + bytes_read = image->read(diskData, sector); + assert(bytes_read == SectorSize); curSector = sector; } switch (pkt->getSize()) { case sizeof(uint8_t): - pkt->set(bytes[accessAddr % SectorSize]); + pkt->set(diskData[accessAddr % SectorSize]); + DPRINTF(IdeDisk, "reading byte %#x value= %#x\n", accessAddr, diskData[accessAddr % + SectorSize]); break; case sizeof(uint16_t): - d16 = (uint16_t*)bytes + (accessAddr % SectorSize)/2; - pkt->set(htobe(*d16)); + memcpy(&d16, diskData + (accessAddr % SectorSize), 2); + pkt->set(htobe(d32)); + DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16); break; case sizeof(uint32_t): - d32 = (uint32_t*)bytes + (accessAddr % SectorSize)/4; - pkt->set(htobe(*d32)); + memcpy(&d32, diskData + (accessAddr % SectorSize), 4); + pkt->set(htobe(d32)); + DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32); break; case sizeof(uint64_t): - d64 = (uint64_t*)bytes + (accessAddr % SectorSize)/8; - pkt->set(htobe(*d64)); + memcpy(&d64, diskData + (accessAddr % SectorSize), 8); + pkt->set(htobe(d64)); + DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64); break; default: panic("Invalid access size\n"); @@ -100,11 +108,74 @@ MmDisk::read(PacketPtr pkt) Tick MmDisk::write(PacketPtr pkt) { - panic("need to implement\n"); - M5_DUMMY_RETURN + Addr accessAddr; + off_t sector; + off_t bytes_read; + uint16_t d16; + uint32_t d32; + uint64_t d64; + + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + accessAddr = pkt->getAddr() - pioAddr; + + sector = accessAddr / SectorSize; + + if (sector != curSector) { + if (dirty) { + bytes_read = image->write(diskData, curSector); + assert(bytes_read == SectorSize); + } + bytes_read = image->read(diskData, sector); + assert(bytes_read == SectorSize); + curSector = sector; + } + dirty = true; + + switch (pkt->getSize()) { + case sizeof(uint8_t): + diskData[accessAddr % SectorSize] = htobe(pkt->get()); + DPRINTF(IdeDisk, "writing byte %#x value= %#x\n", accessAddr, diskData[accessAddr % + SectorSize]); + break; + case sizeof(uint16_t): + d16 = htobe(pkt->get()); + memcpy(diskData + (accessAddr % SectorSize), &d16, 2); + DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16); + break; + case sizeof(uint32_t): + d32 = htobe(pkt->get()); + memcpy(diskData + (accessAddr % SectorSize), &d32, 4); + DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32); + break; + case sizeof(uint64_t): + d64 = htobe(pkt->get()); + memcpy(diskData + (accessAddr % SectorSize), &d64, 8); + DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64); + break; + default: + panic("Invalid access size\n"); + } + + pkt->result = Packet::Success; + return pioDelay; +} + +void +MmDisk::serialize(std::ostream &os) +{ + // just write any dirty changes to the cow layer it will take care of + // serialization + int bytes_read; + if (dirty) { + bytes_read = image->write(diskData, curSector); + assert(bytes_read == SectorSize); + } } + + BEGIN_DECLARE_SIM_OBJECT_PARAMS(MmDisk) Param pio_addr; Param pio_latency; diff --git a/src/dev/sparc/mm_disk.hh b/src/dev/sparc/mm_disk.hh index 0a4626067..30028d2b6 100644 --- a/src/dev/sparc/mm_disk.hh +++ b/src/dev/sparc/mm_disk.hh @@ -46,10 +46,7 @@ class MmDisk : public BasicPioDevice DiskImage *image; off_t curSector; bool dirty; - union { - uint8_t bytes[SectorSize]; - uint32_t words[SectorSize/4]; - }; + uint8_t diskData[SectorSize]; public: struct Params : public BasicPioDevice::Params @@ -64,6 +61,8 @@ class MmDisk : public BasicPioDevice virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); + + virtual void serialize(std::ostream &os); }; #endif //__DEV_SPARC_MM_DISK_HH__ -- cgit v1.2.3