diff options
-rw-r--r-- | SConscript | 8 | ||||
-rw-r--r-- | arch/alpha/system.hh | 1 | ||||
-rw-r--r-- | arch/sparc/system.cc | 200 | ||||
-rw-r--r-- | arch/sparc/system.hh | 114 | ||||
-rw-r--r-- | configs/test/fs.py | 10 | ||||
-rw-r--r-- | cpu/simple/cpu.hh | 4 | ||||
-rw-r--r-- | dev/alpha_console.cc | 4 | ||||
-rw-r--r-- | dev/ide_ctrl.cc | 4 | ||||
-rw-r--r-- | dev/io_device.cc | 8 | ||||
-rw-r--r-- | dev/io_device.hh | 2 | ||||
-rw-r--r-- | dev/isa_fake.cc | 4 | ||||
-rw-r--r-- | dev/ns_gige.cc | 4 | ||||
-rw-r--r-- | dev/pciconfigall.cc | 4 | ||||
-rw-r--r-- | dev/sinic.cc | 4 | ||||
-rw-r--r-- | dev/tsunami_cchip.cc | 4 | ||||
-rw-r--r-- | dev/tsunami_io.cc | 4 | ||||
-rw-r--r-- | dev/tsunami_pchip.cc | 4 | ||||
-rw-r--r-- | dev/uart8250.cc | 4 | ||||
-rw-r--r-- | mem/bridge.cc | 263 | ||||
-rw-r--r-- | mem/bridge.hh | 214 | ||||
-rw-r--r-- | mem/bus.cc | 45 | ||||
-rw-r--r-- | mem/bus.hh | 21 | ||||
-rw-r--r-- | mem/packet.cc | 37 | ||||
-rw-r--r-- | mem/packet.hh | 18 | ||||
-rw-r--r-- | mem/physical.cc | 1 | ||||
-rw-r--r-- | python/m5/objects/Bridge.py | 9 | ||||
-rw-r--r-- | python/m5/objects/System.py | 2 | ||||
-rw-r--r-- | sim/system.hh | 1 |
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 §ion) +{ + 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 §ion); + + /** 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; |