Merge zizzer:/z/m5/Bitkeeper/m5

into zazzer.eecs.umich.edu:/z/rdreslin/m5bk/clean

--HG--
extra : convert_revision : 170f5fd8891b02ad3cc04112c6f304ede3254dae
This commit is contained in:
Ron Dreslinski 2004-11-14 16:19:11 -05:00
commit f7d1166e04
44 changed files with 2626 additions and 516 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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)
namespace EV5 {
#ifdef ALPHA_TLASER
#define DTB_ASN_ASN(X) (((X) >> 57) & 0x7f)
#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff)
const uint64_t AsnMask = ULL(0x7f);
#else
#define DTB_ASN_ASN(X) (((X) >> 57) & 0xff)
#define DTB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff)
const uint64_t AsnMask = ULL(0xff);
#endif
#define DTB_PTE_XRE(X) (((X) >> 8) & 0xf)
#define DTB_PTE_XWE(X) (((X) >> 12) & 0xf)
#define DTB_PTE_FONR(X) (((X) >> 1) & 0x1)
#define DTB_PTE_FONW(X) (((X) >> 2) & 0x1)
#define DTB_PTE_GH(X) (((X) >> 5) & 0x3)
#define DTB_PTE_ASMA(X) (((X) >> 4) & 0x1)
#define ICM_CM(X) (((X) >> 3) & 0x3)
const int VAddrImplBits = 43;
const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1;
const Addr VAddrUnImplMask = ~VAddrImplMask;
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; }
inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; }
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; }
#ifdef ALPHA_TLASER
#define ITB_ASN_ASN(X) (((X) >> 4) & 0x7f)
#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07ffffff)
inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFF00000); }
const int PAddrImplBits = 40;
#else
#define ITB_ASN_ASN(X) (((X) >> 4) & 0xff)
#define ITB_PTE_PPN(X) (((X) >> 32) & 0x07fffffff)
inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFFF00000); }
const int PAddrImplBits = 44; // for Tsunami
#endif
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>
#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)
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; }
#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)
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; }
#define PA_UNCACHED_BIT_39 ULL(0x8000000000)
#define PA_UNCACHED_BIT_40 ULL(0x10000000000)
#define PA_UNCACHED_BIT_43 ULL(0x80000000000)
#define PA_UNCACHED_MASK ULL(0x807ffffffff) // Clear PA<42:35>
#ifdef ALPHA_TLASER
#define PA_IPR_SPACE(X) ((X) >= ULL(0xFFFFF00000))
#define PA_IMPL_MASK ULL(0xffffffffff)
#else
#define PA_IPR_SPACE(X) ((X) >= ULL(0xFFFFFF00000))
#define PA_IMPL_MASK ULL(0xfffffffffff) // for Tsunami
#endif
inline uint64_t MCSR_SP(uint64_t reg) { return reg >> 1 & 0x3; }
#define PA_PFN2PA(X) ((X) << 13)
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; }
#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
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; }
#define OPCODE(X) (X >> 26) & 0x3f
#define RA(X) (X >> 21) & 0x1f
const Addr PalBase = 0x4000;
const Addr PalMax = 0x10000;
////////////////////////////////////////////////////////////////////////
//
//
//
/* namespace EV5 */ }
// 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__
#endif // __ARCH_ALPHA_EV5_HH__

View file

@ -38,14 +38,12 @@ output exec {{
#include <fenv.h>
#endif
#ifdef FULL_SYSTEM
#include "arch/alpha/pseudo_inst.hh"
#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
}};
////////////////////////////////////////////////////////////////////
@ -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;

View file

@ -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__

View file

@ -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)) {

View file

@ -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];

View file

@ -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 = {

View file

@ -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

View file

@ -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..."

View file

@ -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

View file

@ -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) {

View file

@ -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__

View file

@ -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);
}

View file

@ -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(); }
};

View file

@ -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);
}

View file

@ -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;

View file

@ -169,7 +169,7 @@ EtherTap::detach()
}
bool
EtherTap::recvPacket(PacketPtr &packet)
EtherTap::recvPacket(PacketPtr packet)
{
if (dump)
dump->dump(packet);

View file

@ -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);

View file

@ -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);
}
}
@ -235,22 +231,6 @@ IdeController::setDmaComplete(IdeDisk *disk)
}
}
////
// Interrupt handling
////
void
IdeController::intrPost()
{
tsunami->postPciInt(configData->config.hdr.pci0.interruptLine);
}
void
IdeController::intrClear()
{
tsunami->clearPciInt(configData->config.hdr.pci0.interruptLine);
}
////
// Bus timing and bus access functions
////
@ -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)

View file

@ -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);
/**

View file

@ -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");
}

View file

@ -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)

View file

@ -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"
@ -138,10 +138,6 @@ class NSGigE : public PciDev
dmaWriteWaiting
};
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(); }
};

View file

@ -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;

View file

@ -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]));
}
}

View file

@ -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;
/** The bus number we are on */
uint32_t busNum;
/**
* A pointer to the configspace all object that calls us when
* a read comes to this particular device/function.
*/
PciConfigAll *configSpace;
/** The device number we have */
uint32_t deviceNum;
/**
* A pointer to the object that contains the first 64 bytes of
* config space
*/
PciConfigData *configData;
/** The function number */
uint32_t functionNum;
/** The bus number we are on */
uint32_t busNum;
/** The current config space. Unlike the PciConfigData this is updated
* during simulation while continues to refelect what was in the config file.
/** The device number we have */
uint32_t deviceNum;
/** 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__

68
dev/pktfifo.cc Normal file
View file

@ -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);
}
}

95
dev/pktfifo.hh Normal file
View file

@ -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__

View file

@ -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)

View file

@ -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_

View file

@ -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;

1435
dev/sinic.cc Normal file

File diff suppressed because it is too large Load diff

340
dev/sinic.hh Normal file
View file

@ -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__

187
dev/sinicreg.hh Normal file
View file

@ -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__

View file

@ -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

View file

@ -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.

View file

@ -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();

View file

@ -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):

View file

@ -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) {

View file

@ -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);

View file

@ -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;