first pass at merging m5 with linux
[gem5.git] / arch / alpha / vtophys.cc
index 33f8f02ad42df7a9b246ff499a400d3152262516..d91d80c831f1e9895fb7eebb620b273e0e5d6bff 100644 (file)
 
 #include <string>
 
-#include "pmap.h"
+#include "targetarch/pmap.h"
 
-#include "exec_context.hh"
-#include "physical_memory.hh"
-#include "trace.hh"
-#include "vtophys.hh"
+#include "cpu/exec_context.hh"
+#include "mem/functional_mem/physical_memory.hh"
+#include "base/trace.hh"
+#include "targetarch/vtophys.hh"
 
 using namespace std;
 
@@ -96,28 +96,135 @@ vtophys(ExecContext *xc, Addr vaddr)
 {
     Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20];
     Addr paddr = 0;
-    if (vaddr < ALPHA_K0SEG_BASE) {
-        DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
-    } else if (vaddr < ALPHA_K1SEG_BASE) {
-        paddr = ALPHA_K0SEG_TO_PHYS(vaddr);
-    } else {
-        if (!ptbr)
-            panic("vtophys: ptbr is not set on virtual lookup");
-
-        Addr pte = kernel_pte_lookup(xc->physmem, ptbr, vaddr);
-        uint64_t entry = xc->physmem->phys_read_qword(pte);
-        if (pte && entry_valid(entry))
-            paddr = PMAP_PTE_PA(entry) | (vaddr & PGOFSET);
-    }
+//    if (PC_PAL(vaddr)) {
+//     paddr = vaddr & ~ULL(1);
+//    } else {
+        if (vaddr >= ALPHA_K0SEG_BASE && vaddr <= ALPHA_K0SEG_END) {
+            paddr = ALPHA_K0SEG_TO_PHYS(vaddr);
+        } else if (!ptbr) {
+            paddr = vaddr;
+        } else {
+            Addr pte = kernel_pte_lookup(xc->physmem, ptbr, vaddr);
+            uint64_t entry = xc->physmem->phys_read_qword(pte);
+            if (pte && entry_valid(entry))
+                paddr = PMAP_PTE_PA(entry) | (vaddr & PGOFSET);
+        }
+//    }
 
     DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
 
     return paddr;
 }
 
+uint8_t *
+ptomem(ExecContext *xc, Addr paddr, size_t len)
+{
+    return xc->physmem->dma_addr(paddr, len);
+}
+
 uint8_t *
 vtomem(ExecContext *xc, Addr vaddr, size_t len)
 {
     Addr paddr = vtophys(xc, vaddr);
     return xc->physmem->dma_addr(paddr, len);
 }
+
+void
+CopyData(ExecContext *xc, void *dest, Addr vaddr, size_t cplen)
+{
+    Addr paddr;
+    char *dmaaddr;
+    char *dst = (char *)dest;
+    int len;
+
+    paddr = vtophys(xc, vaddr);
+    len = min((int)(ALPHA_PGBYTES - (paddr & PGOFSET)), (int)cplen);
+    dmaaddr = (char *)xc->physmem->dma_addr(paddr, len);
+    assert(dmaaddr);
+
+    memcpy(dst, dmaaddr, len);
+    if (len == cplen)
+        return;
+
+    cplen -= len;
+    dst += len;
+    vaddr += len;
+
+    while (cplen > ALPHA_PGBYTES) {
+        paddr = vtophys(xc, vaddr);
+        dmaaddr = (char *)xc->physmem->dma_addr(paddr, ALPHA_PGBYTES);
+        assert(dmaaddr);
+
+        memcpy(dst, dmaaddr, ALPHA_PGBYTES);
+        cplen -= ALPHA_PGBYTES;
+        dst += ALPHA_PGBYTES;
+        vaddr += ALPHA_PGBYTES;
+    }
+
+    if (cplen > 0) {
+        paddr = vtophys(xc, vaddr);
+        dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen);
+        assert(dmaaddr);
+
+        memcpy(dst, dmaaddr, cplen);
+    }
+}
+
+void
+CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
+{
+    Addr paddr;
+    char *dmaaddr;
+    int len;
+
+    paddr = vtophys(xc, vaddr);
+    len = min((int)(ALPHA_PGBYTES - (paddr & PGOFSET)), (int)maxlen);
+    dmaaddr = (char *)xc->physmem->dma_addr(paddr, len);
+    assert(dmaaddr);
+
+    char *term = (char *)memchr(dmaaddr, 0, len);
+    if (term)
+        len = term - dmaaddr + 1;
+
+    memcpy(dst, dmaaddr, len);
+
+    if (term || len == maxlen)
+        return;
+
+    maxlen -= len;
+    dst += len;
+    vaddr += len;
+
+    while (maxlen > ALPHA_PGBYTES) {
+        paddr = vtophys(xc, vaddr);
+        dmaaddr = (char *)xc->physmem->dma_addr(paddr, ALPHA_PGBYTES);
+        assert(dmaaddr);
+
+        char *term = (char *)memchr(dmaaddr, 0, ALPHA_PGBYTES);
+        len = term ? (term - dmaaddr + 1) : ALPHA_PGBYTES;
+
+        memcpy(dst, dmaaddr, len);
+        if (term)
+            return;
+
+        maxlen -= ALPHA_PGBYTES;
+        dst += ALPHA_PGBYTES;
+        vaddr += ALPHA_PGBYTES;
+    }
+
+    if (maxlen > 0) {
+        paddr = vtophys(xc, vaddr);
+        dmaaddr = (char *)xc->physmem->dma_addr(paddr, maxlen);
+        assert(dmaaddr);
+
+        char *term = (char *)memchr(dmaaddr, 0, maxlen);
+        len = term ? (term - dmaaddr + 1) : maxlen;
+
+        memcpy(dst, dmaaddr, len);
+
+        maxlen -= len;
+    }
+
+    if (maxlen == 0)
+        dst[maxlen] = '\0';
+}