Simple program runs with sendAtomic!
authorSteve Reinhardt <stever@eecs.umich.edu>
Thu, 2 Mar 2006 15:31:48 +0000 (10:31 -0500)
committerSteve Reinhardt <stever@eecs.umich.edu>
Thu, 2 Mar 2006 15:31:48 +0000 (10:31 -0500)
Ignoring returned latency for now.
Refactored loadSections in ObjectFile hierarchy.

base/loader/aout_object.cc:
base/loader/aout_object.hh:
base/loader/ecoff_object.cc:
base/loader/ecoff_object.hh:
base/loader/elf_object.cc:
base/loader/elf_object.hh:
base/loader/object_file.hh:
    Have each section record a pointer to image data.
    This allows us to move common loadSections code into ObjectFile.
base/loader/object_file.cc:
    Have each section record a pointer to image data.
    This allows us to move common loadSections code into ObjectFile.
    Also explicitly load BSS now since we need to allocate the
    translations for it in syscall emulation.
cpu/base.hh:
    Don't need memPort (just pass port in to ExecContext constructor).
cpu/exec_context.cc:
cpu/exec_context.hh:
mem/port.cc:
mem/translating_port.cc:
mem/translating_port.hh:
    Pass syscall emulation Port into constructor instead of
    getting it from BaseCPU.
cpu/simple/cpu.cc:
    Explicitly choose one of three timing models.
    Statically allocate request and packet objects when possible.
    Several more minor bug fixes.
    Works for simple program with SIMPLE_CPU_MEM_IMMEDIATE model now.
    Probably have memory leaks with SIMPLE_CPU_MEM_TIMING (if it works at all).
    Pass syscall emulation Port into constructor instead of
    getting it from BaseCPU.
cpu/simple/cpu.hh:
    Explicitly choose one of three timing models.
    Statically allocate request and packet objects when possible.
    Pass syscall emulation Port into constructor instead of
    getting it from BaseCPU.
mem/physical.cc:
    Set packet result field.

--HG--
extra : convert_revision : 359d0ebe4b4665867f4e26e7394ec0f1d17cfc26

17 files changed:
base/loader/aout_object.cc
base/loader/aout_object.hh
base/loader/ecoff_object.cc
base/loader/ecoff_object.hh
base/loader/elf_object.cc
base/loader/elf_object.hh
base/loader/object_file.cc
base/loader/object_file.hh
cpu/base.hh
cpu/exec_context.cc
cpu/exec_context.hh
cpu/simple/cpu.cc
cpu/simple/cpu.hh
mem/physical.cc
mem/port.cc
mem/translating_port.cc
mem/translating_port.hh

index d1b27120d76005fd591caacf11dd509cb76d9e5b..564898ca39c0fe0e6a8b03a01b3a1a4f8b02ffb1 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "base/loader/aout_object.hh"
 
-#include "mem/translating_port.hh"
 #include "base/loader/symtab.hh"
 
 #include "base/trace.hh"       // for DPRINTF
@@ -64,12 +63,15 @@ AoutObject::AoutObject(const string &_filename, int _fd,
 
     text.baseAddr = N_TXTADDR(*execHdr);
     text.size = execHdr->tsize;
+    text.fileImage = fileData + N_TXTOFF(*execHdr);
 
     data.baseAddr = N_DATADDR(*execHdr);
     data.size = execHdr->dsize;
+    data.fileImage = fileData + N_DATOFF(*execHdr);
 
     bss.baseAddr = N_BSSADDR(*execHdr);
     bss.size = execHdr->bsize;
+    bss.fileImage = NULL;
 
     DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
              text.baseAddr, text.size, data.baseAddr, data.size,
@@ -77,30 +79,6 @@ AoutObject::AoutObject(const string &_filename, int _fd,
 }
 
 
-bool
-AoutObject::loadSections(TranslatingPort *memPort, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    if (text.size != 0)
-        memPort->writeBlobFunctional(textAddr, fileData + N_TXTOFF(*execHdr),
-                                     text.size, true);
-    if (data.size != 0)
-        memPort->writeBlobFunctional(dataAddr, fileData + N_DATOFF(*execHdr),
-                                     data.size, true);
-
-    return true;
-}
-
-
 bool
 AoutObject::loadGlobalSymbols(SymbolTable *symtab)
 {
index 359866dc5d19c05d972d874bfcb05ea964e0019a..aeb710427312c61233e3c7ef6c578db16e24dcbf 100644 (file)
@@ -46,7 +46,6 @@ class AoutObject : public ObjectFile
   public:
     virtual ~AoutObject() {}
 
-    virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
     virtual bool loadGlobalSymbols(SymbolTable *symtab);
     virtual bool loadLocalSymbols(SymbolTable *symtab);
 
index a4b8c871352d4376640bc4542a7ea68accbcc7d7..cd37abaa7ed3d58eb81289bd7280fa03e88fce83 100644 (file)
@@ -29,8 +29,6 @@
 #include <string>
 
 #include "base/loader/ecoff_object.hh"
-
-#include "mem/translating_port.hh"
 #include "base/loader/symtab.hh"
 
 #include "base/trace.hh"       // for DPRINTF
@@ -68,12 +66,15 @@ EcoffObject::EcoffObject(const string &_filename, int _fd,
 
     text.baseAddr = aoutHdr->text_start;
     text.size = aoutHdr->tsize;
+    text.fileImage = fileData + ECOFF_TXTOFF(execHdr);
 
     data.baseAddr = aoutHdr->data_start;
     data.size = aoutHdr->dsize;
+    data.fileImage = fileData + ECOFF_DATOFF(execHdr);
 
     bss.baseAddr = aoutHdr->bss_start;
     bss.size = aoutHdr->bsize;
+    bss.fileImage = NULL;
 
     DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
              text.baseAddr, text.size, data.baseAddr, data.size,
@@ -81,28 +82,6 @@ EcoffObject::EcoffObject(const string &_filename, int _fd,
 }
 
 
-bool
-EcoffObject::loadSections(TranslatingPort *memPort, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    memPort->writeBlobFunctional(textAddr, fileData + ECOFF_TXTOFF(execHdr),
-                                 text.size, true);
-    memPort->writeBlobFunctional(dataAddr, fileData + ECOFF_DATOFF(execHdr),
-                                 data.size, true);
-
-    return true;
-}
-
-
 bool
 EcoffObject::loadGlobalSymbols(SymbolTable *symtab)
 {
index 39b161bfcb30f2273cd75f344eb135a380b975fb..603c70becb63cb583c483eb0d9a2ae982c727695 100644 (file)
@@ -50,7 +50,6 @@ class EcoffObject : public ObjectFile
   public:
     virtual ~EcoffObject() {}
 
-    virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
     virtual bool loadGlobalSymbols(SymbolTable *symtab);
     virtual bool loadLocalSymbols(SymbolTable *symtab);
 
index 11c94d651698fbb861a331d27676512457f4c261..52f236fef84f972303802bd9d6ff6144c4de6d2f 100644 (file)
@@ -43,7 +43,6 @@
 
 #include "base/loader/elf_object.hh"
 
-#include "mem/translating_port.hh"
 #include "base/loader/symtab.hh"
 
 #include "base/trace.hh"       // for DPRINTF
@@ -131,20 +130,19 @@ ElfObject::ElfObject(const string &_filename, int _fd,
         if (text.size == 0) {  // haven't seen text segment yet
             text.baseAddr = phdr.p_vaddr;
             text.size = phdr.p_filesz;
-            // remember where the data is for loadSections()
-            fileTextBits = fileData + phdr.p_offset;
+            text.fileImage = fileData + phdr.p_offset;
             // if there's any padding at the end that's not in the
             // file, call it the bss.  This happens in the "text"
             // segment if there's only one loadable segment (as for
             // kernel images).
             bss.size = phdr.p_memsz - phdr.p_filesz;
             bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
+            bss.fileImage = NULL;
         }
         else if (data.size == 0) { // have text, this must be data
             data.baseAddr = phdr.p_vaddr;
             data.size = phdr.p_filesz;
-            // remember where the data is for loadSections()
-            fileDataBits = fileData + phdr.p_offset;
+            data.fileImage = fileData + phdr.p_offset;
             // if there's any padding at the end that's not in the
             // file, call it the bss.  Warn if this happens for both
             // the text & data segments (should only have one bss).
@@ -153,6 +151,7 @@ ElfObject::ElfObject(const string &_filename, int _fd,
             }
             bss.size = phdr.p_memsz - phdr.p_filesz;
             bss.baseAddr = phdr.p_vaddr + phdr.p_filesz;
+            bss.fileImage = NULL;
         }
     }
 
@@ -169,28 +168,6 @@ ElfObject::ElfObject(const string &_filename, int _fd,
 }
 
 
-bool
-ElfObject::loadSections(TranslatingPort *memPort, bool loadPhys)
-{
-    Addr textAddr = text.baseAddr;
-    Addr dataAddr = data.baseAddr;
-
-    if (loadPhys) {
-        textAddr &= (ULL(1) << 40) - 1;
-        dataAddr &= (ULL(1) << 40) - 1;
-    }
-
-    // Since we don't really have an MMU and all memory is
-    // zero-filled, there's no need to set up the BSS segment.
-    if (text.size != 0)
-        memPort->writeBlobFunctional(textAddr, fileTextBits, text.size, true);
-    if (data.size != 0)
-        memPort->writeBlobFunctional(dataAddr, fileDataBits, data.size, true);
-
-    return true;
-}
-
-
 bool
 ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding)
 {
index 3e93c30b73d6f89b5311aa509f67f98b0a5ab676..72c265edd686f138ec918e4a490efbbdfb66c22d 100644 (file)
@@ -35,9 +35,6 @@ class ElfObject : public ObjectFile
 {
   protected:
 
-    uint8_t *fileTextBits; //!< Pointer to file's text segment image
-    uint8_t *fileDataBits; //!< Pointer to file's data segment image
-
     /// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
     bool loadSomeSymbols(SymbolTable *symtab, int binding);
 
@@ -48,7 +45,6 @@ class ElfObject : public ObjectFile
   public:
     virtual ~ElfObject() {}
 
-    virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
     virtual bool loadGlobalSymbols(SymbolTable *symtab);
     virtual bool loadLocalSymbols(SymbolTable *symtab);
 
index 1410d05b89e05d6ee47bd151b6805c2978ac28fc..f339572698772e7c6ebb9b1357b6ee6aaed54d1e 100644 (file)
@@ -43,6 +43,8 @@
 #include "base/loader/aout_object.hh"
 #include "base/loader/elf_object.hh"
 
+#include "mem/translating_port.hh"
+
 using namespace std;
 
 ObjectFile::ObjectFile(const string &_filename, int _fd,
@@ -60,6 +62,38 @@ ObjectFile::~ObjectFile()
 }
 
 
+bool
+ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
+{
+    if (sec->size != 0) {
+        Addr addr = sec->baseAddr;
+        if (loadPhys) {
+            // this is Alpha-specific... going to have to fix this
+            // for other architectures
+            addr &= (ULL(1) << 40) - 1;
+        }
+
+        if (sec->fileImage) {
+            memPort->writeBlobFunctional(addr, sec->fileImage, sec->size, true);
+        }
+        else {
+            // no image: must be bss
+            memPort->memsetBlobFunctional(addr, 0, sec->size, true);
+        }
+    }
+    return true;
+}
+
+
+bool
+ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys)
+{
+    return (loadSection(&text, memPort, loadPhys)
+            && loadSection(&data, memPort, loadPhys)
+            && loadSection(&bss, memPort, loadPhys));
+}
+
+
 void
 ObjectFile::close()
 {
index 1d750e34115f1b819427355431b8b9ff902dcd31..35ea11b54a0b5b154e359a65809790a40848ef19 100644 (file)
@@ -67,7 +67,7 @@ class ObjectFile
 
     void close();
 
-    virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false) = 0;
+    virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
     virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
     virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
 
@@ -77,8 +77,9 @@ class ObjectFile
   protected:
 
     struct Section {
-        Addr baseAddr;
-        size_t size;
+        Addr     baseAddr;
+        uint8_t *fileImage;
+        size_t   size;
     };
 
     Addr entry;
@@ -88,6 +89,8 @@ class ObjectFile
     Section data;
     Section bss;
 
+    bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
+
   public:
     Addr entryPoint() const { return entry; }
     Addr globalPointer() const { return globalPtr; }
index 870e26a39ae9615e1847956534c2e8fd4159b01a..c0e087f420efc59a8a5a7ee200aed229619cffdc 100644 (file)
@@ -154,14 +154,6 @@ class BaseCPU : public SimObject
      */
     int number_of_threads;
 
-    /**
-     * A pointer to the port into the memory system to be used by syscall
-     * emulation.  This way the data being accessed via syscalls looks in
-     * the memory heirachy for any changes that haven't been written back
-     * to main memory yet.
-     */
-    Port* memPort;
-
     /**
      * Vector of per-thread instruction-based event queues.  Used for
      * scheduling events based on number of instructions committed by
index fa91eb67230370f64241c2bd569a753799041808..0b91992cfb5c1e233a3cbabe73ddd9426b737109 100644 (file)
 #include "base/output.hh"
 #include "cpu/profile.hh"
 #include "kern/kernel_stats.hh"
-#include "mem/translating_port.hh"
 #include "sim/serialize.hh"
 #include "sim/sim_exit.hh"
 #include "sim/system.hh"
 #include "targetarch/stacktrace.hh"
 #else
 #include "sim/process.hh"
+#include "mem/translating_port.hh"
 #endif
 
 using namespace std;
@@ -78,14 +78,14 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
 }
 #else
 ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
-                         Process *_process, int _asid)
+                         Process *_process, int _asid, Port *mem_port)
     : _status(ExecContext::Unallocated),
       cpu(_cpu), thread_num(_thread_num), cpu_id(-1),
       process(_process),
       asid(_asid),
       func_exe_inst(0), storeCondFailures(0)
 {
-    port = new TranslatingPort(cpu->memPort, process->pTable);
+    port = new TranslatingPort(mem_port, process->pTable);
     memset(&regs, 0, sizeof(RegFile));
 }
 #endif
index 8e9e5f2fd17303414e4967d3138461090a8c3ea9..f55b45de1ac86ce47f1056e2e1e6ad25256733fc 100644 (file)
@@ -35,7 +35,6 @@
 #include "sim/host.hh"
 #include "sim/serialize.hh"
 #include "targetarch/byte_swap.hh"
-#include "mem/translating_port.hh"
 
 class BaseCPU;
 
@@ -52,6 +51,7 @@ namespace Kernel { class Binning; class Statistics; }
 #else // !FULL_SYSTEM
 
 #include "sim/process.hh"
+class TranslatingPort;
 
 #endif // FULL_SYSTEM
 
@@ -187,7 +187,7 @@ class ExecContext
                 AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
 #else
     ExecContext(BaseCPU *_cpu, int _thread_num,
-                Process *_process, int _asid);
+                Process *_process, int _asid, Port *mem_port);
 #endif
     virtual ~ExecContext();
 
index 41acd2456960ea281733d11766c7a7027cb0345b..d8d4c3644949e7823cdc083072b58a2978127f7b 100644 (file)
@@ -132,16 +132,6 @@ SimpleCPU::SimpleCPU(Params *p)
       dcachePort(this), tickEvent(this, p->width), xc(NULL)
 {
     _status = Idle;
-#if FULL_SYSTEM
-    xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
-
-    // initialize CPU, including PC
-    TheISA::initCPU(&xc->regs);
-#else
-    xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
-#endif // !FULL_SYSTEM
-
-    memPort = &dcachePort;
 
     //Create Memory Ports (conect them up)
     p->mem->addPort("DCACHE");
@@ -152,11 +142,39 @@ SimpleCPU::SimpleCPU(Params *p)
     icachePort.setPeer(p->mem->getPort("ICACHE"));
     (p->mem->getPort("ICACHE"))->setPeer(&icachePort);
 
+#if FULL_SYSTEM
+    xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
 
+    // initialize CPU, including PC
+    TheISA::initCPU(&xc->regs);
+#else
+    xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0,
+                         &dcachePort);
+#endif // !FULL_SYSTEM
 
-    req = new CpuRequest;
-
-    req->asid = 0;
+#if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
+    ifetch_req = new CpuRequest;
+    ifetch_req->asid = 0;
+    ifetch_req->size = sizeof(MachInst);
+    ifetch_pkt = new Packet;
+    ifetch_pkt->cmd = Read;
+    ifetch_pkt->data = (uint8_t *)&inst;
+    ifetch_pkt->req = ifetch_req;
+    ifetch_pkt->size = sizeof(MachInst);
+
+    data_read_req = new CpuRequest;
+    data_read_req->asid = 0;
+    data_read_pkt = new Packet;
+    data_read_pkt->cmd = Read;
+    data_read_pkt->data = new uint8_t[8];
+    data_read_pkt->req = data_read_req;
+
+    data_write_req = new CpuRequest;
+    data_write_req->asid = 0;
+    data_write_pkt = new Packet;
+    data_write_pkt->cmd = Write;
+    data_write_pkt->req = data_write_req;
+#endif
 
     numInst = 0;
     startNumInst = 0;
@@ -425,6 +443,7 @@ SimpleCPU::copy(Addr dest)
     }
     return fault;
 #else
+    panic("copy not implemented");
     return No_Fault;
 #endif
 }
@@ -437,8 +456,8 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
     if (status() == DcacheWaitResponse || status() == DcacheWaitSwitch) {
 //     Fault fault = xc->read(memReq,data);
         // Not sure what to check for no fault...
-        if (pkt->result == Success) {
-            memcpy(&data, pkt->data, sizeof(T));
+        if (data_read_pkt->result == Success) {
+            memcpy(&data, data_read_pkt->data, sizeof(T));
         }
 
         if (traceData) {
@@ -451,19 +470,45 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
 
 //    memReq->reset(addr, sizeof(T), flags);
 
+#if SIMPLE_CPU_MEM_TIMING
+    CpuRequest *data_read_req = new CpuRequest;
+#endif
+
+    data_read_req->vaddr = addr;
+    data_read_req->size = sizeof(T);
+    data_read_req->flags = flags;
+    data_read_req->time = curTick;
+
     // translate to physical address
-    // NEED NEW TRANSLATION HERE
-    Fault fault = xc->translateDataReadReq(req);
+    Fault fault = xc->translateDataReadReq(data_read_req);
 
     // Now do the access.
     if (fault == No_Fault) {
-        pkt = new Packet;
-        pkt->cmd = Read;
-        req->paddr = addr;
-        pkt->size = sizeof(T);
-        pkt->req = req;
+#if SIMPLE_CPU_MEM_TIMING
+        data_read_pkt = new Packet;
+        data_read_pkt->cmd = Read;
+        data_read_pkt->req = data_read_req;
+        data_read_pkt->data = new uint8_t[8];
+#endif
+        data_read_pkt->addr = data_read_req->paddr;
+        data_read_pkt->size = sizeof(T);
+
+        sendDcacheRequest(data_read_pkt);
+
+#if SIMPLE_CPU_MEM_IMMEDIATE
+        // Need to find a way to not duplicate code above.
 
-        sendDcacheRequest();
+        if (data_read_pkt->result == Success) {
+            memcpy(&data, data_read_pkt->data, sizeof(T));
+        }
+
+        if (traceData) {
+            traceData->setAddr(addr);
+        }
+
+        // @todo: Figure out a way to create a Fault from the packet result.
+        return No_Fault;
+#endif
     }
 /*
         memReq->cmd = Read;
@@ -493,7 +538,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
     }
 */
     // This will need a new way to tell if it has a dcache attached.
-    if (/*!dcacheInterface && */(req->flags & UNCACHEABLE))
+    if (data_read_req->flags & UNCACHEABLE)
         recordEvent("Uncached Read");
 
     return fault;
@@ -546,27 +591,29 @@ template <class T>
 Fault
 SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
 {
-//    memReq->reset(addr, sizeof(T), flags);
-    req->vaddr = addr;
-    req->time = curTick;
-    req->size = sizeof(T);
+    data_write_req->vaddr = addr;
+    data_write_req->time = curTick;
+    data_write_req->size = sizeof(T);
+    data_write_req->flags = flags;
 
     // translate to physical address
-    // NEED NEW TRANSLATION HERE
-    Fault fault = xc->translateDataWriteReq(req);
+    Fault fault = xc->translateDataWriteReq(data_write_req);
 
     // Now do the access.
     if (fault == No_Fault) {
-        pkt = new Packet;
-        pkt->cmd = Write;
-        pkt->size = sizeof(T);
-        pkt->req = req;
-
-        // Copy data into the packet.
-        pkt->data = new uint8_t[64];
-        memcpy(pkt->data, &data, sizeof(T));
+#if SIMPLE_CPU_MEM_TIMING
+        data_write_pkt = new Packet;
+        data_write_pkt->cmd = Write;
+        data_write_pkt->req = data_write_req;
+        data_write_pkt->data = new uint8_t[64];
+        memcpy(data_write_pkt->data, &data, sizeof(T));
+#else
+        data_write_pkt->data = (uint8_t *)&data;
+#endif
+        data_write_pkt->addr = data_write_req->paddr;
+        data_write_pkt->size = sizeof(T);
 
-        sendDcacheRequest();
+        sendDcacheRequest(data_write_pkt);
     }
 
 /*
@@ -594,10 +641,10 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
     }
 */
     if (res && (fault == No_Fault))
-        *res = pkt->result;
+        *res = data_write_pkt->result;
 
     // This will need a new way to tell if it's hooked up to a cache or not.
-    if (/*!dcacheInterface && */(req->flags & UNCACHEABLE))
+    if (data_write_req->flags & UNCACHEABLE)
         recordEvent("Uncached Write");
 
     // If the write needs to have a fault on the access, consider calling
@@ -657,9 +704,11 @@ SimpleCPU::dbg_vtophys(Addr addr)
 #endif // FULL_SYSTEM
 
 void
-SimpleCPU::sendIcacheRequest()
+SimpleCPU::sendIcacheRequest(Packet *pkt)
 {
-#if 0
+    assert(!tickEvent.scheduled());
+#if SIMPLE_CPU_MEM_TIMING
+    retry_pkt = pkt;
     bool success = icachePort.sendTiming(*pkt);
 
     unscheduleTickEvent();
@@ -673,7 +722,7 @@ SimpleCPU::sendIcacheRequest()
         // Need to wait for cache to respond
         _status = IcacheWaitResponse;
     }
-#else
+#elif SIMPLE_CPU_MEM_ATOMIC
     Tick latency = icachePort.sendAtomic(*pkt);
 
     unscheduleTickEvent();
@@ -685,17 +734,21 @@ SimpleCPU::sendIcacheRequest()
     icacheStallCycles += latency;
 
     _status = IcacheAccessComplete;
-
-    delete pkt;
+#elif SIMPLE_CPU_MEM_IMMEDIATE
+    icachePort.sendAtomic(*pkt);
+#else
+#error "SimpleCPU has no mem model set"
 #endif
 }
 
 void
-SimpleCPU::sendDcacheRequest()
+SimpleCPU::sendDcacheRequest(Packet *pkt)
 {
+    assert(!tickEvent.scheduled());
+#if SIMPLE_CPU_MEM_TIMING
     unscheduleTickEvent();
 
-#if 0
+    retry_pkt = pkt;
     bool success = dcachePort.sendTiming(*pkt);
 
     lastDcacheStall = curTick;
@@ -705,7 +758,9 @@ SimpleCPU::sendDcacheRequest()
     } else {
         _status = DcacheWaitResponse;
     }
-#else
+#elif SIMPLE_CPU_MEM_ATOMIC
+    unscheduleTickEvent();
+
     Tick latency = dcachePort.sendAtomic(*pkt);
 
     scheduleTickEvent(latency);
@@ -714,19 +769,22 @@ SimpleCPU::sendDcacheRequest()
     // we check the status of the packet sent (is this valid?),
     // we won't know if the latency is a hit or a miss.
     dcacheStallCycles += latency;
-
-    // Delete the packet right here?
-    delete pkt;
+#elif SIMPLE_CPU_MEM_IMMEDIATE
+    dcachePort.sendAtomic(*pkt);
+#else
+#error "SimpleCPU has no mem model set"
 #endif
 }
 
 void
 SimpleCPU::processResponse(Packet &response)
 {
+    assert(SIMPLE_CPU_MEM_TIMING);
+
     // For what things is the CPU the consumer of the packet it sent
     // out?  This may create a memory leak if that's the case and it's
     // expected of the SimpleCPU to delete its own packet.
-    pkt = &response;
+    Packet *pkt = &response;
 
     switch (status()) {
       case IcacheWaitResponse:
@@ -780,19 +838,23 @@ SimpleCPU::processResponse(Packet &response)
 Packet *
 SimpleCPU::processRetry()
 {
+#if SIMPLE_CPU_MEM_TIMING
     switch(status()) {
       case IcacheRetry:
         icacheRetryCycles += curTick - lastIcacheStall;
-        return pkt;
+        return retry_pkt;
         break;
       case DcacheRetry:
         dcacheRetryCycles += curTick - lastDcacheStall;
-        return pkt;
+        return retry_pkt;
         break;
       default:
         panic("SimpleCPU::processRetry: bad state");
         break;
     }
+#else
+    panic("shouldn't be here");
+#endif
 }
 
 #if FULL_SYSTEM
@@ -884,28 +946,35 @@ SimpleCPU::tick()
 #define IFETCH_FLAGS(pc)       0
 #endif
 
-        req->vaddr = xc->regs.pc & ~3;
-        req->time = curTick;
-        req->size = sizeof(MachInst);
+#if SIMPLE_CPU_MEM_TIMING
+        CpuRequest *ifetch_req = new CpuRequest();
+        ifetch_req->size = sizeof(MachInst);
+#endif
+
+        ifetch_req->vaddr = xc->regs.pc & ~3;
+        ifetch_req->time = curTick;
 
 /*     memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
                      IFETCH_FLAGS(xc->regs.pc));
 */
 
-        fault = xc->translateInstReq(req);
+        fault = xc->translateInstReq(ifetch_req);
 
         if (fault == No_Fault) {
-            pkt = new Packet;
-            pkt->cmd = Read;
-            pkt->addr = req->paddr;
-            pkt->size = sizeof(MachInst);
-            pkt->req = req;
-            pkt->data = (uint8_t *)&inst;
-
-            sendIcacheRequest();
-            return;
-/*         fault = xc->mem->read(memReq, inst);
+#if SIMPLE_CPU_MEM_TIMING
+            Packet *ifetch_pkt = new Packet;
+            ifetch_pkt->cmd = Read;
+            ifetch_pkt->data = (uint8_t *)&inst;
+            ifetch_pkt->req = ifetch_req;
+            ifetch_pkt->size = sizeof(MachInst);
+#endif
+            ifetch_pkt->addr = ifetch_req->paddr;
 
+            sendIcacheRequest(ifetch_pkt);
+#if SIMPLE_CPU_MEM_TIMING || SIMPLE_CPU_MEM_ATOMIC
+            return;
+#endif
+/*
         if (icacheInterface && fault == No_Fault) {
             memReq->completionEvent = NULL;
 
@@ -980,8 +1049,7 @@ SimpleCPU::tick()
 
         // If we have a dcache miss, then we can't finialize the instruction
         // trace yet because we want to populate it with the data later
-        if (traceData &&
-                !(status() == DcacheWaitResponse && pkt->cmd == Read)) {
+        if (traceData && (status() != DcacheWaitResponse)) {
             traceData->finalize();
         }
 
index 3354166ccef62de63dddfeda342bfb88c95ed59d..ca10134f78e3351e8ee2ab079057451478a1f484 100644 (file)
@@ -64,6 +64,16 @@ namespace Trace {
     class InstRecord;
 }
 
+
+// Set exactly one of these symbols to 1 to set the memory access
+// model.  Probably should make these template parameters, or even
+// just fork the CPU models.
+//
+#define SIMPLE_CPU_MEM_TIMING    0
+#define SIMPLE_CPU_MEM_ATOMIC    0
+#define SIMPLE_CPU_MEM_IMMEDIATE 1
+
+
 class SimpleCPU : public BaseCPU
 {
     class CpuPort : public Port
@@ -188,8 +198,16 @@ class SimpleCPU : public BaseCPU
     // current instruction
     MachInst inst;
 
-    CpuRequest *req;
-    Packet *pkt;
+#if SIMPLE_CPU_MEM_TIMING
+    Packet *retry_pkt;
+#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
+    CpuRequest *ifetch_req;
+    Packet     *ifetch_pkt;
+    CpuRequest *data_read_req;
+    Packet     *data_read_pkt;
+    CpuRequest *data_write_req;
+    Packet     *data_write_pkt;
+#endif
 
     // Pointer to the sampler that is telling us to switchover.
     // Used to signal the completion of the pipe drain and schedule
@@ -246,8 +264,8 @@ class SimpleCPU : public BaseCPU
     Stats::Scalar<> dcacheRetryCycles;
     Counter lastDcacheRetry;
 
-    void sendIcacheRequest();
-    void sendDcacheRequest();
+    void sendIcacheRequest(Packet *pkt);
+    void sendDcacheRequest(Packet *pkt);
     void processResponse(Packet &response);
 
     Packet * processRetry();
index fea4b6ec5dd662924d26edddb724dc7fec061496..69544c8fe8a9348edd7b48177d3568643c81f988 100644 (file)
@@ -174,6 +174,8 @@ PhysicalMemory::doFunctionalAccess(Packet &pkt)
       default:
         panic("unimplemented");
     }
+
+    pkt.result = Success;
 }
 
 Port *
index 8c4b3810c1b96916b1fadea684b8da4a220ffb56..e080f8b81ff2034901546eef71883990286af023 100644 (file)
@@ -63,3 +63,12 @@ Port::readBlobFunctional(Addr addr, uint8_t *p, int size)
     blobHelper(addr, p, size, Read);
 }
 
+void
+Port::memsetBlobFunctional(Addr addr, uint8_t val, int size)
+{
+    // quick and dirty...
+    uint8_t *buf = new uint8_t[size];
+
+    memset(buf, val, size);
+    blobHelper(addr, buf, size, Write);
+}
index e385a74b6702d595362fba3ddd65f6390c948fb4..f4f2ca737839b562eff435733d97d8630f4e1839 100644 (file)
@@ -83,23 +83,31 @@ TranslatingPort::writeBlobFunctional(Addr addr, uint8_t *p, int size,
     return No_Fault;
 }
 
-/*
+
 Fault
-TranslatingPort::memsetBlobFunctional(Addr addr, uint8_t val, int size)
+TranslatingPort::memsetBlobFunctional(Addr addr, uint8_t val, int size,
+                                      bool alloc)
 {
     Addr paddr;
 
     for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
 
-       if (!pTable->translate(gen.addr(),paddr))
-           return Machine_Check_Fault;
+        if (!pTable->translate(gen.addr(), paddr)) {
+            if (alloc) {
+                pTable->allocate(roundDown(gen.addr(), VMPageSize),
+                                 VMPageSize);
+                pTable->translate(gen.addr(), paddr);
+            } else {
+                return Machine_Check_Fault;
+            }
+        }
 
-       port->memsetBlobFunctional(paddr, val, gen.size());
+        port->memsetBlobFunctional(paddr, val, gen.size());
     }
 
     return No_Fault;
 }
-*/
+
 
 Fault
 TranslatingPort::writeStringFunctional(Addr addr, const char *str)
index 3d77b2c2b47beb3b0cf2d323a1eb1eeaeaf00d0d..1a334c103991a4535abc6cebdc3e40d45903e20a 100644 (file)
@@ -51,7 +51,8 @@ class TranslatingPort
     Fault readBlobFunctional(Addr addr, uint8_t *p, int size);
     Fault writeBlobFunctional(Addr addr, uint8_t *p, int size,
                               bool alloc = false);
-    //   Fault memsetBlobFunctional(Addr addr, uint8_t val, int size);
+    Fault memsetBlobFunctional(Addr addr, uint8_t val, int size,
+                               bool alloc = false);
     Fault writeStringFunctional(Addr addr, const char *str);
     Fault readStringFunctional(std::string &str, Addr addr);