summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2006-05-04 21:10:51 -0400
committerKorey Sewell <ksewell@umich.edu>2006-05-04 21:10:51 -0400
commitde8eba689164b59679a3e3ef3550bc7abb5ecdce (patch)
tree357184f755ef18190b97547cf5bff888344066ba
parent2e7e844768e160bf81be53d6b633f3851bb4ea80 (diff)
parent8a9d270f6c17efa79f38e629c7cbcafa51aa8494 (diff)
downloadgem5-de8eba689164b59679a3e3ef3550bc7abb5ecdce.tar.xz
Merge zizzer:/bk/newmem
into zizzer.eecs.umich.edu:/.automount/zooks/y/ksewell/research/m5-sim/newmem --HG-- extra : convert_revision : c48a8857f5a520ff8061eb3d8f08dcd43661e68c
-rw-r--r--SConscript8
-rw-r--r--arch/alpha/system.hh1
-rw-r--r--arch/sparc/SConscript1
-rw-r--r--arch/sparc/isa/decoder.isa84
-rw-r--r--arch/sparc/isa/formats/branch.isa23
-rw-r--r--arch/sparc/isa/formats/integerop.isa31
-rw-r--r--arch/sparc/isa/formats/mem.isa11
-rw-r--r--arch/sparc/linux/linux.cc68
-rw-r--r--arch/sparc/linux/linux.hh61
-rw-r--r--arch/sparc/linux/process.cc10
-rw-r--r--arch/sparc/linux/process.hh1
-rw-r--r--arch/sparc/process.cc111
-rw-r--r--arch/sparc/process.hh19
-rw-r--r--arch/sparc/regfile.hh11
-rw-r--r--arch/sparc/system.cc200
-rw-r--r--arch/sparc/system.hh114
-rw-r--r--configs/test/fs.py10
-rwxr-xr-xconfigs/test/hello_sparcbin587552 -> 644149 bytes
-rw-r--r--cpu/simple/cpu.cc2
-rw-r--r--cpu/simple/cpu.hh4
-rw-r--r--dev/alpha_console.cc4
-rw-r--r--dev/ide_ctrl.cc4
-rw-r--r--dev/io_device.cc8
-rw-r--r--dev/io_device.hh3
-rw-r--r--dev/isa_fake.cc4
-rw-r--r--dev/ns_gige.cc4
-rw-r--r--dev/pciconfigall.cc4
-rw-r--r--dev/sinic.cc4
-rw-r--r--dev/tsunami_cchip.cc4
-rw-r--r--dev/tsunami_io.cc4
-rw-r--r--dev/tsunami_pchip.cc4
-rw-r--r--dev/uart8250.cc4
-rw-r--r--mem/bridge.cc263
-rw-r--r--mem/bridge.hh214
-rw-r--r--mem/bus.cc45
-rw-r--r--mem/bus.hh21
-rw-r--r--mem/packet.cc94
-rw-r--r--mem/packet.hh74
-rw-r--r--mem/physical.cc2
-rw-r--r--mem/port.hh2
-rw-r--r--python/m5/objects/Bridge.py9
-rw-r--r--python/m5/objects/System.py2
-rw-r--r--sim/system.hh1
43 files changed, 1379 insertions, 169 deletions
diff --git a/SConscript b/SConscript
index cac083b6b..d49bee5e4 100644
--- a/SConscript
+++ b/SConscript
@@ -87,13 +87,15 @@ base_sources = Split('''
cpu/pc_event.cc
cpu/static_inst.cc
cpu/sampler/sampler.cc
-
- mem/request.cc
+
+ mem/bridge.cc
+ mem/bus.cc
mem/connector.cc
mem/mem_object.cc
+ mem/packet.cc
mem/physical.cc
mem/port.cc
- mem/bus.cc
+ mem/request.cc
python/pyconfig.cc
python/embedded_py.cc
diff --git a/arch/alpha/system.hh b/arch/alpha/system.hh
index fe1307ac3..924e16826 100644
--- a/arch/alpha/system.hh
+++ b/arch/alpha/system.hh
@@ -45,7 +45,6 @@ class AlphaSystem : public System
{
std::string console_path;
std::string palcode;
- std::string boot_osflags;
uint64_t system_type;
uint64_t system_rev;
};
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript
index 172e4390f..fd0df9349 100644
--- a/arch/sparc/SConscript
+++ b/arch/sparc/SConscript
@@ -57,6 +57,7 @@ full_system_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
+ linux/linux.cc
linux/process.cc
process.cc
''')
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index 823bf2626..b9e83afd6 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -16,44 +16,62 @@ decode OP default Unknown::unknown()
0x0: bpcci({{
if(passesCondition(CcrIcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x2: bpccx({{
if(passesCondition(CcrXcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
}
}
0x2: Branch22::bicc({{
if(passesCondition(CcrIcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x3: decode RCOND2
{
format BranchSplit
{
0x1: bpreq({{
- if(Rs1 == 0)
+ if(Rs1.sdw == 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x2: bprle({{
- if(Rs1 <= 0)
+ if(Rs1.sdw <= 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x3: bprl({{
- if(Rs1 < 0)
+ if(Rs1.sdw < 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x5: bprne({{
- if(Rs1 != 0)
+ if(Rs1.sdw != 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x6: bprg({{
- if(Rs1 > 0)
+ if(Rs1.sdw > 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x7: bprge({{
- if(Rs1 >= 0)
+ if(Rs1.sdw >= 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
}
}
@@ -109,7 +127,7 @@ decode OP default Unknown::unknown()
if(Rd.udw<63:31> != 0)
Rd.udw = 0x7FFFFFFF;
else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
- Rd.udw = 0xFFFFFFFF80000000;
+ Rd.udw = 0xFFFFFFFF80000000ULL;
}
}});
}
@@ -117,22 +135,22 @@ decode OP default Unknown::unknown()
0x10: addcc({{
int64_t resTemp, val2 = Rs2_or_imm13;
Rd = resTemp = Rs1 + val2;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{(Rs1<31:0> + val2<31:0>)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{(Rs1<63:1> + val2<63:1> + (Rs1 & val2)<0:>)<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
0x14: subcc({{
- int64_t resTemp, val2 = Rs2_or_imm13;
- Rd = resTemp = Rs1 - val2;}},
- {{((Rs1 & 0xFFFFFFFF - val2 & 0xFFFFFFFF) >> 31)}},
- {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{(((Rs1 >> 1) + (~val2) >> 1) +
- ((Rs1 | ~val2) & 0x1))<63:>}},
- {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
+ int64_t val2 = Rs2_or_imm13;
+ Rd = Rs1 - val2;}},
+ {{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}},
+ {{(Rs1<31:> != val2<31:>) && (Rs1<31:> != Rd<31:>)}},
+ {{(~(Rs1<63:1> + (~val2)<63:1> +
+ (Rs1 | ~val2)<0:>))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != Rd<63:>}}
);
0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
@@ -141,11 +159,10 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = CcrIccC;
Rd = resTemp = Rs1 + val2 + carryin;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
- + carryin)}},
+ {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
+ {{(Rs1<63:1> + val2<63:1> +
+ ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
0x1A: umulcc({{
@@ -162,9 +179,9 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = CcrIccC;
Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
- {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
+ {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{(((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
+ {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
);
0x1D: udivxcc({{
@@ -197,7 +214,7 @@ decode OP default Unknown::unknown()
overflow = (resTemp<63:31> != 0);
underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
if(overflow) Rd = resTemp = 0x7FFFFFFF;
- else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000;
+ else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000ULL;
else Rd = resTemp;
} }},
{{0}},
@@ -333,11 +350,15 @@ decode OP default Unknown::unknown()
{
0x0: movcci({{
if(passesCondition(CcrIcc, COND4))
- Rd = (I ? SIMM11 : RS2);
+ Rd = Rs2_or_imm11;
+ else
+ Rd = Rd;
}});
0x2: movccx({{
if(passesCondition(CcrXcc, COND4))
- Rd = (I ? SIMM11 : RS2);
+ Rd = Rs2_or_imm11;
+ else
+ Rd = Rd;
}});
}
}
@@ -356,16 +377,17 @@ decode OP default Unknown::unknown()
count += oneBits[temp & 0xF];
temp = temp >> 4;
}
+ Rd = count;
}});
}
0x2F: decode RCOND3
{
- 0x1: movreq({{if(Rs1 == 0) Rd = Rs2_or_imm10;}});
- 0x2: movrle({{if(Rs1 <= 0) Rd = Rs2_or_imm10;}});
- 0x3: movrl({{if(Rs1 < 0) Rd = Rs2_or_imm10;}});
- 0x5: movrne({{if(Rs1 != 0) Rd = Rs2_or_imm10;}});
- 0x6: movrg({{if(Rs1 > 0) Rd = Rs2_or_imm10;}});
- 0x7: movrge({{if(Rs1 >= 0) Rd = Rs2_or_imm10;}});
+ 0x1: movreq({{Rd = (Rs1 == 0) ? Rs2_or_imm10 : Rd;}});
+ 0x2: movrle({{Rd = (Rs1 <= 0) ? Rs2_or_imm10 : Rd;}});
+ 0x3: movrl({{Rd = (Rs1 < 0) ? Rs2_or_imm10 : Rd;}});
+ 0x5: movrne({{Rd = (Rs1 != 0) ? Rs2_or_imm10 : Rd;}});
+ 0x6: movrg({{Rd = (Rs1 > 0) ? Rs2_or_imm10 : Rd;}});
+ 0x7: movrge({{Rd = (Rs1 >= 0) ? Rs2_or_imm10 : Rd;}});
}
0x30: decode RD {
0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}});
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index b76f7a9f6..37bdb9402 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -194,7 +194,7 @@ output decoder {{
{
ccprintf(response, " <%s", symbol);
if(symbolAddr != target)
- ccprintf(response, "+0x%x>", target - symbolAddr);
+ ccprintf(response, "+%d>", target - symbolAddr);
else
ccprintf(response, ">");
}
@@ -226,8 +226,25 @@ def template BranchExecute {{
}
}};
+let {{
+ handle_annul = '''
+ {
+ if(A)
+ {
+ NPC = xc->readNextNPC();
+ NNPC = NPC + 4;
+ }
+ else
+ {
+ NPC = xc->readNextPC();
+ NNPC = xc->readNextNPC();
+ }
+ }'''
+}};
+
// Primary format for branch instructions:
def format Branch(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
@@ -247,6 +264,7 @@ def format Branch(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch19(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -257,6 +275,7 @@ def format Branch19(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch22(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -267,6 +286,7 @@ def format Branch22(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch30(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -277,6 +297,7 @@ def format Branch30(code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchSplit(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index 401af2e51..881154b67 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -62,6 +62,21 @@ output header {{
};
/**
+ * Base class for 11 bit immediate integer operations.
+ */
+ class IntOpImm11 : public IntOpImm
+ {
+ protected:
+ // Constructor
+ IntOpImm11(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ IntOpImm(mnem, _machInst, __opClass)
+ {
+ imm = sign_ext(SIMM11, 11);
+ }
+ };
+
+ /**
* Base class for 13 bit immediate integer operations.
*/
class IntOpImm13 : public IntOpImm
@@ -271,14 +286,22 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
- CcrIccN = (Rd >> 63) & 1;
- CcrIccZ = (Rd == 0);
- CcrXccN = (Rd >> 31) & 1;
- CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrIccN = (Rd >> 31) & 1;
+ CcrIccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrXccN = (Rd >> 63) & 1;
+ CcrXccZ = (Rd == 0);
CcrIccV = %(ivValue)s;
CcrIccC = %(icValue)s;
CcrXccV = %(xvValue)s;
CcrXccC = %(xcValue)s;
+ DPRINTF(Sparc, "in = %%d\\n", CcrIccN);
+ DPRINTF(Sparc, "iz = %%d\\n", CcrIccZ);
+ DPRINTF(Sparc, "xn = %%d\\n", CcrXccN);
+ DPRINTF(Sparc, "xz = %%d\\n", CcrXccZ);
+ DPRINTF(Sparc, "iv = %%d\\n", CcrIccV);
+ DPRINTF(Sparc, "ic = %%d\\n", CcrIccC);
+ DPRINTF(Sparc, "xv = %%d\\n", CcrXccV);
+ DPRINTF(Sparc, "xc = %%d\\n", CcrXccC);
'''
}};
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index e15349c7b..12dae57e5 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -30,8 +30,9 @@ output header {{
// Constructor
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- Mem(mnem, _machInst, __opClass), imm(SIMM13)
+ Mem(mnem, _machInst, __opClass)
{
+ imm = sign_ext(SIMM13, 13);
}
std::string generateDisassembly(Addr pc,
@@ -84,7 +85,10 @@ output decoder {{
}
ccprintf(response, "[ ");
printReg(response, _srcRegIdx[!save ? 0 : 1]);
- ccprintf(response, " + 0x%x ]", imm);
+ if(imm >= 0)
+ ccprintf(response, " + 0x%x ]", imm);
+ else
+ ccprintf(response, " + -0x%x ]", -imm);
if(load)
{
ccprintf(response, ", ");
@@ -104,6 +108,7 @@ def template MemExecute {{
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
%(load)s;
%(code)s;
%(store)s;
@@ -126,7 +131,7 @@ let {{
def doMemFormat(code, load, store, name, Name, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
- addrCalcImm = 'EA = Rs1 + SIMM13;'
+ addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem', code,
opt_flags, ("ea_code", addrCalcReg),
("load", load), ("store", store))
diff --git a/arch/sparc/linux/linux.cc b/arch/sparc/linux/linux.cc
new file mode 100644
index 000000000..c7ed29358
--- /dev/null
+++ b/arch/sparc/linux/linux.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003-2005 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 "arch/sparc/linux/linux.hh"
+
+// open(2) flags translation table
+OpenFlagTransTable SparcLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+ { SparcLinux::TGT_O_RDONLY, _O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, _O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, _O_RDWR },
+ { SparcLinux::TGT_O_APPEND, _O_APPEND },
+ { SparcLinux::TGT_O_CREAT, _O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, _O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { SparcLinux::TGT_O_SYNC, _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+ { SparcLinux::TGT_O_RDONLY, O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, O_RDWR },
+ { SparcLinux::TGT_O_APPEND, O_APPEND },
+ { SparcLinux::TGT_O_CREAT, O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, O_EXCL },
+ { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
+ { SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { SparcLinux::TGT_O_SYNC, O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int SparcLinux::NUM_OPEN_FLAGS =
+ (sizeof(SparcLinux::openFlagTable)/sizeof(SparcLinux::openFlagTable[0]));
+
diff --git a/arch/sparc/linux/linux.hh b/arch/sparc/linux/linux.hh
new file mode 100644
index 000000000..1b31f67b0
--- /dev/null
+++ b/arch/sparc/linux/linux.hh
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MIPS_MIPS_LINUX_HH
+#define __MIPS_MIPS_LINUX_HH
+
+#include "kern/linux/linux.hh"
+
+class SparcLinux : public Linux
+{
+ public:
+
+ static OpenFlagTransTable openFlagTable[];
+
+ static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
+ static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
+ static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+
+ static const int NUM_OPEN_FLAGS;
+
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+};
+
+#endif
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index ca85a6d2d..71be6a83a 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -98,7 +98,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
- /* 5 */ SyscallDesc("open", openFunc<Linux>),
+ /* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
/* 8 */ SyscallDesc("creat", unimplementedFunc),
@@ -155,7 +155,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
- /* 62 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
/* 63 */ SyscallDesc("fstat64", unimplementedFunc),
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
/* 65 */ SyscallDesc("msync", unimplementedFunc),
@@ -164,9 +164,9 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
/* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
- /* 71 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
- /* 73 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", unimplementedFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
@@ -281,7 +281,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 185 */ SyscallDesc("setpgid", unimplementedFunc),
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 187 */ SyscallDesc("tkill", unimplementedFunc),
- /* 188 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 188 */ SyscallDesc("exit_group", exitFunc),
/* 189 */ SyscallDesc("uname", unameFunc),
/* 190 */ SyscallDesc("init_module", unimplementedFunc),
/* 191 */ SyscallDesc("personality", unimplementedFunc),
diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh
index 38ddd68b9..23ce66d02 100644
--- a/arch/sparc/linux/process.hh
+++ b/arch/sparc/linux/process.hh
@@ -29,6 +29,7 @@
#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__
+#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc
index 44f2c5984..7f2b0d40a 100644
--- a/arch/sparc/process.cc
+++ b/arch/sparc/process.cc
@@ -54,7 +54,7 @@ SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
if (objFile->getArch() != ObjectFile::SPARC)
- fatal("Object file does not match architecture.");
+ fatal("Object file with arch %x does not match architecture %x.", objFile->getArch(), ObjectFile::SPARC);
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
process = new SparcLinuxProcess(nm, objFile, system,
@@ -85,11 +85,11 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
- stack_base = ((Addr)0x80000000000);
+ stack_base = ((Addr)0x80000000000ULL);
// Set up region for mmaps. Tru64 seems to start just above 0 and
// grow up from there.
- mmap_start = mmap_end = 0x10000;
+ mmap_start = mmap_end = 0x800000;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -135,6 +135,14 @@ SparcLiveProcess::startup()
execContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0);
}
+m5_auxv_t buildAuxVect(int64_t type, int64_t val)
+{
+ m5_auxv_t result;
+ result.a_type = TheISA::htog(type);
+ result.a_val = TheISA::htog(val);
+ return result;
+}
+
void
SparcLiveProcess::argsInit(int intSize, int pageSize)
{
@@ -145,10 +153,75 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
// load object file into target memory
objFile->loadSections(initVirtMem);
+ //These are the auxilliary vector types
+ enum auxTypes
+ {
+ SPARC_AT_HWCAP = 16,
+ SPARC_AT_PAGESZ = 6,
+ SPARC_AT_CLKTCK = 17,
+ SPARC_AT_PHDR = 3,
+ SPARC_AT_PHENT = 4,
+ SPARC_AT_PHNUM = 5,
+ SPARC_AT_BASE = 7,
+ SPARC_AT_FLAGS = 8,
+ SPARC_AT_ENTRY = 9,
+ SPARC_AT_UID = 11,
+ SPARC_AT_EUID = 12,
+ SPARC_AT_GID = 13,
+ SPARC_AT_EGID = 14
+ };
+
+ enum hardwareCaps
+ {
+ M5_HWCAP_SPARC_FLUSH = 1,
+ M5_HWCAP_SPARC_STBAR = 2,
+ M5_HWCAP_SPARC_SWAP = 4,
+ M5_HWCAP_SPARC_MULDIV = 8,
+ M5_HWCAP_SPARC_V9 = 16,
+ //This one should technically only be set
+ //if there is a cheetah or cheetah_plus tlb,
+ //but we'll use it all the time
+ M5_HWCAP_SPARC_ULTRA3 = 32
+ };
+
+ const int64_t hwcap =
+ M5_HWCAP_SPARC_FLUSH |
+ M5_HWCAP_SPARC_STBAR |
+ M5_HWCAP_SPARC_SWAP |
+ M5_HWCAP_SPARC_MULDIV |
+ M5_HWCAP_SPARC_V9 |
+ M5_HWCAP_SPARC_ULTRA3;
+
+ //Setup the auxilliary vectors. These will already have
+ //endian conversion.
+ auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
+ //This would work, but the entry point is a protected member
+ //auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
+ auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
+ //This is the address of the elf "interpreter", which I don't
+ //think we currently set up. It should be set to 0 (I think)
+ //auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
+ //This is the number of headers which were in the original elf
+ //file. This information isn't avaibale by this point.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
+ //This is the size of a program header entry. This isn't easy
+ //to compute here.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
+ //This is should be set to load_addr (whatever that is) +
+ //e_phoff. I think it's a pointer to the program headers.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
+ //This should be easy to get right, but I won't set it for now
+ //auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
+ auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+
//Figure out how big the initial stack needs to be
- int aux_data_size = 0;
- //Figure out the aux_data_size?
+ //Each auxilliary vector is two 8 byte words
+ int aux_data_size = 2 * intSize * auxv.size();
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
@@ -198,8 +271,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
Addr aux_data_base = stack_base - aux_data_size - info_block_padding;
Addr env_data_base = aux_data_base - env_data_size;
Addr arg_data_base = env_data_base - arg_data_size;
- Addr aux_array_base = arg_data_base - aux_array_size;
- Addr envp_array_base = aux_array_base - envp_array_size;
+ Addr auxv_array_base = arg_data_base - aux_array_size;
+ Addr envp_array_base = auxv_array_base - envp_array_size;
Addr argv_array_base = envp_array_base - argv_array_size;
Addr argc_base = argv_array_base - argc_size;
Addr window_save_base = argc_base - window_save_size;
@@ -208,24 +281,34 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
DPRINTF(Sparc, "0x%x - aux data\n", aux_data_base);
DPRINTF(Sparc, "0x%x - env data\n", env_data_base);
DPRINTF(Sparc, "0x%x - arg data\n", arg_data_base);
- DPRINTF(Sparc, "0x%x - aux array\n", aux_array_base);
- DPRINTF(Sparc, "0x%x - env array\n", envp_array_base);
- DPRINTF(Sparc, "0x%x - arg array\n", argv_array_base);
+ DPRINTF(Sparc, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Sparc, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Sparc, "0x%x - argv array\n", argv_array_base);
DPRINTF(Sparc, "0x%x - argc \n", argc_base);
DPRINTF(Sparc, "0x%x - window save\n", window_save_base);
DPRINTF(Sparc, "0x%x - stack min\n", stack_min);
// write contents to stack
uint64_t argc = argv.size();
-
- //Copy the aux stuff? For now just put in the null vect
+ uint64_t guestArgc = TheISA::htog(argc);
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
const uint64_t zero = 0;
- initVirtMem->writeBlob(aux_array_base, (uint8_t*)&zero, 2 * intSize);
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
- initVirtMem->writeBlob(argc_base, (uint8_t*)&argc, intSize);
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
execContexts[0]->setIntReg(ArgumentReg0, argc);
execContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh
index 7b2aec7b9..c177f20a5 100644
--- a/arch/sparc/process.hh
+++ b/arch/sparc/process.hh
@@ -36,18 +36,19 @@
class ObjectFile;
class System;
+typedef struct
+{
+ int64_t a_type;
+ union {
+ int64_t a_val;
+ Addr a_ptr;
+ Addr a_fcn;
+ };
+} m5_auxv_t;
+
class SparcLiveProcess : public LiveProcess
{
protected:
- typedef struct
- {
- int64_t a_type;
- union {
- int64_t a_val;
- Addr a_ptr;
- Addr a_fcn;
- };
- } m5_auxv_t;
static const Addr StackBias = 2047;
diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh
index 744d51771..5169a332f 100644
--- a/arch/sparc/regfile.hh
+++ b/arch/sparc/regfile.hh
@@ -140,7 +140,16 @@ namespace SparcISA
DPRINTF(Sparc, "Now using %s globals",
useAlt ? "alternate" : "regular");
regView[Globals] = useAlt ? altGlobals : regGlobals;
- offset[Globals] = useAlt ? AltGlobalOffset : RegGlobalOffset;
+
+ // You have not included an out-of-class definition of your static
+ // members. See [9.4.2]/4 and about a billion gcc bug reports. If
+ // statements get around the problem through some magic, and than
+ // seems nicer that putting a definition of them in a c file
+ // somewhere.
+ if (useAlt)
+ offset[Globals] = AltGlobalOffset;
+ else
+ offset[Globals] = RegGlobalOffset;
}
void serialize(std::ostream &os);
diff --git a/arch/sparc/system.cc b/arch/sparc/system.cc
new file mode 100644
index 000000000..1e2882607
--- /dev/null
+++ b/arch/sparc/system.cc
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2002-2006 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 "arch/sparc/system.hh"
+#include "arch/vtophys.hh"
+#include "base/remote_gdb.hh"
+#include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
+#include "base/trace.hh"
+#include "mem/physical.hh"
+#include "sim/byteswap.hh"
+#include "sim/builder.hh"
+
+
+using namespace BigEndianGuest;
+
+SparcSystem::SparcSystem(Params *p)
+ : System(p)
+{
+ resetSymtab = new SymbolTable;
+ hypervisorSymtab = new SymbolTable;
+ openbootSymtab = new SymbolTable;
+
+
+ /**
+ * Load the boot code, and hypervisor into memory.
+ */
+ // Read the reset binary
+ reset = createObjectFile(params()->reset_bin);
+ if (reset == NULL)
+ fatal("Could not load reset binary %s", params()->reset_bin);
+
+ // Read the openboot binary
+ openboot = createObjectFile(params()->openboot_bin);
+ if (openboot == NULL)
+ fatal("Could not load openboot bianry %s", params()->openboot_bin);
+
+ // Read the hypervisor binary
+ hypervisor = createObjectFile(params()->hypervisor_bin);
+ if (hypervisor == NULL)
+ fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
+
+
+ // Load reset binary into memory
+ reset->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+ // Load the openboot binary
+ openboot->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+ // Load the hypervisor binary
+ hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask);
+
+ // load symbols
+ if (!reset->loadGlobalSymbols(reset))
+ panic("could not load reset symbols\n");
+
+ if (!openboot->loadGlobalSymbols(openbootSymtab))
+ panic("could not load openboot symbols\n");
+
+ if (!hypervisor->loadLocalSymbols(hypervisorSymtab))
+ panic("could not load hypervisor symbols\n");
+
+ // load symbols into debug table
+ if (!reset->loadGlobalSymbols(debugSymbolTable))
+ panic("could not load reset symbols\n");
+
+ if (!openboot->loadGlobalSymbols(debugSymbolTable))
+ panic("could not load openboot symbols\n");
+
+ if (!hypervisor->loadLocalSymbols(debugSymbolTable))
+ panic("could not load hypervisor symbols\n");
+
+
+ // @todo any fixup code over writing data in binaries on setting break
+ // events on functions should happen here.
+
+}
+
+SparcSystem::~SparcSystem()
+{
+ delete resetSymtab;
+ delete hypervisorSymtab;
+ delete openbootSymtab;
+ delete reset;
+ delete openboot;
+ delete hypervisor;
+}
+
+bool
+SparcSystem::breakpoint()
+{
+ panic("Need to implement");
+}
+
+void
+SparcSystem::serialize(std::ostream &os)
+{
+ System::serialize(os);
+ resetSymtab->serialize("reset_symtab", os);
+ hypervisorSymtab->serialize("hypervisor_symtab", os);
+ openbootSymtab->serialize("openboot_symtab", os);
+}
+
+
+void
+SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
+{
+ System::unserialize(cp,section);
+ resetSymtab->unserialize("reset_symtab", cp, section);
+ hypervisorSymtab->unserialize("hypervisor_symtab", cp, section);
+ openbootSymtab->unserialize("openboot_symtab", cp, section);
+}
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
+
+ SimObjectParam<PhysicalMemory *> physmem;
+
+ Param<std::string> kernel;
+ Param<std::string> reset_bin;
+ Param<std::string> hypervisor_bin;
+ Param<std::string> openboot_bin;
+
+ Param<std::string> boot_osflags;
+ Param<std::string> readfile;
+ Param<unsigned int> init_param;
+
+ Param<bool> bin;
+ VectorParam<std::string> binned_fns;
+ Param<bool> bin_int;
+
+END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
+
+ INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
+ INIT_PARAM(physmem, "phsyical memory"),
+ INIT_PARAM(kernel, "file that contains the kernel code"),
+ INIT_PARAM(reset_bin, "file that contains the reset code"),
+ INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
+ INIT_PARAM(openboot_bin, "file that contains the openboot code"),
+ INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
+ "a"),
+ INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+ INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
+ INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
+ INIT_PARAM_DFLT(bin, "is this system to be binned", false),
+ INIT_PARAM(binned_fns, "functions to be broken down and binned"),
+ INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
+
+END_INIT_SIM_OBJECT_PARAMS(SparcSystem)
+
+CREATE_SIM_OBJECT(SparcSystem)
+{
+ SparcSystem::Params *p = new SparcSystem::Params;
+ p->name = getInstanceName();
+ p->boot_cpu_frequency = boot_cpu_frequency;
+ p->physmem = physmem;
+ p->kernel_path = kernel;
+ p->reset_bin = reset_bin;
+ p->hypervisor_bin = hypervisor_bin;
+ p->openboot_bin = openboot_bin;
+ p->boot_osflags = boot_osflags;
+ p->init_param = init_param;
+ p->readfile = readfile;
+ p->system_type = system_type;
+ p->system_rev = system_rev;
+ p->bin = bin;
+ p->binned_fns = binned_fns;
+ p->bin_int = bin_int;
+ return new SparcSystem(p);
+}
+
+REGISTER_SIM_OBJECT("SparcSystem", SparcSystem)
+
+
diff --git a/arch/sparc/system.hh b/arch/sparc/system.hh
new file mode 100644
index 000000000..27aa8768a
--- /dev/null
+++ b/arch/sparc/system.hh
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_SPARC_SYSTEM_HH__
+#define __ARCH_SPARC_SYSTEM_HH__
+
+#include <string>
+#include <vector>
+
+#include "base/loader/symtab.hh"
+#include "cpu/pc_event.hh"
+#include "kern/system_events.hh"
+#include "sim/sim_object.hh"
+#include "sim/system.hh"
+
+class SparcSystem : public System
+{
+ public:
+ struct Params : public System::Params
+ {
+ std::string reset_bin;
+ std::string hypervison_bin;
+ std::string openboot_bin;
+ std::string boot_osflags;
+ uint64_t system_type;
+ uint64_t system_rev;
+ };
+
+ SparcSystem(Params *p);
+
+ ~SparcaSystem();
+
+ virtual bool breakpoint();
+
+/**
+ * Serialization stuff
+ */
+ public:
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+ /** reset binary symbol table */
+ SymbolTable *resetSymtab;
+
+ /** hypervison binary symbol table */
+ SymbolTable *hypervisorSymtab;
+
+ /** openboot symbol table */
+ SymbolTable *openbootSymtab;
+
+ /** Object pointer for the reset binary */
+ ObjectFile *reset;
+
+ /** Object pointer for the hypervisor code */
+ ObjectFile *hypervisor;
+
+ /** Object pointer for the openboot code */
+ ObjectFile *openboot;
+
+ protected:
+ const Params *params() const { return (const Params *)_params; }
+
+ /** Add a function-based event to reset binary. */
+ template <class T>
+ T *SparcSystem::addResetFuncEvent(const char *lbl)
+ {
+ return addFuncEvent<T>(resetSymtab, lbl);
+ }
+
+ /** Add a function-based event to the hypervisor. */
+ template <class T>
+ T *SparcSystem::addHypervisorFuncEvent(const char *lbl)
+ {
+ return addFuncEvent<T>(hypervisorSymtab, lbl);
+ }
+
+ /** Add a function-based event to the openboot. */
+ template <class T>
+ T *SparcSystem::addOpenbootFuncEvent(const char *lbl)
+ {
+ return addFuncEvent<T>(openbootSymtab, lbl);
+ }
+
+ virtual Addr fixFuncEventAddr(Addr addr);
+
+};
+
+#endif
+
diff --git a/configs/test/fs.py b/configs/test/fs.py
index 6cd4185ed..ce121bd76 100644
--- a/configs/test/fs.py
+++ b/configs/test/fs.py
@@ -139,9 +139,13 @@ class LinuxTsunami(BaseTsunami):
pci_func=0, pci_dev=0, pci_bus=0)
class LinuxAlphaSystem(LinuxAlphaSystem):
- magicbus = Bus()
+ magicbus = Bus(bus_id=0)
+ magicbus2 = Bus(bus_id=1)
+ bridge = Bridge()
physmem = PhysicalMemory(range = AddrRange('128MB'))
- c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus)
+ c0a = Connector(side_a=Parent.magicbus, side_b=Parent.bridge, side_b_name="side_a")
+ c0b = Connector(side_a=Parent.magicbus2, side_b=Parent.bridge, side_b_name="side_b")
+ c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus2)
tsunami = LinuxTsunami()
c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus)
c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus)
@@ -177,7 +181,7 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
read_only=True)
simple_disk = SimpleDisk(disk=Parent.raw_image)
intrctrl = IntrControl()
- cpu = SimpleCPU(mem=Parent.magicbus)
+ cpu = SimpleCPU(mem=Parent.magicbus2)
sim_console = SimConsole(listener=ConsoleListener(port=3456))
kernel = '/z/saidi/work/m5.newmem/build/vmlinux'
pal = binary('ts_osfpal')
diff --git a/configs/test/hello_sparc b/configs/test/hello_sparc
index 7b7302771..e254ae33f 100755
--- a/configs/test/hello_sparc
+++ b/configs/test/hello_sparc
Binary files differ
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 40b506a78..33fe63c26 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -54,6 +54,7 @@
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "kern/kernel_stats.hh"
+#include "mem/packet_impl.hh"
#include "sim/byteswap.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
@@ -631,6 +632,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
data_write_pkt->set(data);
#else
data_write_pkt->reset();
+ data = htog(data);
data_write_pkt->dataStatic(&data);
#endif
data_write_pkt->addr = data_write_req->getPaddr();
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index af585a2e5..945de20af 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -103,6 +103,10 @@ class SimpleCPU : public BaseCPU
virtual void recvStatusChange(Status status);
virtual Packet *recvRetry();
+
+ virtual void getDeviceAddressRanges(AddrRangeList &resp,
+ AddrRangeList &snoop)
+ { resp.clear(); snoop.clear(); }
};
MemObject *mem;
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index e05337bfa..2e46f7be1 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -99,7 +99,7 @@ AlphaConsole::read(Packet &pkt)
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
Addr daddr = pkt.addr - pioAddr;
pkt.allocate();
@@ -191,7 +191,7 @@ AlphaConsole::read(Packet &pkt)
Tick
AlphaConsole::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index 638be9c3d..abdbe5d0a 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -430,7 +430,7 @@ IdeController::read(Packet &pkt)
IdeRegType reg_type;
int disk;
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
pkt.allocate();
if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4)
panic("Bad IDE read size: %d\n", pkt.size);
@@ -518,7 +518,7 @@ IdeController::write(Packet &pkt)
int disk;
uint8_t oldVal, newVal;
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
parseAddr(pkt.addr, offset, channel, reg_type);
diff --git a/dev/io_device.cc b/dev/io_device.cc
index 42b3c382f..24f33d84d 100644
--- a/dev/io_device.cc
+++ b/dev/io_device.cc
@@ -116,7 +116,13 @@ DmaPort::recvTiming(Packet &pkt)
DmaReqState *state;
state = (DmaReqState*)pkt.senderState;
state->completionEvent->schedule(pkt.time - pkt.req->getTime());
+ delete pkt.req;
+ delete &pkt;
+ } else {
+ delete pkt.req;
+ delete &pkt;
}
+
return Success;
}
@@ -203,7 +209,7 @@ DmaPort::sendDma(Packet *pkt)
if (state == Timing) {
if (sendTiming(pkt) == Failure)
transmitList.push_back(&packet);
- } else if (state == Atomic) {*/
+ } else if (state == Atomic) {*/
sendAtomic(*pkt);
if (pkt->senderState) {
DmaReqState *state = (DmaReqState*)pkt->senderState;
diff --git a/dev/io_device.hh b/dev/io_device.hh
index bc0160c46..e492ccf0b 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -31,6 +31,7 @@
#include "base/chunk_generator.hh"
#include "mem/mem_object.hh"
+#include "mem/packet_impl.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
@@ -167,7 +168,7 @@ class DmaPort : public Port
friend class DmaPort;
};
- void sendDma(Packet &pkt);
+ void sendDma(Packet *pkt);
public:
DmaPort(DmaDevice *dev, Platform *p);
diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc
index 8060d1a7c..2f392a41a 100644
--- a/dev/isa_fake.cc
+++ b/dev/isa_fake.cc
@@ -54,7 +54,7 @@ IsaFake::read(Packet &pkt)
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size);
@@ -80,7 +80,7 @@ IsaFake::read(Packet &pkt)
Tick
IsaFake::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size);
pkt.result = Success;
return pioDelay;
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index 02c9bbca4..a2e224ed0 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -493,7 +493,7 @@ NSGigE::read(Packet &pkt)
{
assert(ioEnable);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
pkt.allocate();
//The mask is to give you only the offset into the device register file
@@ -729,7 +729,7 @@ NSGigE::write(Packet &pkt)
DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
daddr, pkt.addr, pkt.size);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register");
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index c3597c486..dfb1d48f6 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -99,7 +99,7 @@ PciConfigAll::read(Packet &pkt)
int func = (daddr >> 8) & 0x7;
int reg = daddr & 0xFF;
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
pkt.allocate();
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr,
@@ -134,7 +134,7 @@ PciConfigAll::read(Packet &pkt)
Tick
PciConfigAll::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
diff --git a/dev/sinic.cc b/dev/sinic.cc
index b91ef83b0..b5b6c6cf5 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -321,7 +321,7 @@ Device::read(Packet &pkt)
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
pkt.allocate();
if (!regValid(raddr))
@@ -408,7 +408,7 @@ Device::write(Packet &pkt)
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
if (!regValid(raddr))
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index f35c34138..7b9032f6e 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -76,7 +76,7 @@ TsunamiCChip::read(Packet &pkt)
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
Addr regnum = (pkt.addr - pioAddr) >> 6;
Addr daddr = (pkt.addr - pioAddr);
@@ -182,7 +182,7 @@ TsunamiCChip::read(Packet &pkt)
Tick
TsunamiCChip::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index ed526bdde..0efcc1028 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -441,7 +441,7 @@ TsunamiIO::read(Packet &pkt)
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
Addr daddr = pkt.addr - pioAddr;
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr,
@@ -505,7 +505,7 @@ TsunamiIO::read(Packet &pkt)
Tick
TsunamiIO::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc
index 05b480cb8..1323a0548 100644
--- a/dev/tsunami_pchip.cc
+++ b/dev/tsunami_pchip.cc
@@ -71,7 +71,7 @@ TsunamiPChip::read(Packet &pkt)
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
pkt.allocate();
Addr daddr = (pkt.addr - pioAddr) >> 6;;
assert(pkt.size == sizeof(uint64_t));
@@ -151,7 +151,7 @@ TsunamiPChip::read(Packet &pkt)
Tick
TsunamiPChip::write(Packet &pkt)
{
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
assert(pkt.result == Unknown);
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
diff --git a/dev/uart8250.cc b/dev/uart8250.cc
index 84885456f..15752c735 100644
--- a/dev/uart8250.cc
+++ b/dev/uart8250.cc
@@ -114,7 +114,7 @@ Uart8250::read(Packet &pkt)
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
assert(pkt.size == 1);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
Addr daddr = pkt.addr - pioAddr;
pkt.allocate();
@@ -198,7 +198,7 @@ Uart8250::write(Packet &pkt)
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
assert(pkt.size == 1);
- pkt.time = curTick + pioDelay;
+ pkt.time += pioDelay;
Addr daddr = pkt.addr - pioAddr;
DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get<uint8_t>());
diff --git a/mem/bridge.cc b/mem/bridge.cc
new file mode 100644
index 000000000..d358ef77b
--- /dev/null
+++ b/mem/bridge.cc
@@ -0,0 +1,263 @@
+
+/*
+ * Copyright (c) 2006 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.
+ */
+
+/**
+ * @file Definition of a simple bus bridge without buffering.
+ */
+
+
+#include "base/trace.hh"
+#include "mem/bridge.hh"
+#include "sim/builder.hh"
+
+void
+Bridge::init()
+{
+ // Make sure that both sides are connected to.
+ if (sideA == NULL || sideB == NULL)
+ panic("Both ports of bus bridge are not connected to a bus.\n");
+}
+
+
+/** Function called by the port when the bus is recieving a Timing
+ * transaction.*/
+bool
+Bridge::recvTiming(Packet &pkt, Side id)
+{
+ if (blockedA && id == SideA)
+ return false;
+ if (blockedB && id == SideB)
+ return false;
+
+ if (delay) {
+ if (!sendEvent.scheduled())
+ sendEvent.schedule(curTick + delay);
+ if (id == SideA) {
+ inboundA.push_back(std::make_pair<Packet*, Tick>(&pkt, curTick));
+ blockCheck(SideA);
+ } else {
+ inboundB.push_back(std::make_pair<Packet*, Tick>(&pkt, curTick));
+ blockCheck(SideB);
+ }
+ } else {
+ if (id == SideB) {
+ sideA->sendPkt(pkt);
+ blockCheck(SideB);
+ } else {
+ sideB->sendPkt(pkt);
+ blockCheck(SideA);
+ }
+ }
+ return true;
+
+}
+
+void
+Bridge::blockCheck(Side id)
+{
+ /* Check that we still have buffer space available. */
+ if (id == SideB) {
+ if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) {
+ sideB->sendStatusChange(Port::Blocked);
+ blockedB = true;
+ } else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) {
+ sideB->sendStatusChange(Port::Unblocked);
+ blockedB = false;
+ }
+ } else {
+ if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) {
+ sideA->sendStatusChange(Port::Blocked);
+ blockedA = true;
+ } else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) {
+ sideA->sendStatusChange(Port::Unblocked);
+ blockedA = false;
+ }
+ }
+}
+
+void Bridge::timerEvent()
+{
+ Tick t = 0;
+
+ assert(inboundA.size() || inboundB.size());
+ if (inboundA.size()) {
+ while (inboundA.front().second <= curTick + delay){
+ sideB->sendPkt(inboundA.front());
+ inboundA.pop_front();
+ }
+ if (inboundA.size())
+ t = inboundA.front().second + delay;
+ }
+ if (inboundB.size()) {
+ while (inboundB.front().second <= curTick + delay){
+ sideB->sendPkt(inboundA.front());
+ inboundB.pop_front();
+ }
+ if (inboundB.size())
+ if (t == 0)
+ t = inboundB.front().second + delay;
+ else
+ t = std::min(t,inboundB.front().second + delay);
+ } else {
+ panic("timerEvent() called but nothing to do?");
+ }
+
+ if (t != 0)
+ sendEvent.schedule(t);
+}
+
+
+void
+Bridge::BridgePort::sendPkt(Packet &pkt)
+{
+ if (!sendTiming(pkt))
+ outbound.push_back(std::make_pair<Packet*,Tick>(&pkt, curTick));
+}
+
+void
+Bridge::BridgePort::sendPkt(std::pair<Packet*, Tick> p)
+{
+ if (!sendTiming(*p.first))
+ outbound.push_back(p);
+}
+
+
+Packet *
+Bridge::BridgePort::recvRetry()
+{
+ Packet *pkt;
+ assert(outbound.size() > 0);
+ assert(outbound.front().second >= curTick + bridge->delay);
+ pkt = outbound.front().first;
+ outbound.pop_front();
+ bridge->blockCheck(side);
+ return pkt;
+}
+
+/** Function called by the port when the bus is recieving a Atomic
+ * transaction.*/
+Tick
+Bridge::recvAtomic(Packet &pkt, Side id)
+{
+ pkt.time += delay;
+
+ if (id == SideA)
+ return sideB->sendAtomic(pkt);
+ else
+ return sideA->sendAtomic(pkt);
+}
+
+/** Function called by the port when the bus is recieving a Functional
+ * transaction.*/
+void
+Bridge::recvFunctional(Packet &pkt, Side id)
+{
+ pkt.time += delay;
+ std::list<std::pair<Packet*, Tick> >::iterator i;
+ bool pktContinue = true;
+
+ for(i = inboundA.begin(); i != inboundA.end(); ++i) {
+ if (pkt.intersect(i->first)) {
+ pktContinue &= fixPacket(pkt, *i->first);
+ }
+ }
+
+ for(i = inboundB.begin(); i != inboundB.end(); ++i) {
+ if (pkt.intersect(i->first)) {
+ pktContinue &= fixPacket(pkt, *i->first);
+ }
+ }
+
+ for(i = sideA->outbound.begin(); i != sideA->outbound.end(); ++i) {
+ if (pkt.intersect(i->first)) {
+ pktContinue &= fixPacket(pkt, *i->first);
+ }
+ }
+
+ for(i = sideB->outbound.begin(); i != sideB->outbound.end(); ++i) {
+ if (pkt.intersect(i->first)) {
+ pktContinue &= fixPacket(pkt, *i->first);
+ }
+ }
+
+ if (pktContinue) {
+ if (id == SideA)
+ sideB->sendFunctional(pkt);
+ else
+ sideA->sendFunctional(pkt);
+ }
+}
+
+/** Function called by the port when the bus is recieving a status change.*/
+void
+Bridge::recvStatusChange(Port::Status status, Side id)
+{
+ if (status == Port::Blocked || status == Port::Unblocked)
+ return ;
+
+ if (id == SideA)
+ sideB->sendStatusChange(status);
+ else
+ sideA->sendStatusChange(status);
+}
+
+void
+Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id)
+{
+ if (id == SideA)
+ sideB->getPeerAddressRanges(resp, snoop);
+ else
+ sideA->getPeerAddressRanges(resp, snoop);
+}
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge)
+
+ Param<int> queue_size_a;
+ Param<int> queue_size_b;
+ Param<Tick> delay;
+ Param<bool> write_ack;
+
+END_DECLARE_SIM_OBJECT_PARAMS(Bridge)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge)
+
+ INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"),
+ INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"),
+ INIT_PARAM(delay, "The miminum delay to cross this bridge"),
+ INIT_PARAM(write_ack, "Acknowledge any writes that are received.")
+
+END_INIT_SIM_OBJECT_PARAMS(Bridge)
+
+CREATE_SIM_OBJECT(Bridge)
+{
+ return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay,
+ write_ack);
+}
+
+REGISTER_SIM_OBJECT("Bridge", Bridge)
diff --git a/mem/bridge.hh b/mem/bridge.hh
new file mode 100644
index 000000000..6bd4d81ab
--- /dev/null
+++ b/mem/bridge.hh
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+/**
+ * @file Decleration of a simple bus bridge object with no buffering
+ */
+
+#ifndef __MEM_BRIDGE_HH__
+#define __MEM_BRIDGE_HH__
+
+#include <string>
+#include <list>
+#include <inttypes.h>
+#include <queue>
+
+
+#include "mem/mem_object.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
+#include "sim/eventq.hh"
+
+class Bridge : public MemObject
+{
+ public:
+ enum Side
+ {
+ SideA,
+ SideB
+ };
+
+ protected:
+ /** Function called by the port when the bus is recieving a Timing
+ transaction.*/
+ bool recvTiming(Packet &pkt, Side id);
+
+ /** Function called by the port when the bus is recieving a Atomic
+ transaction.*/
+ Tick recvAtomic(Packet &pkt, Side id);
+
+ /** Function called by the port when the bus is recieving a Functional
+ transaction.*/
+ void recvFunctional(Packet &pkt, Side id);
+
+ /** Function called by the port when the bus is recieving a status change.*/
+ void recvStatusChange(Port::Status status, Side id);
+
+ /** Process address range request.
+ * @param resp addresses that we can respond to
+ * @param snoop addresses that we would like to snoop
+ * @param id ide of the busport that made the request.
+ */
+ void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id);
+
+
+ /** Event that the SendEvent calls when it fires. This code must reschedule
+ * the send event as required. */
+ void timerEvent();
+
+ /** Decleration of the buses port type, one will be instantiated for each
+ of the interfaces connecting to the bus. */
+ class BridgePort : public Port
+ {
+ /** A pointer to the bus to which this port belongs. */
+ Bridge *bridge;
+
+ /** A id to keep track of the intercafe ID this port is connected to. */
+ Bridge::Side side;
+
+ public:
+
+ /** Constructor for the BusPort.*/
+ BridgePort(Bridge *_bridge, Side _side)
+ : bridge(_bridge), side(_side)
+ { }
+
+ int numQueued() { return outbound.size(); }
+
+ protected:
+ /** Data this is waiting to be transmitted. */
+ std::list<std::pair<Packet*, Tick> > outbound;
+
+ void sendPkt(Packet &pkt);
+ void sendPkt(std::pair<Packet*, Tick> p);
+
+ /** When reciving a timing request from the peer port,
+ pass it to the bridge. */
+ virtual bool recvTiming(Packet &pkt)
+ { return bridge->recvTiming(pkt, side); }
+
+ /** When reciving a retry request from the peer port,
+ pass it to the bridge. */
+ virtual Packet* recvRetry();
+
+ /** When reciving a Atomic requestfrom the peer port,
+ pass it to the bridge. */
+ virtual Tick recvAtomic(Packet &pkt)
+ { return bridge->recvAtomic(pkt, side); }
+
+ /** When reciving a Functional request from the peer port,
+ pass it to the bridge. */
+ virtual void recvFunctional(Packet &pkt)
+ { bridge->recvFunctional(pkt, side); }
+
+ /** When reciving a status changefrom the peer port,
+ pass it to the bridge. */
+ virtual void recvStatusChange(Status status)
+ { bridge->recvStatusChange(status, side); }
+
+ /** When reciving a address range request the peer port,
+ pass it to the bridge. */
+ virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+ { bridge->addressRanges(resp, snoop, side); }
+
+ friend class Bridge;
+ };
+
+ class SendEvent : public Event
+ {
+ Bridge *bridge;
+
+ SendEvent(Bridge *b)
+ : Event(&mainEventQueue), bridge(b) {}
+
+ virtual void process() { bridge->timerEvent(); }
+
+ virtual const char *description() { return "bridge delay event"; }
+ friend class Bridge;
+ };
+
+ SendEvent sendEvent;
+
+ /** Sides of the bus bridges. */
+ BridgePort* sideA;
+ BridgePort* sideB;
+
+ /** inbound queues on both sides. */
+ std::list<std::pair<Packet*, Tick> > inboundA;
+ std::list<std::pair<Packet*, Tick> > inboundB;
+
+ /** The size of the queue for data coming into side a */
+ int queueSizeA;
+ int queueSizeB;
+
+ /* if the side is blocked or not. */
+ bool blockedA;
+ bool blockedB;
+
+ /** Miminum delay though this bridge. */
+ Tick delay;
+
+ /** If this bridge should acknowledge writes. */
+ bool ackWrites;
+
+ public:
+
+ /** A function used to return the port associated with this bus object. */
+ virtual Port *getPort(const std::string &if_name)
+ {
+ if (if_name == "side_a") {
+ if (sideA != NULL)
+ panic("bridge side a already connected to.");
+ sideA = new BridgePort(this, SideA);
+ return sideA;
+ } else if (if_name == "side_b") {
+ if (sideB != NULL)
+ panic("bridge side b already connected to.");
+ sideB = new BridgePort(this, SideB);
+ return sideB;
+ } else
+ return NULL;
+ }
+
+ virtual void init();
+
+ Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack)
+ : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL),
+ queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false),
+ delay(_delay), ackWrites(write_ack)
+ {}
+
+ /** Check if the port should block/unblock after recieving/sending a packet.
+ * */
+ void blockCheck(Side id);
+
+ friend class Bridge::SendEvent;
+
+};
+
+#endif //__MEM_BUS_HH__
diff --git a/mem/bus.cc b/mem/bus.cc
index 86e834894..acc941434 100644
--- a/mem/bus.cc
+++ b/mem/bus.cc
@@ -35,13 +35,22 @@
#include "mem/bus.hh"
#include "sim/builder.hh"
+/** Get the ranges of anyone that we are connected to. */
+void
+Bus::init()
+{
+ std::vector<Port*>::iterator intIter;
+ for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
+ (*intIter)->sendStatusChange(Port::RangeChange);
+}
+
+
/** Function called by the port when the bus is recieving a Timing
* transaction.*/
bool
Bus::recvTiming(Packet &pkt, int id)
{
-
- panic("I need to be implemented, but not right now.");
+ return findPort(pkt.addr, id)->sendTiming(pkt);
}
Port *
@@ -90,10 +99,13 @@ Bus::recvFunctional(Packet &pkt, int id)
void
Bus::recvStatusChange(Port::Status status, int id)
{
+ DPRINTF(Bus, "Bus %d recieved status change from device id %d\n",
+ busId, id);
assert(status == Port::RangeChange &&
"The other statuses need to be implemented.");
assert(id < interfaces.size() && id >= 0);
+ int x;
Port *port = interfaces[id];
AddrRangeList ranges;
AddrRangeList snoops;
@@ -122,12 +134,31 @@ Bus::recvStatusChange(Port::Status status, int id)
portList.push_back(dm);
}
DPRINTF(MMU, "port list has %d entries\n", portList.size());
+
+ // tell all our peers that our address range has changed.
+ // Don't tell the device that caused this change, it already knows
+ for (x = 0; x < interfaces.size(); x++)
+ if (x != id)
+ interfaces[x]->sendStatusChange(Port::RangeChange);
}
void
-Bus::BusPort::addressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
{
- panic("I'm not implemented.\n");
+ std::vector<DevMap>::iterator portIter;
+
+ resp.clear();
+ snoop.clear();
+
+ DPRINTF(Bus, "Bus id %d recieved address range request returning\n",
+ busId);
+ for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
+ if (portIter->portId != id) {
+ resp.push_back(portIter->range);
+ DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start,
+ portIter->range.end);
+ }
+ }
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
@@ -137,12 +168,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
END_DECLARE_SIM_OBJECT_PARAMS(Bus)
BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
- INIT_PARAM(bus_id, "junk bus id")
-END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
+ INIT_PARAM(bus_id, "a globally unique bus id")
+END_INIT_SIM_OBJECT_PARAMS(Bus)
CREATE_SIM_OBJECT(Bus)
{
- return new Bus(getInstanceName());
+ return new Bus(getInstanceName(), bus_id);
}
REGISTER_SIM_OBJECT("Bus", Bus)
diff --git a/mem/bus.hh b/mem/bus.hh
index fad44aba5..de9259a90 100644
--- a/mem/bus.hh
+++ b/mem/bus.hh
@@ -45,6 +45,9 @@
class Bus : public MemObject
{
+ /** a globally unique id for this bus. */
+ int busId;
+
struct DevMap {
int portId;
Range<Addr> range;
@@ -77,6 +80,14 @@ class Bus : public MemObject
Port *
Bus::findPort(Addr addr, int id);
+ /** Process address range request.
+ * @param resp addresses that we can respond to
+ * @param snoop addresses that we would like to snoop
+ * @param id ide of the busport that made the request.
+ */
+ void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id);
+
+
/** Decleration of the buses port type, one will be instantiated for each
of the interfaces connecting to the bus. */
class BusPort : public Port
@@ -120,7 +131,8 @@ class Bus : public MemObject
// downstream from this bus, yes? That is, the union of all
// the 'owned' address ranges of all the other interfaces on
// this bus...
- virtual void addressRanges(AddrRangeList &resp, AddrRangeList &snoop);
+ virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
+ { bus->addressRanges(resp, snoop, id); }
// Hack to make translating port work without changes
virtual int deviceBlockSize() { return 32; }
@@ -141,8 +153,11 @@ class Bus : public MemObject
interfaces.push_back(new BusPort(this, id));
return interfaces.back();
}
- Bus(const std::string &n)
- : MemObject(n) {}
+
+ virtual void init();
+
+ Bus(const std::string &n, int bus_id)
+ : MemObject(n), busId(bus_id) {}
};
diff --git a/mem/packet.cc b/mem/packet.cc
new file mode 100644
index 000000000..ecd2a7be1
--- /dev/null
+++ b/mem/packet.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+/**
+ * @file
+ * Definition of the Packet Class, a packet is a transaction occuring
+ * between a single level of the memory heirarchy (ie L1->L2).
+ */
+#include "base/misc.hh"
+#include "mem/packet.hh"
+
+
+/** delete the data pointed to in the data pointer. Ok to call to matter how
+ * data was allocted. */
+void
+Packet::deleteData() {
+ assert(staticData || dynamicData);
+ if (staticData)
+ return;
+
+ if (arrayData)
+ delete [] data;
+ else
+ delete data;
+}
+
+/** If there isn't data in the packet, allocate some. */
+void
+Packet::allocate() {
+ if (data)
+ return;
+ assert(!staticData);
+ dynamicData = true;
+ arrayData = true;
+ data = new uint8_t[size];
+}
+
+/** Do the packet modify the same addresses. */
+bool
+Packet::intersect(Packet *p) {
+ Addr s1 = addr;
+ Addr e1 = addr + size;
+ Addr s2 = p->addr;
+ Addr e2 = p->addr + p->size;
+
+ if (s1 >= s2 && s1 < e2)
+ return true;
+ if (e1 >= s2 && e1 < e2)
+ return true;
+ return false;
+}
+
+/** Minimally reset a packet so something like simple cpu can reuse it. */
+void
+Packet::reset() {
+ result = Unknown;
+ if (dynamicData) {
+ deleteData();
+ dynamicData = false;
+ arrayData = false;
+ time = curTick;
+ }
+}
+
+
+
+
+bool fixPacket(Packet &func, Packet &timing)
+{ panic("Need to implement!"); }
diff --git a/mem/packet.hh b/mem/packet.hh
index 4329094d5..69d00675d 100644
--- a/mem/packet.hh
+++ b/mem/packet.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -142,7 +142,7 @@ struct Packet
Packet()
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
- result(Unknown)
+ time(curTick), result(Unknown)
{}
~Packet()
@@ -150,87 +150,43 @@ struct Packet
/** Minimally reset a packet so something like simple cpu can reuse it. */
- void reset() {
- result = Unknown;
- if (dynamicData) {
- deleteData();
- dynamicData = false;
- arrayData = false;
- }
- }
+ void reset();
/** Set the data pointer to the following value that should not be freed. */
template <typename T>
- void dataStatic(T *p) {
- assert(!dynamicData);
- data = (PacketDataPtr)p;
- staticData = true;
- }
+ void dataStatic(T *p);
/** Set the data pointer to a value that should have delete [] called on it.
*/
template <typename T>
- void dataDynamicArray(T *p) {
- assert(!staticData && !dynamicData);
- data = (PacketDataPtr)p;
- dynamicData = true;
- arrayData = true;
- }
+ void dataDynamicArray(T *p);
/** set the data pointer to a value that should have delete called on it. */
template <typename T>
- void dataDynamic(T *p) {
- assert(!staticData && !dynamicData);
- data = (PacketDataPtr)p;
- dynamicData = true;
- arrayData = false;
- }
+ void dataDynamic(T *p);
/** return the value of what is pointed to in the packet. */
template <typename T>
- T get() {
- assert(staticData || dynamicData);
- assert(sizeof(T) <= size);
- return *(T*)data;
- }
+ T get();
/** get a pointer to the data ptr. */
template <typename T>
- T* getPtr() {
- assert(staticData || dynamicData);
- return (T*)data;
- }
-
+ T* getPtr();
/** set the value in the data pointer to v. */
template <typename T>
- void set(T v) {
- assert(sizeof(T) <= size);
- *(T*)data = v;
- }
+ void set(T v);
/** delete the data pointed to in the data pointer. Ok to call to matter how
* data was allocted. */
- void deleteData() {
- assert(staticData || dynamicData);
- if (staticData)
- return;
-
- if (arrayData)
- delete [] data;
- else
- delete data;
- }
+ void deleteData();
/** If there isn't data in the packet, allocate some. */
- void allocate() {
- if (data)
- return;
- assert(!staticData);
- dynamicData = true;
- arrayData = true;
- data = new uint8_t[size];
- }
+ void allocate();
+
+ /** Do the packet modify the same addresses. */
+ bool intersect(Packet *p);
};
+bool fixPacket(Packet &func, Packet &timing);
#endif //__MEM_PACKET_HH
diff --git a/mem/physical.cc b/mem/physical.cc
index 02a48b22b..a9cefc70b 100644
--- a/mem/physical.cc
+++ b/mem/physical.cc
@@ -40,6 +40,7 @@
#include "base/misc.hh"
#include "config/full_system.hh"
+#include "mem/packet_impl.hh"
#include "mem/physical.hh"
#include "sim/host.hh"
#include "sim/builder.hh"
@@ -181,7 +182,6 @@ PhysicalMemory::getPort(const std::string &if_name)
void
PhysicalMemory::recvStatusChange(Port::Status status)
{
- panic("??");
}
PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory)
diff --git a/mem/port.hh b/mem/port.hh
index 9557f654c..2ab2806c9 100644
--- a/mem/port.hh
+++ b/mem/port.hh
@@ -227,7 +227,7 @@ class FunctionalPort : public Port
virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); }
- virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");}
+ virtual void recvStatusChange(Status status) {}
template <typename T>
inline void write(Addr addr, T d)
diff --git a/python/m5/objects/Bridge.py b/python/m5/objects/Bridge.py
new file mode 100644
index 000000000..ada715ce9
--- /dev/null
+++ b/python/m5/objects/Bridge.py
@@ -0,0 +1,9 @@
+from m5 import *
+from MemObject import MemObject
+
+class Bridge(MemObject):
+ type = 'Bridge'
+ queue_size_a = Param.Int(16, "The number of requests to buffer")
+ queue_size_b = Param.Int(16, "The number of requests to buffer")
+ delay = Param.Latency('0ns', "The latency of this bridge")
+ write_ack = Param.Bool(False, "Should this bridge ack writes")
diff --git a/python/m5/objects/System.py b/python/m5/objects/System.py
index 65b621dff..622b5a870 100644
--- a/python/m5/objects/System.py
+++ b/python/m5/objects/System.py
@@ -9,6 +9,7 @@ class System(SimObject):
init_param = Param.UInt64(0, "numerical value to pass into simulator")
bin = Param.Bool(False, "is this system binned")
binned_fns = VectorParam.String([], "functions broken down and binned")
+ boot_osflags = Param.String("a", "boot flags to pass to the kernel")
kernel = Param.String("file that contains the kernel code")
readfile = Param.String("", "file to read startup script from")
@@ -16,6 +17,5 @@ class AlphaSystem(System):
type = 'AlphaSystem'
console = Param.String("file that contains the console code")
pal = Param.String("file that contains palcode")
- boot_osflags = Param.String("a", "boot flags to pass to the kernel")
system_type = Param.UInt64("Type of system we are emulating")
system_rev = Param.UInt64("Revision of system we are emulating")
diff --git a/sim/system.hh b/sim/system.hh
index 3c2c27bee..7e21bd587 100644
--- a/sim/system.hh
+++ b/sim/system.hh
@@ -155,6 +155,7 @@ class System : public SimObject
#if FULL_SYSTEM
Tick boot_cpu_frequency;
+ std::string boot_osflags;
uint64_t init_param;
bool bin;
std::vector<std::string> binned_fns;