Merge linux tree with head

arch/alpha/alpha_memory.cc:
dev/alpha_console.cc:
dev/alpha_console.hh:
    Merge

--HG--
extra : convert_revision : 3233648f204338ab3f102ff117754dce955dcc37
This commit is contained in:
Andrew Schultz 2004-02-09 17:50:47 -05:00
commit eac2d6a668
17 changed files with 471 additions and 263 deletions

View file

@ -97,7 +97,8 @@ AlphaTlb::checkCacheability(MemReqPtr &req)
break;
default:
panic("IPR memory space not implemented! PA=%x\n", req->paddr);
panic("IPR memory space not implemented! PA=%x\n",
req->paddr);
}
}
} else {

View file

@ -1225,7 +1225,7 @@ declare {{
{
}
Addr branchTarget(Addr branchPC)
Addr branchTarget(Addr branchPC) const
{
return branchPC + 4 + disp;
}
@ -1287,7 +1287,7 @@ declare {{
{
}
Addr branchTarget(ExecContext *xc)
Addr branchTarget(ExecContext *xc) const
{
Addr NPC = xc->readPC() + 4;
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
@ -2330,10 +2330,6 @@ decode OPCODE default Unknown::unknown() {
// miscellaneous mem-format ops
0x18: decode MEMFUNC {
format WarnUnimpl {
0x0000: trapb();
0x0400: excb();
0x4000: mb();
0x4400: wmb();
0x8000: fetch();
0xa000: fetch_m();
0xe800: ecb();
@ -2347,6 +2343,27 @@ decode OPCODE default Unknown::unknown() {
format BasicOperate {
0xc000: rpcc({{ Ra = curTick; }});
// All of the barrier instructions below do nothing in
// their execute() methods (hence the empty code blocks).
// All of their functionality is hard-coded in the
// pipeline based on the flags IsSerializing,
// IsMemBarrier, and IsWriteBarrier. In the current
// detailed CPU model, the execute() function only gets
// called at fetch, so there's no way to generate pipeline
// behavior at any other stage. Once we go to an
// exec-in-exec CPU model we should be able to get rid of
// these flags and implement this behavior via the
// execute() methods.
// trapb is just a barrier on integer traps, where excb is
// a barrier on integer and FP traps. "EXCB is thus a
// superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
// them the same though.
0x0000: trapb({{ }}, IsSerializing, No_OpClass);
0x0400: excb({{ }}, IsSerializing, No_OpClass);
0x4000: mb({{ }}, IsMemBarrier, RdPort);
0x4400: wmb({{ }}, IsWriteBarrier, WrPort);
}
#ifdef FULL_SYSTEM
@ -2356,13 +2373,13 @@ decode OPCODE default Unknown::unknown() {
if (!xc->misspeculating()) {
xc->regs.intrflag = 0;
}
}}, No_OpClass);
}});
0xf000: rs({{
Ra = xc->regs.intrflag;
if (!xc->misspeculating()) {
xc->regs.intrflag = 1;
}
}}, No_OpClass);
}});
}
#else
format FailUnimpl {
@ -2476,7 +2493,7 @@ decode OPCODE default Unknown::unknown() {
if (!xc->misspeculating())
AlphaPseudo::m5exit(xc);
}}, No_OpClass);
0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
0x30: initparam({{ Ra = cpu->system->init_param; }});
0x40: resetstats({{
if (!xc->misspeculating())
AlphaPseudo::resetstats(xc);

View file

@ -34,6 +34,10 @@
* This file defines a doNothing compression algorithm.
*/
#include <inttypes.h> // for uint8_t
#include "base/misc.hh" // for fatal()
/**
* A dummy compression class to use when no data compression is desired.
*/

83
base/range.cc Normal file
View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2003 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "base/intmath.hh"
#include "base/range.hh"
#include "base/str.hh"
using namespace std;
template <class T>
bool
__x_parse_range(const std::string &str, T &start, T &end)
{
std::vector<std::string> values;
tokenize(values, str, ':');
T thestart, theend;
if (values.size() != 2)
return false;
std::string s = values[0];
std::string e = values[1];
if (!to_number(s, thestart))
return false;
bool increment = (e[0] == '+');
if (increment)
e = e.substr(1);
if (!to_number(e, theend))
return false;
if (increment)
theend += thestart;
start = thestart;
end = theend;
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); }
RANGE_PARSE(unsigned long long);
RANGE_PARSE(signed long long);
RANGE_PARSE(unsigned long);
RANGE_PARSE(signed long);
RANGE_PARSE(unsigned int);
RANGE_PARSE(signed int);
RANGE_PARSE(unsigned short);
RANGE_PARSE(signed short);
RANGE_PARSE(unsigned char);
RANGE_PARSE(signed char);

View file

@ -29,232 +29,351 @@
#ifndef __RANGE_HH__
#define __RANGE_HH__
#include <assert.h>
#include "base/intmath.hh"
#include "base/str.hh"
#include <cassert>
#include <string>
template <class T>
class Range
bool __parse_range(const std::string &s, T &start, T &end);
template <class T>
struct Range
{
private:
bool valid;
/**
* @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() {}
Range(const Range &r) { operator=(r); }
Range(const T &s, const T &e)
: start(s), end(e)
Range()
{
valid = (start <= end);
invalidate();
}
Range(const std::string &s) { valid = parse(s); }
Range(T first, T second)
: start(first), end(second)
{}
~Range() {}
template <class U>
Range(const Range<U> &r)
: start(r.start), end(r.end)
{}
int compare(const T &p);
bool parse(const std::string &s);
const Range &operator=(const Range &r);
template <class U>
Range(const std::pair<U, U> &r)
: start(r.first), end(r.second)
{}
bool isValid() const { return valid; }
};
template<class T>
inline int
Range<T>::compare(const T &p)
Range(const std::string &s)
{
assert(isValid());
if (p < start)
return -1;
else if (p > end)
return 1;
else
return 0;
parse(s);
}
// Parse a range string
//
// Ranges are in the following format:
// <range> := {<start_val>}:{<end>}
// <end> := <end_val> | +<delta>
template<class T>
inline bool
Range<T>::parse(const std::string &str)
template <class U>
const Range<T> &operator=(const Range<U> &r)
{
std::vector<std::string> values;
tokenize(values, str, ':');
T thestart, theend;
if (values.size() != 2)
return false;
std::string s = values[0];
std::string e = values[1];
if (!to_number(s, thestart))
return false;
bool increment = (e[0] == '+');
if (increment)
e = e.substr(1);
if (!to_number(e, theend))
return false;
if (increment)
theend += thestart;
start = thestart;
end = theend;
if (start > end)
return false;
return true;
}
template<class T>
inline const Range<T> &
Range<T>::operator=(const Range<T> &r)
{
if (this != &r) {
start = r.start;
end = r.end;
valid = r.valid;
}
else {
valid = false;
}
return *this;
}
template <class U>
const Range<T> &operator=(const std::pair<U, U> &r)
{
start = r.first;
end = r.second;
return *this;
}
const Range &operator=(const std::string &s)
{
parse(s);
return *this;
}
void invalidate() { start = 0; end = 0; }
T size() const { return end - start; }
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.isValid());
assert(r.valid());
o << r.start << ":" << r.end;
return o;
}
//////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//
// Compare two ranges
// Range to Range Comparisons
//
template<class T>
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 and range2 are identical.
*/
template <class T, class U>
inline bool
operator==(const Range<T> &l, const Range<T> &r)
operator==(const Range<T> &range1, const Range<U> &range2)
{
// ranges must both be valid to be equal
return (l.isValid() && r.isValid() &&
(l.start == r.start) && (l.end == r.end));
assert(range1.valid() && range2.valid());
return range1.start == range2.start && range1.end == range2.end;
}
template<class T>
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 and range2 are not identical.
*/
template <class T, class U>
inline bool
operator!=(const Range<T> &l, const Range<T> &r)
operator!=(const Range<T> &range1, const Range<U> &range2)
{
// for symmetry with ==, an invalid range is not equal to any other
return (!l.isValid() || !r.isValid() ||
(l.start != r.start) || (l.end != r.end));
assert(range1.valid() && range2.valid());
return range1.start != range2.start || range1.end != range2.end;
}
//////////////////////////////////////////
//
// Compare position to a range
//
// - 'pos == range' indicates that position pos is within the given range.
// This test always returns false if the range is invalid.
//
// - 'pos < range' and 'pos > range' indicate that the position is
// before the start of or after the end of the range, respectively.
// The range must be valid for these comparisons to be made.
//
// All other comparisons do the obvious thing based on these definitions.
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 is less than range2 and does not overlap range1.
*/
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;
}
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 is less than range2. range1 may overlap range2,
* but not extend beyond the end of range2.
*/
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;
}
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 is greater than range2 and does not overlap range2.
*/
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;
}
/**
* @param range1 is a range.
* @param range2 is a range.
* @return if range1 is greater than range2. range1 may overlap range2,
* but not extend beyond the beginning of range2.
*/
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;
}
////////////////////////////////////////////////////////////////////////
//
// Position to Range Comparisons
//
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is within the range.
*/
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;
}
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is not within the range.
*/
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;
}
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is below the range.
*/
template <class T, class U>
inline bool
operator<(const T &pos, const Range<U> &range)
{
assert(range.valid());
return pos < range.start;
}
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is below or in the range.
*/
template <class T, class U>
inline bool
operator<=(const T &pos, const Range<U> &range)
{
assert(range.valid());
return pos < range.end;
}
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is above the range.
*/
template <class T, class U>
inline bool
operator>(const T &pos, const Range<U> &range)
{
assert(range.valid());
return pos >= range.end;
}
/**
* @param pos position compared to the range.
* @param range range compared against.
* @return indicates that position pos is above or in the range.
*/
template <class T, class U>
inline bool
operator>=(const T &pos, const Range<U> &range)
{
assert(range.valid());
return pos >= range.start;
}
////////////////////////////////////////////////////////////////////////
//
// Basic comparisons
// Range to Position Comparisons (for symmetry)
//
template<class T>
inline bool
operator==(const T &pos, const Range<T> &range)
{ return range.isValid() && pos >= range.start && pos <= range.end; }
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* @return indicates that position pos is within the range.
*/
template <class T, class U>
inline bool
operator<(const T &pos, const Range<T> &range)
{ assert(range.isValid()); return pos < range.start; }
operator==(const Range<T> &range, const U &pos)
{
assert(range.valid());
return pos >= range.start && pos < range.end;
}
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* @return indicates that position pos is not within the range.
*/
template <class T, class U>
inline bool
operator>(const T &pos, const Range<T> &range)
{ assert(range.isValid()); return pos > range.end; }
operator!=(const Range<T> &range, const U &pos)
{
assert(range.valid());
return pos < range.start || pos >= range.end;
}
//
// Derived comparisons
//
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* @return indicates that position pos is above the range.
*/
template <class T, class U>
inline bool
operator<=(const T &pos, const Range<T> &range)
{ assert(range.isValid()); return pos <= range.end; }
operator<(const Range<T> &range, const U &pos)
{
assert(range.valid());
return range.end <= pos;
}
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* @return indicates that position pos is above or in the range.
*/
template <class T, class U>
inline bool
operator>=(const T &pos, const Range<T> &range)
{ assert(range.isValid()); return pos >= range.start; }
operator<=(const Range<T> &range, const U &pos)
{
assert(range.valid());
return range.start <= pos;
}
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* 'range > pos' indicates that position pos is below the range.
*/
template <class T, class U>
inline bool
operator!=(const T &pos, const Range<T> &range)
{ return !(pos == range); }
operator>(const Range<T> &range, const U &pos)
{
assert(range.valid());
return range.start > pos;
}
//
// Define symmetric comparisons based on above
//
template<class T>
/**
* @param range range compared against.
* @param pos position compared to the range.
* 'range >= pos' indicates that position pos is below or in the range.
*/
template <class T, class U>
inline bool
operator>(const Range<T> &range, const T &pos)
{ return pos < range; }
template<class T>
inline bool
operator<(const Range<T> &range, const T &pos)
{ return pos > range; }
template<class T>
inline bool
operator<=(const Range<T> &range, const T &pos)
{ return pos >= range; }
template<class T>
inline bool
operator>=(const Range<T> &range, const T &pos)
{ return pos <= range; }
template<class T>
inline bool
operator==(const Range<T> &range, const T &pos)
{ return (pos == range); }
template<class T>
inline bool
operator!=(const Range<T> &range, const T &pos)
{ return (pos != range); }
operator>=(const Range<T> &range, const U &pos)
{
assert(range.valid());
return range.end > pos;
}
#endif // __RANGE_HH__

View file

@ -338,7 +338,7 @@ RemoteGDB::acc(Addr va, size_t len)
}
if (va < ALPHA_K1SEG_BASE) {
if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) {
if (va < (ALPHA_K0SEG_BASE + pmem->size())) {
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
"%#x < K0SEG + size\n", va);
return true;

View file

@ -78,6 +78,12 @@ class StaticInstBase : public RefCounted
/// - If IsControl is set, then exactly one of IsDirectControl or
/// IsIndirect Control will be set, and exactly one of
/// IsCondControl or IsUncondControl will be set.
/// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
/// implemented as flags since in the current model there's no
/// other way for instructions to inject behavior into the
/// pipeline outside of fetch. Once we go to an exec-in-exec CPU
/// model we should be able to get rid of these flags and
/// implement this behavior via the execute() methods.
///
enum Flags {
IsNop, ///< Is a no-op (no effect at all).
@ -101,6 +107,11 @@ class StaticInstBase : public RefCounted
IsThreadSync, ///< Thread synchronization operation.
IsSerializing, ///< Serializes pipeline: won't until all
/// older instructions have committed.
IsMemBarrier, ///< Is a memory barrier
IsWriteBarrier, ///< Is a write barrier
NumFlags
};
@ -178,6 +189,9 @@ class StaticInstBase : public RefCounted
bool isUncondCtrl() const { return flags[IsUncondControl]; }
bool isThreadSync() const { return flags[IsThreadSync]; }
bool isSerializing() const { return flags[IsSerializing]; }
bool isMemBarrier() const { return flags[IsMemBarrier]; }
bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
//@}
/// Operation class. Used to select appropriate function unit in issue.
@ -216,11 +230,11 @@ class StaticInst : public StaticInstBase
/// Return logical index (architectural reg num) of i'th destination reg.
/// Only the entries from 0 through numDestRegs()-1 are valid.
RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
/// Return logical index (architectural reg num) of i'th source reg.
/// Only the entries from 0 through numSrcRegs()-1 are valid.
RegIndex srcRegIdx(int i) { return _srcRegIdx[i]; }
RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
/// Pointer to a statically allocated "null" instruction object.
/// Used to give eaCompInst() and memAccInst() something to return
@ -305,7 +319,7 @@ class StaticInst : public StaticInstBase
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
* should be true).
*/
virtual Addr branchTarget(Addr branchPC)
virtual Addr branchTarget(Addr branchPC) const
{
panic("StaticInst::branchTarget() called on instruction "
"that is not a PC-relative branch.");
@ -318,7 +332,7 @@ class StaticInst : public StaticInstBase
* execute the branch in question. Invalid if not an indirect
* branch (i.e. isIndirectCtrl() should be true).
*/
virtual Addr branchTarget(ExecContext *xc)
virtual Addr branchTarget(ExecContext *xc) const
{
panic("StaticInst::branchTarget() called on instruction "
"that is not an indirect branch.");

View file

@ -36,7 +36,7 @@
#define ALPHA_ACCESS_VERSION (1301) /* CH++*/
#ifndef CONSOLE
#include <ostream>
#include <iosfwd>
#include <string>
class Checkpoint;
#endif

View file

@ -56,6 +56,8 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
Addr addr, Addr mask, MemoryController *mmu)
: MmapDevice(name, addr, mask, mmu), disk(d), console(cons)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
consoleData = new uint8_t[size];
memset(consoleData, 0, size);
@ -66,7 +68,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons,
alphaAccess->version = ALPHA_ACCESS_VERSION;
alphaAccess->numCPUs = num_cpus;
alphaAccess->mem_size = system->physmem->getSize();
alphaAccess->mem_size = system->physmem->size();
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
alphaAccess->intrClockFrequency = clock->frequency();
@ -79,7 +81,8 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
memset(data, 0, req->size);
uint64_t val;
Addr daddr = req->paddr & addr_mask;
Addr daddr = req->paddr - addr;
switch (daddr) {
case offsetof(AlphaAccess, inputChar):
val = console->console_in();
@ -126,7 +129,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
return Machine_Check_Fault;
}
Addr daddr = req->paddr & addr_mask;
Addr daddr = req->paddr - addr;
ExecContext *other_xc;
switch (daddr) {
@ -244,11 +247,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
SimObjectParam<SimConsole *> sim_console;
SimObjectParam<SimpleDisk *> disk;
Param<int> size;
Param<int> num_cpus;
SimObjectParam<MemoryController *> mmu;
Param<Addr> addr;
Param<Addr> mask;
SimObjectParam<System *> system;
SimObjectParam<BaseCPU *> cpu;
SimObjectParam<TsunamiIO *> clock;
@ -259,11 +260,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
INIT_PARAM(sim_console, "The Simulator Console"),
INIT_PARAM(disk, "Simple Disk"),
INIT_PARAM_DFLT(size, "AlphaConsole size", sizeof(AlphaAccess)),
INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1),
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(addr, "Device Address"),
INIT_PARAM(mask, "Address Mask"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu, "Processor"),
INIT_PARAM(clock, "Turbolaser Clock")
@ -272,10 +271,8 @@ END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
CREATE_SIM_OBJECT(AlphaConsole)
{
return new AlphaConsole(getInstanceName(), sim_console,
disk, size, system,
cpu, clock, num_cpus,
addr, mask, mmu);
return new AlphaConsole(getInstanceName(), sim_console, disk,
system, cpu, clock, num_cpus, mmu, addr);
}
REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole)

View file

@ -33,9 +33,10 @@
#ifndef __ALPHA_CONSOLE_HH__
#define __ALPHA_CONSOLE_HH__
#include "sim/host.hh"
#include "base/range.hh"
#include "dev/alpha_access.h"
#include "mem/functional_mem/mmap_device.hh"
#include "mem/functional_mem/functional_memory.hh"
#include "sim/host.hh"
#include "dev/tsunami_io.hh"
class BaseCPU;
@ -69,7 +70,7 @@ class SimpleDisk;
* primarily used doing boot before the kernel has loaded its device
* drivers.
*/
class AlphaConsole : public MmapDevice
class AlphaConsole : public FunctionalMemory
{
protected:
union {
@ -83,6 +84,9 @@ class AlphaConsole : public MmapDevice
/** the system console (the terminal) is accessable from the console */
SimConsole *console;
Addr addr;
static const Addr size = 0x80; // equal to sizeof(alpha_access);
public:
/** Standard Constructor */
AlphaConsole(const std::string &name, SimConsole *cons,
@ -91,7 +95,6 @@ class AlphaConsole : public MmapDevice
TsunamiIO *clock, int num_cpus,
Addr addr, Addr mask, MemoryController *mmu);
public:
/**
* memory mapped reads and writes
*/

View file

@ -89,7 +89,7 @@ class EtherLink : public SimObject
Link(const std::string &name, double rate, EtherDump *dump);
~Link() {}
virtual std::string name() const { return objName; }
virtual const std::string name() const { return objName; }
bool busy() const { return (bool)packet; }
bool transmit(PacketPtr &packet);

View file

@ -153,7 +153,7 @@ class Event : public Serializable, public FastAlloc
~Event() {}
virtual std::string name() const {
virtual const std::string name() const {
return csprintf("Event_%x", (uintptr_t)this);
}
@ -257,7 +257,7 @@ class EventQueue : public Serializable
: objName(n), head(NULL)
{}
virtual std::string name() const { return objName; }
virtual const std::string name() const { return objName; }
// schedule the given event on this queue
void schedule(Event *ev);

View file

@ -186,7 +186,7 @@ INSTANTIATE_PARAM_TEMPLATES(string)
class Globals : public Serializable
{
public:
string name() const;
const string name() const;
void serialize(ostream &os);
void unserialize(Checkpoint *cp);
};
@ -194,7 +194,7 @@ class Globals : public Serializable
/// The one and only instance of the Globals class.
Globals globals;
string
const string
Globals::name() const
{
return "Globals";

View file

@ -111,7 +111,7 @@ class Serializable
virtual ~Serializable() {}
// manditory virtual function, so objects must provide names
virtual std::string name() const = 0;
virtual const std::string name() const = 0;
virtual void serialize(std::ostream &os) {}
virtual void unserialize(Checkpoint *cp, const std::string &section) {}

View file

@ -63,7 +63,7 @@ class SimObject : public Serializable
virtual ~SimObject() {}
virtual std::string name() const { return objName; }
virtual const std::string name() const { return objName; }
// initialization pass of all objects. Gets invoked by SimInit()
virtual void init();

View file

@ -49,7 +49,7 @@ nmtest: nmtest.o object_file.o symtab.o misc.o str.o
offtest: offtest.o
$(CXX) $(LFLAGS) -o $@ $^
rangetest: rangetest.o str.o
rangetest: rangetest.o range.o str.o
$(CXX) $(LFLAGS) -o $@ $^
stattest: cprintf.o hostinfo.o misc.o python.o statistics.o stattest.o \

View file

@ -31,11 +31,12 @@
#include "base/range.hh"
using namespace std;
int
main()
{
Range<int> r1(9, 28);
Range<int> r1(make_pair(9, 28));
Range<unsigned> r2("0x1000:+0x100");
cout << r1 << "\n"
@ -44,61 +45,30 @@ main()
#define RANGETEST(X, C, Y) \
cout << X << " "#C" " << Y << " => " << ((X C Y) ? "true" : "false") << "\n"
int i1 = 10;
int i2 = 0x1001;
RANGETEST(i1, < , r1);
RANGETEST(i1, <=, r1);
RANGETEST(i1, > , r1);
RANGETEST(i1, >=, r1);
RANGETEST(i1, ==, r1);
RANGETEST(i1, !=, r1);
RANGETEST(r1, < , i1);
RANGETEST(r1, <=, i1);
RANGETEST(r1, > , i1);
RANGETEST(r1, >=, i1);
RANGETEST(r1, ==, i1);
RANGETEST(r1, !=, i1);
#define TESTEM(X, Y) do { \
RANGETEST(X, < , Y); \
RANGETEST(X, <=, Y); \
RANGETEST(X, > , Y); \
RANGETEST(X, >=, Y); \
RANGETEST(X, ==, Y); \
RANGETEST(X, !=, Y); \
RANGETEST(Y, < , X); \
RANGETEST(Y, <=, X); \
RANGETEST(Y, > , X); \
RANGETEST(Y, >=, X); \
RANGETEST(Y, ==, X); \
RANGETEST(Y, !=, X); \
} while (0)
RANGETEST(i2, < , r1);
RANGETEST(i2, <=, r1);
RANGETEST(i2, > , r1);
RANGETEST(i2, >=, r1);
RANGETEST(i2, ==, r1);
RANGETEST(i2, !=, r1);
RANGETEST(r1, < , i2);
RANGETEST(r1, <=, i2);
RANGETEST(r1, > , i2);
RANGETEST(r1, >=, i2);
RANGETEST(r1, ==, i2);
RANGETEST(r1, !=, i2);
TESTEM(8, r1);
TESTEM(9, r1);
TESTEM(27, r1);
TESTEM(28, r1);
unsigned u1 = 10;
unsigned u2 = 0x1001;
RANGETEST(u1, < , r2);
RANGETEST(u1, <=, r2);
RANGETEST(u1, > , r2);
RANGETEST(u1, >=, r2);
RANGETEST(u1, ==, r2);
RANGETEST(u1, !=, r2);
RANGETEST(r2, < , u1);
RANGETEST(r2, <=, u1);
RANGETEST(r2, > , u1);
RANGETEST(r2, >=, u1);
RANGETEST(r2, ==, u1);
RANGETEST(r2, !=, u1);
RANGETEST(u2, < , r2);
RANGETEST(u2, <=, r2);
RANGETEST(u2, > , r2);
RANGETEST(u2, >=, r2);
RANGETEST(u2, ==, r2);
RANGETEST(u2, !=, r2);
RANGETEST(r2, < , u2);
RANGETEST(r2, <=, u2);
RANGETEST(r2, > , u2);
RANGETEST(r2, >=, u2);
RANGETEST(r2, ==, u2);
RANGETEST(r2, !=, u2);
TESTEM(0x0fff, r2);
TESTEM(0x1000, r2);
TESTEM(0x10ff, r2);
TESTEM(0x1100, r2);
return 0;
}