diff options
200 files changed, 3121 insertions, 1730 deletions
diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index b9eb42a21..67bb0ab3b 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 1a1c738ec..d7004b461 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -440,8 +440,8 @@ AlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const ipr[AlphaISA::IPR_VA] = vaddr; // set MM_STAT register flags - ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) - | ((xc->regs.ra & 0x1f) << 6) + ipr[AlphaISA::IPR_MM_STAT] = (((OPCODE(xc->getInst()) & 0x3f) << 11) + | ((RA(xc->getInst()) & 0x1f) << 6) | (flags & 0x3f)); // set VA_FORM register with faulting formatted address diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 12196c44b..04dd0dcf1 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,10 +80,10 @@ class AlphaTLB : public SimObject class AlphaITB : public AlphaTLB { protected: - mutable Statistics::Scalar<> hits; - mutable Statistics::Scalar<> misses; - mutable Statistics::Scalar<> acv; - mutable Statistics::Formula accesses; + mutable Stats::Scalar<> hits; + mutable Stats::Scalar<> misses; + mutable Stats::Scalar<> acv; + mutable Stats::Formula accesses; protected: void fault(Addr pc, ExecContext *xc) const; @@ -98,18 +98,18 @@ class AlphaITB : public AlphaTLB class AlphaDTB : public AlphaTLB { protected: - mutable Statistics::Scalar<> read_hits; - mutable Statistics::Scalar<> read_misses; - mutable Statistics::Scalar<> read_acv; - mutable Statistics::Scalar<> read_accesses; - mutable Statistics::Scalar<> write_hits; - mutable Statistics::Scalar<> write_misses; - mutable Statistics::Scalar<> write_acv; - mutable Statistics::Scalar<> write_accesses; - Statistics::Formula hits; - Statistics::Formula misses; - Statistics::Formula acv; - Statistics::Formula accesses; + mutable Stats::Scalar<> read_hits; + mutable Stats::Scalar<> read_misses; + mutable Stats::Scalar<> read_acv; + mutable Stats::Scalar<> read_accesses; + mutable Stats::Scalar<> write_hits; + mutable Stats::Scalar<> write_misses; + mutable Stats::Scalar<> write_acv; + mutable Stats::Scalar<> write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula acv; + Stats::Formula accesses; protected: void fault(Addr pc, uint64_t flags, ExecContext *xc) const; diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 2366baed8..149569f14 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index f037a34ac..ecf66f4f5 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -1,15 +1,15 @@ /* $Id$ */ -#include "targetarch/alpha_memory.hh" -#ifdef DEBUG -#include "sim/debug.hh" -#endif +#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/isa_traits.hh" +#include "arch/alpha/osfpal.hh" +#include "base/kgdb.h" +#include "base/remote_gdb.hh" +#include "base/stats/events.hh" #include "cpu/exec_context.hh" +#include "cpu/fast_cpu/fast_cpu.hh" +#include "sim/debug.hh" #include "sim/sim_events.hh" -#include "targetarch/isa_traits.hh" -#include "base/remote_gdb.hh" -#include "base/kgdb.h" // for ALPHA_KENTRY_IF -#include "targetarch/osfpal.hh" #ifdef FULL_SYSTEM @@ -99,9 +99,71 @@ AlphaISA::initIPRs(RegFile *regs) } +template <class XC> +void +AlphaISA::processInterrupts(XC *xc) +{ + //Check if there are any outstanding interrupts + //Handle the interrupts + int ipl = 0; + int summary = 0; + IntReg *ipr = xc->getIprPtr(); + + check_interrupts = 0; + + if (ipr[IPR_ASTRR]) + panic("asynchronous traps not implemented\n"); + + if (ipr[IPR_SIRR]) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (ipr[IPR_SIRR] & (ULL(1) << i)) { + // See table 4-19 of the 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); + } + } + } + + uint64_t interrupts = xc->intr_status(); + + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of the 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } + } + } + + if (ipl && ipl > ipr[IPR_IPLR]) { + ipr[IPR_ISR] = summary; + ipr[IPR_INTID] = ipl; + xc->trap(Interrupt_Fault); + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + ipr[IPR_IPLR], ipl, summary); + } + +} + +template <class XC> +void +AlphaISA::zeroRegisters(XC *xc) +{ + // Insure ISA semantics + // (no longer very clean due to the change in setIntReg() in the + // cpu model. Consider changing later.) + xc->xc->setIntReg(ZeroReg, 0); + xc->xc->setFloatRegDouble(ZeroReg, 0.0); +} + void ExecContext::ev5_trap(Fault fault) { + Stats::recordEvent(csprintf("Fault %s", FaultName(fault))); + assert(!misspeculating()); kernelStats.fault(fault); @@ -581,4 +643,12 @@ ExecContext::simPalCheck(int palFunc) return true; } +//Forward instantiation for FastCPU object +template +void AlphaISA::processInterrupts(FastCPU *xc); + +//Forward instantiation for FastCPU object +template +void AlphaISA::zeroRegisters(FastCPU *xc); + #endif // FULL_SYSTEM diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index 636e37adb..517e1111f 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -75,6 +75,8 @@ #define MM_STAT_ACV_MASK 0x0002 #define MM_STAT_WR_MASK 0x0001 +#define OPCODE(X) (X >> 26) & 0x3f +#define RA(X) (X >> 21) & 0x1f //////////////////////////////////////////////////////////////////////// // diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 33aa55439..45ac122dc 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index f964101df..080699ddb 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -811,7 +811,7 @@ output header {{ public: /// Constructor EACompBase(MachInst machInst) - : AlphaStaticInst("(eacomp)", machInst, IntALU) + : AlphaStaticInst("(eacomp)", machInst, IntAluOp) { } @@ -1072,7 +1072,7 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ # Declare the prefetch instruction object. # convert flags from tuple to list to make them mutable - pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'RdPort'] + pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ LoadStoreBase(name, Name + 'Prefetch', ea_code, '', @@ -1374,8 +1374,8 @@ output decoder {{ } }}; -def format EmulatedCallPal(code) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code)) +def format EmulatedCallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1436,8 +1436,8 @@ output decoder {{ } }}; -def format CallPal(code) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code)) +def format CallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1588,6 +1588,9 @@ output header {{ FailUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1615,6 +1618,9 @@ output header {{ WarnUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1646,9 +1652,8 @@ output exec {{ FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); return Unimplemented_Opcode_Fault; } @@ -1656,42 +1661,24 @@ output exec {{ WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); - warned = true; - } + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } return No_Fault; } }}; -def template WarnUnimplDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - /// Constructor - %(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst) - { - } - }; -}}; - - def format FailUnimpl() {{ iop = InstObjParams(name, 'FailUnimplemented') decode_block = BasicDecodeWithMnemonic.subst(iop) }}; def format WarnUnimpl() {{ - iop = InstObjParams(name, Name, 'WarnUnimplemented') - header_output = WarnUnimplDeclare.subst(iop) - decode_block = BasicDecode.subst(iop) + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) }}; output header {{ @@ -1707,6 +1694,9 @@ output header {{ Unknown(MachInst _machInst) : AlphaStaticInst("unknown", _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1733,9 +1723,8 @@ output exec {{ Fault Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); return Unimplemented_Opcode_Fault; } }}; @@ -2094,13 +2083,13 @@ decode OPCODE default Unknown::unknown() { } 0x13: decode INTFUNC { // integer multiplies - 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMULT); - 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMULT); + 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); + 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); 0x30: umulh({{ uint64_t hi, lo; mul128(Ra, Rb_or_imm, hi, lo); Rc = hi; - }}, IntMULT); + }}, IntMultOp); 0x40: mullv({{ // 32-bit multiply with trap on overflow int64_t Rax = Ra.sl; // sign extended version of Ra.sl @@ -2113,7 +2102,7 @@ decode OPCODE default Unknown::unknown() { if (sign_bits != 0 && sign_bits != mask(33)) fault = Integer_Overflow_Fault; Rc.sl = tmp<31:0>; - }}, IntMULT); + }}, IntMultOp); 0x60: mulqv({{ // 64-bit multiply with trap on overflow uint64_t hi, lo; @@ -2124,18 +2113,40 @@ decode OPCODE default Unknown::unknown() { (hi == mask(64) && lo<63:> == 1))) fault = Integer_Overflow_Fault; Rc = lo; - }}, IntMULT); + }}, IntMultOp); } 0x1c: decode INTFUNC { 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } + 0x32: ctlz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (temp<63:32>) temp >>= 32; else count += 32; + if (temp<31:16>) temp >>= 16; else count += 16; + if (temp<15:8>) temp >>= 8; else count += 8; + if (temp<7:4>) temp >>= 4; else count += 4; + if (temp<3:2>) temp >>= 2; else count += 2; + if (temp<1:1>) temp >>= 1; else count += 1; + if ((temp<0:0>) != 0x1) count += 1; + Rc = count; + }}, IntAluOp); + + 0x33: cttz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (!(temp<31:0>)) { temp >>= 32; count += 32; } + if (!(temp<15:0>)) { temp >>= 16; count += 16; } + if (!(temp<7:0>)) { temp >>= 8; count += 8; } + if (!(temp<3:0>)) { temp >>= 4; count += 4; } + if (!(temp<1:0>)) { temp >>= 2; count += 2; } + if (!(temp<0:0> & ULL(0x1))) count += 1; + Rc = count; + }}, IntAluOp); format FailUnimpl { 0x30: ctpop(); 0x31: perr(); - 0x32: ctlz(); - 0x33: cttz(); 0x34: unpkbw(); 0x35: unpkbl(); 0x36: pkwb(); @@ -2152,11 +2163,11 @@ decode OPCODE default Unknown::unknown() { format BasicOperateWithNopCheck { 0x70: decode RB { - 31: ftoit({{ Rc = Fa.uq; }}, FloatCVT); + 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); } 0x78: decode RB { 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, - FloatCVT); + FloatCvtOp); } } } @@ -2203,8 +2214,8 @@ decode OPCODE default Unknown::unknown() { 0x4: decode RB { 31: decode FP_FULLFUNC { format BasicOperateWithNopCheck { - 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCVT); - 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCVT); + 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); + 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); 0x014: FailUnimpl::itoff(); // VAX-format conversion } } @@ -2219,19 +2230,19 @@ decode OPCODE default Unknown::unknown() { if (Fb < 0.0) fault = Arithmetic_Fault; Fc = sqrt(Fb); - }}, FloatSQRT); + }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) fault = Arithmetic_Fault; Fc.sf = sqrt(Fb.sf); - }}, FloatSQRT); + }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) fault = Arithmetic_Fault; Fc = sqrt(Fb); - }}, FloatSQRT); + }}, FloatSqrtOp); } } } @@ -2257,19 +2268,19 @@ decode OPCODE default Unknown::unknown() { #ifdef SS_COMPATIBLE_FP 0x00: adds({{ Fc = Fa + Fb; }}); 0x01: subs({{ Fc = Fa - Fb; }}); - 0x02: muls({{ Fc = Fa * Fb; }}, FloatMULT); - 0x03: divs({{ Fc = Fa / Fb; }}, FloatDIV); + 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); #else 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); - 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMULT); - 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDIV); + 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); + 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); #endif 0x20: addt({{ Fc = Fa + Fb; }}); 0x21: subt({{ Fc = Fa - Fb; }}); - 0x22: mult({{ Fc = Fa * Fb; }}, FloatMULT); - 0x23: divt({{ Fc = Fa / Fb; }}, FloatDIV); + 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); } } @@ -2283,14 +2294,14 @@ decode OPCODE default Unknown::unknown() { 1: decode FP_FULLFUNC { format BasicOperateWithNopCheck { 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, - FloatCMP); + FloatCmpOp); 0x0a4, 0x5a4: cmptun({{ // unordered Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; - }}, FloatCMP); + }}, FloatCmpOp); } } @@ -2382,7 +2393,7 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb; }}, {{ xc->writeHint(EA, 64); }}, - IsMemRef, IsStore, WrPort); + IsMemRef, IsStore, MemWriteOp); } format BasicOperate { @@ -2412,24 +2423,20 @@ decode OPCODE default Unknown::unknown() { // them the same though. 0x0000: trapb({{ }}, IsSerializing, No_OpClass); 0x0400: excb({{ }}, IsSerializing, No_OpClass); - 0x4000: mb({{ }}, IsMemBarrier, RdPort); - 0x4400: wmb({{ }}, IsWriteBarrier, WrPort); + 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); + 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); } #ifdef FULL_SYSTEM format BasicOperate { 0xe000: rc({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(0); - } - }}); + xc->setIntrFlag(0); + }}, IsNonSpeculative); 0xf000: rs({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(1); - } - }}); + xc->setIntrFlag(1); + }}, IsNonSpeculative); } #else format FailUnimpl { @@ -2449,38 +2456,26 @@ decode OPCODE default Unknown::unknown() { fault = Unimplemented_Opcode_Fault; } else { - bool dopal = true; - - if (!xc->misspeculating()) { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - dopal = xc->simPalCheck(palFunc); - - if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - } - } + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); - // if we're misspeculating, it's still safe (if - // unrealistic) to set NPC, as the control-flow change - // won't get committed. if (dopal) { + AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } } - }}); + }}, IsNonSpeculative); #else 0x00: decode PALFUNC { format EmulatedCallPal { 0x00: halt ({{ - if (!xc->misspeculating()) - SimExit(curTick, "halt instruction encountered"); - }}); + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); 0x83: callsys({{ - if (!xc->misspeculating()) - xc->syscall(); - }}); + xc->syscall(); + }}, IsNonSpeculative); // Read uniq reg into ABI return value register (r0) 0x9e: rduniq({{ R0 = Runiq; }}); // Write uniq reg with value from ABI arg register (r16) @@ -2514,46 +2509,36 @@ decode OPCODE default Unknown::unknown() { // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { 0x00: arm({{ - if (!xc->misspeculating()) - AlphaPseudo::arm(xc->xcBase()); - }}); + AlphaPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); 0x01: quiesce({{ - if (!xc->misspeculating()) - AlphaPseudo::quiesce(xc->xcBase()); - }}); + AlphaPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); 0x10: ivlb({{ - if (!xc->misspeculating()) - AlphaPseudo::ivlb(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x11: ivle({{ - if (!xc->misspeculating()) - AlphaPseudo::ivle(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x20: m5exit_old({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); 0x40: resetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::resetstats(xc->xcBase()); - }}); + AlphaPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x41: dumpstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpstats(xc->xcBase()); - }}); + AlphaPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); 0x42: dumpresetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpresetstats(xc->xcBase()); - }}); + AlphaPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x43: m5checkpoint({{ - if (!xc->misspeculating()) - AlphaPseudo::m5checkpoint(xc->xcBase()); - }}); + AlphaPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); } } diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 05ab89978..179e9897f 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,6 +33,7 @@ #include "targetarch/faults.hh" #include "base/misc.hh" +class FastCPU; class FullCPU; class Checkpoint; @@ -156,8 +157,6 @@ class AlphaISA int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers #endif // FULL_SYSTEM - // Are these architectural, or just for convenience? - uint8_t opcode, ra; // current instruction details (for intr's) void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); @@ -233,6 +232,13 @@ class AlphaISA ConfigNode *node, RegFile ®s); #endif + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template <class XC> + static void zeroRegisters(XC *xc); }; diff --git a/arch/alpha/osfpal.cc b/arch/alpha/osfpal.cc index 90d645ef1..2717079ab 100644 --- a/arch/alpha/osfpal.cc +++ b/arch/alpha/osfpal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/osfpal.hh b/arch/alpha/osfpal.hh index 419235b4a..2a835633f 100644 --- a/arch/alpha/osfpal.hh +++ b/arch/alpha/osfpal.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc index 0a5c5b006..f4201ab09 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/arch/alpha/pseudo_inst.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ #include "sim/stats.hh" using namespace std; -using namespace Statistics; +using namespace Stats; namespace AlphaPseudo { @@ -98,7 +98,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Reset, when, repeat); } @@ -114,7 +114,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Dump, when, repeat); } @@ -130,7 +130,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Dump|Reset, when, repeat); } diff --git a/arch/alpha/pseudo_inst.hh b/arch/alpha/pseudo_inst.hh index e5551a44b..e59487397 100644 --- a/arch/alpha/pseudo_inst.hh +++ b/arch/alpha/pseudo_inst.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/vptr.hh b/arch/alpha/vptr.hh index 7f0b036a3..cd4bc547b 100644 --- a/arch/alpha/vptr.hh +++ b/arch/alpha/vptr.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index d91d80c83..cf2ebbf80 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index f5696e9c8..497a53f0d 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 621720709..011ce7623 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -630,6 +630,9 @@ class CpuModel: CpuModel('SimpleCPU', 'simple_cpu_exec.cc', '#include "cpu/simple_cpu/simple_cpu.hh"', { 'CPU_exec_context': 'SimpleCPU' }) +CpuModel('FastCPU', 'fast_cpu_exec.cc', + '#include "cpu/fast_cpu/fast_cpu.hh"', + { 'CPU_exec_context': 'FastCPU' }) CpuModel('FullCPU', 'full_cpu_exec.cc', '#include "cpu/full_cpu/dyn_inst.hh"', { 'CPU_exec_context': 'DynInst' }) @@ -1057,10 +1060,10 @@ class IntRegOperandTraits(OperandTraits): if (type == 'float' or type == 'double'): error(0, 'Attempt to read integer register as FP') if (size == self.dflt_size): - return '%s = xc->readIntReg(_srcRegIdx[%d]);\n' % \ + return '%s = xc->readIntReg(this, %d);\n' % \ (op_desc.munged_name, op_desc.src_reg_idx) else: - return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \ + return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ (op_desc.munged_name, op_desc.src_reg_idx, size-1) def makeWrite(self, op_desc): @@ -1074,7 +1077,7 @@ class IntRegOperandTraits(OperandTraits): wb = ''' { %s final_val = %s; - xc->setIntReg(_destRegIdx[%d], final_val);\n + xc->setIntReg(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (self.dflt_type, final_val, op_desc.dest_reg_idx) return wb @@ -1107,7 +1110,7 @@ class FloatRegOperandTraits(OperandTraits): func = 'readFloatRegInt' if (size != self.dflt_size): bit_select = 1 - base = 'xc->%s(_srcRegIdx[%d] - FP_Base_DepTag)' % \ + base = 'xc->%s(this, %d)' % \ (func, op_desc.src_reg_idx) if bit_select: return '%s = bits(%s, %d, 0);\n' % \ @@ -1130,7 +1133,7 @@ class FloatRegOperandTraits(OperandTraits): wb = ''' { %s final_val = %s; - xc->%s(_destRegIdx[%d] - FP_Base_DepTag, final_val);\n + xc->%s(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (type, final_val, func, op_desc.dest_reg_idx) return wb @@ -1490,19 +1493,19 @@ class CodeBlock: # These are good enough for most cases, and will be overridden # later otherwise. if 'IsStore' in self.flags: - self.op_class = 'WrPort' + self.op_class = 'MemWriteOp' elif 'IsLoad' in self.flags or 'IsPrefetch' in self.flags: - self.op_class = 'RdPort' + self.op_class = 'MemReadOp' elif 'IsFloating' in self.flags: - self.op_class = 'FloatADD' + self.op_class = 'FloatAddOp' else: - self.op_class = 'IntALU' + self.op_class = 'IntAluOp' # Assume all instruction flags are of the form 'IsFoo' instFlagRE = re.compile(r'Is.*') -# OpClass constants are just a little more complicated -opClassRE = re.compile(r'Int.*|Float.*|.*Port|No_OpClass') +# OpClass constants end in 'Op' except No_OpClass +opClassRE = re.compile(r'.*Op|No_OpClass') class InstObjParams: def __init__(self, mnem, class_name, base_class = '', diff --git a/base/circlebuf.cc b/base/circlebuf.cc index 7bd488ef8..2d77c9482 100644 --- a/base/circlebuf.cc +++ b/base/circlebuf.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/circlebuf.hh b/base/circlebuf.hh index 168158bb7..7549672ab 100644 --- a/base/circlebuf.hh +++ b/base/circlebuf.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/compression/lzss_compression.cc b/base/compression/lzss_compression.cc index 2f6c5d338..46f1b0266 100644 --- a/base/compression/lzss_compression.cc +++ b/base/compression/lzss_compression.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/compression/lzss_compression.hh b/base/compression/lzss_compression.hh index 9707a8aca..e5e8c8da4 100644 --- a/base/compression/lzss_compression.hh +++ b/base/compression/lzss_compression.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/compression/null_compression.hh b/base/compression/null_compression.hh index 6a630b113..195498f1b 100644 --- a/base/compression/null_compression.hh +++ b/base/compression/null_compression.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/cprintf.cc b/base/cprintf.cc index 5cbf0c057..2c8402c9b 100644 --- a/base/cprintf.cc +++ b/base/cprintf.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/cprintf.hh b/base/cprintf.hh index ca5c08b16..a3a621785 100644 --- a/base/cprintf.hh +++ b/base/cprintf.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/cprintf_formats.hh b/base/cprintf_formats.hh index 120dd94b1..b9131310a 100644 --- a/base/cprintf_formats.hh +++ b/base/cprintf_formats.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/dbl_list.hh b/base/dbl_list.hh index 4f6d61a45..1b0478d55 100644 --- a/base/dbl_list.hh +++ b/base/dbl_list.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2001, 2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/fast_alloc.cc b/base/fast_alloc.cc index abb50aa0c..d1e6cfdf1 100644 --- a/base/fast_alloc.cc +++ b/base/fast_alloc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/fast_alloc.hh b/base/fast_alloc.hh index 81f2f1359..4536284df 100644 --- a/base/fast_alloc.hh +++ b/base/fast_alloc.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2001, 2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/fifo_buffer.cc b/base/fifo_buffer.cc index d103d2e60..0fb8458d7 100644 --- a/base/fifo_buffer.cc +++ b/base/fifo_buffer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/fifo_buffer.hh b/base/fifo_buffer.hh index 767db03a4..c51b0394e 100644 --- a/base/fifo_buffer.hh +++ b/base/fifo_buffer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/hashmap.hh b/base/hashmap.hh index 59c1fe3aa..4584813dd 100644 --- a/base/hashmap.hh +++ b/base/hashmap.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/hybrid_pred.cc b/base/hybrid_pred.cc index 12bab975b..d20bf6e51 100644 --- a/base/hybrid_pred.cc +++ b/base/hybrid_pred.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,7 +63,7 @@ HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name, void HybridPredictor::regStats() { - using namespace Statistics; + using namespace Stats; string p_name; stringstream description; @@ -148,7 +148,7 @@ void HybridPredictor::regStats() void HybridPredictor::regFormulas() { - using namespace Statistics; + using namespace Stats; string p_name; stringstream description; diff --git a/base/hybrid_pred.hh b/base/hybrid_pred.hh index 9063f3084..f81faf865 100644 --- a/base/hybrid_pred.hh +++ b/base/hybrid_pred.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,22 +59,22 @@ class HybridPredictor : public GenericPredictor // // Stats // - Statistics::Scalar<> pred_one; //num_one_preds - Statistics::Scalar<> pred_zero; //num_zero_preds - Statistics::Scalar<> correct_pred_one; //num_one_correct - Statistics::Scalar<> correct_pred_zero; //num_zero_correct - Statistics::Scalar<> record_one; //num_one_updates - Statistics::Scalar<> record_zero; //num_zero_updates - - Statistics::Formula total_preds; - Statistics::Formula frac_preds_zero; - Statistics::Formula frac_preds_one; - Statistics::Formula total_correct; - Statistics::Formula total_accuracy; - Statistics::Formula zero_accuracy; - Statistics::Formula one_accuracy; - Statistics::Formula zero_coverage; - Statistics::Formula one_coverage; + Stats::Scalar<> pred_one; //num_one_preds + Stats::Scalar<> pred_zero; //num_zero_preds + Stats::Scalar<> correct_pred_one; //num_one_correct + Stats::Scalar<> correct_pred_zero; //num_zero_correct + Stats::Scalar<> record_one; //num_one_updates + Stats::Scalar<> record_zero; //num_zero_updates + + Stats::Formula total_preds; + Stats::Formula frac_preds_zero; + Stats::Formula frac_preds_one; + Stats::Formula total_correct; + Stats::Formula total_accuracy; + Stats::Formula zero_accuracy; + Stats::Formula one_accuracy; + Stats::Formula zero_coverage; + Stats::Formula one_coverage; public: HybridPredictor(const char *_p_name, const char *_z_name, diff --git a/base/inet.cc b/base/inet.cc index 46aa027fc..e2bdd19ff 100644 --- a/base/inet.cc +++ b/base/inet.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/inet.hh b/base/inet.hh index 1ae2e8542..67ac5a504 100644 --- a/base/inet.hh +++ b/base/inet.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/inifile.cc b/base/inifile.cc index 001e0a6f8..7f6a42dd6 100644 --- a/base/inifile.cc +++ b/base/inifile.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/inifile.hh b/base/inifile.hh index f7229f2f2..01e4e6c17 100644 --- a/base/inifile.hh +++ b/base/inifile.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/intmath.cc b/base/intmath.cc index 2e220aa3b..f84e124fb 100644 --- a/base/intmath.cc +++ b/base/intmath.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001, 2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/intmath.hh b/base/intmath.hh index 28e9d5c68..fc28eecef 100644 --- a/base/intmath.hh +++ b/base/intmath.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001, 2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 5a8f937cc..b8f46449a 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/elf_object.hh b/base/loader/elf_object.hh index 35a6c6d6e..9ae587e9c 100644 --- a/base/loader/elf_object.hh +++ b/base/loader/elf_object.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/object_file.cc b/base/loader/object_file.cc index 25e9b2d19..2eeace36d 100644 --- a/base/loader/object_file.cc +++ b/base/loader/object_file.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index a29bdc153..740cd1b40 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/symtab.cc b/base/loader/symtab.cc index cb18d499c..f6abf7e3d 100644 --- a/base/loader/symtab.cc +++ b/base/loader/symtab.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh index 1502e4250..48230c7a2 100644 --- a/base/loader/symtab.hh +++ b/base/loader/symtab.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/misc.cc b/base/misc.cc index 5caf96d40..075ed2af8 100644 --- a/base/misc.cc +++ b/base/misc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/misc.hh b/base/misc.hh index 45e6db35c..a4f9a99c5 100644 --- a/base/misc.hh +++ b/base/misc.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/mod_num.hh b/base/mod_num.hh index 3b4ef9bb8..831be6b03 100644 --- a/base/mod_num.hh +++ b/base/mod_num.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/pollevent.cc b/base/pollevent.cc index 60a20bd2e..127bf57f5 100644 --- a/base/pollevent.cc +++ b/base/pollevent.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/pollevent.hh b/base/pollevent.hh index 7ea5b83f4..3c9404c08 100644 --- a/base/pollevent.hh +++ b/base/pollevent.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/predictor.hh b/base/predictor.hh index 3b7bd686e..7492273ca 100644 --- a/base/predictor.hh +++ b/base/predictor.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/range.cc b/base/range.cc index 0a4876e89..4453ecc9f 100644 --- a/base/range.cc +++ b/base/range.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/range.hh b/base/range.hh index 2c4a43f48..2197e2f86 100644 --- a/base/range.hh +++ b/base/range.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/refcnt.hh b/base/refcnt.hh index f3e0e4114..d308dd0cf 100644 --- a/base/refcnt.hh +++ b/base/refcnt.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 7b73d60e9..41f11005d 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -344,6 +344,13 @@ RemoteGDB::acc(Addr va, size_t len) } } + /** + * This code says that all accesses to palcode (instruction and data) + * are valid since there isn't a va->pa mapping because palcode is + * accessed physically. At some point this should probably be cleaned up + * but there is no easy way to do it. + */ + if (PC_PAL(va) || va < 0x10000) return true; diff --git a/base/remote_gdb.hh b/base/remote_gdb.hh index fcc1ee2a9..2ed368719 100644 --- a/base/remote_gdb.hh +++ b/base/remote_gdb.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/res_list.hh b/base/res_list.hh index 04c3b7cfa..7080a3ba7 100644 --- a/base/res_list.hh +++ b/base/res_list.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/sat_counter.cc b/base/sat_counter.cc index a8367d8a0..32b5a9f3e 100644 --- a/base/sat_counter.cc +++ b/base/sat_counter.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,7 +69,7 @@ SaturatingCounterPred::SaturatingCounterPred(string p_name, void SaturatingCounterPred::regStats() { - using namespace Statistics; + using namespace Stats; stringstream name, description; // @@ -138,7 +138,7 @@ void SaturatingCounterPred::regStats() void SaturatingCounterPred::regFormulas() { - using namespace Statistics; + using namespace Stats; stringstream name, description; // diff --git a/base/sat_counter.hh b/base/sat_counter.hh index a5d9c7e8a..b5054bed7 100644 --- a/base/sat_counter.hh +++ b/base/sat_counter.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,24 +61,24 @@ class SaturatingCounterPred : public GenericPredictor unsigned *table; // Statistics - Statistics::Scalar<> predicted_one; // Total predictions of one, preds_one - Statistics::Scalar<> predicted_zero; // Total predictions of zero, preds_zero - Statistics::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one - Statistics::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero - - Statistics::Scalar<> record_zero; //updates_zero - Statistics::Scalar<> record_one; //updates_one - - Statistics::Formula preds_total; - Statistics::Formula pred_frac_zero; - Statistics::Formula pred_frac_one; - Statistics::Formula correct_total; - Statistics::Formula updates_total; - Statistics::Formula pred_rate; - Statistics::Formula frac_correct_zero; - Statistics::Formula frac_correct_one; - Statistics::Formula coverage_zero; - Statistics::Formula coverage_one; + Stats::Scalar<> predicted_one; // Total predictions of one, preds_one + Stats::Scalar<> predicted_zero; // Total predictions of zero, preds_zero + Stats::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one + Stats::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero + + Stats::Scalar<> record_zero; //updates_zero + Stats::Scalar<> record_one; //updates_one + + Stats::Formula preds_total; + Stats::Formula pred_frac_zero; + Stats::Formula pred_frac_one; + Stats::Formula correct_total; + Stats::Formula updates_total; + Stats::Formula pred_rate; + Stats::Formula frac_correct_zero; + Stats::Formula frac_correct_one; + Stats::Formula coverage_zero; + Stats::Formula coverage_one; private: bool pred_one(unsigned &counter) { return counter > thresh; } diff --git a/base/sched_list.hh b/base/sched_list.hh index 0f922d63c..86e342ae1 100644 --- a/base/sched_list.hh +++ b/base/sched_list.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/socket.cc b/base/socket.cc index 63b693d94..aa6a183a9 100644 --- a/base/socket.cc +++ b/base/socket.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/socket.hh b/base/socket.hh index 39bacba94..361658720 100644 --- a/base/socket.hh +++ b/base/socket.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/statistics.cc b/base/statistics.cc index 1a44cd342..78012bff7 100644 --- a/base/statistics.cc +++ b/base/statistics.cc @@ -46,7 +46,7 @@ using namespace std; -namespace Statistics { +namespace Stats { StatData * DataAccess::find() const @@ -346,4 +346,4 @@ registerResetCallback(Callback *cb) resetQueue.add(cb); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/statistics.hh b/base/statistics.hh index ee09cc622..bd1698ae7 100644 --- a/base/statistics.hh +++ b/base/statistics.hh @@ -70,7 +70,7 @@ class Callback; extern Tick curTick; /* A namespace for all of the Statistics */ -namespace Statistics { +namespace Stats { /* Contains the statistic implementation details */ ////////////////////////////////////////////////////////////////////// @@ -2897,6 +2897,6 @@ sum(Temp val) return NodePtr(new SumNode<std::plus<Result> >(val)); } -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATISTICS_HH__ diff --git a/base/stats/events.cc b/base/stats/events.cc new file mode 100644 index 000000000..b579981e9 --- /dev/null +++ b/base/stats/events.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifdef USE_MYSQL +#include "base/cprintf.hh" +#include "base/misc.hh" +#include "base/mysql.hh" +#include "base/stats/events.hh" +#include "base/stats/mysql.hh" +#include "base/stats/mysql_run.hh" +#include "base/str.hh" +#endif + +#include "sim/host.hh" +#include "sim/universe.hh" + +using namespace std; + +namespace Stats { + +Tick EventStart = ULL(0xffffffffffffffff); + +#ifdef USE_MYSQL +typedef map<string, uint32_t> event_map_t; +event_map_t event_map; + +void +__event(const string &stat) +{ + MySQL::Connection &mysql = MySqlDB.conn(); + uint16_t run = MySqlDB.run(); + assert(mysql.connected()); + + event_map_t::iterator i = event_map.find(stat); + uint32_t event; + if (i == event_map.end()) { + mysql.query( + csprintf("SELECT en_id " + "from event_names " + "where en_name=\"%s\"", + stat)); + + MySQL::Result result = mysql.store_result(); + if (!result) + panic("could not get a run\n%s\n", mysql.error); + + assert(result.num_fields() == 1); + MySQL::Row row = result.fetch_row(); + if (row) { + if (!to_number(row[0], event)) + panic("invalid event id: %s\n", row[0]); + } else { + mysql.query( + csprintf("INSERT INTO " + "event_names(en_name)" + "values(\"%s\")", + stat)); + + if (mysql.error) + panic("could not get a run\n%s\n", mysql.error); + + event = mysql.insert_id(); + } + } else { + event = (*i).second; + } + + mysql.query( + csprintf("INSERT INTO " + "events(ev_event, ev_run, ev_tick)" + "values(%d, %d, %d)", + event, run, curTick)); + + if (mysql.error) + panic("could not get a run\n%s\n", mysql.error); + +} +#endif + +/* namespace Stats */ } diff --git a/base/stats/events.hh b/base/stats/events.hh new file mode 100644 index 000000000..49c060645 --- /dev/null +++ b/base/stats/events.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifndef __BASE_STATS_EVENTS_HH__ +#define __BASE_STATS_EVENTS_HH__ + +#include <string> + +#include "base/trace.hh" + +namespace Stats { + +extern Tick EventStart; + +#ifdef USE_MYSQL +void __event(const std::string &stat); +bool MySqlConnected(); +#endif + +inline void +recordEvent(const std::string &stat) +{ + if (EventStart > curTick) + return; + + DPRINTF(StatEvents, "Statistics Event: %s\n", stat); + +#ifdef USE_MYSQL + if (!MySqlConnected()) + return; + + __event(stat); +#endif +} + +/* namespace Stats */ } + +#endif // __BASE_STATS_EVENTS_HH__ diff --git a/base/stats/flags.hh b/base/stats/flags.hh index 2303de172..b86f87d25 100644 --- a/base/stats/flags.hh +++ b/base/stats/flags.hh @@ -28,7 +28,7 @@ #ifndef __BASE_STATS_FLAGS_HH__ #define __BASE_STATS_FLAGS_HH__ -namespace Statistics { +namespace Stats { /** * Define the storage for format flags. @@ -68,6 +68,6 @@ enum DisplayMode extern DisplayMode DefaultMode; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_FLAGS_HH__ diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc index 676bc555c..42f68811b 100644 --- a/base/stats/mysql.cc +++ b/base/stats/mysql.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ #include "base/statistics.hh" #include "base/stats/flags.hh" #include "base/stats/mysql.hh" +#include "base/stats/mysql_run.hh" #include "base/stats/statdb.hh" #include "base/stats/types.hh" #include "base/str.hh" @@ -44,19 +45,35 @@ using namespace std; -namespace Statistics { +namespace Stats { -struct MySqlData +MySqlRun MySqlDB; + +bool +MySqlConnected() { - map<int, int> idmap; - MySQL::Connection conn; -}; + return MySqlDB.connected(); +} + +void +MySqlRun::connect(const string &host, const string &user, const string &passwd, + const string &db, const string &name, const string &project) +{ + if (connected()) + panic("can only get one database connection at this time!"); -int -SetupRun(MySqlData *data, const string &name, const string &user, - const string &project) + mysql.connect(host, user, passwd, db); + if (mysql.error) + panic("could not connect to database server\n%s\n", mysql.error); + + remove(name); + cleanup(); + setup(name, user, project); +} + +void +MySqlRun::setup(const string &name, const string &user, const string &project) { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); stringstream insert; @@ -71,13 +88,12 @@ SetupRun(MySqlData *data, const string &name, const string &user, if (mysql.error) panic("could not get a run\n%s\n", mysql.error); - return mysql.insert_id(); + run_id = mysql.insert_id(); } void -DeleteRun(MySqlData *data, const string &name) +MySqlRun::remove(const string &name) { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); stringstream sql; ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name); @@ -85,9 +101,8 @@ DeleteRun(MySqlData *data, const string &name) } void -Cleanup(MySqlData *data) +MySqlRun::cleanup() { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); mysql.query("DELETE data " @@ -119,6 +134,16 @@ Cleanup(MySqlData *data) "FROM bins " "LEFT JOIN data ON bn_id=dt_bin " "WHERE dt_bin IS NULL"); + + mysql.query("DELETE events" + "FROM events" + "LEFT JOIN runs ON ev_run=rn_id" + "WHERE rn_id IS NULL"); + + mysql.query("DELETE event_names" + "FROM event_names" + "LEFT JOIN events ON en_id=ev_event" + "WHERE ev_event IS NULL"); } void @@ -142,9 +167,9 @@ SetupStat::init() } unsigned -SetupStat::operator()(MySqlData *data) +SetupStat::setup() { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); stringstream insert; ccprintf(insert, @@ -245,9 +270,9 @@ SetupStat::operator()(MySqlData *data) } unsigned -SetupBin(MySqlData *data, const string &bin) +SetupBin(const string &bin) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); using namespace MySQL; @@ -292,8 +317,9 @@ void InsertData::flush() { if (size) { - assert(mysql && mysql->connected()); - mysql->query(query); + MySQL::Connection &mysql = MySqlDB.conn(); + assert(mysql.connected()); + mysql.query(query); } query[0] = '\0'; @@ -319,7 +345,8 @@ InsertData::insert() first = false; size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")", - stat, x, y, run, (unsigned long long)sample, bin, data); + stat, x, y, MySqlDB.run(), (unsigned long long)sample, + bin, data); } struct InsertSubData @@ -330,13 +357,13 @@ struct InsertSubData string name; string descr; - void operator()(MySqlData *data); + void setup(); }; void -InsertSubData::operator()(MySqlData *data) +InsertSubData::setup() { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream insert; ccprintf(insert, @@ -348,10 +375,9 @@ InsertSubData::operator()(MySqlData *data) } void -InsertFormula(MySqlData *data, uint16_t stat, uint16_t run, - const string &formula) +InsertFormula(uint16_t stat, const string &formula) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream insert_formula; ccprintf(insert_formula, @@ -363,15 +389,15 @@ InsertFormula(MySqlData *data, uint16_t stat, uint16_t run, stringstream insert_ref; ccprintf(insert_ref, "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)", - stat, run); + stat, MySqlDB.run()); mysql.query(insert_ref); } void -UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq) +UpdatePrereq(uint16_t stat, uint16_t prereq) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream update; ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d", @@ -379,98 +405,6 @@ UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq) mysql.query(update); } -#if 0 -class InsertData -{ - private: - MySQL::Connection &mysql; - MySQL::Statement stmt; - - public: - InsertData(MySqlData *data) - : mysql(data->conn) - { - stmt.prepare("INSERT INTO " - "data(dt_stat,dt_x,dt_y,dt_run,dt_sample,dt_bin,dt_data) " - "values(?,?,?,?,?,?,?)"); - assert(stmt.count() == 7 && "param count invalid"); - - stmt[0].buffer = stat; - stmt[1].buffer = x; - stmt[2].buffer = y; - stmt[3].buffer = run; - stmt[4].buffer = sample; - stmt[5].buffer = bin; - stmt[6].buffer = data; - - stmt.bind(bind); - if (stmt.error) - panic("bind param failed\n%s\n", stmt.error); - } - - public: - uint64_t sample; - uint64_t data; - uint16_t stat; - uint16_t bin; - int16_t x; - int16_t y; - - void operator()(MySQL::Connection &mysql) - { - assert(mysql.connected()) - stmt(); - } -}; -#endif - - -MySql::MySql() - : mysql(NULL), configured(false) -{ -} - -MySql::~MySql() -{ - if (mysql) - delete mysql; -} - -void -MySql::insert(int sim_id, int db_id) -{ - mysql->idmap.insert(make_pair(sim_id, db_id)); -} - -int -MySql::find(int sim_id) -{ - map<int,int>::const_iterator i = mysql->idmap.find(sim_id); - assert(i != mysql->idmap.end()); - return (*i).second; -} - -bool -MySql::valid() const -{ - return mysql && mysql->conn.connected(); -} - -void -MySql::connect(const string &host, const string &user, const string &passwd, - const string &db, const string &name, const string &project) -{ - mysql = new MySqlData; - newdata.mysql = &mysql->conn; - mysql->conn.connect(host, user, passwd, db); - if (mysql->conn.error) - panic("could not connect to database server\n%s\n", mysql->conn.error); - - DeleteRun(mysql, name); - Cleanup(mysql); - run_id = SetupRun(mysql, name, user, project); -} - void MySql::configure() { @@ -489,7 +423,7 @@ MySql::configure() uint16_t prereq_id = find(data->prereq->id); assert(stat_id && prereq_id); - UpdatePrereq(mysql, stat_id, prereq_id); + UpdatePrereq(stat_id, prereq_id); } } @@ -517,14 +451,14 @@ void MySql::configure(const ScalarData &data) { configure(data, "SCALAR"); - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void MySql::configure(const VectorData &data) { configure(data, "VECTOR"); - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -536,7 +470,7 @@ MySql::configure(const VectorData &data) subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata(mysql); + subdata.setup(); } } @@ -553,7 +487,7 @@ MySql::configure(const DistData &data) stat.max = data.data.max; stat.bktsize = data.data.bucket_size; } - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void @@ -568,7 +502,7 @@ MySql::configure(const VectorDistData &data) stat.bktsize = data.data[0].bucket_size; } - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -579,7 +513,7 @@ MySql::configure(const VectorDistData &data) subdata.name = data.subnames[i]; subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata(mysql); + subdata.setup(); } } @@ -590,7 +524,7 @@ void MySql::configure(const Vector2dData &data) { configure(data, "VECTOR2D"); - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -601,7 +535,7 @@ MySql::configure(const Vector2dData &data) subdata.name = data.subnames[i]; subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata(mysql); + subdata.setup(); } } @@ -614,7 +548,7 @@ MySql::configure(const Vector2dData &data) subdata.y = i; subdata.name = data.y_subnames[i]; if (!subdata.name.empty()) - subdata(mysql); + subdata.setup(); } } @@ -625,20 +559,26 @@ void MySql::configure(const FormulaData &data) { configure(data, "FORMULA"); - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void MySql::output(const string &bin) { // set up new bin in database if there is a bin name - newdata.bin = bin.empty() ? 0 : SetupBin(mysql, bin); + newdata.bin = bin.empty() ? 0 : SetupBin(bin); Database::stat_list_t::const_iterator i, end = Database::stats().end(); for (i = Database::stats().begin(); i != end; ++i) (*i)->visit(*this); } +bool +MySql::valid() const +{ + return MySqlDB.connected(); +} + void MySql::output() { @@ -649,7 +589,6 @@ MySql::output() configure(); // store sample # - newdata.run = run_id; newdata.sample = curTick; if (bins().empty()) { @@ -781,7 +720,7 @@ MySql::output(const Vector2dData &data) void MySql::output(const FormulaData &data) { - InsertFormula(mysql, find(data.id), run_id, data.str()); + InsertFormula(find(data.id), data.str()); } /* @@ -841,4 +780,4 @@ MySql::visit(const FormulaData &data) output(data); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/mysql.hh b/base/stats/mysql.hh index 4ff474752..5780009d7 100644 --- a/base/stats/mysql.hh +++ b/base/stats/mysql.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,15 +29,18 @@ #ifndef __BASE_STATS_MYSQL_HH__ #define __BASE_STATS_MYSQL_HH__ +#include <map> #include <string> #include "base/stats/output.hh" namespace MySQL { class Connection; } -namespace Statistics { +namespace Stats { class DistDataData; -class MySqlData; +class MySqlRun; +bool MySqlConnected(); +extern MySqlRun MySqlDB; struct SetupStat { @@ -58,7 +61,7 @@ struct SetupStat uint16_t size; void init(); - unsigned operator()(MySqlData *data); + unsigned setup(); }; class InsertData @@ -70,14 +73,13 @@ class InsertData static const int maxsize = 1024*1024; public: - MySQL::Connection *mysql; + MySqlRun *run; public: uint64_t sample; double data; uint16_t stat; uint16_t bin; - uint16_t run; int16_t x; int16_t y; @@ -92,25 +94,28 @@ class InsertData class MySql : public Output { protected: - std::list<FormulaData *> formulas; - MySqlData *mysql; - bool configured; - uint16_t run_id; - SetupStat stat; InsertData newdata; + std::list<FormulaData *> formulas; + bool configured; - void insert(int sim_id, int db_id); - int find(int sim_id); - + protected: + std::map<int, int> idmap; + + void insert(int sim_id, int db_id) + { + using namespace std; + idmap.insert(make_pair(sim_id, db_id)); + } + + int find(int sim_id) + { + using namespace std; + map<int,int>::const_iterator i = idmap.find(sim_id); + assert(i != idmap.end()); + return (*i).second; + } public: - MySql(); - ~MySql(); - - void connect(const std::string &host, const std::string &user, - const std::string &passwd, const std::string &db, - const std::string &name, const std::string &project); - // Implement Visit virtual void visit(const ScalarData &data); virtual void visit(const VectorData &data); @@ -144,6 +149,6 @@ class MySql : public Output void configure(const FormulaData &data); }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_MYSQL_HH__ diff --git a/base/stats/mysql_run.hh b/base/stats/mysql_run.hh new file mode 100644 index 000000000..0f8d84297 --- /dev/null +++ b/base/stats/mysql_run.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifndef __BASE_STATS_MYSQL_RUN_HH__ +#define __BASE_STATS_MYSQL_RUN_HH__ + +#include <string> + +#include "base/mysql.hh" +#include "sim/host.hh" + +namespace Stats { + +struct MySqlRun +{ + private: + MySQL::Connection mysql; + uint16_t run_id; + + public: + bool connected() const { return mysql.connected(); } + void connect(const std::string &host, const std::string &user, + const std::string &passwd, const std::string &db, + const std::string &name, const std::string &project); + + void setup(const std::string &name, const std::string &user, + const std::string &project); + + void remove(const std::string &name); + void cleanup(); + + MySQL::Connection &conn() { return mysql; } + uint16_t run() const { return run_id; } +}; + +/* namespace Stats */ } + +#endif // __BASE_STATS_MYSQL_RUN_HH__ diff --git a/base/stats/output.hh b/base/stats/output.hh index 9f1fbf415..a575fdf2e 100644 --- a/base/stats/output.hh +++ b/base/stats/output.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include "base/stats/visit.hh" -namespace Statistics { +namespace Stats { struct Output : public Visit { @@ -42,6 +42,6 @@ struct Output : public Visit virtual bool valid() const = 0; }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_OUTPUT_HH__ diff --git a/base/stats/statdb.cc b/base/stats/statdb.cc index f54272a50..eed3d6296 100644 --- a/base/stats/statdb.cc +++ b/base/stats/statdb.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ using namespace std; -namespace Statistics { +namespace Stats { namespace Database { StatData * @@ -86,4 +86,4 @@ TheDatabase &db() } /* namespace Database */ } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/statdb.hh b/base/stats/statdb.hh index fb672e1dc..bd7fabf32 100644 --- a/base/stats/statdb.hh +++ b/base/stats/statdb.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,7 +36,7 @@ class Python; -namespace Statistics { +namespace Stats { class MainBin; class StatData; @@ -69,6 +69,6 @@ void regPrint(void *stat); inline std::string name() { return "Statistics Database"; } /* namespace Database */ } -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_STATDB_HH__ diff --git a/base/stats/text.cc b/base/stats/text.cc index ddd428646..f7e82a30f 100644 --- a/base/stats/text.cc +++ b/base/stats/text.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ __nan() } #endif -namespace Statistics { +namespace Stats { Text::Text() : mystream(false), stream(NULL), compat(false), descriptions(false) @@ -286,14 +286,14 @@ VectorPrint::operator()(std::ostream &stream) const print(stream); } - if (flags & ::Statistics::total) { + if (flags & ::Stats::total) { print.name = base + "total"; print.desc = desc; print.value = total; print(stream); } } else { - if (flags & ::Statistics::total) { + if (flags & ::Stats::total) { print.value = total; print(stream); } @@ -644,7 +644,7 @@ Text::visit(const Vector2dData &data) print(*stream); } - if ((data.flags & ::Statistics::total) && (data.x > 1)) { + if ((data.flags & ::Stats::total) && (data.x > 1)) { print.name = data.name; print.desc = data.desc; print.vec = tot_vec; @@ -732,4 +732,4 @@ Text::visit(const FormulaData &data) visit((const VectorData &)data); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/text.hh b/base/stats/text.hh index 89bddf0cb..9dd036f86 100644 --- a/base/stats/text.hh +++ b/base/stats/text.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ #include "base/stats/output.hh" -namespace Statistics { +namespace Stats { class Text : public Output { @@ -72,6 +72,6 @@ class Text : public Output virtual void output(); }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_TEXT_HH__ diff --git a/base/stats/types.hh b/base/stats/types.hh index 4451c4e6e..fbabfb118 100644 --- a/base/stats/types.hh +++ b/base/stats/types.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +32,7 @@ #include <vector> #include <inttypes.h> -namespace Statistics { +namespace Stats { /** All counters are of 64-bit values. */ typedef double Counter; @@ -44,6 +44,6 @@ typedef double Result; /** vector of results. */ typedef std::vector<Result> VResult; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_TYPES_HH__ diff --git a/base/stats/visit.cc b/base/stats/visit.cc index fec11b262..a270d94f4 100644 --- a/base/stats/visit.cc +++ b/base/stats/visit.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +28,7 @@ #include "base/stats/visit.hh" -namespace Statistics { +namespace Stats { namespace Detail { Visit::Visit() @@ -38,4 +38,4 @@ Visit::~Visit() {} /* namespace Detail */ } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/visit.hh b/base/stats/visit.hh index a03842c52..0b6cc5f22 100644 --- a/base/stats/visit.hh +++ b/base/stats/visit.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ #include "base/time.hh" #include "sim/host.hh" -namespace Statistics { +namespace Stats { class StatData; class ScalarData; @@ -58,6 +58,6 @@ struct Visit virtual void visit(const FormulaData &data) = 0; }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_VISIT_HH__ diff --git a/base/str.cc b/base/str.cc index 5ba23b55f..dd8d80043 100644 --- a/base/str.cc +++ b/base/str.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/str.hh b/base/str.hh index 8fee21a10..812f4d41a 100644 --- a/base/str.hh +++ b/base/str.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/time.cc b/base/time.cc index 9a484a883..e33aac406 100644 --- a/base/time.cc +++ b/base/time.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/time.hh b/base/time.hh index 1f8c7e747..bee8781a9 100644 --- a/base/time.hh +++ b/base/time.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/trace.cc b/base/trace.cc index e56bdb11b..aa82ee403 100644 --- a/base/trace.cc +++ b/base/trace.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/trace.hh b/base/trace.hh index 948bff548..60ea015ea 100644 --- a/base/trace.hh +++ b/base/trace.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/base/traceflags.py b/base/traceflags.py index a378ae722..3d7623965 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -101,6 +101,7 @@ baseFlags = [ 'Chains', 'Dispatch', 'Stats', + 'StatEvents', 'Context', 'Config', 'Sampler', diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc index fe88891d6..3ee7a3892 100644 --- a/cpu/base_cpu.cc +++ b/cpu/base_cpu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -130,7 +130,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, void BaseCPU::regStats() { - using namespace Statistics; + using namespace Stats; numCycles .name(name() + ".numCycles") @@ -242,6 +242,21 @@ BaseCPU::clear_interrupts() intstatus = 0; } + +void +BaseCPU::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_SCALAR(intstatus); +} + +void +BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_SCALAR(intstatus); +} + #endif // FULL_SYSTEM DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU) diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh index 0b4a38b0e..f75f00409 100644 --- a/cpu/base_cpu.hh +++ b/cpu/base_cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,6 +139,21 @@ class BaseCPU : public SimObject #ifdef FULL_SYSTEM System *system; + + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + #endif /** @@ -167,7 +182,7 @@ class BaseCPU : public SimObject public: // Number of CPU cycles simulated - Statistics::Scalar<> numCycles; + Stats::Scalar<> numCycles; }; #endif // __BASE_CPU_HH__ diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index a89cf4bb5..9c21b3a56 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,6 +106,7 @@ ExecContext::serialize(ostream &os) regs.serialize(os); // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(func_exe_inst); + SERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx = false; @@ -128,7 +129,7 @@ ExecContext::serialize(ostream &os) SERIALIZE_SCALAR(ctx); } if (system->bin) { - Statistics::MainBin *cur = Statistics::MainBin::curBin(); + Stats::MainBin *cur = Stats::MainBin::curBin(); string bin_name = cur->name(); SERIALIZE_SCALAR(bin_name); } @@ -143,6 +144,7 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion) regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(func_exe_inst); + UNSERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx; @@ -233,3 +235,16 @@ ExecContext::regStats(const string &name) kernelStats.regStats(name + ".kern"); #endif } + +void +ExecContext::trap(Fault fault) +{ + //TheISA::trap(fault); //One possible way to do it... + + /** @todo: Going to hack it for now. Do a true fixup later. */ +#ifdef FULL_SYSTEM + ev5_trap(fault); +#else + fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); +#endif +} diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 4f62fa6fa..b47f5cd08 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,6 +31,7 @@ #include "sim/host.hh" #include "mem/mem_req.hh" +#include "mem/functional_mem/functional_memory.hh" #include "sim/serialize.hh" #include "targetarch/byte_swap.hh" @@ -44,7 +45,7 @@ class BaseCPU; #include "targetarch/alpha_memory.hh" class MemoryController; -#include "kern/tru64/kernel_stats.hh" +#include "kern/kernel_stats.hh" #include "sim/system.hh" #include "sim/sw_context.hh" @@ -115,6 +116,9 @@ class ExecContext // pointer to CPU associated with this context BaseCPU *cpu; + // Current instruction + MachInst inst; + // Index of hardware thread context on the CPU that this represents. int thread_num; @@ -316,6 +320,18 @@ class ExecContext virtual bool misspeculating(); + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + // // New accessors for new decoder. // @@ -400,6 +416,14 @@ class ExecContext bool simPalCheck(int palFunc); #endif + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault); + #ifndef FULL_SYSTEM IntReg getSyscallArg(int i) { diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc index 0dd1d74d6..e31c3590c 100644 --- a/cpu/exetrace.cc +++ b/cpu/exetrace.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,7 +67,7 @@ Trace::InstRecord::dump(ostream &outs) std::string str; - if (debugSymbolTable->findNearestSymbol(PC, str)) + if ((debugSymbolTable) && (debugSymbolTable->findNearestSymbol(PC, str))) outs << "@" << setw(17) << str << " : "; else outs << "0x" << hex << PC << " : "; diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh index 622ecd729..e114ebc03 100644 --- a/cpu/exetrace.hh +++ b/cpu/exetrace.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/full_cpu/op_class.hh b/cpu/full_cpu/op_class.hh index dbaa6624a..a14ccfaed 100644 --- a/cpu/full_cpu/op_class.hh +++ b/cpu/full_cpu/op_class.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,23 +40,23 @@ */ enum OpClass { No_OpClass = 0, /* inst does not use a functional unit */ - IntALU, /* integer ALU */ - IntMULT, /* integer multiplier */ - IntDIV, /* integer divider */ - FloatADD, /* floating point adder/subtractor */ - FloatCMP, /* floating point comparator */ - FloatCVT, /* floating point<->integer converter */ - FloatMULT, /* floating point multiplier */ - FloatDIV, /* floating point divider */ - FloatSQRT, /* floating point square root */ - RdPort, /* memory read port */ - WrPort, /* memory write port */ - IPrefPort, + IntAluOp, /* integer ALU */ + IntMultOp, /* integer multiplier */ + IntDivOp, /* integer divider */ + FloatAddOp, /* floating point adder/subtractor */ + FloatCmpOp, /* floating point comparator */ + FloatCvtOp, /* floating point<->integer converter */ + FloatMultOp, /* floating point multiplier */ + FloatDivOp, /* floating point divider */ + FloatSqrtOp, /* floating point square root */ + MemReadOp, /* memory read port */ + MemWriteOp, /* memory write port */ + InstPrefetchOp, /* instruction prefetch port (on I-cache) */ Num_OpClasses /* total functional unit classes */ }; /** - * Array mapping OpClass enum values to strings. + * Array mapping OpClass enum values to strings. Defined in fu_pool.cc. */ extern const char *opClassStrings[]; diff --git a/cpu/inst_seq.hh b/cpu/inst_seq.hh index 9c3898ff7..4c403de1e 100644 --- a/cpu/inst_seq.hh +++ b/cpu/inst_seq.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001, 2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc index c71a36b6f..53de9d288 100644 --- a/cpu/intr_control.cc +++ b/cpu/intr_control.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/intr_control.hh b/cpu/intr_control.hh index 37e62ed00..8cdc6b61b 100644 --- a/cpu/intr_control.hh +++ b/cpu/intr_control.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 5d608976d..b55af332a 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -186,7 +186,7 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data) void MemTest::regStats() { - using namespace Statistics; + using namespace Stats; numReadsStat diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index f2409d54c..72e0709d9 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,9 +111,9 @@ class MemTest : public BaseCPU Tick noResponseCycles; uint64_t numReads; - Statistics::Scalar<> numReadsStat; - Statistics::Scalar<> numWritesStat; - Statistics::Scalar<> numCopiesStat; + Stats::Scalar<> numReadsStat; + Stats::Scalar<> numWritesStat; + Stats::Scalar<> numCopiesStat; // called by MemCompleteEvent::process() void completeRequest(MemReqPtr &req, uint8_t *data); diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index 4ee93e864..a86c017d4 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh index b425cc72c..131016fc6 100644 --- a/cpu/pc_event.hh +++ b/cpu/pc_event.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 655a5b3ea..bf4cbfbe2 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ #include "base/pollevent.hh" #include "base/range.hh" #include "base/trace.hh" +#include "base/stats/events.hh" #include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" @@ -254,7 +255,7 @@ SimpleCPU::haltContext(int thread_num) void SimpleCPU::regStats() { - using namespace Statistics; + using namespace Stats; BaseCPU::regStats(); @@ -298,6 +299,7 @@ SimpleCPU::resetStats() void SimpleCPU::serialize(ostream &os) { + BaseCPU::serialize(os); SERIALIZE_ENUM(_status); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); @@ -311,6 +313,7 @@ SimpleCPU::serialize(ostream &os) void SimpleCPU::unserialize(Checkpoint *cp, const string §ion) { + BaseCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); UNSERIALIZE_SCALAR(inst); xc->unserialize(cp, csprintf("%s.xc", section)); @@ -402,6 +405,9 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) } } + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Read"); + return fault; } @@ -487,6 +493,9 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) if (res && (fault == No_Fault)) *res = memReq->result; + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Write"); + return fault; } @@ -708,8 +717,7 @@ SimpleCPU::tick() xc->regs.pc); #ifdef FULL_SYSTEM - xc->regs.opcode = (inst >> 26) & 0x3f; - xc->regs.ra = (inst >> 21) & 0x1f; + xc->setInst(inst); #endif // FULL_SYSTEM xc->func_exe_inst++; diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index a04dcd057..6639dbc1a 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,7 @@ #include "cpu/pc_event.hh" #include "base/statistics.hh" #include "cpu/exec_context.hh" +#include "cpu/static_inst.hh" // forward declarations #ifdef FULL_SYSTEM @@ -209,7 +210,7 @@ class SimpleCPU : public BaseCPU // number of simulated instructions Counter numInst; Counter startNumInst; - Statistics::Scalar<> numInsts; + Stats::Scalar<> numInsts; virtual Counter totalInstructions() const { @@ -217,22 +218,22 @@ class SimpleCPU : public BaseCPU } // number of simulated memory references - Statistics::Scalar<> numMemRefs; + Stats::Scalar<> numMemRefs; // number of simulated loads Counter numLoad; Counter startNumLoad; // number of idle cycles - Statistics::Average<> notIdleFraction; - Statistics::Formula idleFraction; + Stats::Average<> notIdleFraction; + Stats::Formula idleFraction; // number of cycles stalled for I-cache misses - Statistics::Scalar<> icacheStallCycles; + Stats::Scalar<> icacheStallCycles; Counter lastIcacheStall; // number of cycles stalled for D-cache misses - Statistics::Scalar<> dcacheStallCycles; + Stats::Scalar<> dcacheStallCycles; Counter lastDcacheStall; void processCacheCompletion(); @@ -261,37 +262,71 @@ class SimpleCPU : public BaseCPU Fault copy(Addr dest); - uint64_t readIntReg(int reg_idx) { return xc->readIntReg(reg_idx); } + // The register accessor methods provide the index of the + // instruction's operand (e.g., 0 or 1), not the architectural + // register index, to simplify the implementation of register + // renaming. We find the architectural register index by indexing + // into the instruction's own operand index table. Note that a + // raw pointer to the StaticInst is provided instead of a + // ref-counted StaticInstPtr to redice overhead. This is fine as + // long as these methods don't copy the pointer into any long-term + // storage (which is pretty hard to imagine they would have reason + // to do). + + uint64_t readIntReg(StaticInst<TheISA> *si, int idx) + { + return xc->readIntReg(si->srcRegIdx(idx)); + } - float readFloatRegSingle(int reg_idx) - { return xc->readFloatRegSingle(reg_idx); } + float readFloatRegSingle(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegSingle(reg_idx); + } - double readFloatRegDouble(int reg_idx) - { return xc->readFloatRegDouble(reg_idx); } + double readFloatRegDouble(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegDouble(reg_idx); + } - uint64_t readFloatRegInt(int reg_idx) - { return xc->readFloatRegInt(reg_idx); } + uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegInt(reg_idx); + } - void setIntReg(int reg_idx, uint64_t val) - { return xc->setIntReg(reg_idx, val); } + void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val) + { + xc->setIntReg(si->destRegIdx(idx), val); + } - void setFloatRegSingle(int reg_idx, float val) - { return xc->setFloatRegSingle(reg_idx, val); } + void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegSingle(reg_idx, val); + } - void setFloatRegDouble(int reg_idx, double val) - { return xc->setFloatRegDouble(reg_idx, val); } + void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegDouble(reg_idx, val); + } - void setFloatRegInt(int reg_idx, uint64_t val) - { return xc->setFloatRegInt(reg_idx, val); } + void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegInt(reg_idx, val); + } uint64_t readPC() { return xc->readPC(); } - void setNextPC(uint64_t val) { return xc->setNextPC(val); } + void setNextPC(uint64_t val) { xc->setNextPC(val); } uint64_t readUniq() { return xc->readUniq(); } - void setUniq(uint64_t val) { return xc->setUniq(val); } + void setUniq(uint64_t val) { xc->setUniq(val); } uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { return xc->setFpcr(val); } + void setFpcr(uint64_t val) { xc->setFpcr(val); } #ifdef FULL_SYSTEM uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } @@ -300,7 +335,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { return xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 1065fa3d4..9a0425c8f 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ // forward declarations class ExecContext; class DynInst; +class FastCPU; class SimpleCPU; class SymbolTable; @@ -106,11 +107,13 @@ class StaticInstBase : public RefCounted IsThreadSync, ///< Thread synchronization operation. - IsSerializing, ///< Serializes pipeline: won't until all + IsSerializing, ///< Serializes pipeline: won't execute until all /// older instructions have committed. IsMemBarrier, ///< Is a memory barrier IsWriteBarrier, ///< Is a write barrier + IsNonSpeculative, ///< Should not be executed speculatively + NumFlags }; @@ -192,6 +195,7 @@ class StaticInstBase : public RefCounted bool isSerializing() const { return flags[IsSerializing]; } bool isMemBarrier() const { return flags[IsMemBarrier]; } bool isWriteBarrier() const { return flags[IsWriteBarrier]; } + bool isNonSpeculative() const { return flags[IsNonSpeculative]; } //@} /// Operation class. Used to select appropriate function unit in issue. @@ -310,6 +314,11 @@ class StaticInst : public StaticInstBase virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0; /** + * Execute this instruction under FastCPU model. + */ + virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0; + + /** * Execute this instruction under detailed FullCPU model. */ virtual Fault execute(DynInst *xc, Trace::InstRecord *traceData) = 0; diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index e9780b2d0..f8870496f 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ using namespace std; AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, SimObject *clock, + System *system, BaseCPU *cpu, Platform *platform, int num_cpus, MemoryController *mmu, Addr a, HierParams *hier, Bus *bus) : PioDevice(name), disk(d), console(cons), addr(a) @@ -78,14 +78,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->numCPUs = num_cpus; alphaAccess->mem_size = system->physmem->size(); alphaAccess->cpuClock = cpu->getFreq() / 1000000; - TsunamiIO *clock_linux = dynamic_cast<TsunamiIO *>(clock); - TlaserClock *clock_tru64 = dynamic_cast<TlaserClock *>(clock); - if (clock_linux) - alphaAccess->intrClockFrequency = clock_linux->frequency(); - else if (clock_tru64) - alphaAccess->intrClockFrequency = clock_tru64->frequency(); - else - panic("clock must be of type TlaserClock or TsunamiIO\n"); + alphaAccess->intrClockFrequency = platform->intrFrequency(); alphaAccess->diskUnit = 1; } @@ -321,7 +314,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) Param<Addr> addr; SimObjectParam<System *> system; SimObjectParam<BaseCPU *> cpu; - SimObjectParam<SimObject *> clock; + SimObjectParam<Platform *> platform; SimObjectParam<Bus*> io_bus; SimObjectParam<HierParams *> hier; @@ -336,7 +329,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) INIT_PARAM(addr, "Device Address"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu, "Processor"), - INIT_PARAM(clock, "Clock"), + INIT_PARAM(platform, "platform"), INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) @@ -345,7 +338,7 @@ END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) CREATE_SIM_OBJECT(AlphaConsole) { return new AlphaConsole(getInstanceName(), sim_console, disk, - system, cpu, clock, num_cpus, mmu, + system, cpu, platform, num_cpus, mmu, addr, hier, io_bus); } diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index a5cc51c5e..47afa8f4a 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,13 +37,12 @@ #include "dev/alpha_access.h" #include "dev/io_device.hh" #include "sim/host.hh" -#include "dev/tsunami_io.hh" #include "sim/sim_object.hh" class BaseCPU; class SimConsole; class System; -class TlaserClock; +class Platform; class SimpleDisk; /* @@ -88,7 +87,7 @@ class AlphaConsole : public PioDevice public: /** Standard Constructor */ AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, - System *system, BaseCPU *cpu, SimObject *clock, + System *system, BaseCPU *cpu, Platform *platform, int num_cpus, MemoryController *mmu, Addr addr, HierParams *hier, Bus *bus); diff --git a/dev/baddev.cc b/dev/baddev.cc index 8a5d68533..8b552e989 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -1,4 +1,30 @@ -/* $Id$ */ +/* + * Copyright (c) 2004 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. + */ /* @file * BadDevice implemenation @@ -10,10 +36,10 @@ #include "base/trace.hh" #include "cpu/exec_context.hh" -#include "dev/scsi_ctrl.hh" #include "dev/baddev.hh" -#include "dev/tsunamireg.h" -#include "dev/tsunami.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -21,10 +47,17 @@ using namespace std; BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, - const string &devicename) - : FunctionalMemory(name), addr(a), devname(devicename) + HierParams *hier, Bus *bus, const string &devicename) + : PioDevice(name), addr(a), devname(devicename) { mmu->add_child(this, Range<Addr>(addr, addr + size)); + + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &BadDevice::cacheAccess); + pioInterface->addAddrRange(addr, addr + size - 1); + } + } Fault @@ -42,11 +75,18 @@ BadDevice::write(MemReqPtr &req, const uint8_t *data) return No_Fault; } +Tick +BadDevice::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice) SimObjectParam<MemoryController *> mmu; Param<Addr> addr; + SimObjectParam<HierParams *> hier; + SimObjectParam<Bus*> io_bus; Param<string> devicename; END_DECLARE_SIM_OBJECT_PARAMS(BadDevice) @@ -55,13 +95,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice) INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(addr, "Device Address"), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), INIT_PARAM(devicename, "Name of device to error on") END_INIT_SIM_OBJECT_PARAMS(BadDevice) CREATE_SIM_OBJECT(BadDevice) { - return new BadDevice(getInstanceName(), addr, mmu, devicename); + return new BadDevice(getInstanceName(), addr, mmu, hier, io_bus, devicename); } REGISTER_SIM_OBJECT("BadDevice", BadDevice) diff --git a/dev/baddev.hh b/dev/baddev.hh index ed896d792..8680f6b0a 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,8 @@ #ifndef __BADDEV_HH__ #define __BADDEV_HH__ -#include "mem/functional_mem/functional_memory.hh" +#include "base/range.hh" +#include "dev/io_device.hh" /** * BadDevice @@ -42,7 +43,7 @@ * the user that the kernel they are running has unsupported * options (i.e. frame buffer) */ -class BadDevice : public FunctionalMemory +class BadDevice : public PioDevice { private: Addr addr; @@ -51,14 +52,42 @@ class BadDevice : public FunctionalMemory std::string devname; public: - /** - * The default constructor. - */ + /** + * Constructor for the Baddev Class. + * @param name name of the object + * @param a base address of the write + * @param mmu the memory controller + * @param hier object to store parameters universal the device hierarchy + * @param bus The bus that this device is attached to + * @param devicename device that is not implemented + */ BadDevice(const std::string &name, Addr a, MemoryController *mmu, - const std::string &devicename); + HierParams *hier, Bus *bus, const std::string &devicename); + /** + * On a read event we just panic aand hopefully print a + * meaningful error message. + * @param req Contains the address to read from. + * @param data A pointer to write the read data to. + * @return The fault condition of the access. + */ virtual Fault read(MemReqPtr &req, uint8_t *data); + + /** + * On a write event we just panic aand hopefully print a + * meaningful error message. + * @param req Contains the address to write to. + * @param data The data to write. + * @return The fault condition of the access. + */ virtual Fault write(MemReqPtr &req, const uint8_t *data); + + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ + Tick cacheAccess(MemReqPtr &req); }; #endif // __BADDEV_HH__ diff --git a/dev/console.cc b/dev/console.cc index ef3f64d8d..b9bcbb3d1 100644 --- a/dev/console.cc +++ b/dev/console.cc @@ -1,30 +1,5 @@ -/* - * Copyright (c) 2003 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. - */ +/* $Id$ */ + /* @file * User Console Definitions @@ -377,11 +352,15 @@ SimConsole::setPlatform(Platform *p) void SimConsole::serialize(ostream &os) { + SERIALIZE_SCALAR(_status); + SERIALIZE_SCALAR(_enable); } void SimConsole::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_SCALAR(_status); + UNSERIALIZE_SCALAR(_enable); } diff --git a/dev/console.hh b/dev/console.hh index 703d05d51..87be9ccbc 100644 --- a/dev/console.hh +++ b/dev/console.hh @@ -1,30 +1,4 @@ -/* - * Copyright (c) 2003 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. - */ +/* $Id$ */ /* @file * User Console Interface diff --git a/dev/disk_image.cc b/dev/disk_image.cc index 4df196e64..d990d7078 100644 --- a/dev/disk_image.cc +++ b/dev/disk_image.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/disk_image.hh b/dev/disk_image.hh index 7b2c12ef7..b21978058 100644 --- a/dev/disk_image.hh +++ b/dev/disk_image.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherbus.cc b/dev/etherbus.cc index 76697dd3e..82722383c 100644 --- a/dev/etherbus.cc +++ b/dev/etherbus.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherbus.hh b/dev/etherbus.hh index 9ef477808..716636c79 100644 --- a/dev/etherbus.hh +++ b/dev/etherbus.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherdump.cc b/dev/etherdump.cc index b6d6bbe30..54e573be4 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherdump.hh b/dev/etherdump.hh index e22b66166..ef4399e1a 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherint.cc b/dev/etherint.cc index cfffb3a87..c78848674 100644 --- a/dev/etherint.cc +++ b/dev/etherint.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherint.hh b/dev/etherint.hh index 70e29eb7c..ddfe16d88 100644 --- a/dev/etherint.hh +++ b/dev/etherint.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 25991f1a7..3cc4f75ea 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherlink.hh b/dev/etherlink.hh index 3b1dd21bc..4f227fac5 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index 09516c427..76b4a9156 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,70 +35,13 @@ #include <iosfwd> #include <memory> +#include <assert.h> #include "sim/host.hh" #include "base/refcnt.hh" - -#define EADDR_LEN 6 +#include "base/inet_hdrs.hh" class Checkpoint; - -struct pseudo_header -{ - uint32_t src_ip_addr; - uint32_t dest_ip_addr; - uint16_t protocol; - uint16_t len; -}; - -/** Ethernet header struct for casting purposes */ -struct eth_header -{ - uint8_t dest[EADDR_LEN]; - uint8_t src[EADDR_LEN]; - uint16_t type; -}; - -struct ip_header -{ - uint8_t vers_len; - uint8_t service_type; - uint16_t dgram_len; - uint16_t ID; - uint16_t flags_frag_offset; - uint8_t TTL; - uint8_t protocol; - uint16_t hdr_chksum; - uint32_t src_ip_addr; - uint32_t dest_ip_addr; - uint8_t *options; - uint8_t *transport_header; -}; - -struct tcp_header -{ - uint16_t src_port_num; - uint16_t dest_port_num; - uint32_t seq_num; - uint32_t ack_num; - uint8_t hdr_len; - uint8_t flags; - uint16_t rcv_window; - uint16_t chksum; - uint16_t urgent; - uint8_t *options; - uint8_t *data; -}; - -struct udp_header -{ - uint16_t src_port_num; - uint16_t dest_port_num; - uint16_t len; - uint16_t chksum; - uint8_t *data; -}; - /* * Reference counted class containing ethernet packet data */ @@ -119,14 +62,31 @@ class EtherPacket : public RefCounted bool IsMulticast() { return data[0] == 0x01; } bool IsBroadcast() { return data[0] == 0xff; } - ip_header *getIpHdr() { return (ip_header *) (data + 14); } - - void *getTransportHdr() { + bool isIpPkt() { + eth_header *eth = (eth_header *) data; + return (eth->type == 0x800); + } + bool isTcpPkt() { ip_header *ip = getIpHdr(); - return (void *) (ip + (ip->vers_len & 0xf)); + return (ip->protocol == 6); + } + bool isUdpPkt() { + ip_header *ip = getIpHdr(); + return (ip->protocol == 17); + } + + ip_header *getIpHdr() { + assert(isIpPkt()); + return (ip_header *) (data + sizeof(eth_header)); } + tcp_header *getTcpHdr(ip_header *ip) { + return (tcp_header *) (ip + (ip->vers_len & 0xf)); + } + udp_header *getUdpHdr(ip_header *ip) { + return (udp_header *) (ip + (ip->vers_len & 0xf)); + } typedef RefCountingPtr<EtherPacket> PacketPtr; void serialize(std::ostream &os); diff --git a/dev/ethertap.cc b/dev/ethertap.cc index 297053e1e..edc400760 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/ethertap.hh b/dev/ethertap.hh index 0b853a11d..1fe368085 100644 --- a/dev/ethertap.hh +++ b/dev/ethertap.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index f78a8e1ef..46a0e8179 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -255,7 +255,10 @@ IdeController::cacheAccess(MemReqPtr &req) void IdeController::ReadConfig(int offset, int size, uint8_t *data) { + +#if TRACING_ON Addr origOffset = offset; +#endif if (offset < PCI_DEVICE_SPECIFIC) { PciDev::ReadConfig(offset, size, data); @@ -338,63 +341,74 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) memcpy((void *)&pci_regs[offset], (void *)&data, size); } - if (offset == PCI_COMMAND) { - if (config.data[offset] & IOSE) + // Catch the writes to specific PCI registers that have side affects + // (like updating the PIO ranges) + switch (offset) { + case PCI_COMMAND: + if (config.data[offset] & PCI_CMD_IOSE) io_enabled = true; else io_enabled = false; - if (config.data[offset] & BME) + if (config.data[offset] & PCI_CMD_BME) bm_enabled = true; else bm_enabled = false; + break; - } else if (data != 0xffffffff) { - switch (offset) { - case PCI0_BASE_ADDR0: + case PCI0_BASE_ADDR0: + if (BARAddrs[0] != 0) { pri_cmd_addr = BARAddrs[0]; if (pioInterface) pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + pri_cmd_size - 1); - pri_cmd_addr = pri_cmd_addr & PA_UNCACHED_MASK; - break; + pri_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR1: + case PCI0_BASE_ADDR1: + if (BARAddrs[1] != 0) { pri_ctrl_addr = BARAddrs[1]; if (pioInterface) pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + pri_ctrl_size - 1); - pri_ctrl_addr = pri_ctrl_addr & PA_UNCACHED_MASK; - break; + pri_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR2: + case PCI0_BASE_ADDR2: + if (BARAddrs[2] != 0) { sec_cmd_addr = BARAddrs[2]; if (pioInterface) pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + sec_cmd_size - 1); - sec_cmd_addr = sec_cmd_addr & PA_UNCACHED_MASK; - break; + sec_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR3: + case PCI0_BASE_ADDR3: + if (BARAddrs[3] != 0) { sec_ctrl_addr = BARAddrs[3]; if (pioInterface) pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + sec_ctrl_size - 1); - sec_ctrl_addr = sec_ctrl_addr & PA_UNCACHED_MASK; - break; + sec_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR4: + case PCI0_BASE_ADDR4: + if (BARAddrs[4] != 0) { bmi_addr = BARAddrs[4]; if (pioInterface) pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); - bmi_addr = bmi_addr & PA_UNCACHED_MASK; - break; + bmi_addr &= PA_UNCACHED_MASK; } + break; } } @@ -589,6 +603,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) void IdeController::serialize(std::ostream &os) { + // Serialize the PciDev base class + PciDev::serialize(os); + // Serialize register addresses and sizes SERIALIZE_SCALAR(pri_cmd_addr); SERIALIZE_SCALAR(pri_cmd_size); @@ -615,6 +632,9 @@ IdeController::serialize(std::ostream &os) void IdeController::unserialize(Checkpoint *cp, const std::string §ion) { + // Unserialize the PciDev base class + PciDev::unserialize(cp, section); + // Unserialize register addresses and sizes UNSERIALIZE_SCALAR(pri_cmd_addr); UNSERIALIZE_SCALAR(pri_cmd_size); @@ -636,6 +656,18 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(io_enabled); UNSERIALIZE_SCALAR(bm_enabled); UNSERIALIZE_ARRAY(cmd_in_progress, 4); + + if (pioInterface) { + pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + + pri_cmd_size - 1); + pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + + pri_ctrl_size - 1); + pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + + sec_cmd_size - 1); + pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + + sec_ctrl_size - 1); + pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); + } } #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -651,7 +683,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; - SimObjectParam<Bus *> host_bus; + SimObjectParam<Bus *> io_bus; SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(IdeController) @@ -667,7 +699,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM_DFLT(host_bus, "Host bus to attach to", NULL), + INIT_PARAM_DFLT(io_bus, "Host bus to attach to", NULL), INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(IdeController) @@ -676,7 +708,7 @@ CREATE_SIM_OBJECT(IdeController) { return new IdeController(getInstanceName(), intr_ctrl, disks, mmu, configspace, configdata, tsunami, pci_bus, - pci_dev, pci_func, host_bus, hier); + pci_dev, pci_func, io_bus, hier); } REGISTER_SIM_OBJECT("IdeController", IdeController) diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 9698724c1..679c7422b 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -74,10 +74,6 @@ #define UDMACTL (5) #define UDMATIM (6) -// PCI Command bit fields -#define BME 0x04 // Bus master function enable -#define IOSE 0x01 // I/O space enable - typedef enum RegType { COMMAND_BLOCK = 0, CONTROL_BLOCK, @@ -199,12 +195,6 @@ class IdeController : public PciDev virtual Fault write(MemReqPtr &req, const uint8_t *data); /** - * Cache access timing specific to device - * @param req Memory request - */ - Tick cacheAccess(MemReqPtr &req); - - /** * Serialize this object to the given output stream. * @param os The stream to serialize to. */ @@ -217,5 +207,11 @@ class IdeController : public PciDev */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ + Tick cacheAccess(MemReqPtr &req); }; #endif // __IDE_CTRL_HH_ diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 0d12e797d..0f5c02660 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,25 +61,12 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, dmaWriteWaitEvent(this), dmaPrdReadEvent(this), dmaReadEvent(this), dmaWriteEvent(this) { + // Reset the device state + reset(id); + // calculate disk delay in microseconds diskDelay = (delay * ticksPerSecond / 100000); - // initialize the data buffer and shadow registers - dataBuffer = new uint8_t[MAX_DMA_SIZE]; - - memset(dataBuffer, 0, MAX_DMA_SIZE); - memset(&cmdReg, 0, sizeof(CommandReg_t)); - memset(&curPrd.entry, 0, sizeof(PrdEntry_t)); - - dmaInterfaceBytes = 0; - curPrdAddr = 0; - curSector = 0; - curCommand = 0; - cmdBytesLeft = 0; - drqBytesLeft = 0; - dmaRead = false; - intrPending = false; - // fill out the drive ID structure memset(&driveID, 0, sizeof(struct hd_driveid)); @@ -132,6 +119,32 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, driveID.dma_ultra = 0x10; // Statically set hardware config word driveID.hw_config = 0x4001; +} + +IdeDisk::~IdeDisk() +{ + // destroy the data buffer + delete [] dataBuffer; +} + +void +IdeDisk::reset(int id) +{ + // initialize the data buffer and shadow registers + dataBuffer = new uint8_t[MAX_DMA_SIZE]; + + memset(dataBuffer, 0, MAX_DMA_SIZE); + memset(&cmdReg, 0, sizeof(CommandReg_t)); + memset(&curPrd.entry, 0, sizeof(PrdEntry_t)); + + dmaInterfaceBytes = 0; + curPrdAddr = 0; + curSector = 0; + cmdBytes = 0; + cmdBytesLeft = 0; + drqBytesLeft = 0; + dmaRead = false; + intrPending = false; // set the device state to idle dmaState = Dma_Idle; @@ -147,13 +160,7 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, } // set the device ready bit - cmdReg.status |= STATUS_DRDY_BIT; -} - -IdeDisk::~IdeDisk() -{ - // destroy the data buffer - delete [] dataBuffer; + status = STATUS_DRDY_BIT; } //// @@ -216,6 +223,7 @@ IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data) // determine if an action needs to be taken on the state machine if (offset == STATUS_OFFSET) { action = ACT_STAT_READ; + *data = status; // status is in a shadow, explicity copy } else if (offset == DATA_OFFSET) { if (byte) action = ACT_DATA_READ_BYTE; @@ -230,7 +238,7 @@ IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data) if (!byte) panic("Invalid 16-bit read from control block\n"); - *data = ((uint8_t *)&cmdReg)[STATUS_OFFSET]; + *data = status; } if (action != ACT_NONE) @@ -262,6 +270,8 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) action = ACT_DATA_WRITE_BYTE; else action = ACT_DATA_WRITE_SHORT; + } else if (offset == SELECT_OFFSET) { + action = ACT_SELECT_WRITE; } } else { @@ -271,8 +281,13 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data) if (!byte) panic("Invalid 16-bit write to control block\n"); - if (*data & CONTROL_RST_BIT) - panic("Software reset not supported!\n"); + if (*data & CONTROL_RST_BIT) { + // force the device into the reset state + devState = Device_Srst; + action = ACT_SRST_SET; + } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) { + action = ACT_SRST_CLEAR; + } nIENBit = (*data & CONTROL_IEN_BIT) ? true : false; } @@ -315,7 +330,13 @@ IdeDisk::dmaPrdReadDone() physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)), sizeof(PrdEntry_t)); - curPrdAddr += sizeof(PrdEntry_t); + DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n", + curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()), + curPrd.getByteCount(), (cmdBytesLeft/SectorSize), + curPrd.getEOT(), curSector); + + // make sure the new curPrdAddr is properly translated from PCI to system + curPrdAddr = pciToDma(curPrdAddr + sizeof(PrdEntry_t)); if (dmaRead) doDmaRead(); @@ -414,29 +435,8 @@ IdeDisk::dmaReadDone() writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten)); } -#if 0 - // actually copy the data from memory to data buffer - Addr dmaAddr = - ctrl->tsunami->pchip->translatePciToDma(curPrd.getBaseAddr()); - memcpy((void *)dataBuffer, - physmem->dma_addr(dmaAddr, curPrd.getByteCount()), - curPrd.getByteCount()); - - uint32_t bytesWritten = 0; - - while (bytesWritten < curPrd.getByteCount()) { - if (cmdBytesLeft <= 0) - panic("DMA data is larger than # sectors specified\n"); - - writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten)); - - bytesWritten += SectorSize; - cmdBytesLeft -= SectorSize; - } -#endif - // check for the EOT - if (curPrd.getEOT()){ + if (curPrd.getEOT()) { assert(cmdBytesLeft == 0); dmaState = Dma_Idle; updateState(ACT_DMA_DONE); @@ -543,14 +543,6 @@ IdeDisk::dmaWriteDone() bytesInPage); } -#if 0 - Addr dmaAddr = ctrl->tsunami->pchip-> - translatePciToDma(curPrd.getBaseAddr()); - - memcpy(physmem->dma_addr(dmaAddr, curPrd.getByteCount()), - (void *)dataBuffer, curPrd.getByteCount()); -#endif - // check for the EOT if (curPrd.getEOT()) { assert(cmdBytesLeft == 0); @@ -598,7 +590,8 @@ IdeDisk::startDma(const uint32_t &prdTableBase) if (devState != Transfer_Data_Dma) panic("Inconsistent device state for DMA start!\n"); - curPrdAddr = pciToDma((Addr)prdTableBase); + // PRD base address is given by bits 31:2 + curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3))); dmaState = Dma_Transfer; @@ -625,9 +618,6 @@ IdeDisk::startCommand() uint32_t size = 0; dmaRead = false; - // copy the command to the shadow - curCommand = cmdReg.command; - // Decode commands switch (cmdReg.command) { // Supported non-data commands @@ -644,6 +634,7 @@ IdeDisk::startCommand() case WIN_RECAL: case WIN_SPECIFY: + case WIN_STANDBYNOW1: case WIN_FLUSH_CACHE: case WIN_VERIFY: case WIN_SEEK: @@ -655,7 +646,7 @@ IdeDisk::startCommand() // Supported PIO data-in commands case WIN_IDENTIFY: - cmdBytesLeft = drqBytesLeft = sizeof(struct hd_driveid); + cmdBytes = cmdBytesLeft = sizeof(struct hd_driveid); devState = Prepare_Data_In; action = ACT_DATA_READY; break; @@ -666,13 +657,13 @@ IdeDisk::startCommand() panic("Attempt to perform CHS access, only supports LBA\n"); if (cmdReg.sec_count == 0) - cmdBytesLeft = (256 * SectorSize); + cmdBytes = cmdBytesLeft = (256 * SectorSize); else - cmdBytesLeft = (cmdReg.sec_count * SectorSize); + cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize); - drqBytesLeft = SectorSize; curSector = getLBABase(); + /** @todo make this a scheduled event to simulate disk delay */ devState = Prepare_Data_In; action = ACT_DATA_READY; break; @@ -684,11 +675,10 @@ IdeDisk::startCommand() panic("Attempt to perform CHS access, only supports LBA\n"); if (cmdReg.sec_count == 0) - cmdBytesLeft = (256 * SectorSize); + cmdBytes = cmdBytesLeft = (256 * SectorSize); else - cmdBytesLeft = (cmdReg.sec_count * SectorSize); + cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize); - drqBytesLeft = SectorSize; curSector = getLBABase(); devState = Prepare_Data_Out; @@ -703,11 +693,10 @@ IdeDisk::startCommand() panic("Attempt to perform CHS access, only supports LBA\n"); if (cmdReg.sec_count == 0) - cmdBytesLeft = (256 * SectorSize); + cmdBytes = cmdBytesLeft = (256 * SectorSize); else - cmdBytesLeft = (cmdReg.sec_count * SectorSize); + cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize); - drqBytesLeft = SectorSize; curSector = getLBABase(); devState = Prepare_Data_Dma; @@ -720,9 +709,11 @@ IdeDisk::startCommand() if (action != ACT_NONE) { // set the BSY bit - cmdReg.status |= STATUS_BSY_BIT; + status |= STATUS_BSY_BIT; // clear the DRQ bit - cmdReg.status &= ~STATUS_DRQ_BIT; + status &= ~STATUS_DRQ_BIT; + // clear the DF bit + status &= ~STATUS_DF_BIT; updateState(action); } @@ -766,16 +757,30 @@ void IdeDisk::updateState(DevAction_t action) { switch (devState) { + case Device_Srst: + if (action == ACT_SRST_SET) { + // set the BSY bit + status |= STATUS_BSY_BIT; + } else if (action == ACT_SRST_CLEAR) { + // clear the BSY bit + status &= ~STATUS_BSY_BIT; + + // reset the device state + reset(devID); + } + break; + case Device_Idle_S: - if (!isDEVSelect()) + if (action == ACT_SELECT_WRITE && !isDEVSelect()) { devState = Device_Idle_NS; - else if (action == ACT_CMD_WRITE) + } else if (action == ACT_CMD_WRITE) { startCommand(); + } break; case Device_Idle_SI: - if (!isDEVSelect()) { + if (action == ACT_SELECT_WRITE && !isDEVSelect()) { devState = Device_Idle_NS; intrClear(); } else if (action == ACT_STAT_READ || isIENSet()) { @@ -789,7 +794,7 @@ IdeDisk::updateState(DevAction_t action) break; case Device_Idle_NS: - if (isDEVSelect()) { + if (action == ACT_SELECT_WRITE && isDEVSelect()) { if (!isIENSet() && intrPending) { devState = Device_Idle_SI; intrPost(); @@ -827,20 +832,27 @@ IdeDisk::updateState(DevAction_t action) } } else if (action == ACT_DATA_READY) { // clear the BSY bit - cmdReg.status &= ~STATUS_BSY_BIT; + status &= ~STATUS_BSY_BIT; // set the DRQ bit - cmdReg.status |= STATUS_DRQ_BIT; - - // put the first two bytes into the data register - memcpy((void *)&cmdReg.data0, (void *)dataBuffer, - sizeof(uint16_t)); + status |= STATUS_DRQ_BIT; // copy the data into the data buffer - if (curCommand == WIN_IDENTIFY) + if (cmdReg.command == WIN_IDENTIFY) { + // Reset the drqBytes for this block + drqBytesLeft = sizeof(struct hd_driveid); + memcpy((void *)dataBuffer, (void *)&driveID, sizeof(struct hd_driveid)); - else + } else { + // Reset the drqBytes for this block + drqBytesLeft = SectorSize; + readDisk(curSector++, dataBuffer); + } + + // put the first two bytes into the data register + memcpy((void *)&cmdReg.data0, (void *)dataBuffer, + sizeof(uint16_t)); if (!isIENSet()) { devState = Data_Ready_INTRQ_In; @@ -867,9 +879,10 @@ IdeDisk::updateState(DevAction_t action) cmdBytesLeft -= 2; // copy next short into data registers - memcpy((void *)&cmdReg.data0, - (void *)&dataBuffer[SectorSize - drqBytesLeft], - sizeof(uint16_t)); + if (drqBytesLeft) + memcpy((void *)&cmdReg.data0, + (void *)&dataBuffer[SectorSize - drqBytesLeft], + sizeof(uint16_t)); } if (drqBytesLeft == 0) { @@ -879,7 +892,14 @@ IdeDisk::updateState(DevAction_t action) devState = Device_Idle_S; } else { devState = Prepare_Data_In; - cmdReg.status |= STATUS_BSY_BIT; + // set the BSY_BIT + status |= STATUS_BSY_BIT; + // clear the DRQ_BIT + status &= ~STATUS_DRQ_BIT; + + /** @todo change this to a scheduled event to simulate + disk delay */ + updateState(ACT_DATA_READY); } } } @@ -896,20 +916,23 @@ IdeDisk::updateState(DevAction_t action) } else { devState = Device_Idle_S; } - } else if (cmdBytesLeft != 0) { + } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) { // clear the BSY bit - cmdReg.status &= ~STATUS_BSY_BIT; + status &= ~STATUS_BSY_BIT; // set the DRQ bit - cmdReg.status |= STATUS_DRQ_BIT; + status |= STATUS_DRQ_BIT; // clear the data buffer to get it ready for writes memset(dataBuffer, 0, MAX_DMA_SIZE); - if (!isIENSet()) { + // reset the drqBytes for this block + drqBytesLeft = SectorSize; + + if (cmdBytesLeft == cmdBytes || isIENSet()) { + devState = Transfer_Data_Out; + } else { devState = Data_Ready_INTRQ_Out; intrPost(); - } else { - devState = Transfer_Data_Out; } } break; @@ -942,11 +965,17 @@ IdeDisk::updateState(DevAction_t action) writeDisk(curSector++, dataBuffer); // set the BSY bit - cmdReg.status |= STATUS_BSY_BIT; + status |= STATUS_BSY_BIT; + // set the seek bit + status |= STATUS_SEEK_BIT; // clear the DRQ bit - cmdReg.status &= ~STATUS_DRQ_BIT; + status &= ~STATUS_DRQ_BIT; devState = Prepare_Data_Out; + + /** @todo change this to a scheduled event to simulate + disk delay */ + updateState(ACT_DATA_READY); } } break; @@ -964,9 +993,9 @@ IdeDisk::updateState(DevAction_t action) } } else if (action == ACT_DMA_READY) { // clear the BSY bit - cmdReg.status &= ~STATUS_BSY_BIT; + status &= ~STATUS_BSY_BIT; // set the DRQ bit - cmdReg.status |= STATUS_DRQ_BIT; + status |= STATUS_DRQ_BIT; devState = Transfer_Data_Dma; @@ -983,7 +1012,7 @@ IdeDisk::updateState(DevAction_t action) // clear the BSY bit setComplete(); // set the seek bit - cmdReg.status |= 0x10; + status |= STATUS_SEEK_BIT; // clear the controller state for DMA transfer ctrl->setDmaComplete(this); @@ -1009,26 +1038,41 @@ IdeDisk::serialize(ostream &os) Tick reschedule = 0; Events_t event = None; + int eventCount = 0; + if (dmaTransferEvent.scheduled()) { reschedule = dmaTransferEvent.when(); event = Transfer; - } else if (dmaReadWaitEvent.scheduled()) { + eventCount++; + } + if (dmaReadWaitEvent.scheduled()) { reschedule = dmaReadWaitEvent.when(); event = ReadWait; - } else if (dmaWriteWaitEvent.scheduled()) { + eventCount++; + } + if (dmaWriteWaitEvent.scheduled()) { reschedule = dmaWriteWaitEvent.when(); event = WriteWait; - } else if (dmaPrdReadEvent.scheduled()) { + eventCount++; + } + if (dmaPrdReadEvent.scheduled()) { reschedule = dmaPrdReadEvent.when(); event = PrdRead; - } else if (dmaReadEvent.scheduled()) { + eventCount++; + } + if (dmaReadEvent.scheduled()) { reschedule = dmaReadEvent.when(); event = DmaRead; - } else if (dmaWriteEvent.scheduled()) { + eventCount++; + } + if (dmaWriteEvent.scheduled()) { reschedule = dmaWriteEvent.when(); event = DmaWrite; + eventCount++; } + assert(eventCount <= 1); + SERIALIZE_SCALAR(reschedule); SERIALIZE_ENUM(event); @@ -1040,7 +1084,8 @@ IdeDisk::serialize(ostream &os) SERIALIZE_SCALAR(cmdReg.cyl_low); SERIALIZE_SCALAR(cmdReg.cyl_high); SERIALIZE_SCALAR(cmdReg.drive); - SERIALIZE_SCALAR(cmdReg.status); + SERIALIZE_SCALAR(cmdReg.command); + SERIALIZE_SCALAR(status); SERIALIZE_SCALAR(nIENBit); SERIALIZE_SCALAR(devID); @@ -1052,9 +1097,9 @@ IdeDisk::serialize(ostream &os) // Serialize current transfer related information SERIALIZE_SCALAR(cmdBytesLeft); + SERIALIZE_SCALAR(cmdBytes); SERIALIZE_SCALAR(drqBytesLeft); SERIALIZE_SCALAR(curSector); - SERIALIZE_SCALAR(curCommand); SERIALIZE_SCALAR(dmaRead); SERIALIZE_SCALAR(dmaInterfaceBytes); SERIALIZE_SCALAR(intrPending); @@ -1092,7 +1137,8 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(cmdReg.cyl_low); UNSERIALIZE_SCALAR(cmdReg.cyl_high); UNSERIALIZE_SCALAR(cmdReg.drive); - UNSERIALIZE_SCALAR(cmdReg.status); + UNSERIALIZE_SCALAR(cmdReg.command); + UNSERIALIZE_SCALAR(status); UNSERIALIZE_SCALAR(nIENBit); UNSERIALIZE_SCALAR(devID); @@ -1103,10 +1149,10 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(curPrdAddr); // Unserialize current transfer related information + UNSERIALIZE_SCALAR(cmdBytes); UNSERIALIZE_SCALAR(cmdBytesLeft); UNSERIALIZE_SCALAR(drqBytesLeft); UNSERIALIZE_SCALAR(curSector); - UNSERIALIZE_SCALAR(curCommand); UNSERIALIZE_SCALAR(dmaRead); UNSERIALIZE_SCALAR(dmaInterfaceBytes); UNSERIALIZE_SCALAR(intrPending); diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 35e7404d5..409aaef9a 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,8 +40,8 @@ #define DMA_BACKOFF_PERIOD 200 -#define MAX_DMA_SIZE (131072) // 256 * SectorSize (512) -#define MAX_MULTSECT (128) +#define MAX_DMA_SIZE (65536) // 64K +#define MAX_MULTSECT (128) #define PRD_BASE_MASK 0xfffffffe #define PRD_COUNT_MASK 0xfffe @@ -62,7 +62,7 @@ class PrdTableEntry { return (entry.baseAddr & PRD_BASE_MASK); } - uint16_t getByteCount() + uint32_t getByteCount() { return ((entry.byteCount == 0) ? MAX_DMA_SIZE : (entry.byteCount & PRD_COUNT_MASK)); @@ -94,6 +94,8 @@ class PrdTableEntry { #define STATUS_BSY_BIT 0x80 #define STATUS_DRDY_BIT 0x40 #define STATUS_DRQ_BIT 0x08 +#define STATUS_SEEK_BIT 0x10 +#define STATUS_DF_BIT 0x20 #define DRIVE_LBA_BIT 0x40 #define DEV0 (0) @@ -114,10 +116,7 @@ typedef struct CommandReg { uint8_t drive; uint8_t head; }; - union { - uint8_t status; - uint8_t command; - }; + uint8_t command; } CommandReg_t; typedef enum Events { @@ -135,6 +134,7 @@ typedef enum DevAction { ACT_CMD_WRITE, ACT_CMD_COMPLETE, ACT_CMD_ERROR, + ACT_SELECT_WRITE, ACT_STAT_READ, ACT_DATA_READY, ACT_DATA_READ_BYTE, @@ -142,7 +142,9 @@ typedef enum DevAction { ACT_DATA_WRITE_BYTE, ACT_DATA_WRITE_SHORT, ACT_DMA_READY, - ACT_DMA_DONE + ACT_DMA_DONE, + ACT_SRST_SET, + ACT_SRST_CLEAR } DevAction_t; typedef enum DevState { @@ -151,6 +153,9 @@ typedef enum DevState { Device_Idle_SI, Device_Idle_NS, + // Software reset + Device_Srst, + // Non-data commands Command_Execution, @@ -202,6 +207,8 @@ class IdeDisk : public SimObject struct hd_driveid driveID; /** Data buffer for transfers */ uint8_t *dataBuffer; + /** Number of bytes in command data transfer */ + uint32_t cmdBytes; /** Number of bytes left in command data transfer */ uint32_t cmdBytesLeft; /** Number of bytes left in DRQ block */ @@ -210,8 +217,8 @@ class IdeDisk : public SimObject uint32_t curSector; /** Command block registers */ CommandReg_t cmdReg; - /** Shadow of the current command code */ - uint8_t curCommand; + /** Status register */ + uint8_t status; /** Interrupt enable bit */ bool nIENBit; /** Device state */ @@ -249,6 +256,11 @@ class IdeDisk : public SimObject ~IdeDisk(); /** + * Reset the device state + */ + void reset(int id); + + /** * Set the controller for this device * @param c The IDE controller */ @@ -306,17 +318,18 @@ class IdeDisk : public SimObject void updateState(DevAction_t action); // Utility functions - bool isBSYSet() { return (cmdReg.status & STATUS_BSY_BIT); } + bool isBSYSet() { return (status & STATUS_BSY_BIT); } bool isIENSet() { return nIENBit; } bool isDEVSelect() { return ((cmdReg.drive & SELECT_DEV_BIT) == devID); } void setComplete() { // clear out the status byte - cmdReg.status = 0; - + status = 0; // set the DRDY bit - cmdReg.status |= STATUS_DRDY_BIT; + status |= STATUS_DRDY_BIT; + // set the SEEK bit + status |= STATUS_SEEK_BIT; } uint32_t getLBABase() diff --git a/dev/io_device.cc b/dev/io_device.cc index 910b889d8..b39efa1f5 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/io_device.hh b/dev/io_device.hh index 9300d87e7..e6014e73d 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index cae90a3b4..28181ba64 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -88,18 +88,18 @@ using namespace std; /////////////////////////////////////////////////////////////////////// // -// EtherDev PCI Device +// NSGigE PCI Device // -EtherDev::EtherDev(const std::string &name, IntrControl *i, Tick intr_delay, +NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay, MemoryController *mmu, HierParams *hier, Bus *header_bus, Bus *payload_bus, Tick pio_latency, bool dma_desc_free, bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], Addr addr) - : PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), - addr(addr), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), + uint32_t func, bool rx_filter, const int eaddr[6]) + : PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), io_enable(false), + txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), txXferLen(0), rxXferLen(0), txPktXmitted(0), txState(txIdle), CTDD(false), txFifoCnt(0), txFifoAvail(MAX_TX_FIFO_SIZE), txHalt(false), txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), @@ -115,13 +115,12 @@ EtherDev::EtherDev(const std::string &name, IntrControl *i, Tick intr_delay, physmem(pmem), intctrl(i), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0), pioLatency(pio_latency) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); tsunami->ethernet = this; if (header_bus) { pioInterface = newPioInterface(name, hier, header_bus, this, - &EtherDev::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + &NSGigE::cacheAccess); + if (payload_bus) dmaInterface = new DMAInterface<Bus>(name + ".dma", header_bus, payload_bus, 1); @@ -130,10 +129,10 @@ EtherDev::EtherDev(const std::string &name, IntrControl *i, Tick intr_delay, header_bus, header_bus, 1); } else if (payload_bus) { pioInterface = newPioInterface(name, hier, payload_bus, this, - &EtherDev::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); - dmaInterface = new DMAInterface<Bus>(name + ".dma", - payload_bus, payload_bus, 1); + &NSGigE::cacheAccess); + + dmaInterface = new DMAInterface<Bus>(name + ".dma", payload_bus, + payload_bus, 1); } @@ -154,11 +153,11 @@ EtherDev::EtherDev(const std::string &name, IntrControl *i, Tick intr_delay, rom.perfectMatch[5] = eaddr[5]; } -EtherDev::~EtherDev() +NSGigE::~NSGigE() {} void -EtherDev::regStats() +NSGigE::regStats() { txBytes .name(name() + ".txBytes") @@ -212,8 +211,8 @@ EtherDev::regStats() .prereq(rxBytes) ; - txBandwidth = txBytes * Statistics::constant(8) / simSeconds; - rxBandwidth = rxBytes * Statistics::constant(8) / simSeconds; + txBandwidth = txBytes * Stats::constant(8) / simSeconds; + rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; txPacketRate = txPackets / simSeconds; rxPacketRate = rxPackets / simSeconds; } @@ -222,25 +221,70 @@ EtherDev::regStats() * This is to read the PCI general configuration registers */ void -EtherDev::ReadConfig(int offset, int size, uint8_t *data) +NSGigE::ReadConfig(int offset, int size, uint8_t *data) { if (offset < PCI_DEVICE_SPECIFIC) PciDev::ReadConfig(offset, size, data); - else { - panic("need to do this\n"); - } + else + panic("Device specific PCI config space not implemented!\n"); } /** * This is to write to the PCI general configuration registers */ void -EtherDev::WriteConfig(int offset, int size, uint32_t data) +NSGigE::WriteConfig(int offset, int size, uint32_t data) { if (offset < PCI_DEVICE_SPECIFIC) PciDev::WriteConfig(offset, size, data); else - panic("Need to do that\n"); + panic("Device specific PCI config space not implemented!\n"); + + // Need to catch writes to BARs to update the PIO interface + switch (offset) { + //seems to work fine without all these, but i ut in the IO to + //double check, an assertion will fail if we need to properly + // imlpement it + case PCI_COMMAND: + if (config.data[offset] & PCI_CMD_IOSE) + io_enable = true; + else + io_enable = false; +#if 0 + if (config.data[offset] & PCI_CMD_BME) + bm_enabled = true; + else + bm_enabled = false; + break; + + if (config.data[offset] & PCI_CMD_MSE) + mem_enable = true; + else + mem_enable = false; + break; +#endif + + case PCI0_BASE_ADDR0: + if (BARAddrs[0] != 0) { + + if (pioInterface) + pioInterface->addAddrRange(BARAddrs[0], BARAddrs[0] + BARSize[0] - 1); + + BARAddrs[0] &= PA_UNCACHED_MASK; + + } + break; + case PCI0_BASE_ADDR1: + if (BARAddrs[1] != 0) { + + if (pioInterface) + pioInterface->addAddrRange(BARAddrs[1], BARAddrs[1] + BARSize[1] - 1); + + BARAddrs[1] &= PA_UNCACHED_MASK; + + } + break; + } } /** @@ -248,8 +292,10 @@ EtherDev::WriteConfig(int offset, int size, uint32_t data) * spec sheet */ Fault -EtherDev::read(MemReqPtr &req, uint8_t *data) +NSGigE::read(MemReqPtr &req, uint8_t *data) { + assert(io_enable); + //The mask is to give you only the offset into the device register file Addr daddr = req->paddr & 0xfff; DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n", @@ -363,7 +409,6 @@ EtherDev::read(MemReqPtr &req, uint8_t *data) break; case RFDR: - DPRINTF(Ethernet, "reading from RFDR\n"); switch (regs.rfcr & RFCR_RFADDR) { case 0x000: reg = rom.perfectMatch[1]; @@ -437,7 +482,8 @@ EtherDev::read(MemReqPtr &req, uint8_t *data) panic("reading unimplemented register: addr = %#x", daddr); } - DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", daddr, reg, reg); + DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", + daddr, reg, reg); } break; @@ -450,8 +496,10 @@ EtherDev::read(MemReqPtr &req, uint8_t *data) } Fault -EtherDev::write(MemReqPtr &req, const uint8_t *data) +NSGigE::write(MemReqPtr &req, const uint8_t *data) { + assert(io_enable); + Addr daddr = req->paddr & 0xfff; DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n", daddr, req->paddr, req->vaddr, req->size); @@ -685,7 +733,6 @@ EtherDev::write(MemReqPtr &req, const uint8_t *data) case RFCR: regs.rfcr = reg; - DPRINTF(Ethernet, "Writing to RFCR, RFADDR is %#x\n", reg & RFCR_RFADDR); rxFilterEnable = (reg & RFCR_RFEN) ? true : false; @@ -791,11 +838,8 @@ EtherDev::write(MemReqPtr &req, const uint8_t *data) } void -EtherDev::devIntrPost(uint32_t interrupts) +NSGigE::devIntrPost(uint32_t interrupts) { - DPRINTF(Ethernet, "interrupt posted intr=%#x isr=%#x imr=%#x\n", - interrupts, regs.isr, regs.imr); - bool delay = false; if (interrupts & ISR_RESERVE) @@ -846,6 +890,9 @@ EtherDev::devIntrPost(uint32_t interrupts) if (interrupts & ISR_RXERR) regs.isr |= ISR_RXERR; + if (interrupts & ISR_RXDESC) + regs.isr |= ISR_RXDESC; + if (interrupts & ISR_RXOK) { delay = true; regs.isr |= ISR_RXOK; @@ -857,14 +904,14 @@ EtherDev::devIntrPost(uint32_t interrupts) when += intrDelay; cpuIntrPost(when); } + + DPRINTF(Ethernet, "interrupt posted intr=%#x isr=%#x imr=%#x\n", + interrupts, regs.isr, regs.imr); } void -EtherDev::devIntrClear(uint32_t interrupts) +NSGigE::devIntrClear(uint32_t interrupts) { - DPRINTF(Ethernet, "interrupt cleared intr=%x isr=%x imr=%x\n", - interrupts, regs.isr, regs.imr); - if (interrupts & ISR_RESERVE) panic("Cannot clear a reserved interrupt"); @@ -911,15 +958,21 @@ EtherDev::devIntrClear(uint32_t interrupts) if (interrupts & ISR_RXERR) regs.isr &= ~ISR_RXERR; + if (interrupts & ISR_RXDESC) + regs.isr &= ~ISR_RXDESC; + if (interrupts & ISR_RXOK) regs.isr &= ~ISR_RXOK; if (!(regs.isr & regs.imr)) cpuIntrClear(); + + DPRINTF(Ethernet, "interrupt cleared intr=%x isr=%x imr=%x\n", + interrupts, regs.isr, regs.imr); } void -EtherDev::devIntrChangeMask() +NSGigE::devIntrChangeMask() { DPRINTF(Ethernet, "interrupt mask changed\n"); @@ -930,7 +983,7 @@ EtherDev::devIntrChangeMask() } void -EtherDev::cpuIntrPost(Tick when) +NSGigE::cpuIntrPost(Tick when) { if (when > intrTick && intrTick != 0) return; @@ -951,7 +1004,7 @@ EtherDev::cpuIntrPost(Tick when) } void -EtherDev::cpuInterrupt() +NSGigE::cpuInterrupt() { // Don't send an interrupt if there's already one if (cpuPendingIntr) @@ -974,7 +1027,7 @@ EtherDev::cpuInterrupt() } void -EtherDev::cpuIntrClear() +NSGigE::cpuIntrClear() { if (cpuPendingIntr) { cpuPendingIntr = false; @@ -985,11 +1038,11 @@ EtherDev::cpuIntrClear() } bool -EtherDev::cpuIntrPending() const +NSGigE::cpuIntrPending() const { return cpuPendingIntr; } void -EtherDev::txReset() +NSGigE::txReset() { DPRINTF(Ethernet, "transmit reset\n"); @@ -1007,7 +1060,7 @@ EtherDev::txReset() } void -EtherDev::rxReset() +NSGigE::rxReset() { DPRINTF(Ethernet, "receive reset\n"); @@ -1023,8 +1076,22 @@ EtherDev::rxReset() rxState = rxIdle; } +void NSGigE::regsReset() +{ + memset(®s, 0, sizeof(regs)); + regs.config = 0x80000000; + regs.mear = 0x12; + regs.isr = 0x00608000; + regs.txcfg = 0x120; + regs.rxcfg = 0x4; + regs.srr = 0x0103; + regs.mibc = 0x2; + regs.vdr = 0x81; + regs.tesr = 0xc000; +} + void -EtherDev::rxDmaReadCopy() +NSGigE::rxDmaReadCopy() { assert(rxDmaState == dmaReading); @@ -1037,7 +1104,7 @@ EtherDev::rxDmaReadCopy() } bool -EtherDev::doRxDmaRead() +NSGigE::doRxDmaRead() { assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); rxDmaState = dmaReading; @@ -1063,7 +1130,7 @@ EtherDev::doRxDmaRead() } void -EtherDev::rxDmaReadDone() +NSGigE::rxDmaReadDone() { assert(rxDmaState == dmaReading); rxDmaReadCopy(); @@ -1076,7 +1143,7 @@ EtherDev::rxDmaReadDone() } void -EtherDev::rxDmaWriteCopy() +NSGigE::rxDmaWriteCopy() { assert(rxDmaState == dmaWriting); @@ -1089,7 +1156,7 @@ EtherDev::rxDmaWriteCopy() } bool -EtherDev::doRxDmaWrite() +NSGigE::doRxDmaWrite() { assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); rxDmaState = dmaWriting; @@ -1115,7 +1182,7 @@ EtherDev::doRxDmaWrite() } void -EtherDev::rxDmaWriteDone() +NSGigE::rxDmaWriteDone() { assert(rxDmaState == dmaWriting); rxDmaWriteCopy(); @@ -1128,7 +1195,7 @@ EtherDev::rxDmaWriteDone() } void -EtherDev::rxKick() +NSGigE::rxKick() { DPRINTF(Ethernet, "receive kick state=%s (rxBuf.size=%d)\n", NsRxStateStrings[rxState], rxFifo.size()); @@ -1200,6 +1267,11 @@ EtherDev::rxKick() if (rxDmaState != dmaIdle) goto exit; + DPRINTF(Ethernet, + "rxDescCache:\n\tlink=%#x\n\tbufptr=%#x\n\tcmdsts=%#x\n\textsts=%#x\n" + ,rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, + rxDescCache.extsts); + if (rxDescCache.cmdsts & CMDSTS_OWN) { rxState = rxIdle; } else { @@ -1254,12 +1326,10 @@ EtherDev::rxKick() //if (rxPktBytes == 0) { /* packet is done */ assert(rxPktBytes == 0); - rxFifoCnt -= rxPacket->length; - rxPacket = 0; - rxDescCache.cmdsts |= CMDSTS_OWN; rxDescCache.cmdsts &= ~CMDSTS_MORE; rxDescCache.cmdsts |= CMDSTS_OK; + rxDescCache.cmdsts &= 0xffff0000; rxDescCache.cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE #if 0 @@ -1279,31 +1349,33 @@ EtherDev::rxKick() } #endif - eth_header *eth = (eth_header *) rxPacket->data; - // eth->type 0x800 indicated that it's an ip packet. - if (eth->type == 0x800 && extstsEnable) { - rxDescCache.extsts |= EXTSTS_IPPKT; + if (rxPacket->isIpPkt() && extstsEnable) { rxDescCache.extsts |= EXTSTS_IPPKT; if (!ipChecksum(rxPacket, false)) rxDescCache.extsts |= EXTSTS_IPERR; - ip_header *ip = rxFifo.front()->getIpHdr(); - if (ip->protocol == 6) { + if (rxPacket->isTcpPkt()) { rxDescCache.extsts |= EXTSTS_TCPPKT; if (!tcpChecksum(rxPacket, false)) rxDescCache.extsts |= EXTSTS_TCPERR; - } else if (ip->protocol == 17) { + } else if (rxPacket->isUdpPkt()) { rxDescCache.extsts |= EXTSTS_UDPPKT; if (!udpChecksum(rxPacket, false)) rxDescCache.extsts |= EXTSTS_UDPERR; } } + rxFifoCnt -= rxPacket->length; + rxPacket = 0; + /* the driver seems to always receive into desc buffers of size 1514, so you never have a pkt that is split into multiple descriptors on the receive side, so i don't implement that case, hence the assert above. */ + DPRINTF(Ethernet, "rxDesc writeback:\n\tcmdsts=%#x\n\textsts=%#x\n", + rxDescCache.cmdsts, rxDescCache.extsts); + rxDmaAddr = (regs.rxdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; rxDmaData = &(rxDescCache.cmdsts); rxDmaLen = sizeof(rxDescCache.cmdsts) + sizeof(rxDescCache.extsts); @@ -1388,7 +1460,7 @@ EtherDev::rxKick() } void -EtherDev::transmit() +NSGigE::transmit() { if (txFifo.empty()) { DPRINTF(Ethernet, "nothing to transmit\n"); @@ -1421,7 +1493,7 @@ EtherDev::transmit() } void -EtherDev::txDmaReadCopy() +NSGigE::txDmaReadCopy() { assert(txDmaState == dmaReading); @@ -1434,7 +1506,7 @@ EtherDev::txDmaReadCopy() } bool -EtherDev::doTxDmaRead() +NSGigE::doTxDmaRead() { assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); txDmaState = dmaReading; @@ -1460,7 +1532,7 @@ EtherDev::doTxDmaRead() } void -EtherDev::txDmaReadDone() +NSGigE::txDmaReadDone() { assert(txDmaState == dmaReading); txDmaReadCopy(); @@ -1473,7 +1545,7 @@ EtherDev::txDmaReadDone() } void -EtherDev::txDmaWriteCopy() +NSGigE::txDmaWriteCopy() { assert(txDmaState == dmaWriting); @@ -1486,7 +1558,7 @@ EtherDev::txDmaWriteCopy() } bool -EtherDev::doTxDmaWrite() +NSGigE::doTxDmaWrite() { assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); txDmaState = dmaWriting; @@ -1512,7 +1584,7 @@ EtherDev::doTxDmaWrite() } void -EtherDev::txDmaWriteDone() +NSGigE::txDmaWriteDone() { assert(txDmaState == dmaWriting); txDmaWriteCopy(); @@ -1525,7 +1597,7 @@ EtherDev::txDmaWriteDone() } void -EtherDev::txKick() +NSGigE::txKick() { DPRINTF(Ethernet, "transmit kick state=%s\n", NsTxStateStrings[txState]); @@ -1560,8 +1632,8 @@ EtherDev::txKick() if (CTDD) { txState = txDescRefr; - txDmaAddr = txDescCache.link & 0x3fffffff; - txDmaData = &txDescCache; + txDmaAddr = regs.txdp & 0x3fffffff; + txDmaData = &txDescCache + offsetof(ns_desc, link); txDmaLen = sizeof(txDescCache.link); txDmaFree = dmaDescFree; @@ -1572,7 +1644,7 @@ EtherDev::txKick() txState = txDescRead; txDmaAddr = regs.txdp & 0x3fffffff; - txDmaData = &txDescCache + offsetof(ns_desc, link); + txDmaData = &txDescCache; txDmaLen = sizeof(ns_desc); txDmaFree = dmaDescFree; @@ -1592,6 +1664,11 @@ EtherDev::txKick() if (txDmaState != dmaIdle) goto exit; + DPRINTF(Ethernet, + "txDescCache data:\n\tlink=%#x\n\tbufptr=%#x\n\tcmdsts=%#x\n\textsts=%#x\n" + ,txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts, + txDescCache.extsts); + if (txDescCache.cmdsts & CMDSTS_OWN) { txState = txFifoBlock; txFragPtr = txDescCache.bufptr; @@ -1656,12 +1733,15 @@ EtherDev::txKick() txDescCache.cmdsts &= ~CMDSTS_OWN; txDescCache.cmdsts |= CMDSTS_OK; - txDmaAddr = regs.txdp & 0x3fffffff; - txDmaData = &txDescCache + offsetof(ns_desc, cmdsts); + DPRINTF(Ethernet, + "txDesc writeback:\n\tcmdsts=%#x\n\textsts=%#x\n", + txDescCache.cmdsts, txDescCache.extsts); + + txDmaAddr = (regs.txdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; + txDmaData = &(txDescCache.cmdsts); txDmaLen = sizeof(txDescCache.cmdsts) + sizeof(txDescCache.extsts); txDmaFree = dmaDescFree; - if (doTxDmaWrite()) goto exit; @@ -1777,7 +1857,7 @@ EtherDev::txKick() } void -EtherDev::transferDone() +NSGigE::transferDone() { if (txFifo.empty()) return; @@ -1791,7 +1871,7 @@ EtherDev::transferDone() } bool -EtherDev::rxFilter(PacketPtr packet) +NSGigE::rxFilter(PacketPtr packet) { bool drop = true; string type; @@ -1841,7 +1921,7 @@ EtherDev::rxFilter(PacketPtr packet) } bool -EtherDev::recvPacket(PacketPtr packet) +NSGigE::recvPacket(PacketPtr packet) { rxBytes += packet->length; rxPackets++; @@ -1878,11 +1958,10 @@ EtherDev::recvPacket(PacketPtr packet) * else, it just checks what it calculates against the value in the header in packet */ bool -EtherDev::udpChecksum(PacketPtr packet, bool gen) +NSGigE::udpChecksum(PacketPtr packet, bool gen) { - udp_header *hdr = (udp_header *) packet->getTransportHdr(); - ip_header *ip = packet->getIpHdr(); + udp_header *hdr = packet->getUdpHdr(ip); pseudo_header *pseudo = new pseudo_header; @@ -1905,11 +1984,10 @@ EtherDev::udpChecksum(PacketPtr packet, bool gen) } bool -EtherDev::tcpChecksum(PacketPtr packet, bool gen) +NSGigE::tcpChecksum(PacketPtr packet, bool gen) { - tcp_header *hdr = (tcp_header *) packet->getTransportHdr(); - ip_header *ip = packet->getIpHdr(); + tcp_header *hdr = packet->getTcpHdr(ip); pseudo_header *pseudo = new pseudo_header; @@ -1932,7 +2010,7 @@ EtherDev::tcpChecksum(PacketPtr packet, bool gen) } bool -EtherDev::ipChecksum(PacketPtr packet, bool gen) +NSGigE::ipChecksum(PacketPtr packet, bool gen) { ip_header *hdr = packet->getIpHdr(); @@ -1948,7 +2026,7 @@ EtherDev::ipChecksum(PacketPtr packet, bool gen) } uint16_t -EtherDev::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len) +NSGigE::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len) { uint32_t sum = 0; @@ -1978,8 +2056,11 @@ EtherDev::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len) // // void -EtherDev::serialize(ostream &os) +NSGigE::serialize(ostream &os) { + // Serialize the PciDev base class + PciDev::serialize(os); + /* * Finalize any DMA events now. */ @@ -2030,21 +2111,53 @@ EtherDev::serialize(ostream &os) SERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); + SERIALIZE_SCALAR(io_enable); + /* - * Serialize the various helper variables + * Serialize the data Fifos */ - uint32_t txPktBufPtr = (uint32_t) txPacketBufPtr; - SERIALIZE_SCALAR(txPktBufPtr); - uint32_t rxPktBufPtr = (uint32_t) rxPktBufPtr; - SERIALIZE_SCALAR(rxPktBufPtr); - SERIALIZE_SCALAR(txXferLen); - SERIALIZE_SCALAR(rxXferLen); - SERIALIZE_SCALAR(txPktXmitted); + int txNumPkts = txFifo.size(); + SERIALIZE_SCALAR(txNumPkts); + int i = 0; + pktiter_t end = txFifo.end(); + for (pktiter_t p = txFifo.begin(); p != end; ++p) { + nameOut(os, csprintf("%s.txFifo%d", name(), i++)); + (*p)->serialize(os); + } + int rxNumPkts = rxFifo.size(); + SERIALIZE_SCALAR(rxNumPkts); + i = 0; + end = rxFifo.end(); + for (pktiter_t p = rxFifo.begin(); p != end; ++p) { + nameOut(os, csprintf("%s.rxFifo%d", name(), i++)); + (*p)->serialize(os); + } + + /* + * Serialize the various helper variables + */ bool txPacketExists = txPacket; SERIALIZE_SCALAR(txPacketExists); + if (txPacketExists) { + nameOut(os, csprintf("%s.txPacket", name())); + txPacket->serialize(os); + uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); + SERIALIZE_SCALAR(txPktBufPtr); + } + bool rxPacketExists = rxPacket; SERIALIZE_SCALAR(rxPacketExists); + if (rxPacketExists) { + nameOut(os, csprintf("%s.rxPacket", name())); + rxPacket->serialize(os); + uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); + SERIALIZE_SCALAR(rxPktBufPtr); + } + + SERIALIZE_SCALAR(txXferLen); + SERIALIZE_SCALAR(rxXferLen); + SERIALIZE_SCALAR(txPktXmitted); /* * Serialize DescCaches @@ -2061,8 +2174,6 @@ EtherDev::serialize(ostream &os) /* * Serialize tx state machine */ - int txNumPkts = txFifo.size(); - SERIALIZE_SCALAR(txNumPkts); int txState = this->txState; SERIALIZE_SCALAR(txState); SERIALIZE_SCALAR(CTDD); @@ -2077,8 +2188,6 @@ EtherDev::serialize(ostream &os) /* * Serialize rx state machine */ - int rxNumPkts = rxFifo.size(); - SERIALIZE_SCALAR(rxNumPkts); int rxState = this->rxState; SERIALIZE_SCALAR(rxState); SERIALIZE_SCALAR(CRDD); @@ -2091,7 +2200,7 @@ EtherDev::serialize(ostream &os) SERIALIZE_SCALAR(extstsEnable); - /* + /* * If there's a pending transmit, store the time so we can * reschedule it later */ @@ -2099,6 +2208,16 @@ EtherDev::serialize(ostream &os) SERIALIZE_SCALAR(transmitTick); /* + * receive address filter settings + */ + SERIALIZE_SCALAR(rxFilterEnable); + SERIALIZE_SCALAR(acceptBroadcast); + SERIALIZE_SCALAR(acceptMulticast); + SERIALIZE_SCALAR(acceptUnicast); + SERIALIZE_SCALAR(acceptPerfect); + SERIALIZE_SCALAR(acceptArp); + + /* * Keep track of pending interrupt status. */ SERIALIZE_SCALAR(intrTick); @@ -2108,29 +2227,14 @@ EtherDev::serialize(ostream &os) intrEventTick = intrEvent->when(); SERIALIZE_SCALAR(intrEventTick); - int i = 0; - for (pktiter_t p = rxFifo.begin(); p != rxFifo.end(); ++p) { - nameOut(os, csprintf("%s.rxFifo%d", name(), i++)); - (*p)->serialize(os); - } - if (rxPacketExists) { - nameOut(os, csprintf("%s.rxPacket", name())); - rxPacket->serialize(os); - } - i = 0; - for (pktiter_t p = txFifo.begin(); p != txFifo.end(); ++p) { - nameOut(os, csprintf("%s.txFifo%d", name(), i++)); - (*p)->serialize(os); - } - if (txPacketExists) { - nameOut(os, csprintf("%s.txPacket", name())); - txPacket->serialize(os); - } } void -EtherDev::unserialize(Checkpoint *cp, const std::string §ion) +NSGigE::unserialize(Checkpoint *cp, const std::string §ion) { + // Unserialize the PciDev base class + PciDev::unserialize(cp, section); + UNSERIALIZE_SCALAR(regs.command); UNSERIALIZE_SCALAR(regs.config); UNSERIALIZE_SCALAR(regs.mear); @@ -2166,23 +2270,57 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); + UNSERIALIZE_SCALAR(io_enable); + /* - * unserialize the various helper variables + * unserialize the data fifos */ - uint32_t txPktBufPtr; - UNSERIALIZE_SCALAR(txPktBufPtr); - txPacketBufPtr = (uint8_t *) txPktBufPtr; - uint32_t rxPktBufPtr; - UNSERIALIZE_SCALAR(rxPktBufPtr); - rxPacketBufPtr = (uint8_t *) rxPktBufPtr; - UNSERIALIZE_SCALAR(txXferLen); - UNSERIALIZE_SCALAR(rxXferLen); - UNSERIALIZE_SCALAR(txPktXmitted); + int txNumPkts; + UNSERIALIZE_SCALAR(txNumPkts); + int i; + for (i = 0; i < txNumPkts; ++i) { + PacketPtr p = new EtherPacket; + p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); + txFifo.push_back(p); + } + + int rxNumPkts; + UNSERIALIZE_SCALAR(rxNumPkts); + for (i = 0; i < rxNumPkts; ++i) { + PacketPtr p = new EtherPacket; + p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); + rxFifo.push_back(p); + } + /* + * unserialize the various helper variables + */ bool txPacketExists; UNSERIALIZE_SCALAR(txPacketExists); + if (txPacketExists) { + txPacket = new EtherPacket; + txPacket->unserialize(cp, csprintf("%s.txPacket", section)); + uint32_t txPktBufPtr; + UNSERIALIZE_SCALAR(txPktBufPtr); + txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; + } else + txPacket = 0; + bool rxPacketExists; UNSERIALIZE_SCALAR(rxPacketExists); + rxPacket = 0; + if (rxPacketExists) { + rxPacket = new EtherPacket; + rxPacket->unserialize(cp, csprintf("%s.rxPacket", section)); + uint32_t rxPktBufPtr; + UNSERIALIZE_SCALAR(rxPktBufPtr); + rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; + } else + rxPacket = 0; + + UNSERIALIZE_SCALAR(txXferLen); + UNSERIALIZE_SCALAR(rxXferLen); + UNSERIALIZE_SCALAR(txPktXmitted); /* * Unserialize DescCaches @@ -2199,8 +2337,6 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) /* * unserialize tx state machine */ - int txNumPkts; - UNSERIALIZE_SCALAR(txNumPkts); int txState; UNSERIALIZE_SCALAR(txState); this->txState = (TxState) txState; @@ -2217,8 +2353,6 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) /* * unserialize rx state machine */ - int rxNumPkts; - UNSERIALIZE_SCALAR(rxNumPkts); int rxState; UNSERIALIZE_SCALAR(rxState); this->rxState = (RxState) rxState; @@ -2234,8 +2368,7 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(extstsEnable); /* - * If there's a pending transmit, store the time so we can - * reschedule it later + * If there's a pending transmit, reschedule it now */ Tick transmitTick; UNSERIALIZE_SCALAR(transmitTick); @@ -2243,6 +2376,16 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) txEvent.schedule(curTick + transmitTick); /* + * unserialize receive address filter settings + */ + UNSERIALIZE_SCALAR(rxFilterEnable); + UNSERIALIZE_SCALAR(acceptBroadcast); + UNSERIALIZE_SCALAR(acceptMulticast); + UNSERIALIZE_SCALAR(acceptUnicast); + UNSERIALIZE_SCALAR(acceptPerfect); + UNSERIALIZE_SCALAR(acceptArp); + + /* * Keep track of pending interrupt status. */ UNSERIALIZE_SCALAR(intrTick); @@ -2254,30 +2397,17 @@ EtherDev::unserialize(Checkpoint *cp, const std::string §ion) intrEvent->schedule(intrEventTick); } - for (int i = 0; i < rxNumPkts; ++i) { - PacketPtr p = new EtherPacket; - p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); - rxFifo.push_back(p); - } - rxPacket = NULL; - if (rxPacketExists) { - rxPacket = new EtherPacket; - rxPacket->unserialize(cp, csprintf("%s.rxPacket", section)); - } - for (int i = 0; i < txNumPkts; ++i) { - PacketPtr p = new EtherPacket; - p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); - txFifo.push_back(p); - } - if (txPacketExists) { - txPacket = new EtherPacket; - txPacket->unserialize(cp, csprintf("%s.txPacket", section)); + /* + * re-add addrRanges to bus bridges + */ + if (pioInterface) { + pioInterface->addAddrRange(BARAddrs[0], BARAddrs[0] + BARSize[0] - 1); + pioInterface->addAddrRange(BARAddrs[1], BARAddrs[1] + BARSize[1] - 1); } } - Tick -EtherDev::cacheAccess(MemReqPtr &req) +NSGigE::cacheAccess(MemReqPtr &req) { DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", req->paddr, req->paddr - addr); @@ -2286,23 +2416,23 @@ EtherDev::cacheAccess(MemReqPtr &req) //===================================================================== -BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDevInt) +BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) SimObjectParam<EtherInt *> peer; - SimObjectParam<EtherDev *> device; + SimObjectParam<NSGigE *> device; -END_DECLARE_SIM_OBJECT_PARAMS(EtherDevInt) +END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) -BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDevInt) +BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt) INIT_PARAM_DFLT(peer, "peer interface", NULL), INIT_PARAM(device, "Ethernet device of this interface") -END_INIT_SIM_OBJECT_PARAMS(EtherDevInt) +END_INIT_SIM_OBJECT_PARAMS(NSGigEInt) -CREATE_SIM_OBJECT(EtherDevInt) +CREATE_SIM_OBJECT(NSGigEInt) { - EtherDevInt *dev_int = new EtherDevInt(getInstanceName(), device); + NSGigEInt *dev_int = new NSGigEInt(getInstanceName(), device); EtherInt *p = (EtherInt *)peer; if (p) { @@ -2313,10 +2443,10 @@ CREATE_SIM_OBJECT(EtherDevInt) return dev_int; } -REGISTER_SIM_OBJECT("EtherDevInt", EtherDevInt) +REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) -BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDev) +BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param<Tick> tx_delay; Param<Tick> rx_delay; @@ -2324,7 +2454,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDev) Param<Tick> intr_delay; SimObjectParam<MemoryController *> mmu; SimObjectParam<PhysicalMemory *> physmem; - Param<Addr> addr; Param<bool> rx_filter; Param<string> hardware_address; SimObjectParam<Bus*> header_bus; @@ -2344,9 +2473,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDev) Param<uint32_t> pci_dev; Param<uint32_t> pci_func; -END_DECLARE_SIM_OBJECT_PARAMS(EtherDev) +END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) -BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDev) +BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), @@ -2354,7 +2483,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDev) INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), - INIT_PARAM(addr, "Device Address"), INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", "00:99:00:00:00:01"), @@ -2375,22 +2503,21 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDev) INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code") -END_INIT_SIM_OBJECT_PARAMS(EtherDev) +END_INIT_SIM_OBJECT_PARAMS(NSGigE) -CREATE_SIM_OBJECT(EtherDev) +CREATE_SIM_OBJECT(NSGigE) { int eaddr[6]; sscanf(((string)hardware_address).c_str(), "%x:%x:%x:%x:%x:%x", &eaddr[0], &eaddr[1], &eaddr[2], &eaddr[3], &eaddr[4], &eaddr[5]); - return new EtherDev(getInstanceName(), intr_ctrl, intr_delay, - physmem, tx_delay, rx_delay, mmu, hier, header_bus, - payload_bus, pio_latency, dma_desc_free, dma_data_free, - dma_read_delay, dma_write_delay, dma_read_factor, - dma_write_factor, configspace, configdata, - tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr, - addr); + return new NSGigE(getInstanceName(), intr_ctrl, intr_delay, + physmem, tx_delay, rx_delay, mmu, hier, header_bus, + payload_bus, pio_latency, dma_desc_free, dma_data_free, + dma_read_delay, dma_write_delay, dma_read_factor, + dma_write_factor, configspace, configdata, + tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr); } -REGISTER_SIM_OBJECT("EtherDev", EtherDev) +REGISTER_SIM_OBJECT("NSGigE", NSGigE) diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index cb6550720..25a7781e5 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -96,7 +96,7 @@ struct dp_rom { }; class IntrControl; -class EtherDevInt; +class NSGigEInt; class PhysicalMemory; class BaseInterface; class HierParams; @@ -106,7 +106,7 @@ class PciConfigAll; /** * NS DP82830 Ethernet device model */ -class EtherDev : public PciDev +class NSGigE : public PciDev { public: /** Transmit State Machine states */ @@ -158,12 +158,21 @@ class EtherDev : public PciDev dp_regs regs; dp_rom rom; - /*** BASIC STRUCTURES FOR TX/RX ***/ + /** pci settings */ + bool io_enable; +#if 0 + bool mem_enable; + bool bm_enable; +#endif + + /*** BASIC STRUCTURES FOR TX/RX ***/ /* Data FIFOs */ pktbuf_t txFifo; pktbuf_t rxFifo; /** various helper vars */ + PacketPtr txPacket; + PacketPtr rxPacket; uint8_t *txPacketBufPtr; uint8_t *rxPacketBufPtr; uint32_t txXferLen; @@ -171,8 +180,6 @@ class EtherDev : public PciDev uint32_t txPktXmitted; bool rxDmaFree; bool txDmaFree; - PacketPtr txPacket; - PacketPtr rxPacket; /** DescCaches */ ns_desc txDescCache; @@ -236,20 +243,20 @@ class EtherDev : public PciDev void txDmaWriteCopy(); void rxDmaReadDone(); - friend class EventWrapper<EtherDev, &EtherDev::rxDmaReadDone>; - EventWrapper<EtherDev, &EtherDev::rxDmaReadDone> rxDmaReadEvent; + friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>; + EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent; void rxDmaWriteDone(); - friend class EventWrapper<EtherDev, &EtherDev::rxDmaWriteDone>; - EventWrapper<EtherDev, &EtherDev::rxDmaWriteDone> rxDmaWriteEvent; + friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>; + EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent; void txDmaReadDone(); - friend class EventWrapper<EtherDev, &EtherDev::txDmaReadDone>; - EventWrapper<EtherDev, &EtherDev::txDmaReadDone> txDmaReadEvent; + friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>; + EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent; void txDmaWriteDone(); - friend class EventWrapper<EtherDev, &EtherDev::txDmaWriteDone>; - EventWrapper<EtherDev, &EtherDev::txDmaWriteDone> txDmaWriteEvent; + friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>; + EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent; bool dmaDescFree; bool dmaDataFree; @@ -261,34 +268,23 @@ class EtherDev : public PciDev void txReset(); void rxReset(); - void regsReset() { - memset(®s, 0, sizeof(regs)); - regs.config = 0x80000000; - regs.mear = 0x12; - regs.isr = 0x00608000; - regs.txcfg = 0x120; - regs.rxcfg = 0x4; - regs.srr = 0x0103; - regs.mibc = 0x2; - regs.vdr = 0x81; - regs.tesr = 0xc000; - } + void regsReset(); void rxKick(); Tick rxKickTick; - typedef EventWrapper<EtherDev, &EtherDev::rxKick> RxKickEvent; + typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent; friend class RxKickEvent; void txKick(); Tick txKickTick; - typedef EventWrapper<EtherDev, &EtherDev::txKick> TxKickEvent; + typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent; friend class TxKickEvent; /** * Retransmit event */ void transmit(); - typedef EventWrapper<EtherDev, &EtherDev::transmit> TxEvent; + typedef EventWrapper<NSGigE, &NSGigE::transmit> TxEvent; friend class TxEvent; TxEvent txEvent; @@ -323,7 +319,7 @@ class EtherDev : public PciDev void cpuInterrupt(); void cpuIntrClear(); - typedef EventWrapper<EtherDev, &EtherDev::cpuInterrupt> IntrEvent; + typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent; friend class IntrEvent; IntrEvent *intrEvent; @@ -335,18 +331,18 @@ class EtherDev : public PciDev bool ipChecksum(PacketPtr packet, bool gen); uint16_t checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len); - EtherDevInt *interface; + NSGigEInt *interface; public: - EtherDev(const std::string &name, IntrControl *i, Tick intr_delay, + NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay, MemoryController *mmu, HierParams *hier, Bus *header_bus, Bus *payload_bus, Tick pio_latency, bool dma_desc_free, bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], Addr addr); - ~EtherDev(); + uint32_t func, bool rx_filter, const int eaddr[6]); + ~NSGigE(); virtual void WriteConfig(int offset, int size, uint32_t data); virtual void ReadConfig(int offset, int size, uint8_t *data); @@ -360,7 +356,7 @@ class EtherDev : public PciDev bool recvPacket(PacketPtr packet); void transferDone(); - void setInterface(EtherDevInt *i) { assert(!interface); interface = i; } + void setInterface(NSGigEInt *i) { assert(!interface); interface = i; } virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); @@ -369,14 +365,14 @@ class EtherDev : public PciDev void regStats(); private: - Statistics::Scalar<> txBytes; - Statistics::Scalar<> rxBytes; - Statistics::Scalar<> txPackets; - Statistics::Scalar<> rxPackets; - Statistics::Formula txBandwidth; - Statistics::Formula rxBandwidth; - Statistics::Formula txPacketRate; - Statistics::Formula rxPacketRate; + Stats::Scalar<> txBytes; + Stats::Scalar<> rxBytes; + Stats::Scalar<> txPackets; + Stats::Scalar<> rxPackets; + Stats::Formula txBandwidth; + Stats::Formula rxBandwidth; + Stats::Formula txPacketRate; + Stats::Formula rxPacketRate; private: Tick pioLatency; @@ -388,13 +384,13 @@ class EtherDev : public PciDev /* * Ethernet Interface for an Ethernet Device */ -class EtherDevInt : public EtherInt +class NSGigEInt : public EtherInt { private: - EtherDev *dev; + NSGigE *dev; public: - EtherDevInt(const std::string &name, EtherDev *d) + NSGigEInt(const std::string &name, NSGigE *d) : EtherInt(name), dev(d) { dev->setInterface(this); } virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); } diff --git a/dev/ns_gige_reg.h b/dev/ns_gige_reg.h index 774fec435..c87dfe960 100644 --- a/dev/ns_gige_reg.h +++ b/dev/ns_gige_reg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 226fd2749..8937b8e67 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,22 +35,29 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" -#include "dev/scsi_ctrl.hh" #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; -PciConfigAll::PciConfigAll(const string &name, Addr a, - MemoryController *mmu) - : FunctionalMemory(name), addr(a) +PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu, + HierParams *hier, Bus *bus) + : PioDevice(name), addr(a) { mmu->add_child(this, Range<Addr>(addr, addr + size)); + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &PciConfigAll::cacheAccess); + pioInterface->addAddrRange(addr, addr + size - 1); + } + // Make all the pointers to devices null for(int x=0; x < MAX_PCI_DEV; x++) for(int y=0; y < MAX_PCI_FUNC; y++) @@ -148,13 +155,27 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data) void PciConfigAll::serialize(std::ostream &os) { - // code should be written + /* + * There is no state associated with this object that requires + * serialization. The only real state are the device pointers + * which are all setup by the constructor of the PciDev class + */ } void PciConfigAll::unserialize(Checkpoint *cp, const std::string §ion) { - //code should be written + /* + * There is no state associated with this object that requires + * serialization. The only real state are the device pointers + * which are all setup by the constructor of the PciDev class + */ +} + +Tick +PciConfigAll::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; } #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -164,6 +185,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) SimObjectParam<MemoryController *> mmu; Param<Addr> addr; Param<Addr> mask; + SimObjectParam<Bus*> io_bus; + SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) @@ -171,13 +194,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigAll) INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mask, "Address Mask") + INIT_PARAM(mask, "Address Mask"), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(PciConfigAll) CREATE_SIM_OBJECT(PciConfigAll) { - return new PciConfigAll(getInstanceName(), addr, mmu); + return new PciConfigAll(getInstanceName(), addr, mmu, hier, io_bus); } REGISTER_SIM_OBJECT("PciConfigAll", PciConfigAll) diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index 6df1e2fe7..356e62a3c 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,11 +34,13 @@ #ifndef __PCICONFIGALL_HH__ #define __PCICONFIGALL_HH__ -#include "mem/functional_mem/functional_memory.hh" #include "dev/pcireg.h" +#include "base/range.hh" +#include "dev/io_device.hh" -#define MAX_PCI_DEV 32 -#define MAX_PCI_FUNC 8 + +static const uint32_t MAX_PCI_DEV = 32; +static const uint32_t MAX_PCI_FUNC = 8; class PciDev; @@ -49,30 +51,89 @@ class PciDev; * space and passes the requests on to TsunamiPCIDev devices as * appropriate. */ -class PciConfigAll : public FunctionalMemory +class PciConfigAll : public PioDevice { private: Addr addr; static const Addr size = 0xffffff; - public: /** * Pointers to all the devices that are registered with this * particular config space. */ PciDev* devices[MAX_PCI_DEV][MAX_PCI_FUNC]; + public: /** - * The default constructor. - */ - PciConfigAll(const std::string &name, Addr a, MemoryController *mmu); + * Constructor for PCIConfigAll + * @param name name of the object + * @param a base address of the write + * @param mmu the memory controller + * @param hier object to store parameters universal the device hierarchy + * @param bus The bus that this device is attached to + */ + PciConfigAll(const std::string &name, Addr a, MemoryController *mmu, + HierParams *hier, Bus *bus); + + + /** + * Check if a device exists. + * @param pcidev PCI device to check + * @param pcifunc PCI function to check + * @return true if device exists, false otherwise + */ + bool deviceExists(uint32_t pcidev, uint32_t pcifunc) + { return devices[pcidev][pcifunc] != NULL ? true : false; } + + /** + * Registers a device with the config space object. + * @param pcidev PCI device to register + * @param pcifunc PCI function to register + * @param device device to register + */ + void registerDevice(uint8_t pcidev, uint8_t pcifunc, PciDev *device) + { devices[pcidev][pcifunc] = device; } + /** + * Read something in PCI config space. If the device does not exist + * -1 is returned, if the device does exist its PciDev::ReadConfig (or the + * virtual function that overrides) it is called. + * @param req Contains the address of the field to read. + * @param data Return the field read. + * @return The fault condition of the access. + */ virtual Fault read(MemReqPtr &req, uint8_t *data); + + /** + * Write to PCI config spcae. If the device does not exit the simulator + * panics. If it does it is passed on the PciDev::WriteConfig (or the virtual + * function that overrides it). + * @param req Contains the address to write to. + * @param data The data to write. + * @return The fault condition of the access. + */ + virtual Fault write(MemReqPtr &req, const uint8_t *data); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ + Tick cacheAccess(MemReqPtr &req); }; #endif // __PCICONFIGALL_HH__ diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 9ac170b5c..01f336ff8 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,10 +64,10 @@ PciDev::PciDev(const string &name, MemoryController *mmu, PciConfigAll *cf, panic("NULL pointer to configuration data"); // Setup pointer in config space to point to this entry - if (cf->devices[dev][func] != NULL) + if (cf->deviceExists(dev,func)) panic("Two PCI devices occuping same dev: %#x func: %#x", dev, func); else - cf->devices[dev][func] = this; + cf->registerDevice(dev, func, this); } void @@ -247,7 +247,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) break; default: - panic("writing to a read only register"); + DPRINTF(PCIDEV, "Writing to a read only register"); } break; } @@ -256,13 +256,26 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) void PciDev::serialize(ostream &os) { + SERIALIZE_ARRAY(BARSize, 6); + SERIALIZE_ARRAY(BARAddrs, 6); SERIALIZE_ARRAY(config.data, 64); } void PciDev::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_ARRAY(BARSize, 6); + UNSERIALIZE_ARRAY(BARAddrs, 6); UNSERIALIZE_ARRAY(config.data, 64); + + // Add the MMU mappings for the BARs + for (int i=0; i < 6; i++) { + if (BARAddrs[i] != 0) + mmu->add_child((FunctionalMemory *)this, + Range<Addr>(BARAddrs[i], + BARAddrs[i] + + BARSize[i] - 1)); + } } #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pcidev.hh b/dev/pcidev.hh index f8192db3c..c0fe47ac4 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,9 +39,17 @@ class PciConfigAll; class MemoryController; + +/** + * This class encapulates the first 64 bytes of a singles PCI + * devices config space that in configured by the configuration file. + */ class PciConfigData : public SimObject { public: + /** + * Constructor to initialize the devices config space to 0. + */ PciConfigData(const std::string &name) : SimObject(name) { @@ -50,8 +58,13 @@ class PciConfigData : public SimObject memset(BARSize, 0, sizeof(BARSize)); } + /** The first 64 bytes */ PCIConfig config; + + /** The size of the BARs */ uint32_t BARSize[6]; + + /** The addresses of the BARs */ Addr BARAddrs[6]; }; @@ -66,17 +79,50 @@ class PciDev : public DmaDevice { protected: MemoryController *mmu; + /** A pointer to the configspace all object that calls + * us when a read comes to this particular device/function. + */ PciConfigAll *configSpace; + + /** + * A pointer to the object that contains the first 64 bytes of + * config space + */ PciConfigData *configData; + + /** The bus number we are on */ uint32_t busNum; + + /** The device number we have */ uint32_t deviceNum; + + /** The function number */ uint32_t functionNum; + /** The current config space. Unlike the PciConfigData this is updated + * during simulation while continues to refelect what was in the config file. + */ PCIConfig config; + + /** The size of the BARs */ uint32_t BARSize[6]; + + /** The current address mapping of the BARs */ Addr BARAddrs[6]; public: + /** + * Constructor for PCI Dev. This function copies data from the config file + * object PCIConfigData and registers the device with a PciConfigAll object. + * @param name name of the object + * @param mmu a pointer to the memory controller + * @param cf a pointer to the config space object that this device need to + * register with + * @param cd A pointer to the config space values specified in the conig file + * @param bus the bus this device is on + * @param dev the device id of this device + * @param func the function number of this device + */ PciDev(const std::string &name, MemoryController *mmu, PciConfigAll *cf, PciConfigData *cd, uint32_t bus, uint32_t dev, uint32_t func); @@ -87,10 +133,38 @@ class PciDev : public DmaDevice return No_Fault; } + /** + * Write to the PCI config space data that is stored locally. This may be + * overridden by the device but at some point it will eventually call this + * for normal operations that it does not need to override. + * @param offset the offset into config space + * @param size the size of the write + * @param data the data to write + */ virtual void WriteConfig(int offset, int size, uint32_t data); + + + /** + * Read from the PCI config space data that is stored locally. This may be + * overridden by the device but at some point it will eventually call this + * for normal operations that it does not need to override. + * @param offset the offset into config space + * @param size the size of the read + * @param data pointer to the location where the read value should be stored + */ virtual void ReadConfig(int offset, int size, uint8_t *data); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); }; diff --git a/dev/pcireg.h b/dev/pcireg.h index 2921c30be..8e8b7b451 100644 --- a/dev/pcireg.h +++ b/dev/pcireg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -114,6 +114,11 @@ union PCIConfig { #define PCI_HEADER_TYPE 0x0E // Header Type ro #define PCI_BIST 0x0F // Built in self test rw +// some pci command reg bitfields +#define PCI_CMD_BME 0x04 // Bus master function enable +#define PCI_CMD_MSE 0x02 // Memory Space Access enable +#define PCI_CMD_IOSE 0x01 // I/O space enable + // Type 0 PCI offsets #define PCI0_BASE_ADDR0 0x10 // Base Address 0 rw #define PCI0_BASE_ADDR1 0x14 // Base Address 1 rw diff --git a/dev/platform.cc b/dev/platform.cc index c39849162..8515d543a 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/platform.hh b/dev/platform.hh index 407f58406..f0e3d291b 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,6 +60,7 @@ class Platform : public SimObject virtual ~Platform() {} virtual void postConsoleInt() = 0; virtual void clearConsoleInt() = 0; + virtual Tick intrFrequency() = 0; }; #endif // __PLATFORM_HH_ diff --git a/dev/simple_disk.cc b/dev/simple_disk.cc index aa6ff5b38..19e8683df 100644 --- a/dev/simple_disk.cc +++ b/dev/simple_disk.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh index 935865ba4..3031cdb8b 100644 --- a/dev/simple_disk.hh +++ b/dev/simple_disk.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/dev/tsunami.cc b/dev/tsunami.cc index 8956ee557..1cdd7d726 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,6 +56,12 @@ Tsunami::Tsunami(const string &name, System *s, intr_sum_type[i] = 0; } +Tick +Tsunami::intrFrequency() +{ + return io->frequency(); +} + void Tsunami::postConsoleInt() { diff --git a/dev/tsunami.hh b/dev/tsunami.hh index f619e4cff..db266d62d 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,7 +39,7 @@ class IdeController; class TlaserClock; -class EtherDev; +class NSGigE; class TsunamiCChip; class TsunamiPChip; class TsunamiIO; @@ -67,7 +67,7 @@ class Tsunami : public Platform /** Pointer to the disk controller device */ IdeController *disk_controller; /** Pointer to the ethernet controller device */ - EtherDev *ethernet; + NSGigE *ethernet; /** Pointer to the Tsunami CChip. * The chip contains some configuration information and @@ -95,10 +95,33 @@ class Tsunami : public Platform Tsunami(const std::string &name, System *s, IntrControl *intctrl, PciConfigAll *pci, int intrFreq); + /** + * Return the interrupting frequency to AlphaAccess + * @return frequency of RTC interrupts + */ + virtual Tick intrFrequency(); + + /** + * Cause the cpu to post a serial interrupt to the CPU. + */ virtual void postConsoleInt(); + + /** + * Clear a posted CPU interrupt (id=55) + */ virtual void clearConsoleInt(); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); }; diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index ba49c361b..a64f643a2 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -1,4 +1,30 @@ -/* $Id$ */ +/* + * Copyright (c) 2004 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. + */ /* @file * Emulation of the Tsunami CChip CSRs @@ -9,21 +35,23 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/console.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "cpu/intr_control.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" +#include "cpu/intr_control.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu) - : FunctionalMemory(name), addr(a), tsunami(t) + MemoryController *mmu, HierParams *hier, Bus* bus) + : PioDevice(name), addr(a), tsunami(t) { mmu->add_child(this, Range<Addr>(addr, addr + size)); @@ -35,6 +63,12 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, RTCInterrupting[i] = false; } + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &TsunamiCChip::cacheAccess); + pioInterface->addAddrRange(addr, addr + size - 1); + } + drir = 0; misc = 0; @@ -68,7 +102,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - panic("TSDEV_CC_AARx not implemeted\n"); + *(uint64_t*)data = 0; return No_Fault; case TSDEV_CC_DIM0: *(uint64_t*)data = dim[0]; @@ -131,8 +165,8 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) Fault TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) { - DPRINTF(Tsunami, "write - va=%#x size=%d \n", - req->vaddr, req->size); + DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", + req->vaddr, *(uint64_t*)data, req->size); Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; @@ -195,6 +229,11 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) } supportedWrite = true; } + + // ignore NXMs + if (*(uint64_t*)data & 0x10000000) + supportedWrite = true; + if(!supportedWrite) panic("TSDEV_CC_MISC write not implemented\n"); return No_Fault; case TSDEV_CC_AAR0: @@ -342,6 +381,13 @@ TsunamiCChip::clearDRIR(uint32_t interrupt) DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); } +Tick +TsunamiCChip::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} + + void TsunamiCChip::serialize(std::ostream &os) { @@ -371,6 +417,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) SimObjectParam<Tsunami *> tsunami; SimObjectParam<MemoryController *> mmu; Param<Addr> addr; + SimObjectParam<Bus*> io_bus; + SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) @@ -378,13 +426,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) INIT_PARAM(tsunami, "Tsunami"), INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address") + INIT_PARAM(addr, "Device Address"), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) CREATE_SIM_OBJECT(TsunamiCChip) { - return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu); + return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, io_bus); } REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh index adb05a572..a358c98ba 100644 --- a/dev/tsunami_cchip.hh +++ b/dev/tsunami_cchip.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,24 +33,28 @@ #ifndef __TSUNAMI_CCHIP_HH__ #define __TSUNAMI_CCHIP_HH__ -#include "mem/functional_mem/functional_memory.hh" #include "dev/tsunami.hh" +#include "base/range.hh" +#include "dev/io_device.hh" /* * Tsunami CChip */ -class TsunamiCChip : public FunctionalMemory +class TsunamiCChip : public PioDevice { private: + /** The base address of this device */ Addr addr; + + /** The size of mappad from the above address */ static const Addr size = 0xfff; protected: - /** - * pointer to the tsunami object. - * This is our access to all the other tsunami - * devices. - */ + /** + * pointer to the tsunami object. + * This is our access to all the other tsunami + * devices. + */ Tsunami *tsunami; /** @@ -72,24 +76,85 @@ class TsunamiCChip : public FunctionalMemory */ uint64_t drir; + /** + * The MISC register contains the CPU we are currently on + * as well as bits to ack RTC and IPI interrupts. + */ uint64_t misc; + /** Count of the number of pending IPIs on a CPU */ uint64_t ipiInterrupting[Tsunami::Max_CPUs]; + + /** Indicator of which CPUs have had an RTC interrupt */ bool RTCInterrupting[Tsunami::Max_CPUs]; public: + /** + * Initialize the Tsunami CChip by setting all of the + * device register to 0. + * @param name name of this device. + * @param t pointer back to the Tsunami object that we belong to. + * @param a address we are mapped at. + * @param mmu pointer to the memory controller that sends us events. + * @param hier object to store parameters universal the device hierarchy + * @param bus The bus that this device is attached to + */ TsunamiCChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu); + MemoryController *mmu, HierParams *hier, Bus *bus); + /** + * Process a read to the CChip. + * @param req Contains the address to read from. + * @param data A pointer to write the read data to. + * @return The fault condition of the access. + */ virtual Fault read(MemReqPtr &req, uint8_t *data); + + + /** + * Process a write to the CChip. + * @param req Contains the address to write to. + * @param data The data to write. + * @return The fault condition of the access. + */ virtual Fault write(MemReqPtr &req, const uint8_t *data); + /** + * post an RTC interrupt to the CPU + */ void postRTC(); + + /** + * post an interrupt to the CPU. + * @param interrupt the interrupt number to post (0-64) + */ void postDRIR(uint32_t interrupt); + + /** + * clear an interrupt previously posted to the CPU. + * @param interrupt the interrupt number to post (0-64) + */ void clearDRIR(uint32_t interrupt); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ + Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_CCHIP_HH__ diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 2dda86fbc..ea530b3d2 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,15 +37,16 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/console.hh" -#include "dev/tlaser_clock.hh" #include "dev/tsunami_io.hh" -#include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/functional_mem/memory_control.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "sim/builder.hh" #include "dev/tsunami_cchip.hh" +#include "dev/tsunamireg.h" +#include "mem/functional_mem/memory_control.hh" using namespace std; @@ -75,6 +76,22 @@ TsunamiIO::RTCEvent::description() return "tsunami RTC 1024Hz interrupt"; } +void +TsunamiIO::RTCEvent::serialize(std::ostream &os) +{ + Tick time = when(); + SERIALIZE_SCALAR(time); +} + +void +TsunamiIO::RTCEvent::unserialize(Checkpoint *cp, const std::string §ion) +{ + Tick time; + UNSERIALIZE_SCALAR(time); + reschedule(time); +} + + // Timer Event for PIT Timers TsunamiIO::ClockEvent::ClockEvent() : Event(&mainEventQueue) @@ -121,12 +138,40 @@ TsunamiIO::ClockEvent::Status() return status; } +void +TsunamiIO::ClockEvent::serialize(std::ostream &os) +{ + Tick time = scheduled() ? when() : 0; + SERIALIZE_SCALAR(time); + SERIALIZE_SCALAR(status); + SERIALIZE_SCALAR(mode); + SERIALIZE_SCALAR(interval); +} + +void +TsunamiIO::ClockEvent::unserialize(Checkpoint *cp, const std::string §ion) +{ + Tick time; + UNSERIALIZE_SCALAR(time); + UNSERIALIZE_SCALAR(status); + UNSERIALIZE_SCALAR(mode); + UNSERIALIZE_SCALAR(interval); + if (time) + schedule(time); +} + TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu) - : FunctionalMemory(name), addr(a), tsunami(t), rtc(t) + Addr a, MemoryController *mmu, HierParams *hier, Bus *bus) + : PioDevice(name), addr(a), tsunami(t), rtc(t) { mmu->add_child(this, Range<Addr>(addr, addr + size)); + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &TsunamiIO::cacheAccess); + pioInterface->addAddrRange(addr, addr + size - 1); + } + // set the back pointer from tsunami to myself tsunami->io = this; @@ -243,8 +288,11 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) Fault TsunamiIO::write(MemReqPtr &req, const uint8_t *data) { + +#if TRACING_ON uint8_t dt = *(uint8_t*)data; uint64_t dt64 = dt; +#endif DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", req->vaddr, req->size, req->vaddr & 0xfff, dt64); @@ -375,20 +423,32 @@ TsunamiIO::clearPIC(uint8_t bitvector) } } +Tick +TsunamiIO::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} + void TsunamiIO::serialize(std::ostream &os) { SERIALIZE_SCALAR(timerData); SERIALIZE_SCALAR(uip); + SERIALIZE_SCALAR(mask1); + SERIALIZE_SCALAR(mask2); + SERIALIZE_SCALAR(mode1); + SERIALIZE_SCALAR(mode2); SERIALIZE_SCALAR(picr); SERIALIZE_SCALAR(picInterrupting); - Tick time0when = timer0.when(); - Tick time2when = timer2.when(); - Tick rtcwhen = rtc.when(); - SERIALIZE_SCALAR(time0when); - SERIALIZE_SCALAR(time2when); - SERIALIZE_SCALAR(rtcwhen); - + SERIALIZE_SCALAR(RTCAddress); + + // Serialize the timers + nameOut(os, csprintf("%s.timer0", name())); + timer0.serialize(os); + nameOut(os, csprintf("%s.timer2", name())); + timer2.serialize(os); + nameOut(os, csprintf("%s.rtc", name())); + rtc.serialize(os); } void @@ -396,17 +456,18 @@ TsunamiIO::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(timerData); UNSERIALIZE_SCALAR(uip); + UNSERIALIZE_SCALAR(mask1); + UNSERIALIZE_SCALAR(mask2); + UNSERIALIZE_SCALAR(mode1); + UNSERIALIZE_SCALAR(mode2); UNSERIALIZE_SCALAR(picr); UNSERIALIZE_SCALAR(picInterrupting); - Tick time0when; - Tick time2when; - Tick rtcwhen; - UNSERIALIZE_SCALAR(time0when); - UNSERIALIZE_SCALAR(time2when); - UNSERIALIZE_SCALAR(rtcwhen); - timer0.reschedule(time0when); - timer2.reschedule(time2when); - rtc.reschedule(rtcwhen); + UNSERIALIZE_SCALAR(RTCAddress); + + // Unserialize the timers + timer0.unserialize(cp, csprintf("%s.timer0", section)); + timer2.unserialize(cp, csprintf("%s.timer2", section)); + rtc.unserialize(cp, csprintf("%s.rtc", section)); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) @@ -415,6 +476,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) Param<time_t> time; SimObjectParam<MemoryController *> mmu; Param<Addr> addr; + SimObjectParam<Bus*> io_bus; + SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) @@ -424,13 +487,16 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) INIT_PARAM_DFLT(time, "System time to use " "(0 for actual time, default is 1/1/06", ULL(1136073600)), INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address") + INIT_PARAM(addr, "Device Address"), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) CREATE_SIM_OBJECT(TsunamiIO) { - return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu); + return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier, + io_bus); } REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index 90bef2b86..e6a545689 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,78 +33,173 @@ #ifndef __TSUNAMI_DMA_HH__ #define __TSUNAMI_DMA_HH__ -#define RTC_RATE 1024 - -#include "mem/functional_mem/functional_memory.hh" +#include "dev/io_device.hh" +#include "base/range.hh" #include "dev/tsunami.hh" +/** How often the RTC interrupts */ +static const int RTC_RATE = 1024; + /* - * Tsunami I/O device + * Tsunami I/O device is a catch all for all the south bridge stuff we care + * to implement. */ -class TsunamiIO : public FunctionalMemory +class TsunamiIO : public PioDevice { private: + /** The base address of this device */ Addr addr; + + /** The size of mappad from the above address */ static const Addr size = 0xff; struct tm tm; - // In Tsunami RTC only has two i/o ports - // one for data and one for address, so you - // write the address and then read/write the data + /** In Tsunami RTC only has two i/o ports one for data and one for address, + * so you write the address and then read/write the data. This store the + * address you are going to be reading from on a read. + */ uint8_t RTCAddress; protected: + /** + * The ClockEvent is handles the PIT interrupts + */ class ClockEvent : public Event { protected: + /** how often the PIT fires */ Tick interval; + /** The mode of the PIT */ uint8_t mode; + /** The status of the PIT */ uint8_t status; public: + /** + * Just set the mode to 0 + */ ClockEvent(); + /** + * processs the timer event + */ virtual void process(); + + /** + * Returns a description of this event + * @return the description + */ virtual const char *description(); + + /** + * Schedule a timer interrupt to occur sometime in the future. + */ void Program(int count); + + /** + * Write the mode bits of the PIT. + * @param mode the new mode + */ void ChangeMode(uint8_t mode); + + /** + * The current PIT status. + * @return the status of the PIT + */ uint8_t Status(); - }; + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; + + /** + * Process RTC timer events and generate interrupts appropriately. + */ class RTCEvent : public Event { protected: - Tsunami* tsunami; + /** A pointer back to tsunami to create interrupt the processor. */ + Tsunami* tsunami; public: - RTCEvent(Tsunami* t); + /** RTC Event initializes the RTC event by scheduling an event + * RTC_RATE times pre second. */ + RTCEvent(Tsunami* t); - virtual void process(); - virtual const char *description(); - }; + /** + * Interrupth the processor and reschedule the event. + * */ + virtual void process(); + + /** + * Return a description of this event. + * @return a description + */ + virtual const char *description(); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; + + /** uip UpdateInProgess says that the rtc is updating, but we just fake it + * by alternating it on every read of the bit since we are going to + * override the loop_per_jiffy time that it is trying to use the UIP to + * calculate. + */ uint8_t uip; + /** Mask of the PIC1 */ uint8_t mask1; + + /** Mask of the PIC2 */ uint8_t mask2; + + /** Mode of PIC1. Not used for anything */ uint8_t mode1; + + /** Mode of PIC2. Not used for anything */ uint8_t mode2; - uint8_t picr; //Raw PIC interrput register, before masking + /** Raw PIC interrupt register before masking */ + uint8_t picr; //Raw PIC interrput register + + /** Is the pic interrupting right now or not. */ bool picInterrupting; + /** A pointer to the Tsunami device which be belong to */ Tsunami *tsunami; - /* + /** * This timer is initilized, but after I wrote the code * it doesn't seem to be used again, and best I can tell * it too is not connected to any interrupt port */ ClockEvent timer0; - /* + /** * This timer is used to control the speaker, which * we normally could care less about, however it is * also used to calculated the clockspeed and hense @@ -114,27 +209,84 @@ class TsunamiIO : public FunctionalMemory */ ClockEvent timer2; + /** This is the event used to interrupt the cpu like an RTC. */ RTCEvent rtc; + /** The interval is set via two writes to the PIT. + * This variable contains a flag as to how many writes have happened, and + * the time so far. + */ uint32_t timerData; public: - uint32_t frequency() const { return RTC_RATE; } + /** + * Return the freqency of the RTC + * @return interrupt rate of the RTC + */ + Tick frequency() const { return RTC_RATE; } + + /** + * Initialize all the data for devices supported by Tsunami I/O. + * @param name name of this device. + * @param t pointer back to the Tsunami object that we belong to. + * @param init_time Time (as in seconds since 1970) to set RTC to. + * @param a address we are mapped at. + * @param mmu pointer to the memory controller that sends us events. + */ TsunamiIO(const std::string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu); + Addr a, MemoryController *mmu, HierParams *hier, Bus *bus); + /** + * Create the tm struct from seconds since 1970 + */ void set_time(time_t t); + /** + * Process a read to one of the devices we are emulating. + * @param req Contains the address to read from. + * @param data A pointer to write the read data to. + * @return The fault condition of the access. + */ virtual Fault read(MemReqPtr &req, uint8_t *data); + + /** + * Process a write to one of the devices we emulate. + * @param req Contains the address to write to. + * @param data The data to write. + * @return The fault condition of the access. + */ virtual Fault write(MemReqPtr &req, const uint8_t *data); + /** + * Post an PIC interrupt to the CPU via the CChip + * @param bitvector interrupt to post. + */ void postPIC(uint8_t bitvector); + + /** + * Clear a posted interrupt + * @param bitvector interrupt to clear + */ void clearPIC(uint8_t bitvector); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + + Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_IO_HH__ diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index dabf6bf40..b1346bb1a 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -1,4 +1,30 @@ -/* $Id$ */ +/* + * Copyright (c) 2004 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. + */ /* @file * Tsunami PChip (pci) @@ -9,14 +35,12 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" -#include "dev/console.hh" -#include "dev/etherdev.hh" -#include "dev/scsi_ctrl.hh" -#include "dev/tlaser_clock.hh" #include "dev/tsunami_pchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/pio_interface.hh" +#include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" #include "mem/functional_mem/physical_memory.hh" #include "sim/builder.hh" @@ -25,8 +49,9 @@ using namespace std; TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu) - : FunctionalMemory(name), addr(a), tsunami(t) + MemoryController *mmu, HierParams *hier, + Bus *bus) + : PioDevice(name), addr(a), tsunami(t) { mmu->add_child(this, Range<Addr>(addr, addr + size)); @@ -36,6 +61,16 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, tba[i] = 0; } + if (bus) { + pioInterface = newPioInterface(name, hier, bus, this, + &TsunamiPChip::cacheAccess); + pioInterface->addAddrRange(addr, addr + size - 1); + } + + + // initialize pchip control register + pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); + //Set back pointer in tsunami tsunami->pchip = this; } @@ -47,8 +82,6 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) req->vaddr, req->size); Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; -// ExecContext *xc = req->xc; -// int cpuid = xc->cpu_id; switch (req->size) { @@ -91,17 +124,18 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) *(uint64_t*)data = tba[3]; return No_Fault; case TSDEV_PC_PCTL: - // might want to change the clock?? - *(uint64_t*)data = 0x00; // try this + *(uint64_t*)data = pctl; return No_Fault; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); case TSDEV_PC_RES: panic("PC_RES not implemented\n"); case TSDEV_PC_PERROR: - panic("PC_PERROR not implemented\n"); + *(uint64_t*)data = 0x00; + return No_Fault; case TSDEV_PC_PERRMASK: - panic("PC_PERRMASK not implemented\n"); + *(uint64_t*)data = 0x00; + return No_Fault; case TSDEV_PC_PERRSET: panic("PC_PERRSET not implemented\n"); case TSDEV_PC_TLBIV: @@ -179,15 +213,14 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) tba[3] = *(uint64_t*)data; return No_Fault; case TSDEV_PC_PCTL: - // might want to change the clock?? - //*(uint64_t*)data; // try this + pctl = *(uint64_t*)data; return No_Fault; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); case TSDEV_PC_RES: panic("PC_RES not implemented\n"); case TSDEV_PC_PERROR: - panic("PC_PERROR not implemented\n"); + return No_Fault; case TSDEV_PC_PERRMASK: panic("PC_PERRMASK not implemented\n"); case TSDEV_PC_PERRSET: @@ -235,12 +268,29 @@ TsunamiPChip::translatePciToDma(Addr busAddr) Addr pteAddr; Addr dmaAddr; +#if 0 + DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); for (int i = 0; i < 4; i++) { + DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", + i, wsba[i], wsm[i]); + windowBase = wsba[i]; - windowMask = ~wsm[i] & (0x7ff << 20); + windowMask = ~wsm[i] & (ULL(0xfff) << 20); if ((busAddr & windowMask) == (windowBase & windowMask)) { + DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", + i, windowBase, windowMask, (busAddr & windowMask), + (windowBase & windowMask)); + } + } +#endif + + for (int i = 0; i < 4; i++) { + + windowBase = wsba[i]; + windowMask = ~wsm[i] & (ULL(0xfff) << 20); + if ((busAddr & windowMask) == (windowBase & windowMask)) { if (wsba[i] & 0x1) { // see if enabled if (wsba[i] & 0x2) { // see if SG bit is set @@ -254,8 +304,8 @@ TsunamiPChip::translatePciToDma(Addr busAddr) to create an address for the SG page */ - tbaMask = ~(((wsm[i] & (0x7ff << 20)) >> 10) | 0x3ff); - baMask = (wsm[i] & (0x7ff << 20)) | (0x7f << 13); + tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); + baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); memcpy((void *)&pteEntry, @@ -263,10 +313,10 @@ TsunamiPChip::translatePciToDma(Addr busAddr) physmem->dma_addr(pteAddr, sizeof(uint64_t)), sizeof(uint64_t)); - dmaAddr = ((pteEntry & ~0x1) << 12) | (busAddr & 0x1fff); + dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); } else { - baMask = (wsm[i] & (0x7ff << 20)) | 0xfffff; + baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); tbaMask = ~baMask; dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); } @@ -276,12 +326,14 @@ TsunamiPChip::translatePciToDma(Addr busAddr) } } - return 0; + // if no match was found, then return the original address + return busAddr; } void TsunamiPChip::serialize(std::ostream &os) { + SERIALIZE_SCALAR(pctl); SERIALIZE_ARRAY(wsba, 4); SERIALIZE_ARRAY(wsm, 4); SERIALIZE_ARRAY(tba, 4); @@ -290,16 +342,25 @@ TsunamiPChip::serialize(std::ostream &os) void TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_SCALAR(pctl); UNSERIALIZE_ARRAY(wsba, 4); UNSERIALIZE_ARRAY(wsm, 4); UNSERIALIZE_ARRAY(tba, 4); } +Tick +TsunamiPChip::cacheAccess(MemReqPtr &req) +{ + return curTick + 1000; +} + BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) SimObjectParam<Tsunami *> tsunami; SimObjectParam<MemoryController *> mmu; Param<Addr> addr; + SimObjectParam<Bus*> io_bus; + SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) @@ -307,13 +368,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) INIT_PARAM(tsunami, "Tsunami"), INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address") + INIT_PARAM(addr, "Device Address"), + INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) CREATE_SIM_OBJECT(TsunamiPChip) { - return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu); + return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier, io_bus); } REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh index 3ed66c54c..af50872a0 100644 --- a/dev/tsunami_pchip.hh +++ b/dev/tsunami_pchip.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,38 +33,98 @@ #ifndef __TSUNAMI_PCHIP_HH__ #define __TSUNAMI_PCHIP_HH__ -#include "mem/functional_mem/functional_memory.hh" #include "dev/tsunami.hh" +#include "base/range.hh" +#include "dev/io_device.hh" /* * Tsunami PChip */ -class TsunamiPChip : public FunctionalMemory +class TsunamiPChip : public PioDevice { private: + /** The base address of this device */ Addr addr; + + /** The size of mappad from the above address */ static const Addr size = 0xfff; protected: + /** + * pointer to the tsunami object. + * This is our access to all the other tsunami + * devices. + */ Tsunami *tsunami; + /** Pchip control register */ + uint64_t pctl; + + /** Window Base addresses */ uint64_t wsba[4]; + + /** Window masks */ uint64_t wsm[4]; + + /** Translated Base Addresses */ uint64_t tba[4]; public: + /** + * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 + * @param name the name of thes device + * @param t a pointer to the tsunami device + * @param a the address which we respond to + * @param mmu the mmu we are to register with + * @param hier object to store parameters universal the device hierarchy + * @param bus The bus that this device is attached to + */ TsunamiPChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu); + MemoryController *mmu, HierParams *hier, Bus *bus); - // @todo This hack does a quick and dirty translation of the PCI bus address to - // a valid DMA address. This is described in 10-10 of the Tsunami book, should be fixed + /** + * Translate a PCI bus address to a memory address for DMA. + * @todo Andrew says this needs to be fixed. What's wrong with it? + * @param busAddr PCI address to translate. + * @return memory system address + */ Addr translatePciToDma(Addr busAddr); + /** + * Process a read to the PChip. + * @param req Contains the address to read from. + * @param data A pointer to write the read data to. + * @return The fault condition of the access. + */ virtual Fault read(MemReqPtr &req, uint8_t *data); + + /** + * Process a write to the PChip. + * @param req Contains the address to write to. + * @param data The data to write. + * @return The fault condition of the access. + */ virtual Fault write(MemReqPtr &req, const uint8_t *data); + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ virtual void unserialize(Checkpoint *cp, const std::string §ion); + + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ + Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_PCHIP_HH__ diff --git a/dev/tsunami_uart.cc b/dev/tsunami_uart.cc index 6c4c30e7d..84eb80c8a 100644 --- a/dev/tsunami_uart.cc +++ b/dev/tsunami_uart.cc @@ -34,17 +34,55 @@ using namespace std; #define CONS_INT_TX 0x01 // interrupt enable / state bits #define CONS_INT_RX 0x02 + +TsunamiUart::IntrEvent::IntrEvent(TsunamiUart *u) + : Event(&mainEventQueue), uart(u) +{ + DPRINTF(TsunamiUart, "UART Interrupt Event Initilizing\n"); +} + +const char * +TsunamiUart::IntrEvent::description() +{ + return "tsunami uart interrupt delay event"; +} + +void +TsunamiUart::IntrEvent::process() +{ + if (UART_IER_THRI & uart->IER) { + DPRINTF(TsunamiUart, "UART InterEvent, interrupting\n"); + uart->cons->raiseInt(CONS_INT_TX); + } + else + DPRINTF(TsunamiUart, "UART InterEvent, not interrupting\n"); + +} + +void +TsunamiUart::IntrEvent::scheduleIntr() +{ + DPRINTF(TsunamiUart, "Scheduling IER interrupt\n"); + if (!scheduled()) + schedule(curTick + 300); + else + reschedule(curTick + 300); +} + + + TsunamiUart::TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, HierParams *hier, Bus *bus) - : PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false) + : PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false), + intrEvent(this) { mmu->add_child(this, Range<Addr>(addr, addr + size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &TsunamiUart::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(addr, addr + size - 1); } IER = 0; @@ -74,14 +112,14 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data) switch(daddr) { case 0x5: // Status Register - { + { int status = cons->intStatus(); if (!valid_char) { - valid_char = cons->in(next_char); + valid_char = cons->in(next_char); if (!valid_char) status &= ~CONS_INT_RX; } else { - status |= CONS_INT_RX; + status |= CONS_INT_RX; } if (status_store == 3) { @@ -101,18 +139,15 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data) int reg = (1 << 2) | (1 << 5) | (1 << 6); if (status & CONS_INT_RX) reg |= (1 << 0); - *data = reg; - return No_Fault; + *data = reg; + return No_Fault; } break; - } + } case 0x0: // Data register (RX) -// if (!valid_char) -// panic("Invalid character"); - DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n", - isprint(next_char) ? next_char : ' ', next_char); + isprint(next_char) ? next_char : ' ', next_char); *data = next_char; valid_char = false; @@ -129,7 +164,11 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data) *data = 0; return No_Fault; case 0x2: - *data = 0; // This means a 8250 serial port, do we want a 16550? + // High two bits need to be clear for an 8250 (simple) serial port + // Low bit of IIR is 0 for a pending interrupt, 1 otherwise. + int status = cons->intStatus(); + status = (status & 0x1) | (status >> 1); + *data = (~status) & 0x1 ; return No_Fault; } *data = 0; @@ -178,15 +217,20 @@ TsunamiUart::write(MemReqPtr &req, const uint8_t *data) ourchar = *(uint64_t *)data; if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C)) cons->out(ourchar); - if (UART_IER_THRI & IER) - cons->setInt(CONS_INT_TX); + cons->clearInt(CONS_INT_TX); + intrEvent.scheduleIntr(); return No_Fault; break; - case 0x1: // DLM - DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data); + case 0x1: // IER IER = *(uint8_t*)data; + DPRINTF(TsunamiUart, "writing to IER [%#x]\n", IER); if (UART_IER_THRI & IER) - cons->setInt(CONS_INT_TX); + cons->raiseInt(CONS_INT_TX); + else { + cons->clearInt(CONS_INT_TX); + if (intrEvent.scheduled()) + intrEvent.deschedule(); + } return No_Fault; break; case 0x4: // MCR @@ -211,6 +255,14 @@ TsunamiUart::serialize(ostream &os) SERIALIZE_SCALAR(next_char); SERIALIZE_SCALAR(valid_char); SERIALIZE_SCALAR(IER); + Tick intrwhen; + if (intrEvent.scheduled()) + intrwhen = intrEvent.when(); + else + intrwhen = 0; + SERIALIZE_SCALAR(intrwhen); + + } void @@ -220,6 +272,11 @@ TsunamiUart::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(next_char); UNSERIALIZE_SCALAR(valid_char); UNSERIALIZE_SCALAR(IER); + Tick intrwhen; + UNSERIALIZE_SCALAR(intrwhen); + if (intrwhen != 0) + intrEvent.schedule(intrwhen); + } BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart) diff --git a/dev/tsunami_uart.hh b/dev/tsunami_uart.hh index d57b255ae..14ee42e8b 100644 --- a/dev/tsunami_uart.hh +++ b/dev/tsunami_uart.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ class TsunamiUart : public PioDevice Addr addr; static const Addr size = 0x8; + protected: SimConsole *cons; int status_store; @@ -55,6 +56,19 @@ class TsunamiUart : public PioDevice bool valid_char; uint8_t IER; + class IntrEvent : public Event + { + protected: + TsunamiUart *uart; + public: + IntrEvent(TsunamiUart *u); + virtual void process(); + virtual const char *description(); + void scheduleIntr(); + }; + + IntrEvent intrEvent; + public: TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, HierParams *hier, Bus *bus); @@ -66,7 +80,11 @@ class TsunamiUart : public PioDevice virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - public: + /** + * Return how long this access will take. + * @param req the memory request to calcuate + * @return Tick when the request is done + */ Tick cacheAccess(MemReqPtr &req); }; diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h index 927dd60c9..2e4e873a0 100644 --- a/dev/tsunamireg.h +++ b/dev/tsunamireg.h @@ -1,8 +1,35 @@ +/* + * Copyright (c) 2004 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. + */ #ifndef __TSUNAMIREG_H__ #define __TSUNAMIREG_H__ -#define ALPHA_K0SEG_BASE 0xfffffc0000000000ULL +#define ALPHA_K0SEG_BASE ULL(0xfffffc0000000000) // CChip Registers #define TSDEV_CC_CSR 0x00 @@ -105,15 +132,14 @@ #define RTC_CONTROL_REGISTERD 13 // control register D #define RTC_REGNUMBER_RTC_CR1 0x6A // control register 1 -#define PCHIP_PCI0_MEMORY ULL(0x10000000000) -#define PCHIP_PCI0_IO ULL(0x101FC000000) -#define TSUNAMI_PCI0_MEMORY ALPHA_K0SEG_BASE + PCHIP_PCI0_MEMORY -#define TSUNAMI_PCI0_IO ALPHA_K0SEG_BASE + PCHIP_PCI0_IO +#define PCHIP_PCI0_MEMORY ULL(0x00000000000) +#define PCHIP_PCI0_IO ULL(0x001FC000000) +#define TSUNAMI_UNCACHABLE_BIT ULL(0x80000000000) +#define TSUNAMI_PCI0_MEMORY TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_MEMORY +#define TSUNAMI_PCI0_IO TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_IO // UART Defines - - #define UART_IER_THRI 0x02 #define UART_IER_RLSI 0x04 diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh index a3cb94e91..9905a0b16 100644 --- a/kern/linux/linux.hh +++ b/kern/linux/linux.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/kern/linux/linux_syscalls.cc b/kern/linux/linux_syscalls.cc index d259499a2..c3e0bf1e5 100644 --- a/kern/linux/linux_syscalls.cc +++ b/kern/linux/linux_syscalls.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,335 +30,335 @@ namespace { const char * - standard_strings[SystemCalls<Linux>::StandardNumber] = { - - - "llseek", //0 - "newselect", //1 - "sysctl", //2 - "access", //3 - "acct", //4 - "adjtimex", //5 - "afs_syscall", //6 - "alarm", //7 - "bdflush", //8 - "break", //9 - - - "brk", //10 - "capget", //11 - "capset", //12 - "chdir", //13 - "chmod", //14 - "chown", //15 - "chown32", //16 - "chroot", //17 - "clock_getres", //18 - "clock_gettime", //19 - - - "clock_nanosleep", //20 - "clock_settime", //21 - "clone", //22 - "close", //23 - "creat", //24 - "create_module", //25 - "delete_module", //26 - "dup", //27 - "dup2", //28 - "epoll_create", //29 - - - "epoll_ctl", //30 - "epoll_wait", //31 - "execve", //32 - "exit", //33 - "exit_group", //34 - "fadvise64", //35 - "fadvise64_64", //36 - "fchdir", //37 - "fchmod", //38 - "fchown", //39 - - - "fchown32", //40 - "fcntl", //41 - "fcntl64", //42 - "fdatasync", //43 - "fgetxattr", //44 - "flistxattr", //45 - "flock", //46 - "fork", //47 - "fremovexattr", //48 - "fsetxattr", //49 - - - "fstat", //50 - "fstat64", //51 - "fstatfs", //52 - "fstatfs64", //53 - "fsync", //54 - "ftime", //55 - "ftruncate", //56 - "ftruncate64", //57 - "futex", //58 - "get_kernel_syms", //59 - - - "get_thread_area", //60 - "getcwd", //61 - "getdents", //62 - "getdents64", //63 - "getegid", //64 - "getegid32", //65 - "geteuid", //66 - "geteuid32", //67 - "getgid", //68 - "getgid32", //69 - - - "getgroups", //70 - "getgroups32", //71 - "getitimer", //72 - "getpgid", //73 - "getpgrp", //74 - "getpid", //75 - "getpmsg", //76 - "getppid", //77 - "getpriority", //78 - "getresgid", //79 - - - "getresgid32", //80 - "getresuid", //81 - "getresuid32", //82 - "getrlimit", //83 - "getrusage", //84 - "getsid", //85 - "gettid", //86 - "gettimeofday", //87 - "getuid", //88 - "getuid32", //89 - - - "getxattr", //90 - "gtty", //91 - "idle", //92 - "init_module", //93 - "io_cancel", //94 - "io_destroy", //95 - "io_getevents", //96 - "io_setup", //97 - "io_submit", //98 - "ioctl", //99 - - - "ioperm", //100 - "iopl", //101 - "ipc", //102 - "kill", //103 - "lchown", //104 - "lchown32", //105 - "lgetxattr", //106 - "link", //107 - "listxattr", //108 - "llistxattr", //109 - - - "lock", //110 - "lookup_dcookie", //111 - "lremovexattr", //112 - "lseek", //113 - "lsetxattr", //114 - "lstat", //115 - "lstat64", //116 - "madvise", //117 - "madvise1", //118 - "mincore", //119 - - - "mkdir", //120 - "mknod", //121 - "mlock", //122 - "mlockall", //123 - "mmap", //124 - "mmap2", //125 - "modify_ldt", //126 - "mount", //127 - "mprotect", //128 - "mpx", //129 - - - "mremap", //130 - "msync", //131 - "munlock", //132 - "munlockall", //133 - "munmap", //134 - "nanosleep", //135 - "nfsservctl", //136 - "nice", //137 - "oldfstat", //138 - "oldlstat", //139 - - - "oldolduname", //140 - "oldstat", //141 - "olduname", //142 - "open", //143 - "pause", //144 - "personality", //145 - "pipe", //146 - "pivot_root", //147 - "poll", //148 - "prctl", //149 - - - "pread64", //150 - "prof", //151 - "profil", //152 - "ptrace", //153 - "putpmsg", //154 - "pwrite64", //155 - "query_module", //156 - "quotactl", //157 - "read", //158 - "readahead", //159 - - - "readdir", //160 - "readlink", //161 - "readv", //162 - "reboot", //163 - "remap_file_pages", //164 - "removexattr", //165 - "rename", //166 - "restart_syscall", //167 - "rmdir", //168 - "rt_sigaction", //169 - - - "rt_sigpending", //170 - "rt_sigprocmask", //171 - "rt_sigqueueinfo", //172 - "rt_sigreturn", //173 - "rt_sigsuspend", //174 - "rt_sigtimedwait", //175 - "sched_get_priority_max", //176 - "sched_get_priority_min", //177 - "sched_getaffinity", //178 - "sched_getparam", //179 - - - "sched_getscheduler", //180 - "sched_rr_get_interval", //181 - "sched_setaffinity", //182 - "sched_setparam", //183 - "sched_setscheduler", //184 - "sched_yield", //185 - "select", //186 - "sendfile", //187 - "sendfile64", //188 - "set_thread_area", //189 - - - "set_tid_address", //190 - "setdomainname", //191 - "setfsgid", //192 - "setfsgid32", //193 - "setfsuid", //194 - "setfsuid32", //195 - "setgid", //196 - "setgid32", //197 - "setgroups", //198 - "setgroups32", //199 - - - "sethostname", //200 - "setitimer", //201 - "setpgid", //202 - "setpriority", //203 - "setregid", //204 - "setregid32", //205 - "setresgid", //206 - "setresgid32", //207 - "setresuid", //208 - "setresuid32", //209 - - - "setreuid", //210 - "setreuid32", //211 - "setrlimit", //212 - "setsid", //213 - "settimeofday", //214 - "setuid", //215 - "setuid32", //216 - "setxattr", //217 - "sgetmask", //218 - "sigaction", //219 - - - "sigaltstack", //220 - "signal", //221 - "sigpending", //222 - "sigprocmask", //223 - "sigreturn", //224 - "sigsuspend", //225 - "socketcall", //226 - "ssetmask", //227 - "stat", //228 - "stat64", //229 - - - "statfs", //230 - "statfs64", //231 - "stime", //232 - "stty", //233 - "swapoff", //234 - "swapon", //235 - "symlink", //236 - "sync", //237 - "sysfs", //238 - "sysinfo", //239 - - - "syslog", //240 - "tgkill", //241 - "time", //242 - "timer_create", //243 - "timer_delete", //244 - "timer_getoverrun", //245 - "timer_gettime", //246 - "timer_settime", //247 - "times", //248 - "tkill", //249 - - - "truncate", //250 - "truncate64", //251 - "ugetrlimit", //252 - "ulimit", //253 - "umask", //254 - "umount", //255 - "umount2", //256 - "uname", //257 - "unlink", //258 - "uselib", //259 - - - "ustat", //260 - "utime", //261 - "utimes", //262 - "vfork", //263 - "vhangup", //264 - "vm86", //265 - "vm86old", //266 - "vserver", //267 - "wait4", //268 - "waitpid", //269 - - - "write", //270 - "writev", //271 + standard_strings[SystemCalls<Linux>::Number] = { + + + "llseek", //0 + "newselect", //1 + "sysctl", //2 + "access", //3 + "acct", //4 + "adjtimex", //5 + "afs_syscall", //6 + "alarm", //7 + "bdflush", //8 + "break", //9 + + + "brk", //10 + "capget", //11 + "capset", //12 + "chdir", //13 + "chmod", //14 + "chown", //15 + "chown32", //16 + "chroot", //17 + "clock_getres", //18 + "clock_gettime", //19 + + + "clock_nanosleep", //20 + "clock_settime", //21 + "clone", //22 + "close", //23 + "creat", //24 + "create_module", //25 + "delete_module", //26 + "dup", //27 + "dup2", //28 + "epoll_create", //29 + + + "epoll_ctl", //30 + "epoll_wait", //31 + "execve", //32 + "exit", //33 + "exit_group", //34 + "fadvise64", //35 + "fadvise64_64", //36 + "fchdir", //37 + "fchmod", //38 + "fchown", //39 + + + "fchown32", //40 + "fcntl", //41 + "fcntl64", //42 + "fdatasync", //43 + "fgetxattr", //44 + "flistxattr", //45 + "flock", //46 + "fork", //47 + "fremovexattr", //48 + "fsetxattr", //49 + + + "fstat", //50 + "fstat64", //51 + "fstatfs", //52 + "fstatfs64", //53 + "fsync", //54 + "ftime", //55 + "ftruncate", //56 + "ftruncate64", //57 + "futex", //58 + "get_kernel_syms", //59 + + + "get_thread_area", //60 + "getcwd", //61 + "getdents", //62 + "getdents64", //63 + "getegid", //64 + "getegid32", //65 + "geteuid", //66 + "geteuid32", //67 + "getgid", //68 + "getgid32", //69 + + + "getgroups", //70 + "getgroups32", //71 + "getitimer", //72 + "getpgid", //73 + "getpgrp", //74 + "getpid", //75 + "getpmsg", //76 + "getppid", //77 + "getpriority", //78 + "getresgid", //79 + + + "getresgid32", //80 + "getresuid", //81 + "getresuid32", //82 + "getrlimit", //83 + "getrusage", //84 + "getsid", //85 + "gettid", //86 + "gettimeofday", //87 + "getuid", //88 + "getuid32", //89 + + + "getxattr", //90 + "gtty", //91 + "idle", //92 + "init_module", //93 + "io_cancel", //94 + "io_destroy", //95 + "io_getevents", //96 + "io_setup", //97 + "io_submit", //98 + "ioctl", //99 + + + "ioperm", //100 + "iopl", //101 + "ipc", //102 + "kill", //103 + "lchown", //104 + "lchown32", //105 + "lgetxattr", //106 + "link", //107 + "listxattr", //108 + "llistxattr", //109 + + + "lock", //110 + "lookup_dcookie", //111 + "lremovexattr", //112 + "lseek", //113 + "lsetxattr", //114 + "lstat", //115 + "lstat64", //116 + "madvise", //117 + "madvise1", //118 + "mincore", //119 + + + "mkdir", //120 + "mknod", //121 + "mlock", //122 + "mlockall", //123 + "mmap", //124 + "mmap2", //125 + "modify_ldt", //126 + "mount", //127 + "mprotect", //128 + "mpx", //129 + + + "mremap", //130 + "msync", //131 + "munlock", //132 + "munlockall", //133 + "munmap", //134 + "nanosleep", //135 + "nfsservctl", //136 + "nice", //137 + "oldfstat", //138 + "oldlstat", //139 + + + "oldolduname", //140 + "oldstat", //141 + "olduname", //142 + "open", //143 + "pause", //144 + "personality", //145 + "pipe", //146 + "pivot_root", //147 + "poll", //148 + "prctl", //149 + + + "pread64", //150 + "prof", //151 + "profil", //152 + "ptrace", //153 + "putpmsg", //154 + "pwrite64", //155 + "query_module", //156 + "quotactl", //157 + "read", //158 + "readahead", //159 + + + "readdir", //160 + "readlink", //161 + "readv", //162 + "reboot", //163 + "remap_file_pages", //164 + "removexattr", //165 + "rename", //166 + "restart_syscall", //167 + "rmdir", //168 + "rt_sigaction", //169 + + + "rt_sigpending", //170 + "rt_sigprocmask", //171 + "rt_sigqueueinfo", //172 + "rt_sigreturn", //173 + "rt_sigsuspend", //174 + "rt_sigtimedwait", //175 + "sched_get_priority_max", //176 + "sched_get_priority_min", //177 + "sched_getaffinity", //178 + "sched_getparam", //179 + + + "sched_getscheduler", //180 + "sched_rr_get_interval", //181 + "sched_setaffinity", //182 + "sched_setparam", //183 + "sched_setscheduler", //184 + "sched_yield", //185 + "select", //186 + "sendfile", //187 + "sendfile64", //188 + "set_thread_area", //189 + + + "set_tid_address", //190 + "setdomainname", //191 + "setfsgid", //192 + "setfsgid32", //193 + "setfsuid", //194 + "setfsuid32", //195 + "setgid", //196 + "setgid32", //197 + "setgroups", //198 + "setgroups32", //199 + + + "sethostname", //200 + "setitimer", //201 + "setpgid", //202 + "setpriority", //203 + "setregid", //204 + "setregid32", //205 + "setresgid", //206 + "setresgid32", //207 + "setresuid", //208 + "setresuid32", //209 + + + "setreuid", //210 + "setreuid32", //211 + "setrlimit", //212 + "setsid", //213 + "settimeofday", //214 + "setuid", //215 + "setuid32", //216 + "setxattr", //217 + "sgetmask", //218 + "sigaction", //219 + + + "sigaltstack", //220 + "signal", //221 + "sigpending", //222 + "sigprocmask", //223 + "sigreturn", //224 + "sigsuspend", //225 + "socketcall", //226 + "ssetmask", //227 + "stat", //228 + "stat64", //229 + + + "statfs", //230 + "statfs64", //231 + "stime", //232 + "stty", //233 + "swapoff", //234 + "swapon", //235 + "symlink", //236 + "sync", //237 + "sysfs", //238 + "sysinfo", //239 + + + "syslog", //240 + "tgkill", //241 + "time", //242 + "timer_create", //243 + "timer_delete", //244 + "timer_getoverrun", //245 + "timer_gettime", //246 + "timer_settime", //247 + "times", //248 + "tkill", //249 + + + "truncate", //250 + "truncate64", //251 + "ugetrlimit", //252 + "ulimit", //253 + "umask", //254 + "umount", //255 + "umount2", //256 + "uname", //257 + "unlink", //258 + "uselib", //259 + + + "ustat", //260 + "utime", //261 + "utimes", //262 + "vfork", //263 + "vhangup", //264 + "vm86", //265 + "vm86old", //266 + "vserver", //267 + "wait4", //268 + "waitpid", //269 + + + "write", //270 + "writev", //271 }; @@ -367,9 +367,7 @@ namespace { const char * SystemCalls<Linux>::name(int num) { - if (num >= StandardNumber) - return 0; - else if (num >= 0) + if ((num >= 0) && (num < Number)) return standard_strings[num]; else return 0; diff --git a/kern/linux/linux_syscalls.hh b/kern/linux/linux_syscalls.hh index 54d2391a8..a729431a0 100644 --- a/kern/linux/linux_syscalls.hh +++ b/kern/linux/linux_syscalls.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -308,22 +308,15 @@ struct SystemCalls<Linux> waitpid = 270, write = 271, writev = 272, - StandardNumber + Number }; static const char *name(int num); static bool validSyscallNumber(int num) { - return num < StandardNumber; + return num < Number; } - /* why does this exist, I don't think it is needed for linux */ - static int convert(int syscall_num) { - if (!validSyscallNumber(syscall_num)) - return -1; - - return syscall_num ; - } }; #endif // __LINUX_SYSCALLS_HH__ diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index a0000fe33..6287ce470 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +26,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * @file + * linux_system.cc loads the linux kernel, console, pal and patches certain functions. + * The symbol tables are loaded so that traces can show the executing function and we can + * skip functions. Various delay loops are skipped and their final values manually computed to + * speed up boot time. + */ + #include "base/loader/aout_object.hh" #include "base/loader/elf_object.hh" #include "base/loader/object_file.hh" @@ -36,6 +44,7 @@ #include "cpu/base_cpu.hh" #include "kern/linux/linux_events.hh" #include "kern/linux/linux_system.hh" +#include "kern/system_events.hh" #include "mem/functional_mem/memory_control.hh" #include "mem/functional_mem/physical_memory.hh" #include "sim/builder.hh" @@ -51,40 +60,26 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, MemoryController *_memCtrl, PhysicalMemory *_physmem, const string &kernel_path, const string &console_path, const string &palcode, const string &boot_osflags, - const string &bootloader_path, const bool _bin, - const vector<string> &_binned_fns) + const bool _bin, const vector<string> &_binned_fns) : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns), bin(_bin), binned_fns(_binned_fns) { kernelSymtab = new SymbolTable; consoleSymtab = new SymbolTable; - bootloaderSymtab = new SymbolTable; + /** + * Load the kernel, pal, and console code into memory + */ + // Load kernel code ObjectFile *kernel = createObjectFile(kernel_path); if (kernel == NULL) fatal("Could not load kernel file %s", kernel_path); + // Load Console Code ObjectFile *console = createObjectFile(console_path); if (console == NULL) fatal("Could not load console file %s", console_path); - ObjectFile *bootloader = createObjectFile(bootloader_path); - if (bootloader == NULL) - fatal("Could not load bootloader file %s", bootloader_path); - - if (!kernel->loadGlobalSymbols(kernelSymtab)) - panic("could not load kernel symbols\n"); - debugSymbolTable = kernelSymtab; - - if (!kernel->loadLocalSymbols(kernelSymtab)) - panic("could not load kernel local symbols\n"); - - if (!console->loadGlobalSymbols(consoleSymtab)) - panic("could not load console symbols\n"); - - if (!bootloader->loadGlobalSymbols(bootloaderSymtab)) - panic("could not load bootloader symbols\n"); - // Load pal file ObjectFile *pal = createObjectFile(palcode); if (pal == NULL) @@ -98,10 +93,18 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, kernel->loadSections(physmem, true); kernelStart = kernel->textBase(); kernelEnd = kernel->bssBase() + kernel->bssSize(); - /* FIXME: entrypoint not in kernel, but in bootloader, - variable should be re-named appropriately */ kernelEntry = kernel->entryPoint(); + // load symbols + if (!kernel->loadGlobalSymbols(kernelSymtab)) + panic("could not load kernel symbols\n"); + debugSymbolTable = kernelSymtab; + + if (!kernel->loadLocalSymbols(kernelSymtab)) + panic("could not load kernel local symbols\n"); + + if (!console->loadGlobalSymbols(consoleSymtab)) + panic("could not load console symbols\n"); DPRINTF(Loader, "Kernel start = %#x\n" "Kernel end = %#x\n" @@ -110,27 +113,28 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, DPRINTF(Loader, "Kernel loaded...\n"); - // Load bootloader file - bootloader->loadSections(physmem, true); - kernelEntry = bootloader->entryPoint(); - kernelStart = bootloader->textBase(); - DPRINTF(Loader, "Bootloader entry at %#x\n", kernelEntry); #ifdef DEBUG kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); #endif - skipIdeDelay50msEvent = new LinuxSkipIdeDelay50msEvent(&pcEventQueue, - "ide_delay_50ms"); + skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue, + "ide_delay_50ms"); skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue, "calibrate_delay"); - skipCacheProbeEvent = new LinuxSkipFuncEvent(&pcEventQueue, "determine_cpu_caches"); + skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue, + "determine_cpu_caches"); Addr addr = 0; + /** + * find the address of the est_cycle_freq variable and insert it so we don't + * through the lengthly process of trying to calculated it by using the PIT, + * RTC, etc. + */ if (kernelSymtab->findAddress("est_cycle_freq", addr)) { Addr paddr = vtophys(physmem, addr); uint8_t *est_cycle_frequency = @@ -140,31 +144,43 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, *(uint64_t *)est_cycle_frequency = ticksPerSecond; } - if (kernelSymtab->findAddress("aic7xxx_no_reset", addr)) { - Addr paddr = vtophys(physmem, addr); - uint8_t *aic7xxx_no_reset = - physmem->dma_addr(paddr, sizeof(uint32_t)); - - if (aic7xxx_no_reset) { - *(uint32_t *)aic7xxx_no_reset = 1; - } - } + /** + * Copy the osflags (kernel arguments) into the consoles memory. Presently + * Linux does use the console service routine to get these command line + * arguments, but we might as well make them available just in case. + */ if (consoleSymtab->findAddress("env_booted_osflags", addr)) { Addr paddr = vtophys(physmem, addr); char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); if (osflags) - strcpy(osflags, boot_osflags.c_str()); + strcpy(osflags, boot_osflags.c_str()); } + /** + * Since we aren't using a bootloader, we have to copy the kernel arguments + * directly into the kernels memory. + */ + { + Addr paddr = vtophys(physmem, PARAM_ADDR); + char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t)); + if (commandline) + strcpy(commandline, boot_osflags.c_str()); + } + + + /** + * Set the hardware reset parameter block system type and revision information + * to Tsunami. + */ if (consoleSymtab->findAddress("xxm_rpb", addr)) { Addr paddr = vtophys(physmem, addr); char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); if (hwprb) { *(uint64_t*)(hwprb+0x50) = 34; // Tsunami - *(uint64_t*)(hwprb+0x58) = (1<<10); + *(uint64_t*)(hwprb+0x58) = (1<<10); // Plain DP264 } else panic("could not translate hwprb addr to set system type/variation\n"); @@ -182,14 +198,20 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, consolePanicEvent->schedule(addr); #endif + /** + * Any time ide_delay_50ms, calibarte_delay or determine_cpu_caches is called + * just skip the function. Currently determine_cpu_caches only is used put + * information in proc, however if that changes in the future we will have to + * fill in the cache size variables appropriately. + */ if (kernelSymtab->findAddress("ide_delay_50ms", addr)) - skipIdeDelay50msEvent->schedule(addr+8); + skipIdeDelay50msEvent->schedule(addr+sizeof(MachInst)); if (kernelSymtab->findAddress("calibrate_delay", addr)) - skipDelayLoopEvent->schedule(addr+8); + skipDelayLoopEvent->schedule(addr+sizeof(MachInst)); if (kernelSymtab->findAddress("determine_cpu_caches", addr)) - skipCacheProbeEvent->schedule(addr+8); + skipCacheProbeEvent->schedule(addr+sizeof(MachInst)); } LinuxSystem::~LinuxSystem() @@ -199,7 +221,6 @@ LinuxSystem::~LinuxSystem() delete kernelSymtab; delete consoleSymtab; - delete bootloaderSymtab; delete kernelPanicEvent; delete consolePanicEvent; @@ -208,6 +229,7 @@ LinuxSystem::~LinuxSystem() delete skipCacheProbeEvent; } + void LinuxSystem::setDelayLoop(ExecContext *xc) { @@ -239,7 +261,11 @@ LinuxSystem::registerExecContext(ExecContext *xc) RemoteGDB *rgdb = new RemoteGDB(this, xc); GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex); gdbl->listen(); -// gdbl->accept(); + /** + * Uncommenting this line waits for a remote debugger to connect + * to the simulator before continuing. + */ + //gdbl->accept(); if (remoteGDB.size() <= xcIndex) { remoteGDB.resize(xcIndex+1); @@ -275,7 +301,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) Param<string> console_code; Param<string> pal_code; Param<string> boot_osflags; - Param<string> bootloader_code; VectorParam<string> binned_fns; END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) @@ -292,7 +317,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) INIT_PARAM(pal_code, "file that contains palcode"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", "a"), - INIT_PARAM(bootloader_code, "file that contains the bootloader"), INIT_PARAM(binned_fns, "functions to be broken down and binned") @@ -302,8 +326,7 @@ CREATE_SIM_OBJECT(LinuxSystem) { LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl, physmem, kernel_code, console_code, - pal_code, boot_osflags, bootloader_code, - bin, binned_fns); + pal_code, boot_osflags, bin, binned_fns); return sys; } diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index 3b65e7379..4f5a74259 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,47 +32,75 @@ #include <vector> #include "sim/system.hh" +#include "sim/host.hh" #include "targetarch/isa_traits.hh" #include <map> +/** + * MAGIC address where the kernel arguments should go. Defined as + * PARAM in linux kernel alpha-asm. + */ +const Addr PARAM_ADDR = ULL(0xfffffc000030a000); + class ExecContext; class ElfObject; class SymbolTable; class BreakPCEvent; -class LinuxBadAddrEvent; -class LinuxSkipFuncEvent; class LinuxSkipDelayLoopEvent; -class LinuxSkipIdeDelay50msEvent; -class LinuxPrintfEvent; -class LinuxDebugPrintfEvent; -class LinuxDumpMbufEvent; +class SkipFuncEvent; class FnEvent; class AlphaArguments; +/** + * This class contains linux specific system code (Loading, Events, Binning). + * It points to objects that are the system binaries to load and patches them + * appropriately to work in simulator. + */ class LinuxSystem : public System { private: + /** Object pointer for the kernel code */ ElfObject *kernel; + + /** Object pointer for the console code */ ElfObject *console; - ElfObject *bootloader; + /** kernel Symbol table */ SymbolTable *kernelSymtab; - SymbolTable *bootloaderSymtab; + + /** console symbol table */ SymbolTable *consoleSymtab; + /** Event to halt the simulator if the kernel calls panic() */ BreakPCEvent *kernelPanicEvent; + + /** Event to halt the simulator if the console calls panic() */ BreakPCEvent *consolePanicEvent; - LinuxSkipFuncEvent *skipCacheProbeEvent; - LinuxSkipIdeDelay50msEvent *skipIdeDelay50msEvent; - LinuxSkipDelayLoopEvent *skipDelayLoopEvent; - private: + /** Event to skip determine_cpu_caches() because we don't support the + * IPRs that the code can access to figure out cache sizes + */ + SkipFuncEvent *skipCacheProbeEvent; + /** PC based event to skip the ide_delay_50ms() call */ + SkipFuncEvent *skipIdeDelay50msEvent; + + /** Skip calculate_delay_loop() rather than waiting for this to be + * calculated + */ + LinuxSkipDelayLoopEvent *skipDelayLoopEvent; + + /** Begining of kernel code */ Addr kernelStart; + + /** End of kernel code */ Addr kernelEnd; + + /** Entry point in the kernel to start at */ Addr kernelEntry; + bool bin; std::vector<string> binned_fns; @@ -80,7 +108,6 @@ class LinuxSystem : public System std::vector<RemoteGDB *> remoteGDB; std::vector<GDBListener *> gdbListen; - public: LinuxSystem(const std::string _name, const uint64_t _init_param, MemoryController *_memCtrl, @@ -89,7 +116,6 @@ class LinuxSystem : public System const std::string &console_path, const std::string &palcode, const std::string &boot_osflags, - const std::string &bootloader_path, const bool _bin, const std::vector<std::string> &_binned_fns); @@ -100,9 +126,25 @@ class LinuxSystem : public System int registerExecContext(ExecContext *xc); void replaceExecContext(ExecContext *xc, int xcIndex); + /** + * Returns the addess the kernel starts at. + * @return address the kernel starts at + */ Addr getKernelStart() const { return kernelStart; } + + /** + * Returns the addess the kernel ends at. + * @return address the kernel ends at + */ Addr getKernelEnd() const { return kernelEnd; } + + /** + * Returns the addess the entry point to the kernel code. + * @return entry point of the kernel code + */ Addr getKernelEntry() const { return kernelEntry; } + + bool breakpoint(); }; diff --git a/kern/system_events.cc b/kern/system_events.cc index 011dbce5f..351c3ddb2 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/kern/system_events.hh b/kern/system_events.hh index fdf2a06c9..7f658bde9 100644 --- a/kern/system_events.hh +++ b/kern/system_events.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ class FnEvent : public PCEvent private: std::string _name; - Statistics::MainBin *myBin; + Stats::MainBin *myBin; }; #endif // __SYSTEM_EVENTS_HH__ diff --git a/kern/tru64/mbuf.hh b/kern/tru64/mbuf.hh index a386fa611..d0f8dad2a 100644 --- a/kern/tru64/mbuf.hh +++ b/kern/tru64/mbuf.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 89b808653..e96cc9c5d 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/kern/tru64/tru64_events.hh b/kern/tru64/tru64_events.hh index bcf33d686..d6e7c1c97 100644 --- a/kern/tru64/tru64_events.hh +++ b/kern/tru64/tru64_events.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index 31f9c9878..4395162e4 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,18 +42,22 @@ #include "targetarch/isa_traits.hh" #include "targetarch/vtophys.hh" +extern SymbolTable *debugSymbolTable; + using namespace std; Tru64System::Tru64System(const string _name, const uint64_t _init_param, MemoryController *_memCtrl, PhysicalMemory *_physmem, const string &kernel_path, const string &console_path, const string &palcode, const string &boot_osflags, - const bool _bin, const vector<string> &_binned_fns) + const bool _bin, const vector<string> &_binned_fns, + const uint64_t system_type, const uint64_t system_rev) : System(_name, _init_param, _memCtrl, _physmem, _bin,_binned_fns), bin(_bin), binned_fns(_binned_fns) { kernelSymtab = new SymbolTable; consoleSymtab = new SymbolTable; + debugSymbolTable = kernelSymtab; ObjectFile *kernel = createObjectFile(kernel_path); if (kernel == NULL) @@ -130,8 +134,8 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param, char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); if (hwprb) { - *(uint64_t*)(hwprb+0x50) = 12; // Tlaser - *(uint64_t*)(hwprb+0x58) = (2<<1); + *(uint64_t*)(hwprb+0x50) = system_type; + *(uint64_t*)(hwprb+0x58) = system_rev; } else panic("could not translate hwprb addr to set system type/variation\n"); @@ -260,6 +264,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) Param<string> pal_code; Param<string> boot_osflags; VectorParam<string> binned_fns; + Param<uint64_t> system_type; + Param<uint64_t> system_rev; END_DECLARE_SIM_OBJECT_PARAMS(Tru64System) @@ -274,7 +280,10 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System) INIT_PARAM(pal_code, "file that contains palcode"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", "a"), - INIT_PARAM(binned_fns, "functions to be broken down and binned") + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1) + END_INIT_SIM_OBJECT_PARAMS(Tru64System) @@ -283,7 +292,7 @@ CREATE_SIM_OBJECT(Tru64System) Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl, physmem, kernel_code, console_code, pal_code, boot_osflags, bin, - binned_fns); + binned_fns, system_type, system_rev); return sys; } diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh index 144febbf9..8dd696b79 100644 --- a/kern/tru64/tru64_system.hh +++ b/kern/tru64/tru64_system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,9 @@ class Tru64System : public System const std::string &palcode, const std::string &boot_osflags, const bool _bin, - const std::vector<string> &binned_fns); + const std::vector<string> &binned_fns, + const uint64_t system_type, + const uint64_t system_rev); ~Tru64System(); int registerExecContext(ExecContext *xc); diff --git a/sim/builder.cc b/sim/builder.cc index 110c42f25..53e5cf3d8 100644 --- a/sim/builder.cc +++ b/sim/builder.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/builder.hh b/sim/builder.hh index e13a85272..a85c88b76 100644 --- a/sim/builder.hh +++ b/sim/builder.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/debug.cc b/sim/debug.cc index b73ab4245..293edcbe2 100644 --- a/sim/debug.cc +++ b/sim/debug.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/debug.hh b/sim/debug.hh index a4f8b8702..3ccf1dbd4 100644 --- a/sim/debug.hh +++ b/sim/debug.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/eventq.cc b/sim/eventq.cc index a0aac4fee..6b4ccc827 100644 --- a/sim/eventq.cc +++ b/sim/eventq.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/eventq.hh b/sim/eventq.hh index ed37fd4f4..304e4b16a 100644 --- a/sim/eventq.hh +++ b/sim/eventq.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/main.cc b/sim/main.cc index 8861f3ef0..f0d10a67c 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2000-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -236,7 +236,7 @@ main(int argc, char **argv) sayHello(cerr); // Initialize statistics database - Statistics::InitSimStats(); + Stats::InitSimStats(); vector<char *> cppArgs; @@ -390,10 +390,10 @@ main(int argc, char **argv) #endif // Check to make sure that the stats package is properly initialized - Statistics::check(); + Stats::check(); // Reset to put the stats in a consistent state. - Statistics::reset(); + Stats::reset(); // Nothing to simulate if we don't have at least one CPU somewhere. if (BaseCPU::numSimulatedCPUs() == 0) { @@ -418,14 +418,14 @@ main(int argc, char **argv) if (async_dump) { async_dump = false; - using namespace Statistics; + using namespace Stats; SetupEvent(Dump, curTick); } if (async_dumpreset) { async_dumpreset = false; - using namespace Statistics; + using namespace Stats; SetupEvent(Dump | Reset, curTick); } diff --git a/sim/param.cc b/sim/param.cc index bb372f631..4f9d0a577 100644 --- a/sim/param.cc +++ b/sim/param.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/param.hh b/sim/param.hh index 765a7ac1c..fe13edc48 100644 --- a/sim/param.hh +++ b/sim/param.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/process.cc b/sim/process.cc index c6b497343..7f93c1d9e 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -95,7 +95,7 @@ Process::Process(const string &name, void Process::regStats() { - using namespace Statistics; + using namespace Stats; num_syscalls .name(name() + ".PROG:num_syscalls") diff --git a/sim/process.hh b/sim/process.hh index b23302b8f..bd6adc55c 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,7 +98,7 @@ class Process : public SimObject std::string prog_fname; // file name Addr prog_entry; // entry point (initial PC) - Statistics::Scalar<> num_syscalls; // number of syscalls executed + Stats::Scalar<> num_syscalls; // number of syscalls executed protected: diff --git a/sim/serialize.cc b/sim/serialize.cc index f8d6b46bf..945f97c06 100644 --- a/sim/serialize.cc +++ b/sim/serialize.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/serialize.hh b/sim/serialize.hh index 36622b7fe..ad490d616 100644 --- a/sim/serialize.hh +++ b/sim/serialize.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/sim_events.cc b/sim/sim_events.cc index 3530adedc..c454fdcf9 100644 --- a/sim/sim_events.cc +++ b/sim/sim_events.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/sim_events.hh b/sim/sim_events.hh index 4a8e7c115..804c41d73 100644 --- a/sim/sim_events.hh +++ b/sim/sim_events.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/sim_object.cc b/sim/sim_object.cc index 5602a89a2..cab629f8d 100644 --- a/sim/sim_object.cc +++ b/sim/sim_object.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,7 +121,7 @@ SimObject::regAllStats() (*i)->regFormulas(); } - Statistics::registerResetCallback(&StatResetCB); + Stats::registerResetCallback(&StatResetCB); } // diff --git a/sim/sim_object.hh b/sim/sim_object.hh index b1dd19475..1a9ed363d 100644 --- a/sim/sim_object.hh +++ b/sim/sim_object.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/stat_control.cc b/sim/stat_control.cc index c7d2fdd5b..9a4313a61 100644 --- a/sim/stat_control.cc +++ b/sim/stat_control.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,17 +47,17 @@ using namespace std; -Statistics::Formula hostInstRate; -Statistics::Formula hostTickRate; -Statistics::Value hostMemory; -Statistics::Value hostSeconds; +Stats::Formula hostInstRate; +Stats::Formula hostTickRate; +Stats::Value hostMemory; +Stats::Value hostSeconds; -Statistics::Value simTicks; -Statistics::Value simInsts; -Statistics::Value simFreq; -Statistics::Formula simSeconds; +Stats::Value simTicks; +Stats::Value simInsts; +Stats::Value simFreq; +Stats::Formula simSeconds; -namespace Statistics { +namespace Stats { Time statTime(true); Tick startTick; @@ -173,10 +173,10 @@ StatEvent::description() void StatEvent::process() { - if (flags & Statistics::Dump) + if (flags & Stats::Dump) DumpNow(); - if (flags & Statistics::Reset) + if (flags & Stats::Reset) reset(); if (repeat) @@ -205,11 +205,11 @@ SetupEvent(int flags, Tick when, Tick repeat) new StatEvent(flags, when, repeat); } -/* namespace Statistics */ } +/* namespace Stats */ } extern "C" void debugDumpStats() { - Statistics::DumpNow(); + Stats::DumpNow(); } diff --git a/sim/stat_control.hh b/sim/stat_control.hh index 9a5e269e1..d0a9dc6ad 100644 --- a/sim/stat_control.hh +++ b/sim/stat_control.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +32,7 @@ #include <fstream> #include <list> -namespace Statistics { +namespace Stats { enum { Reset = 0x1, @@ -47,6 +47,6 @@ void SetupEvent(int flags, Tick when, Tick repeat = 0); void InitSimStats(); -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __SIM_STAT_CONTROL_HH__ diff --git a/sim/stats.hh b/sim/stats.hh index c5e791cfb..8487bf331 100644 --- a/sim/stats.hh +++ b/sim/stats.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ #include "base/statistics.hh" -extern Statistics::Formula simSeconds; -extern Statistics::Value simTicks; +extern Stats::Formula simSeconds; +extern Stats::Value simTicks; #endif // __SIM_SIM_STATS_HH__ diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 57ae39cf8..a0cbdf414 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index b425ef83c..77d104449 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sim/system.cc b/sim/system.cc index 791a092ac..b5a0e7a56 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,22 +52,25 @@ System::System(const std::string _name, bin(_bin), binned_fns(binned_fns) { + // increment the number of running systems + numSystemsRunning++; + // add self to global system list systemList.push_back(this); if (bin == true) { - Kernel = new Statistics::MainBin("non TCPIP Kernel stats"); + Kernel = new Stats::MainBin("non TCPIP Kernel stats"); Kernel->activate(); - User = new Statistics::MainBin("User stats"); + User = new Stats::MainBin("User stats"); int end = binned_fns.size(); assert(!(end & 1)); - Statistics::MainBin *Bin; + Stats::MainBin *Bin; fnEvents.resize(end>>1); for (int i = 0; i < end; i +=2) { - Bin = new Statistics::MainBin(binned_fns[i]); + Bin = new Stats::MainBin(binned_fns[i]); fnBins.insert(make_pair(binned_fns[i], Bin)); fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this); @@ -178,10 +181,10 @@ System::dumpState(ExecContext *xc) const } } -Statistics::MainBin * +Stats::MainBin * System::getBin(const std::string &name) { - std::map<const std::string, Statistics::MainBin *>::const_iterator i; + std::map<const std::string, Stats::MainBin *>::const_iterator i; i = fnBins.find(name); if (i == fnBins.end()) panic("trying to getBin %s that is not on system map!", name); diff --git a/sim/system.hh b/sim/system.hh index 08fcfb784..baf82a5b5 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,18 +51,18 @@ class System : public SimObject { // lisa's binning stuff private: - std::map<const std::string, Statistics::MainBin *> fnBins; + std::map<const std::string, Stats::MainBin *> fnBins; std::map<const Addr, SWContext *> swCtxMap; protected: std::vector<FnEvent *> fnEvents; public: - Statistics::Scalar<> fnCalls; - Statistics::MainBin *Kernel; - Statistics::MainBin *User; + Stats::Scalar<> fnCalls; + Stats::MainBin *Kernel; + Stats::MainBin *User; - Statistics::MainBin * getBin(const std::string &name); + Stats::MainBin * getBin(const std::string &name); bool findCaller(std::string, std::string) const; SWContext *findContext(Addr pcb); diff --git a/sim/universe.cc b/sim/universe.cc index d6c849ac7..79e32098c 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/bitvectest.cc b/test/bitvectest.cc index 5c2a79a4e..1084a7bbc 100644 --- a/test/bitvectest.cc +++ b/test/bitvectest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/circletest.cc b/test/circletest.cc index 5c8f148a5..6baade920 100644 --- a/test/circletest.cc +++ b/test/circletest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cprintftest.cc b/test/cprintftest.cc index 98af6b6ce..b9c789d0d 100644 --- a/test/cprintftest.cc +++ b/test/cprintftest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/initest.cc b/test/initest.cc index 818c64da7..7a8b479b5 100644 --- a/test/initest.cc +++ b/test/initest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/nmtest.cc b/test/nmtest.cc index 391536c0a..b6f54334b 100644 --- a/test/nmtest.cc +++ b/test/nmtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/offtest.cc b/test/offtest.cc index f0f590973..98f65cdb2 100644 --- a/test/offtest.cc +++ b/test/offtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/paramtest.cc b/test/paramtest.cc index 2efe23c83..a368a672a 100644 --- a/test/paramtest.cc +++ b/test/paramtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/rangetest.cc b/test/rangetest.cc index c38c13fd1..a36999523 100644 --- a/test/rangetest.cc +++ b/test/rangetest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/sized_test.cc b/test/sized_test.cc index d98459409..dfef1b8c6 100644 --- a/test/sized_test.cc +++ b/test/sized_test.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/stattest.cc b/test/stattest.cc index 9b7ba9857..d0b6916bb 100644 --- a/test/stattest.cc +++ b/test/stattest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2004 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,7 @@ #include "sim/host.hh" using namespace std; -using namespace Statistics; +using namespace Stats; Tick curTick = 0; Tick ticksPerSecond = ULL(2000000000); diff --git a/test/strnumtest.cc b/test/strnumtest.cc index d491b8b5d..9740e5294 100644 --- a/test/strnumtest.cc +++ b/test/strnumtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/symtest.cc b/test/symtest.cc index 4efa24cef..8ebcddd30 100644 --- a/test/symtest.cc +++ b/test/symtest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/tokentest.cc b/test/tokentest.cc index eca34f4a2..39d62acda 100644 --- a/test/tokentest.cc +++ b/test/tokentest.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2002-2003 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without |