diff options
60 files changed, 964 insertions, 597 deletions
diff --git a/SConscript b/SConscript index f2aee3bed..ce90d9cb2 100644 --- a/SConscript +++ b/SConscript @@ -369,6 +369,34 @@ syscall_emulation_obj_desc_files = Split(''' sim/Process.od ''') +targetarch_files = Split(''' + alpha_common_syscall_emul.hh + alpha_linux_process.hh + alpha_memory.hh + alpha_tru64_process.hh + aout_machdep.h + arguments.hh + byte_swap.hh + ecoff_machdep.h + elf_machdep.h + ev5.hh + faults.hh + isa_fullsys_traits.hh + isa_traits.hh + machine_exo.h + osfpal.hh + pmap.h + pseudo_inst.hh + syscalls.hh + vptr.hh + vtophys.hh + ''') + +for f in targetarch_files: + env.Command('targetarch/' + f, 'arch/alpha/' + f, + '''echo '#include "arch/alpha/%s"' > $TARGET''' % f) + + # Set up complete list of sources based on configuration. sources = base_sources obj_desc_files = base_obj_desc_files @@ -417,22 +445,6 @@ env.Command(Split('''arch/alpha/decoder.cc '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha') -# 'targetarch' is a symlink to arch/$TARGET_ISA. -def link_targetarch(target, source, env): - link_target = str(target[0]) - link_source = env.subst('$SRCDIR/arch/$TARGET_ISA') - if not os.path.isdir(link_target): - print "symlinking", link_source, "to", link_target - try: - os.symlink(link_source, link_target) - except OSError, desc: - print "Error creating symlink %s: %s" % (link_target, desc) - sys.exit(-1) - -# Tell SCons to use the link_targetarch function to make 'targetarch' -env.Command('targetarch', None, link_targetarch) - - # libelf build is described in its own SConscript file. # SConscript-local is the per-config build, which just copies some # header files into a place where they can be found. @@ -446,11 +458,9 @@ SConscript('sim/pyconfig/SConscript', exports = ['env', 'obj_desc_files'], # environment, and returns a list of all the corresponding SCons # Object nodes (including an extra one for date.cc). We explicitly # add the Object nodes so we can set up special dependencies for -# targetarch and date.cc. +# date.cc. def make_objs(sources, env): objs = [env.Object(s) for s in sources] - # make all objects depend on the targetarch link so it gets made first. - env.Depends(objs, 'targetarch') # make date.cc depend on all other objects so it always gets # recompiled whenever anything else does date_obj = env.Object('base/date.cc') diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 4a350dbfc..b9187a92e 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -30,13 +30,13 @@ #include <string> #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" #include "cpu/exec_context.hh" #include "sim/builder.hh" -#include "targetarch/alpha_memory.hh" -#include "targetarch/ev5.hh" using namespace std; diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc index 2dca3f51e..905d6b9ae 100644 --- a/arch/alpha/arguments.cc +++ b/arch/alpha/arguments.cc @@ -26,10 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/alpha/arguments.hh" +#include "arch/alpha/vtophys.hh" #include "cpu/exec_context.hh" #include "mem/functional_mem/physical_memory.hh" -#include "targetarch/arguments.hh" -#include "targetarch/vtophys.hh" AlphaArguments::Data::~Data() { diff --git a/arch/alpha/arguments.hh b/arch/alpha/arguments.hh index 78e66b3fd..b4dc0eea8 100644 --- a/arch/alpha/arguments.hh +++ b/arch/alpha/arguments.hh @@ -31,9 +31,9 @@ #include <assert.h> +#include "arch/alpha/vtophys.hh" #include "base/refcnt.hh" #include "sim/host.hh" -#include "targetarch/vtophys.hh" class ExecContext; diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index f49eadeb0..7b1ff4a2f 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -7,18 +7,6 @@ #error This code is only valid for EV5 systems #endif -#include "targetarch/isa_traits.hh" - -//////////////////////////////////////////////////////////////////////// -// -// -// - -//////////////////////////////////////////////////////////////////////// -// -// -// - #define MODE2MASK(X) (1 << (X)) // Alpha IPR register accessors diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index a800f9886..c98bb91a5 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "targetarch/faults.hh" +#include "arch/alpha/faults.hh" namespace { const char * diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 6559368e4..b22b2fa29 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -29,9 +29,9 @@ #ifndef __ISA_TRAITS_HH__ #define __ISA_TRAITS_HH__ -#include "sim/host.hh" -#include "targetarch/faults.hh" +#include "arch/alpha/faults.hh" #include "base/misc.hh" +#include "sim/host.hh" class FastCPU; class FullCPU; @@ -121,11 +121,16 @@ class AlphaISA Addr lock_addr; // lock address for LL/SC } MiscRegFile; +static const Addr PageShift = 13; +static const Addr PageBytes = ULL(1) << PageShift; +static const Addr PageMask = ~(PageBytes - 1); +static const Addr PageOffset = PageBytes - 1; + #ifdef FULL_SYSTEM typedef uint64_t InternalProcReg; -#include "targetarch/isa_fullsys_traits.hh" +#include "arch/alpha/isa_fullsys_traits.hh" #else enum { @@ -278,7 +283,7 @@ const int NumInterruptLevels = TheISA::NumInterruptLevels; // more stuff that should be imported here, but I'm too tired to do it // right now... -#include "targetarch/ev5.hh" +#include "arch/alpha/ev5.hh" #endif #endif // __ALPHA_ISA_H__ diff --git a/arch/alpha/osfpal.cc b/arch/alpha/osfpal.cc index 2717079ab..3cdc3864a 100644 --- a/arch/alpha/osfpal.cc +++ b/arch/alpha/osfpal.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "targetarch/osfpal.hh" +#include "arch/alpha/osfpal.hh" namespace { const char *strings[PAL::NumCodes] = { diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 5468d4b07..a8af8f238 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -28,61 +28,47 @@ #include <string> -#include "targetarch/pmap.h" - +#include "arch/alpha/vtophys.hh" +#include "base/trace.hh" #include "cpu/exec_context.hh" #include "mem/functional_mem/physical_memory.hh" -#include "base/trace.hh" -#include "targetarch/vtophys.hh" using namespace std; -inline Addr -level3_index(Addr vaddr) -{ return (vaddr >> ALPHA_PGSHIFT) & PTEMASK; } - -inline Addr -level2_index(Addr vaddr) -{ return (vaddr >> (ALPHA_PGSHIFT + NPTEPG_SHIFT)) & PTEMASK; } - -inline Addr -level1_index(Addr vaddr) -{ return (vaddr >> (ALPHA_PGSHIFT + 2 * NPTEPG_SHIFT)) & PTEMASK; } - -Addr -kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, Addr vaddr) +AlphaISA::PageTableEntry +kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr) { - uint64_t level1_map = ptbr; - Addr level1_pte = level1_map + (level1_index(vaddr) << PTESHIFT); - - uint64_t level1 = pmem->phys_read_qword(level1_pte); - if (!entry_valid(level1)) { + Addr level1_pte = ptbr + vaddr.level1(); + AlphaISA::PageTableEntry level1 = pmem->phys_read_qword(level1_pte); + if (!level1.valid()) { DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); return 0; } - uint64_t level2_map = PMAP_PTE_PA(level1); - Addr level2_pte = level2_map + (level2_index(vaddr) << PTESHIFT); - uint64_t level2 = pmem->phys_read_qword(level2_pte); - if (!entry_valid(level2)) { + Addr level2_pte = level1.paddr() + vaddr.level2(); + AlphaISA::PageTableEntry level2 = pmem->phys_read_qword(level2_pte); + if (!level2.valid()) { DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); return 0; } - uint64_t level3_map = PMAP_PTE_PA(level2); - Addr level3_pte = level3_map + (level3_index(vaddr) << PTESHIFT); - - return level3_pte; + Addr level3_pte = level2.paddr() + vaddr.level3(); + AlphaISA::PageTableEntry level3 = pmem->phys_read_qword(level3_pte); + if (!level3.valid()) { + DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); + return 0; + } + return level3; } Addr vtophys(PhysicalMemory *xc, Addr vaddr) { Addr paddr = 0; - if (vaddr < ALPHA_K0SEG_BASE) + if (AlphaISA::IsUSeg(vaddr)) DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); - else if (vaddr < ALPHA_K1SEG_BASE) - paddr = ALPHA_K0SEG_TO_PHYS(vaddr); + else if (AlphaISA::IsK0Seg(vaddr)) + paddr = AlphaISA::K0Seg2Phys(vaddr); else panic("vtophys: ptbr is not set on virtual lookup"); @@ -92,8 +78,9 @@ vtophys(PhysicalMemory *xc, Addr vaddr) } Addr -vtophys(ExecContext *xc, Addr vaddr) +vtophys(ExecContext *xc, Addr addr) { + AlphaISA::VAddr vaddr = addr; Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20]; Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code @@ -101,15 +88,15 @@ vtophys(ExecContext *xc, Addr vaddr) if (PC_PAL(vaddr) && (vaddr < PAL_MAX)) { paddr = vaddr & ~ULL(1); } else { - if (vaddr >= ALPHA_K0SEG_BASE && vaddr <= ALPHA_K0SEG_END) { - paddr = ALPHA_K0SEG_TO_PHYS(vaddr); + if (AlphaISA::IsK0Seg(vaddr)) { + paddr = AlphaISA::K0Seg2Phys(vaddr); } else if (!ptbr) { paddr = vaddr; } else { - Addr pte = kernel_pte_lookup(xc->physmem, ptbr, vaddr); - uint64_t entry = xc->physmem->phys_read_qword(pte); - if (pte && entry_valid(entry)) - paddr = PMAP_PTE_PA(entry) | (vaddr & PGOFSET); + AlphaISA::PageTableEntry pte = + kernel_pte_lookup(xc->physmem, ptbr, vaddr); + if (pte.valid()) + paddr = pte.paddr() | vaddr.offset(); } } @@ -141,7 +128,8 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) int len; paddr = vtophys(xc, src); - len = min((int)(ALPHA_PGBYTES - (paddr & PGOFSET)), (int)cplen); + len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), + (int)cplen); dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); assert(dmaaddr); @@ -153,15 +141,15 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) dst += len; src += len; - while (cplen > ALPHA_PGBYTES) { + while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, src); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, ALPHA_PGBYTES); + dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); assert(dmaaddr); - memcpy(dst, dmaaddr, ALPHA_PGBYTES); - cplen -= ALPHA_PGBYTES; - dst += ALPHA_PGBYTES; - src += ALPHA_PGBYTES; + memcpy(dst, dmaaddr, AlphaISA::PageBytes); + cplen -= AlphaISA::PageBytes; + dst += AlphaISA::PageBytes; + src += AlphaISA::PageBytes; } if (cplen > 0) { @@ -182,7 +170,8 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) int len; paddr = vtophys(xc, dest); - len = min((int)(ALPHA_PGBYTES - (paddr & PGOFSET)), (int)cplen); + len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), + (int)cplen); dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); assert(dmaaddr); @@ -194,15 +183,15 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) src += len; dest += len; - while (cplen > ALPHA_PGBYTES) { + while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, ALPHA_PGBYTES); + dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); assert(dmaaddr); - memcpy(dmaaddr, src, ALPHA_PGBYTES); - cplen -= ALPHA_PGBYTES; - src += ALPHA_PGBYTES; - dest += ALPHA_PGBYTES; + memcpy(dmaaddr, src, AlphaISA::PageBytes); + cplen -= AlphaISA::PageBytes; + src += AlphaISA::PageBytes; + dest += AlphaISA::PageBytes; } if (cplen > 0) { @@ -222,7 +211,8 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) int len; paddr = vtophys(xc, vaddr); - len = min((int)(ALPHA_PGBYTES - (paddr & PGOFSET)), (int)maxlen); + len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), + (int)maxlen); dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); assert(dmaaddr); @@ -239,21 +229,21 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) dst += len; vaddr += len; - while (maxlen > ALPHA_PGBYTES) { + while (maxlen > AlphaISA::PageBytes) { paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, ALPHA_PGBYTES); + dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); assert(dmaaddr); - char *term = (char *)memchr(dmaaddr, 0, ALPHA_PGBYTES); - len = term ? (term - dmaaddr + 1) : ALPHA_PGBYTES; + char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes); + len = term ? (term - dmaaddr + 1) : AlphaISA::PageBytes; memcpy(dst, dmaaddr, len); if (term) return; - maxlen -= ALPHA_PGBYTES; - dst += ALPHA_PGBYTES; - vaddr += ALPHA_PGBYTES; + maxlen -= AlphaISA::PageBytes; + dst += AlphaISA::PageBytes; + vaddr += AlphaISA::PageBytes; } if (maxlen > 0) { diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index 7c22e3371..8e47a0031 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -26,19 +26,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __VTOPHYS_H__ -#define __VTOPHYS_H__ +#ifndef __ARCH_ALPHA_VTOPHYS_H__ +#define __ARCH_ALPHA_VTOPHYS_H__ -#include "targetarch/isa_traits.hh" -#include "targetarch/pmap.h" - -inline bool entry_valid(uint64_t entry) -{ return (entry & ALPHA_PTE_VALID) != 0; } +#include "arch/alpha/isa_traits.hh" class ExecContext; class PhysicalMemory; -Addr kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, Addr vaddr); +AlphaISA::PageTableEntry +kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr); + Addr vtophys(PhysicalMemory *xc, Addr vaddr); Addr vtophys(ExecContext *xc, Addr vaddr); uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len); @@ -48,5 +46,5 @@ void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); -#endif // __VTOPHYS_H__ +#endif // __ARCH_ALPHA_VTOPHYS_H__ diff --git a/base/bitfield.hh b/base/bitfield.hh index ee5ea72cf..bdc3fb13e 100644 --- a/base/bitfield.hh +++ b/base/bitfield.hh @@ -26,10 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __BITFIELD_HH -#define __BITFIELD_HH +#ifndef __BASE_BITFIELD_HH__ +#define __BASE_BITFIELD_HH__ -#include <inttypes.h> +#include "sim/host.hh" /** * Generate a 64-bit mask of 'nbits' 1s, right justified. @@ -66,4 +66,4 @@ sext(uint64_t val) return sign_bit ? (val | ~mask(N)) : val; } -#endif +#endif // __BASE_BITFIELD_HH__ diff --git a/base/callback.hh b/base/callback.hh index eee629cf5..342ab7e0f 100644 --- a/base/callback.hh +++ b/base/callback.hh @@ -103,4 +103,17 @@ class CallbackQueue } }; +template <class T, void (T::* F)()> +class MakeCallback : public Callback +{ + private: + T *object; + + public: + MakeCallback(T *o) + : object(o) + { } + void process() { (object->*F)(); } +}; + #endif // __CALLBACK_HH__ diff --git a/base/compression/null_compression.hh b/base/compression/null_compression.hh index 195498f1b..63364a955 100644 --- a/base/compression/null_compression.hh +++ b/base/compression/null_compression.hh @@ -26,16 +26,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __NULL_COMPRESSION_HH__ -#define __NULL_COMPRESSION_HH__ +#ifndef __BASE_COMPRESSION_NULL_COMPRESSION_HH__ +#define __BASE_COMPRESSION_NULL_COMPRESSION_HH__ /** * @file * This file defines a doNothing compression algorithm. */ -#include <inttypes.h> // for uint8_t #include "base/misc.hh" // for fatal() +#include "sim/host.hh" /** @@ -73,4 +73,4 @@ class NullCompression } }; -#endif //__NULL_COMPRESSION_HH__ +#endif //__BASE_COMPRESSION_NULL_COMPRESSION_HH__ diff --git a/base/inet.cc b/base/inet.cc index 0b9e32854..eca7238ff 100644 --- a/base/inet.cc +++ b/base/inet.cc @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <cstdio> #include <sstream> #include <string> @@ -34,29 +35,174 @@ #include "base/inet.hh" using namespace std; +namespace Net { + +EthAddr::EthAddr() +{ + memset(data, 0, ETH_ADDR_LEN); +} + +EthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN]) +{ + *data = *ea; +} + +EthAddr::EthAddr(const eth_addr &ea) +{ + *data = *ea.data; +} + +EthAddr::EthAddr(const std::string &addr) +{ + parse(addr); +} + +const EthAddr & +EthAddr::operator=(const eth_addr &ea) +{ + *data = *ea.data; + return *this; +} + +const EthAddr & +EthAddr::operator=(const std::string &addr) +{ + parse(addr); + return *this; +} + +void +EthAddr::parse(const std::string &addr) +{ + // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise + // the sscanf function won't work. + int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1]; + if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1], + &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) { + memset(data, 0xff, ETH_ADDR_LEN); + return; + } + + for (int i = 0; i < ETH_ADDR_LEN; ++i) { + if (bytes[i] & ~0xff) { + memset(data, 0xff, ETH_ADDR_LEN); + return; + } + + data[i] = bytes[i]; + } +} + string -eaddr_string(const uint8_t a[6]) +EthAddr::string() const { stringstream stream; + stream << *this; + return stream.str(); +} + +bool +operator==(const EthAddr &left, const EthAddr &right) +{ + return memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN); +} + +ostream & +operator<<(ostream &stream, const EthAddr &ea) +{ + const uint8_t *a = ea.addr(); ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]); + return stream; +} - return stream.str(); +uint16_t +cksum(const IpPtr &ptr) +{ + int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0); + return ip_cksum_carry(sum); } uint16_t -IpHdr::ip_cksum() const +__tu_cksum(const IpPtr &ip) { - int sum = ip_cksum_add(this, hlen(), 0); - sum = ip_cksum_carry(sum); - return sum; + int tcplen = ip->len() - ip->hlen(); + int sum = ip_cksum_add(ip->payload(), tcplen, 0); + sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination + sum += htons(ip->ip_p + tcplen); + return ip_cksum_carry(sum); } uint16_t -IpHdr::tu_cksum() const +cksum(const TcpPtr &tcp) +{ return __tu_cksum(IpPtr(tcp.packet())); } + +uint16_t +cksum(const UdpPtr &udp) +{ return __tu_cksum(IpPtr(udp.packet())); } + +bool +IpHdr::options(vector<const IpOpt *> &vec) const { - int sum = ip_cksum_add(payload(), len() - hlen(), 0); - sum = ip_cksum_add(&ip_src, 8, sum); // source and destination - sum += htons(ip_p + len() - hlen()); - sum = ip_cksum_carry(sum); - return sum; + vec.clear(); + + const uint8_t *data = bytes() + sizeof(struct ip_hdr); + int all = hlen() - sizeof(struct ip_hdr); + while (all > 0) { + const IpOpt *opt = (const IpOpt *)data; + int len = opt->len(); + if (all < len) + return false; + + vec.push_back(opt); + all -= len; + data += len; + } + + return true; } + +bool +TcpHdr::options(vector<const TcpOpt *> &vec) const +{ + vec.clear(); + + const uint8_t *data = bytes() + sizeof(struct tcp_hdr); + int all = off() - sizeof(struct tcp_hdr); + while (all > 0) { + const TcpOpt *opt = (const TcpOpt *)data; + int len = opt->len(); + if (all < len) + return false; + + vec.push_back(opt); + all -= len; + data += len; + } + + return true; +} + +bool +TcpOpt::sack(vector<SackRange> &vec) const +{ + vec.clear(); + + const uint8_t *data = bytes() + sizeof(struct tcp_hdr); + int all = len() - offsetof(tcp_opt, opt_data.sack); + while (all > 0) { + const uint16_t *sack = (const uint16_t *)data; + int len = sizeof(uint16_t) * 2; + if (all < len) { + vec.clear(); + return false; + } + + vec.push_back(RangeIn(ntohs(sack[0]), ntohs(sack[1]))); + all -= len; + data += len; + } + + return false; +} + +/* namespace Net */ } diff --git a/base/inet.hh b/base/inet.hh index 8a49790a7..7ea4de6bb 100644 --- a/base/inet.hh +++ b/base/inet.hh @@ -29,10 +29,16 @@ #ifndef __BASE_INET_HH__ #define __BASE_INET_HH__ +#include <iosfwd> #include <string> +#include <utility> +#include <vector> -#include "dnet/os.h" +#include "base/range.hh" +#include "dev/etherpkt.hh" +#include "sim/host.hh" +#include "dnet/os.h" #include "dnet/eth.h" #include "dnet/ip.h" #include "dnet/ip6.h" @@ -41,45 +47,90 @@ #include "dnet/icmp.h" #include "dnet/tcp.h" #include "dnet/udp.h" - #include "dnet/intf.h" #include "dnet/route.h" #include "dnet/fw.h" - #include "dnet/blob.h" #include "dnet/rand.h" -#include "sim/host.hh" +namespace Net { -std::string eaddr_string(const uint8_t a[6]); +/* + * Ethernet Stuff + */ +struct EthAddr : protected eth_addr +{ + protected: + void parse(const std::string &addr); -struct EthHdr; -struct IpHdr; -struct TcpHdr; -struct UdpHdr; + public: + EthAddr(); + EthAddr(const uint8_t ea[ETH_ADDR_LEN]); + EthAddr(const eth_addr &ea); + EthAddr(const std::string &addr); + const EthAddr &operator=(const eth_addr &ea); + const EthAddr &operator=(const std::string &addr); -struct EthHdr : protected eth_hdr -{ - uint16_t type() const { return ntohs(eth_type); } + int size() const { return sizeof(eth_addr); } - const IpHdr *ip() const - { return type() == ETH_TYPE_IP ? (const IpHdr *)payload() : 0; } + const uint8_t *bytes() const { return &data[0]; } + uint8_t *bytes() { return &data[0]; } - IpHdr *ip() - { return type() == ETH_TYPE_IP ? (IpHdr *)payload() : 0; } + const uint8_t *addr() const { return &data[0]; } + bool unicast() const { return data[0] == 0x00; } + bool multicast() const { return data[0] == 0x01; } + bool broadcast() const { return data[0] == 0xff; } + std::string string() const; +}; + +std::ostream &operator<<(std::ostream &stream, const EthAddr &ea); +bool operator==(const EthAddr &left, const EthAddr &right); + +struct EthHdr : public eth_hdr +{ + uint16_t type() const { return ntohs(eth_type); } + const EthAddr &src() const { return *(EthAddr *)ð_src; } + const EthAddr &dst() const { return *(EthAddr *)ð_dst; } - bool unicast() { return eth_dst.data[0] == 0x00; } - bool multicast() { return eth_dst.data[0] == 0x01; } - bool broadcast() { return eth_dst.data[0] == 0xff; } + int size() const { return sizeof(eth_hdr); } - int size() const { return sizeof(EthHdr); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } uint8_t *bytes() { return (uint8_t *)this; } uint8_t *payload() { return bytes() + size(); } }; -struct IpHdr : protected ip_hdr +class EthPtr +{ + protected: + friend class IpPtr; + PacketPtr p; + + public: + EthPtr() {} + EthPtr(const PacketPtr &ptr) : p(ptr) { } + + EthHdr *operator->() { return (EthHdr *)p->data; } + EthHdr &operator*() { return *(EthHdr *)p->data; } + operator EthHdr *() { return (EthHdr *)p->data; } + + const EthHdr *operator->() const { return (const EthHdr *)p->data; } + const EthHdr &operator*() const { return *(const EthHdr *)p->data; } + operator const EthHdr *() const { return (const EthHdr *)p->data; } + + const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } +}; + +/* + * IP Stuff + */ +struct IpOpt; +struct IpHdr : public ip_hdr { uint8_t version() const { return ip_v; } uint8_t hlen() const { return ip_hl * 4; } @@ -96,19 +147,7 @@ struct IpHdr : protected ip_hdr void sum(uint16_t sum) { ip_sum = sum; } - uint16_t ip_cksum() const; - uint16_t tu_cksum() const; - - const TcpHdr *tcp() const - { return proto() == IP_PROTO_TCP ? (const TcpHdr *)payload() : 0; } - const UdpHdr *udp() const - { return proto() == IP_PROTO_UDP ? (const UdpHdr *)payload() : 0; } - - TcpHdr *tcp() - { return proto() == IP_PROTO_TCP ? (TcpHdr *)payload() : 0; } - UdpHdr *udp() - { return proto() == IP_PROTO_UDP ? (UdpHdr *)payload() : 0; } - + bool options(std::vector<const IpOpt *> &vec) const; int size() const { return hlen(); } const uint8_t *bytes() const { return (const uint8_t *)this; } @@ -117,7 +156,84 @@ struct IpHdr : protected ip_hdr uint8_t *payload() { return bytes() + size(); } }; -struct TcpHdr : protected tcp_hdr +class IpPtr +{ + protected: + friend class TcpPtr; + friend class UdpPtr; + PacketPtr p; + + const IpHdr *h() const + { return (const IpHdr *)(p->data + sizeof(eth_hdr)); } + IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); } + + void set(const PacketPtr &ptr) + { + EthHdr *eth = (EthHdr *)ptr->data; + if (eth->type() == ETH_TYPE_IP) + p = ptr; + else + p = 0; + } + + public: + IpPtr() {} + IpPtr(const PacketPtr &ptr) { set(ptr); } + IpPtr(const EthPtr &ptr) { set(ptr.p); } + IpPtr(const IpPtr &ptr) : p(ptr.p) { } + + IpHdr *operator->() { return h(); } + IpHdr &operator*() { return *h(); } + operator IpHdr *() { return h(); } + + const IpHdr *operator->() const { return h(); } + const IpHdr &operator*() const { return *h(); } + operator const IpHdr *() const { return h(); } + + const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; } + const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } + const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const IpPtr &ptr); + +struct IpOpt : public ip_opt +{ + uint8_t type() const { return opt_type; } + uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); } + uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); } + uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); } + uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; } + + bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); } + bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); } + bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); } + + const uint8_t *data() const { return opt_data.data8; } + void sec(ip_opt_data_sec &sec) const; + void lsrr(ip_opt_data_rr &rr) const; + void ssrr(ip_opt_data_rr &rr) const; + void ts(ip_opt_data_ts &ts) const; + uint16_t satid() const { return ntohs(opt_data.satid); } + uint16_t mtup() const { return ntohs(opt_data.mtu); } + uint16_t mtur() const { return ntohs(opt_data.mtu); } + void tr(ip_opt_data_tr &tr) const; + const uint32_t *addext() const { return &opt_data.addext[0]; } + uint16_t rtralt() const { return ntohs(opt_data.rtralt); } + void sdb(std::vector<uint32_t> &vec) const; +}; + +/* + * TCP Stuff + */ +struct TcpOpt; +struct TcpHdr : public tcp_hdr { uint16_t sport() const { return ntohs(th_sport); } uint16_t dport() const { return ntohs(th_dport); } @@ -131,6 +247,8 @@ struct TcpHdr : protected tcp_hdr void sum(uint16_t sum) { th_sum = sum; } + bool options(std::vector<const TcpOpt *> &vec) const; + int size() const { return off(); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } @@ -138,7 +256,81 @@ struct TcpHdr : protected tcp_hdr uint8_t *payload() { return bytes() + size(); } }; -struct UdpHdr : protected udp_hdr +class TcpPtr +{ + protected: + PacketPtr p; + int off; + + const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); } + TcpHdr *h() { return (TcpHdr *)(p->data + off); } + + void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const IpPtr &ptr) + { + if (ptr->proto() == IP_PROTO_TCP) + set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); + else + set(0, 0); + } + + public: + TcpPtr() {} + TcpPtr(const IpPtr &ptr) { set(ptr); } + TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {} + + TcpHdr *operator->() { return h(); } + TcpHdr &operator*() { return *h(); } + operator TcpHdr *() { return h(); } + + const TcpHdr *operator->() const { return h(); } + const TcpHdr &operator*() const { return *h(); } + operator const TcpHdr *() const { return h(); } + + const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; } + const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const TcpPtr &ptr); + +typedef Range<uint16_t> SackRange; + +struct TcpOpt : public tcp_opt +{ + uint8_t type() const { return opt_type; } + uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; } + + bool isopt(int opt) const { return type() == opt; } + + const uint8_t *data() const { return opt_data.data8; } + + uint16_t mss() const { return ntohs(opt_data.mss); } + uint8_t wscale() const { return opt_data.wscale; } + bool sack(std::vector<SackRange> &vec) const; + uint32_t echo() const { return ntohl(opt_data.echo); } + uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); } + uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); } + uint32_t cc() const { return ntohl(opt_data.cc); } + uint8_t cksum() const{ return opt_data.cksum; } + const uint8_t *md5() const { return opt_data.md5; } + + int size() const { return len(); } + const uint8_t *bytes() const { return (const uint8_t *)this; } + const uint8_t *payload() const { return bytes() + size(); } + uint8_t *bytes() { return (uint8_t *)this; } + uint8_t *payload() { return bytes() + size(); } +}; + +/* + * UDP Stuff + */ +struct UdpHdr : public udp_hdr { uint16_t sport() const { return ntohs(uh_sport); } uint16_t dport() const { return ntohs(uh_dport); } @@ -147,11 +339,56 @@ struct UdpHdr : protected udp_hdr void sum(uint16_t sum) { uh_sum = htons(sum); } - int size() const { return sizeof(UdpHdr); } + int size() const { return sizeof(udp_hdr); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } uint8_t *bytes() { return (uint8_t *)this; } uint8_t *payload() { return bytes() + size(); } }; +class UdpPtr +{ + protected: + PacketPtr p; + int off; + + const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); } + UdpHdr *h() { return (UdpHdr *)(p->data + off); } + + void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const IpPtr &ptr) + { + if (ptr->proto() == IP_PROTO_UDP) + set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); + else + set(0, 0); + } + + public: + UdpPtr() {} + UdpPtr(const IpPtr &ptr) { set(ptr); } + UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {} + + UdpHdr *operator->() { return h(); } + UdpHdr &operator*() { return *h(); } + operator UdpHdr *() { return h(); } + + const UdpHdr *operator->() const { return h(); } + const UdpHdr &operator*() const { return *h(); } + operator const UdpHdr *() const { return h(); } + + const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } + const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const UdpPtr &ptr); + +/* namespace Net */ } + #endif // __BASE_INET_HH__ diff --git a/base/intmath.hh b/base/intmath.hh index 821514668..5ffe27103 100644 --- a/base/intmath.hh +++ b/base/intmath.hh @@ -120,7 +120,7 @@ FloorLog2(int64_t x) } #if defined(__APPLE__) -int +inline int FloorLog2(size_t x) { assert(x > 0); diff --git a/base/range.cc b/base/range.cc index 4453ecc9f..1087c02c8 100644 --- a/base/range.cc +++ b/base/range.cc @@ -34,12 +34,12 @@ using namespace std; template <class T> bool -__x_parse_range(const std::string &str, T &start, T &end) +__x_parse_range(const std::string &str, T &first, T &last) { std::vector<std::string> values; tokenize(values, str, ':'); - T thestart, theend; + T thefirst, thelast; if (values.size() != 2) return false; @@ -47,29 +47,29 @@ __x_parse_range(const std::string &str, T &start, T &end) std::string s = values[0]; std::string e = values[1]; - if (!to_number(s, thestart)) + if (!to_number(s, thefirst)) return false; bool increment = (e[0] == '+'); if (increment) e = e.substr(1); - if (!to_number(e, theend)) + if (!to_number(e, thelast)) return false; if (increment) - theend += thestart; + thelast += thefirst - 1; - start = thestart; - end = theend; + first = thefirst; + last = thelast; return true; } #define RANGE_PARSE(type) \ template<> bool \ -__parse_range(const std::string &s, type &start, type &end) \ -{ return __x_parse_range(s, start, end); } +__parse_range(const std::string &s, type &first, type &last) \ +{ return __x_parse_range(s, first, last); } RANGE_PARSE(unsigned long long); RANGE_PARSE(signed long long); diff --git a/base/range.hh b/base/range.hh index 2197e2f86..9289792ea 100644 --- a/base/range.hh +++ b/base/range.hh @@ -26,44 +26,32 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __RANGE_HH__ -#define __RANGE_HH__ +#ifndef __BASE_RANGE_HH__ +#define __BASE_RANGE_HH__ #include <cassert> #include <string> +/** + * @param s range string + * EndExclusive Ranges are in the following format: + * <range> := {<start_val>}:{<end>} + * <start> := <end_val> | +<delta> + */ template <class T> bool __parse_range(const std::string &s, T &start, T &end); template <class T> struct Range { - private: - /** - * @param s range string - * Ranges are in the following format: - * <range> := {<start_val>}:{<end>} - * <end> := <end_val> | +<delta> - */ - void - parse(const std::string &s) - { - if (!__parse_range(s, start, end)) - invalidate(); - } - - public: T start; T end; - public: - Range() - { - invalidate(); - } + Range() { invalidate(); } - Range(T first, T second) - : start(first), end(second) + template <class U> + Range(const std::pair<U, U> &r) + : start(r.first), end(r.second) {} template <class U> @@ -71,14 +59,10 @@ struct Range : start(r.start), end(r.end) {} - template <class U> - Range(const std::pair<U, U> &r) - : start(r.first), end(r.second) - {} - Range(const std::string &s) { - parse(s); + if (!__parse_range(s, start, end)) + invalidate(); } template <class U> @@ -99,32 +83,39 @@ struct Range const Range &operator=(const std::string &s) { - parse(s); + if (!__parse_range(s, start, end)) + invalidate(); return *this; } - void invalidate() { start = 0; end = 0; } - T size() const { return end - start; } + void invalidate() { start = 1; end = 0; } + T size() const { return end - start + 1; } bool valid() const { return start < end; } }; template <class T> -inline Range<T> -make_range(T start, T end) -{ - return Range<T>(start, end); -} - -template <class T> inline std::ostream & operator<<(std::ostream &o, const Range<T> &r) { - // don't currently support output of invalid ranges - assert(r.valid()); - o << r.start << ":" << r.end; + o << '[' << r.start << "," << r.end << ']'; return o; } +template <class T> +inline Range<T> +RangeEx(T start, T end) +{ return std::make_pair(start, end - 1); } + +template <class T> +inline Range<T> +RangeIn(T start, T end) +{ return std::make_pair(start, end); } + +template <class T, class U> +inline Range<T> +RangeSize(T start, U size) +{ return std::make_pair(start, start + size - 1); } + //////////////////////////////////////////////////////////////////////// // // Range to Range Comparisons @@ -139,7 +130,6 @@ template <class T, class U> inline bool operator==(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); return range1.start == range2.start && range1.end == range2.end; } @@ -152,7 +142,6 @@ template <class T, class U> inline bool operator!=(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); return range1.start != range2.start || range1.end != range2.end; } @@ -165,8 +154,7 @@ template <class T, class U> inline bool operator<(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); - return range1.end <= range2.start; + return range1.start < range2.start; } /** @@ -179,8 +167,7 @@ template <class T, class U> inline bool operator<=(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); - return range1.start <= range2.start && range1.end <= range2.end; + return range1.start <= range2.start; } /** @@ -192,8 +179,7 @@ template <class T, class U> inline bool operator>(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); - return range1.start >= range2.end; + return range1.start > range2.start; } /** @@ -206,8 +192,7 @@ template <class T, class U> inline bool operator>=(const Range<T> &range1, const Range<U> &range2) { - assert(range1.valid() && range2.valid()); - return range1.start >= range2.start && range1.end >= range2.end; + return range1.start >= range2.start; } //////////////////////////////////////////////////////////////////////// @@ -224,7 +209,6 @@ template <class T, class U> inline bool operator==(const T &pos, const Range<U> &range) { - assert(range.valid()); return pos >= range.start && pos <= range.end; } @@ -237,8 +221,7 @@ template <class T, class U> inline bool operator!=(const T &pos, const Range<U> &range) { - assert(range.valid()); - return pos < range.start || pos >= range.end; + return pos < range.start || pos > range.end; } /** @@ -250,7 +233,6 @@ template <class T, class U> inline bool operator<(const T &pos, const Range<U> &range) { - assert(range.valid()); return pos < range.start; } @@ -263,8 +245,7 @@ template <class T, class U> inline bool operator<=(const T &pos, const Range<U> &range) { - assert(range.valid()); - return pos < range.end; + return pos <= range.end; } /** @@ -276,8 +257,7 @@ template <class T, class U> inline bool operator>(const T &pos, const Range<U> &range) { - assert(range.valid()); - return pos >= range.end; + return pos > range.end; } /** @@ -289,7 +269,6 @@ template <class T, class U> inline bool operator>=(const T &pos, const Range<U> &range) { - assert(range.valid()); return pos >= range.start; } @@ -307,8 +286,7 @@ template <class T, class U> inline bool operator==(const Range<T> &range, const U &pos) { - assert(range.valid()); - return pos >= range.start && pos < range.end; + return pos >= range.start && pos <= range.end; } /** @@ -320,8 +298,7 @@ template <class T, class U> inline bool operator!=(const Range<T> &range, const U &pos) { - assert(range.valid()); - return pos < range.start || pos >= range.end; + return pos < range.start || pos > range.end; } /** @@ -333,8 +310,7 @@ template <class T, class U> inline bool operator<(const Range<T> &range, const U &pos) { - assert(range.valid()); - return range.end <= pos; + return range.end < pos; } /** @@ -346,7 +322,6 @@ template <class T, class U> inline bool operator<=(const Range<T> &range, const U &pos) { - assert(range.valid()); return range.start <= pos; } @@ -359,7 +334,6 @@ template <class T, class U> inline bool operator>(const Range<T> &range, const U &pos) { - assert(range.valid()); return range.start > pos; } @@ -372,8 +346,7 @@ template <class T, class U> inline bool operator>=(const Range<T> &range, const U &pos) { - assert(range.valid()); - return range.end > pos; + return range.end >= pos; } -#endif // __RANGE_HH__ +#endif // __BASE_RANGE_HH__ diff --git a/base/refcnt.hh b/base/refcnt.hh index 251dc905b..00ba8fa4a 100644 --- a/base/refcnt.hh +++ b/base/refcnt.hh @@ -51,15 +51,26 @@ class RefCountingPtr protected: T *data; - void copy(T *d) { + void copy(T *d) + { data = d; if (data) data->incref(); } - void del() { + void del() + { if (data) data->decref(); } + void set(T *d) + { + if (data == d) + return; + + del(); + copy(d); + } + public: RefCountingPtr() : data(NULL) {} @@ -75,21 +86,9 @@ class RefCountingPtr const T &operator*() const { return *data; } const T *get() const { return data; } - RefCountingPtr &operator=(T *p) { - if (data != p) { - del(); - copy(p); - } - return *this; - } - - RefCountingPtr &operator=(const RefCountingPtr &r) { - if (data != r.data) { - del(); - copy(r.data); - } - return *this; - } + RefCountingPtr &operator=(T *p) { set(p); return *this; } + RefCountingPtr &operator=(const RefCountingPtr &r) + { return operator=(r.data); } bool operator!() const { return data == 0; } operator bool() const { return data != 0; } diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 41f11005d..598f03c35 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -326,14 +326,13 @@ bool RemoteGDB::acc(Addr va, size_t len) { Addr last_va; - Addr pte; - va = alpha_trunc_page(va); - last_va = alpha_round_page(va + len); + va = TheISA::TruncPage(va); + last_va = TheISA::RoundPage(va + len); do { - if (va >= ALPHA_K0SEG_BASE && va < ALPHA_K1SEG_BASE) { - if (va < (ALPHA_K0SEG_BASE + pmem->size())) { + if (TheISA::IsK0Seg(va)) { + if (va < (TheISA::K0SegBase + pmem->size())) { DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " "%#x < K0SEG + size\n", va); return true; @@ -355,12 +354,12 @@ RemoteGDB::acc(Addr va, size_t len) return true; Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; - pte = kernel_pte_lookup(pmem, ptbr, va); - if (!pte || !entry_valid(pmem->phys_read_qword(pte))) { + TheISA::PageTableEntry pte = kernel_pte_lookup(pmem, ptbr, va); + if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } - va += ALPHA_PGBYTES; + va += TheISA::PageBytes; } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); diff --git a/base/stats/types.hh b/base/stats/types.hh index fbabfb118..8e45531fb 100644 --- a/base/stats/types.hh +++ b/base/stats/types.hh @@ -30,7 +30,7 @@ #define __BASE_STATS_TYPES_HH__ #include <vector> -#include <inttypes.h> +#include "sim/host.hh" namespace Stats { diff --git a/build/SConstruct b/build/SConstruct index 6a629c064..6b71fa585 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -239,6 +239,8 @@ default_env = Environment(ENV = os.environ, # inherit user's enviroment vars FULL_SYSTEM = False, USE_MYSQL = False) +default_env.SConsignFile("sconsign") + # For some reason, the CC and CXX variables don't get passed into the # environment correctly. This is probably some sort of scons bug that # will eventually be fixed. diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 0b45d2b9d..8ea5798ea 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -345,13 +345,13 @@ SimpleCPU::copySrcTranslate(Addr src) int offset = src & (blk_size - 1); // Make sure block doesn't span page - if (no_warn && (src & (~8191)) != ((src + blk_size) & (~8191)) && + if (no_warn && + (src & TheISA::PageMask) != ((src + blk_size) & TheISA::PageMask) && (src >> 40) != 0xfffffc) { warn("Copied block source spans pages %x.", src); no_warn = false; } - memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address @@ -381,7 +381,8 @@ SimpleCPU::copy(Addr dest) int offset = dest & (blk_size - 1); // Make sure block doesn't span page - if (no_warn && (dest & (~8191)) != ((dest + blk_size) & (~8191)) && + if (no_warn && + (dest & TheISA::PageMask) != ((dest + blk_size) & TheISA::PageMask) && (dest >> 40) != 0xfffffc) { no_warn = false; warn("Copied block destination spans pages %x. ", dest); @@ -400,6 +401,15 @@ SimpleCPU::copy(Addr dest) xc->mem->read(memReq, data); memReq->paddr = dest_addr; xc->mem->write(memReq, data); + if (dcacheInterface) { + memReq->cmd = Copy; + memReq->completionEvent = NULL; + memReq->paddr = xc->copySrcPhysAddr; + memReq->dest = dest_addr; + memReq->size = 64; + memReq->time = curTick; + dcacheInterface->access(memReq); + } } return fault; } diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 451c801ee..d0000dc5b 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -249,8 +249,7 @@ class SimpleCPU : public BaseCPU Fault read(Addr addr, T &data, unsigned flags); template <class T> - Fault write(T data, Addr addr, unsigned flags, - uint64_t *res); + Fault write(T data, Addr addr, unsigned flags, uint64_t *res); void prefetch(Addr addr, unsigned flags) { diff --git a/cpu/trace/opt_cpu.cc b/cpu/trace/opt_cpu.cc index 291525c1d..df4197e26 100644 --- a/cpu/trace/opt_cpu.cc +++ b/cpu/trace/opt_cpu.cc @@ -52,7 +52,13 @@ OptCPU::OptCPU(const string &name, numBlks(cache_size/block_size), assoc(_assoc), numSets(numBlks/assoc), setMask(numSets - 1) { - int log_block_size = (int)(log((double) block_size)/log(2.0)); + int log_block_size = 0; + int tmp_block_size = block_size; + while (tmp_block_size > 1) { + ++log_block_size; + tmp_block_size = tmp_block_size >> 1; + } + assert(1<<log_block_size == block_size); MemReqPtr req; trace->getNextReq(req); refInfo.resize(numSets); @@ -124,7 +130,7 @@ OptCPU::processSet(int set) for (int start = assoc/2; start >= 0; --start) { heapify(set,start); } - verifyHeap(set,0); + //verifyHeap(set,0); for (; i < refInfo[set].size(); ++i) { RefIndex cache_index = lookupValue(refInfo[set][i].addr); @@ -134,8 +140,11 @@ OptCPU::processSet(int set) // replace from cacheHeap[0] // mark replaced block as absent setValue(refInfo[set][cacheHeap[0]].addr, -1); + setValue(refInfo[set][i].addr, 0); cacheHeap[0] = i; heapify(set, 0); + // Make sure its in the cache + assert(lookupValue(refInfo[set][i].addr) != -1); } else { // hit hits++; @@ -143,9 +152,11 @@ OptCPU::processSet(int set) refInfo[set][i].addr); assert(refInfo[set][cacheHeap[cache_index]].nextRefTime == i); assert(heapLeft(cache_index) >= assoc); + + cacheHeap[cache_index] = i; + processRankIncrease(set, cache_index); + assert(lookupValue(refInfo[set][i].addr) != -1); } - cacheHeap[cache_index] = i; - processRankIncrease(set, cache_index); } } void diff --git a/cpu/trace/trace_cpu.cc b/cpu/trace/trace_cpu.cc index e19509fec..b69793a4b 100644 --- a/cpu/trace/trace_cpu.cc +++ b/cpu/trace/trace_cpu.cc @@ -75,9 +75,14 @@ TraceCPU::tick() icacheInterface->squash(nextReq->asid); } else { ++instReqs; - nextReq->completionEvent = - new TraceCompleteEvent(nextReq, this); - icacheInterface->access(nextReq); + if (icacheInterface->doEvents()) { + nextReq->completionEvent = + new TraceCompleteEvent(nextReq, this); + icacheInterface->access(nextReq); + } else { + icacheInterface->access(nextReq); + completeRequest(nextReq); + } } } else { if (dcacheInterface->isBlocked()) @@ -85,9 +90,15 @@ TraceCPU::tick() ++dataReqs; nextReq->time = curTick; - nextReq->completionEvent = - new TraceCompleteEvent(nextReq, this); - dcacheInterface->access(nextReq); + if (dcacheInterface->doEvents()) { + nextReq->completionEvent = + new TraceCompleteEvent(nextReq, this); + dcacheInterface->access(nextReq); + } else { + dcacheInterface->access(nextReq); + completeRequest(nextReq); + } + } nextCycle = dataTrace->getNextReq(nextReq); } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 680704b30..964ab442c 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -61,12 +61,12 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, HierParams *hier, Bus *bus) : PioDevice(name), disk(d), console(cons), addr(a) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &AlphaConsole::cacheAccess); - pioInterface->addAddrRange(addr, addr + size); + pioInterface->addAddrRange(RangeSize(addr, size)); } alphaAccess = new AlphaAccess; diff --git a/dev/baddev.cc b/dev/baddev.cc index 7c563e80a..73b082d47 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -50,12 +50,12 @@ BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, HierParams *hier, Bus *bus, const string &devicename) : PioDevice(name), addr(a), devname(devicename) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &BadDevice::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); } } diff --git a/dev/etherdump.cc b/dev/etherdump.cc index 27817d456..485d5599c 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -42,11 +42,9 @@ using std::string; -EtherDump::EtherDump(const string &name, const string &file, int max) - : SimObject(name), maxlen(max) +EtherDump::EtherDump(const string &name, std::ostream *_stream, int max) + : SimObject(name), stream(_stream), maxlen(max) { - if (!file.empty()) - stream.open(file.c_str()); } #define DLT_EN10MB 1 // Ethernet (10Mb) @@ -74,9 +72,6 @@ struct pcap_pkthdr { void EtherDump::init() { - if (!stream.is_open()) - return; - curtime = time(NULL); s_freq = ticksPerSecond; us_freq = ticksPerSecond / ULL(1000000); @@ -91,7 +86,7 @@ EtherDump::init() hdr.sigfigs = 0; hdr.linktype = DLT_EN10MB; - stream.write(reinterpret_cast<char *>(&hdr), sizeof(hdr)); + stream->write(reinterpret_cast<char *>(&hdr), sizeof(hdr)); /* * output an empty packet with the current time so that we know @@ -103,9 +98,9 @@ EtherDump::init() pkthdr.microseconds = 0; pkthdr.caplen = 0; pkthdr.len = 0; - stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); + stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); - stream.flush(); + stream->flush(); } void @@ -116,9 +111,9 @@ EtherDump::dumpPacket(PacketPtr &packet) pkthdr.microseconds = (curTick / us_freq) % ULL(1000000); pkthdr.caplen = std::min(packet->length, maxlen); pkthdr.len = packet->length; - stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); - stream.write(reinterpret_cast<char *>(packet->data), pkthdr.caplen); - stream.flush(); + stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); + stream->write(reinterpret_cast<char *>(packet->data), pkthdr.caplen); + stream->flush(); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump) @@ -130,28 +125,14 @@ END_DECLARE_SIM_OBJECT_PARAMS(EtherDump) BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump) - INIT_PARAM(file, "file to dump packets to"), + INIT_PARAM_DFLT(file, "file to dump packets to", "etherdump"), INIT_PARAM_DFLT(maxlen, "max portion of packet data to dump", 96) END_INIT_SIM_OBJECT_PARAMS(EtherDump) CREATE_SIM_OBJECT(EtherDump) { - string filename; - if (file.isValid()) { - filename = file; - - if (filename[0] != '/' && !outputDirectory.empty()) - filename = outputDirectory + filename; - } else { - if (outputDirectory.empty()) { - filename = "etherdump"; - } else { - filename = outputDirectory + "etherdump"; - } - } - - return new EtherDump(getInstanceName(), filename, maxlen); + return new EtherDump(getInstanceName(), makeOutputStream(file), maxlen); } REGISTER_SIM_OBJECT("EtherDump", EtherDump) diff --git a/dev/etherdump.hh b/dev/etherdump.hh index 62364359e..b127d05e2 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -43,7 +43,7 @@ class EtherDump : public SimObject { private: - std::ofstream stream; + std::ostream *stream; const int maxlen; void dumpPacket(PacketPtr &packet); void init(); @@ -53,9 +53,9 @@ class EtherDump : public SimObject Tick us_freq; public: - EtherDump(const std::string &name, const std::string &file, int max); + EtherDump(const std::string &name, std::ostream *_stream, int max); - inline void dump(PacketPtr &pkt) { if (stream.is_open()) dumpPacket(pkt); } + inline void dump(PacketPtr &pkt) { dumpPacket(pkt); } }; #endif // __ETHERDUMP_H__ diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index 9c5f00491..1b6e9858f 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -38,7 +38,6 @@ #include <assert.h> #include "base/refcnt.hh" -#include "base/inet.hh" #include "sim/host.hh" /* @@ -58,17 +57,6 @@ class PacketData : public RefCounted ~PacketData() { if (data) delete [] data; } public: - const EthHdr *eth() const { return (const EthHdr *)data; } - const IpHdr *ip() const {const EthHdr *h = eth(); return h ? h->ip() : 0;} - const TcpHdr *tcp() const {const IpHdr *h = ip(); return h ? h->tcp() : 0;} - const UdpHdr *udp() const {const IpHdr *h = ip(); return h ? h->udp() : 0;} - - EthHdr *eth() { return (EthHdr *)data; } - IpHdr *ip() { EthHdr *h = eth(); return h ? h->ip() : 0; } - TcpHdr *tcp() { IpHdr *h = ip(); return h ? h->tcp() : 0; } - UdpHdr *udp() { IpHdr *h = ip(); return h ? h->udp() : 0; } - - public: void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); }; diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index ec881ed15..d08e61fbf 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -63,9 +63,6 @@ IdeController::IdeController(const string &name, IntrControl *ic, Bus *host_bus, Tick pio_latency, HierParams *hier) : PciDev(name, mmu, cf, cd, bus_num, dev_num, func_num), tsunami(t) { - // put back pointer into Tsunami - tsunami->disk_controller = this; - // initialize the PIO interface addresses pri_cmd_addr = 0; pri_cmd_size = BARSize[0]; @@ -377,8 +374,8 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (BARAddrs[0] != 0) { pri_cmd_addr = BARAddrs[0]; if (pioInterface) - pioInterface->addAddrRange(pri_cmd_addr, - pri_cmd_addr + pri_cmd_size - 1); + pioInterface->addAddrRange(RangeSize(pri_cmd_addr, + pri_cmd_size)); pri_cmd_addr &= PA_UNCACHED_MASK; } @@ -388,8 +385,8 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (BARAddrs[1] != 0) { pri_ctrl_addr = BARAddrs[1]; if (pioInterface) - pioInterface->addAddrRange(pri_ctrl_addr, - pri_ctrl_addr + pri_ctrl_size - 1); + pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, + pri_ctrl_size)); pri_ctrl_addr &= PA_UNCACHED_MASK; } @@ -399,8 +396,8 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (BARAddrs[2] != 0) { sec_cmd_addr = BARAddrs[2]; if (pioInterface) - pioInterface->addAddrRange(sec_cmd_addr, - sec_cmd_addr + sec_cmd_size - 1); + pioInterface->addAddrRange(RangeSize(sec_cmd_addr, + sec_cmd_size)); sec_cmd_addr &= PA_UNCACHED_MASK; } @@ -410,8 +407,8 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (BARAddrs[3] != 0) { sec_ctrl_addr = BARAddrs[3]; if (pioInterface) - pioInterface->addAddrRange(sec_ctrl_addr, - sec_ctrl_addr + sec_ctrl_size - 1); + pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, + sec_ctrl_size)); sec_ctrl_addr &= PA_UNCACHED_MASK; } @@ -421,7 +418,7 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) if (BARAddrs[4] != 0) { bmi_addr = BARAddrs[4]; if (pioInterface) - pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); + pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); bmi_addr &= PA_UNCACHED_MASK; } @@ -675,15 +672,11 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(cmd_in_progress, 4); if (pioInterface) { - pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + - pri_cmd_size - 1); - pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + - pri_ctrl_size - 1); - pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + - sec_cmd_size - 1); - pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + - sec_ctrl_size - 1); - pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); + pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); + pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size)); + pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size)); + pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size)); + pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); } } diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index f4e7c1ef1..f3760bd5e 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -35,7 +35,6 @@ #include <deque> #include <string> -#include "arch/alpha/pmap.h" #include "base/cprintf.hh" // csprintf #include "base/trace.hh" #include "dev/disk_image.hh" @@ -51,6 +50,7 @@ #include "sim/builder.hh" #include "sim/sim_object.hh" #include "sim/universe.hh" +#include "targetarch/isa_traits.hh" using namespace std; @@ -188,14 +188,14 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft) uint32_t bytesInPage = 0; // First calculate how many bytes could be in the page - if (bytesLeft > ALPHA_PGBYTES) - bytesInPage = ALPHA_PGBYTES; + if (bytesLeft > TheISA::PageBytes) + bytesInPage = TheISA::PageBytes; else bytesInPage = bytesLeft; // Next, see if we have crossed a page boundary, and adjust Addr upperBound = curAddr + bytesInPage; - Addr pageBound = alpha_trunc_page(curAddr) + ALPHA_PGBYTES; + Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes; assert(upperBound >= curAddr && "DMA read wraps around address space!\n"); @@ -510,7 +510,7 @@ IdeDisk::dmaWriteDone() // setup the initial page and DMA address curAddr = curPrd.getBaseAddr(); - pageAddr = alpha_trunc_page(curAddr); + pageAddr = TheISA::TruncPage(curAddr); dmaAddr = pciToDma(curAddr); // clear out the data buffer @@ -518,14 +518,14 @@ IdeDisk::dmaWriteDone() while (bytesRead < curPrd.getByteCount()) { // see if we have crossed into a new page - if (pageAddr != alpha_trunc_page(curAddr)) { + if (pageAddr != TheISA::TruncPage(curAddr)) { // write the data to memory memcpy(physmem->dma_addr(dmaAddr, bytesInPage), (void *)(dataBuffer + (bytesRead - bytesInPage)), bytesInPage); // update the DMA address and page address - pageAddr = alpha_trunc_page(curAddr); + pageAddr = TheISA::TruncPage(curAddr); dmaAddr = pciToDma(curAddr); bytesInPage = 0; diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 7260ecde4..4d0b93ab9 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -86,7 +86,7 @@ const char *NsDmaState[] = }; using namespace std; - +using namespace Net; /////////////////////////////////////////////////////////////////////// // @@ -99,7 +99,7 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], + 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), @@ -119,8 +119,6 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, physmem(pmem), intctrl(i), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { - tsunami->ethernet = this; - if (header_bus) { pioInterface = newPioInterface(name, hier, header_bus, this, &NSGigE::cacheAccess); @@ -151,12 +149,7 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, dmaWriteFactor = dma_write_factor; regsReset(); - rom.perfectMatch[0] = eaddr[0]; - rom.perfectMatch[1] = eaddr[1]; - rom.perfectMatch[2] = eaddr[2]; - rom.perfectMatch[3] = eaddr[3]; - rom.perfectMatch[4] = eaddr[4]; - rom.perfectMatch[5] = eaddr[5]; + memcpy(&rom.perfectMatch, eaddr.bytes(), ETH_ADDR_LEN); } NSGigE::~NSGigE() @@ -344,8 +337,7 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data) case PCI0_BASE_ADDR0: if (BARAddrs[0] != 0) { if (pioInterface) - pioInterface->addAddrRange(BARAddrs[0], - BARAddrs[0] + BARSize[0] - 1); + pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); BARAddrs[0] &= PA_UNCACHED_MASK; } @@ -353,8 +345,7 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data) case PCI0_BASE_ADDR1: if (BARAddrs[1] != 0) { if (pioInterface) - pioInterface->addAddrRange(BARAddrs[1], - BARAddrs[1] + BARSize[1] - 1); + pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); BARAddrs[1] &= PA_UNCACHED_MASK; } @@ -1341,10 +1332,10 @@ NSGigE::rxKick() #if TRACING_ON if (DTRACE(Ethernet)) { - const IpHdr *ip = rxPacket->ip(); + IpPtr ip(rxPacket); if (ip) { DPRINTF(Ethernet, "ID is %d\n", ip->id()); - const TcpHdr *tcp = rxPacket->tcp(); + TcpPtr tcp(ip); if (tcp) { DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n", tcp->sport(), tcp->dport()); @@ -1403,36 +1394,38 @@ NSGigE::rxKick() */ if (rxFilterEnable) { rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK; - EthHdr *eth = rxFifoFront()->eth(); - if (eth->unicast()) + const EthAddr &dst = rxFifoFront()->dst(); + if (dst->unicast()) rxDescCache.cmdsts |= CMDSTS_DEST_SELF; - if (eth->multicast()) + if (dst->multicast()) rxDescCache.cmdsts |= CMDSTS_DEST_MULTI; - if (eth->broadcast()) + if (dst->broadcast()) rxDescCache.cmdsts |= CMDSTS_DEST_MASK; } #endif - if (extstsEnable && rxPacket->ip()) { + IpPtr ip(rxPacket); + if (extstsEnable && ip) { rxDescCache.extsts |= EXTSTS_IPPKT; rxIpChecksums++; - IpHdr *ip = rxPacket->ip(); - if (ip->ip_cksum() != 0) { + if (cksum(ip) != 0) { DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); rxDescCache.extsts |= EXTSTS_IPERR; } - if (rxPacket->tcp()) { + TcpPtr tcp(ip); + UdpPtr udp(ip); + if (tcp) { rxDescCache.extsts |= EXTSTS_TCPPKT; rxTcpChecksums++; - if (ip->tu_cksum() != 0) { + if (cksum(tcp) != 0) { DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); rxDescCache.extsts |= EXTSTS_TCPERR; } - } else if (rxPacket->udp()) { + } else if (udp) { rxDescCache.extsts |= EXTSTS_UDPPKT; rxUdpChecksums++; - if (ip->tu_cksum() != 0) { + if (cksum(udp) != 0) { DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); rxDescCache.extsts |= EXTSTS_UDPERR; } @@ -1550,10 +1543,10 @@ NSGigE::transmit() if (interface->sendPacket(txFifo.front())) { #if TRACING_ON if (DTRACE(Ethernet)) { - const IpHdr *ip = txFifo.front()->ip(); + IpPtr ip(txFifo.front()); if (ip) { DPRINTF(Ethernet, "ID is %d\n", ip->id()); - const TcpHdr *tcp = txFifo.front()->tcp(); + TcpPtr tcp(ip); if (tcp) { DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n", tcp->sport(), tcp->dport()); @@ -1816,21 +1809,21 @@ NSGigE::txKick() DPRINTF(EthernetSM, "This packet is done, let's wrap it up\n"); /* deal with the the packet that just finished */ if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { - IpHdr *ip = txPacket->ip(); + IpPtr ip(txPacket); if (txDescCache.extsts & EXTSTS_UDPPKT) { - UdpHdr *udp = txPacket->udp(); + UdpPtr udp(ip); udp->sum(0); - udp->sum(ip->tu_cksum()); + udp->sum(cksum(udp)); txUdpChecksums++; } else if (txDescCache.extsts & EXTSTS_TCPPKT) { - TcpHdr *tcp = txPacket->tcp(); + TcpPtr tcp(ip); tcp->sum(0); - tcp->sum(ip->tu_cksum()); + tcp->sum(cksum(tcp)); txTcpChecksums++; } if (txDescCache.extsts & EXTSTS_IPPKT) { ip->sum(0); - ip->sum(ip->ip_cksum()); + ip->sum(cksum(ip)); txIpChecksums++; } } @@ -1989,31 +1982,31 @@ NSGigE::transferDone() } bool -NSGigE::rxFilter(PacketPtr packet) +NSGigE::rxFilter(PacketPtr &packet) { + EthPtr eth = packet; bool drop = true; string type; - EthHdr *eth = packet->eth(); - if (eth->unicast()) { + const EthAddr &dst = eth->dst(); + if (dst.unicast()) { // If we're accepting all unicast addresses if (acceptUnicast) drop = false; // If we make a perfect match - if (acceptPerfect && - memcmp(rom.perfectMatch, packet->data, EADDR_LEN) == 0) + if (acceptPerfect && dst == rom.perfectMatch) drop = false; if (acceptArp && eth->type() == ETH_TYPE_ARP) drop = false; - } else if (eth->broadcast()) { + } else if (dst.broadcast()) { // if we're accepting broadcasts if (acceptBroadcast) drop = false; - } else if (eth->multicast()) { + } else if (dst.multicast()) { // if we're accepting all multicasts if (acceptMulticast) drop = false; @@ -2029,7 +2022,7 @@ NSGigE::rxFilter(PacketPtr packet) } bool -NSGigE::recvPacket(PacketPtr packet) +NSGigE::recvPacket(PacketPtr &packet) { rxBytes += packet->length; rxPackets++; @@ -2122,7 +2115,7 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(regs.taner); SERIALIZE_SCALAR(regs.tesr); - SERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); + SERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); SERIALIZE_SCALAR(ioEnable); @@ -2279,7 +2272,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(regs.taner); UNSERIALIZE_SCALAR(regs.tesr); - UNSERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); + UNSERIALIZE_ARRAY(rom.perfectMatch, ETH_ADDR_LEN); UNSERIALIZE_SCALAR(ioEnable); @@ -2410,8 +2403,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) * re-add addrRanges to bus bridges */ if (pioInterface) { - pioInterface->addAddrRange(BARAddrs[0], BARAddrs[0] + BARSize[0] - 1); - pioInterface->addAddrRange(BARAddrs[1], BARAddrs[1] + BARSize[1] - 1); + pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); + pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); } } @@ -2519,16 +2512,13 @@ END_INIT_SIM_OBJECT_PARAMS(NSGigE) CREATE_SIM_OBJECT(NSGigE) { - int eaddr[6]; - sscanf(((string)hardware_address).c_str(), "%x:%x:%x:%x:%x:%x", - &eaddr[0], &eaddr[1], &eaddr[2], &eaddr[3], &eaddr[4], &eaddr[5]); - return new NSGigE(getInstanceName(), intr_ctrl, intr_delay, physmem, tx_delay, rx_delay, mmu, hier, header_bus, payload_bus, pio_latency, dma_desc_free, dma_data_free, dma_read_delay, dma_write_delay, dma_read_factor, dma_write_factor, configspace, configdata, - tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr, + tsunami, pci_bus, pci_dev, pci_func, rx_filter, + EthAddr((string)hardware_address), tx_fifo_size, rx_fifo_size); } diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index b7838cf6f..60dcf3fc2 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -31,9 +31,10 @@ * DP83820 ethernet controller */ -#ifndef __NS_GIGE_HH__ -#define __NS_GIGE_HH__ +#ifndef __DEV_NS_GIGE_HH__ +#define __DEV_NS_GIGE_HH__ +#include "base/inet.hh" #include "base/statistics.hh" #include "dev/etherint.hh" #include "dev/etherpkt.hh" @@ -44,9 +45,6 @@ #include "mem/bus/bus.hh" #include "sim/eventq.hh" -/** length of ethernet address in bytes */ -#define EADDR_LEN 6 - /** * Ethernet device registers */ @@ -90,7 +88,7 @@ struct dp_rom { * for perfect match memory. * the linux driver doesn't use any other ROM */ - uint8_t perfectMatch[EADDR_LEN]; + uint8_t perfectMatch[ETH_ADDR_LEN]; }; class IntrControl; @@ -302,7 +300,7 @@ class NSGigE : public PciDev * receive address filter */ bool rxFilterEnable; - bool rxFilter(PacketPtr packet); + bool rxFilter(PacketPtr &packet); bool acceptBroadcast; bool acceptMulticast; bool acceptUnicast; @@ -339,7 +337,7 @@ class NSGigE : public PciDev bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], + uint32_t func, bool rx_filter, Net::EthAddr eaddr, uint32_t tx_fifo_size, uint32_t rx_fifo_size); ~NSGigE(); @@ -352,7 +350,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; } @@ -403,4 +401,4 @@ class NSGigEInt : public EtherInt virtual void sendDone() { dev->transferDone(); } }; -#endif // __NS_GIGE_HH__ +#endif // __DEV_NS_GIGE_HH__ diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 740a9b4ac..6fee30c10 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -50,12 +50,12 @@ PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu, HierParams *hier, Bus *bus, Tick pio_latency) : PioDevice(name), addr(a) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &PciConfigAll::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); pioLatency = pio_latency * bus->clockRatio; } diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 7b13aac80..f0ceb40f2 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -129,7 +129,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) case PCI0_INTERRUPT_LINE: case PCI_CACHE_LINE_SIZE: case PCI_LATENCY_TIMER: - *(uint8_t *)&config.data[offset] = byte_value; + *(uint8_t *)&config.data[offset] = htoa(byte_value); break; default: @@ -142,7 +142,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) case PCI_COMMAND: case PCI_STATUS: case PCI_CACHE_LINE_SIZE: - *(uint16_t *)&config.data[offset] = half_value; + *(uint16_t *)&config.data[offset] = htoa(half_value); break; default: @@ -166,67 +166,59 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) // to size of memory it needs if (word_value == 0xffffffff) { // This is I/O Space, bottom two bits are read only - if (config.data[offset] & 0x1) { - *(uint32_t *)&config.data[offset] = + if (htoa(config.data[offset]) & 0x1) { + *(uint32_t *)&config.data[offset] = htoa( ~(BARSize[barnum] - 1) | - (config.data[offset] & 0x3); + (htoa(config.data[offset]) & 0x3)); } else { // This is memory space, bottom four bits are read only - *(uint32_t *)&config.data[offset] = + *(uint32_t *)&config.data[offset] = htoa( ~(BARSize[barnum] - 1) | - (config.data[offset] & 0xF); + (htoa(config.data[offset]) & 0xF)); } } else { // This is I/O Space, bottom two bits are read only - if(config.data[offset] & 0x1) { - *(uint32_t *)&config.data[offset] = (word_value & ~0x3) | - (config.data[offset] & 0x3); + if(htoa(config.data[offset]) & 0x1) { + *(uint32_t *)&config.data[offset] = htoa((word_value & ~0x3) | + (htoa(config.data[offset]) & 0x3)); if (word_value & ~0x1) { Addr base_addr = (word_value & ~0x1) + TSUNAMI_PCI0_IO; - Addr base_size = BARSize[barnum]-1; + Addr base_size = BARSize[barnum]; // It's never been set if (BARAddrs[barnum] == 0) mmu->add_child((FunctionalMemory *)this, - Range<Addr>(base_addr, - base_addr + base_size)); + RangeSize(base_addr, base_size)); else mmu->update_child((FunctionalMemory *)this, - Range<Addr>(BARAddrs[barnum], - BARAddrs[barnum] + - base_size), - Range<Addr>(base_addr, - base_addr + - base_size)); + RangeSize(BARAddrs[barnum], + base_size), + RangeSize(base_addr, base_size)); BARAddrs[barnum] = base_addr; } } else { // This is memory space, bottom four bits are read only - *(uint32_t *)&config.data[offset] = (word_value & ~0xF) | - (config.data[offset] & 0xF); + *(uint32_t *)&config.data[offset] = htoa((word_value & ~0xF) | + (htoa(config.data[offset]) & 0xF)); if (word_value & ~0x3) { Addr base_addr = (word_value & ~0x3) + TSUNAMI_PCI0_MEMORY; - Addr base_size = BARSize[barnum]-1; + Addr base_size = BARSize[barnum]; // It's never been set if (BARAddrs[barnum] == 0) mmu->add_child((FunctionalMemory *)this, - Range<Addr>(base_addr, - base_addr + base_size)); + RangeSize(base_addr, base_size)); else mmu->update_child((FunctionalMemory *)this, - Range<Addr>(BARAddrs[barnum], - BARAddrs[barnum] + - base_size), - Range<Addr>(base_addr, - base_addr + - base_size)); + RangeSize(BARAddrs[barnum], + base_size), + RangeSize(base_addr, base_size)); BARAddrs[barnum] = base_addr; } @@ -238,14 +230,14 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) if (word_value == 0xfffffffe) *(uint32_t *)&config.data[offset] = 0xffffffff; else - *(uint32_t *)&config.data[offset] = word_value; + *(uint32_t *)&config.data[offset] = htoa(word_value); break; case PCI_COMMAND: // This could also clear some of the error bits in the Status // register. However they should never get set, so lets ignore // it for now - *(uint16_t *)&config.data[offset] = half_value; + *(uint16_t *)&config.data[offset] = htoa(half_value); break; default: @@ -273,10 +265,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) // Add the MMU mappings for the BARs for (int i=0; i < 6; i++) { if (BARAddrs[i] != 0) - mmu->add_child((FunctionalMemory *)this, - Range<Addr>(BARAddrs[i], - BARAddrs[i] + - BARSize[i] - 1)); + mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); } } diff --git a/dev/simconsole.cc b/dev/simconsole.cc index a15057402..b2afb3f84 100644 --- a/dev/simconsole.cc +++ b/dev/simconsole.cc @@ -72,27 +72,22 @@ SimConsole::Event::process(int revent) cons->detach(); } -SimConsole::SimConsole(const string &name, const string &file, int num) +SimConsole::SimConsole(const string &name, std::ostream *os, int num) : SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1), - listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL) + listener(NULL), txbuf(16384), rxbuf(16384), outfile(os) #if TRACING_ON == 1 , linebuf(16384) #endif { - if (!file.empty()) - outfile = new ofstream(file.c_str()); - if (outfile) outfile->setf(ios::unitbuf); - } SimConsole::~SimConsole() { close(); - if (outfile) - delete outfile; + closeOutputStream(outfile); } void @@ -311,7 +306,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole) INIT_PARAM(listener, "console listener"), INIT_PARAM(intr_control, "interrupt controller"), - INIT_PARAM_DFLT(output, "file to dump output to", ""), + INIT_PARAM(output, "file to dump output to"), INIT_PARAM_DFLT(append_name, "append name() to filename", true), INIT_PARAM_DFLT(number, "console number", 0) @@ -319,18 +314,18 @@ END_INIT_SIM_OBJECT_PARAMS(SimConsole) CREATE_SIM_OBJECT(SimConsole) { - string filename = output; - if (filename.empty()) { - if (!outputDirectory.empty()) - filename = outputDirectory + getInstanceName(); + string filename; + + if (!output.isValid()) { + filename = getInstanceName(); + } else if (append_name) { + filename = (string)output + "." + getInstanceName(); } else { - if (append_name) - filename += "." + getInstanceName(); - if (!outputDirectory.empty()) - filename = outputDirectory + filename; + filename = output; } - SimConsole *console = new SimConsole(getInstanceName(), filename, number); + SimConsole *console = new SimConsole(getInstanceName(), + makeOutputStream(filename), number); ((ConsoleListener *)listener)->add(console); return console; diff --git a/dev/simconsole.hh b/dev/simconsole.hh index 138e2e36a..c5a281834 100644 --- a/dev/simconsole.hh +++ b/dev/simconsole.hh @@ -70,7 +70,7 @@ class SimConsole : public SimObject ConsoleListener *listener; public: - SimConsole(const std::string &name, const std::string &file, int num); + SimConsole(const std::string &name, std::ostream *os, int num); ~SimConsole(); protected: diff --git a/dev/tsunami.hh b/dev/tsunami.hh index df804956a..0a7fdbcd9 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -62,12 +62,9 @@ class Tsunami : public Platform /** Pointer to the system */ System *system; + /** Pointer to the TsunamiIO device which has the RTC */ TsunamiIO *io; - /** Pointer to the disk controller device */ - IdeController *disk_controller; - /** Pointer to the ethernet controller device */ - NSGigE *ethernet; /** Pointer to the Tsunami CChip. * The chip contains some configuration information and diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index b43bb13bd..20b39f21f 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -53,7 +53,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, Tick pio_latency) : PioDevice(name), addr(a), tsunami(t) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); for(int i=0; i < Tsunami::Max_CPUs; i++) { dim[i] = 0; @@ -66,7 +66,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &TsunamiCChip::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); pioLatency = pio_latency * bus->clockRatio; } diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 105e3b5b7..fab1b4b38 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -164,12 +164,12 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, Tick pio_latency) : PioDevice(name), addr(a), tsunami(t), rtc(t) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &TsunamiIO::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); pioLatency = pio_latency * bus->clockRatio; } diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 89940fb5a..4c94d12af 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -53,7 +53,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, Bus *bus, Tick pio_latency) : PioDevice(name), addr(a), tsunami(t) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); for (int i = 0; i < 4; i++) { wsba[i] = 0; @@ -64,7 +64,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &TsunamiPChip::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); pioLatency = pio_latency * bus->clockRatio; } diff --git a/dev/uart.cc b/dev/uart.cc index fca856d5d..b71ab2d44 100644 --- a/dev/uart.cc +++ b/dev/uart.cc @@ -92,13 +92,13 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, : PioDevice(name), addr(a), size(s), cons(c), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT), platform(p) { - mmu->add_child(this, Range<Addr>(addr, addr + size)); + mmu->add_child(this, RangeSize(addr, size)); if (bus) { pioInterface = newPioInterface(name, hier, bus, this, &Uart::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + pioInterface->addAddrRange(RangeSize(addr, size)); pioLatency = pio_latency * bus->clockRatio; } @@ -287,7 +287,7 @@ Uart::write(MemReqPtr &req, const uint8_t *data) switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // write byte - cons->out(*(uint64_t *)data); + cons->out(*(uint8_t *)data); platform->clearConsoleInt(); status &= ~TX_INT; if (UART_IER_THRI & IER) diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index c08ee08f7..ed0b613ff 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -39,6 +39,7 @@ #include "cpu/static_inst.hh" #include "kern/kernel_stats.hh" #include "kern/linux/linux_syscalls.hh" +#include "kern/tru64/tru64_syscalls.hh" using namespace std; using namespace Stats; @@ -294,6 +295,10 @@ Statistics::serialize(ostream &os) { int exemode = themode; SERIALIZE_SCALAR(exemode); + SERIALIZE_SCALAR(idleProcess); + SERIALIZE_SCALAR(iplLast); + SERIALIZE_SCALAR(iplLastTick); + SERIALIZE_SCALAR(lastModeTick); } void @@ -301,6 +306,10 @@ Statistics::unserialize(Checkpoint *cp, const string §ion) { int exemode; UNSERIALIZE_SCALAR(exemode); + UNSERIALIZE_SCALAR(idleProcess); + UNSERIALIZE_SCALAR(iplLast); + UNSERIALIZE_SCALAR(iplLastTick); + UNSERIALIZE_SCALAR(lastModeTick); themode = (cpu_mode)exemode; } diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh index 55035c6e4..042f0ad2c 100644 --- a/kern/linux/aligned.hh +++ b/kern/linux/aligned.hh @@ -1,7 +1,7 @@ -#ifndef __ALIGNED_HH__ -#define __ALIGNED_HH__ +#ifndef __KERN_LINUX_ALIGNED_HH__ +#define __KERN_LINUX_ALIGNED_HH__ -#include <stdint.h> +#include "sim/host.hh" #include "targetarch/isa_traits.hh" /* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine @@ -18,4 +18,4 @@ typedef Addr Addr_a __attribute__ ((aligned (8))) ; #define Addr_a Addr __attribute__ ((aligned (8))) #endif /* __GNUC__ __GNUC_MINOR__ */ -#endif /* __ALIGNED_H__ */ +#endif /* __KERN_LINUX_ALIGNED_HH__ */ diff --git a/kern/linux/hwrpb.hh b/kern/linux/hwrpb.hh index 3ce03efd7..16544f196 100644 --- a/kern/linux/hwrpb.hh +++ b/kern/linux/hwrpb.hh @@ -1,5 +1,5 @@ -#ifndef __ALPHA_HWRPB_H__ -#define __ALPHA_HWRPB_H__ +#ifndef __KERN_LINUX_HWRPB_HH__ +#define __KERN_LINUX_HWRPB_HH__ #include "kern/linux/aligned.hh" @@ -15,4 +15,4 @@ namespace Linux { uint64_ta res1, res2; }; } -#endif /* __ALPHA_HWRPB_H */ +#endif // __KERN_LINUX_HWRPB_HH__ diff --git a/kern/linux/linux_syscalls.hh b/kern/linux/linux_syscalls.hh index a729431a0..dee7c5fcd 100644 --- a/kern/linux/linux_syscalls.hh +++ b/kern/linux/linux_syscalls.hh @@ -29,11 +29,14 @@ #ifndef __LINUX_SYSCALLS_HH__ #define __LINUX_SYSCALLS_HH__ -#include "targetarch/syscalls.hh" #include "kern/linux/linux.hh" -struct SystemCalls<Linux> +template <class OS> +class SystemCalls; + +class SystemCalls<Linux> { + public: enum { syscall = 0, llseek = 1, diff --git a/kern/system_events.cc b/kern/system_events.cc index b6526d193..9acf2f65a 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -70,6 +70,7 @@ void IdleStartEvent::process(ExecContext *xc) { xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]); + remove(); } void diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index fb9d43a0e..a322060d8 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -32,8 +32,9 @@ #include "kern/tru64/tru64_events.hh" #include "kern/tru64/dump_mbuf.hh" #include "kern/tru64/printf.hh" -#include "targetarch/arguments.hh" #include "mem/functional_mem/memory_control.hh" +#include "targetarch/arguments.hh" +#include "targetarch/isa_traits.hh" //void SkipFuncEvent::process(ExecContext *xc); @@ -46,8 +47,8 @@ BadAddrEvent::process(ExecContext *xc) uint64_t a0 = xc->regs.intRegFile[ArgumentReg0]; - if (a0 < ALPHA_K0SEG_BASE || a0 >= ALPHA_K1SEG_BASE || - xc->memctrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) { + if (!TheISA::IsK0Seg(a0) || + xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & PA_IMPL_MASK)) { DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); xc->regs.intRegFile[ReturnValueReg] = 0x1; diff --git a/kern/tru64/tru64_syscalls.hh b/kern/tru64/tru64_syscalls.hh index f4853e3f8..7ddc699b1 100644 --- a/kern/tru64/tru64_syscalls.hh +++ b/kern/tru64/tru64_syscalls.hh @@ -29,11 +29,14 @@ #ifndef __TRU64_SYSCALLS_HH__ #define __TRU64_SYSCALLS_HH__ -#include "targetarch/syscalls.hh" #include "kern/tru64/tru64.hh" -struct SystemCalls<Tru64> +template <class OS> +class SystemCalls; + +class SystemCalls<Tru64> { + public: enum { syscall = 0, exit = 1, diff --git a/sim/builder.cc b/sim/builder.cc index 53e5cf3d8..fa5c113a7 100644 --- a/sim/builder.cc +++ b/sim/builder.cc @@ -39,31 +39,11 @@ using namespace std; - -ostream & -builderStream() -{ - static ofstream file; - static ostream *stream = NULL; - - if (!stream) { - if (!outputDirectory.empty()) { - string filename = outputDirectory + "builder.txt"; - file.open(filename.c_str()); - stream = &file; - } else { - stream = outputStream; - } - } - - return *stream; -} - SimObjectBuilder::SimObjectBuilder(const string &_configClass, const string &_instanceName, ConfigNode *_configNode, const string &_simObjClassName) - : ParamContext(_configClass, true), + : ParamContext(_configClass, NoAutoInit), instanceName(_instanceName), configNode(_configNode), simObjClassName(_simObjClassName) @@ -187,10 +167,10 @@ SimObjectClass::createObject(IniFile &configDB, // echo object parameters to stats file (for documenting the // config used to generate the associated stats) - builderStream() << "[" << object->name() << "]" << endl; - builderStream() << "type=" << simObjClassName << endl; - objectBuilder->showParams(builderStream()); - builderStream() << endl; + *configStream << "[" << object->name() << "]" << endl; + *configStream << "type=" << simObjClassName << endl; + objectBuilder->showParams(*configStream); + *configStream << endl; // done with the SimObjectBuilder now delete objectBuilder; diff --git a/sim/builder.hh b/sim/builder.hh index a85c88b76..36e40c2a9 100644 --- a/sim/builder.hh +++ b/sim/builder.hh @@ -38,9 +38,6 @@ class SimObject; -std::ostream & -builderStream(); - // // A SimObjectBuilder serves as an evaluation context for a set of // parameters that describe a specific instance of a SimObject. This diff --git a/sim/main.cc b/sim/main.cc index 2a0427303..76507bbd8 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -111,7 +111,7 @@ static void showBriefHelp(ostream &out) { out << "Usage: " << myProgName - << " [-hn] [-Dname[=def]] [-Uname] [-I[dir]] " + << " [-hnu] [-Dname[=def]] [-Uname] [-I[dir]] " << "[--<section>:<param>=<value>] [<config file> ...]" << endl << " -h: print long help (including parameter listing)" << endl << " -n: don't load default.ini" << endl @@ -396,7 +396,7 @@ main(int argc, char **argv) // Echo command line and all parameter settings to stats file as well. echoCommandLine(argc, argv, *outputStream); - ParamContext::showAllContexts(builderStream()); + ParamContext::showAllContexts(*configStream); // Now process the configuration hierarchy and create the SimObjects. ConfigHierarchy configHierarchy(simConfigDB); diff --git a/sim/param.cc b/sim/param.cc index 84ecbf8f9..d20be8d33 100644 --- a/sim/param.cc +++ b/sim/param.cc @@ -560,15 +560,27 @@ SimObjectBaseParam::parse(const string &s, vector<SimObject *>&value) list<ParamContext *> *ParamContext::ctxList = NULL; -ParamContext::ParamContext(const string &_iniSection, bool noAutoParse) +ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase) : iniFilePtr(NULL), // initialized on call to parseParams() - iniSection(_iniSection), paramList(NULL) + iniSection(_iniSection), paramList(NULL), + initPhase(_initPhase) { - if (!noAutoParse) { + // Put this context on global list for initialization + if (initPhase != NoAutoInit) { if (ctxList == NULL) ctxList = new list<ParamContext *>(); - (*ctxList).push_back(this); + // keep list sorted by ascending initPhase values + list<ParamContext *>::iterator i = ctxList->begin(); + list<ParamContext *>::iterator end = ctxList->end(); + for (; i != end; ++i) { + if (initPhase <= (*i)->initPhase) { + // found where we want to insert + break; + } + } + // (fall through case: insert at end) + ctxList->insert(i, this); } } diff --git a/sim/param.hh b/sim/param.hh index fe13edc48..6706820c2 100644 --- a/sim/param.hh +++ b/sim/param.hh @@ -74,11 +74,30 @@ class ParamContext public: - // Second arg, if set to true, says don't put on paramContextList - // (i.e. don't automatically parse params). Used by derived - // SimObjectBuilder class, where parsing is done in - // SimObject::create() - ParamContext(const std::string &_iniSection, bool noAutoParse = false); + /// Initialization phases for ParamContext objects. + enum InitPhase { + NoAutoInit = -1, ///< Don't initialize at all... params + /// will be parsed later (used by + /// SimObjectBuilder, which parses + /// params in SimObject::create(). + OutputInitPhase = 0, ///< Output stream initialization + TraceInitPhase = 1, ///< Trace context initialization: + /// depends on output streams, but + /// needs to come before others so we + /// can use tracing in other + /// ParamContext init code + StatsInitPhase = 2, ///< Stats output initialization + DefaultInitPhase = 3 ///< Everything else + }; + + /// Records the initialization phase for this ParamContext. + InitPhase initPhase; + + /// Constructor. + /// @param _iniSection Name of .ini section corresponding to this context. + /// @param _initPhase Initialization phase (see InitPhase). + ParamContext(const std::string &_iniSection, + InitPhase _initPhase = DefaultInitPhase); virtual ~ParamContext() {} diff --git a/sim/process.cc b/sim/process.cc index b4febc75b..98db1f2e0 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -392,14 +392,10 @@ CREATE_SIM_OBJECT(LiveProcess) // dummy for default env vector<string> null_vec; - // We do this with "temp" because of the bogus compiler warning - // you get with g++ 2.95 -O if you just "return new LiveProcess(..." - LiveProcess *temp = LiveProcess::create(getInstanceName(), - stdin_fd, stdout_fd, stderr_fd, - cmd, - env.isValid() ? env : null_vec); - - return temp; + return LiveProcess::create(getInstanceName(), + stdin_fd, stdout_fd, stderr_fd, + cmd, + env.isValid() ? env : null_vec); } diff --git a/sim/serialize.cc b/sim/serialize.cc index 91548f653..2a5e3d398 100644 --- a/sim/serialize.cc +++ b/sim/serialize.cc @@ -335,10 +335,7 @@ SerializeParamContext::checkParams() if (serialize_dir.isValid()) { checkpointDirBase = serialize_dir; } else { - if (outputDirectory.empty()) - checkpointDirBase = "m5.%012d"; - else - checkpointDirBase = outputDirectory + "cpt.%012d"; + checkpointDirBase = outputDirectory + "cpt.%012d"; } // guarantee that directory ends with a '/' diff --git a/sim/system.cc b/sim/system.cc index f8312e33b..9fdadf649 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -156,8 +156,8 @@ System::System(Params *p) if (!hwrpb) panic("could not translate hwrpb addr\n"); - *(uint64_t*)(hwrpb+0x50) = params->system_type; - *(uint64_t*)(hwrpb+0x58) = params->system_rev; + *(uint64_t*)(hwrpb+0x50) = htoa(params->system_type); + *(uint64_t*)(hwrpb+0x58) = htoa(params->system_rev); } else panic("could not find hwrpb\n"); diff --git a/sim/universe.cc b/sim/universe.cc index 79e32098c..824b985fa 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -51,14 +51,13 @@ double __ticksPerPS; string outputDirectory; ostream *outputStream; +ostream *configStream; class UniverseParamContext : public ParamContext { - private: - ofstream outputFile; - public: - UniverseParamContext(const string &is) : ParamContext(is) {} + UniverseParamContext(const string &is) + : ParamContext(is, OutputInitPhase) {} void checkParams(); }; @@ -68,9 +67,14 @@ Param<Tick> universe_freq(&universe, "frequency", "tick frequency", 200000000); Param<string> universe_output_dir(&universe, "output_dir", - "directory to output data to"); + "directory to output data to", + "."); Param<string> universe_output_file(&universe, "output_file", - "file to dump simulator output to"); + "file to dump simulator output to", + "cout"); +Param<string> universe_config_output_file(&universe, "config_output_file", + "file to dump simulator config to", + "m5config.out"); void UniverseParamContext::checkParams() @@ -97,26 +101,49 @@ UniverseParamContext::checkParams() } } - string filename; - if (universe_output_file.isValid()) { - string f = universe_output_file; - if (f != "stdout" && f != "cout" && f != "stderr" && f != "cerr") - filename = outputDirectory + f; - else - filename = f; - } else { - if (outputDirectory.empty()) - filename = "stdout"; - else - filename = outputDirectory + "output.txt"; - } + outputStream = makeOutputStream(universe_output_file); + configStream = universe_config_output_file.isValid() + ? makeOutputStream(universe_config_output_file) + : outputStream; +} - if (filename == "stdout" || filename == "cout") - outputStream = &cout; - else if (filename == "stderr" || filename == "cerr") - outputStream = &cerr; - else { - outputFile.open(filename.c_str(), ios::trunc); - outputStream = &outputFile; - } + +std::ostream * +makeOutputStream(std::string &name) +{ + if (name == "cerr" || name == "stderr") + return &std::cerr; + + if (name == "cout" || name == "stdout") + return &std::cout; + + string path = (name[0] != '/') ? outputDirectory + name : name; + + // have to dynamically allocate a stream since we're going to + // return it... though the caller can't easily free it since it + // may be cerr or cout. need GC! + ofstream *s = new ofstream(path.c_str(), ios::trunc); + + if (!s->is_open()) + fatal("Cannot open file %s", path); + + return s; } + + +void +closeOutputStream(std::ostream *os) +{ + // can't close cerr or cout + if (os == &std::cerr || os == &std::cout) + return; + + // can only close ofstreams, not generic ostreams, so try to + // downcast and close only if the downcast succeeds + std::ofstream *ofs = dynamic_cast<std::ofstream *>(os); + if (ofs) + ofs->close(); +} + + + |