From d96de69abc02b40e1dec4843a7a7b7e30749f4fa Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 20 Feb 2006 23:26:39 -0500 Subject: [PATCH] Add in a new translating port that allows syscalls to translate addresses via the page table before accessing the memory port. Other compile issues cleaned up. SConscript: Changes to compile the new Translating Port. Split out memtester and eio support, will rework them back in after first getting a simpleCPU to work arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: sim/syscall_emul.cc: sim/syscall_emul.hh: Changes to use the new translating Port. cpu/exec_context.cc: cpu/exec_context.hh: Create a translating port in each execution context. sim/process.cc: Fix the way we do proxy memory --HG-- extra : convert_revision : 3d33218fe8b425a5d9ce24757f1112b4aa6001fd --- SConscript | 13 +++- arch/alpha/alpha_linux_process.cc | 12 +-- arch/alpha/alpha_tru64_process.cc | 98 ++++++++++++------------ cpu/exec_context.cc | 2 + cpu/exec_context.hh | 5 +- mem/translating_port.cc | 119 ++++++++++++++++++++++++++++++ mem/translating_port.hh | 59 +++++++++++++++ sim/process.cc | 4 +- sim/syscall_emul.cc | 16 ++-- sim/syscall_emul.hh | 75 ++++++++----------- 10 files changed, 288 insertions(+), 115 deletions(-) create mode 100644 mem/translating_port.cc create mode 100644 mem/translating_port.hh diff --git a/SConscript b/SConscript index b4f57ddbc..3e613d840 100644 --- a/SConscript +++ b/SConscript @@ -93,7 +93,7 @@ base_sources = Split(''' mem/memory.cc mem/page_table.cc mem/physical.cc - mem/proxy.cc + mem/translating_port.cc python/pyconfig.cc python/embedded_py.cc @@ -294,14 +294,21 @@ syscall_emulation_sources = Split(''' arch/alpha/alpha_common_syscall_emul.cc arch/alpha/alpha_linux_process.cc arch/alpha/alpha_tru64_process.cc - cpu/memtest/memtest.cc - encumbered/eio/eio.cc + encumbered/eio/exolex.cc encumbered/eio/libexo.cc sim/process.cc sim/syscall_emul.cc ''') +eio_sources = Split(''' + encumbered/eio/eio.cc + ''') + +memtest_sources = Split(''' + cpu/memtest/memtest.cc + ''') + targetarch_files = Split(''' alpha_common_syscall_emul.hh alpha_linux_process.hh diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index be2013e1e..16816e901 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -36,7 +36,7 @@ #include "cpu/base.hh" #include "cpu/exec_context.hh" -#include "mem/port.hh" +#include "mem/translating_port.hh" #include "sim/fake_syscall.hh" #include "sim/host.hh" #include "sim/process.hh" @@ -236,7 +236,7 @@ class Linux { /// buffer. Also copies the target buffer out to the simulated /// memory space. Used by stat(), fstat(), and lstat(). static void - copyOutStatBuf(Port *memPort, Addr addr, struct stat *host) + copyOutStatBuf(TranslatingPort *memPort, Addr addr, struct stat *host) { TypedBufferArg tgt(addr); @@ -259,7 +259,7 @@ class Linux { // Same for stat64 static void - copyOutStat64Buf(Port *memPort, Addr addr, struct stat64 *host) + copyOutStat64Buf(TranslatingPort *memPort, Addr addr, struct stat64 *host) { TypedBufferArg tgt(addr); @@ -307,7 +307,7 @@ class Linux { strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); - name.copyOut(xc->cpu->memPort); + name.copyOut(xc->port); return 0; } @@ -327,7 +327,7 @@ class Linux { TypedBufferArg fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; - fpcr.copyOut(xc->cpu->memPort); + fpcr.copyOut(xc->port); return 0; } @@ -353,7 +353,7 @@ class Linux { case 14: { // SSI_IEEE_FP_CONTROL TypedBufferArg fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->cpu->memPort); + fpcr.copyIn(xc->port); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " " setting FPCR to 0x%x\n", *(uint64_t*)fpcr); return 0; diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 3b5eef8b0..a9c7b5c74 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -46,7 +46,7 @@ #include "base/trace.hh" #include "cpu/base.hh" #include "cpu/exec_context.hh" -#include "mem/functional/functional.hh" +#include "mem/translating_port.hh" #include "sim/fake_syscall.hh" #include "sim/host.hh" #include "sim/process.hh" @@ -537,7 +537,7 @@ class Tru64 { /// memory space. Used by stat(), fstat(), and lstat(). template static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) + copyOutStatBuf(TranslatingPort *memPort, Addr addr, global_stat *host) { TypedBufferArg tgt(addr); @@ -555,7 +555,7 @@ class Tru64 { tgt->st_blksize = host->st_blksize; tgt->st_blocks = host->st_blocks; - tgt.copyOut(mem); + tgt.copyOut(memPort); } /// Helper function to convert a host statfs buffer to a target statfs @@ -563,7 +563,7 @@ class Tru64 { /// memory space. Used by statfs() and fstatfs(). template static void - copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) + copyOutStatfsBuf(TranslatingPort *memPort, Addr addr, global_statfs *host) { TypedBufferArg tgt(addr); @@ -580,36 +580,36 @@ class Tru64 { tgt->f_ffree = host->f_ffree; memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid)); - tgt.copyOut(mem); + tgt.copyOut(memPort); } class F64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatBuf(TranslatingPort *memPort, Addr addr, global_stat *host) { - Tru64::copyOutStatBuf(mem, addr, host); + Tru64::copyOutStatBuf(memPort, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatfsBuf(TranslatingPort *memPort, Addr addr, global_statfs *host) { - Tru64::copyOutStatfsBuf(mem, addr, host); + Tru64::copyOutStatfsBuf(memPort, addr, host); } }; class PreF64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatBuf(TranslatingPort *memPort, Addr addr, global_stat *host) { - Tru64::copyOutStatBuf(mem, addr, host); + Tru64::copyOutStatBuf(memPort, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatfsBuf(TranslatingPort *memPort, Addr addr, global_statfs *host) { - Tru64::copyOutStatfsBuf(mem, addr, host); + Tru64::copyOutStatfsBuf(memPort, addr, host); } }; @@ -618,7 +618,7 @@ class Tru64 { /// the simulated memory space. Used by pre_F64_stat(), /// pre_F64_fstat(), and pre_F64_lstat(). static void - copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) + copyOutPreF64StatBuf(TranslatingPort *memPort, Addr addr, struct stat *host) { TypedBufferArg tgt(addr); @@ -636,7 +636,7 @@ class Tru64 { tgt->st_blksize = host->st_blksize; tgt->st_blocks = host->st_blocks; - tgt.copyOut(mem); + tgt.copyOut(memPort); } @@ -656,7 +656,7 @@ class Tru64 { strcpy(name->version, "732"); strcpy(name->machine, "alpha"); - name.copyOut(xc->mem); + name.copyOut(xc->port); return 0; } @@ -674,21 +674,21 @@ class Tru64 { case Tru64::GSI_MAX_CPU: { TypedBufferArg max_cpu(xc->getSyscallArg(1)); *max_cpu = process->numCpus(); - max_cpu.copyOut(xc->mem); + max_cpu.copyOut(xc->port); return 1; } case Tru64::GSI_CPUS_IN_BOX: { TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); *cpus_in_box = process->numCpus(); - cpus_in_box.copyOut(xc->mem); + cpus_in_box.copyOut(xc->port); return 1; } case Tru64::GSI_PHYSMEM: { TypedBufferArg physmem(xc->getSyscallArg(1)); *physmem = 1024 * 1024; // physical memory in KB - physmem.copyOut(xc->mem); + physmem.copyOut(xc->port); return 1; } @@ -705,14 +705,14 @@ class Tru64 { infop->cpu_ex_binding = 0; infop->mhz = 667; - infop.copyOut(xc->mem); + infop.copyOut(xc->port); return 1; } case Tru64::GSI_PROC_TYPE: { TypedBufferArg proc_type(xc->getSyscallArg(1)); *proc_type = 11; - proc_type.copyOut(xc->mem); + proc_type.copyOut(xc->port); return 1; } @@ -721,14 +721,14 @@ class Tru64 { strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); - bufArg.copyOut(xc->mem); + bufArg.copyOut(xc->port); return 1; } case Tru64::GSI_CLK_TCK: { TypedBufferArg clk_hz(xc->getSyscallArg(1)); *clk_hz = 1024; - clk_hz.copyOut(xc->mem); + clk_hz.copyOut(xc->port); return 1; } @@ -822,7 +822,7 @@ class Tru64 { // just pass basep through uninterpreted. TypedBufferArg basep(tgt_basep); - basep.copyIn(xc->mem); + basep.copyIn(xc->port); long host_basep = (off_t)*basep; int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); @@ -849,7 +849,7 @@ class Tru64 { tgt_dp->d_reclen = tgt_bufsize; tgt_dp->d_namlen = namelen; strcpy(tgt_dp->d_name, host_dp->d_name); - tgt_dp.copyOut(xc->mem); + tgt_dp.copyOut(xc->port); tgt_buf_ptr += tgt_bufsize; host_buf_ptr += host_dp->d_reclen; @@ -858,7 +858,7 @@ class Tru64 { delete [] host_buf; *basep = host_basep; - basep.copyOut(xc->mem); + basep.copyOut(xc->port); return tgt_buf_ptr - tgt_buf; #endif @@ -872,7 +872,7 @@ class Tru64 { RegFile *regs = &xc->regs; TypedBufferArg sc(xc->getSyscallArg(0)); - sc.copyIn(xc->mem); + sc.copyIn(xc->port); // Restore state from sigcontext structure. // Note that we'll advance PC <- NPC before the end of the cycle, @@ -917,7 +917,7 @@ class Tru64 { elp->si_phz = clk_hz; elp->si_boottime = seconds_since_epoch; // seconds since epoch? elp->si_max_procs = process->numCpus(); - elp.copyOut(xc->mem); + elp.copyOut(xc->port); return 0; } @@ -947,7 +947,7 @@ class Tru64 { { TypedBufferArg argp(xc->getSyscallArg(0)); - argp.copyIn(xc->mem); + argp.copyIn(xc->port); // if the user chose an address, just let them have it. Otherwise // pick one for them. @@ -955,7 +955,7 @@ class Tru64 { argp->address = process->next_thread_stack_base; int stack_size = (argp->rsize + argp->ysize + argp->gsize); process->next_thread_stack_base -= stack_size; - argp.copyOut(xc->mem); + argp.copyOut(xc->port); } return 0; @@ -975,7 +975,7 @@ class Tru64 { TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); - attrp.copyIn(xc->mem); + attrp.copyIn(xc->port); if (attrp->nxm_version != NXM_LIB_VERSION) { cerr << "nxm_task_init: thread library version mismatch! " @@ -1016,7 +1016,7 @@ class Tru64 { config->nxm_slot_state = slot_state_addr; config->nxm_rad[0] = rad_state_addr; - config.copyOut(xc->mem); + config.copyOut(xc->port); // initialize the slot_state array and copy it out TypedBufferArg slot_state(slot_state_addr, @@ -1027,7 +1027,7 @@ class Tru64 { (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; } - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->port); // same for the per-RAD "shared" struct. Note that we need to // allocate extra bytes for the per-VP array which is embedded at @@ -1061,13 +1061,13 @@ class Tru64 { } } - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->port); // // copy pointer to shared config area out to user // *configptr_ptr = config_addr; - configptr_ptr.copyOut(xc->mem); + configptr_ptr.copyOut(xc->port); // Register this as a valid address range with the process process->nxm_start = base_addr; @@ -1104,7 +1104,7 @@ class Tru64 { int thread_index = xc->getSyscallArg(2); // get attribute args - attrp.copyIn(xc->mem); + attrp.copyIn(xc->port); if (attrp->version != NXM_LIB_VERSION) { cerr << "nxm_thread_create: thread library version mismatch! " @@ -1129,7 +1129,7 @@ class Tru64 { TypedBufferArg rad_state(0x14000, rad_state_size); - rad_state.copyIn(xc->mem); + rad_state.copyIn(xc->port); uint64_t uniq_val = attrp->pthid - rad_state->nxm_uniq_offset; @@ -1140,7 +1140,7 @@ class Tru64 { // This is supposed to be a port number. Make something up. *kidp = 99; - kidp.copyOut(xc->mem); + kidp.copyOut(xc->port); return 0; } else if (attrp->type == Tru64::NXM_TYPE_VP) { @@ -1154,7 +1154,7 @@ class Tru64 { ssp->nxm_u.pth_id = attrp->pthid; ssp->nxm_u.nxm_active = uniq_val | 1; - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->port); Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info); int slot_state_size = @@ -1164,7 +1164,7 @@ class Tru64 { slot_state(slot_state_addr, slot_state_size); - slot_state.copyIn(xc->mem); + slot_state.copyIn(xc->port); if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) { cerr << "nxm_thread_createFunc: requested VP slot " @@ -1174,7 +1174,7 @@ class Tru64 { slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->port); // Find a free simulator execution context. for (int i = 0; i < process->numCpus(); ++i) { @@ -1188,7 +1188,7 @@ class Tru64 { // and get away with just sticking the thread index // here. *kidp = thread_index; - kidp.copyOut(xc->mem); + kidp.copyOut(xc->port); return 0; } @@ -1317,12 +1317,12 @@ class Tru64 { { TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->port); if (*lockp == 0) { // lock is free: grab it *lockp = 1; - lockp.copyOut(xc->mem); + lockp.copyOut(xc->port); } else { // lock is busy: disable until free process->waitList.push_back(Process::WaitRec(uaddr, xc)); @@ -1336,7 +1336,7 @@ class Tru64 { { TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->port); assert(*lockp != 0); // Check for a process waiting on the lock. @@ -1345,7 +1345,7 @@ class Tru64 { // clear lock field if no waiting context is taking over the lock if (num_waiting == 0) { *lockp = 0; - lockp.copyOut(xc->mem); + lockp.copyOut(xc->port); } } @@ -1372,12 +1372,12 @@ class Tru64 { Addr uaddr = xc->getSyscallArg(0); TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->port); if (*lockp == 0) { // lock is free: grab it *lockp = 1; - lockp.copyOut(xc->mem); + lockp.copyOut(xc->port); return 0; } else { return 1; @@ -1432,7 +1432,7 @@ class Tru64 { TypedBufferArg lockp(lock_addr); // user is supposed to acquire lock before entering - lockp.copyIn(xc->mem); + lockp.copyIn(xc->port); assert(*lockp != 0); m5_unlock_mutex(lock_addr, process, xc); diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index a281609f4..10894230b 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -37,6 +37,7 @@ #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" @@ -85,6 +86,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, asid(_asid), func_exe_inst(0), storeCondFailures(0) { + port = new TranslatingPort(cpu->memPort, process->pTable); memset(®s, 0, sizeof(RegFile)); } #endif diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index c40b00e4c..3d40c06f0 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -35,8 +35,8 @@ #include "sim/host.hh" #include "sim/serialize.hh" #include "targetarch/byte_swap.hh" +#include "mem/translating_port.hh" -class Memory; class BaseCPU; #if FULL_SYSTEM @@ -122,6 +122,9 @@ class ExecContext int cpu_id; System *system; + + /// Port that syscalls can use to access memory (provides translation step). + TranslatingPort *port; // Memory *mem; #if FULL_SYSTEM diff --git a/mem/translating_port.cc b/mem/translating_port.cc new file mode 100644 index 000000000..11004769e --- /dev/null +++ b/mem/translating_port.cc @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "mem/port.hh" +#include "mem/translating_port.hh" +#include "mem/page_table.hh" + +TranslatingPort::TranslatingPort(Port *_port, PageTable *p_table) + : port(_port), pTable(p_table) +{ } + +TranslatingPort::~TranslatingPort() +{ } + +Fault +TranslatingPort::readBlobFunctional(Addr addr, uint8_t *p, int size) +{ + Addr paddr; + + //@todo Break up things larger than a page size + pTable->page_check(addr, size); + + + if (!pTable->translate(addr,paddr)) + return Machine_Check_Fault; + + port->readBlobFunctional(paddr, p, size); + return No_Fault; +} + +Fault +TranslatingPort::writeBlobFunctional(Addr addr, const uint8_t *p, int size) +{ + Addr paddr; + + //@todo Break up things larger than a page size + pTable->page_check(addr, size); + + if (!pTable->translate(addr,paddr)) + return Machine_Check_Fault; + + port->writeBlobFunctional(paddr, p, size); + return No_Fault; +} + +Fault +TranslatingPort::memsetBlobFunctional(Addr addr, uint8_t val, int size) +{ + Addr paddr; + + //@todo Break up things larger than a page size + pTable->page_check(addr, size); + + if (!pTable->translate(addr,paddr)) + return Machine_Check_Fault; + + port->memsetBlobFunctional(paddr, val, size); + return No_Fault; +} + +Fault +TranslatingPort::writeStringFunctional(Addr addr, const char *str) +{ + //@todo Break up things larger than a page size + //pTable->page_check(addr, size); + //Need to check string length??? + + Addr paddr; + + if (!pTable->translate(addr,paddr)) + return Machine_Check_Fault; + + port->writeStringFunctional(paddr, str); + return No_Fault; +} + +Fault +TranslatingPort::readStringFunctional(std::string &str, Addr addr) +{ + //@todo Break up things larger than a page size + //pTable->page_check(addr, size); + //Need to check string length??? + + Addr paddr; + + if (!pTable->translate(addr,paddr)) + return Machine_Check_Fault; + + //@todo Break this up into readBlobs + port->readStringFunctional(str, paddr); + return No_Fault; +} + diff --git a/mem/translating_port.hh b/mem/translating_port.hh new file mode 100644 index 000000000..20140d26a --- /dev/null +++ b/mem/translating_port.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2001-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 __MEM_TRANSLATING_PROT_HH__ +#define __MEM_TRANSLATING_PROT_HH__ + +#include "mem/memory.hh" + +class Port; +class PageTable; + +class TranslatingPort +{ + private: + Port *port; + PageTable *pTable; + + TranslatingPort(const TranslatingPort &specmem); + const TranslatingPort &operator=(const TranslatingPort &specmem); + + public: + TranslatingPort(Port *_port, PageTable *p_table); + virtual ~TranslatingPort(); + + public: + Fault readBlobFunctional(Addr addr, uint8_t *p, int size); + Fault writeBlobFunctional(Addr addr, const uint8_t *p, int size); + Fault memsetBlobFunctional(Addr addr, uint8_t val, int size); + Fault writeStringFunctional(Addr addr, const char *str); + Fault readStringFunctional(std::string &str, Addr addr); + +}; + +#endif diff --git a/sim/process.cc b/sim/process.cc index 26d6bf708..2355fdc19 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -154,7 +154,7 @@ Process::startup() if (execContexts.empty()) fatal("Process %s is not associated with any CPUs!\n", name()); - initVirtMem = new ProxyMemory(system->physmem, pTable); + initVirtMem = new ProxyMemory(system->physmem, pTable); // first exec context for this process... initialize & enable ExecContext *xc = execContexts[0]; @@ -249,7 +249,7 @@ copyStringArray(vector &strings, Addr array_ptr, Addr data_ptr, { for (int i = 0; i < strings.size(); ++i) { func->prot_write(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr)); - func->writeString(data_ptr, strings[i].c_str()); + func->writeStringFunctional(data_ptr, strings[i].c_str()); array_ptr += sizeof(Addr); data_ptr += strings[i].size() + 1; } diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 78b4201d4..0cebee0e1 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -128,7 +128,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); if (bytes_read != -1) - bufArg.copyOut(xc->cpu->memPort); + bufArg.copyOut(xc->port); return bytes_read; } @@ -140,7 +140,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int nbytes = xc->getSyscallArg(2); BufferArg bufArg(xc->getSyscallArg(1), nbytes); - bufArg.copyIn(xc->cpu->memPort); + bufArg.copyIn(xc->port); int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); @@ -181,7 +181,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) strncpy((char *)name.bufferPtr(), hostname, name_len); - name.copyOut(xc->cpu->memPort); + name.copyOut(xc->port); return 0; } @@ -191,7 +191,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) return (TheISA::IntReg)-EFAULT; int result = unlink(path.c_str()); @@ -203,12 +203,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string old_name; - if (xc->cpu->memPort->readStringFunctional(old_name, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(old_name, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; string new_name; - if (xc->cpu->memPort->readStringFunctional(new_name, xc->getSyscallArg(1)) != No_Fault) + if (xc->port->readStringFunctional(new_name, xc->getSyscallArg(1)) != No_Fault) return -EFAULT; int64_t result = rename(old_name.c_str(), new_name.c_str()); @@ -220,7 +220,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; off_t length = xc->getSyscallArg(1); @@ -248,7 +248,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; /* XXX endianess */ diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 04b7bbe1c..ed3b0fc8b 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -43,7 +43,7 @@ #include #include "base/intmath.hh" // for RoundUp -#include "mem/port.hh" +#include "mem/translating_port.hh" #include "targetarch/isa_traits.hh" // for Addr #include "base/trace.hh" @@ -104,7 +104,7 @@ class BaseBufferArg { // // copy data into simulator space (read from target memory) // - virtual bool copyIn(Port *memport) + virtual bool copyIn(TranslatingPort *memport) { memport->readBlobFunctional(addr, bufPtr, size); return true; // no EFAULT detection for now @@ -113,7 +113,7 @@ class BaseBufferArg { // // copy data out of simulator space (write to target memory) // - virtual bool copyOut(Port *memport) + virtual bool copyOut(TranslatingPort *memport) { memport->writeBlobFunctional(addr, bufPtr, size); return true; // no EFAULT detection for now @@ -315,11 +315,8 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; -*/ - //@todo Fix fault condition - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); if (path == "/dev/sysdev0") { // This is a memory-mapped high-resolution timer device on Alpha. @@ -365,11 +362,8 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* - if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; -*/ - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); uint32_t mode = xc->getSyscallArg(1); mode_t hostMode = 0; @@ -421,11 +415,8 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* - if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) - return -EFAULT; */ - - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; struct stat hostBuf; int result = stat(path.c_str(), &hostBuf); @@ -433,7 +424,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatBuf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -457,7 +448,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStat64Buf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -471,10 +462,8 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) - return -EFAULT;*/ - - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; struct stat hostBuf; int result = lstat(path.c_str(), &hostBuf); @@ -482,7 +471,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -495,10 +484,8 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) - return -EFAULT; */ - - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; struct stat64 hostBuf; int result = lstat64(path.c_str(), &hostBuf); @@ -506,7 +493,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -530,7 +517,7 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -544,10 +531,8 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) - return -EFAULT;*/ - - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; struct statfs hostBuf; int result = statfs(path.c_str(), &hostBuf); @@ -555,7 +540,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatfsBuf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -578,7 +563,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatfsBuf(xc->cpu->memPort, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->port, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -602,12 +587,12 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, for (int i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; - xc->cpu->memPort->readBlobFunctional(tiov_base + i*sizeof(typename OS::tgt_iovec), + xc->port->readBlobFunctional(tiov_base + i*sizeof(typename OS::tgt_iovec),(uint8_t*) &tiov, sizeof(typename OS::tgt_iovec)); hiov[i].iov_len = tiov.iov_len; hiov[i].iov_base = new char [hiov[i].iov_len]; - xc->cpu->memPort->readBlobFunctional(tiov.iov_base, - hiov[i].iov_base, hiov[i].iov_len); + xc->port->readBlobFunctional(tiov.iov_base, + (uint8_t *)hiov[i].iov_base, hiov[i].iov_len); } int result = writev(process->sim_fd(fd), hiov, count); @@ -687,7 +672,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, break; } - rlp.copyOut(xc->cpu->memPort); + rlp.copyOut(xc->port); return 0; } @@ -702,7 +687,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, getElapsedTime(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; - tp.copyOut(xc->cpu->memPort); + tp.copyOut(xc->port); return 0; } @@ -716,13 +701,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; -/* if (xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) - return -EFAULT;*/ - - xc->cpu->memPort->readStringFunctional(path, xc->getSyscallArg(0)); + if (xc->port->readStringFunctional(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; TypedBufferArg tp(xc->getSyscallArg(1)); - tp.copyIn(xc->cpu->memPort); + tp.copyIn(xc->port); struct timeval hostTimeval[2]; for (int i = 0; i < 2; ++i) @@ -772,7 +755,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, rup->ru_nvcsw = 0; rup->ru_nivcsw = 0; - rup.copyOut(xc->cpu->memPort); + rup.copyOut(xc->port); return 0; } -- 2.30.2