From 8fc76693d2ecdf43c0680a99deba54b14c50ba7e Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 12 Nov 2004 18:47:07 -0500 Subject: slightly different parameters for nfs script --HG-- extra : convert_revision : 1576f875646567cc661a8e3f07c00c4b282e9f64 --- configs/boot/nfs-client.rcS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configs/boot/nfs-client.rcS b/configs/boot/nfs-client.rcS index a8c45f4a5..86ad54da6 100755 --- a/configs/boot/nfs-client.rcS +++ b/configs/boot/nfs-client.rcS @@ -45,7 +45,6 @@ mkdir /nfs mount 10.0.0.1:/nfs /nfs echo "done." -/bin/bonnie++ -u 99 -s 120 -r 0 +/bin/bonnie++ -u 99 -s 120 -r 0 -n 0 -d /nfs -echo -n "starting bash shell..." -/bin/bash +/sbin/m5 exit -- cgit v1.2.3 From c4e5ef64b366edc3636de67e41dc8465eeeaf756 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 11:32:17 -0500 Subject: defining SYSTEM_EV5 isn't all that necessary --HG-- extra : convert_revision : 7d39dd9f814434cb95ec769204d7f2426b0290fd --- arch/alpha/ev5.hh | 4 ---- build/SConstruct | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index 7b1ff4a2f..4956d65d9 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -3,10 +3,6 @@ #ifndef __EV5_H__ #define __EV5_H__ -#ifndef SYSTEM_EV5 -#error This code is only valid for EV5 systems -#endif - #define MODE2MASK(X) (1 << (X)) // Alpha IPR register accessors diff --git a/build/SConstruct b/build/SConstruct index 6b71fa585..3d7db1db2 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -93,7 +93,7 @@ def AlphaConfig(env): def KernelConfig(env): env.Replace(TARGET_ISA = 'alpha') env.Replace(FULL_SYSTEM = True) - env.Append(CPPDEFINES = ['FULL_SYSTEM', 'SYSTEM_EV5']) + env.Append(CPPDEFINES = ['FULL_SYSTEM']) # Base configurations map. configs_map = { -- cgit v1.2.3 From bde7f4d121825e8a53148ff6793bf119a1ec530f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 11:33:43 -0500 Subject: defining SYSTEM_EV5 isn't all that necessary --HG-- extra : convert_revision : 2ed4866db9483820d550bad00fdbc8dd027f95ba --- arch/alpha/ev5.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 34b65a915..6deccefdb 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -15,10 +15,6 @@ #ifdef FULL_SYSTEM -#ifndef SYSTEM_EV5 -#error This code is only valid for EV5 systems -#endif - //////////////////////////////////////////////////////////////////////// // // -- cgit v1.2.3 -- cgit v1.2.3 From 425dda00df994b2483850e80260618b2a1a957bf Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 14:01:38 -0500 Subject: Macros are nasty, so let's get rid of them. Convert all all macros in ev5.hh to inline functions or constant typed variables and make them follow our style while we're at it. All of the stuff in this file actually belongs in the ISA traits code, but this is a first step at getting things done in the right manner. arch/alpha/alpha_memory.cc: arch/alpha/alpha_memory.hh: arch/alpha/ev5.cc: arch/alpha/isa_desc: dev/ns_gige.cc: kern/tru64/tru64_events.cc: deal with changes in ev5.hh arch/alpha/ev5.hh: Macros are nasty, so let's get rid of them. Convert all all macros to inline functions or constant typed variables. Make them follow our style while we're at it. All of the stuff in this file actually belongs in the ISA traits code, but this is a first step at getting things done in the right manner. arch/alpha/isa_traits.hh: move some of the ev5 specific code into the isa arch/alpha/vtophys.cc: base/remote_gdb.cc: deal with isa addition cpu/exec_context.hh: be less isa specific and use the isa traits to figure out what we can. dev/alpha_console.cc: dev/pciconfigall.cc: dev/tsunami_cchip.cc: dev/tsunami_io.cc: dev/tsunami_pchip.cc: dev/uart.cc: deal with changes in ev5.hh I don't believe this masking is actually necessary. We should look at removing it later. dev/ide_ctrl.cc: sort #includes deal with changes in ev5.hh --HG-- extra : convert_revision : c8a3adf0a4b1d198aefe38fc38b295abf289b08a --- arch/alpha/alpha_memory.cc | 119 +++++++++++++++++--------------- arch/alpha/alpha_memory.hh | 7 +- arch/alpha/ev5.cc | 4 +- arch/alpha/ev5.hh | 167 ++++++++++++++++++--------------------------- arch/alpha/isa_desc | 10 ++- arch/alpha/isa_traits.hh | 15 ++-- arch/alpha/vtophys.cc | 2 +- base/remote_gdb.cc | 2 +- cpu/exec_context.hh | 6 +- dev/alpha_console.cc | 4 +- dev/ide_ctrl.cc | 20 +++--- dev/ns_gige.cc | 4 +- dev/pciconfigall.cc | 4 +- dev/tsunami_cchip.cc | 4 +- dev/tsunami_io.cc | 4 +- dev/tsunami_pchip.cc | 4 +- dev/uart.cc | 5 +- kern/tru64/tru64_events.cc | 2 +- 18 files changed, 182 insertions(+), 201 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index b9187a92e..81a1902a0 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -31,7 +31,6 @@ #include #include "arch/alpha/alpha_memory.hh" -#include "arch/alpha/ev5.hh" #include "base/inifile.hh" #include "base/str.hh" #include "base/trace.hh" @@ -39,6 +38,7 @@ #include "sim/builder.hh" using namespace std; +using namespace EV5; /////////////////////////////////////////////////////////////////////// // @@ -49,6 +49,8 @@ bool uncacheBit39 = false; bool uncacheBit40 = false; #endif +#define MODE2MASK(X) (1 << (X)) + AlphaTLB::AlphaTLB(const string &name, int s) : SimObject(name), size(s), nlu(0) { @@ -103,12 +105,12 @@ AlphaTLB::checkCacheability(MemReqPtr &req) #ifdef ALPHA_TLASER - if (req->paddr & PA_UNCACHED_BIT_39) { + if (req->paddr & PAddrUncachedBit39) { #else - if (req->paddr & PA_UNCACHED_BIT_43) { + if (req->paddr & PAddrUncachedBit43) { #endif // IPR memory space not implemented - if (PA_IPR_SPACE(req->paddr)) { + if (PAddrIprSpace(req->paddr)) { if (!req->xc->misspeculating()) { switch (req->paddr) { case ULL(0xFFFFF00188): @@ -126,7 +128,7 @@ AlphaTLB::checkCacheability(MemReqPtr &req) #ifndef ALPHA_TLASER // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) - req->paddr &= PA_UNCACHED_MASK; + req->paddr &= PAddrUncachedMask; #endif } } @@ -135,8 +137,9 @@ AlphaTLB::checkCacheability(MemReqPtr &req) // insert a new TLB entry void -AlphaTLB::insert(Addr vaddr, AlphaISA::PTE &pte) +AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte) { + AlphaISA::VAddr vaddr = addr; if (table[nlu].valid) { Addr oldvpn = table[nlu].tag; PageTable::iterator i = lookupTable.find(oldvpn); @@ -157,14 +160,13 @@ AlphaTLB::insert(Addr vaddr, AlphaISA::PTE &pte) lookupTable.erase(i); } - Addr vpn = VA_VPN(vaddr); - DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vpn, pte.ppn); + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); table[nlu] = pte; - table[nlu].tag = vpn; + table[nlu].tag = vaddr.vpn(); table[nlu].valid = true; - lookupTable.insert(make_pair(vpn, nlu)); + lookupTable.insert(make_pair(vaddr.vpn(), nlu)); nextnlu(); } @@ -197,21 +199,22 @@ AlphaTLB::flushProcesses() } void -AlphaTLB::flushAddr(Addr vaddr, uint8_t asn) +AlphaTLB::flushAddr(Addr addr, uint8_t asn) { - Addr vpn = VA_VPN(vaddr); + AlphaISA::VAddr vaddr = addr; - PageTable::iterator i = lookupTable.find(vpn); + PageTable::iterator i = lookupTable.find(vaddr.vpn()); if (i == lookupTable.end()) return; - while (i->first == vpn) { + while (i->first == vaddr.vpn()) { int index = i->second; AlphaISA::PTE *pte = &table[index]; assert(pte->valid); - if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { - DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vpn, pte->ppn); + if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), + pte->ppn); // invalidate this entry pte->valid = false; @@ -287,7 +290,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const if (!xc->misspeculating()) { ipr[AlphaISA::IPR_ITB_TAG] = pc; ipr[AlphaISA::IPR_IFAULT_VA_FORM] = - ipr[AlphaISA::IPR_IVPTBR] | (VA_VPN(pc) << 3); + ipr[AlphaISA::IPR_IVPTBR] | (AlphaISA::VAddr(pc).vpn() << 3); } } @@ -297,9 +300,9 @@ AlphaITB::translate(MemReqPtr &req) const { InternalProcReg *ipr = req->xc->regs.ipr; - if (PC_PAL(req->vaddr)) { + if (AlphaISA::PcPAL(req->vaddr)) { // strip off PAL PC marker (lsb is 1) - req->paddr = (req->vaddr & ~3) & PA_IMPL_MASK; + req->paddr = (req->vaddr & ~3) & PAddrImplMask; hits++; return No_Fault; } @@ -319,24 +322,23 @@ AlphaITB::translate(MemReqPtr &req) const // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #ifdef ALPHA_TLASER if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && - VA_SPACE_EV5(req->vaddr) == 2) { + VAddrSpaceEV5(req->vaddr) == 2) { #else - if (VA_SPACE_EV6(req->vaddr) == 0x7e) { + if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif - - // only valid in kernel mode - if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) { + if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != + AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; return ITB_Acv_Fault; } - req->paddr = req->vaddr & PA_IMPL_MASK; + req->paddr = req->vaddr & PAddrImplMask; #ifndef ALPHA_TLASER // sign extend the physical address properly - if (req->paddr & PA_UNCACHED_BIT_40) + if (req->paddr & PAddrUncachedBit40) req->paddr |= ULL(0xf0000000000); else req->paddr &= ULL(0xffffffffff); @@ -344,8 +346,8 @@ AlphaITB::translate(MemReqPtr &req) const } else { // not a physical address: need to look up pte - AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); if (!pte) { fault(req->vaddr, req->xc); @@ -353,7 +355,8 @@ AlphaITB::translate(MemReqPtr &req) const return ITB_Fault_Fault; } - req->paddr = PA_PFN2PA(pte->ppn) + VA_POFS(req->vaddr & ~3); + req->paddr = (pte->ppn << AlphaISA::PageShift) + + (AlphaISA::VAddr(req->vaddr).offset() & ~3); // check permissions for this access if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { @@ -368,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const } // check that the physical address is ok (catch bad physical addresses) - if (req->paddr & ~PA_IMPL_MASK) + if (req->paddr & ~PAddrImplMask) return Machine_Check_Fault; checkCacheability(req); @@ -457,7 +460,7 @@ void AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const { ExecContext *xc = req->xc; - Addr vaddr = req->vaddr; + AlphaISA::VAddr vaddr = req->vaddr; uint64_t *ipr = xc->regs.ipr; // Set fault address and flags. Even though we're modeling an @@ -468,16 +471,17 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const if (!xc->misspeculating() && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) { // set VA register with faulting address - ipr[AlphaISA::IPR_VA] = vaddr; + ipr[AlphaISA::IPR_VA] = req->vaddr; // set MM_STAT register flags - ipr[AlphaISA::IPR_MM_STAT] = (((OPCODE(xc->getInst()) & 0x3f) << 11) - | ((RA(xc->getInst()) & 0x1f) << 6) - | (flags & 0x3f)); + 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 ipr[AlphaISA::IPR_VA_FORM] = - ipr[AlphaISA::IPR_MVPTBR] | (VA_VPN(vaddr) << 3); + ipr[AlphaISA::IPR_MVPTBR] | (vaddr.vpn() << 3); } } @@ -500,7 +504,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const return Alignment_Fault; } - if (PC_PAL(pc)) { + if (pc & 0x1) { mode = (req->flags & ALTMODE) ? (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) : AlphaISA::mode_kernel; @@ -511,8 +515,9 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const } else { // verify that this is a good virtual address if (!validVirtualAddress(req->vaddr)) { - fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | - MM_STAT_ACV_MASK); + fault(req, (write ? MM_STAT_WR_MASK : 0) | + MM_STAT_BAD_VA_MASK | + MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } return DTB_Fault_Fault; @@ -521,24 +526,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // Check for "superpage" mapping #ifdef ALPHA_TLASER if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && - VA_SPACE_EV5(req->vaddr) == 2) { + VAddrSpaceEV5(req->vaddr) == 2) { #else - if (VA_SPACE_EV6(req->vaddr) == 0x7e) { + if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif // only valid in kernel mode if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) { - fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); + fault(req, ((write ? MM_STAT_WR_MASK : 0) | + MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } return DTB_Acv_Fault; } - req->paddr = req->vaddr & PA_IMPL_MASK; + req->paddr = req->vaddr & PAddrImplMask; #ifndef ALPHA_TLASER // sign extend the physical address properly - if (req->paddr & PA_UNCACHED_BIT_40) + if (req->paddr & PAddrUncachedBit40) req->paddr |= ULL(0xf0000000000); else req->paddr &= ULL(0xffffffffff); @@ -551,36 +557,39 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const read_accesses++; // not a physical address: need to look up pte - AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); if (!pte) { // page fault - fault(req, - (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); + fault(req, (write ? MM_STAT_WR_MASK : 0) | + MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; } - req->paddr = PA_PFN2PA(pte->ppn) | VA_POFS(req->vaddr); + req->paddr = (pte->ppn << AlphaISA::PageShift) + + AlphaISA::VAddr(req->vaddr).offset(); if (write) { if (!(pte->xwe & MODE2MASK(mode))) { // declare the instruction access fault - fault(req, (MM_STAT_WR_MASK | MM_STAT_ACV_MASK | - (pte->fonw ? MM_STAT_FONW_MASK : 0))); + fault(req, MM_STAT_WR_MASK | + MM_STAT_ACV_MASK | + (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; return DTB_Fault_Fault; } if (pte->fonw) { - fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); + fault(req, MM_STAT_WR_MASK | + MM_STAT_FONW_MASK); write_acv++; return DTB_Fault_Fault; } } else { if (!(pte->xre & MODE2MASK(mode))) { - fault(req, (MM_STAT_ACV_MASK | - (pte->fonr ? MM_STAT_FONR_MASK : 0))); + fault(req, MM_STAT_ACV_MASK | + (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; return DTB_Acv_Fault; } @@ -599,7 +608,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const } // check that the physical address is ok (catch bad physical addresses) - if (req->paddr & ~PA_IMPL_MASK) + if (req->paddr & ~PAddrImplMask) return Machine_Check_Fault; checkCacheability(req); diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 42bc03ddd..0d4b8d1f2 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -31,9 +31,10 @@ #include +#include "arch/alpha/isa_traits.hh" +#include "base/statistics.hh" #include "mem/mem_req.hh" #include "sim/sim_object.hh" -#include "base/statistics.hh" class ExecContext; @@ -66,8 +67,8 @@ class AlphaTLB : public SimObject // static helper functions... really EV5 VM traits static bool validVirtualAddress(Addr vaddr) { // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & VA_UNIMPL_MASK; - return (unimplBits == 0) || (unimplBits == VA_UNIMPL_MASK); + Addr unimplBits = vaddr & EV5::VAddrUnImplMask; + return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); } static void checkCacheability(MemReqPtr &req); diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 6deccefdb..2e32da531 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -15,6 +15,8 @@ #ifdef FULL_SYSTEM +using namespace EV5; + //////////////////////////////////////////////////////////////////////// // // @@ -92,7 +94,7 @@ AlphaISA::initIPRs(RegFile *regs) uint64_t *ipr = regs->ipr; bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); - ipr[IPR_PAL_BASE] = PAL_BASE; + ipr[IPR_PAL_BASE] = PalBase; ipr[IPR_MCSR] = 0x6; } diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index 4956d65d9..317f3d19d 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -1,112 +1,79 @@ /* $Id$ */ -#ifndef __EV5_H__ -#define __EV5_H__ +#ifndef __ARCH_ALPHA_EV5_HH__ +#define __ARCH_ALPHA_EV5_HH__ -#define MODE2MASK(X) (1 << (X)) - -// Alpha IPR register accessors -#define PC_PAL(X) ((X) & 0x1) -#define MCSR_SP(X) (((X) >> 1) & 0x3) - -#define ICSR_SDE(X) (((X) >> 30) & 0x1) -#define ICSR_SPE(X) (((X) >> 28) & 0x3) -#define ICSR_FPE(X) (((X) >> 26) & 0x1) - -#define ALT_MODE_AM(X) (((X) >> 3) & 0x3) - -#define DTB_CM_CM(X) (((X) >> 3) & 0x3) +namespace EV5 { #ifdef ALPHA_TLASER -#define DTB_ASN_ASN(X) (((X) >> 57) & 0x7f) -#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff) +const uint64_t AsnMask = ULL(0x7f); #else -#define DTB_ASN_ASN(X) (((X) >> 57) & 0xff) -#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff) +const uint64_t AsnMask = ULL(0xff); #endif -#define DTB_PTE_XRE(X) (((X) >> 8) & 0xf) -#define DTB_PTE_XWE(X) (((X) >> 12) & 0xf) -#define DTB_PTE_FONR(X) (((X) >> 1) & 0x1) -#define DTB_PTE_FONW(X) (((X) >> 2) & 0x1) -#define DTB_PTE_GH(X) (((X) >> 5) & 0x3) -#define DTB_PTE_ASMA(X) (((X) >> 4) & 0x1) - -#define ICM_CM(X) (((X) >> 3) & 0x3) +const int VAddrImplBits = 43; +const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1; +const Addr VAddrUnImplMask = ~VAddrImplMask; +inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; } +inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; } +inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; } +inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; } +inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; } #ifdef ALPHA_TLASER -#define ITB_ASN_ASN(X) (((X) >> 4) & 0x7f) -#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff) +inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFF00000); } +const int PAddrImplBits = 40; #else -#define ITB_ASN_ASN(X) (((X) >> 4) & 0xff) -#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff) +inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFFF00000); } +const int PAddrImplBits = 44; // for Tsunami #endif - -#define ITB_PTE_XRE(X) (((X) >> 8) & 0xf) -#define ITB_PTE_FONR(X) (((X) >> 1) & 0x1) -#define ITB_PTE_FONW(X) (((X) >> 2) & 0x1) -#define ITB_PTE_GH(X) (((X) >> 5) & 0x3) -#define ITB_PTE_ASMA(X) (((X) >> 4) & 0x1) - -#define VA_UNIMPL_MASK ULL(0xfffff80000000000) -#define VA_IMPL_MASK ULL(0x000007ffffffffff) -#define VA_IMPL(X) ((X) & VA_IMPL_MASK) -#define VA_VPN(X) (VA_IMPL(X) >> 13) -#define VA_SPACE_EV5(X) (((X) >> 41) & 0x3) -#define VA_SPACE_EV6(X) (((X) >> 41) & 0x7f) -#define VA_POFS(X) ((X) & 0x1fff) - -#define PA_UNCACHED_BIT_39 ULL(0x8000000000) -#define PA_UNCACHED_BIT_40 ULL(0x10000000000) -#define PA_UNCACHED_BIT_43 ULL(0x80000000000) -#define PA_UNCACHED_MASK ULL(0x807ffffffff) // Clear PA<42:35> -#ifdef ALPHA_TLASER -#define PA_IPR_SPACE(X) ((X) >= ULL(0xFFFFF00000)) -#define PA_IMPL_MASK ULL(0xffffffffff) -#else -#define PA_IPR_SPACE(X) ((X) >= ULL(0xFFFFFF00000)) -#define PA_IMPL_MASK ULL(0xfffffffffff) // for Tsunami -#endif - -#define PA_PFN2PA(X) ((X) << 13) - - -#define MM_STAT_BAD_VA_MASK 0x0020 -#define MM_STAT_DTB_MISS_MASK 0x0010 -#define MM_STAT_FONW_MASK 0x0008 -#define MM_STAT_FONR_MASK 0x0004 -#define MM_STAT_ACV_MASK 0x0002 -#define MM_STAT_WR_MASK 0x0001 - -#define OPCODE(X) (X >> 26) & 0x3f -#define RA(X) (X >> 21) & 0x1f - -//////////////////////////////////////////////////////////////////////// -// -// -// - -// VPTE size for HW_LD/HW_ST -#define HW_VPTE ((inst >> 11) & 0x1) - -// QWORD size for HW_LD/HW_ST -#define HW_QWORD ((inst >> 12) & 0x1) - -// ALT mode for HW_LD/HW_ST -#define HW_ALT (((inst >> 14) & 0x1) ? ALTMODE : 0) - -// LOCK/COND mode for HW_LD/HW_ST -#define HW_LOCK (((inst >> 10) & 0x1) ? LOCKED : 0) -#define HW_COND (((inst >> 10) & 0x1) ? LOCKED : 0) - -// PHY size for HW_LD/HW_ST -#define HW_PHY (((inst >> 15) & 0x1) ? PHYSICAL : 0) - -// OFFSET for HW_LD/HW_ST -#define HW_OFS (inst & 0x3ff) - - -#define PAL_BASE 0x4000 -#define PAL_MAX 0x10000 - -#endif //__EV5_H__ +const Addr PAddrImplMask = (ULL(1) << PAddrImplBits) - 1; +const Addr PAddrUncachedBit39 = ULL(0x8000000000); +const Addr PAddrUncachedBit40 = ULL(0x10000000000); +const Addr PAddrUncachedBit43 = ULL(0x80000000000); +const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35> + +inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; } +inline Addr DTB_PTE_PPN(uint64_t reg) +{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } +inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; } +inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } +inline int DTB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; } +inline int DTB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; } +inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; } + +inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; } +inline Addr ITB_PTE_PPN(uint64_t reg) +{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } +inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } +inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; } +inline int ITB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; } +inline bool ITB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; } + +inline uint64_t MCSR_SP(uint64_t reg) { return reg >> 1 & 0x3; } + +inline bool ICSR_SDE(uint64_t reg) { return reg >> 30 & 0x1; } +inline int ICSR_SPE(uint64_t reg) { return reg >> 28 & 0x3; } +inline bool ICSR_FPE(uint64_t reg) { return reg >> 26 & 0x1; } + +inline uint64_t ALT_MODE_AM(uint64_t reg) { return reg >> 3 & 0x3; } +inline uint64_t DTB_CM_CM(uint64_t reg) { return reg >> 3 & 0x3; } +inline uint64_t ICM_CM(uint64_t reg) { return reg >> 3 & 0x3; } + +const uint64_t MM_STAT_BAD_VA_MASK = ULL(0x0020); +const uint64_t MM_STAT_DTB_MISS_MASK = ULL(0x0010); +const uint64_t MM_STAT_FONW_MASK = ULL(0x0008); +const uint64_t MM_STAT_FONR_MASK = ULL(0x0004); +const uint64_t MM_STAT_ACV_MASK = ULL(0x0002); +const uint64_t MM_STAT_WR_MASK = ULL(0x0001); +inline int Opcode(AlphaISA::MachInst inst) { return inst >> 26 & 0x3f; } +inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; } + +const Addr PalBase = 0x4000; +const Addr PalMax = 0x10000; + +/* namespace EV5 */ } + +#endif // __ARCH_ALPHA_EV5_HH__ diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index 9d65a02f0..5154d78d1 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -38,14 +38,12 @@ output exec {{ #include #endif -#include "cpu/base_cpu.hh" -#include "cpu/exetrace.hh" -#include "sim/sim_exit.hh" - #ifdef FULL_SYSTEM -#include "arch/alpha/ev5.hh" #include "arch/alpha/pseudo_inst.hh" #endif +#include "cpu/base_cpu.hh" +#include "cpu/exetrace.hh" +#include "sim/sim_exit.hh" }}; //////////////////////////////////////////////////////////////////// @@ -515,7 +513,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = No_Fault; // dummy... this ipr access should not fault - if (!ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { + if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { fault = Fen_Fault; } return fault; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index b22b2fa29..ff3da1502 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ISA_TRAITS_HH__ -#define __ISA_TRAITS_HH__ +#ifndef __ARCH_ALPHA_ISA_TRAITS_HH__ +#define __ARCH_ALPHA_ISA_TRAITS_HH__ #include "arch/alpha/faults.hh" #include "base/misc.hh" @@ -42,6 +42,11 @@ class Checkpoint; template class StaticInst; template class StaticInstPtr; +namespace EV5 { +int DTB_ASN_ASN(uint64_t reg); +int ITB_ASN_ASN(uint64_t reg); +} + class AlphaISA { public: @@ -160,6 +165,8 @@ static const Addr PageOffset = PageBytes - 1; InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers + inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } + inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif // FULL_SYSTEM void serialize(std::ostream &os); @@ -281,9 +288,7 @@ typedef TheISA::InternalProcReg InternalProcReg; const int NumInternalProcRegs = TheISA::NumInternalProcRegs; const int NumInterruptLevels = TheISA::NumInterruptLevels; -// more stuff that should be imported here, but I'm too tired to do it -// right now... #include "arch/alpha/ev5.hh" #endif -#endif // __ALPHA_ISA_H__ +#endif // __ARCH_ALPHA_ISA_TRAITS_HH__ diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index a8af8f238..e26721aab 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -85,7 +85,7 @@ vtophys(ExecContext *xc, Addr addr) Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? - if (PC_PAL(vaddr) && (vaddr < PAL_MAX)) { + if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { paddr = vaddr & ~ULL(1); } else { if (AlphaISA::IsK0Seg(vaddr)) { diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 598f03c35..484a01944 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -350,7 +350,7 @@ RemoteGDB::acc(Addr va, size_t len) * but there is no easy way to do it. */ - if (PC_PAL(va) || va < 0x10000) + if (AlphaISA::PcPAL(va) || va < 0x10000) return true; Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 2ba2d7524..8437a5585 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -196,8 +196,8 @@ class ExecContext #ifdef FULL_SYSTEM bool validInstAddr(Addr addr) { return true; } bool validDataAddr(Addr addr) { return true; } - int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); } - int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); } + int getInstAsid() { return regs.instAsid(); } + int getDataAsid() { return regs.dataAsid(); } Fault translateInstReq(MemReqPtr &req) { @@ -410,7 +410,7 @@ class ExecContext int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); - bool inPalMode() { return PC_PAL(regs.pc); } + bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } void ev5_trap(Fault fault); bool simPalCheck(int palFunc); #endif diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 964ab442c..7deabe2fc 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -98,7 +98,7 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) { memset(data, 0, req->size); - Addr daddr = req->paddr - (addr & PA_IMPL_MASK); + Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); switch (req->size) { @@ -198,7 +198,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) return Machine_Check_Fault; } - Addr daddr = req->paddr - (addr & PA_IMPL_MASK); + Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); ExecContext *other_xc; switch (daddr) { diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index d08e61fbf..aa0217745 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -34,16 +34,16 @@ #include "base/trace.hh" #include "cpu/intr_control.hh" #include "dev/dma.hh" -#include "dev/pcireg.h" -#include "dev/pciconfigall.hh" -#include "dev/ide_disk.hh" #include "dev/ide_ctrl.hh" +#include "dev/ide_disk.hh" +#include "dev/pciconfigall.hh" +#include "dev/pcireg.h" +#include "dev/platform.hh" #include "dev/tsunami_cchip.hh" #include "mem/bus/bus.hh" +#include "mem/bus/dma_interface.hh" #include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface_impl.hh" -#include "mem/bus/dma_interface.hh" -#include "dev/tsunami.hh" #include "mem/functional_mem/memory_control.hh" #include "mem/functional_mem/physical_memory.hh" #include "sim/builder.hh" @@ -377,7 +377,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); - pri_cmd_addr &= PA_UNCACHED_MASK; + pri_cmd_addr &= EV5::PAddrUncachedMask; } break; @@ -388,7 +388,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size)); - pri_ctrl_addr &= PA_UNCACHED_MASK; + pri_ctrl_addr &= EV5::PAddrUncachedMask; } break; @@ -399,7 +399,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size)); - sec_cmd_addr &= PA_UNCACHED_MASK; + sec_cmd_addr &= EV5::PAddrUncachedMask; } break; @@ -410,7 +410,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size)); - sec_ctrl_addr &= PA_UNCACHED_MASK; + sec_ctrl_addr &= EV5::PAddrUncachedMask; } break; @@ -420,7 +420,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (pioInterface) pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - bmi_addr &= PA_UNCACHED_MASK; + bmi_addr &= EV5::PAddrUncachedMask; } break; } diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 4d0b93ab9..8eca91510 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -339,7 +339,7 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data) if (pioInterface) pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - BARAddrs[0] &= PA_UNCACHED_MASK; + BARAddrs[0] &= EV5::PAddrUncachedMask; } break; case PCI0_BASE_ADDR1: @@ -347,7 +347,7 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data) if (pioInterface) pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - BARAddrs[1] &= PA_UNCACHED_MASK; + BARAddrs[1] &= EV5::PAddrUncachedMask; } break; } diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 6fee30c10..d5302d9ad 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -71,7 +71,7 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) DPRINTF(PciConfigAll, "read va=%#x size=%d\n", req->vaddr, req->size); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; @@ -115,7 +115,7 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) Fault PciConfigAll::write(MemReqPtr &req, const uint8_t *data) { - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 20b39f21f..c389063d0 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -83,7 +83,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; ExecContext *xc = req->xc; switch (req->size) { @@ -169,7 +169,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 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; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; bool supportedWrite = false; uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index fab1b4b38..51ff8b81c 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -196,7 +196,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", req->vaddr, req->size, req->vaddr & 0xfff); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); switch(req->size) { @@ -298,7 +298,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", req->vaddr, req->size, req->vaddr & 0xfff, dt64); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)); + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); switch(req->size) { case sizeof(uint8_t): diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 4c94d12af..9af19d930 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -82,7 +82,7 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; switch (req->size) { @@ -171,7 +171,7 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) DPRINTF(Tsunami, "write - va=%#x size=%d \n", req->vaddr, req->size); - Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6; + Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; switch (req->size) { diff --git a/dev/uart.cc b/dev/uart.cc index b71ab2d44..2ff94dda5 100644 --- a/dev/uart.cc +++ b/dev/uart.cc @@ -44,7 +44,6 @@ #include "mem/bus/pio_interface_impl.hh" #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" -#include "targetarch/ev5.hh" using namespace std; @@ -118,7 +117,7 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, Fault Uart::read(MemReqPtr &req, uint8_t *data) { - Addr daddr = req->paddr - (addr & PA_IMPL_MASK); + Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); DPRINTF(Uart, " read register %#x\n", daddr); @@ -246,7 +245,7 @@ Uart::read(MemReqPtr &req, uint8_t *data) Fault Uart::write(MemReqPtr &req, const uint8_t *data) { - Addr daddr = req->paddr - (addr & PA_IMPL_MASK); + Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); DPRINTF(Uart, " write register %#x value %#x\n", daddr, *(uint8_t*)data); diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index a322060d8..f4300116e 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -48,7 +48,7 @@ BadAddrEvent::process(ExecContext *xc) uint64_t a0 = xc->regs.intRegFile[ArgumentReg0]; if (!TheISA::IsK0Seg(a0) || - xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & PA_IMPL_MASK)) { + xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); xc->regs.intRegFile[ReturnValueReg] = 0x1; -- cgit v1.2.3 From e9f3279334f714de7bbd1415377715cd00a763d5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 14:46:02 -0500 Subject: sort #includes don't need to include ev5.hh anymore --HG-- extra : convert_revision : f80d2767936d3fb07a9cb7fd4709cafe9ea93e63 --- dev/simconsole.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dev/simconsole.cc b/dev/simconsole.cc index b2afb3f84..d8d890e15 100644 --- a/dev/simconsole.cc +++ b/dev/simconsole.cc @@ -45,12 +45,11 @@ #include "base/misc.hh" #include "base/socket.hh" #include "base/trace.hh" +#include "dev/platform.hh" #include "dev/simconsole.hh" +#include "dev/uart.hh" #include "mem/functional_mem/memory_control.hh" #include "sim/builder.hh" -#include "targetarch/ev5.hh" -#include "dev/uart.hh" -#include "dev/platform.hh" using namespace std; -- cgit v1.2.3 From b031888038a905e1572bbd3ed42ee4e4a7f599a6 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 15:45:22 -0500 Subject: Use parameter structs for initialization so it's easier to add new devices. Abstract the Platform more so that it is unnecessary to know know platform specifics for interrupting or translating PCI DMA addresses. dev/ide_ctrl.cc: convert to parameter struct for initialization use the interrupt functions in the PciDev base class convert from tsunami to using platform We don't need an interrupt controller here. dev/ide_ctrl.hh: don't use Tsunami, use Platform make the IdeDisk a friend so that it can access my plaform convert to parameter struct for construction dev/ide_disk.cc: don't use tsunami references, but platform references dev/ns_gige.cc: Convert to parameter struct for initialzation. Use code in base class for interrupts so we don't need to know anything about the platform. Don't need an IntrControl *. dev/ns_gige.hh: We don't need a Tsunami * anymore convert to a parameter struct for construction dev/pcidev.cc: deal with new parameter struct dev/pcidev.hh: - Move all of the configuration parameters into a param struct that we can pass into the constructor. - Add a Platform * for accessing new generic interrupt post/clear and dma address translation fuctions - Create functions for posting/clearing interrupts and translating dma addresses dev/platform.cc: have default functions that panic on pci calls dev/platform.hh: don't make the pci stuff pure virtual, but rather provide default implementations that panic. Also, add dma address translation. dev/tsunami.cc: this-> isn't necessary here. add pci address translation dev/tsunami.hh: implement the pciToDma address translation --HG-- extra : convert_revision : 7db27a2fa1f1bd84704921ec7ca0280b5653c43e --- dev/ide_ctrl.cc | 68 +++++++++++++------------------ dev/ide_ctrl.hh | 47 ++++++++-------------- dev/ide_disk.cc | 2 +- dev/ns_gige.cc | 123 ++++++++++++++++++++++++++++++++------------------------ dev/ns_gige.hh | 38 ++++++++++------- dev/pcidev.cc | 34 ++++++++-------- dev/pcidev.hh | 91 +++++++++++++++++++++++++---------------- dev/platform.cc | 18 +++++++++ dev/platform.hh | 6 ++- dev/tsunami.cc | 10 ++++- dev/tsunami.hh | 2 + 11 files changed, 248 insertions(+), 191 deletions(-) diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index aa0217745..109908ead 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -39,7 +39,6 @@ #include "dev/pciconfigall.hh" #include "dev/pcireg.h" #include "dev/platform.hh" -#include "dev/tsunami_cchip.hh" #include "mem/bus/bus.hh" #include "mem/bus/dma_interface.hh" #include "mem/bus/pio_interface.hh" @@ -55,13 +54,8 @@ using namespace std; // Initialization and destruction //// -IdeController::IdeController(const string &name, IntrControl *ic, - const vector &new_disks, - MemoryController *mmu, PciConfigAll *cf, - PciConfigData *cd, Tsunami *t, uint32_t bus_num, - uint32_t dev_num, uint32_t func_num, - Bus *host_bus, Tick pio_latency, HierParams *hier) - : PciDev(name, mmu, cf, cd, bus_num, dev_num, func_num), tsunami(t) +IdeController::IdeController(Params *p) + : PciDev(p) { // initialize the PIO interface addresses pri_cmd_addr = 0; @@ -96,23 +90,25 @@ IdeController::IdeController(const string &name, IntrControl *ic, memset(cmd_in_progress, 0, sizeof(cmd_in_progress)); // create the PIO and DMA interfaces - if (host_bus) { - pioInterface = newPioInterface(name, hier, host_bus, this, + if (params()->host_bus) { + pioInterface = newPioInterface(name(), params()->hier, + params()->host_bus, this, &IdeController::cacheAccess); - dmaInterface = new DMAInterface(name + ".dma", host_bus, - host_bus, 1); - pioLatency = pio_latency * host_bus->clockRatio; + dmaInterface = new DMAInterface(name() + ".dma", + params()->host_bus, + params()->host_bus, 1); + pioLatency = params()->pio_latency * params()->host_bus->clockRatio; } // setup the disks attached to controller memset(disks, 0, sizeof(IdeDisk *) * 4); - if (new_disks.size() > 3) + if (params()->disks.size() > 3) panic("IDE controllers support a maximum of 4 devices attached!\n"); - for (int i = 0; i < new_disks.size(); i++) { - disks[i] = new_disks[i]; + for (int i = 0; i < params()->disks.size(); i++) { + disks[i] = params()->disks[i]; disks[i]->setController(this, dmaInterface); } } @@ -235,22 +231,6 @@ IdeController::setDmaComplete(IdeDisk *disk) } } -//// -// Interrupt handling -//// - -void -IdeController::intrPost() -{ - tsunami->postPciInt(configData->config.hdr.pci0.interruptLine); -} - -void -IdeController::intrClear() -{ - tsunami->clearPciInt(configData->config.hdr.pci0.interruptLine); -} - //// // Bus timing and bus access functions //// @@ -684,12 +664,11 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) - SimObjectParam intr_ctrl; SimObjectVectorParam disks; SimObjectParam mmu; SimObjectParam configspace; SimObjectParam configdata; - SimObjectParam tsunami; + SimObjectParam platform; Param pci_bus; Param pci_dev; Param pci_func; @@ -701,12 +680,11 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeController) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) - INIT_PARAM(intr_ctrl, "Interrupt Controller"), INIT_PARAM(disks, "IDE disks attached to this controller"), INIT_PARAM(mmu, "Memory controller"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(tsunami, "Tsunami chipset pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), @@ -718,9 +696,21 @@ END_INIT_SIM_OBJECT_PARAMS(IdeController) CREATE_SIM_OBJECT(IdeController) { - return new IdeController(getInstanceName(), intr_ctrl, disks, mmu, - configspace, configdata, tsunami, pci_bus, - pci_dev, pci_func, io_bus, pio_latency, hier); + IdeController::Params *params = new IdeController::Params; + params->name = getInstanceName(); + params->mmu = mmu; + params->configSpace = configspace; + params->configData = configdata; + params->plat = platform; + params->busNum = pci_bus; + params->deviceNum = pci_dev; + params->functionNum = pci_func; + + params->disks = disks; + params->host_bus = io_bus; + params->pio_latency = pio_latency; + params->hier = hier; + return new IdeController(params); } REGISTER_SIM_OBJECT("IdeController", IdeController) diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index b29e5ae9a..9a6b476b8 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -80,14 +80,14 @@ typedef enum RegType { BMI_BLOCK } RegType_t; +class BaseInterface; +class Bus; +class HierParams; class IdeDisk; class IntrControl; class PciConfigAll; -class Tsunami; class PhysicalMemory; -class BaseInterface; -class HierParams; -class Bus; +class Platform; /** * Device model for an Intel PIIX4 IDE controller @@ -95,6 +95,8 @@ class Bus; class IdeController : public PciDev { + friend class IdeDisk; + private: /** Primary command block registers */ Addr pri_cmd_addr; @@ -125,10 +127,6 @@ class IdeController : public PciDev bool bm_enabled; bool cmd_in_progress[4]; - public: - /** Pointer to the chipset */ - Tsunami *tsunami; - private: /** IDE disks connected to controller */ IdeDisk *disks[4]; @@ -149,29 +147,18 @@ class IdeController : public PciDev bool isDiskSelected(IdeDisk *diskPtr); public: - /** - * Constructs and initializes this controller. - * @param name The name of this controller. - * @param ic The interrupt controller. - * @param mmu The memory controller - * @param cf PCI config space - * @param cd PCI config data - * @param bus_num The PCI bus number - * @param dev_num The PCI device number - * @param func_num The PCI function number - * @param host_bus The host bus to connect to - * @param hier The hierarchy parameters - */ - IdeController(const std::string &name, IntrControl *ic, - const std::vector &new_disks, - MemoryController *mmu, PciConfigAll *cf, - PciConfigData *cd, Tsunami *t, - uint32_t bus_num, uint32_t dev_num, uint32_t func_num, - Bus *host_bus, Tick pio_latency, HierParams *hier); + struct Params : public PciDev::Params + { + /** Array of disk objects */ + std::vector disks; + Bus *host_bus; + Tick pio_latency; + HierParams *hier; + }; + const Params *params() const { return (const Params *)_params; } - /** - * Deletes the connected devices. - */ + public: + IdeController(Params *p); ~IdeController(); virtual void WriteConfig(int offset, int size, uint32_t data); diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index f3760bd5e..073c10436 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -177,7 +177,7 @@ Addr IdeDisk::pciToDma(Addr pciAddr) { if (ctrl) - return ctrl->tsunami->pchip->translatePciToDma(pciAddr); + return ctrl->plat->pciToDma(pciAddr); else panic("Access to unset controller!\n"); } diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 8eca91510..8f233c433 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -41,7 +41,6 @@ #include "dev/etherlink.hh" #include "dev/ns_gige.hh" #include "dev/pciconfigall.hh" -#include "dev/tsunami_cchip.hh" #include "mem/bus/bus.hh" #include "mem/bus/dma_interface.hh" #include "mem/bus/pio_interface.hh" @@ -92,64 +91,62 @@ using namespace Net; // // NSGigE PCI Device // -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, EthAddr eaddr, - uint32_t tx_fifo_size, uint32_t rx_fifo_size) - : PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), ioEnable(false), - maxTxFifoSize(tx_fifo_size), maxRxFifoSize(rx_fifo_size), +NSGigE::NSGigE(Params *p) + : PciDev(p), ioEnable(false), + txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size), txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false), - CTDD(false), txFifoAvail(tx_fifo_size), + CTDD(false), txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), - rxEnable(false), CRDD(false), rxPktBytes(0), rxFifoCnt(0), + rxEnable(false), CRDD(false), rxPktBytes(0), rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), rxDmaReadEvent(this), rxDmaWriteEvent(this), txDmaReadEvent(this), txDmaWriteEvent(this), - dmaDescFree(dma_desc_free), dmaDataFree(dma_data_free), - txDelay(tx_delay), rxDelay(rx_delay), rxKickTick(0), txKickTick(0), - txEvent(this), rxFilterEnable(rx_filter), acceptBroadcast(false), + dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free), + txDelay(p->tx_delay), rxDelay(p->rx_delay), + rxKickTick(0), txKickTick(0), + txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), acceptPerfect(false), acceptArp(false), - physmem(pmem), intctrl(i), intrTick(0), cpuPendingIntr(false), + physmem(p->pmem), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { - if (header_bus) { - pioInterface = newPioInterface(name, hier, header_bus, this, + if (p->header_bus) { + pioInterface = newPioInterface(name(), p->hier, + p->header_bus, this, &NSGigE::cacheAccess); - pioLatency = pio_latency * header_bus->clockRatio; + pioLatency = p->pio_latency * p->header_bus->clockRatio; - if (payload_bus) - dmaInterface = new DMAInterface(name + ".dma", - header_bus, payload_bus, 1); + if (p->payload_bus) + dmaInterface = new DMAInterface(name() + ".dma", + p->header_bus, + p->payload_bus, 1); else - dmaInterface = new DMAInterface(name + ".dma", - header_bus, header_bus, 1); - } else if (payload_bus) { - pioInterface = newPioInterface(name, hier, payload_bus, this, + dmaInterface = new DMAInterface(name() + ".dma", + p->header_bus, + p->header_bus, 1); + } else if (p->payload_bus) { + pioInterface = newPioInterface(name(), p->hier, + p->payload_bus, this, &NSGigE::cacheAccess); - pioLatency = pio_latency * payload_bus->clockRatio; + pioLatency = p->pio_latency * p->payload_bus->clockRatio; - dmaInterface = new DMAInterface(name + ".dma", payload_bus, - payload_bus, 1); + dmaInterface = new DMAInterface(name() + ".dma", + p->payload_bus, + p->payload_bus, 1); } - intrDelay = US2Ticks(intr_delay); - dmaReadDelay = dma_read_delay; - dmaWriteDelay = dma_write_delay; - dmaReadFactor = dma_read_factor; - dmaWriteFactor = dma_write_factor; + intrDelay = US2Ticks(p->intr_delay); + dmaReadDelay = p->dma_read_delay; + dmaWriteDelay = p->dma_write_delay; + dmaReadFactor = p->dma_read_factor; + dmaWriteFactor = p->dma_write_factor; regsReset(); - memcpy(&rom.perfectMatch, eaddr.bytes(), ETH_ADDR_LEN); + memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN); } NSGigE::~NSGigE() @@ -1028,8 +1025,8 @@ NSGigE::cpuInterrupt() // Send interrupt cpuPendingIntr = true; - DPRINTF(EthernetIntr, "posting cchip interrupt\n"); - tsunami->postPciInt(configData->config.hdr.pci0.interruptLine); + DPRINTF(EthernetIntr, "posting interrupt\n"); + intrPost(); } } @@ -1048,8 +1045,8 @@ NSGigE::cpuIntrClear() cpuPendingIntr = false; - DPRINTF(EthernetIntr, "clearing cchip interrupt\n"); - tsunami->clearPciInt(configData->config.hdr.pci0.interruptLine); + DPRINTF(EthernetIntr, "clearing interrupt\n"); + intrClear(); } bool @@ -2450,7 +2447,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param tx_delay; Param rx_delay; - SimObjectParam intr_ctrl; Param intr_delay; SimObjectParam mmu; SimObjectParam physmem; @@ -2468,7 +2464,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param dma_write_factor; SimObjectParam configspace; SimObjectParam configdata; - SimObjectParam tsunami; + SimObjectParam platform; Param pci_bus; Param pci_dev; Param pci_func; @@ -2481,7 +2477,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), - INIT_PARAM(intr_ctrl, "Interrupt Controller"), INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), @@ -2500,7 +2495,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(tsunami, "Tsunami"), + INIT_PARAM(platform, "Platform"), INIT_PARAM(pci_bus, "PCI bus"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), @@ -2512,14 +2507,36 @@ END_INIT_SIM_OBJECT_PARAMS(NSGigE) CREATE_SIM_OBJECT(NSGigE) { - 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, - EthAddr((string)hardware_address), - tx_fifo_size, rx_fifo_size); + NSGigE::Params *params = new NSGigE::Params; + + params->name = getInstanceName(); + params->mmu = mmu; + params->configSpace = configspace; + params->configData = configdata; + params->plat = platform; + params->busNum = pci_bus; + params->deviceNum = pci_dev; + params->functionNum = pci_func; + + params->intr_delay = intr_delay; + params->pmem = physmem; + params->tx_delay = tx_delay; + params->rx_delay = rx_delay; + params->hier = hier; + params->header_bus = header_bus; + params->payload_bus = payload_bus; + params->pio_latency = pio_latency; + params->dma_desc_free = dma_desc_free; + params->dma_data_free = dma_data_free; + params->dma_read_delay = dma_read_delay; + params->dma_write_delay = dma_write_delay; + params->dma_read_factor = dma_read_factor; + params->dma_write_factor = dma_write_factor; + params->rx_filter = rx_filter; + params->eaddr = hardware_address; + params->tx_fifo_size = tx_fifo_size; + params->rx_fifo_size = rx_fifo_size; + return new NSGigE(params); } REGISTER_SIM_OBJECT("NSGigE", NSGigE) diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 60dcf3fc2..5f023dccc 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -41,7 +41,6 @@ #include "dev/io_device.hh" #include "dev/ns_gige_reg.h" #include "dev/pcidev.hh" -#include "dev/tsunami.hh" #include "mem/bus/bus.hh" #include "sim/eventq.hh" @@ -138,10 +137,6 @@ class NSGigE : public PciDev dmaWriteWaiting }; - private: - /** pointer to the chipset */ - Tsunami *tsunami; - private: Addr addr; static const Addr size = sizeof(dp_regs); @@ -330,16 +325,31 @@ class NSGigE : public PciDev NSGigEInt *interface; public: - 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, Net::EthAddr eaddr, - uint32_t tx_fifo_size, uint32_t rx_fifo_size); + struct Params : public PciDev::Params + { + PhysicalMemory *pmem; + HierParams *hier; + Bus *header_bus; + Bus *payload_bus; + Tick intr_delay; + Tick tx_delay; + Tick rx_delay; + 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; + bool rx_filter; + Net::EthAddr eaddr; + uint32_t tx_fifo_size; + uint32_t rx_fifo_size; + }; + + NSGigE(Params *params); ~NSGigE(); + const Params *params() const { return (const Params *)_params; } virtual void WriteConfig(int offset, int size, uint32_t data); virtual void ReadConfig(int offset, int size, uint8_t *data); diff --git a/dev/pcidev.cc b/dev/pcidev.cc index f0ceb40f2..0c64bcb94 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -50,24 +50,23 @@ using namespace std; -PciDev::PciDev(const string &name, MemoryController *mmu, PciConfigAll *cf, - PciConfigData *cd, uint32_t bus, uint32_t dev, uint32_t func) - : DmaDevice(name), mmu(mmu), configSpace(cf), configData(cd), busNum(bus), - deviceNum(dev), functionNum(func) +PciDev::PciDev(Params *p) + : DmaDevice(p->name), _params(p), plat(p->plat), configData(p->configData) { // copy the config data from the PciConfigData object - if (cd) { - memcpy(config.data, cd->config.data, sizeof(config.data)); - memcpy(BARSize, cd->BARSize, sizeof(BARSize)); - memcpy(BARAddrs, cd->BARAddrs, sizeof(BARAddrs)); + if (configData) { + memcpy(config.data, configData->config.data, sizeof(config.data)); + memcpy(BARSize, configData->BARSize, sizeof(BARSize)); + memcpy(BARAddrs, configData->BARAddrs, sizeof(BARAddrs)); } else panic("NULL pointer to configuration data"); // Setup pointer in config space to point to this entry - if (cf->deviceExists(dev,func)) - panic("Two PCI devices occuping same dev: %#x func: %#x", dev, func); + if (p->configSpace->deviceExists(p->deviceNum, p->functionNum)) + panic("Two PCI devices occuping same dev: %#x func: %#x", + p->deviceNum, p->functionNum); else - cf->registerDevice(dev, func, this); + p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); } void @@ -79,7 +78,7 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data) *(uint32_t*)data = htoa(*(uint32_t*)data); DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - deviceNum, functionNum, offset, size, + params()->deviceNum, params()->functionNum, offset, size, *(uint32_t*)(config.data + offset)); break; @@ -88,7 +87,7 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data) *(uint16_t*)data = htoa(*(uint16_t*)data); DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - deviceNum, functionNum, offset, size, + params()->deviceNum, params()->functionNum, offset, size, *(uint16_t*)(config.data + offset)); break; @@ -96,7 +95,7 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data) memcpy((uint8_t*)data, config.data + offset, sizeof(uint8_t)); DPRINTF(PCIDEV, "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - deviceNum, functionNum, offset, size, + params()->deviceNum, params()->functionNum, offset, size, (uint16_t)(*(uint8_t*)(config.data + offset))); break; @@ -119,7 +118,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) DPRINTF(PCIDEV, "write device: %#x function: %#x reg: %#x size: %d data: %#x\n", - deviceNum, functionNum, offset, size, word_value); + params()->deviceNum, params()->functionNum, offset, size, + word_value); barnum = (offset - PCI0_BASE_ADDR0) >> 2; @@ -177,6 +177,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) (htoa(config.data[offset]) & 0xF)); } } else { + MemoryController *mmu = params()->mmu; + // This is I/O Space, bottom two bits are read only if(htoa(config.data[offset]) & 0x1) { *(uint32_t *)&config.data[offset] = htoa((word_value & ~0x3) | @@ -265,7 +267,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) // Add the MMU mappings for the BARs for (int i=0; i < 6; i++) { if (BARAddrs[i] != 0) - mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); + params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); } } diff --git a/dev/pcidev.hh b/dev/pcidev.hh index c0fe47ac4..73d2e3c44 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -30,11 +30,12 @@ * Interface for devices using PCI configuration */ -#ifndef __PCI_DEV_HH__ -#define __PCI_DEV_HH__ +#ifndef __DEV_PCIDEV_HH__ +#define __DEV_PCIDEV_HH__ -#include "dev/pcireg.h" #include "dev/io_device.hh" +#include "dev/pcireg.h" +#include "dev/platform.hh" class PciConfigAll; class MemoryController; @@ -78,29 +79,43 @@ class PciConfigData : public SimObject 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; + struct Params; + Params *_params; - /** - * A pointer to the object that contains the first 64 bytes of - * config space - */ - PciConfigData *configData; + public: + struct Params + { + std::string name; + Platform *plat; + MemoryController *mmu; + + /** + * A pointer to the configspace all object that calls us when + * a read comes to this particular device/function. + */ + PciConfigAll *configSpace; - /** The bus number we are on */ - uint32_t busNum; + /** + * A pointer to the object that contains the first 64 bytes of + * config space + */ + PciConfigData *configData; - /** The device number we have */ - uint32_t deviceNum; + /** The bus number we are on */ + uint32_t busNum; - /** The function number */ - uint32_t functionNum; + /** The device number we have */ + uint32_t deviceNum; - /** The current config space. Unlike the PciConfigData this is updated - * during simulation while continues to refelect what was in the config file. + /** The function number */ + uint32_t functionNum; + }; + const Params *params() const { return _params; } + + protected: + /** The current config space. Unlike the PciConfigData this is + * updated during simulation while continues to refelect what was + * in the config file. */ PCIConfig config; @@ -110,21 +125,29 @@ class PciDev : public DmaDevice /** The current address mapping of the BARs */ Addr BARAddrs[6]; + protected: + Platform *plat; + PciConfigData *configData; + + public: + Addr pciToDma(Addr pciAddr) const + { return plat->pciToDma(pciAddr); } + + void + intrPost() + { plat->postPciInt(configData->config.hdr.pci0.interruptLine); } + + void + intrClear() + { plat->clearPciInt(configData->config.hdr.pci0.interruptLine); } + 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 + * Constructor for PCI Dev. This function copies data from the + * config file object PCIConfigData and registers the device with + * a PciConfigAll object. */ - PciDev(const std::string &name, MemoryController *mmu, PciConfigAll *cf, - PciConfigData *cd, uint32_t bus, uint32_t dev, uint32_t func); + PciDev(Params *params); virtual Fault read(MemReqPtr &req, uint8_t *data) { return No_Fault; @@ -168,4 +191,4 @@ class PciDev : public DmaDevice virtual void unserialize(Checkpoint *cp, const std::string §ion); }; -#endif // __PCI_DEV_HH__ +#endif // __DEV_PCIDEV_HH__ diff --git a/dev/platform.cc b/dev/platform.cc index 8515d543a..cf012352b 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -32,5 +32,23 @@ using namespace std; +void +Platform::postPciInt(int line) +{ + panic("No PCI interrupt support in platform."); +} + +void +Platform::clearPciInt(int line) +{ + panic("No PCI interrupt support in platform."); +} + +Addr +Platform::pciToDma(Addr pciAddr) const +{ + panic("No PCI dma support in platform."); +} + DEFINE_SIM_OBJECT_CLASS_NAME("Platform", Platform) diff --git a/dev/platform.hh b/dev/platform.hh index 0c90e06ba..717e49411 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -35,6 +35,7 @@ #define __PLATFORM_HH_ #include "sim/sim_object.hh" +#include "targetarch/isa_traits.hh" class PciConfigAll; class IntrControl; @@ -65,8 +66,9 @@ class Platform : public SimObject virtual void postConsoleInt() = 0; virtual void clearConsoleInt() = 0; virtual Tick intrFrequency() = 0; - virtual void postPciInt(int line) = 0; - virtual void clearPciInt(int line) = 0; + virtual void postPciInt(int line); + virtual void clearPciInt(int line); + virtual Addr pciToDma(Addr pciAddr) const; }; #endif // __PLATFORM_HH_ diff --git a/dev/tsunami.cc b/dev/tsunami.cc index ce2d473a9..f98254354 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -77,13 +77,19 @@ Tsunami::clearConsoleInt() void Tsunami::postPciInt(int line) { - this->cchip->postDRIR(line); + cchip->postDRIR(line); } void Tsunami::clearPciInt(int line) { - this->cchip->clearDRIR(line); + cchip->clearDRIR(line); +} + +Addr +Tsunami::pciToDma(Addr pciAddr) const +{ + return pchip->translatePciToDma(pciAddr); } void diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 0a7fdbcd9..05563f80b 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -118,6 +118,8 @@ class Tsunami : public Platform */ virtual void clearPciInt(int line); + virtual Addr pciToDma(Addr pciAddr) const; + /** * Serialize this object to the given output stream. * @param os The stream to serialize to. -- cgit v1.2.3 -- cgit v1.2.3 From bd3e3c02300312ae8d00ae9abf3fa009a2cddbc7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 16:24:47 -0500 Subject: forgot a change in the previous commit. the ide controller doesn't have its own interrupt functions dev/ide_ctrl.hh: oops. we don't have our own interrupt functions anymore we get them from the base class. --HG-- extra : convert_revision : 3eac228ec59f4fea0b0e49f961e8b21705dee27f --- dev/ide_ctrl.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 9a6b476b8..f1082d094 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -164,9 +164,6 @@ class IdeController : public PciDev virtual void WriteConfig(int offset, int size, uint32_t data); virtual void ReadConfig(int offset, int size, uint8_t *data); - void intrPost(); - void intrClear(); - void setDmaComplete(IdeDisk *disk); /** -- cgit v1.2.3 From acb98fb0f64a3b6a4f2f3151b0d4fb14fdfcf7cf Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 16:33:16 -0500 Subject: we shouldn't ever pass around references to PacketPtrs, const references are ok, or pass by value. --HG-- extra : convert_revision : 7280a1c7d22b9294fddbe50f02f6f4c6ca9b2e5b --- dev/etherint.hh | 16 ++++++++-------- dev/etherlink.cc | 8 ++++---- dev/etherlink.hh | 6 +++--- dev/ethertap.cc | 2 +- dev/ethertap.hh | 2 +- dev/ns_gige.cc | 4 ++-- dev/ns_gige.hh | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dev/etherint.hh b/dev/etherint.hh index ddfe16d88..bcdf0ae06 100644 --- a/dev/etherint.hh +++ b/dev/etherint.hh @@ -31,8 +31,8 @@ * components. */ -#ifndef __ETHERINT_HH__ -#define __ETHERINT_HH__ +#ifndef __DEV_ETHERINT_HH__ +#define __DEV_ETHERINT_HH__ #include @@ -54,13 +54,13 @@ class EtherInt : public SimObject virtual ~EtherInt() {} void setPeer(EtherInt *p); - virtual bool recvPacket(PacketPtr &packet) = 0; + void recvDone() { peer->sendDone(); } - bool sendPacket(PacketPtr &packet) - { - return peer ? peer->recvPacket(packet) : true; - } virtual void sendDone() = 0; + + bool sendPacket(PacketPtr packet) + { return peer ? peer->recvPacket(packet) : true; } + virtual bool recvPacket(PacketPtr packet) = 0; }; -#endif // __ETHERINT_HH__ +#endif // __DEV_ETHERINT_HH__ diff --git a/dev/etherlink.cc b/dev/etherlink.cc index ccb18d363..a361713cd 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -105,7 +105,7 @@ EtherLink::unserialize(Checkpoint *cp, const string §ion) } void -EtherLink::Link::txComplete(PacketPtr &packet) +EtherLink::Link::txComplete(PacketPtr packet) { DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); @@ -122,7 +122,7 @@ class LinkDelayEvent : public Event LinkDelayEvent(EtherLink::Link *link); public: - LinkDelayEvent(EtherLink::Link *link, PacketPtr &pkt, Tick when); + LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); void process(); @@ -153,7 +153,7 @@ EtherLink::Link::txDone() } bool -EtherLink::Link::transmit(PacketPtr &pkt) +EtherLink::Link::transmit(PacketPtr pkt) { if (busy()) { DPRINTF(Ethernet, "packet not sent, link busy\n"); @@ -217,7 +217,7 @@ LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l) setFlags(AutoDelete); } -LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr &p, Tick when) +LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) : Event(&mainEventQueue), link(l), packet(p) { setFlags(AutoSerialize); diff --git a/dev/etherlink.hh b/dev/etherlink.hh index 204348c6d..e998a006f 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -75,7 +75,7 @@ class EtherLink : public SimObject DoneEvent doneEvent; friend class LinkDelayEvent; - void txComplete(PacketPtr &packet); + void txComplete(PacketPtr packet); public: Link(const std::string &name, double rate, Tick delay, @@ -85,7 +85,7 @@ class EtherLink : public SimObject virtual const std::string name() const { return objName; } bool busy() const { return (bool)packet; } - bool transmit(PacketPtr &packet); + bool transmit(PacketPtr packet); void setTxInt(Interface *i) { assert(!txint); txint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; } @@ -104,7 +104,7 @@ class EtherLink : public SimObject public: Interface(const std::string &name, Link *txlink, Link *rxlink); - bool recvPacket(PacketPtr &packet) { return txlink->transmit(packet); } + bool recvPacket(PacketPtr packet) { return txlink->transmit(packet); } void sendDone() { peer->sendDone(); } }; diff --git a/dev/ethertap.cc b/dev/ethertap.cc index b40a93c1b..03f2724b1 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -169,7 +169,7 @@ EtherTap::detach() } bool -EtherTap::recvPacket(PacketPtr &packet) +EtherTap::recvPacket(PacketPtr packet) { if (dump) dump->dump(packet); diff --git a/dev/ethertap.hh b/dev/ethertap.hh index 9c77a4a4f..5f760ed34 100644 --- a/dev/ethertap.hh +++ b/dev/ethertap.hh @@ -94,7 +94,7 @@ class EtherTap : public EtherInt EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz); virtual ~EtherTap(); - virtual bool recvPacket(PacketPtr &packet); + virtual bool recvPacket(PacketPtr packet); virtual void sendDone(); virtual void serialize(std::ostream &os); diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 8f233c433..79b128025 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1979,7 +1979,7 @@ NSGigE::transferDone() } bool -NSGigE::rxFilter(PacketPtr &packet) +NSGigE::rxFilter(const PacketPtr &packet) { EthPtr eth = packet; bool drop = true; @@ -2019,7 +2019,7 @@ NSGigE::rxFilter(PacketPtr &packet) } bool -NSGigE::recvPacket(PacketPtr &packet) +NSGigE::recvPacket(PacketPtr packet) { rxBytes += packet->length; rxPackets++; diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 5f023dccc..fc2c88a6c 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -295,7 +295,7 @@ class NSGigE : public PciDev * receive address filter */ bool rxFilterEnable; - bool rxFilter(PacketPtr &packet); + bool rxFilter(const PacketPtr &packet); bool acceptBroadcast; bool acceptMulticast; bool acceptUnicast; @@ -360,7 +360,7 @@ class NSGigE : public PciDev bool cpuIntrPending() const; void cpuIntrAck() { cpuIntrClear(); } - bool recvPacket(PacketPtr &packet); + bool recvPacket(PacketPtr packet); void transferDone(); void setInterface(NSGigEInt *i) { assert(!interface); interface = i; } @@ -407,7 +407,7 @@ class NSGigEInt : public EtherInt NSGigEInt(const std::string &name, NSGigE *d) : EtherInt(name), dev(d) { dev->setInterface(this); } - virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); } + virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } virtual void sendDone() { dev->transferDone(); } }; -- cgit v1.2.3 From 8922d699532cf5027c8cabe53aaf8be4db470764 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 16:46:56 -0500 Subject: change the serialization of a packet so that we don't do a nameOut. This fixes a subtle bug in serialization that can pop up. --HG-- extra : convert_revision : b52df977dcbef1c9bd0d4405ba0b36dff3737cdf --- dev/etherlink.cc | 13 +++++-------- dev/etherpkt.cc | 15 ++++++++------- dev/etherpkt.hh | 6 ++++-- dev/ns_gige.cc | 26 ++++++++++---------------- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/dev/etherlink.cc b/dev/etherlink.cc index a361713cd..1e2be41fe 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -185,10 +185,8 @@ EtherLink::Link::serialize(ostream &os) SERIALIZE_SCALAR(event_time); } - if (packet_exists) { - nameOut(os, csprintf("%s.packet", name())); - packet->serialize(os); - } + if (packet_exists) + packet->serialize("packet", os); } void @@ -198,7 +196,7 @@ EtherLink::Link::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(packet_exists); if (packet_exists) { packet = new PacketData; - packet->unserialize(cp, csprintf("%s.packet", section)); + packet->unserialize("packet", cp, section); } bool event_scheduled; @@ -238,8 +236,7 @@ LinkDelayEvent::serialize(ostream &os) Event::serialize(os); SERIALIZE_OBJPTR(link); - nameOut(os, csprintf("%s.packet", name())); - packet->serialize(os); + packet->serialize("packet", os); } @@ -248,7 +245,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) { Event::unserialize(cp, section); packet = new PacketData; - packet->unserialize(cp, csprintf("%s.packet", section)); + packet->unserialize("packet", cp, section); } diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc index 273b8ee64..bf60bc150 100644 --- a/dev/etherpkt.cc +++ b/dev/etherpkt.cc @@ -28,22 +28,23 @@ #include +#include "base/misc.hh" #include "dev/etherpkt.hh" #include "sim/serialize.hh" using namespace std; void -PacketData::serialize(ostream &os) +PacketData::serialize(const string &base, ostream &os) { - SERIALIZE_SCALAR(length); - SERIALIZE_ARRAY(data, length); + paramOut(os, base + ".length", length); + arrayParamOut(os, base + ".data", data, length); } void -PacketData::unserialize(Checkpoint *cp, const string §ion) +PacketData::unserialize(const string &base, Checkpoint *cp, + const string §ion) { - UNSERIALIZE_SCALAR(length); - data = new uint8_t[length]; - UNSERIALIZE_ARRAY(data, length); + paramIn(cp, section, base + ".length", length); + arrayParamIn(cp, section, base + ".data", data, length); } diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index 1b6e9858f..7a7809f0a 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -52,13 +52,15 @@ class PacketData : public RefCounted public: PacketData() : data(NULL), length(0) { } + explicit PacketData(size_t size) : data(new uint8_t[size]), length(0) { } PacketData(std::auto_ptr d, int l) : data(d.release()), length(l) { } ~PacketData() { if (data) delete [] data; } public: - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); }; typedef RefCountingPtr PacketPtr; diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 79b128025..39bae07ab 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -2123,19 +2123,15 @@ NSGigE::serialize(ostream &os) 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); - } + for (pktiter_t p = txFifo.begin(); p != end; ++p) + (*p)->serialize(csprintf("txFifo%d", i++), 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); - } + for (pktiter_t p = rxFifo.begin(); p != end; ++p) + (*p)->serialize(csprintf("rxFifo%d", i++), os); /* * Serialize the various helper variables @@ -2143,8 +2139,7 @@ NSGigE::serialize(ostream &os) bool txPacketExists = txPacket; SERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { - nameOut(os, csprintf("%s.txPacket", name())); - txPacket->serialize(os); + txPacket->serialize("txPacket", os); uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); SERIALIZE_SCALAR(txPktBufPtr); } @@ -2152,8 +2147,7 @@ NSGigE::serialize(ostream &os) bool rxPacketExists = rxPacket; SERIALIZE_SCALAR(rxPacketExists); if (rxPacketExists) { - nameOut(os, csprintf("%s.rxPacket", name())); - rxPacket->serialize(os); + rxPacket->serialize("rxPacket", os); uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); SERIALIZE_SCALAR(rxPktBufPtr); } @@ -2281,7 +2275,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) int i; for (i = 0; i < txNumPkts; ++i) { PacketPtr p = new PacketData; - p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); + p->unserialize(csprintf("rxFifo%d", i), cp, section); txFifo.push_back(p); } @@ -2289,7 +2283,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxNumPkts); for (i = 0; i < rxNumPkts; ++i) { PacketPtr p = new PacketData; - p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); + p->unserialize(csprintf("rxFifo%d", i), cp, section); rxFifo.push_back(p); } @@ -2300,7 +2294,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { txPacket = new PacketData; - txPacket->unserialize(cp, csprintf("%s.txPacket", section)); + txPacket->unserialize("txPacket", cp, section); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; @@ -2312,7 +2306,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) rxPacket = 0; if (rxPacketExists) { rxPacket = new PacketData; - rxPacket->unserialize(cp, csprintf("%s.rxPacket", section)); + rxPacket->unserialize("rxPacket", cp, section); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; -- cgit v1.2.3 From 4760ae46c6f9236bc5c5b45be9f9b059e6594958 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 16:52:08 -0500 Subject: Use the new PacketFifo class to avoid manual calculations --HG-- extra : convert_revision : afa193904b7ed4d5e5c50e9dcb78e8e855b00ecc --- SConscript | 1 + dev/ns_gige.cc | 66 +++++++++------------------------------- dev/ns_gige.hh | 11 ++----- dev/pktfifo.cc | 68 +++++++++++++++++++++++++++++++++++++++++ dev/pktfifo.hh | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 181 insertions(+), 60 deletions(-) create mode 100644 dev/pktfifo.cc create mode 100644 dev/pktfifo.hh diff --git a/SConscript b/SConscript index a2b1c44fa..4fedf25ba 100644 --- a/SConscript +++ b/SConscript @@ -271,6 +271,7 @@ full_system_sources = Split(''' dev/etherdev.cc dev/pciconfigall.cc dev/pcidev.cc + dev/pktfifo.cc dev/scsi.cc dev/scsi_ctrl.cc dev/scsi_disk.cc diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 39bae07ab..e34420a8e 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -1060,7 +1060,6 @@ NSGigE::txReset() DPRINTF(Ethernet, "transmit reset\n"); CTDD = false; - txFifoAvail = maxTxFifoSize; txEnable = false;; txFragPtr = 0; assert(txDescCnt == 0); @@ -1076,7 +1075,6 @@ NSGigE::rxReset() CRDD = false; assert(rxPktBytes == 0); - rxFifoCnt = 0; rxEnable = false; rxFragPtr = 0; assert(rxDescCnt == 0); @@ -1346,9 +1344,7 @@ NSGigE::rxKick() // Must clear the value before popping to decrement the // reference count - rxFifo.front() = NULL; - rxFifo.pop_front(); - rxFifoCnt -= rxPacket->length; + rxFifo.pop(); } @@ -1536,7 +1532,7 @@ NSGigE::transmit() } DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n", - maxTxFifoSize - txFifoAvail); + txFifo.size()); if (interface->sendPacket(txFifo.front())) { #if TRACING_ON if (DTRACE(Ethernet)) { @@ -1556,12 +1552,9 @@ NSGigE::transmit() txBytes += txFifo.front()->length; txPackets++; - txFifoAvail += txFifo.front()->length; - DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", - txFifoAvail); - txFifo.front() = NULL; - txFifo.pop_front(); + txFifo.avail()); + txFifo.pop(); /* * normally do a writeback of the descriptor here, and ONLY @@ -1829,7 +1822,7 @@ NSGigE::txKick() // this is just because the receive can't handle a // packet bigger want to make sure assert(txPacket->length <= 1514); - txFifo.push_back(txPacket); + txFifo.push(txPacket); /* * this following section is not tqo spec, but @@ -1875,7 +1868,7 @@ NSGigE::txKick() } } else { DPRINTF(EthernetSM, "this descriptor isn't done yet\n"); - if (txFifoAvail) { + if (!txFifo.full()) { txState = txFragRead; /* @@ -1884,7 +1877,7 @@ NSGigE::txKick() * is not enough room in the fifo, just whatever room * is left in the fifo */ - txXferLen = min(txDescCnt, txFifoAvail); + txXferLen = min(txDescCnt, txFifo.avail()); txDmaAddr = txFragPtr & 0x3fffffff; txDmaData = txPacketBufPtr; @@ -1910,7 +1903,6 @@ NSGigE::txKick() txPacketBufPtr += txXferLen; txFragPtr += txXferLen; txDescCnt -= txXferLen; - txFifoAvail -= txXferLen; txState = txFifoBlock; break; @@ -2025,7 +2017,7 @@ NSGigE::recvPacket(PacketPtr packet) rxPackets++; DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n", - maxRxFifoSize - rxFifoCnt); + rxFifo.avail()); if (!rxEnable) { DPRINTF(Ethernet, "receive disabled...packet dropped\n"); @@ -2040,15 +2032,14 @@ NSGigE::recvPacket(PacketPtr packet) return true; } - if ((rxFifoCnt + packet->length) >= maxRxFifoSize) { + if (rxFifo.avail() < packet->length) { DPRINTF(Ethernet, "packet will not fit in receive buffer...packet dropped\n"); devIntrPost(ISR_RXORN); return false; } - rxFifo.push_back(packet); - rxFifoCnt += packet->length; + rxFifo.push(packet); interface->recvDone(); rxKick(); @@ -2119,19 +2110,8 @@ NSGigE::serialize(ostream &os) /* * Serialize the data Fifos */ - int txNumPkts = txFifo.size(); - SERIALIZE_SCALAR(txNumPkts); - int i = 0; - pktiter_t end = txFifo.end(); - for (pktiter_t p = txFifo.begin(); p != end; ++p) - (*p)->serialize(csprintf("txFifo%d", i++), os); - - int rxNumPkts = rxFifo.size(); - SERIALIZE_SCALAR(rxNumPkts); - i = 0; - end = rxFifo.end(); - for (pktiter_t p = rxFifo.begin(); p != end; ++p) - (*p)->serialize(csprintf("rxFifo%d", i++), os); + rxFifo.serialize("rxFifo", os); + txFifo.serialize("txFifo", os); /* * Serialize the various helper variables @@ -2174,7 +2154,6 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(txState); SERIALIZE_SCALAR(txEnable); SERIALIZE_SCALAR(CTDD); - SERIALIZE_SCALAR(txFifoAvail); SERIALIZE_SCALAR(txFragPtr); SERIALIZE_SCALAR(txDescCnt); int txDmaState = this->txDmaState; @@ -2188,7 +2167,6 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(rxEnable); SERIALIZE_SCALAR(CRDD); SERIALIZE_SCALAR(rxPktBytes); - SERIALIZE_SCALAR(rxFifoCnt); SERIALIZE_SCALAR(rxDescCnt); int rxDmaState = this->rxDmaState; SERIALIZE_SCALAR(rxDmaState); @@ -2270,22 +2248,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) /* * unserialize the data fifos */ - int txNumPkts; - UNSERIALIZE_SCALAR(txNumPkts); - int i; - for (i = 0; i < txNumPkts; ++i) { - PacketPtr p = new PacketData; - p->unserialize(csprintf("rxFifo%d", i), cp, section); - txFifo.push_back(p); - } - - int rxNumPkts; - UNSERIALIZE_SCALAR(rxNumPkts); - for (i = 0; i < rxNumPkts; ++i) { - PacketPtr p = new PacketData; - p->unserialize(csprintf("rxFifo%d", i), cp, section); - rxFifo.push_back(p); - } + rxFifo.unserialize("rxFifo", cp, section); + txFifo.unserialize("txFifo", cp, section); /* * unserialize the various helper variables @@ -2336,7 +2300,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) this->txState = (TxState) txState; UNSERIALIZE_SCALAR(txEnable); UNSERIALIZE_SCALAR(CTDD); - UNSERIALIZE_SCALAR(txFifoAvail); UNSERIALIZE_SCALAR(txFragPtr); UNSERIALIZE_SCALAR(txDescCnt); int txDmaState; @@ -2352,7 +2315,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxEnable); UNSERIALIZE_SCALAR(CRDD); UNSERIALIZE_SCALAR(rxPktBytes); - UNSERIALIZE_SCALAR(rxFifoCnt); UNSERIALIZE_SCALAR(rxDescCnt); int rxDmaState; UNSERIALIZE_SCALAR(rxDmaState); diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index fc2c88a6c..90711d63f 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -41,6 +41,7 @@ #include "dev/io_device.hh" #include "dev/ns_gige_reg.h" #include "dev/pcidev.hh" +#include "dev/pktfifo.hh" #include "mem/bus/bus.hh" #include "sim/eventq.hh" @@ -158,10 +159,8 @@ class NSGigE : public PciDev /*** BASIC STRUCTURES FOR TX/RX ***/ /* Data FIFOs */ - pktbuf_t txFifo; - uint32_t maxTxFifoSize; - pktbuf_t rxFifo; - uint32_t maxRxFifoSize; + PacketFifo txFifo; + PacketFifo rxFifo; /** various helper vars */ PacketPtr txPacket; @@ -183,8 +182,6 @@ class NSGigE : public PciDev /** Current Transmit Descriptor Done */ bool CTDD; - /** current amt of free space in txDataFifo in bytes */ - uint32_t txFifoAvail; /** halt the tx state machine after next packet */ bool txHalt; /** ptr to the next byte in the current fragment */ @@ -201,8 +198,6 @@ class NSGigE : public PciDev bool CRDD; /** num of bytes in the current packet being drained from rxDataFifo */ uint32_t rxPktBytes; - /** number of bytes in the rxFifo */ - uint32_t rxFifoCnt; /** halt the rx state machine after current packet */ bool rxHalt; /** ptr to the next byte in current fragment */ diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc new file mode 100644 index 000000000..cf09ae910 --- /dev/null +++ b/dev/pktfifo.cc @@ -0,0 +1,68 @@ +/* + * 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 + * 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. + */ + +#include "base/misc.hh" +#include "dev/pktfifo.hh" + +using namespace std; + +void +PacketFifo::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".size", _size); + paramOut(os, base + ".maxsize", _maxsize); + paramOut(os, base + ".packets", fifo.size()); + + int i = 0; + std::list::iterator p = fifo.begin(); + std::list::iterator end = fifo.end(); + while (p != end) { + (*p)->serialize(csprintf("%s.packet%d", base, i), os); + ++p; + ++i; + } +} + +void +PacketFifo::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".size", _size); + paramIn(cp, section, base + ".maxsize", _maxsize); + int fifosize; + paramIn(cp, section, base + ".packets", fifosize); + + fifo.clear(); + fifo.resize(fifosize); + + for (int i = 0; i < fifosize; ++i) { + PacketPtr p = new PacketData; + p->unserialize(csprintf("%s.packet%d", base, i), cp, section); + fifo.push_back(p); + } +} diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh new file mode 100644 index 000000000..a54a49996 --- /dev/null +++ b/dev/pktfifo.hh @@ -0,0 +1,95 @@ +/* + * 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 + * 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 __DEV_PKTFIFO_HH__ +#define __DEV_PKTFIFO_HH__ + +#include +#include +#include + +#include "dev/etherpkt.hh" +#include "sim/serialize.hh" + +class Checkpoint; +class PacketFifo +{ + protected: + std::list fifo; + int _maxsize; + int _size; + + public: + explicit PacketFifo(int max) : _maxsize(max), _size(0) {} + virtual ~PacketFifo() {} + + int maxsize() const { return _maxsize; } + int packets() const { return fifo.size(); } + int size() const { return _size; } + int avail() const { return _maxsize - _size; } + bool empty() const { return _size == 0; } + bool full() const { return _size >= _maxsize; } + + bool push(PacketPtr ptr) + { + if (avail() < ptr->length) + return false; + + _size += ptr->length; + fifo.push_back(ptr); + return true; + } + + PacketPtr front() { return fifo.front(); } + + void pop() + { + if (empty()) + return; + + _size -= fifo.front()->length; + fifo.front() = NULL; + fifo.pop_front(); + } + + void clear() + { + fifo.clear(); + _size = 0; + } + +/** + * Serialization stuff + */ + public: + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, + Checkpoint *cp, const std::string §ion); +}; + +#endif // __DEV_PKTFIFO_HH__ -- cgit v1.2.3 From 9f8db6f4465c57b949504ecc2d4b5e321c4e3602 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 17:05:13 -0500 Subject: don't handle device specific configuration stuff in the base class. While we're at it, very minor formatting. --HG-- extra : convert_revision : b7c719f92ece7234838434294b33833289adbada --- dev/pcidev.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 0c64bcb94..d156b6a02 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -72,6 +72,9 @@ PciDev::PciDev(Params *p) void PciDev::ReadConfig(int offset, int size, uint8_t *data) { + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); + switch(size) { case sizeof(uint32_t): memcpy((uint8_t*)data, config.data + offset, sizeof(uint32_t)); @@ -107,6 +110,9 @@ PciDev::ReadConfig(int offset, int size, uint8_t *data) void PciDev::WriteConfig(int offset, int size, uint32_t data) { + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); + uint32_t barnum; union { @@ -181,7 +187,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) // This is I/O Space, bottom two bits are read only if(htoa(config.data[offset]) & 0x1) { - *(uint32_t *)&config.data[offset] = htoa((word_value & ~0x3) | + *(uint32_t *)&config.data[offset] = + htoa((word_value & ~0x3) | (htoa(config.data[offset]) & 0x3)); if (word_value & ~0x1) { @@ -203,7 +210,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) } else { // This is memory space, bottom four bits are read only - *(uint32_t *)&config.data[offset] = htoa((word_value & ~0xF) | + *(uint32_t *)&config.data[offset] = + htoa((word_value & ~0xF) | (htoa(config.data[offset]) & 0xF)); if (word_value & ~0x3) { -- cgit v1.2.3 From 7e4229fb8fa70cd91f831ad056186e9fc43b9f80 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 13 Nov 2004 17:10:48 -0500 Subject: Add the Simple Integrated Network Interface Controller --HG-- extra : convert_revision : 2bce25881a104e8282a5ed819769c6a7de414fb2 --- SConscript | 1 + dev/sinic.cc | 1435 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ dev/sinic.hh | 340 +++++++++++++ dev/sinicreg.hh | 187 ++++++++ 4 files changed, 1963 insertions(+) create mode 100644 dev/sinic.cc create mode 100644 dev/sinic.hh create mode 100644 dev/sinicreg.hh diff --git a/SConscript b/SConscript index 4fedf25ba..7769d0708 100644 --- a/SConscript +++ b/SConscript @@ -276,6 +276,7 @@ full_system_sources = Split(''' dev/scsi_ctrl.cc dev/scsi_disk.cc dev/scsi_none.cc + dev/sinic.cc dev/simple_disk.cc dev/tlaser_clock.cc dev/tlaser_ipi.cc diff --git a/dev/sinic.cc b/dev/sinic.cc new file mode 100644 index 000000000..32a3825fc --- /dev/null +++ b/dev/sinic.cc @@ -0,0 +1,1435 @@ +/* + * 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. + */ + +#include +#include +#include + +#include "base/inet.hh" +#include "cpu/exec_context.hh" +#include "cpu/intr_control.hh" +#include "dev/dma.hh" +#include "dev/etherlink.hh" +#include "dev/sinic.hh" +#include "dev/pciconfigall.hh" +#include "mem/bus/bus.hh" +#include "mem/bus/dma_interface.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" +#include "sim/debug.hh" +#include "sim/eventq.hh" +#include "sim/host.hh" +#include "sim/sim_stats.hh" +#include "targetarch/vtophys.hh" + +using namespace Net; + +namespace Sinic { + +const char *RxStateStrings[] = +{ + "rxIdle", + "rxFifoBlock", + "rxBeginCopy", + "rxCopy", + "rxCopyDone" +}; + +const char *TxStateStrings[] = +{ + "txIdle", + "txFifoBlock", + "txBeginCopy", + "txCopy", + "txCopyDone" +}; + + +/////////////////////////////////////////////////////////////////////// +// +// Sinic PCI Device +// +Base::Base(Params *p) + : PciDev(p), rxEnable(false), txEnable(false), + intrDelay(US2Ticks(p->intr_delay)), + intrTick(0), cpuIntrEnable(false), cpuPendingIntr(false), intrEvent(0), + interface(NULL) +{ +} + +Device::Device(Params *p) + : Base(p), plat(p->plat), physmem(p->physmem), + rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), + rxKickTick(0), txKickTick(0), + txEvent(this), rxDmaEvent(this), txDmaEvent(this), + dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor), + dmaWriteDelay(p->dma_write_delay), dmaWriteFactor(p->dma_write_factor) +{ + reset(); + + if (p->header_bus) { + pioInterface = newPioInterface(p->name, p->hier, p->header_bus, this, + &Device::cacheAccess); + + pioLatency = p->pio_latency * p->header_bus->clockRatio; + + if (p->payload_bus) + dmaInterface = new DMAInterface(p->name + ".dma", + p->header_bus, p->payload_bus, + 1); + else + dmaInterface = new DMAInterface(p->name + ".dma", + p->header_bus, p->header_bus, + 1); + } else if (p->payload_bus) { + pioInterface = newPioInterface(p->name, p->hier, p->payload_bus, this, + &Device::cacheAccess); + + pioLatency = p->pio_latency * p->payload_bus->clockRatio; + + dmaInterface = new DMAInterface(p->name + ".dma", p->payload_bus, + p->payload_bus, 1); + } +} + +Device::~Device() +{} + +void +Device::regStats() +{ + rxBytes + .name(name() + ".rxBytes") + .desc("Bytes Received") + .prereq(rxBytes) + ; + + rxBandwidth + .name(name() + ".rxBandwidth") + .desc("Receive Bandwidth (bits/s)") + .precision(0) + .prereq(rxBytes) + ; + + rxPackets + .name(name() + ".rxPackets") + .desc("Number of Packets Received") + .prereq(rxBytes) + ; + + rxPacketRate + .name(name() + ".rxPPS") + .desc("Packet Reception Rate (packets/s)") + .precision(0) + .prereq(rxBytes) + ; + + rxIpPackets + .name(name() + ".rxIpPackets") + .desc("Number of IP Packets Received") + .prereq(rxBytes) + ; + + rxTcpPackets + .name(name() + ".rxTcpPackets") + .desc("Number of Packets Received") + .prereq(rxBytes) + ; + + rxUdpPackets + .name(name() + ".rxUdpPackets") + .desc("Number of UDP Packets Received") + .prereq(rxBytes) + ; + + rxIpChecksums + .name(name() + ".rxIpChecksums") + .desc("Number of rx IP Checksums done by device") + .precision(0) + .prereq(rxBytes) + ; + + rxTcpChecksums + .name(name() + ".rxTcpChecksums") + .desc("Number of rx TCP Checksums done by device") + .precision(0) + .prereq(rxBytes) + ; + + rxUdpChecksums + .name(name() + ".rxUdpChecksums") + .desc("Number of rx UDP Checksums done by device") + .precision(0) + .prereq(rxBytes) + ; + + txBytes + .name(name() + ".txBytes") + .desc("Bytes Transmitted") + .prereq(txBytes) + ; + + txBandwidth + .name(name() + ".txBandwidth") + .desc("Transmit Bandwidth (bits/s)") + .precision(0) + .prereq(txBytes) + ; + + txPackets + .name(name() + ".txPackets") + .desc("Number of Packets Transmitted") + .prereq(txBytes) + ; + + txPacketRate + .name(name() + ".txPPS") + .desc("Packet Tranmission Rate (packets/s)") + .precision(0) + .prereq(txBytes) + ; + + txIpPackets + .name(name() + ".txIpPackets") + .desc("Number of IP Packets Transmitted") + .prereq(txBytes) + ; + + txTcpPackets + .name(name() + ".txTcpPackets") + .desc("Number of TCP Packets Transmitted") + .prereq(txBytes) + ; + + txUdpPackets + .name(name() + ".txUdpPackets") + .desc("Number of Packets Transmitted") + .prereq(txBytes) + ; + + txIpChecksums + .name(name() + ".txIpChecksums") + .desc("Number of tx IP Checksums done by device") + .precision(0) + .prereq(txBytes) + ; + + txTcpChecksums + .name(name() + ".txTcpChecksums") + .desc("Number of tx TCP Checksums done by device") + .precision(0) + .prereq(txBytes) + ; + + txUdpChecksums + .name(name() + ".txUdpChecksums") + .desc("Number of tx UDP Checksums done by device") + .precision(0) + .prereq(txBytes) + ; + + txBandwidth = txBytes * Stats::constant(8) / simSeconds; + rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; + txPacketRate = txPackets / simSeconds; + rxPacketRate = rxPackets / simSeconds; +} + +/** + * This is to write to the PCI general configuration registers + */ +void +Device::WriteConfig(int offset, int size, uint32_t data) +{ + switch (offset) { + case PCI0_BASE_ADDR0: + // Need to catch writes to BARs to update the PIO interface + PciDev::WriteConfig(offset, size, data); + if (BARAddrs[0] != 0) { + if (pioInterface) + pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); + + BARAddrs[0] &= EV5::PAddrUncachedMask; + } + break; + + default: + PciDev::WriteConfig(offset, size, data); + } +} + +/** + * This reads the device registers, which are detailed in the NS83820 + * spec sheet + */ +Fault +Device::read(MemReqPtr &req, uint8_t *data) +{ + assert(config.hdr.command & PCI_CMD_MSE); + + //The mask is to give you only the offset into the device register file + Addr daddr = req->paddr & 0xfff; + + if (Regs::regSize(daddr) == 0) + panic("invalid address: da=%#x pa=%#x va=%#x size=%d", + daddr, req->paddr, req->vaddr, req->size); + + if (req->size != Regs::regSize(daddr)) + panic("invalid size for reg %s: da=%#x pa=%#x va=%#x size=%d", + Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size); + + DPRINTF(EthernetPIO, "read reg=%s da=%#x pa=%#x va=%#x size=%d\n", + Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size); + + uint32_t ®32 = *(uint32_t *)data; + uint64_t ®64 = *(uint64_t *)data; + + switch (daddr) { + case Regs::Config: + reg32 = regs.Config; + break; + + case Regs::RxMaxCopy: + reg32 = regs.RxMaxCopy; + break; + + case Regs::TxMaxCopy: + reg32 = regs.TxMaxCopy; + break; + + case Regs::RxThreshold: + reg32 = regs.RxThreshold; + break; + + case Regs::TxThreshold: + reg32 = regs.TxThreshold; + break; + + case Regs::IntrStatus: + reg32 = regs.IntrStatus; + devIntrClear(); + break; + + case Regs::IntrMask: + reg32 = regs.IntrMask; + break; + + case Regs::RxData: + reg64 = regs.RxData; + break; + + case Regs::RxDone: + case Regs::RxWait: + reg64 = Regs::set_RxDone_FifoLen(regs.RxDone, + min(rxFifo.packets(), 255)); + break; + + case Regs::TxData: + reg64 = regs.TxData; + break; + + case Regs::TxDone: + case Regs::TxWait: + reg64 = Regs::set_TxDone_FifoLen(regs.TxDone, + min(txFifo.packets(), 255)); + break; + + case Regs::HwAddr: + reg64 = params()->eaddr; + break; + + default: + panic("reading write only register %s: da=%#x pa=%#x va=%#x size=%d", + Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size); + } + + DPRINTF(EthernetPIO, "read reg=%s done val=%#x\n", Regs::regName(daddr), + Regs::regSize(daddr) == 4 ? reg32 : reg64); + + return No_Fault; +} + +Fault +Device::write(MemReqPtr &req, const uint8_t *data) +{ + assert(config.hdr.command & PCI_CMD_MSE); + Addr daddr = req->paddr & 0xfff; + + if (Regs::regSize(daddr) == 0) + panic("invalid address: da=%#x pa=%#x va=%#x size=%d", + daddr, req->paddr, req->vaddr, req->size); + + if (req->size != Regs::regSize(daddr)) + panic("invalid size: reg=%s da=%#x pa=%#x va=%#x size=%d", + Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size); + + uint32_t reg32 = *(uint32_t *)data; + uint64_t reg64 = *(uint64_t *)data; + + DPRINTF(EthernetPIO, "write reg=%s val=%#x da=%#x pa=%#x va=%#x size=%d\n", + Regs::regName(daddr), Regs::regSize(daddr) == 4 ? reg32 : reg64, + daddr, req->paddr, req->vaddr, req->size); + + + switch (daddr) { + case Regs::Config: + changeConfig(reg32); + break; + + case Regs::RxThreshold: + regs.RxThreshold = reg32; + break; + + case Regs::TxThreshold: + regs.TxThreshold = reg32; + break; + + case Regs::IntrMask: + devIntrChangeMask(reg32); + break; + + case Regs::RxData: + if (rxState != rxIdle) + panic("receive machine busy with another request!"); + + regs.RxDone = 0; + regs.RxData = reg64; + if (rxEnable) { + rxState = rxFifoBlock; + rxKick(); + } + break; + + case Regs::TxData: + if (txState != txIdle) + panic("transmit machine busy with another request!"); + + regs.TxDone = 0; + regs.TxData = reg64; + if (txEnable) { + txState = txFifoBlock; + txKick(); + } + break; + + default: + panic("writing read only register %s: da=%#x pa=%#x va=%#x size=%d", + Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size); + } + + return No_Fault; +} + +void +Device::devIntrPost(uint32_t interrupts) +{ + if ((interrupts & Regs::Intr_Res)) + panic("Cannot set a reserved interrupt"); + + regs.IntrStatus |= interrupts; + + DPRINTF(EthernetIntr, + "interrupt written to intStatus: intr=%#x status=%#x mask=%#x\n", + interrupts, regs.IntrStatus, regs.IntrMask); + + if ((regs.IntrStatus & regs.IntrMask)) { + Tick when = curTick; + if ((regs.IntrStatus & regs.IntrMask & Regs::Intr_NoDelay) == 0) + when += intrDelay; + cpuIntrPost(when); + } +} + +void +Device::devIntrClear(uint32_t interrupts) +{ + if ((interrupts & Regs::Intr_Res)) + panic("Cannot clear a reserved interrupt"); + + regs.IntrStatus &= ~interrupts; + + DPRINTF(EthernetIntr, + "interrupt cleared from intStatus: intr=%x status=%x mask=%x\n", + interrupts, regs.IntrStatus, regs.IntrMask); + + if (!(regs.IntrStatus & regs.IntrMask)) + cpuIntrClear(); +} + +void +Device::devIntrChangeMask(uint32_t newmask) +{ + if (regs.IntrMask == newmask) + return; + + regs.IntrMask = newmask; + + DPRINTF(EthernetIntr, + "interrupt mask changed: intStatus=%x intMask=%x masked=%x\n", + regs.IntrStatus, regs.IntrMask, regs.IntrStatus & regs.IntrMask); + + if (regs.IntrStatus & regs.IntrMask) + cpuIntrPost(curTick); + else + cpuIntrClear(); +} + +void +Base::cpuIntrPost(Tick when) +{ + // If the interrupt you want to post is later than an interrupt + // already scheduled, just let it post in the coming one and don't + // schedule another. + // HOWEVER, must be sure that the scheduled intrTick is in the + // future (this was formerly the source of a bug) + /** + * @todo this warning should be removed and the intrTick code should + * be fixed. + */ + assert(when >= curTick); + assert(intrTick >= curTick || intrTick == 0); + if (!cpuIntrEnable) { + DPRINTF(EthernetIntr, "interrupts not enabled.\n", + intrTick); + return; + } + + if (when > intrTick && intrTick != 0) { + DPRINTF(EthernetIntr, "don't need to schedule event...intrTick=%d\n", + intrTick); + return; + } + + intrTick = when; + if (intrTick < curTick) { + debug_break(); + intrTick = curTick; + } + + DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n", + intrTick); + + if (intrEvent) + intrEvent->squash(); + intrEvent = new IntrEvent(this, true); + intrEvent->schedule(intrTick); +} + +void +Base::cpuInterrupt() +{ + assert(intrTick == curTick); + + // Whether or not there's a pending interrupt, we don't care about + // it anymore + intrEvent = 0; + intrTick = 0; + + // Don't send an interrupt if there's already one + if (cpuPendingIntr) { + DPRINTF(EthernetIntr, + "would send an interrupt now, but there's already pending\n"); + } else { + // Send interrupt + cpuPendingIntr = true; + + DPRINTF(EthernetIntr, "posting interrupt\n"); + intrPost(); + } +} + +void +Base::cpuIntrClear() +{ + if (!cpuPendingIntr) + return; + + if (intrEvent) { + intrEvent->squash(); + intrEvent = 0; + } + + intrTick = 0; + + cpuPendingIntr = false; + + DPRINTF(EthernetIntr, "clearing cchip interrupt\n"); + intrClear(); +} + +bool +Base::cpuIntrPending() const +{ return cpuPendingIntr; } + +void +Device::changeConfig(uint32_t newconf) +{ + uint32_t changed = regs.Config ^ newconf; + if (!changed) + return; + + regs.Config = newconf; + + if ((changed & Regs::Config_Reset)) { + assert(regs.Config & Regs::Config_Reset); + reset(); + regs.Config &= ~Regs::Config_Reset; + } + + if ((changed & Regs::Config_IntEn)) { + cpuIntrEnable = regs.Config & Regs::Config_IntEn; + if (cpuIntrEnable) { + if (regs.IntrStatus & regs.IntrMask) + cpuIntrPost(curTick); + } else { + cpuIntrClear(); + } + } + + if ((changed & Regs::Config_TxEn)) { + txEnable = regs.Config & Regs::Config_TxEn; + if (txEnable) + txKick(); + } + + if ((changed & Regs::Config_RxEn)) { + rxEnable = regs.Config & Regs::Config_RxEn; + if (rxEnable) + rxKick(); + } +} + +void +Device::reset() +{ + using namespace Regs; + memset(®s, 0, sizeof(regs)); + regs.RxMaxCopy = params()->rx_max_copy; + regs.TxMaxCopy = params()->tx_max_copy; + regs.IntrMask = Intr_TxFifo | Intr_RxFifo | Intr_RxData; + + rxState = rxIdle; + txState = txIdle; + + rxFifo.clear(); + txFifo.clear(); +} + +void +Device::rxDmaCopy() +{ + assert(rxState == rxCopy); + rxState = rxCopyDone; + physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); + DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", + rxDmaAddr, rxDmaLen); + DDUMP(EthernetDMA, rxDmaData, rxDmaLen); +} + +void +Device::rxDmaDone() +{ + rxDmaCopy(); + rxKick(); +} + +void +Device::rxKick() +{ + DPRINTF(EthernetSM, "receive kick rxState=%s (rxFifo.size=%d)\n", + RxStateStrings[rxState], rxFifo.size()); + + if (rxKickTick > curTick) { + DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n", + rxKickTick); + return; + } + + next: + switch (rxState) { + case rxIdle: + if (rxPioRequest) { + pioInterface->respond(rxPioRequest, curTick); + rxPioRequest = 0; + } + goto exit; + + case rxFifoBlock: + if (rxPacket) { + rxState = rxBeginCopy; + break; + } + + if (rxFifo.empty()) { + DPRINTF(EthernetSM, "receive waiting for data. Nothing to do.\n"); + goto exit; + } + + // Grab a new packet from the fifo. + rxPacket = rxFifo.front(); + rxPacketBufPtr = rxPacket->data; + rxPktBytes = rxPacket->length; + assert(rxPktBytes); + + rxDoneData = 0; + /* scope for variables */ { + IpPtr ip(rxPacket); + if (ip) { + rxDoneData |= Regs::RxDone_IpPacket; + rxIpChecksums++; + if (cksum(ip) != 0) { + DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); + rxDoneData |= Regs::RxDone_IpError; + } + TcpPtr tcp(ip); + UdpPtr udp(ip); + if (tcp) { + rxDoneData |= Regs::RxDone_TcpPacket; + rxTcpChecksums++; + if (cksum(tcp) != 0) { + DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); + rxDoneData |= Regs::RxDone_TcpError; + } + } else if (udp) { + rxDoneData |= Regs::RxDone_UdpPacket; + rxUdpChecksums++; + if (cksum(udp) != 0) { + DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); + rxDoneData |= Regs::RxDone_UdpError; + } + } + } + } + rxState = rxBeginCopy; + break; + + case rxBeginCopy: + rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(regs.RxData)); + rxDmaLen = min(Regs::get_RxData_Len(regs.RxData), rxPktBytes); + rxDmaData = rxPacketBufPtr; + + if (dmaInterface) { + if (!dmaInterface->busy()) { + dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, + curTick, &rxDmaEvent, true); + rxState = rxCopy; + } + goto exit; + } + + rxState = rxCopy; + if (dmaWriteDelay != 0 || dmaWriteFactor != 0) { + Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; + Tick start = curTick + dmaWriteDelay + factor; + rxDmaEvent.schedule(start); + goto exit; + } + + rxDmaCopy(); + break; + + case rxCopy: + DPRINTF(EthernetSM, "receive machine still copying\n"); + goto exit; + + case rxCopyDone: + regs.RxDone = rxDoneData | rxDmaLen; + + if (rxPktBytes == rxDmaLen) { + rxPacket = NULL; + rxFifo.pop(); + } else { + regs.RxDone |= Regs::RxDone_More; + rxPktBytes -= rxDmaLen; + rxPacketBufPtr += rxDmaLen; + } + + regs.RxDone |= Regs::RxDone_Complete; + devIntrPost(Regs::Intr_RxData); + rxState = rxIdle; + break; + + default: + panic("Invalid rxState!"); + } + + DPRINTF(EthernetSM, "entering next rxState=%s\n", + RxStateStrings[rxState]); + + goto next; + + exit: + /** + * @todo do we want to schedule a future kick? + */ + DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n", + RxStateStrings[rxState]); +} + +void +Device::txDmaCopy() +{ + assert(txState == txCopy); + txState = txCopyDone; + physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); + DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", + txDmaAddr, txDmaLen); + DDUMP(EthernetDMA, txDmaData, txDmaLen); +} + +void +Device::txDmaDone() +{ + txDmaCopy(); + txKick(); +} + +void +Device::transmit() +{ + if (txFifo.empty()) { + DPRINTF(Ethernet, "nothing to transmit\n"); + return; + } + + PacketPtr packet = txFifo.front(); + if (!interface->sendPacket(packet)) { + DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n", + txFifo.avail()); + goto reschedule; + } + + txFifo.pop(); + +#if TRACING_ON + if (DTRACE(Ethernet)) { + IpPtr ip(packet); + if (ip) { + DPRINTF(Ethernet, "ID is %d\n", ip->id()); + TcpPtr tcp(ip); + if (tcp) { + DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n", + tcp->sport(), tcp->dport()); + } + } + } +#endif + + DDUMP(Ethernet, packet->data, packet->length); + txBytes += packet->length; + txPackets++; + + DPRINTF(Ethernet, "Packet Transmit: successful txFifo Available %d\n", + txFifo.avail()); + + if (txFifo.size() <= params()->tx_fifo_threshold) + devIntrPost(Regs::Intr_TxFifo); + + devIntrPost(Regs::Intr_TxDone); + + reschedule: + if (!txFifo.empty() && !txEvent.scheduled()) { + DPRINTF(Ethernet, "reschedule transmit\n"); + txEvent.schedule(curTick + 1000); + } +} + +void +Device::txKick() +{ + DPRINTF(EthernetSM, "transmit kick txState=%s (txFifo.size=%d)\n", + TxStateStrings[txState], txFifo.size()); + + if (txKickTick > curTick) { + DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n", + txKickTick); + return; + } + + next: + switch (txState) { + case txIdle: + if (txPioRequest) { + pioInterface->respond(txPioRequest, curTick + pioLatency); + txPioRequest = 0; + } + goto exit; + + case txFifoBlock: + if (!txPacket) { + // Grab a new packet from the fifo. + txPacket = new PacketData(16384); + txPacketBufPtr = txPacket->data; + } + + if (txFifo.avail() - txPacket->length < + Regs::get_TxData_Len(regs.TxData)) { + DPRINTF(EthernetSM, "transmit fifo full. Nothing to do.\n"); + goto exit; + } + + txState = txBeginCopy; + break; + + case txBeginCopy: + txDmaAddr = plat->pciToDma(Regs::get_TxData_Addr(regs.TxData)); + txDmaLen = Regs::get_TxData_Len(regs.TxData); + txDmaData = txPacketBufPtr; + + if (dmaInterface) { + if (!dmaInterface->busy()) { + dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, + curTick, &txDmaEvent, true); + txState = txCopy; + } + + goto exit; + } + + txState = txCopy; + if (dmaReadDelay != 0 || dmaReadFactor != 0) { + Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; + Tick start = curTick + dmaReadDelay + factor; + txDmaEvent.schedule(start); + goto exit; + } + + txDmaCopy(); + break; + + case txCopy: + DPRINTF(EthernetSM, "transmit machine still copying\n"); + goto exit; + + case txCopyDone: + txPacket->length += txDmaLen; + if ((regs.TxData & Regs::TxData_More)) { + txPacketBufPtr += txDmaLen; + } else { + assert(txPacket->length <= txFifo.avail()); + if ((regs.TxData & Regs::TxData_Checksum)) { + IpPtr ip(txPacket); + if (ip) { + TcpPtr tcp(ip); + if (tcp) { + tcp->sum(0); + tcp->sum(cksum(tcp)); + txTcpChecksums++; + } + + UdpPtr udp(ip); + if (udp) { + udp->sum(0); + udp->sum(cksum(udp)); + txUdpChecksums++; + } + + ip->sum(0); + ip->sum(cksum(ip)); + txIpChecksums++; + } + } + txFifo.push(txPacket); + txPacket = 0; + transmit(); + } + + regs.TxDone = txDmaLen | Regs::TxDone_Complete; + devIntrPost(Regs::Intr_TxData); + txState = txIdle; + break; + + default: + panic("Invalid txState!"); + } + + DPRINTF(EthernetSM, "entering next txState=%s\n", + TxStateStrings[txState]); + + goto next; + + exit: + /** + * @todo do we want to schedule a future kick? + */ + DPRINTF(EthernetSM, "tx state machine exited txState=%s\n", + TxStateStrings[txState]); +} + +void +Device::transferDone() +{ + if (txFifo.empty()) { + DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n"); + return; + } + + DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n"); + + if (txEvent.scheduled()) + txEvent.reschedule(curTick + 1); + else + txEvent.schedule(curTick + 1); +} + +bool +Device::rxFilter(const PacketPtr &packet) +{ + if (!Regs::get_Config_Filter(regs.Config)) + return false; + + panic("receive filter not implemented\n"); + bool drop = true; + +#if 0 + string type; + + EthHdr *eth = packet->eth(); + if (eth->unicast()) { + // If we're accepting all unicast addresses + if (acceptUnicast) + drop = false; + + // If we make a perfect match + if (acceptPerfect && params->eaddr == eth.dst()) + drop = false; + + if (acceptArp && eth->type() == ETH_TYPE_ARP) + drop = false; + + } else if (eth->broadcast()) { + // if we're accepting broadcasts + if (acceptBroadcast) + drop = false; + + } else if (eth->multicast()) { + // if we're accepting all multicasts + if (acceptMulticast) + drop = false; + + } + + if (drop) { + DPRINTF(Ethernet, "rxFilter drop\n"); + DDUMP(EthernetData, packet->data, packet->length); + } +#endif + return drop; +} + +bool +Device::recvPacket(PacketPtr packet) +{ + rxBytes += packet->length; + rxPackets++; + + DPRINTF(Ethernet, "Receiving packet from wire, rxFifo Available is %d\n", + rxFifo.avail()); + + if (!rxEnable) { + DPRINTF(Ethernet, "receive disabled...packet dropped\n"); + interface->recvDone(); + return true; + } + + if (rxFilter(packet)) { + DPRINTF(Ethernet, "packet filtered...dropped\n"); + interface->recvDone(); + return true; + } + + if (rxFifo.size() >= params()->rx_fifo_threshold) + devIntrPost(Regs::Intr_RxFifo); + + if (!rxFifo.push(packet)) { + DPRINTF(Ethernet, + "packet will not fit in receive buffer...packet dropped\n"); + return false; + } + + interface->recvDone(); + devIntrPost(Regs::Intr_RxDone); + rxKick(); + return true; +} + +//===================================================================== +// +// +void +Base::serialize(ostream &os) +{ + // Serialize the PciDev base class + PciDev::serialize(os); + + SERIALIZE_SCALAR(rxEnable); + SERIALIZE_SCALAR(txEnable); + SERIALIZE_SCALAR(cpuIntrEnable); + + /* + * Keep track of pending interrupt status. + */ + SERIALIZE_SCALAR(intrTick); + SERIALIZE_SCALAR(cpuPendingIntr); + Tick intrEventTick = 0; + if (intrEvent) + intrEventTick = intrEvent->when(); + SERIALIZE_SCALAR(intrEventTick); +} + +void +Base::unserialize(Checkpoint *cp, const std::string §ion) +{ + // Unserialize the PciDev base class + PciDev::unserialize(cp, section); + + UNSERIALIZE_SCALAR(rxEnable); + UNSERIALIZE_SCALAR(txEnable); + UNSERIALIZE_SCALAR(cpuIntrEnable); + + /* + * Keep track of pending interrupt status. + */ + UNSERIALIZE_SCALAR(intrTick); + UNSERIALIZE_SCALAR(cpuPendingIntr); + Tick intrEventTick; + UNSERIALIZE_SCALAR(intrEventTick); + if (intrEventTick) { + intrEvent = new IntrEvent(this, true); + intrEvent->schedule(intrEventTick); + } +} + +void +Device::serialize(ostream &os) +{ + // Serialize the PciDev base class + Base::serialize(os); + + if (rxDmaEvent.scheduled()) + rxDmaCopy(); + + if (txDmaEvent.scheduled()) + txDmaCopy(); + + /* + * Serialize the device registers + */ + SERIALIZE_SCALAR(regs.Config); + SERIALIZE_SCALAR(regs.RxMaxCopy); + SERIALIZE_SCALAR(regs.TxMaxCopy); + SERIALIZE_SCALAR(regs.RxThreshold); + SERIALIZE_SCALAR(regs.TxThreshold); + SERIALIZE_SCALAR(regs.IntrStatus); + SERIALIZE_SCALAR(regs.IntrMask); + SERIALIZE_SCALAR(regs.RxData); + SERIALIZE_SCALAR(regs.RxDone); + SERIALIZE_SCALAR(regs.TxData); + SERIALIZE_SCALAR(regs.TxDone); + + /* + * Serialize rx state machine + */ + int rxState = this->rxState; + SERIALIZE_SCALAR(rxState); + rxFifo.serialize("rxFifo", os); + bool rxPacketExists = rxPacket; + SERIALIZE_SCALAR(rxPacketExists); + if (rxPacketExists) { + rxPacket->serialize("rxPacket", os); + uint32_t rxPktBufPtr = (uint32_t) (rxPacketBufPtr - rxPacket->data); + SERIALIZE_SCALAR(rxPktBufPtr); + SERIALIZE_SCALAR(rxPktBytes); + } + SERIALIZE_SCALAR(rxDoneData); + + /* + * Serialize tx state machine + */ + int txState = this->txState; + SERIALIZE_SCALAR(txState); + txFifo.serialize("txFifo", os); + bool txPacketExists = txPacket; + SERIALIZE_SCALAR(txPacketExists); + if (txPacketExists) { + txPacket->serialize("txPacket", os); + uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data); + SERIALIZE_SCALAR(txPktBufPtr); + SERIALIZE_SCALAR(txPktBytes); + } + + /* + * If there's a pending transmit, store the time so we can + * reschedule it later + */ + Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick : 0; + SERIALIZE_SCALAR(transmitTick); +} + +void +Device::unserialize(Checkpoint *cp, const std::string §ion) +{ + // Unserialize the PciDev base class + Base::unserialize(cp, section); + + /* + * Unserialize the device registers + */ + UNSERIALIZE_SCALAR(regs.Config); + UNSERIALIZE_SCALAR(regs.RxMaxCopy); + UNSERIALIZE_SCALAR(regs.TxMaxCopy); + UNSERIALIZE_SCALAR(regs.RxThreshold); + UNSERIALIZE_SCALAR(regs.TxThreshold); + UNSERIALIZE_SCALAR(regs.IntrStatus); + UNSERIALIZE_SCALAR(regs.IntrMask); + UNSERIALIZE_SCALAR(regs.RxData); + UNSERIALIZE_SCALAR(regs.RxDone); + UNSERIALIZE_SCALAR(regs.TxData); + UNSERIALIZE_SCALAR(regs.TxDone); + + /* + * Unserialize rx state machine + */ + int rxState; + UNSERIALIZE_SCALAR(rxState); + this->rxState = (RxState) rxState; + rxFifo.unserialize("rxFifo", cp, section); + bool rxPacketExists; + UNSERIALIZE_SCALAR(rxPacketExists); + rxPacket = 0; + if (rxPacketExists) { + rxPacket = new PacketData; + rxPacket->unserialize("rxPacket", cp, section); + uint32_t rxPktBufPtr; + UNSERIALIZE_SCALAR(rxPktBufPtr); + this->rxPacketBufPtr = (uint8_t *) rxPacket->data + rxPktBufPtr; + UNSERIALIZE_SCALAR(rxPktBytes); + } + UNSERIALIZE_SCALAR(rxDoneData); + + /* + * Unserialize tx state machine + */ + int txState; + UNSERIALIZE_SCALAR(txState); + this->txState = (TxState) txState; + txFifo.unserialize("txFifo", cp, section); + bool txPacketExists; + UNSERIALIZE_SCALAR(txPacketExists); + txPacket = 0; + if (txPacketExists) { + txPacket = new PacketData; + txPacket->unserialize("txPacket", cp, section); + uint32_t txPktBufPtr; + UNSERIALIZE_SCALAR(txPktBufPtr); + this->txPacketBufPtr = (uint8_t *) txPacket->data + txPktBufPtr; + UNSERIALIZE_SCALAR(txPktBytes); + } + + /* + * If there's a pending transmit, reschedule it now + */ + Tick transmitTick; + UNSERIALIZE_SCALAR(transmitTick); + if (transmitTick) + txEvent.schedule(curTick + transmitTick); + + /* + * re-add addrRanges to bus bridges + */ + if (pioInterface) { + pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); + pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); + } +} + +Tick +Device::cacheAccess(MemReqPtr &req) +{ + //The mask is to give you only the offset into the device register file + Addr daddr = req->paddr - addr; + + DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", + req->paddr, daddr); + + Tick when = curTick + pioLatency; + + switch (daddr) { + case Regs::RxDone: + if (rxState != rxIdle) { + rxPioRequest = req; + when = 0; + } + break; + + case Regs::TxDone: + if (txState != txIdle) { + txPioRequest = req; + when = 0; + } + break; + } + + return when; +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface) + + SimObjectParam peer; + SimObjectParam device; + +END_DECLARE_SIM_OBJECT_PARAMS(Interface) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Interface) + + INIT_PARAM_DFLT(peer, "peer interface", NULL), + INIT_PARAM(device, "Ethernet device of this interface") + +END_INIT_SIM_OBJECT_PARAMS(Interface) + +CREATE_SIM_OBJECT(Interface) +{ + Interface *dev_int = new Interface(getInstanceName(), device); + + EtherInt *p = (EtherInt *)peer; + if (p) { + dev_int->setPeer(p); + p->setPeer(dev_int); + } + + return dev_int; +} + +REGISTER_SIM_OBJECT("SinicInt", Interface) + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) + + Param tx_delay; + Param rx_delay; + Param intr_delay; + SimObjectParam mmu; + SimObjectParam physmem; + Param rx_filter; + Param hardware_address; + SimObjectParam header_bus; + SimObjectParam payload_bus; + SimObjectParam hier; + Param pio_latency; + SimObjectParam configspace; + SimObjectParam configdata; + SimObjectParam platform; + Param pci_bus; + Param pci_dev; + Param pci_func; + Param rx_max_copy; + Param tx_max_copy; + Param rx_fifo_size; + Param tx_fifo_size; + Param rx_fifo_threshold; + Param tx_fifo_threshold; + Param dma_read_delay; + Param dma_read_factor; + Param dma_write_delay; + Param dma_write_factor; + +END_DECLARE_SIM_OBJECT_PARAMS(Device) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Device) + + INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), + INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), + INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), + INIT_PARAM(mmu, "Memory Controller"), + INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), + INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", + "00:99:00:00:00:01"), + INIT_PARAM_DFLT(header_bus, "The IO Bus to attach to for headers", NULL), + INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), + INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), + INIT_PARAM(configspace, "PCI Configspace"), + INIT_PARAM(configdata, "PCI Config data"), + INIT_PARAM(platform, "Platform"), + INIT_PARAM(pci_bus, "PCI bus"), + INIT_PARAM(pci_dev, "PCI device number"), + INIT_PARAM(pci_func, "PCI function code"), + INIT_PARAM_DFLT(rx_max_copy, "rx max copy", 16*1024), + INIT_PARAM_DFLT(tx_max_copy, "rx max copy", 16*1024), + INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 64*1024), + INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 64*1024), + INIT_PARAM_DFLT(rx_fifo_threshold, "max size in bytes of rxFifo", 48*1024), + INIT_PARAM_DFLT(tx_fifo_threshold, "max size in bytes of txFifo", 16*1024), + INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0), + INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0), + INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0), + INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0) + +END_INIT_SIM_OBJECT_PARAMS(Device) + + +CREATE_SIM_OBJECT(Device) +{ + Device::Params *params = new Device::Params; + params->name = getInstanceName(); + params->intr_delay = intr_delay; + params->physmem = physmem; + params->tx_delay = tx_delay; + params->rx_delay = rx_delay; + params->mmu = mmu; + params->hier = hier; + params->header_bus = header_bus; + params->payload_bus = payload_bus; + params->pio_latency = pio_latency; + params->configSpace = configspace; + params->configData = configdata; + params->plat = platform; + params->busNum = pci_bus; + params->deviceNum = pci_dev; + params->functionNum = pci_func; + params->rx_filter = rx_filter; + params->eaddr = hardware_address; + params->rx_max_copy = rx_max_copy; + params->tx_max_copy = tx_max_copy; + params->rx_fifo_size = rx_fifo_size; + params->tx_fifo_size = tx_fifo_size; + params->rx_fifo_threshold = rx_fifo_threshold; + params->tx_fifo_threshold = tx_fifo_threshold; + params->dma_read_delay = dma_read_delay; + params->dma_read_factor = dma_read_factor; + params->dma_write_delay = dma_write_delay; + params->dma_write_factor = dma_write_factor; + return new Device(params); +} + +REGISTER_SIM_OBJECT("Sinic", Device) + +/* namespace Sinic */ } diff --git a/dev/sinic.hh b/dev/sinic.hh new file mode 100644 index 000000000..ef515ffad --- /dev/null +++ b/dev/sinic.hh @@ -0,0 +1,340 @@ +/* + * 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 __DEV_SINIC_HH__ +#define __DEV_SINIC_HH__ + +#include "base/inet.hh" +#include "base/statistics.hh" +#include "dev/etherint.hh" +#include "dev/etherpkt.hh" +#include "dev/io_device.hh" +#include "dev/pcidev.hh" +#include "dev/pktfifo.hh" +#include "dev/sinicreg.hh" +#include "mem/bus/bus.hh" +#include "sim/eventq.hh" + +namespace Sinic { + +class Interface; +class Base : public PciDev +{ + protected: + bool rxEnable; + bool txEnable; + + protected: + Tick intrDelay; + Tick intrTick; + bool cpuIntrEnable; + bool cpuPendingIntr; + void cpuIntrPost(Tick when); + void cpuInterrupt(); + void cpuIntrClear(); + + typedef EventWrapper IntrEvent; + friend class IntrEvent; + IntrEvent *intrEvent; + Interface *interface; + + bool cpuIntrPending() const; + void cpuIntrAck() { cpuIntrClear(); } + +/** + * Serialization stuff + */ + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +/** + * Construction/Destruction/Parameters + */ + public: + struct Params : public PciDev::Params + { + Tick intr_delay; + }; + + Base(Params *p); +}; + +class Device : public Base +{ + protected: + Platform *plat; + PhysicalMemory *physmem; + + protected: + /** Receive State Machine States */ + enum RxState { + rxIdle, + rxFifoBlock, + rxBeginCopy, + rxCopy, + rxCopyDone + }; + + /** Transmit State Machine states */ + enum TxState { + txIdle, + txFifoBlock, + txBeginCopy, + txCopy, + txCopyDone + }; + + /** device register file */ + struct { + uint32_t Config; + uint32_t RxMaxCopy; + uint32_t TxMaxCopy; + uint32_t RxThreshold; + uint32_t TxThreshold; + uint32_t IntrStatus; + uint32_t IntrMask; + uint64_t RxData; + uint64_t RxDone; + uint64_t TxData; + uint64_t TxDone; + } regs; + + private: + Addr addr; + static const Addr size = Regs::Size; + + protected: + RxState rxState; + PacketFifo rxFifo; + PacketPtr rxPacket; + uint8_t *rxPacketBufPtr; + int rxPktBytes; + uint64_t rxDoneData; + Addr rxDmaAddr; + uint8_t *rxDmaData; + int rxDmaLen; + + TxState txState; + PacketFifo txFifo; + PacketPtr txPacket; + uint8_t *txPacketBufPtr; + int txPktBytes; + Addr txDmaAddr; + uint8_t *txDmaData; + int txDmaLen; + + protected: + void reset(); + + void rxKick(); + Tick rxKickTick; + typedef EventWrapper RxKickEvent; + friend class RxKickEvent; + + void txKick(); + Tick txKickTick; + typedef EventWrapper TxKickEvent; + friend class TxKickEvent; + + /** + * Retransmit event + */ + void transmit(); + void txEventTransmit() + { + transmit(); + if (txState == txFifoBlock) + txKick(); + } + typedef EventWrapper TxEvent; + friend class TxEvent; + TxEvent txEvent; + + void txDump() const; + void rxDump() const; + + /** + * receive address filter + */ + bool rxFilter(const PacketPtr &packet); + +/** + * device configuration + */ + void changeConfig(uint32_t newconfig); + +/** + * device ethernet interface + */ + public: + bool recvPacket(PacketPtr packet); + void transferDone(); + void setInterface(Interface *i) { assert(!interface); interface = i; } + +/** + * DMA parameters + */ + protected: + void rxDmaCopy(); + void rxDmaDone(); + friend class EventWrapper; + EventWrapper rxDmaEvent; + + void txDmaCopy(); + void txDmaDone(); + friend class EventWrapper; + EventWrapper txDmaEvent; + + Tick dmaReadDelay; + Tick dmaReadFactor; + Tick dmaWriteDelay; + Tick dmaWriteFactor; + +/** + * PIO parameters + */ + protected: + MemReqPtr rxPioRequest; + MemReqPtr txPioRequest; + +/** + * Interrupt management + */ + protected: + void devIntrPost(uint32_t interrupts); + void devIntrClear(uint32_t interrupts = Regs::Intr_All); + void devIntrChangeMask(uint32_t newmask); + +/** + * PCI Configuration interface + */ + public: + virtual void WriteConfig(int offset, int size, uint32_t data); + +/** + * Memory Interface + */ + public: + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); + Tick cacheAccess(MemReqPtr &req); + +/** + * Statistics + */ + private: + Stats::Scalar<> rxBytes; + Stats::Formula rxBandwidth; + Stats::Scalar<> rxPackets; + Stats::Formula rxPacketRate; + Stats::Scalar<> rxIpPackets; + Stats::Scalar<> rxTcpPackets; + Stats::Scalar<> rxUdpPackets; + Stats::Scalar<> rxIpChecksums; + Stats::Scalar<> rxTcpChecksums; + Stats::Scalar<> rxUdpChecksums; + + Stats::Scalar<> txBytes; + Stats::Formula txBandwidth; + Stats::Scalar<> txPackets; + Stats::Formula txPacketRate; + Stats::Scalar<> txIpPackets; + Stats::Scalar<> txTcpPackets; + Stats::Scalar<> txUdpPackets; + Stats::Scalar<> txIpChecksums; + Stats::Scalar<> txTcpChecksums; + Stats::Scalar<> txUdpChecksums; + + public: + virtual void regStats(); + +/** + * Serialization stuff + */ + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +/** + * Construction/Destruction/Parameters + */ + public: + struct Params : public Base::Params + { + IntrControl *i; + PhysicalMemory *pmem; + Tick tx_delay; + Tick rx_delay; + HierParams *hier; + Bus *header_bus; + Bus *payload_bus; + Tick pio_latency; + PhysicalMemory *physmem; + IntrControl *intctrl; + bool rx_filter; + Net::EthAddr eaddr; + uint32_t rx_max_copy; + uint32_t tx_max_copy; + uint32_t rx_fifo_size; + uint32_t tx_fifo_size; + uint32_t rx_fifo_threshold; + uint32_t tx_fifo_threshold; + Tick dma_read_delay; + Tick dma_read_factor; + Tick dma_write_delay; + Tick dma_write_factor; + }; + + protected: + const Params *params() const { return (const Params *)_params; } + + public: + Device(Params *params); + ~Device(); +}; + +/* + * Ethernet Interface for an Ethernet Device + */ +class Interface : public EtherInt +{ + private: + Device *dev; + + public: + Interface(const std::string &name, Device *d) + : EtherInt(name), dev(d) { dev->setInterface(this); } + + virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } + virtual void sendDone() { dev->transferDone(); } +}; + +/* namespace Sinic */ } + +#endif // __DEV_SINIC_HH__ diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh new file mode 100644 index 000000000..9f3412a31 --- /dev/null +++ b/dev/sinicreg.hh @@ -0,0 +1,187 @@ +/* + * 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 __DEV_SINICREG_HH__ +#define __DEV_SINICREG_HH__ + +#define __SINIC_REG32(NAME, VAL) static const uint32_t NAME = (VAL) +#define __SINIC_REG64(NAME, VAL) static const uint64_t NAME = (VAL) + +#define __SINIC_VAL32(NAME, OFFSET, WIDTH) \ + static const uint32_t NAME##_width = WIDTH; \ + static const uint32_t NAME##_offset = OFFSET; \ + static const uint32_t NAME##_mask = (1 << WIDTH) - 1; \ + static const uint32_t NAME = ((1 << WIDTH) - 1) << OFFSET; \ + static inline uint32_t get_##NAME(uint32_t reg) \ + { return (reg & NAME) >> OFFSET; } \ + static inline uint32_t set_##NAME(uint32_t reg, uint32_t val) \ + { return (reg & ~NAME) | ((val << OFFSET) & NAME); } + +#define __SINIC_VAL64(NAME, OFFSET, WIDTH) \ + static const uint64_t NAME##_width = WIDTH; \ + static const uint64_t NAME##_offset = OFFSET; \ + static const uint64_t NAME##_mask = (ULL(1) << WIDTH) - 1; \ + static const uint64_t NAME = ((ULL(1) << WIDTH) - 1) << OFFSET; \ + static inline uint64_t get_##NAME(uint64_t reg) \ + { return (reg & NAME) >> OFFSET; } \ + static inline uint64_t set_##NAME(uint64_t reg, uint64_t val) \ + { return (reg & ~NAME) | ((val << OFFSET) & NAME); } + +namespace Sinic { +namespace Regs { + +// Registers +__SINIC_REG32(Config, 0x00); // 32: configuration register +__SINIC_REG32(RxMaxCopy, 0x04); // 32: max rx copy +__SINIC_REG32(TxMaxCopy, 0x08); // 32: max tx copy +__SINIC_REG32(RxThreshold, 0x0c); // 32: receive fifo threshold +__SINIC_REG32(TxThreshold, 0x10); // 32: transmit fifo threshold +__SINIC_REG32(IntrStatus, 0x14); // 32: interrupt status +__SINIC_REG32(IntrMask, 0x18); // 32: interrupt mask +__SINIC_REG32(RxData, 0x20); // 64: receive data +__SINIC_REG32(RxDone, 0x28); // 64: receive done +__SINIC_REG32(RxWait, 0x30); // 64: receive done (busy wait) +__SINIC_REG32(TxData, 0x38); // 64: transmit data +__SINIC_REG32(TxDone, 0x40); // 64: transmit done +__SINIC_REG32(TxWait, 0x48); // 64: transmit done (busy wait) +__SINIC_REG32(HwAddr, 0x50); // 64: mac address +__SINIC_REG32(Size, 0x58); + +// Config register bits +__SINIC_VAL32(Config_Reset, 31, 1); // reset chip +__SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter +__SINIC_VAL32(Config_Vlan, 6, 1); // enable vlan tagging +__SINIC_VAL32(Config_Virtual, 5, 1); // enable virtual addressing +__SINIC_VAL32(Config_Desc, 4, 1); // enable tx/rx descriptors +__SINIC_VAL32(Config_Poll, 3, 1); // enable polling +__SINIC_VAL32(Config_IntEn, 2, 1); // enable interrupts +__SINIC_VAL32(Config_TxEn, 1, 1); // enable transmit +__SINIC_VAL32(Config_RxEn, 0, 1); // enable receive + +// Interrupt register bits +__SINIC_VAL32(Intr_TxFifo, 5, 1); // Fifo oflow/uflow/threshold +__SINIC_VAL32(Intr_TxData, 4, 1); // DMA Completed w/ interrupt +__SINIC_VAL32(Intr_TxDone, 3, 1); // Packet transmitted +__SINIC_VAL32(Intr_RxFifo, 2, 1); // Fifo oflow/uflow/threshold +__SINIC_VAL32(Intr_RxData, 1, 1); // DMA Completed w/ interrupt +__SINIC_VAL32(Intr_RxDone, 0, 1); // Packet received +__SINIC_REG32(Intr_All, 0x3f); +__SINIC_REG32(Intr_NoDelay, 0x24); +__SINIC_REG32(Intr_Res, ~0x3f); + +// RX Data Description +__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M +__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB + +// TX Data Description +__SINIC_VAL64(TxData_More, 63, 1); +__SINIC_VAL64(TxData_Checksum, 62, 1); +__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 1M +__SINIC_VAL64(TxData_Addr, 0, 40); // Address 1TB + +// RX Done/Busy Information +__SINIC_VAL64(RxDone_Complete, 63, 1); +__SINIC_VAL64(RxDone_IpPacket, 45, 1); +__SINIC_VAL64(RxDone_TcpPacket, 44, 1); +__SINIC_VAL64(RxDone_UdpPacket, 43, 1); +__SINIC_VAL64(RxDone_IpError, 42, 1); +__SINIC_VAL64(RxDone_TcpError, 41, 1); +__SINIC_VAL64(RxDone_UdpError, 40, 1); +__SINIC_VAL64(RxDone_More, 32, 1); +__SINIC_VAL64(RxDone_FifoLen, 20, 8); // up to 255 packets +__SINIC_VAL64(RxDone_CopyLen, 0, 20); // up to 256k + +// TX Done/Busy Information +__SINIC_VAL64(TxDone_Complete, 63, 1); +__SINIC_VAL64(TxDone_FifoLen, 20, 8); // up to 255 packets +__SINIC_VAL64(TxDone_CopyLen, 0, 20); // up to 256k + +inline int +regSize(int offset) +{ + static const char sizes[] = { + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 0, + 8, 0, + 8, 0, + 8, 0, + 8, 0, + 8, 0, + 8, 0, + 8, 0 + }; + + if (offset & 0x3) + return 0; + + if (offset >= Size) + return 0; + + return sizes[offset / 4]; +} + +inline const char * +regName(int offset) +{ + static const char *names[] = { + "Config", + "RxMaxCopy", + "TxMaxCopy", + "RxThreshold", + "TxThreshold", + "IntrStatus", + "IntrMask", + "invalid", + "RxData", "invalid", + "RxDone", "invalid", + "RxWait", "invalid", + "TxData", "invalid", + "TxDone", "invalid", + "TxWait", "invalid", + "HwAddr", "invalid" + }; + + if (offset & 0x3) + return "invalid"; + + if (offset >= Size) + return "invalid"; + + return names[offset / 4]; +} + +/* namespace Regs */ } +/* namespace Sinic */ } + +#endif // __DEV_SINICREG_HH__ -- cgit v1.2.3 From 2e0695ec9ae9bbc798c8164e9dd66f59fef93b4e Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 13 Nov 2004 21:13:25 -0500 Subject: Get rid of obsolete sim/sim_stats.* files (looks like these are replaced by sim/stats.hh and sim/stat_control.*) dev/ns_gige.cc: dev/sinic.cc: Include sim/stats.hh instead of sim/sim_stats.hh --HG-- extra : convert_revision : 5e07932eab45ae4fb719baa4f94c5f62092a8446 --- dev/ns_gige.cc | 2 +- dev/sinic.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index e34420a8e..401599126 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -50,7 +50,7 @@ #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/host.hh" -#include "sim/sim_stats.hh" +#include "sim/stats.hh" #include "targetarch/vtophys.hh" const char *NsRxStateStrings[] = diff --git a/dev/sinic.cc b/dev/sinic.cc index 32a3825fc..80364ef20 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -47,7 +47,7 @@ #include "sim/debug.hh" #include "sim/eventq.hh" #include "sim/host.hh" -#include "sim/sim_stats.hh" +#include "sim/stats.hh" #include "targetarch/vtophys.hh" using namespace Net; -- cgit v1.2.3 From f63dd31f4ec1c68ddadbce406a8d1b7d93670016 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 13 Nov 2004 23:08:08 -0500 Subject: fixed nfs scripts hopefully for the last time configs/boot/nfs-client.rcS: lucky #3 --HG-- extra : convert_revision : a55f29e4c087e7ab95ea584316ad6fe4ebb5df9a --- configs/boot/nfs-client.rcS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/boot/nfs-client.rcS b/configs/boot/nfs-client.rcS index 86ad54da6..b0763b77f 100755 --- a/configs/boot/nfs-client.rcS +++ b/configs/boot/nfs-client.rcS @@ -45,6 +45,6 @@ mkdir /nfs mount 10.0.0.1:/nfs /nfs echo "done." -/bin/bonnie++ -u 99 -s 120 -r 0 -n 0 -d /nfs +/bin/bonnie++ -u 99 -s 100 -r 0 -n 0 -d /nfs /sbin/m5 exit -- cgit v1.2.3 From a89398e26271ce8e299aa77b521591c363a492ab Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 13 Nov 2004 23:09:17 -0500 Subject: patched nfs boot scripts configs/boot/nfs-server.rcS: made the partition size correct --HG-- extra : convert_revision : 4e9bdbe3e465aea2a914fd928b47296031c2523b --- configs/boot/nfs-server.rcS | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/configs/boot/nfs-server.rcS b/configs/boot/nfs-server.rcS index c5b17348e..feefc057f 100755 --- a/configs/boot/nfs-server.rcS +++ b/configs/boot/nfs-server.rcS @@ -47,14 +47,13 @@ echo "/nfs 10.0.0.0/255.0.0.0(rw,sync,no_root_squash)" > /etc/exports /sbin/insmod /modules/scsi_debug.ko dev_size_mb=128 echo -n "creating partition and formatting..." -echo "1,126,L" > /tmp/sfdisk.run -echo ";" >> /tmp/sfdisk.run -echo ";" >> /tmp/sfdisk.run -/usr/sbin/sfdisk --force /dev/sda < /tmp/sfdisk.run +echo "1,120,L" > /tmp/sfdisk.run +/usr/sbin/sfdisk -uM --force /dev/sda < /tmp/sfdisk.run /sbin/mke2fs /dev/sda1 mkdir /nfs /bin/mount /dev/sda1 /nfs chmod a+rwx /nfs +/usr/sbin/sfdisk -uM -l /dev/sda echo "done." echo -n "starting nfs kernel server..." -- cgit v1.2.3