From 89bb4f7e373e79635ee818412c5498e37f986e24 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Mar 2020 01:43:46 -0700 Subject: [PATCH] arm: Make semihosting use virtual addresses. This is in accordance with the spec. To successfully translate requests which need their secure flag set, build a translating port proxy with that flag enabled. Change-Id: I6ceec12aed297c57831a368a74d8b4e41f86f4c9 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26624 Reviewed-by: Nikos Nikoleris Maintainer: Giacomo Travaglini Tested-by: kokoro --- src/arch/arm/semihosting.cc | 41 ++++++++++++++++++++++--------------- src/arch/arm/semihosting.hh | 8 ++++---- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc index 7b7592f92..7718cd002 100644 --- a/src/arch/arm/semihosting.cc +++ b/src/arch/arm/semihosting.cc @@ -45,9 +45,11 @@ #include "debug/Semihosting.hh" #include "dev/serial/serial.hh" #include "mem/physical.hh" -#include "mem/secure_port_proxy.hh" +#include "mem/se_translating_port_proxy.hh" +#include "mem/translating_port_proxy.hh" #include "params/ArmSemihosting.hh" #include "sim/byteswap.hh" +#include "sim/full_system.hh" #include "sim/pseudo_inst.hh" #include "sim/sim_exit.hh" #include "sim/system.hh" @@ -237,21 +239,28 @@ ArmSemihosting::unserialize(CheckpointIn &cp) } PortProxy & -ArmSemihosting::physProxy(ThreadContext *tc) +ArmSemihosting::portProxy(ThreadContext *tc) { - static std::unique_ptr phys_proxy_s; + static std::unique_ptr port_proxy_s; static System *secure_sys = nullptr; if (ArmISA::inSecureState(tc)) { System *sys = tc->getSystemPtr(); if (sys != secure_sys) { - phys_proxy_s.reset(new SecurePortProxy(sys->getSystemPort(), - sys->cacheLineSize())); + if (FullSystem) { + port_proxy_s.reset( + new TranslatingPortProxy(tc, Request::SECURE)); + } else { + port_proxy_s.reset( + new SETranslatingPortProxy( + tc, SETranslatingPortProxy::NextPage, + Request::SECURE)); + } } secure_sys = sys; - return *phys_proxy_s; + return *port_proxy_s; } else { - return tc->getPhysProxy(); + return tc->getVirtProxy(); } } @@ -262,7 +271,7 @@ ArmSemihosting::readString(ThreadContext *tc, Addr ptr, size_t len) std::vector buf(len + 1); buf[len] = '\0'; - physProxy(tc).readBlob(ptr, buf.data(), len); + portProxy(tc).readBlob(ptr, buf.data(), len); return std::string(buf.data()); } @@ -320,7 +329,7 @@ ArmSemihosting::callClose(ThreadContext *tc, uint64_t handle) ArmSemihosting::RetErrno ArmSemihosting::callWriteC(ThreadContext *tc, InPlaceArg arg) { - const char c = physProxy(tc).read(arg.addr); + const char c = portProxy(tc).read(arg.addr); DPRINTF(Semihosting, "Semihosting SYS_WRITEC('%c')\n", c); std::cout.put(c); @@ -332,7 +341,7 @@ ArmSemihosting::RetErrno ArmSemihosting::callWrite0(ThreadContext *tc, InPlaceArg arg) { DPRINTF(Semihosting, "Semihosting SYS_WRITE0(...)\n"); - PortProxy &proxy = physProxy(tc); + PortProxy &proxy = portProxy(tc); std::string str; proxy.readString(str, arg.addr); std::cout.write(str.c_str(), str.size()); @@ -348,7 +357,7 @@ ArmSemihosting::callWrite(ThreadContext *tc, uint64_t handle, Addr addr, return RetErrno(size, EBADF); std::vector buffer(size); - physProxy(tc).readBlob(addr, buffer.data(), buffer.size()); + portProxy(tc).readBlob(addr, buffer.data(), buffer.size()); int64_t ret = files[handle]->write(buffer.data(), buffer.size()); if (ret < 0) { @@ -375,7 +384,7 @@ ArmSemihosting::callRead(ThreadContext *tc, uint64_t handle, Addr addr, } else { panic_if(ret > buffer.size(), "Read longer than buffer size."); - physProxy(tc).writeBlob(addr, buffer.data(), ret); + portProxy(tc).writeBlob(addr, buffer.data(), ret); // Return the number of bytes not written return retOK(size - ret); @@ -449,7 +458,7 @@ ArmSemihosting::callTmpNam(ThreadContext *tc, Addr addr, uint64_t id, if (path_len >= size) return retError(ENOSPC); - physProxy(tc).writeBlob(addr, path, path_len + 1); + portProxy(tc).writeBlob(addr, path, path_len + 1); return retOK(0); } @@ -512,7 +521,7 @@ ArmSemihosting::RetErrno ArmSemihosting::callGetCmdLine(ThreadContext *tc, Addr addr, InPlaceArg size_arg) { - PortProxy &proxy = physProxy(tc); + PortProxy &proxy = portProxy(tc); ByteOrder endian = ArmISA::byteOrder(tc); size_t size = size_arg.read(tc, endian); @@ -576,7 +585,7 @@ ArmSemihosting::callHeapInfo32(ThreadContext *tc, Addr block_addr) (uint32_t)heap_base, (uint32_t)heap_limit, (uint32_t)stack_base, (uint32_t)stack_limit }; - physProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc)); + portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc)); return retOK(0); } @@ -590,7 +599,7 @@ ArmSemihosting::callHeapInfo64(ThreadContext *tc, Addr block_addr) std::array block = { heap_base, heap_limit, stack_base, stack_limit }; - physProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc)); + portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc)); return retOK(0); } diff --git a/src/arch/arm/semihosting.hh b/src/arch/arm/semihosting.hh index e255d201b..83d41fd42 100644 --- a/src/arch/arm/semihosting.hh +++ b/src/arch/arm/semihosting.hh @@ -73,7 +73,7 @@ class ArmSemihosting : public SimObject { public: - static PortProxy &physProxy(ThreadContext *tc); + static PortProxy &portProxy(ThreadContext *tc); struct AbiBase { @@ -110,7 +110,7 @@ class ArmSemihosting : public SimObject Arg get(ThreadContext *tc) { - Arg arg = ArmSemihosting::physProxy(tc).read( + Arg arg = ArmSemihosting::portProxy(tc).read( argPointer, endian); argPointer += sizeof(Arg); return arg; @@ -159,7 +159,7 @@ class ArmSemihosting : public SimObject uint64_t read(ThreadContext *tc, ByteOrder endian) { - auto &proxy = ArmSemihosting::physProxy(tc); + auto &proxy = ArmSemihosting::portProxy(tc); if (size == 8) return proxy.read(addr, endian); else if (size == 4) @@ -172,7 +172,7 @@ class ArmSemihosting : public SimObject void write(ThreadContext *tc, uint64_t val, ByteOrder endian) { - auto &proxy = ArmSemihosting::physProxy(tc); + auto &proxy = ArmSemihosting::portProxy(tc); if (size == 8) proxy.write(addr, val, endian); else if (size == 4) -- 2.30.2