summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2006-04-28 15:41:22 -0400
committerAli Saidi <saidi@eecs.umich.edu>2006-04-28 15:41:22 -0400
commitca8a659394e96a0a0c11693cbaae59e6b027795a (patch)
tree79f9509a48359bbc870ae34ce8b6e2fc6bc027de
parent7bb70e3e30f30c669e475c47b950f0abd24367d0 (diff)
parentb43d1a00fb69015c751fba57d22a6fa94a292f04 (diff)
downloadgem5-ca8a659394e96a0a0c11693cbaae59e6b027795a.tar.xz
Merge zizzer:/bk/newmem
into zeep.pool:/z/saidi/work/m5.newmem --HG-- extra : convert_revision : d6f7c4dd146613eeba39249f2d916a77108bc8c1
-rw-r--r--SConscript8
-rw-r--r--arch/alpha/system.hh1
-rw-r--r--arch/sparc/system.cc200
-rw-r--r--arch/sparc/system.hh114
-rw-r--r--configs/test/fs.py10
-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.hh2
-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.cc37
-rw-r--r--mem/packet.hh18
-rw-r--r--mem/physical.cc1
-rw-r--r--python/m5/objects/Bridge.py9
-rw-r--r--python/m5/objects/System.py2
-rw-r--r--sim/system.hh1
28 files changed, 956 insertions, 42 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/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/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index 3640348a3..252d57206 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..1f4ef4b6e 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -167,7 +167,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..590617f99
--- /dev/null
+++ b/mem/packet.cc
@@ -0,0 +1,37 @@
+/*
+ * 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 "mem/packet.hh"
+
+bool fixPacket(Packet &func, Packet &timing)
+{ panic("Need to implement!"); }
diff --git a/mem/packet.hh b/mem/packet.hh
index 4329094d5..a5bd6bc59 100644
--- a/mem/packet.hh
+++ b/mem/packet.hh
@@ -142,7 +142,7 @@ struct Packet
Packet()
: data(NULL), staticData(false), dynamicData(false), arrayData(false),
- result(Unknown)
+ time(curTick), result(Unknown)
{}
~Packet()
@@ -156,6 +156,7 @@ struct Packet
deleteData();
dynamicData = false;
arrayData = false;
+ time = curTick;
}
}
@@ -231,6 +232,21 @@ struct Packet
arrayData = true;
data = new uint8_t[size];
}
+
+ /** Do the packet modify the same addresses. */
+ bool 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;
+ }
};
+bool fixPacket(Packet &func, Packet &timing);
#endif //__MEM_PACKET_HH
diff --git a/mem/physical.cc b/mem/physical.cc
index 02a48b22b..fd304e63b 100644
--- a/mem/physical.cc
+++ b/mem/physical.cc
@@ -181,7 +181,6 @@ PhysicalMemory::getPort(const std::string &if_name)
void
PhysicalMemory::recvStatusChange(Port::Status status)
{
- panic("??");
}
PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory)
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;