summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2004-11-14 16:19:11 -0500
committerRon Dreslinski <rdreslin@umich.edu>2004-11-14 16:19:11 -0500
commitf7d1166e04aa3ec2d13df382832edb5157118410 (patch)
treecf15d02622ee384e18a7327bbacd8bd0afe5afa5
parentcf5eea0e456011d2c2dba28b75497fb6980ae364 (diff)
parenta89398e26271ce8e299aa77b521591c363a492ab (diff)
downloadgem5-f7d1166e04aa3ec2d13df382832edb5157118410.tar.xz
Merge zizzer:/z/m5/Bitkeeper/m5
into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/clean --HG-- extra : convert_revision : 170f5fd8891b02ad3cc04112c6f304ede3254dae
-rw-r--r--SConscript2
-rw-r--r--arch/alpha/alpha_memory.cc119
-rw-r--r--arch/alpha/alpha_memory.hh7
-rw-r--r--arch/alpha/ev5.cc6
-rw-r--r--arch/alpha/ev5.hh171
-rw-r--r--arch/alpha/isa_desc10
-rw-r--r--arch/alpha/isa_traits.hh15
-rw-r--r--arch/alpha/vtophys.cc2
-rw-r--r--base/remote_gdb.cc2
-rw-r--r--build/SConstruct2
-rwxr-xr-xconfigs/boot/nfs-client.rcS5
-rwxr-xr-xconfigs/boot/nfs-server.rcS7
-rw-r--r--cpu/exec_context.hh6
-rw-r--r--dev/alpha_console.cc4
-rw-r--r--dev/etherint.hh16
-rw-r--r--dev/etherlink.cc21
-rw-r--r--dev/etherlink.hh6
-rw-r--r--dev/etherpkt.cc15
-rw-r--r--dev/etherpkt.hh6
-rw-r--r--dev/ethertap.cc2
-rw-r--r--dev/ethertap.hh2
-rw-r--r--dev/ide_ctrl.cc88
-rw-r--r--dev/ide_ctrl.hh50
-rw-r--r--dev/ide_disk.cc2
-rw-r--r--dev/ns_gige.cc213
-rw-r--r--dev/ns_gige.hh55
-rw-r--r--dev/pciconfigall.cc4
-rw-r--r--dev/pcidev.cc46
-rw-r--r--dev/pcidev.hh91
-rw-r--r--dev/pktfifo.cc68
-rw-r--r--dev/pktfifo.hh95
-rw-r--r--dev/platform.cc18
-rw-r--r--dev/platform.hh6
-rw-r--r--dev/simconsole.cc5
-rw-r--r--dev/sinic.cc1435
-rw-r--r--dev/sinic.hh340
-rw-r--r--dev/sinicreg.hh187
-rw-r--r--dev/tsunami.cc10
-rw-r--r--dev/tsunami.hh2
-rw-r--r--dev/tsunami_cchip.cc4
-rw-r--r--dev/tsunami_io.cc4
-rw-r--r--dev/tsunami_pchip.cc4
-rw-r--r--dev/uart.cc5
-rw-r--r--kern/tru64/tru64_events.cc2
44 files changed, 2635 insertions, 525 deletions
diff --git a/SConscript b/SConscript
index a2b1c44fa..7769d0708 100644
--- a/SConscript
+++ b/SConscript
@@ -271,10 +271,12 @@ 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
dev/scsi_none.cc
+ dev/sinic.cc
dev/simple_disk.cc
dev/tlaser_clock.cc
dev/tlaser_ipi.cc
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 <vector>
#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 <map>
+#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 34b65a915..2e32da531 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -15,9 +15,7 @@
#ifdef FULL_SYSTEM
-#ifndef SYSTEM_EV5
-#error This code is only valid for EV5 systems
-#endif
+using namespace EV5;
////////////////////////////////////////////////////////////////////////
//
@@ -96,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 7b1ff4a2f..317f3d19d 100644
--- a/arch/alpha/ev5.hh
+++ b/arch/alpha/ev5.hh
@@ -1,116 +1,79 @@
/* $Id$ */
-#ifndef __EV5_H__
-#define __EV5_H__
+#ifndef __ARCH_ALPHA_EV5_HH__
+#define __ARCH_ALPHA_EV5_HH__
-#ifndef SYSTEM_EV5
-#error This code is only valid for EV5 systems
-#endif
-
-#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)
-
-#ifdef ALPHA_TLASER
-#define DTB_ASN_ASN(X) (((X) >> 57) & 0x7f)
-#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff)
-#else
-#define DTB_ASN_ASN(X) (((X) >> 57) & 0xff)
-#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff)
-#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)
+namespace EV5 {
#ifdef ALPHA_TLASER
-#define ITB_ASN_ASN(X) (((X) >> 4) & 0x7f)
-#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff)
+const uint64_t AsnMask = ULL(0x7f);
#else
-#define ITB_ASN_ASN(X) (((X) >> 4) & 0xff)
-#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff)
+const uint64_t AsnMask = ULL(0xff);
#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)
+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; }
-#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)
+inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFF00000); }
+const int PAddrImplBits = 40;
#else
-#define PA_IPR_SPACE(X) ((X) >= ULL(0xFFFFFF00000))
-#define PA_IMPL_MASK ULL(0xfffffffffff) // for Tsunami
+inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFFF00000); }
+const int PAddrImplBits = 44; // 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 <fenv.h>
#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 ISA> class StaticInst;
template <class ISA> 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/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 = {
diff --git a/configs/boot/nfs-client.rcS b/configs/boot/nfs-client.rcS
index a8c45f4a5..b0763b77f 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 100 -r 0 -n 0 -d /nfs
-echo -n "starting bash shell..."
-/bin/bash
+/sbin/m5 exit
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..."
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/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 <string>
@@ -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..1e2be41fe 100644
--- a/dev/etherlink.cc
+++ b/dev/etherlink.cc
@@ -105,7 +105,7 @@ EtherLink::unserialize(Checkpoint *cp, const string &section)
}
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");
@@ -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 &section)
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;
@@ -217,7 +215,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);
@@ -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 &section)
{
Event::unserialize(cp, section);
packet = new PacketData;
- packet->unserialize(cp, csprintf("%s.packet", section));
+ packet->unserialize("packet", cp, section);
}
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/etherpkt.cc b/dev/etherpkt.cc
index 273b8ee64..bf60bc150 100644
--- a/dev/etherpkt.cc
+++ b/dev/etherpkt.cc
@@ -28,22 +28,23 @@
#include <iostream>
+#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 &section)
+PacketData::unserialize(const string &base, Checkpoint *cp,
+ const string &section)
{
- 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<uint8_t> 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 &section);
+ void serialize(const std::string &base, std::ostream &os);
+ void unserialize(const std::string &base, Checkpoint *cp,
+ const std::string &section);
};
typedef RefCountingPtr<PacketData> PacketPtr;
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/ide_ctrl.cc b/dev/ide_ctrl.cc
index d08e61fbf..109908ead 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -34,16 +34,15 @@
#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/tsunami_cchip.hh"
+#include "dev/ide_disk.hh"
+#include "dev/pciconfigall.hh"
+#include "dev/pcireg.h"
+#include "dev/platform.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"
@@ -55,13 +54,8 @@ using namespace std;
// Initialization and destruction
////
-IdeController::IdeController(const string &name, IntrControl *ic,
- const vector<IdeDisk *> &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<Bus>(name + ".dma", host_bus,
- host_bus, 1);
- pioLatency = pio_latency * host_bus->clockRatio;
+ dmaInterface = new DMAInterface<Bus>(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);
}
}
@@ -236,22 +232,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
////
@@ -377,7 +357,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 +368,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 +379,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 +390,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 +400,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;
}
@@ -684,12 +664,11 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
- SimObjectParam<IntrControl *> intr_ctrl;
SimObjectVectorParam<IdeDisk *> disks;
SimObjectParam<MemoryController *> mmu;
SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Tsunami *> tsunami;
+ SimObjectParam<Platform *> platform;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> 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..f1082d094 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,37 +147,23 @@ 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<IdeDisk *> &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<IdeDisk *> 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);
virtual void ReadConfig(int offset, int size, uint8_t *data);
- void intrPost();
- void intrClear();
-
void setDmaComplete(IdeDisk *disk);
/**
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 4d0b93ab9..401599126 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"
@@ -51,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[] =
@@ -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<Bus>(name + ".dma",
- header_bus, payload_bus, 1);
+ if (p->payload_bus)
+ dmaInterface = new DMAInterface<Bus>(name() + ".dma",
+ p->header_bus,
+ p->payload_bus, 1);
else
- dmaInterface = new DMAInterface<Bus>(name + ".dma",
- header_bus, header_bus, 1);
- } else if (payload_bus) {
- pioInterface = newPioInterface(name, hier, payload_bus, this,
+ dmaInterface = new DMAInterface<Bus>(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<Bus>(name + ".dma", payload_bus,
- payload_bus, 1);
+ dmaInterface = new DMAInterface<Bus>(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()
@@ -339,7 +336,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 +344,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;
}
@@ -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
@@ -1063,7 +1060,6 @@ NSGigE::txReset()
DPRINTF(Ethernet, "transmit reset\n");
CTDD = false;
- txFifoAvail = maxTxFifoSize;
txEnable = false;;
txFragPtr = 0;
assert(txDescCnt == 0);
@@ -1079,7 +1075,6 @@ NSGigE::rxReset()
CRDD = false;
assert(rxPktBytes == 0);
- rxFifoCnt = 0;
rxEnable = false;
rxFragPtr = 0;
assert(rxDescCnt == 0);
@@ -1349,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();
}
@@ -1539,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)) {
@@ -1559,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
@@ -1832,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
@@ -1878,7 +1868,7 @@ NSGigE::txKick()
}
} else {
DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
- if (txFifoAvail) {
+ if (!txFifo.full()) {
txState = txFragRead;
/*
@@ -1887,7 +1877,7 @@ NSGigE::txKick()
* is not enough room in the fifo, just whatever room
* is left in the fifo
*/
- txXferLen = min<uint32_t>(txDescCnt, txFifoAvail);
+ txXferLen = min<uint32_t>(txDescCnt, txFifo.avail());
txDmaAddr = txFragPtr & 0x3fffffff;
txDmaData = txPacketBufPtr;
@@ -1913,7 +1903,6 @@ NSGigE::txKick()
txPacketBufPtr += txXferLen;
txFragPtr += txXferLen;
txDescCnt -= txXferLen;
- txFifoAvail -= txXferLen;
txState = txFifoBlock;
break;
@@ -1982,7 +1971,7 @@ NSGigE::transferDone()
}
bool
-NSGigE::rxFilter(PacketPtr &packet)
+NSGigE::rxFilter(const PacketPtr &packet)
{
EthPtr eth = packet;
bool drop = true;
@@ -2022,13 +2011,13 @@ NSGigE::rxFilter(PacketPtr &packet)
}
bool
-NSGigE::recvPacket(PacketPtr &packet)
+NSGigE::recvPacket(PacketPtr packet)
{
rxBytes += packet->length;
rxPackets++;
DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
- maxRxFifoSize - rxFifoCnt);
+ rxFifo.avail());
if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n");
@@ -2043,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();
@@ -2122,23 +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) {
- nameOut(os, csprintf("%s.txFifo%d", name(), i++));
- (*p)->serialize(os);
- }
-
- int rxNumPkts = rxFifo.size();
- SERIALIZE_SCALAR(rxNumPkts);
- i = 0;
- end = rxFifo.end();
- for (pktiter_t p = rxFifo.begin(); p != end; ++p) {
- nameOut(os, csprintf("%s.rxFifo%d", name(), i++));
- (*p)->serialize(os);
- }
+ rxFifo.serialize("rxFifo", os);
+ txFifo.serialize("txFifo", os);
/*
* Serialize the various helper variables
@@ -2146,8 +2119,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);
}
@@ -2155,8 +2127,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);
}
@@ -2183,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;
@@ -2197,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);
@@ -2279,22 +2248,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
/*
* unserialize the data fifos
*/
- int txNumPkts;
- UNSERIALIZE_SCALAR(txNumPkts);
- int i;
- for (i = 0; i < txNumPkts; ++i) {
- PacketPtr p = new PacketData;
- p->unserialize(cp, csprintf("%s.rxFifo%d", section, i));
- txFifo.push_back(p);
- }
-
- int rxNumPkts;
- UNSERIALIZE_SCALAR(rxNumPkts);
- for (i = 0; i < rxNumPkts; ++i) {
- PacketPtr p = new PacketData;
- p->unserialize(cp, csprintf("%s.rxFifo%d", section, i));
- rxFifo.push_back(p);
- }
+ rxFifo.unserialize("rxFifo", cp, section);
+ txFifo.unserialize("txFifo", cp, section);
/*
* unserialize the various helper variables
@@ -2303,7 +2258,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
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;
@@ -2315,7 +2270,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
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;
@@ -2345,7 +2300,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
this->txState = (TxState) txState;
UNSERIALIZE_SCALAR(txEnable);
UNSERIALIZE_SCALAR(CTDD);
- UNSERIALIZE_SCALAR(txFifoAvail);
UNSERIALIZE_SCALAR(txFragPtr);
UNSERIALIZE_SCALAR(txDescCnt);
int txDmaState;
@@ -2361,7 +2315,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(rxEnable);
UNSERIALIZE_SCALAR(CRDD);
UNSERIALIZE_SCALAR(rxPktBytes);
- UNSERIALIZE_SCALAR(rxFifoCnt);
UNSERIALIZE_SCALAR(rxDescCnt);
int rxDmaState;
UNSERIALIZE_SCALAR(rxDmaState);
@@ -2450,7 +2403,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
Param<Tick> tx_delay;
Param<Tick> rx_delay;
- SimObjectParam<IntrControl *> intr_ctrl;
Param<Tick> intr_delay;
SimObjectParam<MemoryController *> mmu;
SimObjectParam<PhysicalMemory *> physmem;
@@ -2468,7 +2420,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
Param<Tick> dma_write_factor;
SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Tsunami *> tsunami;
+ SimObjectParam<Platform *> platform;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
@@ -2481,7 +2433,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 +2451,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 +2463,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..90711d63f 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -41,7 +41,7 @@
#include "dev/io_device.hh"
#include "dev/ns_gige_reg.h"
#include "dev/pcidev.hh"
-#include "dev/tsunami.hh"
+#include "dev/pktfifo.hh"
#include "mem/bus/bus.hh"
#include "sim/eventq.hh"
@@ -139,10 +139,6 @@ class NSGigE : public PciDev
};
private:
- /** pointer to the chipset */
- Tsunami *tsunami;
-
- private:
Addr addr;
static const Addr size = sizeof(dp_regs);
@@ -163,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;
@@ -188,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 */
@@ -206,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 */
@@ -300,7 +290,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;
@@ -330,16 +320,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);
@@ -350,7 +355,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; }
@@ -397,7 +402,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(); }
};
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/pcidev.cc b/dev/pcidev.cc
index f0ceb40f2..d156b6a02 100644
--- a/dev/pcidev.cc
+++ b/dev/pcidev.cc
@@ -50,36 +50,38 @@
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
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));
*(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 +90,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 +98,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;
@@ -108,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 {
@@ -119,7 +124,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,9 +183,12 @@ 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) |
+ *(uint32_t *)&config.data[offset] =
+ htoa((word_value & ~0x3) |
(htoa(config.data[offset]) & 0x3));
if (word_value & ~0x1) {
@@ -201,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) {
@@ -265,7 +275,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
// 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 &section);
};
-#endif // __PCI_DEV_HH__
+#endif // __DEV_PCIDEV_HH__
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<PacketPtr>::iterator p = fifo.begin();
+ std::list<PacketPtr>::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 &section)
+{
+ 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 <iosfwd>
+#include <list>
+#include <string>
+
+#include "dev/etherpkt.hh"
+#include "sim/serialize.hh"
+
+class Checkpoint;
+class PacketFifo
+{
+ protected:
+ std::list<PacketPtr> 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 &section);
+};
+
+#endif // __DEV_PKTFIFO_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/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;
diff --git a/dev/sinic.cc b/dev/sinic.cc
new file mode 100644
index 000000000..80364ef20
--- /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 <cstdio>
+#include <deque>
+#include <string>
+
+#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/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<Bus>(p->name + ".dma",
+ p->header_bus, p->payload_bus,
+ 1);
+ else
+ dmaInterface = new DMAInterface<Bus>(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<Bus>(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 &reg32 = *(uint32_t *)data;
+ uint64_t &reg64 = *(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(&regs, 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<int>(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 &section)
+{
+ // 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 &section)
+{
+ // 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<EtherInt *> peer;
+ SimObjectParam<Device *> 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<Tick> tx_delay;
+ Param<Tick> rx_delay;
+ Param<Tick> intr_delay;
+ SimObjectParam<MemoryController *> mmu;
+ SimObjectParam<PhysicalMemory *> physmem;
+ Param<bool> rx_filter;
+ Param<string> hardware_address;
+ SimObjectParam<Bus*> header_bus;
+ SimObjectParam<Bus*> payload_bus;
+ SimObjectParam<HierParams *> hier;
+ Param<Tick> pio_latency;
+ SimObjectParam<PciConfigAll *> configspace;
+ SimObjectParam<PciConfigData *> configdata;
+ SimObjectParam<Platform *> platform;
+ Param<uint32_t> pci_bus;
+ Param<uint32_t> pci_dev;
+ Param<uint32_t> pci_func;
+ Param<uint32_t> rx_max_copy;
+ Param<uint32_t> tx_max_copy;
+ Param<uint32_t> rx_fifo_size;
+ Param<uint32_t> tx_fifo_size;
+ Param<uint32_t> rx_fifo_threshold;
+ Param<uint32_t> tx_fifo_threshold;
+ Param<Tick> dma_read_delay;
+ Param<Tick> dma_read_factor;
+ Param<Tick> dma_write_delay;
+ Param<Tick> 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<Base, &Base::cpuInterrupt> 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 &section);
+
+/**
+ * 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<Device, &Device::rxKick> RxKickEvent;
+ friend class RxKickEvent;
+
+ void txKick();
+ Tick txKickTick;
+ typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
+ friend class TxKickEvent;
+
+ /**
+ * Retransmit event
+ */
+ void transmit();
+ void txEventTransmit()
+ {
+ transmit();
+ if (txState == txFifoBlock)
+ txKick();
+ }
+ typedef EventWrapper<Device, &Device::txEventTransmit> 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<Device, &Device::rxDmaDone>;
+ EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
+
+ void txDmaCopy();
+ void txDmaDone();
+ friend class EventWrapper<Device, &Device::txDmaDone>;
+ EventWrapper<Device, &Device::rxDmaDone> 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 &section);
+
+/**
+ * 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__
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.
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;