[gem5-dev] [S] Change in gem5/gem5[develop]: base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69677?usp=email ) Change subject: base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path. .. base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path. Normally this would just generate a warning, but a warning is easy to miss, and truncating the path to fit would be surprising. Since the max length isn't likely to change, a path which has to be truncated is essentially fundementally wrong, and could be defined as something else which is short enough before being used in the config. Note that this only applies to either the abstract path which is just a string, or the file name and not the directory path on a file based socket. Change-Id: I8702cf02c03053b5d0b6133f25b0e588de666f15 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69677 Maintainer: Gabe Black Reviewed-by: Earl Ou Tested-by: kokoro --- M src/base/socket.cc M src/base/socket.hh 2 files changed, 10 insertions(+), 13 deletions(-) Approvals: Gabe Black: Looks good to me, approved kokoro: Regressions pass Earl Ou: Looks good to me, approved diff --git a/src/base/socket.cc b/src/base/socket.cc index 76dc73f..62f2071 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -261,15 +261,12 @@ }); } -std::string -ListenSocketUnix::truncate(const std::string , size_t max_len) +void +ListenSocketUnix::checkPathLength(const std::string , size_t max_len) { -if (original.size() <= max_len) -return original; - -std::string truncated = original.substr(0, max_len); -warn("%s: Truncated \"%s\" to \"%s\"", name(), original, truncated); -return truncated; +fatal_if(original.size() > max_len, +"Length of socket path '%s' is %d, greater than max %d.", +original, original.size(), max_len); } void @@ -303,9 +300,9 @@ ListenSocketUnixFile::ListenSocketUnixFile(const std::string &_name, const std::string &_dir, const std::string &_fname) : -ListenSocketUnix(_name), dir(_dir), -fname(truncate(_fname, sizeof(sockaddr_un::sun_path) - 1)) +ListenSocketUnix(_name), dir(_dir), fname(_fname) { +checkPathLength(fname, sizeof(sockaddr_un::sun_path) - 1); } ListenSocketUnixFile::~ListenSocketUnixFile() @@ -385,9 +382,9 @@ ListenSocketUnixAbstract::ListenSocketUnixAbstract( const std::string &_name, const std::string &_path) : -ListenSocketUnix(_name), -path(truncate(_path, sizeof(sockaddr_un::sun_path) - 1)) +ListenSocketUnix(_name), path(_path) { +checkPathLength(path, sizeof(sockaddr_un::sun_path) - 1); } void diff --git a/src/base/socket.hh b/src/base/socket.hh index b8828e7..bc17213 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -162,7 +162,7 @@ protected: virtual size_t prepSockaddrUn(sockaddr_un ) const = 0; -std::string truncate(const std::string , size_t max_len); +void checkPathLength(const std::string , size_t max_len); ListenSocketUnix(const std::string &_name) : ListenSocket(_name) {} -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69677?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I8702cf02c03053b5d0b6133f25b0e588de666f15 Gerrit-Change-Number: 69677 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Chia-You Chen Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jesse Pai Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69677?usp=email ) Change subject: base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path. .. base: fatal() if a socket path doesn't fit in sockaddr_un.sun_path. Normally this would just generate a warning, but a warning is easy to miss, and truncating the path to fit would be surprising. Since the max length isn't likely to change, a path which has to be truncated is essentially fundementally wrong, and could be defined as something else which is short enough before being used in the config. Note that this only applies to either the abstract path which is just a string, or the file name and not the directory path on a file based socket. Change-Id: I8702cf02c03053b5d0b6133f25b0e588de666f15 --- M src/base/socket.cc M src/base/socket.hh 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index 76dc73f..62f2071 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -261,15 +261,12 @@ }); } -std::string -ListenSocketUnix::truncate(const std::string , size_t max_len) +void +ListenSocketUnix::checkPathLength(const std::string , size_t max_len) { -if (original.size() <= max_len) -return original; - -std::string truncated = original.substr(0, max_len); -warn("%s: Truncated \"%s\" to \"%s\"", name(), original, truncated); -return truncated; +fatal_if(original.size() > max_len, +"Length of socket path '%s' is %d, greater than max %d.", +original, original.size(), max_len); } void @@ -303,9 +300,9 @@ ListenSocketUnixFile::ListenSocketUnixFile(const std::string &_name, const std::string &_dir, const std::string &_fname) : -ListenSocketUnix(_name), dir(_dir), -fname(truncate(_fname, sizeof(sockaddr_un::sun_path) - 1)) +ListenSocketUnix(_name), dir(_dir), fname(_fname) { +checkPathLength(fname, sizeof(sockaddr_un::sun_path) - 1); } ListenSocketUnixFile::~ListenSocketUnixFile() @@ -385,9 +382,9 @@ ListenSocketUnixAbstract::ListenSocketUnixAbstract( const std::string &_name, const std::string &_path) : -ListenSocketUnix(_name), -path(truncate(_path, sizeof(sockaddr_un::sun_path) - 1)) +ListenSocketUnix(_name), path(_path) { +checkPathLength(path, sizeof(sockaddr_un::sun_path) - 1); } void diff --git a/src/base/socket.hh b/src/base/socket.hh index b8828e7..bc17213 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -162,7 +162,7 @@ protected: virtual size_t prepSockaddrUn(sockaddr_un ) const = 0; -std::string truncate(const std::string , size_t max_len); +void checkPathLength(const std::string , size_t max_len); ListenSocketUnix(const std::string &_name) : ListenSocket(_name) {} -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69677?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I8702cf02c03053b5d0b6133f25b0e588de666f15 Gerrit-Change-Number: 69677 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: arch,base,dev,sim: Convert objects to use the HostSocket param type.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69166?usp=email ) Change subject: arch,base,dev,sim: Convert objects to use the HostSocket param type. .. arch,base,dev,sim: Convert objects to use the HostSocket param type. This will make it possible to connect any of these objects with a named socket, in addition to the usual port numbers. Change-Id: Id441c3628f62d60608a07c5cb697786e33199981 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69166 Reviewed-by: Jui-min Lee Tested-by: kokoro Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang --- M src/arch/arm/fastmodel/remote_gdb.cc M src/arch/arm/fastmodel/remote_gdb.hh M src/arch/arm/remote_gdb.cc M src/arch/arm/remote_gdb.hh M src/arch/mips/remote_gdb.cc M src/arch/mips/remote_gdb.hh M src/arch/power/remote_gdb.cc M src/arch/power/remote_gdb.hh M src/arch/riscv/remote_gdb.cc M src/arch/riscv/remote_gdb.hh M src/arch/sparc/remote_gdb.cc M src/arch/sparc/remote_gdb.hh M src/arch/x86/remote_gdb.cc M src/arch/x86/remote_gdb.hh M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/vnc/Vnc.py M src/base/vnc/vncserver.cc M src/dev/net/Ethernet.py M src/dev/net/ethertap.cc M src/dev/serial/Terminal.py M src/dev/serial/terminal.cc M src/sim/Workload.py 23 files changed, 44 insertions(+), 38 deletions(-) Approvals: Jui-min Lee: Looks good to me, but someone else must approve kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved diff --git a/src/arch/arm/fastmodel/remote_gdb.cc b/src/arch/arm/fastmodel/remote_gdb.cc index d8dddad..555439e 100644 --- a/src/arch/arm/fastmodel/remote_gdb.cc +++ b/src/arch/arm/fastmodel/remote_gdb.cc @@ -61,8 +61,9 @@ context->setMiscRegNoEffect(MISCREG_FPCR, r.fpcr); } -FastmodelRemoteGDB::FastmodelRemoteGDB(System *_system, int port) -: gem5::ArmISA::RemoteGDB(_system, port), regCache64(this) +FastmodelRemoteGDB::FastmodelRemoteGDB(System *_system, +ListenSocketConfig _listen_config) +: gem5::ArmISA::RemoteGDB(_system, _listen_config) { } diff --git a/src/arch/arm/fastmodel/remote_gdb.hh b/src/arch/arm/fastmodel/remote_gdb.hh index 75dc658..15b4e67 100644 --- a/src/arch/arm/fastmodel/remote_gdb.hh +++ b/src/arch/arm/fastmodel/remote_gdb.hh @@ -39,7 +39,7 @@ class FastmodelRemoteGDB : public ArmISA::RemoteGDB { public: -FastmodelRemoteGDB(System *_system, int port); +FastmodelRemoteGDB(System *_system, ListenSocketConfig _listen_config); protected: class AArch64GdbRegCache : public ArmISA::RemoteGDB::AArch64GdbRegCache diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc index c357f02..7dd3c3d 100644 --- a/src/arch/arm/remote_gdb.cc +++ b/src/arch/arm/remote_gdb.cc @@ -201,8 +201,9 @@ mmu->translateFunctional(req, tc, BaseMMU::Execute) == NoFault; } -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig _listen_config) +: BaseRemoteGDB(_system, _listen_config), +regCache32(this), regCache64(this) { } diff --git a/src/arch/arm/remote_gdb.hh b/src/arch/arm/remote_gdb.hh index aeb2db6..f6ec3db 100644 --- a/src/arch/arm/remote_gdb.hh +++ b/src/arch/arm/remote_gdb.hh @@ -118,7 +118,7 @@ AArch64GdbRegCache regCache64; public: -RemoteGDB(System *_system, int _port); +RemoteGDB(System *_system, ListenSocketConfig _listen_config); BaseGdbRegCache *gdbRegs() override; bool checkBpKind(size_t kind) override; std::vector diff --git a/src/arch/mips/remote_gdb.cc b/src/arch/mips/remote_gdb.cc index fcf31e1..f14305a 100644 --- a/src/arch/mips/remote_gdb.cc +++ b/src/arch/mips/remote_gdb.cc @@ -151,8 +151,8 @@ using namespace MipsISA; -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig _listen_config) +: BaseRemoteGDB(_system, _listen_config), regCache(this) { } diff --git a/src/arch/mips/remote_gdb.hh b/src/arch/mips/remote_gdb.hh index 6a38956..6fd193a 100644 --- a/src/arch/mips/remote_gdb.hh +++ b/src/arch/mips/remote_gdb.hh @@ -80,7 +80,7 @@ MipsGdbRegCache regCache; public: -RemoteGDB(System *_system, int _port); +RemoteGDB(System *_system, ListenSocketConfig _listen_config); BaseGdbRegCache *gdbRegs(); std::vector availableFeatures() const diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc index c69c571..14b9df4 100644 --- a/src/arch/power/remote_gdb.cc +++ b/src/arch/power/remote_gdb.cc @@ -155,8 +155,9 @@ using namespace PowerISA; -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Remove the now unused UnixSocketAddr class and associated code.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69169?usp=email ) Change subject: base: Remove the now unused UnixSocketAddr class and associated code. .. base: Remove the now unused UnixSocketAddr class and associated code. This job is now handled by the python param code, and the ListenSocket classes. Change-Id: I3a29b880b2484c5e25071bdef59fc73e1e8c2760 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69169 Tested-by: kokoro Maintainer: Gabe Black Reviewed-by: Simon Park --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 0 insertions(+), 167 deletions(-) Approvals: Simon Park: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/base/socket.cc b/src/base/socket.cc index a30c6af..76dc73f 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -61,75 +61,12 @@ namespace gem5 { -namespace -{ - -bool -isSocketNameAbstract(const std::string ) -{ -if (path.empty()) { -return false; -} -// No null byte should be present in the path -return path.front() == '@'; -} - -std::string -resolve(const std::string ) -{ -if (path.empty()) { -return path; -} -if (isSocketNameAbstract(path)) { -return '\0' + path.substr(1); -} -return simout.resolve(path); -} - -} // namespace bool ListenSocket::listeningDisabled = false; bool ListenSocket::anyListening = false; bool ListenSocket::bindToLoopback = false; -UnixSocketAddr -UnixSocketAddr::build(const std::string ) -{ -sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path = {}}; - -const bool is_abstract = isSocketNameAbstract(path); -size_t max_len = sizeof(addr.sun_path); -if (!is_abstract) { -// File based socket names need to be null terminated -max_len -= 1; -} - -std::string resolved_path = resolve(path); -std::string fmt_path = replace(resolved_path, '\0', '@'); -if (resolved_path.size() > max_len) { -resolved_path = resolved_path.substr(0, max_len); -const std::string untruncated_path = std::move(fmt_path); -fmt_path = replace(resolved_path, '\0', '@'); -warn("SocketPath: unix socket path truncated from '%s' to '%s'", - untruncated_path, fmt_path); -} - -// We can't use strncpy here, since abstract sockets start with \0 which -// will make strncpy think that the string is empty. -memcpy(addr.sun_path, resolved_path.c_str(), resolved_path.size()); -// We can't use sizeof(sockaddr_un) for abstract sockets, since all -// sizeof(sun_path) bytes are used in representing the path. -const size_t path_size = -is_abstract ? resolved_path.size() : sizeof(addr.sun_path); -const size_t addr_size = offsetof(sockaddr_un, sun_path) + path_size; - -return UnixSocketAddr{.addr = std::move(addr), - .addrSize = addr_size, - .isAbstract = is_abstract, - .formattedPath = std::move(fmt_path)}; -} - void ListenSocket::cleanup() { diff --git a/src/base/socket.hh b/src/base/socket.hh index 5ae02aa..b8828e7 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -43,37 +43,6 @@ namespace gem5 { -/** - * @brief Wrapper around sockaddr_un, so that it can be used for both file - * based unix sockets as well as abstract unix sockets. - */ -struct UnixSocketAddr -{ -/** - * @brief Builds UnixSocketAddr from the given path. - * @pre: `path` either represents a file based unix socket, or an abstract - * unix socket. If `path` represents an abstract socket, it should - * start with the character '@', and it should not have any null - * bytes in the name. - * @param path: Pathname, where the socket should be instantiated. - * @return UnixSocketAddr - */ -static UnixSocketAddr build(const std::string ); - -sockaddr_un addr; -// Size of `sockaddr_un addr`. This is equal to sizeof(sockaddr_un) if -// `addr` represents a normal file based unix socket. For abstract sockets -// however, the size could be different. Because all sizeof(sun_path) is -// used to represent the name of an abstract socket, addrSize for abstract -// sockets only count the number of characters actually used by sun_path, -// excluding any trailing null bytes. -size_t addrSize; -bool isAbstract; -// Formatted string for file based sockets look the same as addr.sun_path. -// For abstract sockets however, all null bytes are replaced with @ -std::string formattedPath; -}; - class ListenSocket : public Named { protected: diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index 7bf9e18..5fd0f3f 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -45,79
[gem5-dev] [M] Change in gem5/gem5[develop]: base,python: Add a param type for host sockets.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69165?usp=email ) Change subject: base,python: Add a param type for host sockets. .. base,python: Add a param type for host sockets. These can either be set to an integer, in which case it's interpreted as a TCP port, or a string, in which case it's treated as a unix domain socket. If the unix domain socket is prefixed with a "@", it will be treated as an abstract socket. When stored in the ini file, there is always a prefix added to make parsing the string more systematic and less ambiguous. A port number is prefixed with "#", an abstract socket with "@", and a socket file with the prefix "P" for "path". Change-Id: I1fc7a579074e849b3becd936238c62fb0d9a2087 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69165 Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black Tested-by: kokoro --- M src/base/socket.cc M src/base/socket.hh M src/python/m5/params.py M src/python/pybind11/core.cc 4 files changed, 102 insertions(+), 0 deletions(-) Approvals: kokoro: Regressions pass Gabe Black: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved diff --git a/src/base/socket.cc b/src/base/socket.cc index 0f47b2a..a30c6af 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -208,6 +208,32 @@ return sfd; } +bool +ListenSocketConfig::parseIni(const std::string , +ListenSocketConfig ) +{ +if (value.size() == 0) { +retval = listenSocketEmptyConfig(); +return true; +} else if (value[0] == '@') { +retval = listenSocketUnixAbstractConfig(value.substr(1)); +return true; +} else if (value[0] == 'P') { +std::filesystem::path p(value.substr(1)); +retval = listenSocketUnixFileConfig(p.parent_path(), p.filename()); +return true; +} else if (value[0] == '#') { +uint64_t port; +bool ret = to_number(value.substr(1), port); +if (!ret) +return false; +retval = listenSocketInetConfig(port); +return true; +} else { +panic("Can't interpret %s as a host socket.", value); +} +} + ListenSocketInet::ListenSocketInet(const std::string &_name, int port) : ListenSocket(_name), _port(port) {} diff --git a/src/base/socket.hh b/src/base/socket.hh index 33c1c3a..5ae02aa 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -159,6 +159,8 @@ operator bool() const { return (bool)builder; } +static bool parseIni(const std::string , ListenSocketConfig ); + private: Builder builder; }; diff --git a/src/python/m5/params.py b/src/python/m5/params.py index e9047a8..2ca6dfc 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1085,6 +1085,65 @@ code(f"{ret} to_bool({src}, {dest});") +class HostSocket(ParamValue): +cxx_type = "ListenSocketConfig" + +@classmethod +def cxx_predecls(cls, code): +code('#include "base/socket.hh"') + +def __init__(self, value): +if isinstance(value, HostSocket): +self.value = value.value +else: +self.value = value + +def getValue(self): +from _m5.socket import listenSocketEmptyConfig +from _m5.socket import listenSocketInetConfig +from _m5.socket import listenSocketUnixFileConfig +from _m5.socket import listenSocketUnixAbstractConfig + +if isinstance(self.value, str): +if self.value[0] == "@": +return listenSocketUnixAbstractConfig(self.value[1:]) +else: +d, f = os.path.split(self.value) +return listenSocketUnixFileConfig(d, f) +else: +if self.value == 0: +return listenSocketEmptyConfig() +else: +return listenSocketInetConfig(self.value) + +def __call__(self, value): +self.__init__(value) +return value + +def __str__(self): +if isinstance(self.value, str): +return self.value +else: +return "#" + str(self.value) + +def ini_str(self): +if isinstance(self.value, str): +if self.value[0] == "@": +return self.value +else: +return "P" + self.value +else: +return "#" + str(self.value) + +@classmethod +def cxx_ini_predecls(cls, code): +code('#include "base/socket.hh"') + +@classmethod +def cxx_ini_parse(cls, code, src, dest, ret): +code(f"{ret} ListenSocketConfig::parseIni({src}, {dest});") + + def IncEthernetAddr(addr, val=1): bytes = [int(x, 16) for x in addr.split(":")] bytes[5] += val diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc index bd83a74..0b03d5a 100644 --- a/src/python/pybind11/core.cc +++ b/src/python/pybind11/core.cc @@ -223,6 +223,20 @@
[gem5-dev] [M] Change in gem5/gem5[develop]: mem: Use HostSocket in the SharedMemoryServer.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69168?usp=email ) ( 6 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: mem: Use HostSocket in the SharedMemoryServer. .. mem: Use HostSocket in the SharedMemoryServer. Use a HostSocket parameter to accept connections, rather than a hand implementation for unix domain sockets. This consolidates this code with the code derived from it in ListenSocket, and also makes it possible to connect to the SharedMemoryServer over an AF_INET socket. Change-Id: I8e05434d08cffaebdf6c68a967e2ee7613c10a76 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69168 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Jui-min Lee --- M src/mem/shared_memory_server.cc M src/mem/shared_memory_server.hh 2 files changed, 26 insertions(+), 45 deletions(-) Approvals: Gabe Black: Looks good to me, approved kokoro: Regressions pass Jui-min Lee: Looks good to me, approved diff --git a/src/mem/shared_memory_server.cc b/src/mem/shared_memory_server.cc index 6344ee0..3e49164 100644 --- a/src/mem/shared_memory_server.cc +++ b/src/mem/shared_memory_server.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include "base/logging.hh" #include "base/output.hh" @@ -49,54 +50,37 @@ namespace memory { +namespace +{ + +ListenSocketPtr +buildListenSocket(const std::string , const std::string ) +{ +fatal_if(path.empty(), "%s: Empty socket path", name); +if (path[0] == '@') +return listenSocketUnixAbstractConfig(path.substr(1)).build(name); + +std::filesystem::path p(path); +return listenSocketUnixFileConfig( +p.parent_path(), p.filename()).build(name); +} + +} // anonymous namespace + SharedMemoryServer::SharedMemoryServer(const SharedMemoryServerParams& params) : SimObject(params), - sockAddr(UnixSocketAddr::build(params.server_path)), system(params.system), - serverFd(-1) + listener(buildListenSocket(params.server_path, name())) { fatal_if(system == nullptr, "Requires a system to share memory from!"); -// Create a new unix socket. -serverFd = ListenSocket::socketCloexec(AF_UNIX, SOCK_STREAM, 0); -panic_if(serverFd < 0, "%s: cannot create unix socket: %s", name(), - strerror(errno)); +listener->listen(); -const auto& [serv_addr, addr_size, is_abstract, formatted_path] = sockAddr; - -if (!is_abstract) { -// Ensure the unix socket path to use is not occupied. Also, if there's -// actually anything to be removed, warn the user something might be -// off. -bool old_sock_removed = unlink(serv_addr.sun_path) == 0; -warn_if(old_sock_removed, -"%s: server path %s was occupied and will be replaced. Please " -"make sure there is no other server using the same path.", -name(), serv_addr.sun_path); -} -int bind_retv = bind( -serverFd, reinterpret_cast(_addr), addr_size); -fatal_if(bind_retv != 0, "%s: cannot bind unix socket '%s': %s", name(), - formatted_path, strerror(errno)); -// Start listening. -int listen_retv = listen(serverFd, 1); -fatal_if(listen_retv != 0, "%s: listen failed: %s", name(), - strerror(errno)); -listenSocketEvent.reset(new ListenSocketEvent(serverFd, this)); +listenSocketEvent.reset(new ListenSocketEvent(listener->getfd(), this)); pollQueue.schedule(listenSocketEvent.get()); -inform("%s: listening at %s", name(), formatted_path); +inform("%s: listening at %s", name(), *listener); } -SharedMemoryServer::~SharedMemoryServer() -{ -if (!sockAddr.isAbstract) { -int unlink_retv = unlink(sockAddr.addr.sun_path); -warn_if(unlink_retv != 0, "%s: cannot unlink unix socket: %s", name(), -strerror(errno)); -} -int close_retv = close(serverFd); -warn_if(close_retv != 0, "%s: cannot close unix socket: %s", name(), -strerror(errno)); -} +SharedMemoryServer::~SharedMemoryServer() {} SharedMemoryServer::BaseShmPollEvent::BaseShmPollEvent( int fd, SharedMemoryServer* shm_server) @@ -130,10 +114,7 @@ void SharedMemoryServer::ListenSocketEvent::process(int revents) { -panic_if(revents & (POLLERR | POLLNVAL), "%s: listen socket is broken", - name()); -int cli_fd = ListenSocket::acceptCloexec(pfd.fd, nullptr, nullptr); -panic_if(cli_fd < 0, "%s: accept failed: %s", name(), strerror(errno)); +int cli_fd = shmServer->listener->accept(); inform("%s: accept new connection %d", name(), cli_fd); shmServer->clientSocketEvents[cli_fd].reset( new ClientSocketEvent(cli_fd, shmServer)); diff --git a/src/mem/shared_memory_server.hh
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Add support for unix domain sockets in ListenSocket.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69164?usp=email ) Change subject: base: Add support for unix domain sockets in ListenSocket. .. base: Add support for unix domain sockets in ListenSocket. Change-Id: I6a5fa2cd3e4b567829203bf9d61ad2b55c259697 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69164 Tested-by: kokoro Maintainer: Bobby Bruce Reviewed-by: Jui-min Lee --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 207 insertions(+), 4 deletions(-) Approvals: kokoro: Regressions pass Jui-min Lee: Looks good to me, approved Bobby Bruce: Looks good to me, approved diff --git a/src/base/socket.cc b/src/base/socket.cc index 13962d4..2e9f815 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -39,6 +39,7 @@ #include #include +#include #include "base/logging.hh" #include "base/output.hh" @@ -187,10 +188,10 @@ ListenSocket::accept() { struct sockaddr_in sockaddr; -socklen_t slen = sizeof (sockaddr); +socklen_t slen = sizeof(sockaddr); int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd == -1) -return -1; +panic_if(sfd == -1, "%s: Failed to accept connection: %s", +name(), strerror(errno)); return sfd; } @@ -285,4 +286,147 @@ }); } +std::string +ListenSocketUnix::truncate(const std::string , size_t max_len) +{ +if (original.size() <= max_len) +return original; + +std::string truncated = original.substr(0, max_len); +warn("%s: Truncated \"%s\" to \"%s\"", name(), original, truncated); +return truncated; +} + +void +ListenSocketUnix::listen() +{ +panic_if(listening, "%s: Socket already listening!", name()); + +// only create socket if not already created by previous call +if (fd == -1) { +fd = socketCloexec(PF_UNIX, SOCK_STREAM, 0); +panic_if(fd < 0, "%s: Can't create unix socket:%s !", +name(), strerror(errno)); +} + +sockaddr_un serv_addr; +std::memset(_addr, 0, sizeof(serv_addr)); +size_t addr_size = prepSockaddrUn(serv_addr); + +fatal_if(bind(fd, (struct sockaddr *)&(serv_addr), addr_size) != 0, +"%s: Cannot bind unix socket %s: %s", name(), *this, +strerror(errno)); + +fatal_if(::listen(fd, 1) == -1, "%s: Failed to listen on %s: %s\n", +name(), *this, strerror(errno)); + +ccprintf(std::cerr, "%s: Listening for connections on %s\n", +name(), *this); + +setListening(); +} + +ListenSocketUnixFile::ListenSocketUnixFile(const std::string &_name, +const std::string &_dir, const std::string &_fname) : +ListenSocketUnix(_name), dir(_dir), +fname(truncate(_fname, sizeof(sockaddr_un::sun_path) - 1)) +{ +} + +ListenSocketUnixFile::~ListenSocketUnixFile() +{ +if (fd != -1) { +close(fd); +fd = -1; +unlink(); +} +} + +bool +ListenSocketUnixFile::unlink() const +{ +auto path = resolvedDir + "/" + fname; +return ::unlink(path.c_str()) == 0; +} + +size_t +ListenSocketUnixFile::prepSockaddrUn(sockaddr_un ) const +{ +addr.sun_family = AF_UNIX; +std::memcpy(addr.sun_path, fname.c_str(), fname.size()); +return sizeof(addr.sun_path); +} + +void +ListenSocketUnixFile::listen() +{ +resolvedDir = simout.resolve(dir); +warn_if(unlink(), +"%s: server path %s was occupied and will be replaced. Please " +"make sure there is no other server using the same path.", +name(), resolvedDir + "/" + fname); + +// Make sure "dir" exists. +std::error_code ec; +std::filesystem::create_directory(resolvedDir, ec); +fatal_if(ec, "Failed to create directory %s", ec.message()); + +// Change the working directory to the directory containing the socket so +// that we maximize the limited space in sockaddr_un.sun_path. +auto cwd = std::filesystem::current_path(ec); +panic_if(ec, "Failed to get current working directory %s", ec.message()); +std::filesystem::current_path(resolvedDir, ec); +fatal_if(ec, "Failed to change to directory %s: %s", +resolvedDir, ec.message()); + +ListenSocketUnix::listen(); + +std::filesystem::current_path(cwd, ec); +panic_if(ec, "Failed to change back working directory %s", ec.message()); +} + +void +ListenSocketUnixFile::output(std::ostream ) const +{ +os << "socket \"" << dir << "/" << fname << "\""; +} + +ListenSocketConfig +listenSocketUnixFileConfig(std::string dir, std::string fname) +{ +return ListenSocketConfig([dir, fname](const std::string ) { +return std::make_unique(name, dir, fname); +}); +} + +size_t +ListenSocketUnixAbstract::prepSockaddrUn(sockaddr_un ) const +{ +addr.sun_family = AF_UNIX; +addr.sun_path[0] = '\0'; +std::memcpy(_path[1], path.c_str(), path.size()); +return
[gem5-dev] [XS] Change in gem5/gem5[develop]: util: Add a missing free() to m5term.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69557?usp=email ) Change subject: util: Add a missing free() to m5term. .. util: Add a missing free() to m5term. The "cwd" string is used to store the previous working directory, if m5term needs to change it to maximize the space it has to create a unix domain socket using a relative path. That string was not being freed, which is a small memory leak. This change frees that memory. Change-Id: I1ad901e7c59614dd938165cae91c3f666d86e872 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69557 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Jason Lowe-Power --- M util/term/term.c 1 file changed, 1 insertion(+), 0 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/util/term/term.c b/util/term/term.c index cf3fdda..b1624b2 100644 --- a/util/term/term.c +++ b/util/term/term.c @@ -235,6 +235,7 @@ perror("chdir back failed:"); exit(1); } +free(cwd); } // Return the FD of our new connection. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69557?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I1ad901e7c59614dd938165cae91c3f666d86e872 Gerrit-Change-Number: 69557 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jason Lowe-Power Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [XS] Change in gem5/gem5[develop]: util: Add a missing free() to m5term.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69557?usp=email ) Change subject: util: Add a missing free() to m5term. .. util: Add a missing free() to m5term. The "cwd" string is used to store the previous working directory, if m5term needs to change it to maximize the space it has to create a unix domain socket using a relative path. That string was not being freed, which is a small memory leak. This change frees that memory. Change-Id: I1ad901e7c59614dd938165cae91c3f666d86e872 --- M util/term/term.c 1 file changed, 1 insertion(+), 0 deletions(-) diff --git a/util/term/term.c b/util/term/term.c index cf3fdda..b1624b2 100644 --- a/util/term/term.c +++ b/util/term/term.c @@ -235,6 +235,7 @@ perror("chdir back failed:"); exit(1); } +free(cwd); } // Return the FD of our new connection. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69557?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I1ad901e7c59614dd938165cae91c3f666d86e872 Gerrit-Change-Number: 69557 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add an "abortPending" method to the DMA port class.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69437?usp=email ) Change subject: dev: Add an "abortPending" method to the DMA port class. .. dev: Add an "abortPending" method to the DMA port class. This will abort any pending transactions that have been given to the port. Change-Id: Ie5f2c702530656a0c4590461369d430abead14cd Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69437 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Gabe Black --- M src/dev/dma_device.cc M src/dev/dma_device.hh 2 files changed, 86 insertions(+), 17 deletions(-) Approvals: Gabe Black: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc index ebda635..24e931e 100644 --- a/src/dev/dma_device.cc +++ b/src/dev/dma_device.cc @@ -81,6 +81,8 @@ void DmaPort::handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay) { +assert(pendingCount != 0); +pendingCount--; DPRINTF(DMA, "Received response %s for addr: %#x size: %d nb: %d," \ " tot: %d sched %d\n", MemCmd(state->cmd).toString(), addr, size, @@ -93,11 +95,22 @@ state->numBytes += size; assert(state->totBytes >= state->numBytes); -// If we have reached the total number of bytes for this DMA request, -// then signal the completion and delete the sate. -if (state->totBytes == state->numBytes) { -assert(pendingCount != 0); -pendingCount--; +bool all_bytes = (state->totBytes == state->numBytes); +if (state->aborted) { +// If this request was aborted, check to see if its in flight accesses +// have finished. There may be packets for more than one request in +// flight at a time, so check for finished requests, or no more +// packets. +if (all_bytes || pendingCount == 0) { +// If yes, signal its abort event (if any) and delete the state. +if (state->abortEvent) { +device->schedule(state->abortEvent, curTick()); +} +delete state; +} +} else if (all_bytes) { +// If we have reached the end of this DMA request, then signal the +// completion and delete the sate. if (state->completionEvent) { delay += state->delay; device->schedule(state->completionEvent, curTick() + delay); @@ -166,8 +179,9 @@ void DmaPort::recvReqRetry() { -assert(transmitList.size()); -trySendTimingReq(); +retryPending = false; +if (transmitList.size()) +trySendTimingReq(); } void @@ -184,7 +198,6 @@ transmitList.push_back( new DmaReqState(cmd, addr, cacheLineSize, size, data, flag, requestorId, sid, ssid, event, delay)); -pendingCount++; // In zero time, also initiate the sending of the packets for the request // we have just created. For atomic this involves actually completing all @@ -201,6 +214,42 @@ } void +DmaPort::abortPending() +{ +if (inRetry) { +delete inRetry; +inRetry = nullptr; +} + +if (pendingCount && !transmitList.empty()) { +auto *state = transmitList.front(); +if (state->numBytes != state->gen.complete()) { +// In flight packets refer to the transmission at the front of the +// list, and not a transmission whose packets have all been sent +// but not completed. Preserve the state so the packets don't have +// dangling pointers. +transmitList.pop_front(); +state->aborted = true; +} +} + +// Get rid of requests that haven't started yet. +while (!transmitList.empty()) { +auto *state = transmitList.front(); +if (state->abortEvent) +device->schedule(state->abortEvent, curTick()); +delete state; +transmitList.pop_front(); +} + +if (sendEvent.scheduled()) +device->deschedule(sendEvent); + +if (pendingCount == 0) +signalDrainDone(); +} + +void DmaPort::trySendTimingReq() { // Send the next packet for the first DMA request on the transmit list, @@ -216,14 +265,17 @@ // Check if this was the last packet now, since hypothetically the packet // response may come immediately, and state may be deleted. bool last = state->gen.last(); -if (!sendTimingReq(pkt)) +if (sendTimingReq(pkt)) { +pendingCount++; +} else { +retryPending = true; inRetry = pkt; -if (!inRetry) { +} +if (!retryPending) { +state->gen.next(); // If that was the last packet from this request, pop it from the list. if (last) transmitList.pop_front(); -else -state->gen.next(); DPRINTF(DMA, "-- Done\n"); // If
[gem5-dev] [M] Change in gem5/gem5[develop]: util: Make m5term able to connect to unix domain sockets.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69167?usp=email ) ( 6 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: util: Make m5term able to connect to unix domain sockets. .. util: Make m5term able to connect to unix domain sockets. To connect to a unix domain socket, it must start with a non-digit character to avoid being confused with a TCP port. If it starts with an "@" character, then it is treated as an abstract socket. Change-Id: I3a71eb8ef80018546f3bbf9d781770bd37ecec09 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69167 Reviewed-by: Jui-min Lee Maintainer: Gabe Black Tested-by: kokoro --- M util/term/term.c 1 file changed, 139 insertions(+), 31 deletions(-) Approvals: Gabe Black: Looks good to me, approved Jui-min Lee: Looks good to me, approved kokoro: Regressions pass diff --git a/util/term/term.c b/util/term/term.c index 529712c..cf3fdda 100644 --- a/util/term/term.c +++ b/util/term/term.c @@ -27,26 +27,30 @@ */ #include -#include -#include -#include -#include -#include -#include +#include #include #include #include +#include +#include #include +#include #include #include #include #include #include +#include +#include +#include +#include +#include #include ssize_t atomicio(ssize_t (*)(), int, void *, size_t); voidreadwrite(int); -int remote_connect(char *, char *, struct addrinfo); +int remote_connect_inet(char *, char *); +int remote_connect_unix(const char *); struct termios saved_ios; voidraw_term(); @@ -60,7 +64,6 @@ { int ch, s, ret; char *host, *port, *endp; -struct addrinfo hints; socklen_t len; ret = 1; @@ -87,33 +90,38 @@ raw_term(); +if (strcmp(host, "--unix") == 0) { +s = remote_connect_unix(port); +} else { +s = remote_connect_inet(host, port); +} + +if (s != -1) { +readwrite(s); +close(s); +} + +exit(0); +} + +/* + * remote_connect_inet() + * Return's a socket connected to a remote host. Properly bind's to a local + * port or source address if needed. Return's -1 on failure. + */ +int +remote_connect_inet(char *host, char *port) +{ +struct addrinfo hints; +struct addrinfo *res, *res0; +int s, error; + /* Initialize addrinfo structure */ memset(, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; -s = remote_connect(host, port, hints); -ret = 0; -readwrite(s); - -if (s) -close(s); - -exit(ret); -} - -/* - * remote_connect() - * Return's a socket connected to a remote host. Properly bind's to a local - * port or source address if needed. Return's -1 on failure. - */ -int -remote_connect(char *host, char *port, struct addrinfo hints) -{ -struct addrinfo *res, *res0; -int s, error; - if ((error = getaddrinfo(host, port, , ))) errx(1, "getaddrinfo: %s", gai_strerror(error)); @@ -136,6 +144,104 @@ } /* + * remote_connect_inet() + * Return's a socket connected to a remote host. Properly bind's to a local + * port or source address if needed. Return's -1 on failure. + */ +int +remote_connect_unix(const char *cpath) +{ +struct sockaddr_un addr; + +// Create a copy of path so we can safely modify it in place. +char *path = strdup(cpath); +char *const path_buf = path; + +// Create a unix domain socket. +int s = socket(AF_UNIX, SOCK_STREAM, 0); +if (s == -1) +return s; + +// Prepare the scokaddr_un. +memset(, 0, sizeof(addr)); +addr.sun_family = AF_UNIX; + +// Keep track of where we're filling in the path, and the remaining space. +int path_size = sizeof(addr.sun_path); +char *sun_path = _path[0]; + +// Keep track of the current directory in case we change it to maximize +// what we can fit in the limited space in sun_path. +char *cwd = NULL; + +if (path[0] == '@') { +// If this is an abstract socket, prefix it with a null byte. +*sun_path++ = '\0'; +path++; +path_size--; +// Keep track of how much of sun_path is actual data since everything +// we include will be part of the lookup. +int len = strlen(path); +if (len < path_size) { +fprintf(stderr, +"warning: Truncated abstract socket from %d to %d bytes.\n", +len, path_size); +path_size = len; +} +} else { +// Switch to the parent directory of the socket. +cwd = (char *)malloc(PATH_MAX); +if (!cwd) +errx(1, "Failed to allocate %d byte buffer.", PATH_MAX); +if (!getcwd(cwd, PATH_MAX)) { +perror("getcwd failed"); +
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add an "abortPending" method to the DMA port class.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69437?usp=email ) Change subject: dev: Add an "abortPending" method to the DMA port class. .. dev: Add an "abortPending" method to the DMA port class. This will abort any pending transactions that have been given to the port. Change-Id: Ie5f2c702530656a0c4590461369d430abead14cd --- M src/dev/dma_device.cc M src/dev/dma_device.hh 2 files changed, 85 insertions(+), 17 deletions(-) diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc index ebda635..4a060fb 100644 --- a/src/dev/dma_device.cc +++ b/src/dev/dma_device.cc @@ -81,6 +81,8 @@ void DmaPort::handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay) { +assert(pendingCount != 0); +pendingCount--; DPRINTF(DMA, "Received response %s for addr: %#x size: %d nb: %d," \ " tot: %d sched %d\n", MemCmd(state->cmd).toString(), addr, size, @@ -93,11 +95,21 @@ state->numBytes += size; assert(state->totBytes >= state->numBytes); -// If we have reached the total number of bytes for this DMA request, -// then signal the completion and delete the sate. -if (state->totBytes == state->numBytes) { -assert(pendingCount != 0); -pendingCount--; +if (state->aborted) { +// If this request was aborted, check to see if its in flight accesses +// have finished. There may be packets for more than one request in +// flight at a time, so check for finished requests, or no more +// packets. +if (state->gen.done() || pendingCount == 0) { +// If yes, signal its abort event (if any) and delete the state. +if (state->abortEvent) { +device->schedule(state->abortEvent, curTick()); +} +delete state; +} +} else if (state->gen.done()) { +// If we have reached the end of this DMA request, then signal the +// completion and delete the sate. if (state->completionEvent) { delay += state->delay; device->schedule(state->completionEvent, curTick() + delay); @@ -166,8 +178,9 @@ void DmaPort::recvReqRetry() { -assert(transmitList.size()); -trySendTimingReq(); +retryPending = false; +if (transmitList.size()) +trySendTimingReq(); } void @@ -184,7 +197,6 @@ transmitList.push_back( new DmaReqState(cmd, addr, cacheLineSize, size, data, flag, requestorId, sid, ssid, event, delay)); -pendingCount++; // In zero time, also initiate the sending of the packets for the request // we have just created. For atomic this involves actually completing all @@ -201,6 +213,42 @@ } void +DmaPort::abortPending() +{ +if (inRetry) { +delete inRetry; +inRetry = nullptr; +} + +if (pendingCount && !transmitList.empty()) { +auto *state = transmitList.front(); +if (state->numBytes != state->gen.complete()) { +// In flight packets refer to the transmission at the front of the +// list, and not a transmission whose packets have all been sent +// but not completed. Preserve the state so the packets don't have +// dangling pointers. +transmitList.pop_front(); +state->aborted = true; +} +} + +// Get rid of requests that haven't started yet. +while (!transmitList.empty()) { +auto *state = transmitList.front(); +if (state->abortEvent) +device->schedule(state->abortEvent, curTick()); +delete state; +transmitList.pop_front(); +} + +if (sendEvent.scheduled()) +device->deschedule(sendEvent); + +if (pendingCount == 0) +signalDrainDone(); +} + +void DmaPort::trySendTimingReq() { // Send the next packet for the first DMA request on the transmit list, @@ -216,14 +264,17 @@ // Check if this was the last packet now, since hypothetically the packet // response may come immediately, and state may be deleted. bool last = state->gen.last(); -if (!sendTimingReq(pkt)) +if (sendTimingReq(pkt)) { +pendingCount++; +} else { +retryPending = true; inRetry = pkt; -if (!inRetry) { +} +if (!retryPending) { +state->gen.next(); // If that was the last packet from this request, pop it from the list. if (last) transmitList.pop_front(); -else -state->gen.next(); DPRINTF(DMA, "-- Done\n"); // If there is more to do, then do so. if (!transmitList.empty()) { @@ -236,8 +287,8 @@ DPRINTF(DMA, "-- Failed, waiting for retry\n"); } -DPRINTF(DMA, "TransmitList: %d, inRetry: %d\n", -transmitList.size(), inRetry ? 1 : 0); +DPRINTF(DMA,
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Abstract the AF_INET-ness out of ListenSocket.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email ) Change subject: base: Abstract the AF_INET-ness out of ListenSocket. .. base: Abstract the AF_INET-ness out of ListenSocket. Put them into a subclass called ListenSocketInet. Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69163 Maintainer: Bobby Bruce Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Jui-min Lee Reviewed-by: Bobby Bruce --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 75 insertions(+), 47 deletions(-) Approvals: Bobby Bruce: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass Jui-min Lee: Looks good to me, but someone else must approve Gabe Black: Looks good to me, approved diff --git a/src/base/socket.cc b/src/base/socket.cc index 5fb8492..13962d4 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,11 +173,7 @@ // // -ListenSocket::ListenSocket(const std::string &_name, int port) -: Named(_name), listening(false), fd(-1), _port(port) -{} - -ListenSocket::ListenSocket() : ListenSocket("", -1) {} +ListenSocket::ListenSocket(const std::string &_name) : Named(_name) {} ListenSocket::~ListenSocket() { @@ -185,9 +181,41 @@ close(fd); } +// Open a connection. Accept will block, so if you don't want it to, +// make sure a connection is ready before you call accept. +int +ListenSocket::accept() +{ +struct sockaddr_in sockaddr; +socklen_t slen = sizeof (sockaddr); +int sfd = acceptCloexec(fd, (struct sockaddr *), ); +if (sfd == -1) +return -1; + +return sfd; +} + +ListenSocketInet::ListenSocketInet(const std::string &_name, int port) +: ListenSocket(_name), _port(port) +{} + +int +ListenSocketInet::accept() +{ +int sfd = ListenSocket::accept(); +if (sfd == -1) +return -1; + +int i = 1; +int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); +warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); + +return sfd; +} + // Create a socket and configure it for listening bool -ListenSocket::listen(int port) +ListenSocketInet::listen(int port) { panic_if(listening, "Socket already listening!"); @@ -228,13 +256,12 @@ return false; } -listening = true; -anyListening = true; +setListening(); return true; } void -ListenSocket::listen() +ListenSocketInet::listen() { while (!listen(_port)) { _port++; @@ -245,35 +272,16 @@ } void -ListenSocket::output(std::ostream ) const +ListenSocketInet::output(std::ostream ) const { os << "port " << _port; } - -// Open a connection. Accept will block, so if you don't want it to, -// make sure a connection is ready before you call accept. -int -ListenSocket::accept() -{ -struct sockaddr_in sockaddr; -socklen_t slen = sizeof (sockaddr); -int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd == -1) -return -1; - -int i = 1; -int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); -warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); - -return sfd; -} - ListenSocketConfig listenSocketInetConfig(int port) { return ListenSocketConfig([port](const std::string ) { -return std::make_unique(name, port); +return std::make_unique(name, port); }); } diff --git a/src/base/socket.hh b/src/base/socket.hh index 638ce40..761312b 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -93,31 +93,34 @@ static void loopbackOnly(); protected: -bool listening; -int fd; -int _port; +bool listening = false; +int fd = -1; + +void +setListening() +{ +listening = true; +anyListening = true; +} /* * cleanup resets the static variables back to their default values. */ static void cleanup(); -virtual bool listen(int port); +ListenSocket(const std::string &_name); public: /** * @ingroup api_socket * @{ */ -ListenSocket(const std::string &_name, int port); -ListenSocket(); virtual ~ListenSocket(); virtual int accept(); +virtual void listen() = 0; -virtual void listen(); - -virtual void output(std::ostream ) const; +virtual void output(std::ostream ) const = 0; int getfd() const { return fd; } bool islistening() const { return listening; } @@ -130,6 +133,13 @@ /** @} */ // end of api_socket }; +inline static std::ostream & +operator << (std::ostream , const ListenSocket ) +{ +socket.output(os); +return os; +} + using ListenSocketPtr = std::unique_ptr; class ListenSocketConfig @@ -155,14 +165,24 @@ static inline ListenSocketConfig listenSocketEmptyConfig() {
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev: Add a level of indirection for ListenSockets.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email ) Change subject: base,cpu,dev: Add a level of indirection for ListenSockets. .. base,cpu,dev: Add a level of indirection for ListenSockets. This makes room for there to be different implementations for different types of sockets. Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69162 Reviewed-by: Yu-hsin Wang Tested-by: kokoro Maintainer: Gabe Black --- M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/base/vnc/vncserver.hh M src/cpu/nativetrace.cc M src/cpu/nativetrace.hh M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc M src/dev/serial/terminal.hh 11 files changed, 76 insertions(+), 38 deletions(-) Approvals: kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index c8cb32f..095b2bd 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,10 +392,11 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), -listener(_system->name() + ".remote_gdb", _port), fd(-1), sys(_system), -connectEvent(*this), disconnectEvent(*this), trapEvent(this), -singleStepEvent(*this) -{} +fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), +trapEvent(this), singleStepEvent(*this) +{ +listener = listenSocketInetConfig(_port).build(name()); +} BaseRemoteGDB::~BaseRemoteGDB() { @@ -417,25 +418,22 @@ return; } -listener.listen(); +listener->listen(); incomingConnectionEvent = -new IncomingConnectionEvent(this, listener.getfd(), POLLIN); +new IncomingConnectionEvent(this, listener->getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); - -ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", - curTick(), name(), listener); } void BaseRemoteGDB::connect() { -panic_if(!listener.islistening(), +panic_if(!listener->islistening(), "Can't accept GDB connections without any threads!"); pollQueue.remove(incomingConnectionEvent); -int sfd = listener.accept(); +int sfd = listener->accept(); if (sfd != -1) { if (isAttached()) @@ -448,9 +446,9 @@ const ListenSocket & BaseRemoteGDB::hostSocket() const { -panic_if(!listener.islistening(), +panic_if(!listener->islistening(), "Remote GDB socket is unknown until listen() has been called."); -return listener; +return *listener; } void @@ -513,7 +511,7 @@ assert(selectThreadContext(_tc->contextId())); // Now that we have a thread, we can start listening. -if (!listener.islistening()) +if (!listener->islistening()) listen(); } diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 60a0d6a..9f09582 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -231,7 +231,7 @@ IncomingConnectionEvent *incomingConnectionEvent; IncomingDataEvent *incomingDataEvent; -ListenSocket listener; +ListenSocketPtr listener; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 1aff73a..5fb8492 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -269,4 +269,12 @@ return sfd; } +ListenSocketConfig +listenSocketInetConfig(int port) +{ +return ListenSocketConfig([port](const std::string ) { +return std::make_unique(name, port); +}); +} + } // namespace gem5 diff --git a/src/base/socket.hh b/src/base/socket.hh index 81f4d62..638ce40 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include #include "base/named.hh" @@ -127,6 +130,33 @@ /** @} */ // end of api_socket }; +using ListenSocketPtr = std::unique_ptr; + +class ListenSocketConfig +{ + public: +using Builder = std::function)>; + +ListenSocketConfig() {} +ListenSocketConfig(Builder _builder) : builder(_builder) {} + +ListenSocketPtr +build(const std::string ) const +{ +assert(builder); +return builder(name); +} + +operator bool() const { return (bool)builder; } + + private: +Builder builder; +}; + +static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; } + +ListenSocketConfig listenSocketInetConfig(int port); + inline static std::ostream & operator << (std::ostream , const ListenSocket ) { diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 2d32cef..4e5c951 100644 --- a/src/base/vnc/vncserver.cc +++
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev,sim: Pull common logic into ListenSocket::listen().
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69160?usp=email ) Change subject: base,cpu,dev,sim: Pull common logic into ListenSocket::listen(). .. base,cpu,dev,sim: Pull common logic into ListenSocket::listen(). Create a version of listen() which handles common logic internally, including scanning for an available port number, and notifying what port was chosen. The port is managed internal to ListenSocket, so that the logic interacting with it doesn't need to manually manage a port number, and hence a port number does not need to exist for non AF_INET sockets. Change-Id: Ie371eccc4d0da5e7b90714508e4cb72fb0091875 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69160 Tested-by: kokoro Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black --- M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/base/vnc/vncserver.hh M src/cpu/nativetrace.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc M src/dev/serial/terminal.hh M src/sim/workload.cc 11 files changed, 64 insertions(+), 60 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 1a2fef4..c8cb32f 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,7 +392,7 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), -_port(_port), fd(-1), sys(_system), +listener(_system->name() + ".remote_gdb", _port), fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), trapEvent(this), singleStepEvent(*this) {} @@ -417,17 +417,14 @@ return; } -while (!listener.listen(_port)) { -DPRINTF(GDBMisc, "Can't bind port %d\n", _port); -_port++; -} +listener.listen(); incomingConnectionEvent = new IncomingConnectionEvent(this, listener.getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); -ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n", - curTick(), name(), _port); +ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", + curTick(), name(), listener); } void @@ -448,12 +445,12 @@ } } -int -BaseRemoteGDB::port() const +const ListenSocket & +BaseRemoteGDB::hostSocket() const { panic_if(!listener.islistening(), - "Remote GDB port is unknown until listen() has been called.\n"); -return _port; + "Remote GDB socket is unknown until listen() has been called."); +return listener; } void diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 80c108b..60a0d6a 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -161,7 +161,7 @@ void listen(); void connect(); -int port() const; +const ListenSocket () const; void attach(int fd); void detach(); @@ -232,7 +232,6 @@ IncomingDataEvent *incomingDataEvent; ListenSocket listener; -int _port; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 280f92b..1aff73a 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,10 +173,12 @@ // // -ListenSocket::ListenSocket() -: listening(false), fd(-1) +ListenSocket::ListenSocket(const std::string &_name, int port) +: Named(_name), listening(false), fd(-1), _port(port) {} +ListenSocket::ListenSocket() : ListenSocket("", -1) {} + ListenSocket::~ListenSocket() { if (fd != -1) @@ -231,6 +233,23 @@ return true; } +void +ListenSocket::listen() +{ +while (!listen(_port)) { +_port++; +fatal_if(_port > 65536, "%s: cannot find an available port.", name()); +} +ccprintf(std::cerr, "%s: Listening for connections on %s\n", +name(), *this); +} + +void +ListenSocket::output(std::ostream ) const +{ +os << "port " << _port; +} + // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. diff --git a/src/base/socket.hh b/src/base/socket.hh index d2393e9..7a616bd 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -35,6 +35,8 @@ #include +#include "base/named.hh" + namespace gem5 { @@ -69,7 +71,7 @@ std::string formattedPath; }; -class ListenSocket +class ListenSocket : public Named { protected: /** @@ -90,6 +92,7 @@ protected: bool listening; int fd; +int _port; /* * cleanup resets the static variables back to their default values. @@ -101,12 +104,16 @@ * @ingroup api_socket * @{ */ +ListenSocket(const std::string &_name, int port); ListenSocket();
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Make ListenSocket::listen(int port) protected.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69161?usp=email ) Change subject: base: Make ListenSocket::listen(int port) protected. .. base: Make ListenSocket::listen(int port) protected. Stop making the old API available. Change-Id: I70752d081cb572a8ae5bf396d2ea43ecc7be1e9c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69161 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/base/socket.hh M src/base/socket.test.cc 2 files changed, 19 insertions(+), 35 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/base/socket.hh b/src/base/socket.hh index 7a616bd..81f4d62 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -99,6 +99,8 @@ */ static void cleanup(); +virtual bool listen(int port); + public: /** * @ingroup api_socket @@ -110,7 +112,6 @@ virtual int accept(); -virtual bool listen(int port); virtual void listen(); virtual void output(std::ostream ) const; diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index cb24c49..8e1c25b 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -121,6 +121,7 @@ class MockListenSocket : public ListenSocket { public: +MockListenSocket(int port) : ListenSocket("mock", port) {} /* * This mock Listen Socket is used to ensure the static variables are reset * back to their default values after deconstruction (i.e., after a test @@ -138,7 +139,7 @@ * Tests the default behavior where listenSocket is constructed, and is * not listening to a port. */ -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); EXPECT_EQ(-1, listen_socket.getfd()); EXPECT_FALSE(listen_socket.islistening()); EXPECT_FALSE(listen_socket.allDisabled()); @@ -146,7 +147,7 @@ TEST(SocketTest, DisableAll) { -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); listen_socket.disableAll(); EXPECT_EQ(-1, listen_socket.getfd()); EXPECT_FALSE(listen_socket.islistening()); @@ -155,8 +156,8 @@ TEST(SocketTest, ListenToPort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); EXPECT_NE(-1, listen_socket.getfd()); EXPECT_TRUE(listen_socket.islistening()); EXPECT_FALSE(listen_socket.allDisabled()); @@ -164,32 +165,14 @@ TEST(SocketTest, RelistenWithSameInstanceSamePort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You cannot listen to another port if you are already listening to one. */ gtestLogOutput.str(""); -EXPECT_ANY_THROW(listen_socket.listen(TestPort1)); -std::string expected = -"panic: panic condition listening occurred: " -"Socket already listening!\n"; -std::string actual = gtestLogOutput.str(); -EXPECT_EQ(expected, actual); -} - -TEST(SocketTest, RelistenWithSameInstanceDifferentPort) -{ -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); - -/* - * You cannot listen to another port if you are already listening to one. - */ -gtestLogOutput.str(""); -EXPECT_ANY_THROW(listen_socket.listen(TestPort2)); - +EXPECT_ANY_THROW(listen_socket.listen()); std::string expected = "panic: panic condition listening occurred: " "Socket already listening!\n"; @@ -199,30 +182,30 @@ TEST(SocketTest, RelistenWithDifferentInstanceOnDifferentPort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You can listen to another port with a different instance. */ -MockListenSocket listen_socket_2; -EXPECT_TRUE(listen_socket_2.listen(TestPort2)); +MockListenSocket listen_socket_2(TestPort2); +listen_socket_2.listen(); } TEST(SocketTest, RelistenWithDifferentInstanceOnSamePort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You cannot listen to a port that's already being listened to. */ -MockListenSocket listen_socket_2; -EXPECT_FALSE(listen_socket_2.listen(TestPort1)); +MockListenSocket listen_socket_2(TestPort1); +listen_socket_2.listen(); } TEST(SocketTest, AcceptError) { -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); EXPECT_EQ(-1, listen_socket.accept()); } -- To view, visit
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev: Simplify ListenSocket::listen().
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69159?usp=email ) Change subject: base,cpu,dev: Simplify ListenSocket::listen(). .. base,cpu,dev: Simplify ListenSocket::listen(). Remove the "reuse" parameter which default to true and was always also explicitly set to true. Tidy up the code itself slightly, mostly by using "panic_if" to remove some nesting. Change-Id: Ie23971aabf2fe4252d27f1887468360722a72379 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69159 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/base/remote_gdb.cc M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc M src/base/vnc/vncserver.cc M src/cpu/nativetrace.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc 8 files changed, 24 insertions(+), 38 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index b709ac3..1a2fef4 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -417,7 +417,7 @@ return; } -while (!listener.listen(_port, true)) { +while (!listener.listen(_port)) { DPRINTF(GDBMisc, "Can't bind port %d\n", _port); _port++; } diff --git a/src/base/socket.cc b/src/base/socket.cc index 0a62a88..280f92b 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -185,24 +185,20 @@ // Create a socket and configure it for listening bool -ListenSocket::listen(int port, bool reuse) +ListenSocket::listen(int port) { -if (listening) -panic("Socket already listening!"); +panic_if(listening, "Socket already listening!"); // only create socket if not already created by a previous call if (fd == -1) { fd = socketCloexec(PF_INET, SOCK_STREAM, 0); -if (fd < 0) -panic("Can't create socket:%s !", strerror(errno)); +panic_if(fd < 0, "Can't create socket:%s !", strerror(errno)); } -if (reuse) { -int i = 1; -if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *), - sizeof(i)) < 0) -panic("ListenSocket(listen): setsockopt() SO_REUSEADDR failed!"); -} +int i = 1; +int ret = ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, , sizeof(i)); +panic_if(ret < 0, +"ListenSocket(listen): setsockopt() SO_REUSEADDR failed!"); struct sockaddr_in sockaddr; sockaddr.sin_family = PF_INET; @@ -211,16 +207,16 @@ sockaddr.sin_port = htons(port); // finally clear sin_zero std::memset(_zero, 0, sizeof(sockaddr.sin_zero)); -int ret = ::bind(fd, (struct sockaddr *), sizeof (sockaddr)); +ret = ::bind(fd, (struct sockaddr *), sizeof (sockaddr)); if (ret != 0) { -if (ret == -1 && errno != EADDRINUSE) -panic("ListenSocket(listen): bind() failed!"); +panic_if(ret == -1 && errno != EADDRINUSE, +"ListenSocket(listen): bind() failed!"); return false; } if (::listen(fd, 1) == -1) { -if (errno != EADDRINUSE) -panic("ListenSocket(listen): listen() failed!"); +panic_if(errno != EADDRINUSE, +"ListenSocket(listen): listen() failed!"); // User may decide to retry with a different port later; however, the // socket is already bound to a port and the next bind will surely // fail. We'll close the socket and reset fd to -1 so our user can diff --git a/src/base/socket.hh b/src/base/socket.hh index aa451b6..d2393e9 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -106,7 +106,7 @@ virtual int accept(); -virtual bool listen(int port, bool reuse = true); +virtual bool listen(int port); int getfd() const { return fd; } bool islistening() const { return listening; } diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index 1ab1f21..cb24c49 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -162,19 +162,6 @@ EXPECT_FALSE(listen_socket.allDisabled()); } -TEST(SocketTest, ListenToPortReuseFalse) -{ -MockListenSocket listen_socket; -/* - * The ListenSocket object should have the same state regardless as to - * whether reuse is true or false (it is true by default). - */ -EXPECT_TRUE(listen_socket.listen(TestPort1, false)); -EXPECT_NE(-1, listen_socket.getfd()); -EXPECT_TRUE(listen_socket.islistening()); -EXPECT_FALSE(listen_socket.allDisabled()); -} - TEST(SocketTest, RelistenWithSameInstanceSamePort) { MockListenSocket listen_socket; @@ -185,7 +172,9 @@ */ gtestLogOutput.str(""); EXPECT_ANY_THROW(listen_socket.listen(TestPort1)); -std::string expected = "panic: Socket already listening!\n"; +std::string expected = +"panic: panic
[gem5-dev] [S] Change in gem5/gem5[develop]: base,dev: Simplify the ListenSocket::accept method.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69158?usp=email ) Change subject: base,dev: Simplify the ListenSocket::accept method. .. base,dev: Simplify the ListenSocket::accept method. Remove the nodelay option which is always set to the same thing, and simplify the logic of the method itself. Change-Id: I78cd91f99cbaec9abddedbc7dcddc563daedb81f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69158 Tested-by: kokoro Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang --- M src/base/remote_gdb.cc M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc 6 files changed, 12 insertions(+), 12 deletions(-) Approvals: Gabe Black: Looks good to me, approved kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index dd37a35..b709ac3 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -438,7 +438,7 @@ pollQueue.remove(incomingConnectionEvent); -int sfd = listener.accept(true); +int sfd = listener.accept(); if (sfd != -1) { if (isAttached()) diff --git a/src/base/socket.cc b/src/base/socket.cc index 23f2b40..0a62a88 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -239,17 +239,17 @@ // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. int -ListenSocket::accept(bool nodelay) +ListenSocket::accept() { struct sockaddr_in sockaddr; socklen_t slen = sizeof (sockaddr); int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd != -1 && nodelay) { -int i = 1; -if (::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (char *), - sizeof(i)) < 0) -warn("ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); -} +if (sfd == -1) +return -1; + +int i = 1; +int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); +warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); return sfd; } diff --git a/src/base/socket.hh b/src/base/socket.hh index af4a651..aa451b6 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -104,7 +104,7 @@ ListenSocket(); virtual ~ListenSocket(); -virtual int accept(bool nodelay = true); +virtual int accept(); virtual bool listen(int port, bool reuse = true); diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index c98838a..5792c44 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -190,7 +190,7 @@ if (!listener.islistening()) panic("%s: cannot accept a connection if not listening!", name()); -int fd = listener.accept(true); +int fd = listener.accept(); if (fd < 0) { warn("%s: failed to accept VNC connection!", name()); return; diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index 5b1e957..b28f255 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -280,7 +280,7 @@ if (!listener.islistening()) panic("TapListener(accept): cannot accept if we're not listening!"); -int sfd = listener.accept(true); +int sfd = listener.accept(); if (sfd != -1) tap->attach(sfd); } diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index d4108a3..fada99c 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -195,7 +195,7 @@ if (!listener.islistening()) panic("%s: cannot accept a connection if not listening!", name()); -int fd = listener.accept(true); +int fd = listener.accept(); if (data_fd != -1) { char message[] = "terminal already attached!\n"; atomic_write(fd, message, sizeof(message)); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69158?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I78cd91f99cbaec9abddedbc7dcddc563daedb81f Gerrit-Change-Number: 69158 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bobby Bruce Gerrit-Reviewer: Daniel Carvalho Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [XS] Change in gem5/gem5[develop]: base: Flip the default for ListenSocket::accept(bool nodelay).
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69157?usp=email ) Change subject: base: Flip the default for ListenSocket::accept(bool nodelay). .. base: Flip the default for ListenSocket::accept(bool nodelay). This option was almost always overridden from false to true anyway, except in one place (in the ethertap device) which was likely just by accident. This will give external users a chance to remove the option without changing behavior, so that the option can be removed entirely in a later change. Change-Id: I77add40b8131b91997b2aecbfff6c7de0ee9ead9 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69157 Reviewed-by: Yu-hsin Wang Tested-by: kokoro Maintainer: Gabe Black --- M src/base/socket.hh 1 file changed, 1 insertion(+), 1 deletion(-) Approvals: Gabe Black: Looks good to me, approved kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved diff --git a/src/base/socket.hh b/src/base/socket.hh index f3b2760..af4a651 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -104,7 +104,7 @@ ListenSocket(); virtual ~ListenSocket(); -virtual int accept(bool nodelay = false); +virtual int accept(bool nodelay = true); virtual bool listen(int port, bool reuse = true); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69157?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I77add40b8131b91997b2aecbfff6c7de0ee9ead9 Gerrit-Change-Number: 69157 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bobby Bruce Gerrit-Reviewer: Daniel Carvalho Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: mem: Use HostSocket in the SharedMemoryServer.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69168?usp=email ) Change subject: mem: Use HostSocket in the SharedMemoryServer. .. mem: Use HostSocket in the SharedMemoryServer. Use a HostSocket parameter to accept connections, rather than a hand implementation for unix domain sockets. This consolidates this code with the code derived from it in ListenSocket, and also makes it possible to connect to the SharedMemoryServer over an AF_INET socket. Change-Id: I8e05434d08cffaebdf6c68a967e2ee7613c10a76 --- M src/mem/SharedMemoryServer.py M src/mem/shared_memory_server.cc M src/mem/shared_memory_server.hh 3 files changed, 9 insertions(+), 48 deletions(-) diff --git a/src/mem/SharedMemoryServer.py b/src/mem/SharedMemoryServer.py index 9700422..70a8923 100644 --- a/src/mem/SharedMemoryServer.py +++ b/src/mem/SharedMemoryServer.py @@ -12,6 +12,4 @@ Parent.any, "The system where the target shared memory is actually stored.", ) -server_path = Param.String( -"The unix socket path where the server should be running upon." -) +server_path = Param.HostSocket("Socket path or port for the server.") diff --git a/src/mem/shared_memory_server.cc b/src/mem/shared_memory_server.cc index 6344ee0..5787832 100644 --- a/src/mem/shared_memory_server.cc +++ b/src/mem/shared_memory_server.cc @@ -51,52 +51,18 @@ SharedMemoryServer::SharedMemoryServer(const SharedMemoryServerParams& params) : SimObject(params), - sockAddr(UnixSocketAddr::build(params.server_path)), system(params.system), - serverFd(-1) + listener(params.server_path.build(name())) { fatal_if(system == nullptr, "Requires a system to share memory from!"); -// Create a new unix socket. -serverFd = ListenSocket::socketCloexec(AF_UNIX, SOCK_STREAM, 0); -panic_if(serverFd < 0, "%s: cannot create unix socket: %s", name(), - strerror(errno)); +listener->listen(); -const auto& [serv_addr, addr_size, is_abstract, formatted_path] = sockAddr; - -if (!is_abstract) { -// Ensure the unix socket path to use is not occupied. Also, if there's -// actually anything to be removed, warn the user something might be -// off. -bool old_sock_removed = unlink(serv_addr.sun_path) == 0; -warn_if(old_sock_removed, -"%s: server path %s was occupied and will be replaced. Please " -"make sure there is no other server using the same path.", -name(), serv_addr.sun_path); -} -int bind_retv = bind( -serverFd, reinterpret_cast(_addr), addr_size); -fatal_if(bind_retv != 0, "%s: cannot bind unix socket '%s': %s", name(), - formatted_path, strerror(errno)); -// Start listening. -int listen_retv = listen(serverFd, 1); -fatal_if(listen_retv != 0, "%s: listen failed: %s", name(), - strerror(errno)); -listenSocketEvent.reset(new ListenSocketEvent(serverFd, this)); +listenSocketEvent.reset(new ListenSocketEvent(listener->getfd(), this)); pollQueue.schedule(listenSocketEvent.get()); -inform("%s: listening at %s", name(), formatted_path); +inform("%s: listening at %s", name(), *listener); } -SharedMemoryServer::~SharedMemoryServer() -{ -if (!sockAddr.isAbstract) { -int unlink_retv = unlink(sockAddr.addr.sun_path); -warn_if(unlink_retv != 0, "%s: cannot unlink unix socket: %s", name(), -strerror(errno)); -} -int close_retv = close(serverFd); -warn_if(close_retv != 0, "%s: cannot close unix socket: %s", name(), -strerror(errno)); -} +SharedMemoryServer::~SharedMemoryServer() {} SharedMemoryServer::BaseShmPollEvent::BaseShmPollEvent( int fd, SharedMemoryServer* shm_server) @@ -130,10 +96,7 @@ void SharedMemoryServer::ListenSocketEvent::process(int revents) { -panic_if(revents & (POLLERR | POLLNVAL), "%s: listen socket is broken", - name()); -int cli_fd = ListenSocket::acceptCloexec(pfd.fd, nullptr, nullptr); -panic_if(cli_fd < 0, "%s: accept failed: %s", name(), strerror(errno)); +int cli_fd = shmServer->listener->accept(); inform("%s: accept new connection %d", name(), cli_fd); shmServer->clientSocketEvents[cli_fd].reset( new ClientSocketEvent(cli_fd, shmServer)); diff --git a/src/mem/shared_memory_server.hh b/src/mem/shared_memory_server.hh index d9fbeb3..a4ef63d 100644 --- a/src/mem/shared_memory_server.hh +++ b/src/mem/shared_memory_server.hh @@ -83,10 +83,10 @@ void process(int revent) override; }; -UnixSocketAddr sockAddr; System* system; -int serverFd; +ListenSocketPtr listener; + std::unique_ptr listenSocketEvent; std::unordered_map> clientSocketEvents; -- To view, visit
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Remove the now unused UnixSocketAddr class and associated code.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69169?usp=email ) Change subject: base: Remove the now unused UnixSocketAddr class and associated code. .. base: Remove the now unused UnixSocketAddr class and associated code. This job is now handled by the python param code, and the ListenSocket classes. Change-Id: I3a29b880b2484c5e25071bdef59fc73e1e8c2760 --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 0 insertions(+), 167 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index 0ef0062..86012bb 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -49,75 +49,12 @@ namespace gem5 { -namespace -{ - -bool -isSocketNameAbstract(const std::string ) -{ -if (path.empty()) { -return false; -} -// No null byte should be present in the path -return path.front() == '@'; -} - -std::string -resolve(const std::string ) -{ -if (path.empty()) { -return path; -} -if (isSocketNameAbstract(path)) { -return '\0' + path.substr(1); -} -return simout.resolve(path); -} - -} // namespace bool ListenSocket::listeningDisabled = false; bool ListenSocket::anyListening = false; bool ListenSocket::bindToLoopback = false; -UnixSocketAddr -UnixSocketAddr::build(const std::string ) -{ -sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path = {}}; - -const bool is_abstract = isSocketNameAbstract(path); -size_t max_len = sizeof(addr.sun_path); -if (!is_abstract) { -// File based socket names need to be null terminated -max_len -= 1; -} - -std::string resolved_path = resolve(path); -std::string fmt_path = replace(resolved_path, '\0', '@'); -if (resolved_path.size() > max_len) { -resolved_path = resolved_path.substr(0, max_len); -const std::string untruncated_path = std::move(fmt_path); -fmt_path = replace(resolved_path, '\0', '@'); -warn("SocketPath: unix socket path truncated from '%s' to '%s'", - untruncated_path, fmt_path); -} - -// We can't use strncpy here, since abstract sockets start with \0 which -// will make strncpy think that the string is empty. -memcpy(addr.sun_path, resolved_path.c_str(), resolved_path.size()); -// We can't use sizeof(sockaddr_un) for abstract sockets, since all -// sizeof(sun_path) bytes are used in representing the path. -const size_t path_size = -is_abstract ? resolved_path.size() : sizeof(addr.sun_path); -const size_t addr_size = offsetof(sockaddr_un, sun_path) + path_size; - -return UnixSocketAddr{.addr = std::move(addr), - .addrSize = addr_size, - .isAbstract = is_abstract, - .formattedPath = std::move(fmt_path)}; -} - void ListenSocket::cleanup() { diff --git a/src/base/socket.hh b/src/base/socket.hh index 5974348..123a6fe 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -43,37 +43,6 @@ namespace gem5 { -/** - * @brief Wrapper around sockaddr_un, so that it can be used for both file - * based unix sockets as well as abstract unix sockets. - */ -struct UnixSocketAddr -{ -/** - * @brief Builds UnixSocketAddr from the given path. - * @pre: `path` either represents a file based unix socket, or an abstract - * unix socket. If `path` represents an abstract socket, it should - * start with the character '@', and it should not have any null - * bytes in the name. - * @param path: Pathname, where the socket should be instantiated. - * @return UnixSocketAddr - */ -static UnixSocketAddr build(const std::string ); - -sockaddr_un addr; -// Size of `sockaddr_un addr`. This is equal to sizeof(sockaddr_un) if -// `addr` represents a normal file based unix socket. For abstract sockets -// however, the size could be different. Because all sizeof(sun_path) is -// used to represent the name of an abstract socket, addrSize for abstract -// sockets only count the number of characters actually used by sun_path, -// excluding any trailing null bytes. -size_t addrSize; -bool isAbstract; -// Formatted string for file based sockets look the same as addr.sun_path. -// For abstract sockets however, all null bytes are replaced with @ -std::string formattedPath; -}; - class ListenSocket : public Named { protected: diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index 7bf9e18..5fd0f3f 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -45,79 +45,6 @@ * socket.cc have not been fully tested due to interaction with system-calls. */ -namespace { - -std::string -repeat(const std::string& str, size_t n) -{ -std::stringstream ss; -for (int i = 0; i < n; ++i) { -ss <<
[gem5-dev] [M] Change in gem5/gem5[develop]: util: Make m5term able to connect to unix domain sockets.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69167?usp=email ) Change subject: util: Make m5term able to connect to unix domain sockets. .. util: Make m5term able to connect to unix domain sockets. To connect to a unix domain socket, it must start with a non-digit character to avoid being confused with a TCP port. If it starts with an "@" character, then it is treated as an abstract socket. Change-Id: I3a71eb8ef80018546f3bbf9d781770bd37ecec09 --- M util/term/term.c 1 file changed, 117 insertions(+), 29 deletions(-) diff --git a/util/term/term.c b/util/term/term.c index 529712c..8cbd202 100644 --- a/util/term/term.c +++ b/util/term/term.c @@ -27,26 +27,30 @@ */ #include -#include -#include -#include -#include -#include -#include +#include #include #include #include +#include +#include #include +#include #include #include #include #include #include +#include +#include +#include +#include +#include #include ssize_t atomicio(ssize_t (*)(), int, void *, size_t); voidreadwrite(int); -int remote_connect(char *, char *, struct addrinfo); +int remote_connect_inet(char *, char *); +int remote_connect_unix(char *); struct termios saved_ios; voidraw_term(); @@ -60,7 +64,6 @@ { int ch, s, ret; char *host, *port, *endp; -struct addrinfo hints; socklen_t len; ret = 1; @@ -87,33 +90,40 @@ raw_term(); +if (isdigit(port[0])) { +s = remote_connect_inet(host, port); +} else { +if (argc != 2) +errx(1, "host specified with local socket"); +s = remote_connect_unix(port); +} + +if (s != -1) { +readwrite(s); +close(s); +} + +exit(0); +} + +/* + * remote_connect_inet() + * Return's a socket connected to a remote host. Properly bind's to a local + * port or source address if needed. Return's -1 on failure. + */ +int +remote_connect_inet(char *host, char *port) +{ +struct addrinfo hints; +struct addrinfo *res, *res0; +int s, error; + /* Initialize addrinfo structure */ memset(, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; -s = remote_connect(host, port, hints); -ret = 0; -readwrite(s); - -if (s) -close(s); - -exit(ret); -} - -/* - * remote_connect() - * Return's a socket connected to a remote host. Properly bind's to a local - * port or source address if needed. Return's -1 on failure. - */ -int -remote_connect(char *host, char *port, struct addrinfo hints) -{ -struct addrinfo *res, *res0; -int s, error; - if ((error = getaddrinfo(host, port, , ))) errx(1, "getaddrinfo: %s", gai_strerror(error)); @@ -136,6 +146,84 @@ } /* + * remote_connect_inet() + * Return's a socket connected to a remote host. Properly bind's to a local + * port or source address if needed. Return's -1 on failure. + */ +int +remote_connect_unix(char *path) +{ +struct sockaddr_un addr; + +// Create a copy of path so we can safely modify it in place. +char *pathc = strdup(path); +path = pathc; + +// Create a unix domain socket. +int s = socket(AF_UNIX, SOCK_STREAM, 0); +if (s == -1) +return s; + +// Prepare the scokaddr_un. +memset(, 0, sizeof(addr)); +addr.sun_family = AF_UNIX; + +// Keep track of where we're filling in the path, and the remaining space. +int path_size = sizeof(addr.sun_path); +char *sun_path = _path[0]; + +// Keep track of the current directory in case we change it to maximize +// what we can fit in the limited space in sun_path. +char *cwd = NULL; + +if (path[0] == '@') { +// If this is an abstract socket, prefix it with a null byte. +*sun_path++ = '\0'; +path++; +path_size--; +// Keep track of how much of sun_path is actual data since everything +// we include will be part of the lookup. +int len = strlen(path); +if (len < path_size) +path_size = len; +} else { +// Switch to the parent directory of the socket. +cwd = (char *)malloc(PATH_MAX); +getcwd(cwd, PATH_MAX); +char *dirc = strdup(path); +char *dname = dirname(dirc); +chdir(dname); +free(dirc); + +// Replace the path with just the filename part. We still have a +// pointer to our copy of "path" so we can clean it up later. +path = basename(path); +} + +// Copy the path into sun_path. +strncpy(sun_path, path, path_size); + +// Figure out how much actual data we have in sockaddr_un. +int struct_len = (char *)sun_path + path_size - (char *) + +// Actually connect to the socket. +if (connect(s, (struct sockaddr *), struct_len) == -1) { +// If
[gem5-dev] [M] Change in gem5/gem5[develop]: arch,base,dev,sim: Convert objects to use the HostSocket param type.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69166?usp=email ) Change subject: arch,base,dev,sim: Convert objects to use the HostSocket param type. .. arch,base,dev,sim: Convert objects to use the HostSocket param type. This will make it possible to connect any of these objects with a named socket, in addition to the usual port numbers. Change-Id: Id441c3628f62d60608a07c5cb697786e33199981 --- M src/arch/arm/fastmodel/remote_gdb.cc M src/arch/arm/fastmodel/remote_gdb.hh M src/arch/arm/remote_gdb.cc M src/arch/arm/remote_gdb.hh M src/arch/mips/remote_gdb.cc M src/arch/mips/remote_gdb.hh M src/arch/power/remote_gdb.cc M src/arch/power/remote_gdb.hh M src/arch/riscv/remote_gdb.cc M src/arch/riscv/remote_gdb.hh M src/arch/sparc/remote_gdb.cc M src/arch/sparc/remote_gdb.hh M src/arch/x86/remote_gdb.cc M src/arch/x86/remote_gdb.hh M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/vnc/Vnc.py M src/base/vnc/vncserver.cc M src/dev/net/Ethernet.py M src/dev/net/ethertap.cc M src/dev/serial/Terminal.py M src/dev/serial/terminal.cc M src/sim/Workload.py 23 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/arch/arm/fastmodel/remote_gdb.cc b/src/arch/arm/fastmodel/remote_gdb.cc index e13fee8..dcd136a 100644 --- a/src/arch/arm/fastmodel/remote_gdb.cc +++ b/src/arch/arm/fastmodel/remote_gdb.cc @@ -32,8 +32,9 @@ namespace fastmodel { -FastmodelRemoteGDB::FastmodelRemoteGDB(System *_system, int port) -: gem5::ArmISA::RemoteGDB(_system, port) +FastmodelRemoteGDB::FastmodelRemoteGDB(System *_system, +ListenSocketConfig _listen_config) +: gem5::ArmISA::RemoteGDB(_system, _listen_config) { } diff --git a/src/arch/arm/fastmodel/remote_gdb.hh b/src/arch/arm/fastmodel/remote_gdb.hh index 93cf882..dce3854 100644 --- a/src/arch/arm/fastmodel/remote_gdb.hh +++ b/src/arch/arm/fastmodel/remote_gdb.hh @@ -39,7 +39,7 @@ class FastmodelRemoteGDB : public gem5::ArmISA::RemoteGDB { public: -FastmodelRemoteGDB(System *_system, int port); +FastmodelRemoteGDB(System *_system, ListenSocketConfig _listen_config); private: bool readBlob(Addr vaddr, size_t size, char *data) override; diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc index c357f02..7dd3c3d 100644 --- a/src/arch/arm/remote_gdb.cc +++ b/src/arch/arm/remote_gdb.cc @@ -201,8 +201,9 @@ mmu->translateFunctional(req, tc, BaseMMU::Execute) == NoFault; } -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig _listen_config) +: BaseRemoteGDB(_system, _listen_config), +regCache32(this), regCache64(this) { } diff --git a/src/arch/arm/remote_gdb.hh b/src/arch/arm/remote_gdb.hh index 8e512a4..6175399 100644 --- a/src/arch/arm/remote_gdb.hh +++ b/src/arch/arm/remote_gdb.hh @@ -118,7 +118,7 @@ AArch64GdbRegCache regCache64; public: -RemoteGDB(System *_system, int _port); +RemoteGDB(System *_system, ListenSocketConfig _listen_config); BaseGdbRegCache *gdbRegs() override; bool checkBpKind(size_t kind) override; std::vector diff --git a/src/arch/mips/remote_gdb.cc b/src/arch/mips/remote_gdb.cc index fcf31e1..f14305a 100644 --- a/src/arch/mips/remote_gdb.cc +++ b/src/arch/mips/remote_gdb.cc @@ -151,8 +151,8 @@ using namespace MipsISA; -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig _listen_config) +: BaseRemoteGDB(_system, _listen_config), regCache(this) { } diff --git a/src/arch/mips/remote_gdb.hh b/src/arch/mips/remote_gdb.hh index 6a38956..6fd193a 100644 --- a/src/arch/mips/remote_gdb.hh +++ b/src/arch/mips/remote_gdb.hh @@ -80,7 +80,7 @@ MipsGdbRegCache regCache; public: -RemoteGDB(System *_system, int _port); +RemoteGDB(System *_system, ListenSocketConfig _listen_config); BaseGdbRegCache *gdbRegs(); std::vector availableFeatures() const diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc index c69c571..14b9df4 100644 --- a/src/arch/power/remote_gdb.cc +++ b/src/arch/power/remote_gdb.cc @@ -155,8 +155,9 @@ using namespace PowerISA; -RemoteGDB::RemoteGDB(System *_system, int _port) -: BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this) +RemoteGDB::RemoteGDB(System *_system, ListenSocketConfig _listen_config) +: BaseRemoteGDB(_system, _listen_config), +regCache32(this), regCache64(this) { } diff --git a/src/arch/power/remote_gdb.hh b/src/arch/power/remote_gdb.hh index 138913e..fedb91d 100644 --- a/src/arch/power/remote_gdb.hh +++ b/src/arch/power/remote_gdb.hh @@ -112,7 +112,7 @@ Power64GdbRegCache regCache64; public: -RemoteGDB(System *_system, int _port); +
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Make ListenSocket::listen(int port) protected.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69161?usp=email ) Change subject: base: Make ListenSocket::listen(int port) protected. .. base: Make ListenSocket::listen(int port) protected. Stop making the old API available. Change-Id: I70752d081cb572a8ae5bf396d2ea43ecc7be1e9c --- M src/base/socket.hh M src/base/socket.test.cc 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/base/socket.hh b/src/base/socket.hh index 7a616bd..81f4d62 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -99,6 +99,8 @@ */ static void cleanup(); +virtual bool listen(int port); + public: /** * @ingroup api_socket @@ -110,7 +112,6 @@ virtual int accept(); -virtual bool listen(int port); virtual void listen(); virtual void output(std::ostream ) const; diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index cb24c49..8e1c25b 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -121,6 +121,7 @@ class MockListenSocket : public ListenSocket { public: +MockListenSocket(int port) : ListenSocket("mock", port) {} /* * This mock Listen Socket is used to ensure the static variables are reset * back to their default values after deconstruction (i.e., after a test @@ -138,7 +139,7 @@ * Tests the default behavior where listenSocket is constructed, and is * not listening to a port. */ -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); EXPECT_EQ(-1, listen_socket.getfd()); EXPECT_FALSE(listen_socket.islistening()); EXPECT_FALSE(listen_socket.allDisabled()); @@ -146,7 +147,7 @@ TEST(SocketTest, DisableAll) { -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); listen_socket.disableAll(); EXPECT_EQ(-1, listen_socket.getfd()); EXPECT_FALSE(listen_socket.islistening()); @@ -155,8 +156,8 @@ TEST(SocketTest, ListenToPort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); EXPECT_NE(-1, listen_socket.getfd()); EXPECT_TRUE(listen_socket.islistening()); EXPECT_FALSE(listen_socket.allDisabled()); @@ -164,32 +165,14 @@ TEST(SocketTest, RelistenWithSameInstanceSamePort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You cannot listen to another port if you are already listening to one. */ gtestLogOutput.str(""); -EXPECT_ANY_THROW(listen_socket.listen(TestPort1)); -std::string expected = -"panic: panic condition listening occurred: " -"Socket already listening!\n"; -std::string actual = gtestLogOutput.str(); -EXPECT_EQ(expected, actual); -} - -TEST(SocketTest, RelistenWithSameInstanceDifferentPort) -{ -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); - -/* - * You cannot listen to another port if you are already listening to one. - */ -gtestLogOutput.str(""); -EXPECT_ANY_THROW(listen_socket.listen(TestPort2)); - +EXPECT_ANY_THROW(listen_socket.listen()); std::string expected = "panic: panic condition listening occurred: " "Socket already listening!\n"; @@ -199,30 +182,30 @@ TEST(SocketTest, RelistenWithDifferentInstanceOnDifferentPort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You can listen to another port with a different instance. */ -MockListenSocket listen_socket_2; -EXPECT_TRUE(listen_socket_2.listen(TestPort2)); +MockListenSocket listen_socket_2(TestPort2); +listen_socket_2.listen(); } TEST(SocketTest, RelistenWithDifferentInstanceOnSamePort) { -MockListenSocket listen_socket; -EXPECT_TRUE(listen_socket.listen(TestPort1)); +MockListenSocket listen_socket(TestPort1); +listen_socket.listen(); /* * You cannot listen to a port that's already being listened to. */ -MockListenSocket listen_socket_2; -EXPECT_FALSE(listen_socket_2.listen(TestPort1)); +MockListenSocket listen_socket_2(TestPort1); +listen_socket_2.listen(); } TEST(SocketTest, AcceptError) { -MockListenSocket listen_socket; +MockListenSocket listen_socket(-1); EXPECT_EQ(-1, listen_socket.accept()); } -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69161?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id:
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Add support for unix domain sockets in ListenSocket.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69164?usp=email ) Change subject: base: Add support for unix domain sockets in ListenSocket. .. base: Add support for unix domain sockets in ListenSocket. Change-Id: I6a5fa2cd3e4b567829203bf9d61ad2b55c259697 --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 208 insertions(+), 4 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index 0324788..c401a08 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -39,6 +39,7 @@ #include #include +#include #include "base/logging.hh" #include "base/output.hh" @@ -187,10 +188,10 @@ ListenSocket::accept() { struct sockaddr_in sockaddr; -socklen_t slen = sizeof (sockaddr); +socklen_t slen = sizeof(sockaddr); int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd == -1) -return -1; +panic_if(sfd == -1, "%s: Failed to accept connection: %s", +name(), strerror(errno)); return sfd; } @@ -286,4 +287,148 @@ }); } +std::string +ListenSocketUnix::truncate(const std::string , size_t max_len) +{ +if (original.size() <= max_len) +return original; + +std::string truncated = original.substr(0, max_len); +warn("%s: Truncated \"%s\" to \"%s\"", original, truncated); +return truncated; +} + +void +ListenSocketUnix::listen() +{ +panic_if(listening, "Socket already listening!"); + +// only create socket if not already created by previous call +if (fd == -1) { +fd = socketCloexec(PF_UNIX, SOCK_STREAM, 0); +panic_if(fd < 0, "%s: Can't create unix socket:%s !", +name(), strerror(errno)); +} + +sockaddr_un serv_addr; +std::memset(_addr, 0, sizeof(serv_addr)); +size_t addr_size = prepSockaddrUn(serv_addr); + +fatal_if(bind(fd, (struct sockaddr *)&(serv_addr), addr_size) != 0, +"%s: Cannot bind unix socket %s: %s", name(), *this, +strerror(errno)); + +fatal_if(::listen(fd, 1) == -1, "%s: Failed to listen on %s: %s\n", +name(), *this, strerror(errno)); + +ccprintf(std::cerr, "%s: Listening for connections on %s\n", +name(), *this); + +listening = true; +anyListening = true; +} + +ListenSocketUnixFile::ListenSocketUnixFile(const std::string &_name, +const std::string &_dir, const std::string &_fname) : +ListenSocketUnix(_name), dir(_dir), +fname(truncate(_fname, sizeof(sockaddr_un::sun_path))) +{ +} + +ListenSocketUnixFile::~ListenSocketUnixFile() +{ +if (fd != -1) { +close(fd); +fd = -1; +unlink(); +} +} + +bool +ListenSocketUnixFile::unlink() const +{ +auto path = resolvedDir + "/" + fname; +return ::unlink(path.c_str()) == 0; +} + +size_t +ListenSocketUnixFile::prepSockaddrUn(sockaddr_un ) const +{ +addr.sun_family = AF_UNIX; +std::memcpy(addr.sun_path, fname.c_str(), fname.size()); +return sizeof(addr.sun_path); +} + +void +ListenSocketUnixFile::listen() +{ +auto resolvedDir = simout.resolve(dir); +warn_if(unlink(), +"%s: server path %s was occupied and will be replaced. Please " +"make sure there is no other server using the same path.", +name(), resolvedDir + "/" + fname); + +// Make sure "dir" exists. +std::error_code ec; +std::filesystem::create_directory(resolvedDir, ec); +fatal_if(ec, "Failed to create directory %s", ec.message()); + +// Change the working directory to the directory containing the socket so +// that we maximize the limited space in sockaddr_un.sun_path. +auto cwd = std::filesystem::current_path(ec); +panic_if(ec, "Failed to get current working directory %s", ec.message()); +std::filesystem::current_path(resolvedDir, ec); +fatal_if(ec, "Failed to change to directory %s: %s", +resolvedDir, ec.message()); + +ListenSocketUnix::listen(); + +std::filesystem::current_path(cwd, ec); +panic_if(ec, "Failed to change back working directory %s", ec.message()); +} + +void +ListenSocketUnixFile::output(std::ostream ) const +{ +os << "socket \"" << dir << "/" << fname << "\""; +} + +ListenSocketConfig +listenSocketUnixFileConfig(std::string dir, std::string fname) +{ +return ListenSocketConfig([dir, fname](const std::string ) { +return std::make_unique(name, dir, fname); +}); +} + +size_t +ListenSocketUnixAbstract::prepSockaddrUn(sockaddr_un ) const +{ +addr.sun_family = AF_UNIX; +addr.sun_path[0] = '\0'; +std::memcpy(_path[1], path.c_str(), path.size()); +return offsetof(sockaddr_un, sun_path) + path.size(); +} + +ListenSocketUnixAbstract::ListenSocketUnixAbstract( +const std::string &_name, const std::string &_path) : +ListenSocketUnix(_name), +path(truncate(_path,
[gem5-dev] [M] Change in gem5/gem5[develop]: base,python: Add a param type for host sockets.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69165?usp=email ) Change subject: base,python: Add a param type for host sockets. .. base,python: Add a param type for host sockets. These can either be set to an integer, in which case it's interpreted as a TCP port, or a string, in which case it's treated as a unix domain socket. If the unix domain socket is prefixed with a "@", it will be treated as an abstract socket. When stored in the ini file, there is always a prefix added to make parsing the string more systematic and less ambiguous. A port number is prefixed with "#", an abstract socket with "@", and a socket file with the prefix "P" for "path". Change-Id: I1fc7a579074e849b3becd936238c62fb0d9a2087 --- M src/base/socket.cc M src/base/socket.hh M src/python/m5/params.py M src/python/pybind11/core.cc 4 files changed, 99 insertions(+), 0 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index c401a08..0ef0062 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -196,6 +196,32 @@ return sfd; } +bool +ListenSocketConfig::parseIni(const std::string , +ListenSocketConfig ) +{ +if (value.size() == 0) { +retval = listenSocketEmptyConfig(); +return true; +} else if (value[0] == '@') { +retval = listenSocketUnixAbstractConfig(value.substr(1)); +return true; +} else if (value[0] == 'P') { +std::filesystem::path p(value.substr(1)); +retval = listenSocketUnixFileConfig(p.parent_path(), p.filename()); +return true; +} else if (value[0] == '#') { +uint64_t port; +bool ret = to_number(value.substr(1), port); +if (!ret) +return false; +retval = listenSocketInetConfig(port); +return true; +} else { +panic("Can't interpret %s as a host socket.", value); +} +} + ListenSocketInet::ListenSocketInet(const std::string &_name, int port) : ListenSocket(_name), _port(port) {} diff --git a/src/base/socket.hh b/src/base/socket.hh index 82e8375..5974348 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -152,6 +152,8 @@ operator bool() const { return (bool)builder; } +static bool parseIni(const std::string , ListenSocketConfig ); + private: Builder builder; }; diff --git a/src/python/m5/params.py b/src/python/m5/params.py index e9047a8..c2c1321 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1085,6 +1085,62 @@ code(f"{ret} to_bool({src}, {dest});") +class HostSocket(ParamValue): +cxx_type = "ListenSocketConfig" +@classmethod +def cxx_predecls(cls, code): +code('#include "base/socket.hh"') + +def __init__(self, value): +if isinstance(value, HostSocket): +self.value = value.value +else: +self.value = value + +def getValue(self): +from _m5.socket import listenSocketEmptyConfig +from _m5.socket import listenSocketInetConfig +from _m5.socket import listenSocketUnixFileConfig +from _m5.socket import listenSocketUnixAbstractConfig +if isinstance(self.value, str): +if self.value[0] == '@': +return listenSocketUnixAbstractConfig(self.value[1:]) +else: +d, f = os.path.split(self.value) +return listenSocketUnixFileConfig(d, f) +else: +if self.value == 0: +return listenSocketEmptyConfig() +else: +return listenSocketInetConfig(self.value) + +def __call__(self, value): +self.__init__(value) +return value + +def __str__(self): +if isinstance(self.value, str): +return self.value +else: +return "#" + str(self.value) + +def ini_str(self): +if isinstance(self.value, str): +if self.value[0] == '@': +return self.value +else: +return 'P' + self.value +else: +return "#" + str(self.value) + +@classmethod +def cxx_ini_predecls(cls, code): +code('#include "base/socket.hh"') + +@classmethod +def cxx_ini_parse(cls, code, src, dest, ret): +code(f"{ret} ListenSocketConfig::parseIni({src}, {dest});") + def IncEthernetAddr(addr, val=1): bytes = [int(x, 16) for x in addr.split(":")] bytes[5] += val diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc index bd83a74..0b03d5a 100644 --- a/src/python/pybind11/core.cc +++ b/src/python/pybind11/core.cc @@ -223,6 +223,20 @@ m.def("setInterpDir", ::setInterpDir); } +static void +init_socket(py::module_ _native) +{ +py::module_ m_socket = m_native.def_submodule("socket"); +m_socket +.def("listenSocketEmptyConfig", ) +.def("listenSocketInetConfig", ) +
[gem5-dev] [S] Change in gem5/gem5[develop]: base,dev: Simplify the ListenSocket::accept method.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69158?usp=email ) Change subject: base,dev: Simplify the ListenSocket::accept method. .. base,dev: Simplify the ListenSocket::accept method. Remove the nodelay option which is always set to the same thing, and simplify the logic of the method itself. Change-Id: I78cd91f99cbaec9abddedbc7dcddc563daedb81f --- M src/base/remote_gdb.cc M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index dd37a35..b709ac3 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -438,7 +438,7 @@ pollQueue.remove(incomingConnectionEvent); -int sfd = listener.accept(true); +int sfd = listener.accept(); if (sfd != -1) { if (isAttached()) diff --git a/src/base/socket.cc b/src/base/socket.cc index 23f2b40..0a62a88 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -239,17 +239,17 @@ // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. int -ListenSocket::accept(bool nodelay) +ListenSocket::accept() { struct sockaddr_in sockaddr; socklen_t slen = sizeof (sockaddr); int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd != -1 && nodelay) { -int i = 1; -if (::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (char *), - sizeof(i)) < 0) -warn("ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); -} +if (sfd == -1) +return -1; + +int i = 1; +int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); +warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); return sfd; } diff --git a/src/base/socket.hh b/src/base/socket.hh index af4a651..aa451b6 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -104,7 +104,7 @@ ListenSocket(); virtual ~ListenSocket(); -virtual int accept(bool nodelay = true); +virtual int accept(); virtual bool listen(int port, bool reuse = true); diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index c98838a..5792c44 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -190,7 +190,7 @@ if (!listener.islistening()) panic("%s: cannot accept a connection if not listening!", name()); -int fd = listener.accept(true); +int fd = listener.accept(); if (fd < 0) { warn("%s: failed to accept VNC connection!", name()); return; diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index 5b1e957..b28f255 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -280,7 +280,7 @@ if (!listener.islistening()) panic("TapListener(accept): cannot accept if we're not listening!"); -int sfd = listener.accept(true); +int sfd = listener.accept(); if (sfd != -1) tap->attach(sfd); } diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index d4108a3..fada99c 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -195,7 +195,7 @@ if (!listener.islistening()) panic("%s: cannot accept a connection if not listening!", name()); -int fd = listener.accept(true); +int fd = listener.accept(); if (data_fd != -1) { char message[] = "terminal already attached!\n"; atomic_write(fd, message, sizeof(message)); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69158?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I78cd91f99cbaec9abddedbc7dcddc563daedb81f Gerrit-Change-Number: 69158 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev: Simplify ListenSocket::listen().
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69159?usp=email ) Change subject: base,cpu,dev: Simplify ListenSocket::listen(). .. base,cpu,dev: Simplify ListenSocket::listen(). Remove the "reuse" parameter which default to true and was always also explicitly set to true. Tidy up the code itself slightly, mostly by using "panic_if" to remove some nesting. Change-Id: Ie23971aabf2fe4252d27f1887468360722a72379 --- M src/base/remote_gdb.cc M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc M src/base/vnc/vncserver.cc M src/cpu/nativetrace.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc 8 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index b709ac3..1a2fef4 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -417,7 +417,7 @@ return; } -while (!listener.listen(_port, true)) { +while (!listener.listen(_port)) { DPRINTF(GDBMisc, "Can't bind port %d\n", _port); _port++; } diff --git a/src/base/socket.cc b/src/base/socket.cc index 0a62a88..280f92b 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -185,24 +185,20 @@ // Create a socket and configure it for listening bool -ListenSocket::listen(int port, bool reuse) +ListenSocket::listen(int port) { -if (listening) -panic("Socket already listening!"); +panic_if(listening, "Socket already listening!"); // only create socket if not already created by a previous call if (fd == -1) { fd = socketCloexec(PF_INET, SOCK_STREAM, 0); -if (fd < 0) -panic("Can't create socket:%s !", strerror(errno)); +panic_if(fd < 0, "Can't create socket:%s !", strerror(errno)); } -if (reuse) { -int i = 1; -if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *), - sizeof(i)) < 0) -panic("ListenSocket(listen): setsockopt() SO_REUSEADDR failed!"); -} +int i = 1; +int ret = ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, , sizeof(i)); +panic_if(ret < 0, +"ListenSocket(listen): setsockopt() SO_REUSEADDR failed!"); struct sockaddr_in sockaddr; sockaddr.sin_family = PF_INET; @@ -211,16 +207,16 @@ sockaddr.sin_port = htons(port); // finally clear sin_zero std::memset(_zero, 0, sizeof(sockaddr.sin_zero)); -int ret = ::bind(fd, (struct sockaddr *), sizeof (sockaddr)); +ret = ::bind(fd, (struct sockaddr *), sizeof (sockaddr)); if (ret != 0) { -if (ret == -1 && errno != EADDRINUSE) -panic("ListenSocket(listen): bind() failed!"); +panic_if(ret == -1 && errno != EADDRINUSE, +"ListenSocket(listen): bind() failed!"); return false; } if (::listen(fd, 1) == -1) { -if (errno != EADDRINUSE) -panic("ListenSocket(listen): listen() failed!"); +panic_if(errno != EADDRINUSE, +"ListenSocket(listen): listen() failed!"); // User may decide to retry with a different port later; however, the // socket is already bound to a port and the next bind will surely // fail. We'll close the socket and reset fd to -1 so our user can diff --git a/src/base/socket.hh b/src/base/socket.hh index aa451b6..d2393e9 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -106,7 +106,7 @@ virtual int accept(); -virtual bool listen(int port, bool reuse = true); +virtual bool listen(int port); int getfd() const { return fd; } bool islistening() const { return listening; } diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index 1ab1f21..cb24c49 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -162,19 +162,6 @@ EXPECT_FALSE(listen_socket.allDisabled()); } -TEST(SocketTest, ListenToPortReuseFalse) -{ -MockListenSocket listen_socket; -/* - * The ListenSocket object should have the same state regardless as to - * whether reuse is true or false (it is true by default). - */ -EXPECT_TRUE(listen_socket.listen(TestPort1, false)); -EXPECT_NE(-1, listen_socket.getfd()); -EXPECT_TRUE(listen_socket.islistening()); -EXPECT_FALSE(listen_socket.allDisabled()); -} - TEST(SocketTest, RelistenWithSameInstanceSamePort) { MockListenSocket listen_socket; @@ -185,7 +172,9 @@ */ gtestLogOutput.str(""); EXPECT_ANY_THROW(listen_socket.listen(TestPort1)); -std::string expected = "panic: Socket already listening!\n"; +std::string expected = +"panic: panic condition listening occurred: " +"Socket already listening!\n"; std::string actual = gtestLogOutput.str(); EXPECT_EQ(expected, actual); } @@ -201,7 +190,9 @@ gtestLogOutput.str(""); EXPECT_ANY_THROW(listen_socket.listen(TestPort2));
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev,sim: Pull common logic into ListenSocket::listen().
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69160?usp=email ) Change subject: base,cpu,dev,sim: Pull common logic into ListenSocket::listen(). .. base,cpu,dev,sim: Pull common logic into ListenSocket::listen(). Create a version of listen() which handles common logic internally, including scanning for an available port number, and notifying what port was chosen. The port is managed internal to ListenSocket, so that the logic interacting with it doesn't need to manually manage a port number, and hence a port number does not need to exist for non AF_INET sockets. Change-Id: Ie371eccc4d0da5e7b90714508e4cb72fb0091875 --- M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/base/vnc/vncserver.hh M src/cpu/nativetrace.cc M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc M src/dev/serial/terminal.hh M src/sim/workload.cc 11 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 1a2fef4..2e66a92 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,7 +392,7 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), -_port(_port), fd(-1), sys(_system), +listener(name(), _port), fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), trapEvent(this), singleStepEvent(*this) {} @@ -417,17 +417,14 @@ return; } -while (!listener.listen(_port)) { -DPRINTF(GDBMisc, "Can't bind port %d\n", _port); -_port++; -} +listener.listen(); incomingConnectionEvent = new IncomingConnectionEvent(this, listener.getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); -ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n", - curTick(), name(), _port); +ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", + curTick(), name(), listener); } void @@ -448,12 +445,12 @@ } } -int -BaseRemoteGDB::port() const +const ListenSocket & +BaseRemoteGDB::hostSocket() const { panic_if(!listener.islistening(), - "Remote GDB port is unknown until listen() has been called.\n"); -return _port; + "Remote GDB socket is unknown until listen() has been called."); +return listener; } void diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 7981a13..25b7c54 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -161,7 +161,7 @@ void listen(); void connect(); -int port() const; +const ListenSocket () const; void attach(int fd); void detach(); @@ -232,7 +232,6 @@ IncomingDataEvent *incomingDataEvent; ListenSocket listener; -int _port; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 280f92b..1aff73a 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,10 +173,12 @@ // // -ListenSocket::ListenSocket() -: listening(false), fd(-1) +ListenSocket::ListenSocket(const std::string &_name, int port) +: Named(_name), listening(false), fd(-1), _port(port) {} +ListenSocket::ListenSocket() : ListenSocket("", -1) {} + ListenSocket::~ListenSocket() { if (fd != -1) @@ -231,6 +233,23 @@ return true; } +void +ListenSocket::listen() +{ +while (!listen(_port)) { +_port++; +fatal_if(_port > 65536, "%s: cannot find an available port.", name()); +} +ccprintf(std::cerr, "%s: Listening for connections on %s\n", +name(), *this); +} + +void +ListenSocket::output(std::ostream ) const +{ +os << "port " << _port; +} + // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. diff --git a/src/base/socket.hh b/src/base/socket.hh index d2393e9..7a616bd 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -35,6 +35,8 @@ #include +#include "base/named.hh" + namespace gem5 { @@ -69,7 +71,7 @@ std::string formattedPath; }; -class ListenSocket +class ListenSocket : public Named { protected: /** @@ -90,6 +92,7 @@ protected: bool listening; int fd; +int _port; /* * cleanup resets the static variables back to their default values. @@ -101,12 +104,16 @@ * @ingroup api_socket * @{ */ +ListenSocket(const std::string &_name, int port); ListenSocket(); virtual ~ListenSocket(); virtual int accept(); virtual bool listen(int port); +virtual void listen(); + +virtual void output(std::ostream ) const; int getfd() const { return fd; } bool islistening() const { return listening; } @@ -119,6 +126,13 @@
[gem5-dev] [XS] Change in gem5/gem5[develop]: base: Flip the default for ListenSocket::accept(bool nodelay).
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69157?usp=email ) Change subject: base: Flip the default for ListenSocket::accept(bool nodelay). .. base: Flip the default for ListenSocket::accept(bool nodelay). This option was almost always overridden from false to true anyway, except in one place (in the ethertap device) which was likely just by accident. This will give external users a chance to remove the option without changing behavior, so that the option can be removed entirely in a later change. Change-Id: I77add40b8131b91997b2aecbfff6c7de0ee9ead9 --- M src/base/socket.hh 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/socket.hh b/src/base/socket.hh index f3b2760..af4a651 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -104,7 +104,7 @@ ListenSocket(); virtual ~ListenSocket(); -virtual int accept(bool nodelay = false); +virtual int accept(bool nodelay = true); virtual bool listen(int port, bool reuse = true); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69157?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I77add40b8131b91997b2aecbfff6c7de0ee9ead9 Gerrit-Change-Number: 69157 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: base,cpu,dev: Add a level of indirection for ListenSockets.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email ) Change subject: base,cpu,dev: Add a level of indirection for ListenSockets. .. base,cpu,dev: Add a level of indirection for ListenSockets. This makes room for there to be different implementations for different types of sockets. Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f --- M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/base/vnc/vncserver.hh M src/cpu/nativetrace.cc M src/cpu/nativetrace.hh M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc M src/dev/serial/terminal.hh 11 files changed, 76 insertions(+), 38 deletions(-) diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 2e66a92..095b2bd 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,10 +392,11 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), -listener(name(), _port), fd(-1), sys(_system), -connectEvent(*this), disconnectEvent(*this), trapEvent(this), -singleStepEvent(*this) -{} +fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), +trapEvent(this), singleStepEvent(*this) +{ +listener = listenSocketInetConfig(_port).build(name()); +} BaseRemoteGDB::~BaseRemoteGDB() { @@ -417,25 +418,22 @@ return; } -listener.listen(); +listener->listen(); incomingConnectionEvent = -new IncomingConnectionEvent(this, listener.getfd(), POLLIN); +new IncomingConnectionEvent(this, listener->getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); - -ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", - curTick(), name(), listener); } void BaseRemoteGDB::connect() { -panic_if(!listener.islistening(), +panic_if(!listener->islistening(), "Can't accept GDB connections without any threads!"); pollQueue.remove(incomingConnectionEvent); -int sfd = listener.accept(); +int sfd = listener->accept(); if (sfd != -1) { if (isAttached()) @@ -448,9 +446,9 @@ const ListenSocket & BaseRemoteGDB::hostSocket() const { -panic_if(!listener.islistening(), +panic_if(!listener->islistening(), "Remote GDB socket is unknown until listen() has been called."); -return listener; +return *listener; } void @@ -513,7 +511,7 @@ assert(selectThreadContext(_tc->contextId())); // Now that we have a thread, we can start listening. -if (!listener.islistening()) +if (!listener->islistening()) listen(); } diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 25b7c54..bf10e77 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -231,7 +231,7 @@ IncomingConnectionEvent *incomingConnectionEvent; IncomingDataEvent *incomingDataEvent; -ListenSocket listener; +ListenSocketPtr listener; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 1aff73a..5fb8492 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -269,4 +269,12 @@ return sfd; } +ListenSocketConfig +listenSocketInetConfig(int port) +{ +return ListenSocketConfig([port](const std::string ) { +return std::make_unique(name, port); +}); +} + } // namespace gem5 diff --git a/src/base/socket.hh b/src/base/socket.hh index 81f4d62..638ce40 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include #include "base/named.hh" @@ -127,6 +130,33 @@ /** @} */ // end of api_socket }; +using ListenSocketPtr = std::unique_ptr; + +class ListenSocketConfig +{ + public: +using Builder = std::function)>; + +ListenSocketConfig() {} +ListenSocketConfig(Builder _builder) : builder(_builder) {} + +ListenSocketPtr +build(const std::string ) const +{ +assert(builder); +return builder(name); +} + +operator bool() const { return (bool)builder; } + + private: +Builder builder; +}; + +static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; } + +ListenSocketConfig listenSocketInetConfig(int port); + inline static std::ostream & operator << (std::ostream , const ListenSocket ) { diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 2d32cef..4e5c951 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -117,8 +117,8 @@ */ VncServer::VncServer(const Params ) : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number), - listener(p.name, p.port), sendUpdate(false), - supportsRawEnc(false), supportsResizeEnc(false) +
[gem5-dev] [M] Change in gem5/gem5[develop]: base: Abstract the AF_INET-ness out of ListenSocket.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email ) Change subject: base: Abstract the AF_INET-ness out of ListenSocket. .. base: Abstract the AF_INET-ness out of ListenSocket. Put them into a subclass called ListenSocketInet. Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index 5fb8492..0324788 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,11 +173,7 @@ // // -ListenSocket::ListenSocket(const std::string &_name, int port) -: Named(_name), listening(false), fd(-1), _port(port) -{} - -ListenSocket::ListenSocket() : ListenSocket("", -1) {} +ListenSocket::ListenSocket(const std::string &_name) : Named(_name) {} ListenSocket::~ListenSocket() { @@ -185,9 +181,41 @@ close(fd); } +// Open a connection. Accept will block, so if you don't want it to, +// make sure a connection is ready before you call accept. +int +ListenSocket::accept() +{ +struct sockaddr_in sockaddr; +socklen_t slen = sizeof (sockaddr); +int sfd = acceptCloexec(fd, (struct sockaddr *), ); +if (sfd == -1) +return -1; + +return sfd; +} + +ListenSocketInet::ListenSocketInet(const std::string &_name, int port) +: ListenSocket(_name), _port(port) +{} + +int +ListenSocketInet::accept() +{ +int sfd = ListenSocket::accept(); +if (sfd == -1) +return -1; + +int i = 1; +int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); +warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); + +return sfd; +} + // Create a socket and configure it for listening bool -ListenSocket::listen(int port) +ListenSocketInet::listen(int port) { panic_if(listening, "Socket already listening!"); @@ -234,7 +262,7 @@ } void -ListenSocket::listen() +ListenSocketInet::listen() { while (!listen(_port)) { _port++; @@ -245,35 +273,16 @@ } void -ListenSocket::output(std::ostream ) const +ListenSocketInet::output(std::ostream ) const { os << "port " << _port; } - -// Open a connection. Accept will block, so if you don't want it to, -// make sure a connection is ready before you call accept. -int -ListenSocket::accept() -{ -struct sockaddr_in sockaddr; -socklen_t slen = sizeof (sockaddr); -int sfd = acceptCloexec(fd, (struct sockaddr *), ); -if (sfd == -1) -return -1; - -int i = 1; -int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, , sizeof(i)); -warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); - -return sfd; -} - ListenSocketConfig listenSocketInetConfig(int port) { return ListenSocketConfig([port](const std::string ) { -return std::make_unique(name, port); +return std::make_unique(name, port); }); } diff --git a/src/base/socket.hh b/src/base/socket.hh index 638ce40..e233d85 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -93,31 +93,27 @@ static void loopbackOnly(); protected: -bool listening; -int fd; -int _port; +bool listening = false; +int fd = -1; /* * cleanup resets the static variables back to their default values. */ static void cleanup(); -virtual bool listen(int port); +ListenSocket(const std::string &_name); public: /** * @ingroup api_socket * @{ */ -ListenSocket(const std::string &_name, int port); -ListenSocket(); virtual ~ListenSocket(); virtual int accept(); +virtual void listen() = 0; -virtual void listen(); - -virtual void output(std::ostream ) const; +virtual void output(std::ostream ) const = 0; int getfd() const { return fd; } bool islistening() const { return listening; } @@ -130,6 +126,13 @@ /** @} */ // end of api_socket }; +inline static std::ostream & +operator << (std::ostream , const ListenSocket ) +{ +socket.output(os); +return os; +} + using ListenSocketPtr = std::unique_ptr; class ListenSocketConfig @@ -155,14 +158,24 @@ static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; } -ListenSocketConfig listenSocketInetConfig(int port); +// AF_INET based sockets. -inline static std::ostream & -operator << (std::ostream , const ListenSocket ) +class ListenSocketInet : public ListenSocket { -socket.output(os); -return os; -} + protected: +int _port; + +virtual bool listen(int port); + + public: +ListenSocketInet(const std::string &_name, int port); + +int accept() override; +void listen() override; +void output(std::ostream ) const override; +}; + +ListenSocketConfig listenSocketInetConfig(int port); } // namespace gem5 diff --git
[gem5-dev] [S] Change in gem5/gem5[develop]: mem: Add a parameter which will make a memory truly a ROM.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/68557?usp=email ) Change subject: mem: Add a parameter which will make a memory truly a ROM. .. mem: Add a parameter which will make a memory truly a ROM. This piggy-backs on the writeOK method which already exists. It also modifies the flags returned as part of the memory's backdoor descriptor which doesn't enforce that the memory is read only, but will let the other party know it's expected not to write to it. Change-Id: Ib95e619c76c327d302e62a88515a92af11815981 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68557 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Matthew Poremba --- M src/mem/AbstractMemory.py M src/mem/abstract_mem.cc M src/mem/abstract_mem.hh 3 files changed, 14 insertions(+), 4 deletions(-) Approvals: Matthew Poremba: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/mem/AbstractMemory.py b/src/mem/AbstractMemory.py index ea88fd8..7ab24bc 100644 --- a/src/mem/AbstractMemory.py +++ b/src/mem/AbstractMemory.py @@ -74,3 +74,5 @@ image_file = Param.String( "", "Image to load into memory as its initial contents" ) + +writeable = Param.Bool(True, "Allow writes to this memory") diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 03f2557..9340f7e 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -59,10 +59,11 @@ AbstractMemory::AbstractMemory(const Params ) : ClockedObject(p), range(p.range), pmemAddr(NULL), backdoor(params().range, nullptr, - (MemBackdoor::Flags)(MemBackdoor::Readable | - MemBackdoor::Writeable)), + (MemBackdoor::Flags)(p.writeable ? + MemBackdoor::Readable | MemBackdoor::Writeable : + MemBackdoor::Readable)), confTableReported(p.conf_table_reported), inAddrMap(p.in_addr_map), -kvmMap(p.kvm_map), _system(NULL), +kvmMap(p.kvm_map), writeable(p.writeable), _system(NULL), stats(*this) { panic_if(!range.valid() || !range.size(), diff --git a/src/mem/abstract_mem.hh b/src/mem/abstract_mem.hh index 53b7940..7f12487 100644 --- a/src/mem/abstract_mem.hh +++ b/src/mem/abstract_mem.hh @@ -129,6 +129,9 @@ // Should KVM map this memory for the guest const bool kvmMap; +// Are writes allowed to this memory +const bool writeable; + std::list lockedAddrList; // helper function for checkLockedAddrs(): we really want to @@ -149,8 +152,12 @@ // requesting execution context), 'true' otherwise. Note that // this method must be called on *all* stores since even // non-conditional stores must clear any matching lock addresses. -bool writeOK(PacketPtr pkt) { +bool +writeOK(PacketPtr pkt) +{ const RequestPtr = pkt->req; +if (!writeable) +return false; if (lockedAddrList.empty()) { // no locked addrs: nothing to check, store_conditional fails bool isLLSC = pkt->isLLSC(); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/68557?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ib95e619c76c327d302e62a88515a92af11815981 Gerrit-Change-Number: 68557 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Matthew Poremba Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: mem: Add a parameter which will make a memory truly a ROM.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/68557?usp=email ) Change subject: mem: Add a parameter which will make a memory truly a ROM. .. mem: Add a parameter which will make a memory truly a ROM. This piggy-backs on the writeOK method which already exists. It also modifies the flags returned as part of the memory's backdoor descriptor which doesn't enforce that the memory is read only, but will let the other party know it's expected not to write to it. Bug: 254411221 Test: Used this flag with the GSA's boot ROM and saw that it no longer Test: accepted a corrupting write which overwrote the reset vector. Change-Id: Ib95e619c76c327d302e62a88515a92af11815981 --- M src/mem/AbstractMemory.py M src/mem/abstract_mem.cc M src/mem/abstract_mem.hh 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/mem/AbstractMemory.py b/src/mem/AbstractMemory.py index ea88fd8..7ab24bc 100644 --- a/src/mem/AbstractMemory.py +++ b/src/mem/AbstractMemory.py @@ -74,3 +74,5 @@ image_file = Param.String( "", "Image to load into memory as its initial contents" ) + +writeable = Param.Bool(True, "Allow writes to this memory") diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 03f2557..9340f7e 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -59,10 +59,11 @@ AbstractMemory::AbstractMemory(const Params ) : ClockedObject(p), range(p.range), pmemAddr(NULL), backdoor(params().range, nullptr, - (MemBackdoor::Flags)(MemBackdoor::Readable | - MemBackdoor::Writeable)), + (MemBackdoor::Flags)(p.writeable ? + MemBackdoor::Readable | MemBackdoor::Writeable : + MemBackdoor::Readable)), confTableReported(p.conf_table_reported), inAddrMap(p.in_addr_map), -kvmMap(p.kvm_map), _system(NULL), +kvmMap(p.kvm_map), writeable(p.writeable), _system(NULL), stats(*this) { panic_if(!range.valid() || !range.size(), diff --git a/src/mem/abstract_mem.hh b/src/mem/abstract_mem.hh index 53b7940..7f12487 100644 --- a/src/mem/abstract_mem.hh +++ b/src/mem/abstract_mem.hh @@ -129,6 +129,9 @@ // Should KVM map this memory for the guest const bool kvmMap; +// Are writes allowed to this memory +const bool writeable; + std::list lockedAddrList; // helper function for checkLockedAddrs(): we really want to @@ -149,8 +152,12 @@ // requesting execution context), 'true' otherwise. Note that // this method must be called on *all* stores since even // non-conditional stores must clear any matching lock addresses. -bool writeOK(PacketPtr pkt) { +bool +writeOK(PacketPtr pkt) +{ const RequestPtr = pkt->req; +if (!writeable) +return false; if (lockedAddrList.empty()) { // no locked addrs: nothing to check, store_conditional fails bool isLLSC = pkt->isLLSC(); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/68557?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ib95e619c76c327d302e62a88515a92af11815981 Gerrit-Change-Number: 68557 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: cpu: Add a generic model_reset port on the BaseCPU.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67574?usp=email ) Change subject: cpu: Add a generic model_reset port on the BaseCPU. .. cpu: Add a generic model_reset port on the BaseCPU. This port will stop execution on the CPU when raised. When lowered, it will allow execution to reset the state of the CPU and allow execution to resume. The state could theoretically be reset when the reset state starts, but then it wouldn't reflect the most up to date condition of the CPU when resuming. For instance, if a reset vector was set somehow, that wouldn't be updated if it was changed while reset was asserted. The tradeoff is that the state won't look like it will when execution resumes while reset is held (to GDB for instance), but that seems like a more obvious and less common sort of problem. This signal is managed by the BaseCPU itself, but is backed by a virtual method which can be overridden by other CPU types which may not work the same way or have the same components. For instance, a fast model CPU could toggle reset lines on the underlying model and let it handle resetting all the state. The fast models in particular already have a generic reset line with the same name, but they have it at the level of the fast model which may have multiple cores within it, each represented by a gem5 CPU. It isn't implemented here, but there could be some sort of cooperation between these signals where the reset at the core level is considered an "or" of the cluster level reset and the individual core level resets. At least in the A76 model, there are resets for each individual core within the cluster as well, which the generic reset toggles. Another option would be to get rid of the whole cluster reset pin, and make the user gang the resets for each of the cores together to whatever reset signal they're using. That's effectively what the cluster level reset is doing, but within the C++ of the model wrapper instead of in the python config. Change-Id: Ie6b4769298ea224ec5dc88360cbb52ee8fbbf69c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67574 Tested-by: kokoro Reviewed-by: Roger Chang Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang --- M src/cpu/BaseCPU.py M src/cpu/base.cc M src/cpu/base.hh 3 files changed, 106 insertions(+), 0 deletions(-) Approvals: Gabe Black: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved kokoro: Regressions pass Roger Chang: Looks good to me, but someone else must approve diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 438d4f4..d77036a 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -53,6 +53,7 @@ from m5.objects.SubSystem import SubSystem from m5.objects.ClockDomain import * from m5.objects.Platform import Platform +from m5.objects.ResetPort import ResetResponsePort default_tracer = ExeTracer() @@ -153,6 +154,8 @@ "between CPU models)", ) +model_reset = ResetResponsePort("Generic reset for the CPU") + tracer = Param.InstTracer(default_tracer, "Instruction tracer") icache_port = RequestPort("Instruction Port") diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 98c53d4..60d443a 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -47,6 +47,8 @@ #include #include +#include "arch/generic/decoder.hh" +#include "arch/generic/isa.hh" #include "arch/generic/tlb.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" @@ -130,6 +132,7 @@ _dataRequestorId(p.system->getRequestorId(this, "data")), _taskId(context_switch_task_id::Unknown), _pid(invldPid), _switchedOut(p.switched_out), _cacheLineSize(p.system->cacheLineSize()), + modelResetPort(p.name + ".model_reset"), interrupts(p.interrupts), numThreads(p.numThreads), system(p.system), previousCycle(0), previousState(CPU_STATE_SLEEP), functionTraceStream(nullptr), currentFunctionStart(0), @@ -178,6 +181,10 @@ fatal("Number of ISAs (%i) assigned to the CPU does not equal number " "of threads (%i).\n", params().isa.size(), numThreads); } + +modelResetPort.onChange([this](const bool _val) { +setReset(new_val); +}); } void @@ -413,6 +420,8 @@ return getDataPort(); else if (if_name == "icache_port") return getInstPort(); +else if (if_name == "model_reset") +return modelResetPort; else return ClockedObject::getPort(if_name, idx); } @@ -479,6 +488,12 @@ void BaseCPU::activateContext(ThreadID thread_num) { +if (modelResetPort.state()) { +DPRINTF(Thread, "CPU in reset, not activating context %d\n", +threadContexts[thread_num]->contextId()); +return; +} + DPRINTF(Thread, "activate contextId %d\n", threadContexts[thread_num]->contextId()); // Squash enter power gating event while cpu gets activated
[gem5-dev] [S] Change in gem5/gem5[develop]: dev: Add a definition for VectorResetResponsePort.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67576?usp=email ) Change subject: dev: Add a definition for VectorResetResponsePort. .. dev: Add a definition for VectorResetResponsePort. This is just a simple extension of the regular ResetResponsePort, and is useful if there is a collection of reset pins on a device. Change-Id: I6ccb21e949d3a51bf8b788ffd23e4b2b02706da9 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67576 Tested-by: kokoro Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black --- M src/dev/ResetPort.py 1 file changed, 24 insertions(+), 1 deletion(-) Approvals: Yu-hsin Wang: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/dev/ResetPort.py b/src/dev/ResetPort.py index f35bc11..15caa47 100644 --- a/src/dev/ResetPort.py +++ b/src/dev/ResetPort.py @@ -42,8 +42,15 @@ super().__init__(RESET_RESPONSE_ROLE, desc) -# VectorResetRequestPort presents a bank of artifact reset request +# VectorResetRequestPort represents a bank of artifact reset request # ports. class VectorResetRequestPort(VectorPort): def __init__(self, desc): super().__init__(RESET_REQUEST_ROLE, desc, is_source=True) + + +# VectorResetResponsePort represents a bank of artifact reset request +# ports. +class VectorResetResponsePort(VectorPort): +def __init__(self, desc): +super().__init__(RESET_RESPONSE_ROLE, desc) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67576?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I6ccb21e949d3a51bf8b788ffd23e4b2b02706da9 Gerrit-Change-Number: 67576 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-CC: Gabe Black Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: fastmodel: Export the reset signals of the GIC.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67575?usp=email ) Change subject: fastmodel: Export the reset signals of the GIC. .. fastmodel: Export the reset signals of the GIC. These are the "reset" and "po_reset" lines. It seems reasonable that these are the normal reset and the power on reset signals, but that's not spelled out in the fast model "lisa" file, nor does it explain exactly what the difference is between them. Change-Id: I686b4d973fc3cfff8a3ec05f8c95ee2cb6ff6698 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67575 Reviewed-by: Jui-min Lee Maintainer: Gabe Black Tested-by: kokoro --- M src/arch/arm/fastmodel/GIC/FastModelGIC.py M src/arch/arm/fastmodel/GIC/GIC.lisa M src/arch/arm/fastmodel/GIC/gic.cc M src/arch/arm/fastmodel/GIC/gic.hh 4 files changed, 54 insertions(+), 1 deletion(-) Approvals: Jui-min Lee: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/arch/arm/fastmodel/GIC/FastModelGIC.py b/src/arch/arm/fastmodel/GIC/FastModelGIC.py index ce0a8c5..b1a9a3c 100644 --- a/src/arch/arm/fastmodel/GIC/FastModelGIC.py +++ b/src/arch/arm/fastmodel/GIC/FastModelGIC.py @@ -42,6 +42,7 @@ from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket from m5.objects.Gic import BaseGic from m5.objects.IntPin import VectorIntSourcePin +from m5.objects.ResetPort import ResetResponsePort from m5.objects.SystemC import SystemC_ScModule GICV3_COMMS_TARGET_ROLE = "GICV3 COMMS TARGET" @@ -850,6 +851,9 @@ wake_request = VectorIntSourcePin("GIC wake request initiator") +reset = ResetResponsePort("Reset") +po_reset = ResetResponsePort("Power on reset") + # Used for DTB autogeneration _state = FdtState(addr_cells=2, size_cells=2, interrupt_cells=3) diff --git a/src/arch/arm/fastmodel/GIC/GIC.lisa b/src/arch/arm/fastmodel/GIC/GIC.lisa index 34b09c8..5443b55 100644 --- a/src/arch/arm/fastmodel/GIC/GIC.lisa +++ b/src/arch/arm/fastmodel/GIC/GIC.lisa @@ -56,6 +56,10 @@ // Outgoing wake requests. gic.wake_request => self.wake_request; +// Reset signals. +self.normal_reset => gic.reset; +self.po_reset => gic.po_reset; + // Internal ports for PPI and SPI programmatic access. self.ppi_0 => gic.ppi_in_0; self.ppi_1 => gic.ppi_in_1; @@ -405,6 +409,9 @@ } } +slave port normal_reset; +slave port po_reset; + internal slave port spi[988]; internal slave port ppi_0[16]; diff --git a/src/arch/arm/fastmodel/GIC/gic.cc b/src/arch/arm/fastmodel/GIC/gic.cc index 493aa81..5f01cfb 100644 --- a/src/arch/arm/fastmodel/GIC/gic.cc +++ b/src/arch/arm/fastmodel/GIC/gic.cc @@ -72,10 +72,15 @@ SCGIC::SCGIC(const SCFastModelGICParams , sc_core::sc_module_name _name) -: scx_evs_GIC(_name), _params(params) +: scx_evs_GIC(_name), _params(params), + resetPort(params.name + ".reset", 0), + poResetPort(params.name + ".po_reset", 0) { signalInterrupt.bind(signal_interrupt); +resetPort.signal_out.bind(scx_evs_GIC::normal_reset); +poResetPort.signal_out.bind(scx_evs_GIC::po_reset); + for (int i = 0; i < wake_request.size(); i++) { wakeRequests.emplace_back( new SignalReceiver(csprintf("%s.wakerequest[%d]", name(), i))); @@ -298,6 +303,18 @@ set_parameter("gic.consolidators", params.consolidators); } +Port & +SCGIC::gem5_getPort(const std::string _name, int idx) +{ +if (if_name == "reset") { +return resetPort; +} else if (if_name == "po_reset") { +return poResetPort; +} else { +return scx_evs_GIC::gem5_getPort(if_name, idx); +} +} + void SCGIC::before_end_of_elaboration() { @@ -341,6 +358,8 @@ return *ptr; } else if (if_name == "wake_request") { return *wakeRequestPorts.at(idx); +} else if (if_name == "reset" || if_name == "po_reset") { +return scGIC->gem5_getPort(if_name, idx); } else { return BaseGic::getPort(if_name, idx); } diff --git a/src/arch/arm/fastmodel/GIC/gic.hh b/src/arch/arm/fastmodel/GIC/gic.hh index 0e502fc..070fe3b 100644 --- a/src/arch/arm/fastmodel/GIC/gic.hh +++ b/src/arch/arm/fastmodel/GIC/gic.hh @@ -37,6 +37,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/common/signal_sender.hh" #include "dev/arm/base_gic.hh" #include "dev/intpin.hh" #include "params/FastModelGIC.hh" @@ -91,9 +92,13 @@ SCGIC(const SCFastModelGICParams ) : SCGIC(p, p.name.c_str()) {} SCGIC(const SCFastModelGICParams , sc_core::sc_module_name _name); +Port _getPort(const std::string _name, int idx) override; + SignalInterruptInitiatorSocket signalInterrupt; std::vector> wakeRequests; +SignalSender
[gem5-dev] [S] Change in gem5/gem5[develop]: arch-riscv: Implement the resetThread method on the ISA object.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67573?usp=email ) Change subject: arch-riscv: Implement the resetThread method on the ISA object. .. arch-riscv: Implement the resetThread method on the ISA object. This method invokes a Reset fault on the associated ThreadContext. Change-Id: Ie0725b06e0b506640b9038a986a9c56d9eed7011 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67573 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Roger Chang --- M src/arch/riscv/isa.cc M src/arch/riscv/isa.hh 2 files changed, 24 insertions(+), 0 deletions(-) Approvals: Roger Chang: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 6e4c380..3809c61 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -34,6 +34,7 @@ #include #include +#include "arch/riscv/faults.hh" #include "arch/riscv/interrupts.hh" #include "arch/riscv/mmu.hh" #include "arch/riscv/pagetable.hh" @@ -723,6 +724,12 @@ tc->getCpuPtr()->wakeup(tc->threadId()); } +void +ISA::resetThread() +{ +Reset().invoke(tc); +} + } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index e332956..5a2a610 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -127,6 +127,8 @@ void globalClearExclusive() override; +void resetThread() override; + RiscvType rvType() const { return rv_type; } }; -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67573?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie0725b06e0b506640b9038a986a9c56d9eed7011 Gerrit-Change-Number: 67573 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Roger Chang Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-CC: Giacomo Travaglini Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: arch: Add a virtual method to the BaseISA to reset its ThreadContext.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67572?usp=email ) Change subject: arch: Add a virtual method to the BaseISA to reset its ThreadContext. .. arch: Add a virtual method to the BaseISA to reset its ThreadContext. This will be used as part of a generic CPU reset mechanism. Change-Id: I010f6bdaca0cbb6be1799ccdc345c4828515209d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67572 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- M src/arch/generic/isa.hh 1 file changed, 18 insertions(+), 0 deletions(-) Approvals: Gabe Black: Looks good to me, approved Giacomo Travaglini: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/generic/isa.hh b/src/arch/generic/isa.hh index e4e7929..e9e4d95 100644 --- a/src/arch/generic/isa.hh +++ b/src/arch/generic/isa.hh @@ -43,6 +43,7 @@ #include #include "arch/generic/pcstate.hh" +#include "base/logging.hh" #include "cpu/reg_class.hh" #include "mem/packet.hh" #include "mem/request.hh" @@ -83,6 +84,8 @@ virtual bool inUserMode() const = 0; virtual void copyRegsFrom(ThreadContext *src) = 0; +virtual void resetThread() { panic("Thread reset not implemented."); } + const RegClasses () const { return _regClasses; } // Locked memory handling functions. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67572?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I010f6bdaca0cbb6be1799ccdc345c4828515209d Gerrit-Change-Number: 67572 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Roger Chang Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: arch-riscv: Get rid of redundant reset fault invocation.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67571?usp=email ) Change subject: arch-riscv: Get rid of redundant reset fault invocation. .. arch-riscv: Get rid of redundant reset fault invocation. It was added in one change, another pending change which also added it was rebased on top of it, and the redundant addition was left in when the second change was submitted. Change-Id: I3faf53bca983d8568af45ec7174c2a064eadc0a6 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67571 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Roger Chang --- M src/arch/riscv/bare_metal/fs_workload.cc 1 file changed, 17 insertions(+), 5 deletions(-) Approvals: Roger Chang: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/arch/riscv/bare_metal/fs_workload.cc b/src/arch/riscv/bare_metal/fs_workload.cc index 83f5411..4f7adb3 100644 --- a/src/arch/riscv/bare_metal/fs_workload.cc +++ b/src/arch/riscv/bare_metal/fs_workload.cc @@ -59,11 +59,6 @@ { Workload::initState(); -for (auto *tc: system->threads) { -RiscvISA::Reset().invoke(tc); -tc->activate(); -} - warn_if(!bootloader->buildImage().write(system->physProxy), "Could not load sections to memory."); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67571?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I3faf53bca983d8568af45ec7174c2a064eadc0a6 Gerrit-Change-Number: 67571 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Roger Chang Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: dev: Add a definition for VectorResetResponsePort.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67576?usp=email ) Change subject: dev: Add a definition for VectorResetResponsePort. .. dev: Add a definition for VectorResetResponsePort. This is just a simple extension of the regular ResetResponsePort, and is useful if there is a collection of reset pins on a device. Change-Id: I6ccb21e949d3a51bf8b788ffd23e4b2b02706da9 --- M src/dev/ResetPort.py 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dev/ResetPort.py b/src/dev/ResetPort.py index f35bc11..15caa47 100644 --- a/src/dev/ResetPort.py +++ b/src/dev/ResetPort.py @@ -42,8 +42,15 @@ super().__init__(RESET_RESPONSE_ROLE, desc) -# VectorResetRequestPort presents a bank of artifact reset request +# VectorResetRequestPort represents a bank of artifact reset request # ports. class VectorResetRequestPort(VectorPort): def __init__(self, desc): super().__init__(RESET_REQUEST_ROLE, desc, is_source=True) + + +# VectorResetResponsePort represents a bank of artifact reset request +# ports. +class VectorResetResponsePort(VectorPort): +def __init__(self, desc): +super().__init__(RESET_RESPONSE_ROLE, desc) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67576?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I6ccb21e949d3a51bf8b788ffd23e4b2b02706da9 Gerrit-Change-Number: 67576 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: fastmodel: Export the reset signals of the GIC.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67575?usp=email ) Change subject: fastmodel: Export the reset signals of the GIC. .. fastmodel: Export the reset signals of the GIC. These are the "reset" and "po_reset" lines. It seems reasonable that these are the normal reset and the power on reset signals, but that's not spelled out in the fast model "lisa" file, nor does it explain exactly what the difference is between them. Change-Id: I686b4d973fc3cfff8a3ec05f8c95ee2cb6ff6698 --- M src/arch/arm/fastmodel/GIC/FastModelGIC.py M src/arch/arm/fastmodel/GIC/GIC.lisa M src/arch/arm/fastmodel/GIC/gic.cc M src/arch/arm/fastmodel/GIC/gic.hh 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/fastmodel/GIC/FastModelGIC.py b/src/arch/arm/fastmodel/GIC/FastModelGIC.py index ce0a8c5..24ab660 100644 --- a/src/arch/arm/fastmodel/GIC/FastModelGIC.py +++ b/src/arch/arm/fastmodel/GIC/FastModelGIC.py @@ -42,6 +42,7 @@ from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket from m5.objects.Gic import BaseGic from m5.objects.IntPin import VectorIntSourcePin +from m5.objects.ResetPort import ResetResponsePort from m5.objects.SystemC import SystemC_ScModule GICV3_COMMS_TARGET_ROLE = "GICV3 COMMS TARGET" @@ -850,6 +851,9 @@ wake_request = VectorIntSourcePin("GIC wake request initiator") +reset = ResetResponsePort('Reset') +po_reset = ResetResponsePort('Power on reset') + # Used for DTB autogeneration _state = FdtState(addr_cells=2, size_cells=2, interrupt_cells=3) diff --git a/src/arch/arm/fastmodel/GIC/GIC.lisa b/src/arch/arm/fastmodel/GIC/GIC.lisa index 34b09c8..5443b55 100644 --- a/src/arch/arm/fastmodel/GIC/GIC.lisa +++ b/src/arch/arm/fastmodel/GIC/GIC.lisa @@ -56,6 +56,10 @@ // Outgoing wake requests. gic.wake_request => self.wake_request; +// Reset signals. +self.normal_reset => gic.reset; +self.po_reset => gic.po_reset; + // Internal ports for PPI and SPI programmatic access. self.ppi_0 => gic.ppi_in_0; self.ppi_1 => gic.ppi_in_1; @@ -405,6 +409,9 @@ } } +slave port normal_reset; +slave port po_reset; + internal slave port spi[988]; internal slave port ppi_0[16]; diff --git a/src/arch/arm/fastmodel/GIC/gic.cc b/src/arch/arm/fastmodel/GIC/gic.cc index 493aa81..5f01cfb 100644 --- a/src/arch/arm/fastmodel/GIC/gic.cc +++ b/src/arch/arm/fastmodel/GIC/gic.cc @@ -72,10 +72,15 @@ SCGIC::SCGIC(const SCFastModelGICParams , sc_core::sc_module_name _name) -: scx_evs_GIC(_name), _params(params) +: scx_evs_GIC(_name), _params(params), + resetPort(params.name + ".reset", 0), + poResetPort(params.name + ".po_reset", 0) { signalInterrupt.bind(signal_interrupt); +resetPort.signal_out.bind(scx_evs_GIC::normal_reset); +poResetPort.signal_out.bind(scx_evs_GIC::po_reset); + for (int i = 0; i < wake_request.size(); i++) { wakeRequests.emplace_back( new SignalReceiver(csprintf("%s.wakerequest[%d]", name(), i))); @@ -298,6 +303,18 @@ set_parameter("gic.consolidators", params.consolidators); } +Port & +SCGIC::gem5_getPort(const std::string _name, int idx) +{ +if (if_name == "reset") { +return resetPort; +} else if (if_name == "po_reset") { +return poResetPort; +} else { +return scx_evs_GIC::gem5_getPort(if_name, idx); +} +} + void SCGIC::before_end_of_elaboration() { @@ -341,6 +358,8 @@ return *ptr; } else if (if_name == "wake_request") { return *wakeRequestPorts.at(idx); +} else if (if_name == "reset" || if_name == "po_reset") { +return scGIC->gem5_getPort(if_name, idx); } else { return BaseGic::getPort(if_name, idx); } diff --git a/src/arch/arm/fastmodel/GIC/gic.hh b/src/arch/arm/fastmodel/GIC/gic.hh index 0e502fc..070fe3b 100644 --- a/src/arch/arm/fastmodel/GIC/gic.hh +++ b/src/arch/arm/fastmodel/GIC/gic.hh @@ -37,6 +37,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/common/signal_sender.hh" #include "dev/arm/base_gic.hh" #include "dev/intpin.hh" #include "params/FastModelGIC.hh" @@ -91,9 +92,13 @@ SCGIC(const SCFastModelGICParams ) : SCGIC(p, p.name.c_str()) {} SCGIC(const SCFastModelGICParams , sc_core::sc_module_name _name); +Port _getPort(const std::string _name, int idx) override; + SignalInterruptInitiatorSocket signalInterrupt; std::vector> wakeRequests; +SignalSender resetPort; +SignalSender poResetPort; void before_end_of_elaboration() override; -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67575?usp=email To unsubscribe, or for help writing mail filters, visit
[gem5-dev] [M] Change in gem5/gem5[develop]: cpu: Add a generic model_reset port on the BaseCPU.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67574?usp=email ) Change subject: cpu: Add a generic model_reset port on the BaseCPU. .. cpu: Add a generic model_reset port on the BaseCPU. This port will stop execution on the CPU when raised. When lowered, it will allow execution to reset the state of the CPU and allow execution to resume. The state could theoretically be reset when the reset state starts, but then it wouldn't reflect the most up to date condition of the CPU when resuming. For instance, if a reset vector was set somehow, that wouldn't be updated if it was changed while reset was asserted. The tradeoff is that the state won't look like it will when execution resumes while reset is held (to GDB for instance), but that seems like a more obvious and less common sort of problem. This signal is managed by the BaseCPU itself, but is backed by a virtual method which can be overridden by other CPU types which may not work the same way or have the same components. For instance, a fast model CPU could toggle reset lines on the underlying model and let it handle resetting all the state. The fast models in particular already have a generic reset line with the same name, but they have it at the level of the fast model which may have multiple cores within it, each represented by a gem5 CPU. It isn't implemented here, but there could be some sort of cooperation between these signals where the reset at the core level is considered an "or" of the cluster level reset and the individual core level resets. At least in the A76 model, there are resets for each individual core within the cluster as well, which the generic reset toggles. Another option would be to get rid of the whole cluster reset pin, and make the user gang the resets for each of the cores together to whatever reset signal they're using. That's effectively what the cluster level reset is doing, but within the C++ of the model wrapper instead of in the python config. Change-Id: Ie6b4769298ea224ec5dc88360cbb52ee8fbbf69c --- M src/cpu/BaseCPU.py M src/cpu/base.cc M src/cpu/base.hh 3 files changed, 98 insertions(+), 0 deletions(-) diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 438d4f4..d77036a 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -53,6 +53,7 @@ from m5.objects.SubSystem import SubSystem from m5.objects.ClockDomain import * from m5.objects.Platform import Platform +from m5.objects.ResetPort import ResetResponsePort default_tracer = ExeTracer() @@ -153,6 +154,8 @@ "between CPU models)", ) +model_reset = ResetResponsePort("Generic reset for the CPU") + tracer = Param.InstTracer(default_tracer, "Instruction tracer") icache_port = RequestPort("Instruction Port") diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 98c53d4..c544280 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -47,6 +47,8 @@ #include #include +#include "arch/generic/decoder.hh" +#include "arch/generic/isa.hh" #include "arch/generic/tlb.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" @@ -130,6 +132,7 @@ _dataRequestorId(p.system->getRequestorId(this, "data")), _taskId(context_switch_task_id::Unknown), _pid(invldPid), _switchedOut(p.switched_out), _cacheLineSize(p.system->cacheLineSize()), + modelResetPort(p.name + ".model_reset"), interrupts(p.interrupts), numThreads(p.numThreads), system(p.system), previousCycle(0), previousState(CPU_STATE_SLEEP), functionTraceStream(nullptr), currentFunctionStart(0), @@ -178,6 +181,10 @@ fatal("Number of ISAs (%i) assigned to the CPU does not equal number " "of threads (%i).\n", params().isa.size(), numThreads); } + +modelResetPort.onChange([this](const bool _val) { +setReset(new_val); +}); } void @@ -413,6 +420,8 @@ return getDataPort(); else if (if_name == "icache_port") return getInstPort(); +else if (if_name == "model_reset") +return modelResetPort; else return ClockedObject::getPort(if_name, idx); } @@ -479,6 +488,12 @@ void BaseCPU::activateContext(ThreadID thread_num) { +if (modelResetPort.state()) { +DPRINTF(Thread, "CPU in reset, not activating context %d\n", +threadContexts[thread_num]->contextId()); +return; +} + DPRINTF(Thread, "activate contextId %d\n", threadContexts[thread_num]->contextId()); // Squash enter power gating event while cpu gets activated @@ -602,6 +617,29 @@ // we are switching to. getInstPort().takeOverFrom(>getInstPort()); getDataPort().takeOverFrom(>getDataPort()); + +// Switch over the reset line as well. +modelResetPort.takeOverFrom(>modelResetPort); +} + +void +BaseCPU::setReset(bool state) +{ +for (auto tc: threadContexts) { +if
[gem5-dev] [S] Change in gem5/gem5[develop]: arch-riscv: Implement the resetThread method on the ISA object.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67573?usp=email ) Change subject: arch-riscv: Implement the resetThread method on the ISA object. .. arch-riscv: Implement the resetThread method on the ISA object. This method invokes a Reset fault on the associated ThreadContext. Change-Id: Ie0725b06e0b506640b9038a986a9c56d9eed7011 --- M src/arch/riscv/isa.cc M src/arch/riscv/isa.hh 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 6e4c380..3809c61 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -34,6 +34,7 @@ #include #include +#include "arch/riscv/faults.hh" #include "arch/riscv/interrupts.hh" #include "arch/riscv/mmu.hh" #include "arch/riscv/pagetable.hh" @@ -723,6 +724,12 @@ tc->getCpuPtr()->wakeup(tc->threadId()); } +void +ISA::resetThread() +{ +Reset().invoke(tc); +} + } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index e332956..5a2a610 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -127,6 +127,8 @@ void globalClearExclusive() override; +void resetThread() override; + RiscvType rvType() const { return rv_type; } }; -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67573?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie0725b06e0b506640b9038a986a9c56d9eed7011 Gerrit-Change-Number: 67573 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: arch-riscv: Get rid of redundant reset fault invocation.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67571?usp=email ) Change subject: arch-riscv: Get rid of redundant reset fault invocation. .. arch-riscv: Get rid of redundant reset fault invocation. It was added in one change, another pending change which also added it was rebased on top of it, and the redundant addition was left in when the second change was submitted. Change-Id: I3faf53bca983d8568af45ec7174c2a064eadc0a6 --- M src/arch/riscv/bare_metal/fs_workload.cc 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/arch/riscv/bare_metal/fs_workload.cc b/src/arch/riscv/bare_metal/fs_workload.cc index 83f5411..4f7adb3 100644 --- a/src/arch/riscv/bare_metal/fs_workload.cc +++ b/src/arch/riscv/bare_metal/fs_workload.cc @@ -59,11 +59,6 @@ { Workload::initState(); -for (auto *tc: system->threads) { -RiscvISA::Reset().invoke(tc); -tc->activate(); -} - warn_if(!bootloader->buildImage().write(system->physProxy), "Could not load sections to memory."); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67571?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I3faf53bca983d8568af45ec7174c2a064eadc0a6 Gerrit-Change-Number: 67571 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: arch: Add a virtual method to the BaseISA to reset its ThreadContext.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67572?usp=email ) Change subject: arch: Add a virtual method to the BaseISA to reset its ThreadContext. .. arch: Add a virtual method to the BaseISA to reset its ThreadContext. This will be used as part of a generic CPU reset mechanism. Change-Id: I010f6bdaca0cbb6be1799ccdc345c4828515209d --- M src/arch/generic/isa.hh 1 file changed, 14 insertions(+), 0 deletions(-) diff --git a/src/arch/generic/isa.hh b/src/arch/generic/isa.hh index e4e7929..e9e4d95 100644 --- a/src/arch/generic/isa.hh +++ b/src/arch/generic/isa.hh @@ -43,6 +43,7 @@ #include #include "arch/generic/pcstate.hh" +#include "base/logging.hh" #include "cpu/reg_class.hh" #include "mem/packet.hh" #include "mem/request.hh" @@ -83,6 +84,8 @@ virtual bool inUserMode() const = 0; virtual void copyRegsFrom(ThreadContext *src) = 0; +virtual void resetThread() { panic("Thread reset not implemented."); } + const RegClasses () const { return _regClasses; } // Locked memory handling functions. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67572?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I010f6bdaca0cbb6be1799ccdc345c4828515209d Gerrit-Change-Number: 67572 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: sim: Add some helpers for setting up Signal*Ports in python.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67511?usp=email ) Change subject: sim: Add some helpers for setting up Signal*Ports in python. .. sim: Add some helpers for setting up Signal*Ports in python. The only difference between these types in python are the compatibility strings which restrict what can connect to what. For ports which are generally useful like interrupts or resets, they should have port types with special names and even more restrictive compatibility. For other ports which are one off signals between components, that would be overkill, and these helpers will let you make a signal port which is only restricted to ports which carry the same type of data. The helpers are intended to look similar to their C++ counterpart templates, and are functions which take a type signature as a string as their argument, and return a class which is specialized to use that type signature. The class itself can be stored, or used immediately. foo = SignalSourcePort('bool')('A port for the foo signal') Change-Id: If6359b2c69f34ff775cd9aa01272ac487db08bf7 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67511 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Yu-hsin Wang --- M src/sim/SConscript A src/sim/SignalPort.py 2 files changed, 106 insertions(+), 0 deletions(-) Approvals: kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved diff --git a/src/sim/SConscript b/src/sim/SConscript index 75b595b..e26676c 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -42,6 +42,7 @@ SimObject('RedirectPath.py', sim_objects=['RedirectPath']) SimObject('PowerState.py', sim_objects=['PowerState'], enums=['PwrState']) SimObject('PowerDomain.py', sim_objects=['PowerDomain']) +SimObject('SignalPort.py', sim_objects=[]) Source('async.cc') Source('backtrace_%s.cc' % env['BACKTRACE_IMPL'], add_tags='gem5 trace') diff --git a/src/sim/SignalPort.py b/src/sim/SignalPort.py new file mode 100644 index 000..fc529a8 --- /dev/null +++ b/src/sim/SignalPort.py @@ -0,0 +1,77 @@ +# Copyright 2023 Google, Inc. +# +# 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. + +from m5.params import Port, VectorPort + +SIGNAL_SOURCE_ROLE_TEMPLATE = "Signal source <%s>" +SIGNAL_SINK_ROLE_TEMPLATE = "Signal sink <%s>" + + +def SignalSourcePort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class SignalSourcePort(Port): +def __init__(self, desc): +super().__init__(source_role, desc, is_source=True) + +return SignalSourcePort + + +def VectorSignalSourcePort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class VectorSignalSourcePort(VectorPort): +def __init__(self, desc): +super().__init__(source_role, desc, is_source=True) + +return VectorSignalSourcePort + + +def SignalSinkPort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class SignalSinkPort(Port): +def __init__(self, desc): +super().__init__(sink_role, desc) + +return SignalSinkPort +
[gem5-dev] [M] Change in gem5/gem5[develop]: sim: Add some helpers for setting up Signal*Ports in python.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67511?usp=email ) Change subject: sim: Add some helpers for setting up Signal*Ports in python. .. sim: Add some helpers for setting up Signal*Ports in python. The only difference between these types in python are the compatibility strings which restrict what can connect to what. For ports which are generally useful like interrupts or resets, they should have port types with special names and even more restrictive compatibility. For other ports which are one off signals between components, that would be overkill, and these helpers will let you make a signal port which is only restricted to ports which carry the same type of data. The helpers are intended to look similar to their C++ counterpart templates, and are functions which take a type signature as a string as their argument, and return a class which is specialized to use that type signature. The class itself can be stored, or used immediately. foo = SignalSourcePort('bool')('A port for the foo signal') Change-Id: If6359b2c69f34ff775cd9aa01272ac487db08bf7 --- M src/sim/SConscript A src/sim/SignalPort.py 2 files changed, 98 insertions(+), 0 deletions(-) diff --git a/src/sim/SConscript b/src/sim/SConscript index 75b595b..e26676c 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -42,6 +42,7 @@ SimObject('RedirectPath.py', sim_objects=['RedirectPath']) SimObject('PowerState.py', sim_objects=['PowerState'], enums=['PwrState']) SimObject('PowerDomain.py', sim_objects=['PowerDomain']) +SimObject('SignalPort.py', sim_objects=[]) Source('async.cc') Source('backtrace_%s.cc' % env['BACKTRACE_IMPL'], add_tags='gem5 trace') diff --git a/src/sim/SignalPort.py b/src/sim/SignalPort.py new file mode 100644 index 000..cf84adf --- /dev/null +++ b/src/sim/SignalPort.py @@ -0,0 +1,73 @@ +# Copyright 2023 Google, Inc. +# +# 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. + +from m5.params import Port, VectorPort + +SIGNAL_SOURCE_ROLE_TEMPLATE = "Signal source <%s>" +SIGNAL_SINK_ROLE_TEMPLATE = "Signal sink <%s>" + +def SignalSourcePort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class SignalSourcePort(Port): +def __init__(self, desc): +super().__init__(source_role, desc, is_source=True) + +return SignalSourcePort + +def VectorSignalSourcePort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class VectorSignalSourcePort(VectorPort): +def __init__(self, desc): +super().__init__(source_role, desc, is_source=True) + +return VectorSignalSourcePort + +def SignalSinkPort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class SignalSinkPort(Port): +def __init__(self, desc): +super().__init__(sink_role, desc) + +return SignalSinkPort + +def VectorSignalSinkPort(type_signature): +source_role = SIGNAL_SOURCE_ROLE_TEMPLATE % type_signature +sink_role = SIGNAL_SINK_ROLE_TEMPLATE % type_signature +Port.compat(source_role, sink_role) + +class VectorSignalSinkPort(VectorPort): +
[gem5-dev] [S] Change in gem5/gem5[develop]: fastmodel: Export the "reset_in" reset signal from the PL330.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67351?usp=email ) Change subject: fastmodel: Export the "reset_in" reset signal from the PL330. .. fastmodel: Export the "reset_in" reset signal from the PL330. This is essentially the same as how the reset signals were exported from the CortexR52 which I used as an example, except here there is only one reset. I passed through with the same name rather than calling it "model_reset" as in the CortexR52 since the pass through is trivial, and renaming the signal with no additional functionality seemed like it would just create confusion. In the CortexR52 case it makes more sense since there are multiple reset lines that need to be toggled to actually cause a reset, and a level of abstraction is actually helpful. Change-Id: I6b61fed6eb1566d131d4b0367fe4ae65031b25f8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67351 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py M src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa M src/arch/arm/fastmodel/PL330_DMAC/pl330.cc M src/arch/arm/fastmodel/PL330_DMAC/pl330.hh 4 files changed, 40 insertions(+), 1 deletion(-) Approvals: Gabe Black: Looks good to me, approved kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved diff --git a/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py index ad43fed..21ead52 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py +++ b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py @@ -26,6 +26,7 @@ from m5.params import * from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket from m5.objects.IntPin import IntSourcePin +from m5.objects.ResetPort import ResetResponsePort from m5.objects.SystemC import SystemC_ScModule @@ -197,6 +198,8 @@ pio_s = AmbaTargetSocket(64, "Register accesses (secure)") pio_ns = AmbaTargetSocket(64, "Register accesses (non-secure)") +reset_in = ResetResponsePort("System reset") + # irq_abort_master_port # irq_master_port # pvbus_m diff --git a/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa index 3c31c90..d57dfda 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa +++ b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa @@ -64,6 +64,9 @@ // Interrupts. pl330.irq_master_port => self.irq; pl330.irq_abort_master_port => self.irq_abort; + +// Reset signals. +self.reset_in => pl330.reset_in; } properties @@ -85,4 +88,6 @@ master port irq[32]; master port irq_abort; + +slave port reset_in; } diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc index e582404..13162bd 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc @@ -45,7 +45,8 @@ dma(amba_m, params.name + ".dma", -1), pioS(amba_s, params.name + ".pio_s", -1), pioNs(amba_s_ns, params.name + ".pio_ns", -1), -irqAbortReceiver("irq_abort_receiver") +irqAbortReceiver("irq_abort_receiver"), +resetIn("reset_in", 0) { set_parameter("pl330.fifo_size", params.fifo_size); set_parameter("pl330.max_transfer", params.max_transfer); @@ -211,6 +212,9 @@ // And install it. irqAbortReceiver.onChange(abort_change); + +// Plumb the reset signal. +resetIn.signal_out.bind(this->reset_in); } void @@ -250,6 +254,8 @@ } if (port != -1 && port < irqPort.size()) return *irqPort[port].at(idx); +} else if (if_name == "reset_in") { +return resetIn; } return scx_evs_PL330::gem5_getPort(if_name, idx); diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh index 3af56f2..389f704 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh @@ -39,6 +39,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/common/signal_sender.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" #include "dev/intpin.hh" #include "params/FastModelPL330.hh" @@ -73,6 +74,8 @@ void allocateIrq(int idx, int count); +SignalSender resetIn; + public: PL330(const FastModelPL330Params , sc_core::sc_module_name _name); PL330(const FastModelPL330Params ) : -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67351?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I6b61fed6eb1566d131d4b0367fe4ae65031b25f8
[gem5-dev] [S] Change in gem5/gem5[develop]: fastmodel: Export the "reset_in" reset signal from the PL330.
Attention is currently required from: Yu-hsin Wang. Hello kokoro, Yu-hsin Wang, I'd like you to do a code review. Please visit https://gem5-review.googlesource.com/c/public/gem5/+/67351?usp=email to review the following change. Change subject: fastmodel: Export the "reset_in" reset signal from the PL330. .. fastmodel: Export the "reset_in" reset signal from the PL330. This is essentially the same as how the reset signals were exported from the CortexR52 which I used as an example, except here there is only one reset. I passed through with the same name rather than calling it "model_reset" as in the CortexR52 since the pass through is trivial, and renaming the signal with no additional functionality seemed like it would just create confusion. In the CortexR52 case it makes more sense since there are multiple reset lines that need to be toggled to actually cause a reset, and a level of abstraction is actually helpful. Change-Id: I6b61fed6eb1566d131d4b0367fe4ae65031b25f8 Reviewed-on: https://soc-sim-external-review.googlesource.com/c/gem5/gem5/+/9473 Reviewed-by: Yu-hsin Wang Presubmit-Ready: Gabe Black Tested-by: kokoro --- M src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py M src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa M src/arch/arm/fastmodel/PL330_DMAC/pl330.cc M src/arch/arm/fastmodel/PL330_DMAC/pl330.hh 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py index ad43fed..21ead52 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py +++ b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py @@ -26,6 +26,7 @@ from m5.params import * from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket from m5.objects.IntPin import IntSourcePin +from m5.objects.ResetPort import ResetResponsePort from m5.objects.SystemC import SystemC_ScModule @@ -197,6 +198,8 @@ pio_s = AmbaTargetSocket(64, "Register accesses (secure)") pio_ns = AmbaTargetSocket(64, "Register accesses (non-secure)") +reset_in = ResetResponsePort("System reset") + # irq_abort_master_port # irq_master_port # pvbus_m diff --git a/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa index 3c31c90..d57dfda 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa +++ b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa @@ -64,6 +64,9 @@ // Interrupts. pl330.irq_master_port => self.irq; pl330.irq_abort_master_port => self.irq_abort; + +// Reset signals. +self.reset_in => pl330.reset_in; } properties @@ -85,4 +88,6 @@ master port irq[32]; master port irq_abort; + +slave port reset_in; } diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc index e582404..13162bd 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc @@ -45,7 +45,8 @@ dma(amba_m, params.name + ".dma", -1), pioS(amba_s, params.name + ".pio_s", -1), pioNs(amba_s_ns, params.name + ".pio_ns", -1), -irqAbortReceiver("irq_abort_receiver") +irqAbortReceiver("irq_abort_receiver"), +resetIn("reset_in", 0) { set_parameter("pl330.fifo_size", params.fifo_size); set_parameter("pl330.max_transfer", params.max_transfer); @@ -211,6 +212,9 @@ // And install it. irqAbortReceiver.onChange(abort_change); + +// Plumb the reset signal. +resetIn.signal_out.bind(this->reset_in); } void @@ -250,6 +254,8 @@ } if (port != -1 && port < irqPort.size()) return *irqPort[port].at(idx); +} else if (if_name == "reset_in") { +return resetIn; } return scx_evs_PL330::gem5_getPort(if_name, idx); diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh index 3af56f2..389f704 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh @@ -39,6 +39,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/common/signal_sender.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" #include "dev/intpin.hh" #include "params/FastModelPL330.hh" @@ -73,6 +74,8 @@ void allocateIrq(int idx, int count); +SignalSender resetIn; + public: PL330(const FastModelPL330Params , sc_core::sc_module_name _name); PL330(const FastModelPL330Params ) : -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67351?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I6b61fed6eb1566d131d4b0367fe4ae65031b25f8
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add a "resetter" callback to the typed register class.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67203?usp=email ) Change subject: dev: Add a "resetter" callback to the typed register class. .. dev: Add a "resetter" callback to the typed register class. When using the typed register template, most functionality of the class can be controlled using callbacks. For instance, callbacks can be installed to handle reads or writes to a register without having to subclass the template and override those methods using inheritance. The recently added reset() method did not follow this pattern though, which has two problems. First, it's inconsistent with how the class is normally used. Second, once you've defined a subclass, the reader, writer, etc, callbacks still expect the type of the original class. That means these have to either awkwardly use a type different from the actual real type of the register, or use awkward, inefficient, and/or dangerous casting to get back to the true type. To address these problems, this change adds a resetter(...) method which works like the reader(...) or writer(...) methods to optionally install a callback to implement any special reset behavior. Change-Id: Ia74b36616fd459c1dbed9304568903a76a4b55de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67203 Tested-by: kokoro Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black --- M src/dev/reg_bank.hh M src/dev/reg_bank.test.cc 2 files changed, 119 insertions(+), 1 deletion(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 32d9058..3d8dc57 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -270,6 +270,12 @@ * is an alternative form of update which also takes a custom bitmask, if you * need to update bits other than the normally writeable ones. * + * Similarly, you can set a "resetter" handler which is responsible for + * resetting the register. It takes a reference to the current Register, and + * no other parameters. The "initialValue" accessor can retrieve the value the + * register was constructed with. The register is simply set to this value + * in the default resetter implementation. + * * = Read only bits = * * Often registers have bits which are fixed and not affected by writes. To @@ -554,6 +560,7 @@ using WriteFunc = std::function)>; using PartialWriteFunc = std::function< void (This , const Data , int first, int last)>; +using ResetFunc = std::function; private: Data _data = {}; @@ -564,6 +571,7 @@ WriteFunc _writer = defaultWriter; PartialWriteFunc _partialWriter = defaultPartialWriter; PartialReadFunc _partialReader = defaultPartialReader; +ResetFunc _resetter = defaultResetter; protected: static Data defaultReader(This ) { return reg.get(); } @@ -587,6 +595,12 @@ mask(first, last))); } +static void +defaultResetter(This ) +{ +reg.get() = reg.initialValue(); +} + constexpr Data htoreg(Data data) { @@ -721,6 +735,30 @@ return partialWriter(wrapper); } +// Set the callables which handle resetting. +// +// The default resetter restores the initial value used in the +// constructor. +constexpr This & +resetter(const ResetFunc _resetter) +{ +_resetter = new_resetter; +return *this; +} +template +constexpr This & +resetter(Parent *parent, void (Parent::*nr)(Args... args)) +{ +auto wrapper = [parent, nr](Args&&... args) { +return (parent->*nr)(std::forward(args)...); +}; +return resetter(wrapper); +} + +// An accessor which returns the initial value as set in the +// constructor. This is intended to be used in a resetter function. +const Data () const { return _resetData; } + /* * Interface for accessing the register's state, for use by the @@ -817,7 +855,7 @@ } // Reset our data to its initial value. -void reset() override { get() = _resetData; } +void reset() override { _resetter(*this); } }; private: diff --git a/src/dev/reg_bank.test.cc b/src/dev/reg_bank.test.cc index b4bc969..4439526 100644 --- a/src/dev/reg_bank.test.cc +++ b/src/dev/reg_bank.test.cc @@ -868,6 +868,56 @@ EXPECT_EQ(write_value, 0x0344); } +// Use the default resetter for a register. +TEST_F(TypedRegisterTest, DefaultResetter) +{ +BackingType initial_value = reg.get(); + +reg.get() = initial_value + 1; +EXPECT_EQ(reg.get(), initial_value + 1); + +
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add a "resetter" callback to the typed register class.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67203?usp=email ) Change subject: dev: Add a "resetter" callback to the typed register class. .. dev: Add a "resetter" callback to the typed register class. When using the typed register template, most functionality of the class can be controlled using callbacks. For instance, callbacks can be installed to handle reads or writes to a register without having to subclass the template and override those methods using inheritance. The recently added reset() method did not follow this pattern though, which has two problems. First, it's inconsistent with how the class is normally used. Second, once you've defined a subclass, the reader, writer, etc, callbacks still expect the type of the original class. That means these have to either awkwardly use a type different from the actual real type of the register, or use awkward, inefficient, and/or dangerous casting to get back to the true type. To address these problems, this change adds a resetter(...) method which works like the reader(...) or writer(...) methods to optionally install a callback to implement any special reset behavior. Change-Id: Ia74b36616fd459c1dbed9304568903a76a4b55de --- M src/dev/reg_bank.hh M src/dev/reg_bank.test.cc 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 32d9058..dd68554 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -270,6 +270,12 @@ * is an alternative form of update which also takes a custom bitmask, if you * need to update bits other than the normally writeable ones. * + * Similarly, you can set a "resetter" handler which is responsible for + * resetting the register. It takes a reference to the current Register, and + * no other parameters. The "initialValue" accessor can retrieve the value the + * register was constructed with. The register is simply set to this value + * in the default resetter implementation. + * * = Read only bits = * * Often registers have bits which are fixed and not affected by writes. To @@ -547,13 +553,14 @@ protected: using This = Register; - public: + public:& using ReadFunc = std::function; using PartialReadFunc = std::function< Data (This , int first, int last)>; using WriteFunc = std::function)>; using PartialWriteFunc = std::function< void (This , const Data , int first, int last)>; +using ResetFunc = std::function; private: Data _data = {}; @@ -564,6 +571,7 @@ WriteFunc _writer = defaultWriter; PartialWriteFunc _partialWriter = defaultPartialWriter; PartialReadFunc _partialReader = defaultPartialReader; +ResetFunc _resetter = defaultResetter; protected: static Data defaultReader(This ) { return reg.get(); } @@ -587,6 +595,12 @@ mask(first, last))); } +static void +defaultResetter(This ) +{ +reg.get() = reg.initialValue(); +} + constexpr Data htoreg(Data data) { @@ -721,6 +735,30 @@ return partialWriter(wrapper); } +// Set the callables which handle resetting. +// +// The default resetter restores the initial value used in the +// constructor. +constexpr This & +resetter(const ResetFunc _resetter) +{ +_resetter = new_resetter; +return *this; +} +template +constexpr This & +resetter(Parent *parent, void (Parent::*nr)(Args... args)) +{ +auto wrapper = [parent, nr](Args&&... args) { +return (parent->*nr)(std::forward(args)...); +}; +return resetter(wrapper); +} + +// An accessor which returns the initial value as set in the +// constructor. This is intended to be used in a resetter function. +const Data () const { return _resetData; } + /* * Interface for accessing the register's state, for use by the @@ -817,7 +855,7 @@ } // Reset our data to its initial value. -void reset() override { get() = _resetData; } +void reset() override { _resetter(*this); } }; private: diff --git a/src/dev/reg_bank.test.cc b/src/dev/reg_bank.test.cc index b4bc969..4439526 100644 --- a/src/dev/reg_bank.test.cc +++ b/src/dev/reg_bank.test.cc @@ -868,6 +868,56 @@ EXPECT_EQ(write_value, 0x0344); } +// Use the default resetter for a register. +TEST_F(TypedRegisterTest, DefaultResetter) +{ +BackingType initial_value = reg.get(); + +reg.get() = initial_value + 1; +EXPECT_EQ(reg.get(), initial_value + 1); + +reg.reset(); + +EXPECT_EQ(reg.get(),
[gem5-dev] [L] Change in gem5/gem5[develop]: fastmodel,dev: Replace the reset port with a Signal*Port.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66675?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: fastmodel,dev: Replace the reset port with a Signal*Port. .. fastmodel,dev: Replace the reset port with a Signal*Port. The ResetRequestPort and ResetResponsePort have a few problems: 1. A reset signal should happen during the time a reset is asserted, or in other words the device should stay in reset and not doing anything while reset is asserted. It should not immediately restart execution while the reset is still held. 2. These names are misleading, since there is no response. These names are inherited from other port types where there is an actual response. There is a new generic SignalSourcePort and SignalSinkPort set of port classes which are templated on the type of signal they propogate, and which can be used in place of reset ports in c++. These ports can still have a specialized role which will ensure that only reset ports are connected to each other for a form of type checking, although the underlying c++ instances are more interoperable than that. Change-Id: Id98bef901ab61ac5b200dbbe49439bb2d2e6c57f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66675 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/CortexA76/evs.cc M src/arch/arm/fastmodel/CortexA76/evs.hh M src/arch/arm/fastmodel/CortexR52/evs.cc M src/arch/arm/fastmodel/CortexR52/evs.hh M src/arch/arm/fastmodel/reset_controller/example.cc M src/arch/arm/fastmodel/reset_controller/example.hh M src/dev/SConscript D src/dev/reset_port.cc D src/dev/reset_port.hh 9 files changed, 63 insertions(+), 188 deletions(-) Approvals: Gabe Black: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/CortexA76/evs.cc b/src/arch/arm/fastmodel/CortexA76/evs.cc index 1c06935..c9ce3cc 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.cc +++ b/src/arch/arm/fastmodel/CortexA76/evs.cc @@ -71,32 +71,25 @@ } template -void -ScxEvsCortexA76::requestReset() -{ -// Reset all cores. -for (auto _reset : this->poweron_reset) { -poweron_reset->signal_out.set_state(0, true); -poweron_reset->signal_out.set_state(0, false); -} -// Reset DSU. -this->top_reset.signal_out.set_state(0, true); -this->top_reset.signal_out.set_state(0, false); -// Reset debug APB. -this->dbg_reset.signal_out.set_state(0, true); -this->dbg_reset.signal_out.set_state(0, false); -} - -template ScxEvsCortexA76::ScxEvsCortexA76( const sc_core::sc_module_name _name, const Params ) : Base(mod_name), amba(Base::amba, p.name + ".amba", -1), top_reset(p.name + ".top_reset", 0), dbg_reset(p.name + ".dbg_reset", 0), -model_reset(p.name + ".model_reset", -1, this), +model_reset(p.name + ".model_reset"), params(p) { +model_reset.onChange([this](const bool _val) { +// Set reset for all cores. +for (auto _reset : poweron_reset) +poweron_reset->signal_out.set_state(0, new_val); +// Set reset for DSU. +top_reset.signal_out.set_state(0, new_val); +// Set reset for debug APB. +dbg_reset.signal_out.set_state(0, new_val); +}); + for (int i = 0; i < CoreCount; i++) { redist.emplace_back(new TlmGicTarget(this->redistributor[i], csprintf("%s.redistributor[%d]", name(), i), i)); diff --git a/src/arch/arm/fastmodel/CortexA76/evs.hh b/src/arch/arm/fastmodel/CortexA76/evs.hh index 081e80f..7c4ef60 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.hh +++ b/src/arch/arm/fastmodel/CortexA76/evs.hh @@ -35,7 +35,6 @@ #include "arch/arm/fastmodel/common/signal_sender.hh" #include "arch/arm/fastmodel/iris/cpu.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" -#include "dev/reset_port.hh" #include "mem/port_proxy.hh" #include "params/FastModelScxEvsCortexA76x1.hh" #include "params/FastModelScxEvsCortexA76x2.hh" @@ -45,6 +44,7 @@ #include "scx_evs_CortexA76x2.h" #include "scx_evs_CortexA76x3.h" #include "scx_evs_CortexA76x4.h" +#include "sim/signal.hh" #include "systemc/ext/core/sc_event.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/tlm_port_wrapper.hh" @@ -99,7 +99,7 @@ SignalSender dbg_reset; -ResetResponsePort model_reset; +SignalSinkPort model_reset; CortexA76Cluster *gem5CpuCluster; @@ -129,8 +129,6 @@ void setCluster(SimObject *cluster) override; void setResetAddr(int core, Addr addr, bool secure) override; - -void requestReset(); }; struct ScxEvsCortexA76x1Types diff --git a/src/arch/arm/fastmodel/CortexR52/evs.cc
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Introduce a reset() method on RegisterBank and Register classes.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: dev: Introduce a reset() method on RegisterBank and Register classes. .. dev: Introduce a reset() method on RegisterBank and Register classes. This will make it much easier to implement reset behaviors on devices which have RegisterBanks in them. Change-Id: I73fe9874fcb69feed33611a320dcca85c0de2d0e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66671 Tested-by: kokoro Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Reviewed-by: Jui-min Lee --- M src/dev/reg_bank.hh M src/dev/serial/uart8250.hh 2 files changed, 63 insertions(+), 2 deletions(-) Approvals: Gabe Black: Looks good to me, approved Jui-min Lee: Looks good to me, but someone else must approve kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 31c0ce5..66d668b 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -117,6 +117,11 @@ * RegisterBankLE and RegisterBankBE aliases to make it a little easier to * refer to one or the other version. * + * A RegisterBank also has a reset() method which will (by default) call the + * reset() method on each register within it. This method is virtual, and so + * can be overridden if something additional or different needs to be done to + * reset the hardware model. + * * * == Register interface == * @@ -145,6 +150,12 @@ * it still has to implement these methods, but they don't have to actually do * anything. * + * Each register also has a "reset" method, which will reset the register as + * if its containing device is being reset. By default, this will just restore + * the initial value of the register, but can be overridden to implement + * additional behavior like resetting other aspects of the device which are + * controlled by the value of the register. + * * * == Basic Register types == * @@ -360,6 +371,9 @@ // Methods for implementing serialization for checkpoints. virtual void serialize(std::ostream ) const = 0; virtual bool unserialize(const std::string ) = 0; + +// Reset the register. +virtual void reset() = 0; }; // Filler registers which return a fixed pattern. @@ -388,6 +402,9 @@ void serialize(std::ostream ) const override {} bool unserialize(const std::string ) override { return true; } + +// Resetting a read only register doesn't need to do anything. +void reset() override {} }; // Register which reads as all zeroes. @@ -453,6 +470,10 @@ void serialize(std::ostream ) const override {} bool unserialize(const std::string ) override { return true; } +// Assume since the buffer is managed externally, it will be reset +// externally. +void reset() override {} + protected: /** * This method exists so that derived classes that need to initialize @@ -516,6 +537,8 @@ return true; } + +void reset() override { buffer = std::array{}; } }; template @@ -534,6 +557,7 @@ private: Data _data = {}; +Data _resetData = {}; Data _writeMask = mask(sizeof(Data) * 8); ReadFunc _reader = defaultReader; @@ -602,11 +626,13 @@ // Constructor and move constructor with an initial data value. constexpr Register(const std::string _name, const Data _data) : -RegisterBase(new_name, sizeof(Data)), _data(new_data) +RegisterBase(new_name, sizeof(Data)), _data(new_data), +_resetData(new_data) {} constexpr Register(const std::string _name, const Data &_data) : -RegisterBase(new_name, sizeof(Data)), _data(new_data) +RegisterBase(new_name, sizeof(Data)), _data(new_data), +_resetData(new_data) {} // Set which bits of the register are writeable. @@ -789,6 +815,9 @@ { return ParseParam::parse(s, get()); } + +// Reset our data to its initial value. +void reset() override { get() = _resetData; } }; private: @@ -984,6 +1013,14 @@ } } } + +// By default, reset all the registers in the bank. +virtual void +reset() +{ +for (auto &[offset, reg]: _offsetMap) +reg.get().reset(); +} }; using RegisterBankLE = RegisterBank; diff --git a/src/dev/serial/uart8250.hh b/src/dev/serial/uart8250.hh index c55d889..5774f78 100644 --- a/src/dev/serial/uart8250.hh +++ b/src/dev/serial/uart8250.hh @@ -113,6 +113,13 @@ void
[gem5-dev] [M] Change in gem5/gem5[develop]: fastmodel,dev: Rework the Int*Pin classes with Signal*Port.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66673?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: fastmodel,dev: Rework the Int*Pin classes with Signal*Port. .. fastmodel,dev: Rework the Int*Pin classes with Signal*Port. These are largely compatibility wrappers around the Signal*Port classes. The python versions of these types enforce more specific compatibility, but on the c++ side the Signal*Port classes can be used directly instead. Change-Id: I1325074d0ed1c8fc6dfece5ac1ee33872cc4f5e3 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66673 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/common/signal_sender.hh M src/dev/SConscript D src/dev/intpin.cc M src/dev/intpin.hh 4 files changed, 66 insertions(+), 139 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/common/signal_sender.hh b/src/arch/arm/fastmodel/common/signal_sender.hh index f4772cf..812a1b9 100644 --- a/src/arch/arm/fastmodel/common/signal_sender.hh +++ b/src/arch/arm/fastmodel/common/signal_sender.hh @@ -50,11 +50,11 @@ SignalSender(const std::string &_name, PortID _id) : IntSinkPinBase(_name, _id, 0), signal_out((_name + ".sig").c_str()) -{} - - private: -void raiseOnDevice() override { signal_out.set_state(id, true); } -void lowerOnDevice() override { signal_out.set_state(id, false); } +{ +onChange([this](const bool _val) { +signal_out.set_state(id, new_val); +}); +} }; } // namespace fastmodel diff --git a/src/dev/SConscript b/src/dev/SConscript index 6a6ce40..d991ed5 100644 --- a/src/dev/SConscript +++ b/src/dev/SConscript @@ -36,7 +36,6 @@ Source('dma_virt_device.cc') SimObject('IntPin.py', sim_objects=[]) -Source('intpin.cc') SimObject('ResetPort.py', sim_objects=[]) Source('reset_port.cc') diff --git a/src/dev/intpin.cc b/src/dev/intpin.cc deleted file mode 100644 index c378337..000 --- a/src/dev/intpin.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2019 Google, Inc. - * - * 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 "dev/intpin.hh" - -#include "base/logging.hh" - -namespace gem5 -{ - -void -IntSinkPinBase::bind(Port ) -{ -source = dynamic_cast(); -fatal_if(!source, "Attempt to bind interrupt sink pin %s to " -"incompatible port %s.", name(), peer.name()); -Port::bind(peer); -} - -void -IntSinkPinBase::unbind() -{ -source = nullptr; -Port::unbind(); -} - -void -IntSourcePinBase::bind(Port ) -{ -sink = dynamic_cast(); -fatal_if(!sink, "Attempt to bind interrupt source pin %s to " -"incompatible port %s.", name(), peer.name()); -Port::bind(peer); -} - -void -IntSourcePinBase::unbind() -{ -sink = nullptr; -Port::unbind(); -} - -} // namespace gem5 diff --git a/src/dev/intpin.hh b/src/dev/intpin.hh index 2704887..578dd90 100644 --- a/src/dev/intpin.hh +++ b/src/dev/intpin.hh @@ -28,94 +28,71 @@ #ifndef __DEV_INTPIN_HH__ #define __DEV_INTPIN_HH__ -#include "sim/port.hh" +#include + +#include "sim/signal.hh" namespace gem5 { -class IntSourcePinBase; - -class IntSinkPinBase : public Port +class IntSinkPinBase :
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Implement a "Signal" port which has a templated State type.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66672?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: dev: Implement a "Signal" port which has a templated State type. .. dev: Implement a "Signal" port which has a templated State type. This port type transmits a value of the templated State type. When the value changes, the sink port will call the registered callback with the new value. Change-Id: I72eaf74658a2c63bece95e48c1a72694874eaad8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66672 Maintainer: Gabe Black Reviewed-by: Jui-min Lee Tested-by: kokoro Reviewed-by: Yu-hsin Wang --- A src/sim/signal.hh 1 file changed, 149 insertions(+), 0 deletions(-) Approvals: Gabe Black: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved Jui-min Lee: Looks good to me, but someone else must approve kokoro: Regressions pass diff --git a/src/sim/signal.hh b/src/sim/signal.hh new file mode 100644 index 000..3cb3f62 --- /dev/null +++ b/src/sim/signal.hh @@ -0,0 +1,131 @@ +/* + * Copyright 2022 Google, Inc. + * + * 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 __SIM_SIGNAL_HH__ +#define __SIM_SIGNAL_HH__ + +#include + +#include "base/logging.hh" +#include "sim/port.hh" + +namespace gem5 +{ + +template +class SignalSourcePort; + +template +class SignalSinkPort : public Port +{ + public: +using OnChangeFunc = std::function; + + private: +friend SignalSourcePort; + +SignalSourcePort *_source = nullptr; + +State _state = {}; +OnChangeFunc _onChange; + + protected: +void +set(const State _state) +{ +if (new_state == _state) +return; + +_state = new_state; +if (_onChange) +_onChange(_state); +} + + public: +SignalSinkPort(const std::string &_name, PortID _id=InvalidPortID) : +Port(_name, _id) +{} + +const State () const { return _state; } +void onChange(OnChangeFunc func) { _onChange = std::move(func); } + +void +bind(Port ) override +{ +_source = dynamic_cast *>(); +fatal_if(!_source, "Attempt to bind signal pin %s to " +"incompatible pin %s", name(), peer.name()); +Port::bind(peer); +} +void +unbind() override +{ +_source = nullptr; +Port::unbind(); +} +}; + +template +class SignalSourcePort : public Port +{ + private: +SignalSinkPort *sink = nullptr; +State _state = {}; + + public: +SignalSourcePort(const std::string &_name, PortID _id=InvalidPortID) : +Port(_name, _id) +{} + +void +set(const State _state) +{ +_state = new_state; +sink->set(new_state); +} + +const State () const { return _state; } + +void +bind(Port ) override +{ +sink = dynamic_cast *>(); +fatal_if(!sink, "Attempt to bind signal pin %s to " +"incompatible pin %s", name(), peer.name()); +Port::bind(peer); +} +void +unbind() override +{ +sink = nullptr; +Port::unbind(); +} +}; + +} // namespace gem5 + +#endif //__SIM_SIGNAL_HH__ -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66672?usp=email To unsubscribe, or for help writing mail filters, visit
[gem5-dev] [S] Change in gem5/gem5[develop]: fastmodel: Change the Signal proxies to use Signal*Port.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66674?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: fastmodel: Change the Signal proxies to use Signal*Port. .. fastmodel: Change the Signal proxies to use Signal*Port. Change-Id: Ia1aa32d5ea50ff4cc47d1d72a9c25dabd6c30de9 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66674 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Yu-hsin Wang --- M src/arch/arm/fastmodel/common/signal_receiver.hh M src/arch/arm/fastmodel/common/signal_sender.hh 2 files changed, 19 insertions(+), 7 deletions(-) Approvals: Gabe Black: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/common/signal_receiver.hh b/src/arch/arm/fastmodel/common/signal_receiver.hh index 9907877..9ec760e 100644 --- a/src/arch/arm/fastmodel/common/signal_receiver.hh +++ b/src/arch/arm/fastmodel/common/signal_receiver.hh @@ -87,7 +87,7 @@ class SignalReceiverInt : public SignalReceiver { public: -using IntPin = IntSourcePin; +using IntPin = SignalSourcePort; explicit SignalReceiverInt(const std::string ) : SignalReceiver(name) @@ -95,7 +95,7 @@ onChange([this](bool status) { for (auto : signalOut) { if (signal && signal->isConnected()) -status ? signal->raise() : signal->lower(); +signal->set(status); } }); } @@ -108,7 +108,7 @@ } if (!signalOut[idx]) { signalOut[idx] = std::make_unique( -csprintf("%s.signalOut[%d]", get_name(), idx), idx, this); +csprintf("%s.signalOut[%d]", get_name(), idx), idx); } return *signalOut[idx]; } diff --git a/src/arch/arm/fastmodel/common/signal_sender.hh b/src/arch/arm/fastmodel/common/signal_sender.hh index 812a1b9..c596ed1 100644 --- a/src/arch/arm/fastmodel/common/signal_sender.hh +++ b/src/arch/arm/fastmodel/common/signal_sender.hh @@ -33,7 +33,7 @@ #include #pragma GCC diagnostic pop -#include "dev/intpin.hh" +#include "sim/signal.hh" namespace gem5 { @@ -42,14 +42,13 @@ namespace fastmodel { -class SignalSender : public IntSinkPinBase +class SignalSender : public SignalSinkPort { public: amba_pv::signal_master_port signal_out; SignalSender(const std::string &_name, PortID _id) : -IntSinkPinBase(_name, _id, 0), -signal_out((_name + ".sig").c_str()) +SignalSinkPort(_name, _id), signal_out((_name + ".sig").c_str()) { onChange([this](const bool _val) { signal_out.set_state(id, new_val); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66674?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia1aa32d5ea50ff4cc47d1d72a9c25dabd6c30de9 Gerrit-Change-Number: 66674 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: fastmodel: Change the Signal proxies to use Signal*Port.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66674?usp=email ) Change subject: fastmodel: Change the Signal proxies to use Signal*Port. .. fastmodel: Change the Signal proxies to use Signal*Port. Change-Id: Ia1aa32d5ea50ff4cc47d1d72a9c25dabd6c30de9 --- M src/arch/arm/fastmodel/common/signal_receiver.hh M src/arch/arm/fastmodel/common/signal_sender.hh 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/arch/arm/fastmodel/common/signal_receiver.hh b/src/arch/arm/fastmodel/common/signal_receiver.hh index 9907877..9ec760e 100644 --- a/src/arch/arm/fastmodel/common/signal_receiver.hh +++ b/src/arch/arm/fastmodel/common/signal_receiver.hh @@ -87,7 +87,7 @@ class SignalReceiverInt : public SignalReceiver { public: -using IntPin = IntSourcePin; +using IntPin = SignalSourcePort; explicit SignalReceiverInt(const std::string ) : SignalReceiver(name) @@ -95,7 +95,7 @@ onChange([this](bool status) { for (auto : signalOut) { if (signal && signal->isConnected()) -status ? signal->raise() : signal->lower(); +signal->set(status); } }); } @@ -108,7 +108,7 @@ } if (!signalOut[idx]) { signalOut[idx] = std::make_unique( -csprintf("%s.signalOut[%d]", get_name(), idx), idx, this); +csprintf("%s.signalOut[%d]", get_name(), idx), idx); } return *signalOut[idx]; } diff --git a/src/arch/arm/fastmodel/common/signal_sender.hh b/src/arch/arm/fastmodel/common/signal_sender.hh index 812a1b9..c596ed1 100644 --- a/src/arch/arm/fastmodel/common/signal_sender.hh +++ b/src/arch/arm/fastmodel/common/signal_sender.hh @@ -33,7 +33,7 @@ #include #pragma GCC diagnostic pop -#include "dev/intpin.hh" +#include "sim/signal.hh" namespace gem5 { @@ -42,14 +42,13 @@ namespace fastmodel { -class SignalSender : public IntSinkPinBase +class SignalSender : public SignalSinkPort { public: amba_pv::signal_master_port signal_out; SignalSender(const std::string &_name, PortID _id) : -IntSinkPinBase(_name, _id, 0), -signal_out((_name + ".sig").c_str()) +SignalSinkPort(_name, _id), signal_out((_name + ".sig").c_str()) { onChange([this](const bool _val) { signal_out.set_state(id, new_val); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66674?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia1aa32d5ea50ff4cc47d1d72a9c25dabd6c30de9 Gerrit-Change-Number: 66674 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: fastmodel,dev: Rework the Int*Pin classes with Signal*Port.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66673?usp=email ) Change subject: fastmodel,dev: Rework the Int*Pin classes with Signal*Port. .. fastmodel,dev: Rework the Int*Pin classes with Signal*Port. These are largely compatibility wrappers around the Signal*Port classes. The python versions of these types enforce more specific compatibility, but on the c++ side the Signal*Port classes can be used directly instead. Change-Id: I1325074d0ed1c8fc6dfece5ac1ee33872cc4f5e3 --- M src/arch/arm/fastmodel/common/signal_sender.hh M src/dev/SConscript D src/dev/intpin.cc M src/dev/intpin.hh 4 files changed, 62 insertions(+), 139 deletions(-) diff --git a/src/arch/arm/fastmodel/common/signal_sender.hh b/src/arch/arm/fastmodel/common/signal_sender.hh index f4772cf..812a1b9 100644 --- a/src/arch/arm/fastmodel/common/signal_sender.hh +++ b/src/arch/arm/fastmodel/common/signal_sender.hh @@ -50,11 +50,11 @@ SignalSender(const std::string &_name, PortID _id) : IntSinkPinBase(_name, _id, 0), signal_out((_name + ".sig").c_str()) -{} - - private: -void raiseOnDevice() override { signal_out.set_state(id, true); } -void lowerOnDevice() override { signal_out.set_state(id, false); } +{ +onChange([this](const bool _val) { +signal_out.set_state(id, new_val); +}); +} }; } // namespace fastmodel diff --git a/src/dev/SConscript b/src/dev/SConscript index 6a6ce40..d991ed5 100644 --- a/src/dev/SConscript +++ b/src/dev/SConscript @@ -36,7 +36,6 @@ Source('dma_virt_device.cc') SimObject('IntPin.py', sim_objects=[]) -Source('intpin.cc') SimObject('ResetPort.py', sim_objects=[]) Source('reset_port.cc') diff --git a/src/dev/intpin.cc b/src/dev/intpin.cc deleted file mode 100644 index c378337..000 --- a/src/dev/intpin.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2019 Google, Inc. - * - * 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 "dev/intpin.hh" - -#include "base/logging.hh" - -namespace gem5 -{ - -void -IntSinkPinBase::bind(Port ) -{ -source = dynamic_cast(); -fatal_if(!source, "Attempt to bind interrupt sink pin %s to " -"incompatible port %s.", name(), peer.name()); -Port::bind(peer); -} - -void -IntSinkPinBase::unbind() -{ -source = nullptr; -Port::unbind(); -} - -void -IntSourcePinBase::bind(Port ) -{ -sink = dynamic_cast(); -fatal_if(!sink, "Attempt to bind interrupt source pin %s to " -"incompatible port %s.", name(), peer.name()); -Port::bind(peer); -} - -void -IntSourcePinBase::unbind() -{ -sink = nullptr; -Port::unbind(); -} - -} // namespace gem5 diff --git a/src/dev/intpin.hh b/src/dev/intpin.hh index 2704887..578dd90 100644 --- a/src/dev/intpin.hh +++ b/src/dev/intpin.hh @@ -28,94 +28,71 @@ #ifndef __DEV_INTPIN_HH__ #define __DEV_INTPIN_HH__ -#include "sim/port.hh" +#include + +#include "sim/signal.hh" namespace gem5 { -class IntSourcePinBase; - -class IntSinkPinBase : public Port +class IntSinkPinBase : public SignalSinkPort { - protected: -friend IntSourcePinBase; + private: +const int _number = 0; -IntSourcePinBase *source = nullptr; + public: -int _number = 0; -bool _state = false; +template +IntSinkPinBase(const std::string &_name, PortID _id, Device *dev, +int num) : +SignalSinkPort(_name, _id), _number(num) +{ +
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Introduce a reset() method on RegisterBank and Register classes.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email ) Change subject: dev: Introduce a reset() method on RegisterBank and Register classes. .. dev: Introduce a reset() method on RegisterBank and Register classes. This will make it much easier to implement reset behaviors on devices which have RegisterBanks in them. Change-Id: I73fe9874fcb69feed33611a320dcca85c0de2d0e --- M src/dev/reg_bank.hh M src/dev/serial/uart8250.hh 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 31c0ce5..66d668b 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -117,6 +117,11 @@ * RegisterBankLE and RegisterBankBE aliases to make it a little easier to * refer to one or the other version. * + * A RegisterBank also has a reset() method which will (by default) call the + * reset() method on each register within it. This method is virtual, and so + * can be overridden if something additional or different needs to be done to + * reset the hardware model. + * * * == Register interface == * @@ -145,6 +150,12 @@ * it still has to implement these methods, but they don't have to actually do * anything. * + * Each register also has a "reset" method, which will reset the register as + * if its containing device is being reset. By default, this will just restore + * the initial value of the register, but can be overridden to implement + * additional behavior like resetting other aspects of the device which are + * controlled by the value of the register. + * * * == Basic Register types == * @@ -360,6 +371,9 @@ // Methods for implementing serialization for checkpoints. virtual void serialize(std::ostream ) const = 0; virtual bool unserialize(const std::string ) = 0; + +// Reset the register. +virtual void reset() = 0; }; // Filler registers which return a fixed pattern. @@ -388,6 +402,9 @@ void serialize(std::ostream ) const override {} bool unserialize(const std::string ) override { return true; } + +// Resetting a read only register doesn't need to do anything. +void reset() override {} }; // Register which reads as all zeroes. @@ -453,6 +470,10 @@ void serialize(std::ostream ) const override {} bool unserialize(const std::string ) override { return true; } +// Assume since the buffer is managed externally, it will be reset +// externally. +void reset() override {} + protected: /** * This method exists so that derived classes that need to initialize @@ -516,6 +537,8 @@ return true; } + +void reset() override { buffer = std::array{}; } }; template @@ -534,6 +557,7 @@ private: Data _data = {}; +Data _resetData = {}; Data _writeMask = mask(sizeof(Data) * 8); ReadFunc _reader = defaultReader; @@ -602,11 +626,13 @@ // Constructor and move constructor with an initial data value. constexpr Register(const std::string _name, const Data _data) : -RegisterBase(new_name, sizeof(Data)), _data(new_data) +RegisterBase(new_name, sizeof(Data)), _data(new_data), +_resetData(new_data) {} constexpr Register(const std::string _name, const Data &_data) : -RegisterBase(new_name, sizeof(Data)), _data(new_data) +RegisterBase(new_name, sizeof(Data)), _data(new_data), +_resetData(new_data) {} // Set which bits of the register are writeable. @@ -789,6 +815,9 @@ { return ParseParam::parse(s, get()); } + +// Reset our data to its initial value. +void reset() override { get() = _resetData; } }; private: @@ -984,6 +1013,14 @@ } } } + +// By default, reset all the registers in the bank. +virtual void +reset() +{ +for (auto &[offset, reg]: _offsetMap) +reg.get().reset(); +} }; using RegisterBankLE = RegisterBank; diff --git a/src/dev/serial/uart8250.hh b/src/dev/serial/uart8250.hh index c55d889..5774f78 100644 --- a/src/dev/serial/uart8250.hh +++ b/src/dev/serial/uart8250.hh @@ -113,6 +113,13 @@ void serialize(std::ostream ) const override {} bool unserialize(const std::string ) override { return true; } + +void +reset() override +{ +_reg1.reset(); +_reg2.reset(); +} }; class BankedRegister : public PairedRegister -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email To unsubscribe, or for help writing mail filters, visit
[gem5-dev] [M] Change in gem5/gem5[develop]: fastmodel,dev: Replace the reset port with a Signal*Port.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66675?usp=email ) Change subject: fastmodel,dev: Replace the reset port with a Signal*Port. .. fastmodel,dev: Replace the reset port with a Signal*Port. The ResetRequestPort and ResetResponsePort have a few problems: 1. A reset signal should happen during the time a reset is asserted, or in other words the device should stay in reset and not doing anything while reset is asserted. It should not immediately restart execution while the reset is still held. 2. These names are misleading, since there is no response. These names are inherited from other port types where there is an actual response. There is a new generic SignalSourcePort and SignalSinkPort set of port classes which are templated on the type of signal they propogate, and which can be used in place of reset ports in c++. These ports can still have a specialized role which will ensure that only reset ports are connected to each other for a form of type checking, although the underlying c++ instances are more interoperable than that. Change-Id: Id98bef901ab61ac5b200dbbe49439bb2d2e6c57f --- M src/arch/arm/fastmodel/CortexA76/evs.cc M src/arch/arm/fastmodel/CortexA76/evs.hh M src/arch/arm/fastmodel/CortexR52/evs.cc M src/arch/arm/fastmodel/CortexR52/evs.hh M src/arch/arm/fastmodel/reset_controller/example.cc M src/arch/arm/fastmodel/reset_controller/example.hh M src/dev/SConscript D src/dev/reset_port.cc D src/dev/reset_port.hh 9 files changed, 59 insertions(+), 188 deletions(-) diff --git a/src/arch/arm/fastmodel/CortexA76/evs.cc b/src/arch/arm/fastmodel/CortexA76/evs.cc index 1c06935..c9ce3cc 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.cc +++ b/src/arch/arm/fastmodel/CortexA76/evs.cc @@ -71,32 +71,25 @@ } template -void -ScxEvsCortexA76::requestReset() -{ -// Reset all cores. -for (auto _reset : this->poweron_reset) { -poweron_reset->signal_out.set_state(0, true); -poweron_reset->signal_out.set_state(0, false); -} -// Reset DSU. -this->top_reset.signal_out.set_state(0, true); -this->top_reset.signal_out.set_state(0, false); -// Reset debug APB. -this->dbg_reset.signal_out.set_state(0, true); -this->dbg_reset.signal_out.set_state(0, false); -} - -template ScxEvsCortexA76::ScxEvsCortexA76( const sc_core::sc_module_name _name, const Params ) : Base(mod_name), amba(Base::amba, p.name + ".amba", -1), top_reset(p.name + ".top_reset", 0), dbg_reset(p.name + ".dbg_reset", 0), -model_reset(p.name + ".model_reset", -1, this), +model_reset(p.name + ".model_reset"), params(p) { +model_reset.onChange([this](const bool _val) { +// Set reset for all cores. +for (auto _reset : poweron_reset) +poweron_reset->signal_out.set_state(0, new_val); +// Set reset for DSU. +top_reset.signal_out.set_state(0, new_val); +// Set reset for debug APB. +dbg_reset.signal_out.set_state(0, new_val); +}); + for (int i = 0; i < CoreCount; i++) { redist.emplace_back(new TlmGicTarget(this->redistributor[i], csprintf("%s.redistributor[%d]", name(), i), i)); diff --git a/src/arch/arm/fastmodel/CortexA76/evs.hh b/src/arch/arm/fastmodel/CortexA76/evs.hh index 081e80f..7c4ef60 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.hh +++ b/src/arch/arm/fastmodel/CortexA76/evs.hh @@ -35,7 +35,6 @@ #include "arch/arm/fastmodel/common/signal_sender.hh" #include "arch/arm/fastmodel/iris/cpu.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" -#include "dev/reset_port.hh" #include "mem/port_proxy.hh" #include "params/FastModelScxEvsCortexA76x1.hh" #include "params/FastModelScxEvsCortexA76x2.hh" @@ -45,6 +44,7 @@ #include "scx_evs_CortexA76x2.h" #include "scx_evs_CortexA76x3.h" #include "scx_evs_CortexA76x4.h" +#include "sim/signal.hh" #include "systemc/ext/core/sc_event.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/tlm_port_wrapper.hh" @@ -99,7 +99,7 @@ SignalSender dbg_reset; -ResetResponsePort model_reset; +SignalSinkPort model_reset; CortexA76Cluster *gem5CpuCluster; @@ -129,8 +129,6 @@ void setCluster(SimObject *cluster) override; void setResetAddr(int core, Addr addr, bool secure) override; - -void requestReset(); }; struct ScxEvsCortexA76x1Types diff --git a/src/arch/arm/fastmodel/CortexR52/evs.cc b/src/arch/arm/fastmodel/CortexR52/evs.cc index 734323e..0ad3f18 100644 --- a/src/arch/arm/fastmodel/CortexR52/evs.cc +++ b/src/arch/arm/fastmodel/CortexR52/evs.cc @@ -101,9 +101,19 @@ ext_slave(Base::ext_slave, p.name + ".ext_slave", -1), top_reset(p.name + ".top_reset", 0), dbg_reset(p.name + ".dbg_reset", 0), -model_reset(p.name + ".model_reset", -1, this), +model_reset(p.name +
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Implement a "Signal" port which has a templated State type.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66672?usp=email ) Change subject: dev: Implement a "Signal" port which has a templated State type. .. dev: Implement a "Signal" port which has a templated State type. This port type transmits a value of the templated State type. When the value changes, the sink port will call the registered callback with the new value. Change-Id: I72eaf74658a2c63bece95e48c1a72694874eaad8 --- A src/sim/signal.hh 1 file changed, 144 insertions(+), 0 deletions(-) diff --git a/src/sim/signal.hh b/src/sim/signal.hh new file mode 100644 index 000..3cb3f62 --- /dev/null +++ b/src/sim/signal.hh @@ -0,0 +1,131 @@ +/* + * Copyright 2022 Google, Inc. + * + * 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 __SIM_SIGNAL_HH__ +#define __SIM_SIGNAL_HH__ + +#include + +#include "base/logging.hh" +#include "sim/port.hh" + +namespace gem5 +{ + +template +class SignalSourcePort; + +template +class SignalSinkPort : public Port +{ + public: +using OnChangeFunc = std::function; + + private: +friend SignalSourcePort; + +SignalSourcePort *_source = nullptr; + +State _state = {}; +OnChangeFunc _onChange; + + protected: +void +set(const State _state) +{ +if (new_state == _state) +return; + +_state = new_state; +if (_onChange) +_onChange(_state); +} + + public: +SignalSinkPort(const std::string &_name, PortID _id=InvalidPortID) : +Port(_name, _id) +{} + +const State () const { return _state; } +void onChange(OnChangeFunc func) { _onChange = std::move(func); } + +void +bind(Port ) override +{ +_source = dynamic_cast *>(); +fatal_if(!_source, "Attempt to bind signal pin %s to " +"incompatible pin %s", name(), peer.name()); +Port::bind(peer); +} +void +unbind() override +{ +_source = nullptr; +Port::unbind(); +} +}; + +template +class SignalSourcePort : public Port +{ + private: +SignalSinkPort *sink = nullptr; +State _state = {}; + + public: +SignalSourcePort(const std::string &_name, PortID _id=InvalidPortID) : +Port(_name, _id) +{} + +void +set(const State _state) +{ +_state = new_state; +sink->set(new_state); +} + +const State () const { return _state; } + +void +bind(Port ) override +{ +sink = dynamic_cast *>(); +fatal_if(!sink, "Attempt to bind signal pin %s to " +"incompatible pin %s", name(), peer.name()); +Port::bind(peer); +} +void +unbind() override +{ +sink = nullptr; +Port::unbind(); +} +}; + +} // namespace gem5 + +#endif //__SIM_SIGNAL_HH__ -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66672?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I72eaf74658a2c63bece95e48c1a72694874eaad8 Gerrit-Change-Number: 66672 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: systemc: Enable DMI in the non-blocking/timing mode bridge.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/65754?usp=email ) Change subject: systemc: Enable DMI in the non-blocking/timing mode bridge. .. systemc: Enable DMI in the non-blocking/timing mode bridge. Change-Id: Ia618081e2dbf8b49f62480ac5dc29f87100cd4f1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65754 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Gabe Black --- M src/systemc/tlm_bridge/tlm_to_gem5.cc 1 file changed, 38 insertions(+), 2 deletions(-) Approvals: kokoro: Regressions pass Gabe Black: Looks good to me, approved; Looks good to me, approved diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc index 47a2fba..c02efe7 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc @@ -207,6 +207,29 @@ TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload , sc_core::sc_time ) { +MemBackdoor::Flags flags; +switch (trans.get_command()) { + case tlm::TLM_READ_COMMAND: +flags = MemBackdoor::Readable; +break; + case tlm::TLM_WRITE_COMMAND: +flags = MemBackdoor::Writeable; +break; + default: +panic("TlmToGem5Bridge: " +"received transaction with unsupported command"); +} +Addr start_addr = trans.get_address(); +Addr length = trans.get_data_length(); + +MemBackdoorReq req({start_addr, start_addr + length}, flags); +MemBackdoorPtr backdoor = nullptr; + +bmp.sendMemBackdoorReq(req, backdoor); + +if (backdoor) +trans.set_dmi_allowed(true); + tlm::tlm_phase phase = tlm::BEGIN_RESP; auto status = socket->nb_transport_bw(trans, phase, delay); @@ -574,12 +597,12 @@ DPRINTF(TlmBridge, "register blocking interface"); socket.register_b_transport( this, ::b_transport); -socket.register_get_direct_mem_ptr( -this, ::get_direct_mem_ptr); } else { panic("gem5 operates neither in Timing nor in Atomic mode"); } +socket.register_get_direct_mem_ptr( +this, ::get_direct_mem_ptr); socket.register_transport_dbg( this, ::transport_dbg); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/65754?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia618081e2dbf8b49f62480ac5dc29f87100cd4f1 Gerrit-Change-Number: 65754 Gerrit-PatchSet: 4 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add an offset checking mechanism to RegisterBank.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66431?usp=email ) Change subject: dev: Add an offset checking mechanism to RegisterBank. .. dev: Add an offset checking mechanism to RegisterBank. When adding a long list of registers, it can be easy to miss one which will offset all the registers after it. It can be hard to find those sorts of problems, and tedious and error prone to fix them. This change adds a mechanism to simply annotate what offset a register should have. That should also make the register list more self documenting, since you'll be able to easily see what offset a register has from the source without having to count up everything in front of it. Change-Id: Ia7e419ffb062a64a10106305f875cec6f9fe9a80 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66431 Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black Tested-by: kokoro --- M src/dev/reg_bank.hh M src/dev/reg_bank.test.cc 2 files changed, 120 insertions(+), 11 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 42af7bc..31c0ce5 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,9 @@ * entire device, with the address from accesses passed into read or write * unmodified. * + * The base(), size() and name() methods can be used to access each of those + * read only properties of the RegisterBank instance. + * * To add actual registers to the RegisterBank (discussed below), you can use * either the addRegister method which adds a single register, or addRegisters * which adds an initializer list of them all at once. The register will be @@ -91,8 +95,19 @@ * existing registers. The size of the bank is automatically accumulated as * registers are added. * - * The base(), size() and name() methods can be used to access each of those - * read only properties of the RegisterBank instance. + * When adding a lot of registers, you might accidentally add an extra, + * or accidentally skip one in a long list. Because the offset is handled + * automatically, some of your registers might end up shifted higher or lower + * than you expect. To help mitigate this, you can set what offset you expect + * a register to have by specifying it as an offset, register pair. + * + * addRegisters({{0x1000, reg0}, reg1, reg2}); + * + * If the register would end up at a different offset, gem5 will panic. You + * can also leave off the register if you want to just check the offset, for + * instance between groups of registers. + * + * addRegisters({reg0, reg1, reg2, 0x100c}) * * While the RegisterBank itself doesn't have any data in it directly and so * has no endianness, it's very likely all the registers within it will have @@ -805,19 +820,52 @@ virtual ~RegisterBank() {} -void -addRegisters( -std::initializer_list> regs) +class RegisterAdder { -panic_if(regs.size() == 0, "Adding an empty list of registers to %s?", - name()); -for (auto : regs) { -_offsetMap.emplace(_base + _size, reg); -_size += reg.get().size(); + private: +std::optional offset; +std::optional reg; + + public: +// Nothing special to do for this register. +RegisterAdder(RegisterBase _reg) : reg(_reg) {} +// Ensure that this register is added at a particular offset. +RegisterAdder(Addr new_offset, RegisterBase _reg) : +offset(new_offset), reg(_reg) +{} +// No register, just check that the offset is what we expect. +RegisterAdder(Addr new_offset) : offset(new_offset) {} + +friend class RegisterBank; +}; + +void +addRegisters(std::initializer_list adders) +{ +panic_if(std::empty(adders), +"Adding an empty list of registers to %s?", name()); +for (auto : adders) { +const Addr offset = _base + _size; + +if (adder.reg) { +auto *reg = adder.reg.value(); +if (adder.offset && adder.offset.value() != offset) { +panic( +"Expected offset of register %s.%s to be %#x, is %#x.", +name(), reg->name(), adder.offset.value(), offset); +} +_offsetMap.emplace(offset, *reg); +_size += reg->size(); +} else if (adder.offset) { +if (adder.offset.value() != offset) { +panic("Expected current offset of %s to be %#x, is %#x.", +name(), adder.offset.value(), offset); +} +}
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Add an offset checking mechanism to RegisterBank.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66431?usp=email ) Change subject: dev: Add an offset checking mechanism to RegisterBank. .. dev: Add an offset checking mechanism to RegisterBank. When adding a long list of registers, it can be easy to miss one which will offset all the registers after it. It can be hard to find those sorts of problems, and tedious and error prone to fix them. This change adds a mechanism to simply annotate what offset a register should have. That should also make the register list more self documenting, since you'll be able to easily see what offset a register has from the source without having to count up everything in front of it. Change-Id: Ia7e419ffb062a64a10106305f875cec6f9fe9a80 --- M src/dev/reg_bank.hh M src/dev/reg_bank.test.cc 2 files changed, 117 insertions(+), 11 deletions(-) diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 42af7bc..6348597 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -84,6 +84,9 @@ * entire device, with the address from accesses passed into read or write * unmodified. * + * The base(), size() and name() methods can be used to access each of those + * read only properties of the RegisterBank instance. + * * To add actual registers to the RegisterBank (discussed below), you can use * either the addRegister method which adds a single register, or addRegisters * which adds an initializer list of them all at once. The register will be @@ -91,8 +94,19 @@ * existing registers. The size of the bank is automatically accumulated as * registers are added. * - * The base(), size() and name() methods can be used to access each of those - * read only properties of the RegisterBank instance. + * When adding a lot of registers, you might accidentally add an extra, + * or accidentally skip one in a long list. Because the offset is handled + * automatically, some of your registers might end up shifted higher or lower + * than you expect. To help mitigate this, you can set what offset you expect + * a register to have by specifying it as an offset, register pair. + * + * addRegisters({{0x1000, reg0}, reg1, reg2}); + * + * If the register would end up at a different offset, gem5 will panic. You + * can also leave off the register if you want to just check the offset, for + * instance between groups of registers. + * + * addRegisters({reg0, reg1, reg2, 0x100c}) * * While the RegisterBank itself doesn't have any data in it directly and so * has no endianness, it's very likely all the registers within it will have @@ -805,19 +819,54 @@ virtual ~RegisterBank() {} -void -addRegisters( -std::initializer_list> regs) +class RegisterAdder { -panic_if(regs.size() == 0, "Adding an empty list of registers to %s?", - name()); -for (auto : regs) { -_offsetMap.emplace(_base + _size, reg); -_size += reg.get().size(); + private: +bool checkOffset = false; +Addr offset = 0; +RegisterBase *reg = nullptr; + + public: +// Nothing special to do for this register. +RegisterAdder(RegisterBase _reg) : reg(_reg) {} +// Ensure that this register is added at a particular offset. +RegisterAdder(Addr new_offset, RegisterBase _reg) : +checkOffset(true), offset(new_offset), reg(_reg) +{} +// No register, just check that the offset is what we expect. +RegisterAdder(Addr new_offset) : checkOffset(true), offset(new_offset) +{} + +friend class RegisterBank; +}; + +void +addRegisters(std::initializer_list adders) +{ +panic_if(adders.size() == 0, +"Adding an empty list of registers to %s?", name()); +for (auto : adders) { +const Addr offset = _base + _size; +auto *reg = adder.reg; + +if (reg) { +if (adder.checkOffset && adder.offset != offset) { +panic( +"Expected offset of register %s.%s to be %#x, is %#x.", +name(), reg->name(), adder.offset, offset); +} +_offsetMap.emplace(offset, *reg); +_size += reg->size(); +} else if (adder.checkOffset) { +if (adder.offset != offset) { +panic("Expected current offset of %s to be %#x, is %#x.", +name(), adder.offset, offset); +} +} } } -void addRegister(RegisterBase ) { addRegisters({reg}); } +void addRegister(RegisterAdder reg) { addRegisters({reg}); } Addr base() const { return _base; } Addr size() const { return _size; } diff --git a/src/dev/reg_bank.test.cc b/src/dev/reg_bank.test.cc
[gem5-dev] [M] Change in gem5/gem5[develop]: dev,mem,systemc: Implement and use the recvMemBackdoorReq func.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/65753?usp=email ) Change subject: dev,mem,systemc: Implement and use the recvMemBackdoorReq func. .. dev,mem,systemc: Implement and use the recvMemBackdoorReq func. Change-Id: If6e12d4fcef0c31131a9768099a72542a8f62ab1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65753 Tested-by: kokoro Reviewed-by: Jason Lowe-Power Maintainer: Gabe Black Reviewed-by: Jui-min Lee --- M src/mem/cfi_mem.cc M src/mem/cfi_mem.hh M src/mem/coherent_xbar.cc M src/mem/coherent_xbar.hh M src/mem/mem_ctrl.cc M src/mem/mem_ctrl.hh M src/mem/noncoherent_xbar.cc M src/mem/noncoherent_xbar.hh M src/mem/simple_mem.cc M src/mem/simple_mem.hh M src/mem/sys_bridge.hh M src/systemc/tlm_bridge/gem5_to_tlm.cc M src/systemc/tlm_bridge/gem5_to_tlm.hh M src/systemc/tlm_bridge/tlm_to_gem5.cc 14 files changed, 170 insertions(+), 16 deletions(-) Approvals: Gabe Black: Looks good to me, approved Jason Lowe-Power: Looks good to me, but someone else must approve kokoro: Regressions pass Jui-min Lee: Looks good to me, approved diff --git a/src/mem/cfi_mem.cc b/src/mem/cfi_mem.cc index 70dc43f..f8c1084 100644 --- a/src/mem/cfi_mem.cc +++ b/src/mem/cfi_mem.cc @@ -275,6 +275,14 @@ pkt->popLabel(); } +void +CfiMemory::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) +{ +if (backdoor.ptr()) +_backdoor = +} + bool CfiMemory::recvTimingReq(PacketPtr pkt) { @@ -486,6 +494,13 @@ mem.recvFunctional(pkt); } +void +CfiMemory::MemoryPort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) +{ +mem.recvMemBackdoorReq(req, _backdoor); +} + bool CfiMemory::MemoryPort::recvTimingReq(PacketPtr pkt) { diff --git a/src/mem/cfi_mem.hh b/src/mem/cfi_mem.hh index 5a7a1c5..4a02267 100644 --- a/src/mem/cfi_mem.hh +++ b/src/mem/cfi_mem.hh @@ -248,6 +248,8 @@ Tick recvAtomicBackdoor( PacketPtr pkt, MemBackdoorPtr &_backdoor) override; void recvFunctional(PacketPtr pkt) override; +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) override; bool recvTimingReq(PacketPtr pkt) override; void recvRespRetry() override; AddrRangeList getAddrRanges() const override; @@ -361,6 +363,8 @@ Tick recvAtomic(PacketPtr pkt); Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &_backdoor); void recvFunctional(PacketPtr pkt); +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor); bool recvTimingReq(PacketPtr pkt); void recvRespRetry(); diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc index 7d1cd5d..8163299 100644 --- a/src/mem/coherent_xbar.cc +++ b/src/mem/coherent_xbar.cc @@ -998,6 +998,14 @@ } void +CoherentXBar::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +PortID dest_id = findPort(req.range()); +memSidePorts[dest_id]->sendMemBackdoorReq(req, backdoor); +} + +void CoherentXBar::recvFunctional(PacketPtr pkt, PortID cpu_side_port_id) { if (!pkt->isPrint()) { diff --git a/src/mem/coherent_xbar.hh b/src/mem/coherent_xbar.hh index 1c55cc0..9693d92 100644 --- a/src/mem/coherent_xbar.hh +++ b/src/mem/coherent_xbar.hh @@ -136,6 +136,13 @@ xbar.recvFunctional(pkt, id); } +void +recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) override +{ +xbar.recvMemBackdoorReq(req, backdoor); +} + AddrRangeList getAddrRanges() const override { @@ -374,6 +381,11 @@ transaction.*/ void recvFunctional(PacketPtr pkt, PortID cpu_side_port_id); +/** Function called by the port when the crossbar receives a request for +a memory backdoor.*/ +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ); + /** Function called by the port when the crossbar is receiving a functional snoop transaction.*/ void recvFunctionalSnoop(PacketPtr pkt, PortID mem_side_port_id); diff --git a/src/mem/mem_ctrl.cc b/src/mem/mem_ctrl.cc index c65d68a..beaace1 100644 --- a/src/mem/mem_ctrl.cc +++ b/src/mem/mem_ctrl.cc @@ -1364,6 +1364,17 @@ pkt->print()); } +void +MemCtrl::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +panic_if(!dram->getAddrRange().contains(req.range().start()), +"Can't handle address range for backdoor %s.", +req.range().to_string()); + +dram->getBackdoor(backdoor); +} + bool MemCtrl::recvFunctionalLogic(PacketPtr pkt, MemInterface* mem_intr) { @@ -1474,6 +1485,13 @@ pkt->popLabel(); } +void +MemCtrl::MemoryPort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +ctrl.recvMemBackdoorReq(req, backdoor);
[gem5-dev] [M] Change in gem5/gem5[develop]: mem: Add an API for requesting a back door without a Packet/Request.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/65752?usp=email ) Change subject: mem: Add an API for requesting a back door without a Packet/Request. .. mem: Add an API for requesting a back door without a Packet/Request. Make this part of the Functional protocol, since it should always return immediately, can be shared by the atomic and timing protocols, and thematically fits with that protocol. The default implementation on the receiving end just ignores the request and leaves the back door pointer set to null, effectively making back doors default "off" which matches their behavior in the atomic protocol. This mechamism helps fix a bug in the TLM gem5 bridges which need to translate to/from the DMI and back door mechanisms, where there can be an explicit request for a back door which does not have a transaction associated with it. It is also necessary for bridging DMI requests in timing mode, since the DMI requests must be instant, and the timing protocol does not send/receive packets instantly. Change-Id: I905f13b9bc83c3fa7877b05ce932e17c308125e2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65752 Tested-by: kokoro Reviewed-by: Jason Lowe-Power Maintainer: Gabe Black --- M src/mem/port.cc M src/mem/port.hh M src/mem/protocol/functional.cc M src/mem/protocol/functional.hh 4 files changed, 103 insertions(+), 0 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved kokoro: Regressions pass Gabe Black: Looks good to me, approved diff --git a/src/mem/port.cc b/src/mem/port.cc index 00f7ce6..18793d4 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -102,6 +102,11 @@ // Functional protocol. void recvFunctional(PacketPtr) override { blowUp(); } +void +recvMemBackdoorReq(const MemBackdoorReq &, MemBackdoorPtr &) override +{ +blowUp(); +} // General. AddrRangeList getAddrRanges() const override { return AddrRangeList(); } @@ -205,4 +210,15 @@ return recvAtomic(pkt); } +void +ResponsePort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +if (!defaultBackdoorWarned) { +DPRINTF(ResponsePort, +"Port %s doesn't support requesting a back door.", name()); +defaultBackdoorWarned = true; +} +} + } // namespace gem5 diff --git a/src/mem/port.hh b/src/mem/port.hh index 33ff117..fb0f4b8 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -161,6 +161,21 @@ */ void sendFunctional(PacketPtr pkt) const; +/** + * Send a request for a back door to a range of memory. + * + * @param req An object which describes what back door is being requested. + * @param backdoor Can be set to a back door pointer by the target to let + *caller have direct access to the requested range. The original + *caller should initialize this pointer to nullptr. If a receiver + *does not want to provide a back door, they should leave this + *value. If an intermediary wants to support a back door across it, + *it should pass this pointer through, or if not, return without + *passing the request further downstream. + */ +void sendMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ); + public: /* The timing protocol. */ @@ -438,6 +453,8 @@ * Default implementations. */ Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr ) override; +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) override; bool tryTiming(PacketPtr pkt) override @@ -491,6 +508,18 @@ } } +inline void +RequestPort::sendMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +try { +return FunctionalRequestProtocol::sendMemBackdoorReq( +_responsePort, req, backdoor); +} catch (UnboundPortException) { +reportUnbound(); +} +} + inline bool RequestPort::sendTimingReq(PacketPtr pkt) { diff --git a/src/mem/protocol/functional.cc b/src/mem/protocol/functional.cc index 0f54d92..29cec23 100644 --- a/src/mem/protocol/functional.cc +++ b/src/mem/protocol/functional.cc @@ -53,6 +53,14 @@ return peer->recvFunctional(pkt); } +void +FunctionalRequestProtocol::sendMemBackdoorReq( +FunctionalResponseProtocol *peer, +const MemBackdoorReq , MemBackdoorPtr ) +{ +return peer->recvMemBackdoorReq(req, backdoor); +} + /* The response protocol. */ void diff --git a/src/mem/protocol/functional.hh b/src/mem/protocol/functional.hh index 27db171..4f330b4 100644 --- a/src/mem/protocol/functional.hh +++ b/src/mem/protocol/functional.hh @@ -41,6 +41,7 @@ #ifndef __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ #define __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ +#include "mem/backdoor.hh" #include "mem/packet.hh" namespace gem5 @@ -66,6
[gem5-dev] [S] Change in gem5/gem5[develop]: mem: Add a class to describe a back door request.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/65751?usp=email ) Change subject: mem: Add a class to describe a back door request. .. mem: Add a class to describe a back door request. In cases where a back door is not being requested alongside a packet or request, there needs to be a structure which describes the address range to use, and what type of access the back door should support. It would be possible to make a Packet/Request to carry that information, but those types are actually pretty big, and have a lot of extra overhead which would be overkill for this purpose. Change-Id: I3638361ffa758ee959cb3bc57f7c35f2aa34a36c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65751 Reviewed-by: Jason Lowe-Power Maintainer: Gabe Black Tested-by: kokoro --- M src/mem/backdoor.hh 1 file changed, 39 insertions(+), 0 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/mem/backdoor.hh b/src/mem/backdoor.hh index 73e6670..54fe4ac 100644 --- a/src/mem/backdoor.hh +++ b/src/mem/backdoor.hh @@ -126,6 +126,25 @@ typedef MemBackdoor *MemBackdoorPtr; +class MemBackdoorReq +{ + private: +AddrRange _range; +MemBackdoor::Flags _flags; + + public: +MemBackdoorReq(AddrRange r, MemBackdoor::Flags new_flags) : +_range(r), _flags(new_flags) +{} + +const AddrRange () const { return _range; } + +bool readable() const { return _flags & MemBackdoor::Readable; } +bool writeable() const { return _flags & MemBackdoor::Writeable; } + +MemBackdoor::Flags flags() const { return _flags; } +}; + } // namespace gem5 #endif //__MEM_BACKDOOR_HH__ -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/65751?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I3638361ffa758ee959cb3bc57f7c35f2aa34a36c Gerrit-Change-Number: 65751 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jason Lowe-Power Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Nikos Nikoleris Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: mem: Add an API for requesting a back door without a Packet/Request.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/65752?usp=email ) Change subject: mem: Add an API for requesting a back door without a Packet/Request. .. mem: Add an API for requesting a back door without a Packet/Request. Make this part of the Functional protocol, since it should always return immediately, can be shared by the atomic and timing protocols, and thematically fits with that protocol. The default implementation on the receiving end just ignores the request and leaves the back door pointer set to null, effectively making back doors default "off" which matches their behavior in the atomic protocol. This mechamism helps fix a bug in the TLM gem5 bridges which need to translate to/from the DMI and back door mechanisms, where there can be an explicit request for a back door which does not have a transaction associated with it. It is also necessary for bridging DMI requests in timing mode, since the DMI requests must be instant, and the timing protocol does not send/receive packets instantly. Change-Id: I905f13b9bc83c3fa7877b05ce932e17c308125e2 --- M src/mem/port.cc M src/mem/port.hh M src/mem/protocol/functional.cc M src/mem/protocol/functional.hh 4 files changed, 99 insertions(+), 0 deletions(-) diff --git a/src/mem/port.cc b/src/mem/port.cc index 00f7ce6..18793d4 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -102,6 +102,11 @@ // Functional protocol. void recvFunctional(PacketPtr) override { blowUp(); } +void +recvMemBackdoorReq(const MemBackdoorReq &, MemBackdoorPtr &) override +{ +blowUp(); +} // General. AddrRangeList getAddrRanges() const override { return AddrRangeList(); } @@ -205,4 +210,15 @@ return recvAtomic(pkt); } +void +ResponsePort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +if (!defaultBackdoorWarned) { +DPRINTF(ResponsePort, +"Port %s doesn't support requesting a back door.", name()); +defaultBackdoorWarned = true; +} +} + } // namespace gem5 diff --git a/src/mem/port.hh b/src/mem/port.hh index 33ff117..fb0f4b8 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -161,6 +161,21 @@ */ void sendFunctional(PacketPtr pkt) const; +/** + * Send a request for a back door to a range of memory. + * + * @param req An object which describes what back door is being requested. + * @param backdoor Can be set to a back door pointer by the target to let + *caller have direct access to the requested range. The original + *caller should initialize this pointer to nullptr. If a receiver + *does not want to provide a back door, they should leave this + *value. If an intermediary wants to support a back door across it, + *it should pass this pointer through, or if not, return without + *passing the request further downstream. + */ +void sendMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ); + public: /* The timing protocol. */ @@ -438,6 +453,8 @@ * Default implementations. */ Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr ) override; +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) override; bool tryTiming(PacketPtr pkt) override @@ -491,6 +508,18 @@ } } +inline void +RequestPort::sendMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +try { +return FunctionalRequestProtocol::sendMemBackdoorReq( +_responsePort, req, backdoor); +} catch (UnboundPortException) { +reportUnbound(); +} +} + inline bool RequestPort::sendTimingReq(PacketPtr pkt) { diff --git a/src/mem/protocol/functional.cc b/src/mem/protocol/functional.cc index 0f54d92..29cec23 100644 --- a/src/mem/protocol/functional.cc +++ b/src/mem/protocol/functional.cc @@ -53,6 +53,14 @@ return peer->recvFunctional(pkt); } +void +FunctionalRequestProtocol::sendMemBackdoorReq( +FunctionalResponseProtocol *peer, +const MemBackdoorReq , MemBackdoorPtr ) +{ +return peer->recvMemBackdoorReq(req, backdoor); +} + /* The response protocol. */ void diff --git a/src/mem/protocol/functional.hh b/src/mem/protocol/functional.hh index 27db171..4f330b4 100644 --- a/src/mem/protocol/functional.hh +++ b/src/mem/protocol/functional.hh @@ -41,6 +41,7 @@ #ifndef __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ #define __MEM_GEM5_PROTOCOL_FUNCTIONAL_HH__ +#include "mem/backdoor.hh" #include "mem/packet.hh" namespace gem5 @@ -66,6 +67,16 @@ * Receive a functional snoop request packet from the peer. */ virtual void recvFunctionalSnoop(PacketPtr pkt) = 0; + +/** + * Send a request for a back door to a range of memory. + * + * @param req An object which describes
[gem5-dev] [S] Change in gem5/gem5[develop]: mem: Add a class to describe a back door request.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/65751?usp=email ) Change subject: mem: Add a class to describe a back door request. .. mem: Add a class to describe a back door request. In cases where a back door is not being requested alongside a packet or request, there needs to be a structure which describes the address range to use, and what type of access the back door should support. It would be possible to make a Packet/Request to carry that information, but those types are actually pretty big, and have a lot of extra overhead which would be overkill for this purpose. Change-Id: I3638361ffa758ee959cb3bc57f7c35f2aa34a36c --- M src/mem/backdoor.hh 1 file changed, 35 insertions(+), 0 deletions(-) diff --git a/src/mem/backdoor.hh b/src/mem/backdoor.hh index 73e6670..54fe4ac 100644 --- a/src/mem/backdoor.hh +++ b/src/mem/backdoor.hh @@ -126,6 +126,25 @@ typedef MemBackdoor *MemBackdoorPtr; +class MemBackdoorReq +{ + private: +AddrRange _range; +MemBackdoor::Flags _flags; + + public: +MemBackdoorReq(AddrRange r, MemBackdoor::Flags new_flags) : +_range(r), _flags(new_flags) +{} + +const AddrRange () const { return _range; } + +bool readable() const { return _flags & MemBackdoor::Readable; } +bool writeable() const { return _flags & MemBackdoor::Writeable; } + +MemBackdoor::Flags flags() const { return _flags; } +}; + } // namespace gem5 #endif //__MEM_BACKDOOR_HH__ -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/65751?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I3638361ffa758ee959cb3bc57f7c35f2aa34a36c Gerrit-Change-Number: 65751 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [M] Change in gem5/gem5[develop]: dev,mem,systemc: Implement and use the recvMemBackdoorReq func.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/65753?usp=email ) Change subject: dev,mem,systemc: Implement and use the recvMemBackdoorReq func. .. dev,mem,systemc: Implement and use the recvMemBackdoorReq func. Change-Id: If6e12d4fcef0c31131a9768099a72542a8f62ab1 --- M src/mem/cfi_mem.cc M src/mem/cfi_mem.hh M src/mem/coherent_xbar.cc M src/mem/coherent_xbar.hh M src/mem/mem_ctrl.cc M src/mem/mem_ctrl.hh M src/mem/noncoherent_xbar.cc M src/mem/noncoherent_xbar.hh M src/mem/simple_mem.cc M src/mem/simple_mem.hh M src/mem/sys_bridge.hh M src/systemc/tlm_bridge/gem5_to_tlm.cc M src/systemc/tlm_bridge/gem5_to_tlm.hh M src/systemc/tlm_bridge/tlm_to_gem5.cc 14 files changed, 165 insertions(+), 16 deletions(-) diff --git a/src/mem/cfi_mem.cc b/src/mem/cfi_mem.cc index 70dc43f..f8c1084 100644 --- a/src/mem/cfi_mem.cc +++ b/src/mem/cfi_mem.cc @@ -275,6 +275,14 @@ pkt->popLabel(); } +void +CfiMemory::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) +{ +if (backdoor.ptr()) +_backdoor = +} + bool CfiMemory::recvTimingReq(PacketPtr pkt) { @@ -486,6 +494,13 @@ mem.recvFunctional(pkt); } +void +CfiMemory::MemoryPort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) +{ +mem.recvMemBackdoorReq(req, _backdoor); +} + bool CfiMemory::MemoryPort::recvTimingReq(PacketPtr pkt) { diff --git a/src/mem/cfi_mem.hh b/src/mem/cfi_mem.hh index 5a7a1c5..4a02267 100644 --- a/src/mem/cfi_mem.hh +++ b/src/mem/cfi_mem.hh @@ -248,6 +248,8 @@ Tick recvAtomicBackdoor( PacketPtr pkt, MemBackdoorPtr &_backdoor) override; void recvFunctional(PacketPtr pkt) override; +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor) override; bool recvTimingReq(PacketPtr pkt) override; void recvRespRetry() override; AddrRangeList getAddrRanges() const override; @@ -361,6 +363,8 @@ Tick recvAtomic(PacketPtr pkt); Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &_backdoor); void recvFunctional(PacketPtr pkt); +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr &_backdoor); bool recvTimingReq(PacketPtr pkt); void recvRespRetry(); diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc index 7d1cd5d..8163299 100644 --- a/src/mem/coherent_xbar.cc +++ b/src/mem/coherent_xbar.cc @@ -998,6 +998,14 @@ } void +CoherentXBar::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +PortID dest_id = findPort(req.range()); +memSidePorts[dest_id]->sendMemBackdoorReq(req, backdoor); +} + +void CoherentXBar::recvFunctional(PacketPtr pkt, PortID cpu_side_port_id) { if (!pkt->isPrint()) { diff --git a/src/mem/coherent_xbar.hh b/src/mem/coherent_xbar.hh index 1c55cc0..9693d92 100644 --- a/src/mem/coherent_xbar.hh +++ b/src/mem/coherent_xbar.hh @@ -136,6 +136,13 @@ xbar.recvFunctional(pkt, id); } +void +recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) override +{ +xbar.recvMemBackdoorReq(req, backdoor); +} + AddrRangeList getAddrRanges() const override { @@ -374,6 +381,11 @@ transaction.*/ void recvFunctional(PacketPtr pkt, PortID cpu_side_port_id); +/** Function called by the port when the crossbar receives a request for +a memory backdoor.*/ +void recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ); + /** Function called by the port when the crossbar is receiving a functional snoop transaction.*/ void recvFunctionalSnoop(PacketPtr pkt, PortID mem_side_port_id); diff --git a/src/mem/mem_ctrl.cc b/src/mem/mem_ctrl.cc index c65d68a..beaace1 100644 --- a/src/mem/mem_ctrl.cc +++ b/src/mem/mem_ctrl.cc @@ -1364,6 +1364,17 @@ pkt->print()); } +void +MemCtrl::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +panic_if(!dram->getAddrRange().contains(req.range().start()), +"Can't handle address range for backdoor %s.", +req.range().to_string()); + +dram->getBackdoor(backdoor); +} + bool MemCtrl::recvFunctionalLogic(PacketPtr pkt, MemInterface* mem_intr) { @@ -1474,6 +1485,13 @@ pkt->popLabel(); } +void +MemCtrl::MemoryPort::recvMemBackdoorReq(const MemBackdoorReq , +MemBackdoorPtr ) +{ +ctrl.recvMemBackdoorReq(req, backdoor); +} + Tick MemCtrl::MemoryPort::recvAtomic(PacketPtr pkt) { diff --git a/src/mem/mem_ctrl.hh b/src/mem/mem_ctrl.hh index fe5d478..2819fb4 100644 --- a/src/mem/mem_ctrl.hh +++ b/src/mem/mem_ctrl.hh @@ -267,6 +267,8 @@ PacketPtr pkt, MemBackdoorPtr ) override; void recvFunctional(PacketPtr pkt) override; +void
[gem5-dev] [S] Change in gem5/gem5[develop]: systemc: Enable DMI in the non-blocking/timing mode bridge.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/65754?usp=email ) Change subject: systemc: Enable DMI in the non-blocking/timing mode bridge. .. systemc: Enable DMI in the non-blocking/timing mode bridge. Change-Id: Ia618081e2dbf8b49f62480ac5dc29f87100cd4f1 --- M src/systemc/tlm_bridge/tlm_to_gem5.cc 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/systemc/tlm_bridge/tlm_to_gem5.cc b/src/systemc/tlm_bridge/tlm_to_gem5.cc index 468ea83..bb8d578 100644 --- a/src/systemc/tlm_bridge/tlm_to_gem5.cc +++ b/src/systemc/tlm_bridge/tlm_to_gem5.cc @@ -241,6 +241,29 @@ trans.acquire(); +MemBackdoor::Flags flags; +switch (trans.get_command()) { + case tlm::TLM_READ_COMMAND: +flags = MemBackdoor::Readable; +break; + case tlm::TLM_WRITE_COMMAND: +flags = MemBackdoor::Writeable; +break; + default: +panic("TlmToGem5Bridge: " +"received transaction with unsupported command"); +} +Addr start_addr = trans.get_address(); +Addr length = trans.get_data_length(); + +MemBackdoorReq req({start_addr, start_addr + length}, flags); +MemBackdoorPtr backdoor = nullptr; + +bmp.sendMemBackdoorReq(req, backdoor); + +if (backdoor) +trans.set_dmi_allowed(true); + auto res = payload2packet(_id, trans); auto pkt = res.first; pkt->pushSenderState(new Gem5SystemC::TlmSenderState(trans)); @@ -580,12 +603,12 @@ DPRINTF(TlmBridge, "register blocking interface"); socket.register_b_transport( this, ::b_transport); -socket.register_get_direct_mem_ptr( -this, ::get_direct_mem_ptr); } else { panic("gem5 operates neither in Timing nor in Atomic mode"); } +socket.register_get_direct_mem_ptr( +this, ::get_direct_mem_ptr); socket.register_transport_dbg( this, ::transport_dbg); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/65754?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia618081e2dbf8b49f62480ac5dc29f87100cd4f1 Gerrit-Change-Number: 65754 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org
[gem5-dev] [S] Change in gem5/gem5[develop]: stdlib: Add missing ()s in get_supported_isas.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58929 ) Change subject: stdlib: Add missing ()s in get_supported_isas. .. stdlib: Add missing ()s in get_supported_isas. A function was used directly instead of being called when interating through ISA names. Change-Id: I9dc53259a766a68070e0b79bb55f721a93fcdeed Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58929 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- M src/python/gem5/runtime.py 1 file changed, 17 insertions(+), 1 deletion(-) Approvals: Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/python/gem5/runtime.py b/src/python/gem5/runtime.py index 108dfc4..0984f6f 100644 --- a/src/python/gem5/runtime.py +++ b/src/python/gem5/runtime.py @@ -48,7 +48,7 @@ if "TARGET_ISA" in buildEnv.keys(): supported_isas.add(get_isa_from_str(buildEnv["TARGET_ISA"])) else: -for key in get_isas_str_set: +for key in get_isas_str_set(): if buildEnv[f"USE_{key.upper()}_ISA"]: supported_isas.add(get_isa_from_str(key)) return supported_isas -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58929 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I9dc53259a766a68070e0b79bb55f721a93fcdeed Gerrit-Change-Number: 58929 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bobby Bruce Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jason Lowe-Power Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: stdlib: Add missing ()s in get_supported_isas.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58929 ) Change subject: stdlib: Add missing ()s in get_supported_isas. .. stdlib: Add missing ()s in get_supported_isas. A function was used directly instead of being called when interating through ISA names. Change-Id: I9dc53259a766a68070e0b79bb55f721a93fcdeed --- M src/python/gem5/runtime.py 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/python/gem5/runtime.py b/src/python/gem5/runtime.py index 108dfc4..0984f6f 100644 --- a/src/python/gem5/runtime.py +++ b/src/python/gem5/runtime.py @@ -48,7 +48,7 @@ if "TARGET_ISA" in buildEnv.keys(): supported_isas.add(get_isa_from_str(buildEnv["TARGET_ISA"])) else: -for key in get_isas_str_set: +for key in get_isas_str_set(): if buildEnv[f"USE_{key.upper()}_ISA"]: supported_isas.add(get_isa_from_str(key)) return supported_isas -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58929 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I9dc53259a766a68070e0b79bb55f721a93fcdeed Gerrit-Change-Number: 58929 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Remove old support for building with a batch processor.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58891 ) Change subject: scons: Remove old support for building with a batch processor. .. scons: Remove old support for building with a batch processor. Other systems like distcc and ccache exist for this purpose. The SCons CacheDir mechanism relies on multiple developers having read/write access to a central caching directory, and for them to use each other's build output. I expect there is only a relatively narrow window where that would be useful, where there are multiple developers working on a very similar version of gem5, and where security considerations would still allow them to build in mostly unvalidated intermediate build products supplied by other developers. Change-Id: I45dc31b68c68906401fb1cd9e9ed658f2ba1dd6c --- M SConstruct M src/Kconfig 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/SConstruct b/SConstruct index 87a8b3e..6900d2f 100755 --- a/SConstruct +++ b/SConstruct @@ -828,20 +828,6 @@ kconfig.update_env(env, kconfig_file.abspath, config_file.abspath) -# Do this after we save setting back, or else we'll tack on an -# extra 'qdo' every time we run scons. -if env['CONF']['BATCH']: -env['CC'] = env['CONF']['BATCH_CMD'] + ' ' + env['CC'] -env['CXX']= env['CONF']['BATCH_CMD'] + ' ' + env['CXX'] -env['AS'] = env['CONF']['BATCH_CMD'] + ' ' + env['AS'] -env['AR'] = env['CONF']['BATCH_CMD'] + ' ' + env['AR'] -env['RANLIB'] = env['CONF']['BATCH_CMD'] + ' ' + env['RANLIB'] - -# Cache build files in the supplied directory. -if env['CONF']['M5_BUILD_CACHE']: -print('Using build cache located at', env['CONF']['M5_BUILD_CACHE']) -CacheDir(env['CONF']['M5_BUILD_CACHE']) - env.Append(CCFLAGS='$CCFLAGS_EXTRA') env.Append(LINKFLAGS='$LINKFLAGS_EXTRA') diff --git a/src/Kconfig b/src/Kconfig index fff5ea3..67089ea 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -25,19 +25,6 @@ mainmenu "$(MAIN_MENU_TEXT)" -config BATCH -bool "Use batch pool for build and test" -default n - -config BATCH_CMD -string "Batch pool submission command name" -default "qdo" -depends on BATCH - -config M5_BUILD_CACHE -string "Cache built objects in this directory" -default "" - config USE_EFENCE bool "Link with Electric Fence malloc debugger" default n -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58891 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I45dc31b68c68906401fb1cd9e9ed658f2ba1dd6c Gerrit-Change-Number: 58891 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Ensure the fast model license count is always at least 1.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58490 ) Change subject: scons: Ensure the fast model license count is always at least 1. .. scons: Ensure the fast model license count is always at least 1. Even though the default value for the license count is 1, it seems that if fast model is disabled, kconfig will set it to 0. When creating a cycle using itertools over a list with zero elements, it will raise a StopIteration. Even though we don't actually try to build any fast model components in that case, we do still set them up with a license slot. If the cycle iterator is essentially broken, that will prevent that from working and break the build. This change forces the license count to be at least 1, even if fast model is disabled and the license count may be set to 0 in the config. Change-Id: Ia8df256a8f292deb6fb6fa3c5f9a7d58c2b7f782 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58490 Reviewed-by: Andreas Sandberg Maintainer: Gabe Black Tested-by: kokoro --- M src/arch/arm/fastmodel/SConscript 1 file changed, 30 insertions(+), 1 deletion(-) Approvals: Andreas Sandberg: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index 23ddb84..b8ee987 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -268,7 +268,10 @@ t[0] = t[1] -license_count = int(env['CONF']['ARMLMD_LICENSE_COUNT']) +# If fast model is disabled, ARMLMD_LICENSE_COUNT will be 0 which will break +# the cycle() iterator below. The fast model components won't be built, but +# they still need to be set up successfully with valid license slots. +license_count = max(int(env['CONF']['ARMLMD_LICENSE_COUNT']), 1) arm_licenses = list((Value(object()) for i in range(license_count))) license_cycle = cycle(arm_licenses) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58490 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia8df256a8f292deb6fb6fa3c5f9a7d58c2b7f782 Gerrit-Change-Number: 58490 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Andreas Sandberg Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Sudhanshu Jha Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-CC: Gabe Black Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [M] Change in gem5/gem5[develop]: arch: Eliminate the now unused read_code and write_code args.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/49743 ) ( 64 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: arch: Eliminate the now unused read_code and write_code args. .. arch: Eliminate the now unused read_code and write_code args. Also eliminate the buildReadCode and buildWriteCode methods. Change-Id: I27b1b87ab51a44b5d7280e29e22f38d97d968a65 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49743 Maintainer: Gabe Black Maintainer: Giacomo Travaglini Reviewed-by: Giacomo Travaglini Tested-by: kokoro --- M src/arch/isa_parser/operand_types.py 1 file changed, 17 insertions(+), 57 deletions(-) Approvals: Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/isa_parser/operand_types.py b/src/arch/isa_parser/operand_types.py index a9f5eab..897235a 100755 --- a/src/arch/isa_parser/operand_types.py +++ b/src/arch/isa_parser/operand_types.py @@ -45,8 +45,7 @@ class OperandDesc(object): def __init__(self, base_cls, dflt_ext, reg_spec, flags=None, -sort_pri=None, read_code=None, write_code=None, -read_predicate=None, write_predicate=None): +sort_pri=None, read_predicate=None, write_predicate=None): from .isa_parser import makeList @@ -97,8 +96,6 @@ 'reg_spec': reg_spec, 'flags': flags, 'sort_pri': sort_pri, -'read_code': read_code, -'write_code': write_code, 'read_predicate': read_predicate, 'write_predicate': write_predicate, }) @@ -118,28 +115,6 @@ src_reg_constructor = '\n\tsetSrcRegIdx(_numSrcRegs++, %s);' dst_reg_constructor = '\n\tsetDestRegIdx(_numDestRegs++, %s);' -def buildReadCode(self, pred_read, op_idx): -subst_dict = {"name": self.base_name, - "reg_idx": self.reg_spec, - "ctype": self.ctype, - "op_idx": op_idx} -code = self.read_code % subst_dict -return f'{self.base_name} = {code};\n' - -def buildWriteCode(self, pred_write, op_idx): -subst_dict = {"name": self.base_name, - "reg_idx": self.reg_spec, - "ctype": self.ctype, - "final_val": self.base_name, - "op_idx": op_idx} -code = self.write_code % subst_dict -return f''' -{{ -{self.ctype} final_val = {self.base_name}; -{code}; -if (traceData) {{ traceData->setData(final_val); }} -}}''' - def regId(self): return f'RegId({self.reg_class}, {self.reg_spec})' @@ -260,9 +235,6 @@ class RegValOperand(RegOperand): def makeRead(self, pred_read, op_idx): -if self.read_code != None: -return self.buildReadCode(pred_read, op_idx) - reg_val = f'xc->getRegOperand(this, {op_idx})' if self.ctype == 'float': @@ -276,9 +248,6 @@ return f'{self.base_name} = {reg_val};\n' def makeWrite(self, pred_write, op_idx): -if self.write_code != None: -return self.buildWriteCode(pred_write, op_idx) - reg_val = self.base_name if self.ctype == 'float': @@ -363,8 +332,6 @@ return c_read def makeReadW(self, pred_write, op_idx): -assert(self.read_code == None) - c_readw = f'\t\tauto _d{op_idx} = \n' \ f'\t\t*({self.parser.namespace}::VecRegContainer *)\n' \ f'\t\txc->getWritableRegOperand(this, {op_idx});\n' @@ -395,9 +362,6 @@ return c_read def makeRead(self, pred_read, op_idx): -if self.read_code != None: -return self.buildReadCode(pred_read, op_idx) - name = self.base_name if self.is_dest and self.is_src: name += '_merger' @@ -420,9 +384,6 @@ return c_read def makeWrite(self, pred_write, op_idx): -if self.write_code != None: -return self.buildWriteCode(pred_write, op_idx) - return f''' if (traceData) {{ traceData->setData(tmp_d{op_idx}); @@ -446,9 +407,6 @@ return '' def makeRead(self, pred_read, op_idx): -if self.read_code != None: -return self.buildReadCode(pred_read, op_idx) - c_read = f'\t\t{self.parser.namespace}::VecPredRegContainer ' \ f'\t\ttmp_s{op_idx}; ' \ f'xc->getRegOperand(this, {op_idx}, _s{op_idx});\n' @@ -459,8 +417,6 @@ return c_read def makeReadW(self, pred_write, op_idx): -assert(self.read_code == None) - c_readw = f'\t\tauto _d{op_idx} = \n' \
[gem5-dev] [S] Change in gem5/gem5[develop]: arch-x86: Override make(Read|Write) instead of (read|write)_code.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/49741 ) Change subject: arch-x86: Override make(Read|Write) instead of (read| write)_code. .. arch-x86: Override make(Read|Write) instead of (read|write)_code. Change-Id: Iab077f58e19aa6bfeed555caa31a4c8b3d261059 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49741 Tested-by: kokoro Reviewed-by: Gabe Black Maintainer: Gabe Black --- M src/arch/x86/isa/operands.isa 1 file changed, 31 insertions(+), 9 deletions(-) Approvals: Gabe Black: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 2eaab4b..afbb8a0 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -55,20 +55,29 @@ let {{ class IntReg(IntRegOp): -def __init__(self, idx, id, *args, **kwargs): +def __init__(self, idx, id, data_size='dataSize', *args, **kwargs): super().__init__('uqw', idx, 'IsInteger', id, *args, **kwargs) +self.attrs['data_size'] = data_size class PickedReg(IntReg): -def __init__(self, idx, id, size='dataSize'): -super().__init__(idx, id, -read_code='pick(xc->getRegOperand(this, %(op_idx)s), ' - '%(reg_idx)s, ' + size + ')') +@overrideInOperand +def makeRead(self, predRead, op_idx): +return f'{self.base_name} = pick(xc->getRegOperand(' \ +f'this, {op_idx}), {self.reg_spec}, ' \ +f'{self.data_size});\n' + +def __init__(self, idx, id, data_size='dataSize'): +super().__init__(idx, id, data_size) class SignedPickedReg(IntReg): -def __init__(self, idx, id, size='dataSize'): -super().__init__(idx, id, -read_code='signedPick(xc->getRegOperand(this, ' -'%(op_idx)s), %(reg_idx)s, ' + size + ')') +@overrideInOperand +def makeRead(self, predRead, op_idx): +return f'{self.base_name} = signedPick(xc->getRegOperand(' \ +f'this, {op_idx}), {self.reg_spec}, ' \ +f'{self.data_size});\n' + +def __init__(self, idx, id, data_size='dataSize'): +super().__init__(idx, id, data_size) class FloatReg(FloatRegOp): def __init__(self, idx, id): -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49741 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Iab077f58e19aa6bfeed555caa31a4c8b3d261059 Gerrit-Change-Number: 49741 Gerrit-PatchSet: 67 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bradford Beckmann Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Matt Sinclair Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [M] Change in gem5/gem5[develop]: misc: Add KCONFIG.md file which talks about Kconfig files.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58634 ) ( 2 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: misc: Add KCONFIG.md file which talks about Kconfig files. .. misc: Add KCONFIG.md file which talks about Kconfig files. There are some minor aspects about how Kconfig files are used in gem5 which are a little different from how they are documented online or are used in other projects. Document that in this file. Change-Id: Ib981d1e265cf466d453071b33820d6baa24e17d4 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58634 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- A KCONFIG.md 1 file changed, 131 insertions(+), 0 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/KCONFIG.md b/KCONFIG.md new file mode 100644 index 000..9292539 --- /dev/null +++ b/KCONFIG.md @@ -0,0 +1,114 @@ +This file explains how to work with gem5's implementation of the kconfig +configuration system, very similar to what's used by the linux kernel. It talks +about how to work with the Kconfig files themselves which define what user +adjustable configuration parameters there are, and how they work and +interoperate. + +This file does *not*: + + * Describe how kconfig works generally. This is well documented elsewhere, for +instance [here]( +https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html): + * The settings in gem5's kconfig files. These should be documented with help + text within the kconfig files, and in the code where these options are + consumed. + * The various tools which can manipulate a given configuration. These are + documented in gem5's SCons help text. + +# kconfiglib + +gem5 uses the kconfiglib python library for consuming and manipulating kconfig +configurations. It is very similar to the kconfig implementation used by the +linux kernel, but is slightly different and has some small extensions added to +it. Almost all kconfig documentation written for the kernel's implementation +should apply here as well, but it may occasionally be necessary to refer to the +kconfiglib documentation. + +Also, because gem5's build system is more modular than kconfig's design +supports out of the box, particularly for "choice" blocks, we have extended +kconfiglib and added a "cont_choice" keyword. This keyword is very similar to +"choice", except "cont_choice" blocks can be re-opened and extended with more +options further into the config. + +This can be used to set up a central point where the user can choose between +mutually exclusive options, and still allow new Kconfig files to add new +options without modifying the original source. + +Having to choose between mutually exclusive options should be avoided in +general, but is unavoidable in a few key places in gem5 at the moment. Once +those areas have been addressed, this keyword may be removed in the future. + +# The 'CONF' dict in the SCons environment + +In "env" SCons environment in SConscript files, or the "main" environment in +SConsopts files, can hold many variables which help SCons operate generally, +like setting what include paths to use, what the compiler command line is, etc. +These environments each have a 'CONF' sub-dict which holds all the variables +which are actually used to configure gem5, and not to configure SCons and the +build process itself. + +All variables in this dict are automatically available to include in c++. To +access the value of env['CONF']['FOO'], you would #include "config/foo.hh". +Because these variables are in a shared namespace, their names should be unique +and distinctive. + +These values are available in config scripts through the m5.defines.buildEnv +dict. + +# Automatic/measured configuration values. + +Some configuration values are not set by the user, and are measured from the +host environment. These could reflect the availability of a header file, +library or tool, whether the compiler supports a particular option or language +feature, etc. + +These values should be measured in SConsopts files, and stored in the 'CONF' +dict described above. Like any other variable in 'CONF', they are then +available to C++ through generated header files, to config scripts through +buildEnv, etc. They are also available in the kconfig files themselves through +a mechanism discussed below. + +# Accessing 'CONF' values in Kconfig files. + +When the gem5 Kconfig files are processed to either manipulate a configuration +through a tool, or to apply a configuration to the gem5 build, all the values +in 'CONF' are temporarily put into environment variables. In the Kconfig files +themselves, these
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Use the 'png' tag for the PNG library.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58709 ) Change subject: scons: Use the 'png' tag for the PNG library. .. scons: Use the 'png' tag for the PNG library. Use that instead of checking HAVE_PNG manually. Change-Id: I70876982c2506bee1173341fa100f5fae2ae4302 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58709 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Reviewed-by: Giacomo Travaglini Tested-by: kokoro --- M src/base/SConscript 1 file changed, 17 insertions(+), 2 deletions(-) Approvals: Giacomo Travaglini: Looks good to me, approved Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/base/SConscript b/src/base/SConscript index 99d4bee..1d40d79 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -43,8 +43,7 @@ Source('debug.cc', add_tags=['gem5 trace', 'gem5 events']) GTest('debug.test', 'debug.test.cc', 'debug.cc') Source('fenv.cc', tags='fenv') -if env['CONF']['HAVE_PNG']: -SourceLib('png') +SourceLib('png', tags='png') Source('pngwriter.cc', tags='png') Source('fiber.cc') GTest('fiber.test', 'fiber.test.cc', 'fiber.cc') -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58709 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I70876982c2506bee1173341fa100f5fae2ae4302 Gerrit-Change-Number: 58709 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-CC: Earl Ou Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Use the 'png' tag for the PNG library.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58709 ) Change subject: scons: Use the 'png' tag for the PNG library. .. scons: Use the 'png' tag for the PNG library. Use that instead of checking HAVE_PNG manually. Change-Id: I70876982c2506bee1173341fa100f5fae2ae4302 --- M src/base/SConscript 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/base/SConscript b/src/base/SConscript index 99d4bee..1d40d79 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -43,8 +43,7 @@ Source('debug.cc', add_tags=['gem5 trace', 'gem5 events']) GTest('debug.test', 'debug.test.cc', 'debug.cc') Source('fenv.cc', tags='fenv') -if env['CONF']['HAVE_PNG']: -SourceLib('png') +SourceLib('png', tags='png') Source('pngwriter.cc', tags='png') Source('fiber.cc') GTest('fiber.test', 'fiber.test.cc', 'fiber.cc') -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58709 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I70876982c2506bee1173341fa100f5fae2ae4302 Gerrit-Change-Number: 58709 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58633 ) Change subject: scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1. .. scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1. Ensure that SCons.Subst.Literal can be hashed. https: //pairlist2.pair.net/pipermail/scons-dev/2018-October/004766.html Change-Id: I5221b63a5fd63189eb690c77e780805dc6d68125 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58633 Maintainer: Gabe Black Reviewed-by: Bobby Bruce Maintainer: Bobby Bruce Tested-by: kokoro --- M SConstruct 1 file changed, 25 insertions(+), 0 deletions(-) Approvals: Bobby Bruce: Looks good to me, approved; Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/SConstruct b/SConstruct index b170cf4..cf130c1 100755 --- a/SConstruct +++ b/SConstruct @@ -94,6 +94,14 @@ import SCons.Node.FS import SCons.Tool +if getattr(SCons, '__version__', None) in ('3.0.0', '3.0.1'): +# Monkey patch a fix which appears in version 3.0.2, since we only +# require version 3.0.0 +def __hash__(self): +return hash(self.lstr) +import SCons.Subst +SCons.Subst.Literal.__hash__ = __hash__ + # -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58633 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I5221b63a5fd63189eb690c77e780805dc6d68125 Gerrit-Change-Number: 58633 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bobby Bruce Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [M] Change in gem5/gem5[develop]: misc: Add KCONFIG.md file which talks about Kconfig files.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58634 ) Change subject: misc: Add KCONFIG.md file which talks about Kconfig files. .. misc: Add KCONFIG.md file which talks about Kconfig files. There are some minor aspects about how Kconfig files are used in gem5 which are a little different from how they are documented online or are used in other projects. Document that in this file. Change-Id: Ib981d1e265cf466d453071b33820d6baa24e17d4 --- A KCONFIG.md 1 file changed, 124 insertions(+), 0 deletions(-) diff --git a/KCONFIG.md b/KCONFIG.md new file mode 100644 index 000..ccbe448 --- /dev/null +++ b/KCONFIG.md @@ -0,0 +1,111 @@ +This file explains how to work with gem5's implementation of the kconfig +configuration system, very similar to what's used by the linux kernel. It talks +about how to work with the Kconfig files themselves which define what user +adjustable configuration parameters there are, and how they work and +interoperate. + +This file does *not*: + * Describe how kconfig works generally. This is well documented elsewhere. + * The settings in gem5's kconfig files. These should be documented with help + text within the kconfig files, and in the code where these options are + consumed. + * The various tools which can manipulate a given configuration. These are + documented in gem5's SCons help text. + +# kconfiglib + +gem5 uses the kconfiglib python library for consuming and manipulating kconfig +configurations. It is very similar to the kconfig implementation used by the +linux kernel, but is slightly different and has some small extensions added to +it. Almost all kconfig documentation written for the kernel's implementation +should apply here as well, but it may occasionally be necessary to refer to the +kconfiglib documentation. + +Also, because gem5's build system is more modular than kconfig's design +supports out of the box, particularly for "choice" blocks, we have extended +kconfiglib and added a "cont_choice" keyword. This keyword is very similar to +"choice", except "cont_choice" blocks can be re-opened and extended with more +options further into the config. + +This can be used to set up a central point where the user can choose between +mutually exclusive options, and still allow new Kconfig files to add new +options without modifying the original source. + +Having to choose between mutually exclusive options should be avoided in +general, but is unavoidable in a few key places in gem5 at the moment. Once +those areas have been addressed, this keyword may be removed in the future. + +# The 'CONF' dict in the SCons environment + +In "env" SCons environment in SConscript files, or the "main" environment in +SConsopts files, can hold many variables which help SCons operate generally, +like setting what include paths to use, what the compiler command line is, etc. +These environments each have a 'CONF' sub-dict which holds all the variables +which are actually used to configure gem5, and not to configure SCons and the +build process itself. + +All variables in this dict are automatically available to include in c++. To +access the value of env['CONF']['FOO'], you would #include "config/foo.hh". +Because these variables are in a shared namespace, their names should be unique +and distinctive. + +These values are available in config scripts through the m5.defines.buildEnv +dict. + +# Automatic/measured configuration values. + +Some configuration values are not set by the user, and are measured from the +host environment. These could reflect the availability of a header file, +library or tool, whether the compiler supports a particular option or language +feature, etc. + +These values should be measured in SConsopts files, and stored in the 'CONF' +dict described above. Like any other variable in 'CONF', they are then +available to C++ through generated header files, to config scripts through +buildEnv, etc. They are also available in the kconfig files themselves through +a mechanism discussed below. + +# Accessing 'CONF' values in Kconfig files. + +When the gem5 Kconfig files are processed to either manipulate a configuration +through a tool, or to apply a configuration to the gem5 build, all the values +in 'CONF' are temporarily put into environment variables. In the Kconfig files +themselves, these environment variables can be accessed using $(FOO) syntax, +which is described in kconfiglib's documentation. + +Note that this is slightly different from the kernel's Kconfig syntax, where +the environment variables would have to be imported in using other keywords +first. + +This is generally used to make automatic/measured settings which were +determined in SConsopts files available in Kconfig files. They can then be used +to compute dependencies, or to set default values, etc.
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58633 ) Change subject: scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1. .. scons: Monkey patch a fix from 3.0.2 into 3.0.0 and 3.0.1. Ensure that SCons.Subst.Literal can be hashed. https: //pairlist2.pair.net/pipermail/scons-dev/2018-October/004766.html Change-Id: I5221b63a5fd63189eb690c77e780805dc6d68125 --- M SConstruct 1 file changed, 20 insertions(+), 0 deletions(-) diff --git a/SConstruct b/SConstruct index b170cf4..cf130c1 100755 --- a/SConstruct +++ b/SConstruct @@ -94,6 +94,14 @@ import SCons.Node.FS import SCons.Tool +if getattr(SCons, '__version__', None) in ('3.0.0', '3.0.1'): +# Monkey patch a fix which appears in version 3.0.2, since we only +# require version 3.0.0 +def __hash__(self): +return hash(self.lstr) +import SCons.Subst +SCons.Subst.Literal.__hash__ = __hash__ + # -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58633 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I5221b63a5fd63189eb690c77e780805dc6d68125 Gerrit-Change-Number: 58633 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] [S] Change in gem5/gem5[develop]: scons: Increase the minimum version of SCons to 3.0.2.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58629 ) Change subject: scons: Increase the minimum version of SCons to 3.0.2. .. scons: Increase the minimum version of SCons to 3.0.2. This includes a fix for hashing the Literal type, which causes issues on python 3 within the fast model SConscript. The old requirement was 3.0.0. It looks like there are bug fix versions up to 3.0.5, although we don't yet have a specific reason to require those since we haven't run into the bugs fixed in those versions (yet). Change-Id: I429ed889791fa581693ad2dc5b597ba27b7690fc --- M site_scons/site_init.py 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 5eeb290..7b96fb1 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -42,7 +42,7 @@ # Check for recent-enough Python and SCons versions. try: -EnsureSConsVersion(3, 0, 0) +EnsureSConsVersion(3, 0, 2) except SystemExit as e: print(""" For more details, see: -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58629 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I429ed889791fa581693ad2dc5b597ba27b7690fc Gerrit-Change-Number: 58629 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Ensure the fast model license count is always at least 1.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58490 ) Change subject: scons: Ensure the fast model license count is always at least 1. .. scons: Ensure the fast model license count is always at least 1. Even though the default value for the license count is 1, it seems that if fast model is disabled, kconfig will set it to 0. When creating a cycle using itertools over a list with zero elements, it will raise a StopIteration. Even though we don't actually try to build any fast model components in that case, we do still set them up with a license slot. If the cycle iterator is essentially broken, that will prevent that from working and break the build. This change forces the license count to be at least 1, even if fast model is disabled and the license count may be set to 0 in the config. Change-Id: Ia8df256a8f292deb6fb6fa3c5f9a7d58c2b7f782 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index bfe7e97..b458d0f 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -268,7 +268,7 @@ t[0] = t[1] -license_count = int(env['CONF']['ARMLMD_LICENSE_COUNT']) +license_count = max(int(env['CONF']['ARMLMD_LICENSE_COUNT']), 1) arm_licenses = list((Value(object()) for i in range(license_count))) license_cycle = cycle(arm_licenses) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58490 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia8df256a8f292deb6fb6fa3c5f9a7d58c2b7f782 Gerrit-Change-Number: 58490 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-CC: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Only warn about not finding fast model libs if it's enabled.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58355 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: scons: Only warn about not finding fast model libs if it's enabled. .. scons: Only warn about not finding fast model libs if it's enabled. These warnings could be confusing and aren't useful if it's not. Change-Id: Ie660f639a3d8ee3406153ceb771b1ba5d0df9225 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58355 Reviewed-by: Yu-hsin Wang Maintainer: Gabe Black Tested-by: kokoro --- M src/arch/arm/fastmodel/SConscript 1 file changed, 17 insertions(+), 1 deletion(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index cfbe4b9..cded3cd 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -105,7 +105,8 @@ full_name = Dir(path).File(static_name).get_abspath() if os.path.isfile(full_name): return File(full_name) -warning("Failed to find FM static lib: " + name) +if env['CONF']['USE_ARM_FASTMODEL']: +warning("Failed to find FM static lib: " + name) return name # Adjust the build environment to support building in Fast Models. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58355 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie660f639a3d8ee3406153ceb771b1ba5d0df9225 Gerrit-Change-Number: 58355 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Add a tag for arm fastmodel and use it.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58356 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: scons: Add a tag for arm fastmodel and use it. .. scons: Add a tag for arm fastmodel and use it. This avoids some python logic in the SConscript files, and explicit references to the configuration system. Change-Id: If6ee61bb8c23606859e60323b8ca2c5254dbdecc Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58356 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/CortexA76/SConscript M src/arch/arm/fastmodel/CortexR52/SConscript M src/arch/arm/fastmodel/GIC/SConscript M src/arch/arm/fastmodel/PL330_DMAC/SConscript M src/arch/arm/fastmodel/SConscript M src/arch/arm/fastmodel/iris/SConscript M src/arch/arm/fastmodel/reset_controller/SConscript 7 files changed, 56 insertions(+), 53 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/CortexA76/SConscript b/src/arch/arm/fastmodel/CortexA76/SConscript index 7b18318..f3c6606 100644 --- a/src/arch/arm/fastmodel/CortexA76/SConscript +++ b/src/arch/arm/fastmodel/CortexA76/SConscript @@ -25,9 +25,6 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') for name in ('x1', 'x2', 'x3', 'x4'): @@ -39,7 +36,8 @@ SimObject('FastModelCortexA76.py', sim_objects=[ 'FastModelCortexA76', 'FastModelCortexA76Cluster'] + -[f'FastModelScxEvsCortexA76x{num}' for num in (1, 2, 3, 4)]) -Source('cortex_a76.cc') -Source('evs.cc') -Source('thread_context.cc') +[f'FastModelScxEvsCortexA76x{num}' for num in (1, 2, 3, 4)], +tags='arm fastmodel') +Source('cortex_a76.cc', tags='arm fastmodel') +Source('evs.cc', tags='arm fastmodel') +Source('thread_context.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/CortexR52/SConscript b/src/arch/arm/fastmodel/CortexR52/SConscript index a1d308b..bf3df74 100644 --- a/src/arch/arm/fastmodel/CortexR52/SConscript +++ b/src/arch/arm/fastmodel/CortexR52/SConscript @@ -25,9 +25,6 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') for name in ('x1', 'x2', 'x3', 'x4'): @@ -40,7 +37,8 @@ SimObject('FastModelCortexR52.py', sim_objects=[ 'FastModelCortexR52', 'FastModelCortexR52Cluster'] + -[f'FastModelScxEvsCortexR52x{num}' for num in (1, 2, 3, 4)]) -Source('cortex_r52.cc') -Source('evs.cc') -Source('thread_context.cc') +[f'FastModelScxEvsCortexR52x{num}' for num in (1, 2, 3, 4)], +tags='arm fastmodel') +Source('cortex_r52.cc', tags='arm fastmodel') +Source('evs.cc', tags='arm fastmodel') +Source('thread_context.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/GIC/SConscript b/src/arch/arm/fastmodel/GIC/SConscript index cff18e5..c56ddd5 100644 --- a/src/arch/arm/fastmodel/GIC/SConscript +++ b/src/arch/arm/fastmodel/GIC/SConscript @@ -25,13 +25,11 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') ArmFastModelComponent(File('GIC.sgproj'), File('GIC.lisa'), protocol_dir.File('SignalInterruptProtocol.lisa') ).prepare_env(env) -SimObject('FastModelGIC.py', sim_objects=['SCFastModelGIC', 'FastModelGIC']) -Source('gic.cc') +SimObject('FastModelGIC.py', sim_objects=['SCFastModelGIC', 'FastModelGIC'], +tags='arm fastmodel') +Source('gic.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/PL330_DMAC/SConscript b/src/arch/arm/fastmodel/PL330_DMAC/SConscript index 8527133..e93b45c 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/SConscript +++ b/src/arch/arm/fastmodel/PL330_DMAC/SConscript @@ -25,13 +25,11 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') ArmFastModelComponent(File('PL330.sgproj'), File('PL330.lisa'), protocol_dir.File('SignalInterruptProtocol.lisa') ).prepare_env(env) -SimObject('FastModelPL330.py', sim_objects=['FastModelPL330']) -Source('pl330.cc') +SimObject('FastModelPL330.py', sim_objects=['FastModelPL330'], +tags='arm fastmodel') +Source('pl330.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index cded3cd..bfe7e97 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -48,13 +48,11 @@ import os.path if env['CONF']['USE_ARM_FASTMODEL']: -if not env['CONF']['USE_SYSTEMC']: +if env['CONF']['USE_SYSTEMC']: +env.TagImplies('arm fastmodel', 'arm isa') +else:
[gem5-dev] Change in gem5/gem5[develop]: scons: Rework the fastmodel extract_var helper.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58354 ) Change subject: scons: Rework the fastmodel extract_var helper. .. scons: Rework the fastmodel extract_var helper. This helper extracts config variables and sets them up for use in fast model tools. Rework this function for two purposes. First, ensure that the ['CONF'] subdict is used consistently. It was used in one spot in that function, but not anywhere else. Avoid those mistakes by accessing the configuration dict only once, and then reusing the value. Second, only print the values of those variables if they aren't empty. That avoids extra log output for values which aren't set up and aren't being used, while still exposing those values if they are set up. This will print them even if they aren't being actively used, but are set up and could be with other changes in the config. Change-Id: Ia3ea76e6cb6b3347fd082112a1eaa8d594e06ca2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58354 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- M src/arch/arm/fastmodel/SConscript 1 file changed, 32 insertions(+), 5 deletions(-) Approvals: Gabe Black: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index 5c4bbf9..cfbe4b9 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -61,13 +61,15 @@ env['ENV']['SYSTEMC_HOME'] = systemc_home.abspath def extract_var(name): -if name not in env['CONF']: -error('Error: %s is not set' % name) -print('%s = %s' % (name, env[name])) +val = env['CONF'].get(name, None) +if val is None: +error(f'{name} is not set') +if env['CONF']['USE_ARM_FASTMODEL']: +print(f'{name} = {val}') # Make sure the value of this variable shows up as an environment variable # for commands scons runs. -env['ENV'][name] = env[name] -return env[name] +env['ENV'][name] = val +return val pvlib_home, maxcore_home, armlmd_license_file = \ list(map(extract_var, ('PVLIB_HOME', 'MAXCORE_HOME', -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58354 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia3ea76e6cb6b3347fd082112a1eaa8d594e06ca2 Gerrit-Change-Number: 58354 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Stop the fast model project file parser from writing files.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58353 ) Change subject: scons: Stop the fast model project file parser from writing files. .. scons: Stop the fast model project file parser from writing files. PLY tries to write these little files into the SCons installation directory, which it shouldn't even if it was allowed to. This avoids a bunch of annoying messages about not having enough permission. Change-Id: Ifd4eda9dd9f8518b3fd075e8a46de1b6c12c2127 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58353 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Jui-min Lee --- M SConstruct M src/arch/arm/fastmodel/SConscript 2 files changed, 35 insertions(+), 0 deletions(-) Approvals: Gabe Black: Looks good to me, approved; Looks good to me, approved Jui-min Lee: Looks good to me, approved kokoro: Regressions pass diff --git a/SConstruct b/SConstruct index 684cc8c..b170cf4 100755 --- a/SConstruct +++ b/SConstruct @@ -85,6 +85,9 @@ from os.path import isdir, isfile from os.path import join, split +import logging +logging.basicConfig() + # SCons imports import SCons import SCons.Node diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index a8734cd..5c4bbf9 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -36,6 +36,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from itertools import cycle +import logging import shlex Import('*') @@ -147,6 +148,19 @@ SourceLib('rt') class ProjectFileParser(Grammar): +def __init__(self): +self.log = logging.getLogger('fm_proj_ply') +if GetOption('verbose'): +self.log.setLevel(logging.DEBUG) + +self.yacc_kwargs['write_tables'] = False + +self.yacc_kwargs['debuglog'] = self.log +self.yacc_kwargs['errorlog'] = self.log + +self.lex_kwargs['debuglog'] = self.log +self.lex_kwargs['errorlog'] = self.log + class Param(object): def __init__(self, is_object): self.is_object = is_object -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58353 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ifd4eda9dd9f8518b3fd075e8a46de1b6c12c2127 Gerrit-Change-Number: 58353 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Tone down a fast model error into a warning.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58352 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: scons: Tone down a fast model error into a warning. .. scons: Tone down a fast model error into a warning. If a fast model static library can't be found, we should treat that as a warning instead of an error, and pass back the original library name so that it can at least be added and potentially come from somewhere else. In practice, this is important because gem5 will be configured by SCons indirectly in the future, using kconfig based tools that SCons runs on the user's behalf. If SCons is misconfigured or not configured, this error can trip, preventing those tools from starting. That creates a catch 22, since you'd need SCons to fix the config, and SCons can't run because of the config. We can avoid that problem by making SCons more lenient, so that it can still run even if it doesn't find static libraries where it might have expected to. Change-Id: Iadfd823b61fe96b937c2650250487d290492f265 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58352 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/SConscript 1 file changed, 31 insertions(+), 1 deletion(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index a7f6e17..a8734cd 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -102,7 +102,8 @@ full_name = Dir(path).File(static_name).get_abspath() if os.path.isfile(full_name): return File(full_name) -error("Failed to find FM static lib: " + name) +warning("Failed to find FM static lib: " + name) +return name # Adjust the build environment to support building in Fast Models. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58352 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Iadfd823b61fe96b937c2650250487d290492f265 Gerrit-Change-Number: 58352 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Earl Ou Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Add a priority field to the SourceLib construct.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58350 ) Change subject: scons: Add a priority field to the SourceLib construct. .. scons: Add a priority field to the SourceLib construct. This helps specify ordering for libraries that need it. Libraries with a higher priority will be sorted earlier in the list, which can be necessary when working with static libraries/archives. The default value for "priority" is zero. It's only really necessary to ensure relative ordering of particular pairings of libraries, so it should be ok to use an absolute integer value for this. If you need to order relative to a library, there is a good chance you're adding it, or the place it's added is well known and you can easily find its priority value. It's also unlikely that there would be a complex series of interactions between libraries that would make a more complicated system warranted. Change-Id: Ie94a35e6563c07f8d462a4a52d0173ea3cf4f8de Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58350 Maintainer: Gabe Black Reviewed-by: Jui-min Lee Tested-by: kokoro Reviewed-by: Yu-hsin Wang --- M src/SConscript 1 file changed, 32 insertions(+), 1 deletion(-) Approvals: Jui-min Lee: Looks good to me, but someone else must approve Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/SConscript b/src/SConscript index 746d3f1..a7b6cec 100644 --- a/src/SConscript +++ b/src/SConscript @@ -76,7 +76,9 @@ pass class SourceLib(SourceItem): -pass +def __init__(self, *args, **kwargs): +self.priority = kwargs.pop('priority', 0) +super().__init__(*args, **kwargs) build_tools = Dir('#build_tools') @@ -388,6 +390,8 @@ env['BUILDDIR'], self.path(env).dir.abspath) libs = self.libs(env) +# Higher priority libraries should be earlier in the list. +libs.sort(key=lambda l: l.priority, reverse=True) if libs: env.Append(LIBS=list(lib.source for lib in libs)) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58350 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie94a35e6563c07f8d462a4a52d0173ea3cf4f8de Gerrit-Change-Number: 58350 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Andreas Sandberg Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-CC: Gabe Black Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Get rid of an unused fast model variable.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58351 ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: scons: Get rid of an unused fast model variable. .. scons: Get rid of an unused fast model variable. This held the location of the license file, assuming it actually was a license file and not a license server URL. If this variable was unset because the fast model configuration parameters hadn't been set, then the "File" would resolve to the local directory, and SCons would get upset that you'd called the same path a directory and a file. We can avoid this problem by just getting rid of this variable, since it isn't used anyway. Change-Id: I2ccda90b85f2c83c73816967d145e6bf45733f89 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58351 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Tested-by: kokoro --- M src/arch/arm/fastmodel/SConscript 1 file changed, 22 insertions(+), 2 deletions(-) Approvals: Yu-hsin Wang: Looks good to me, approved Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index cbb2c15..a7f6e17 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -74,8 +74,6 @@ pvlib_home = Dir(pvlib_home) maxcore_home = Dir(maxcore_home) -armlmd_license_file = File(armlmd_license_file) - pvlib_flavor = env['CONF']['PVLIB_FLAVOR'] pvlib_lib_dir = pvlib_home.Dir('lib').Dir(pvlib_flavor) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58351 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I2ccda90b85f2c83c73816967d145e6bf45733f89 Gerrit-Change-Number: 58351 Gerrit-PatchSet: 3 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Jui-min Lee Gerrit-Reviewer: Yu-hsin Wang Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Remove an error check from the ProtoBuf declare-er.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/58349 ) Change subject: scons: Remove an error check from the ProtoBuf declare-er. .. scons: Remove an error check from the ProtoBuf declare-er. ProtoBuf files can (and should) be declared to SCons unconditionally, but then also use a "protobuf" tag. This lets SCons still include them conditionally when it gathers sources to build certain binaries without having additional python logic in SConscripts, or manually interpreting config state. Change-Id: I9426d647bc2d6c9d7eee7dadba77f75ed83bcaad Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58349 Maintainer: Giacomo Travaglini Reviewed-by: Jason Lowe-Power Reviewed-by: Bobby Bruce Tested-by: kokoro --- M src/SConscript 1 file changed, 20 insertions(+), 5 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved Bobby Bruce: Looks good to me, approved Giacomo Travaglini: Looks good to me, approved kokoro: Regressions pass diff --git a/src/SConscript b/src/SConscript index c1b00f0..d55520b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -259,11 +259,6 @@ def ProtoBuf(source, tags=None, add_tags=None): '''Add a Protocol Buffer to build''' - -if not env['HAVE_PROTOC'] or not env['CONF']['HAVE_PROTOBUF']: -error('Got protobuf to build, but lacks support!') - -'''Specify the source file, and any tags''' Source(source, tags, add_tags, append={'CXXFLAGS': '-Wno-array-bounds'}) env['PROTOC_GRPC'] = distutils.spawn.find_executable('grpc_cpp_plugin') -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58349 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I9426d647bc2d6c9d7eee7dadba77f75ed83bcaad Gerrit-Change-Number: 58349 Gerrit-PatchSet: 2 Gerrit-Owner: Gabe Black Gerrit-Reviewer: Bobby Bruce Gerrit-Reviewer: Gabe Black Gerrit-Reviewer: Giacomo Travaglini Gerrit-Reviewer: Jason Lowe-Power Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Stop the fast model project file parser from writing files.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58353 ) Change subject: scons: Stop the fast model project file parser from writing files. .. scons: Stop the fast model project file parser from writing files. PLY tries to write these little files into the SCons installation directory, which it shouldn't even if it was allowed to. This avoids a bunch of annoying messages about not having enough permission. Change-Id: Ifd4eda9dd9f8518b3fd075e8a46de1b6c12c2127 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 25 insertions(+), 0 deletions(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index a8734cd..884f970 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -36,6 +36,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from itertools import cycle +import logging import shlex Import('*') @@ -147,6 +148,17 @@ SourceLib('rt') class ProjectFileParser(Grammar): +def __init__(self): +self.log = logging.getLogger() + +self.yacc_kwargs['write_tables'] = False + +self.yacc_kwargs['debuglog'] = self.log +self.yacc_kwargs['errorlog'] = self.log + +self.lex_kwargs['debuglog'] = self.log +self.lex_kwargs['errorlog'] = self.log + class Param(object): def __init__(self, is_object): self.is_object = is_object -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58353 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ifd4eda9dd9f8518b3fd075e8a46de1b6c12c2127 Gerrit-Change-Number: 58353 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Add a tag for arm fastmodel and use it.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58356 ) Change subject: scons: Add a tag for arm fastmodel and use it. .. scons: Add a tag for arm fastmodel and use it. This avoids some python logic in the SConscript files, and explicit references to the configuration system. Change-Id: If6ee61bb8c23606859e60323b8ca2c5254dbdecc --- M src/arch/arm/fastmodel/CortexA76/SConscript M src/arch/arm/fastmodel/CortexR52/SConscript M src/arch/arm/fastmodel/GIC/SConscript M src/arch/arm/fastmodel/PL330_DMAC/SConscript M src/arch/arm/fastmodel/SConscript M src/arch/arm/fastmodel/iris/SConscript M src/arch/arm/fastmodel/reset_controller/SConscript 7 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/arch/arm/fastmodel/CortexA76/SConscript b/src/arch/arm/fastmodel/CortexA76/SConscript index 7b18318..f3c6606 100644 --- a/src/arch/arm/fastmodel/CortexA76/SConscript +++ b/src/arch/arm/fastmodel/CortexA76/SConscript @@ -25,9 +25,6 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') for name in ('x1', 'x2', 'x3', 'x4'): @@ -39,7 +36,8 @@ SimObject('FastModelCortexA76.py', sim_objects=[ 'FastModelCortexA76', 'FastModelCortexA76Cluster'] + -[f'FastModelScxEvsCortexA76x{num}' for num in (1, 2, 3, 4)]) -Source('cortex_a76.cc') -Source('evs.cc') -Source('thread_context.cc') +[f'FastModelScxEvsCortexA76x{num}' for num in (1, 2, 3, 4)], +tags='arm fastmodel') +Source('cortex_a76.cc', tags='arm fastmodel') +Source('evs.cc', tags='arm fastmodel') +Source('thread_context.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/CortexR52/SConscript b/src/arch/arm/fastmodel/CortexR52/SConscript index a1d308b..bf3df74 100644 --- a/src/arch/arm/fastmodel/CortexR52/SConscript +++ b/src/arch/arm/fastmodel/CortexR52/SConscript @@ -25,9 +25,6 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') for name in ('x1', 'x2', 'x3', 'x4'): @@ -40,7 +37,8 @@ SimObject('FastModelCortexR52.py', sim_objects=[ 'FastModelCortexR52', 'FastModelCortexR52Cluster'] + -[f'FastModelScxEvsCortexR52x{num}' for num in (1, 2, 3, 4)]) -Source('cortex_r52.cc') -Source('evs.cc') -Source('thread_context.cc') +[f'FastModelScxEvsCortexR52x{num}' for num in (1, 2, 3, 4)], +tags='arm fastmodel') +Source('cortex_r52.cc', tags='arm fastmodel') +Source('evs.cc', tags='arm fastmodel') +Source('thread_context.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/GIC/SConscript b/src/arch/arm/fastmodel/GIC/SConscript index cff18e5..c56ddd5 100644 --- a/src/arch/arm/fastmodel/GIC/SConscript +++ b/src/arch/arm/fastmodel/GIC/SConscript @@ -25,13 +25,11 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') ArmFastModelComponent(File('GIC.sgproj'), File('GIC.lisa'), protocol_dir.File('SignalInterruptProtocol.lisa') ).prepare_env(env) -SimObject('FastModelGIC.py', sim_objects=['SCFastModelGIC', 'FastModelGIC']) -Source('gic.cc') +SimObject('FastModelGIC.py', sim_objects=['SCFastModelGIC', 'FastModelGIC'], +tags='arm fastmodel') +Source('gic.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/PL330_DMAC/SConscript b/src/arch/arm/fastmodel/PL330_DMAC/SConscript index 8527133..e93b45c 100644 --- a/src/arch/arm/fastmodel/PL330_DMAC/SConscript +++ b/src/arch/arm/fastmodel/PL330_DMAC/SConscript @@ -25,13 +25,11 @@ Import('*') -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() - protocol_dir = Dir('..').Dir('protocol') ArmFastModelComponent(File('PL330.sgproj'), File('PL330.lisa'), protocol_dir.File('SignalInterruptProtocol.lisa') ).prepare_env(env) -SimObject('FastModelPL330.py', sim_objects=['FastModelPL330']) -Source('pl330.cc') +SimObject('FastModelPL330.py', sim_objects=['FastModelPL330'], +tags='arm fastmodel') +Source('pl330.cc', tags='arm fastmodel') diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index b176dbf..7f04e12 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -48,13 +48,11 @@ import os.path if env['CONF']['USE_ARM_FASTMODEL']: -if not env['CONF']['USE_SYSTEMC']: +if env['CONF']['USE_SYSTEMC']: +env.TagImplies('arm fastmodel', 'arm isa') +else: warning('ARM Fast Models require systemc support') env['CONF']['USE_ARM_FASTMODEL'] = False -Return() - -if not env['CONF']['USE_ARM_FASTMODEL']: -Return() systemc_home = Dir('#/src/systemc/ext/systemc_home') @@ -144,11 +142,11 @@ 'IrisSupport', ) for lib in fm_static_libs: -SourceLib(staticify(env, lib)) +SourceLib(staticify(env, lib), tags='arm
[gem5-dev] Change in gem5/gem5[develop]: scons: Get rid of an unused fast model variable.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58351 ) Change subject: scons: Get rid of an unused fast model variable. .. scons: Get rid of an unused fast model variable. This held the location of the license file, assuming it actually was a license file and not a license server URL. If this variable was unset because the fast model configuration parameters hadn't been set, then the "File" would resolve to the local directory, and SCons would get upset that you'd called the same path a directory and a file. We can avoid this problem by just getting rid of this variable, since it isn't used anyway. Change-Id: I2ccda90b85f2c83c73816967d145e6bf45733f89 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index cbb2c15..a7f6e17 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -74,8 +74,6 @@ pvlib_home = Dir(pvlib_home) maxcore_home = Dir(maxcore_home) -armlmd_license_file = File(armlmd_license_file) - pvlib_flavor = env['CONF']['PVLIB_FLAVOR'] pvlib_lib_dir = pvlib_home.Dir('lib').Dir(pvlib_flavor) -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58351 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I2ccda90b85f2c83c73816967d145e6bf45733f89 Gerrit-Change-Number: 58351 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Tone down a fast model error into a warning.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58352 ) Change subject: scons: Tone down a fast model error into a warning. .. scons: Tone down a fast model error into a warning. If a fast model static library can't be found, we should treat that as a warning instead of an error, and pass back the original library name so that it can at least be added and potentially come from somewhere else. In practice, this is important because gem5 will be configured by SCons indirectly in the future, using kconfig based tools that SCons runs on the user's behalf. If SCons is misconfigured or not configured, this error can trip, preventing those tools from starting. That creates a catch 22, since you'd need SCons to fix the config, and SCons can't run because of the config. We can avoid that problem by making SCons more lenient, so that it can still run even if it doesn't find static libraries where it might have expected to. Change-Id: Iadfd823b61fe96b937c2650250487d290492f265 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index a7f6e17..a8734cd 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -102,7 +102,8 @@ full_name = Dir(path).File(static_name).get_abspath() if os.path.isfile(full_name): return File(full_name) -error("Failed to find FM static lib: " + name) +warning("Failed to find FM static lib: " + name) +return name # Adjust the build environment to support building in Fast Models. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58352 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Iadfd823b61fe96b937c2650250487d290492f265 Gerrit-Change-Number: 58352 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Only warn about not finding fast model libs if it's enabled.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58355 ) Change subject: scons: Only warn about not finding fast model libs if it's enabled. .. scons: Only warn about not finding fast model libs if it's enabled. These warnings could be confusing and aren't useful if it's not. Change-Id: Ie660f639a3d8ee3406153ceb771b1ba5d0df9225 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index 5226a78..b176dbf 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -105,7 +105,8 @@ full_name = Dir(path).File(static_name).get_abspath() if os.path.isfile(full_name): return File(full_name) -warning("Failed to find FM static lib: " + name) +if env['CONF']['USE_ARM_FASTMODEL']: +warning("Failed to find FM static lib: " + name) return name # Adjust the build environment to support building in Fast Models. -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58355 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie660f639a3d8ee3406153ceb771b1ba5d0df9225 Gerrit-Change-Number: 58355 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: scons: Rework the fastmodel extract_var helper.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/58354 ) Change subject: scons: Rework the fastmodel extract_var helper. .. scons: Rework the fastmodel extract_var helper. This helper extracts config variables and sets them up for use in fast model tools. Rework this function for two purposes. First, ensure that the ['CONF'] subdict is used consistently. It was used in one spot in that function, but not anywhere else. Avoid those mistakes by accessing the configuration dict only once, and then reusing the value. Second, only print the values of those variables if they aren't empty. That avoids extra log output for values which aren't set up and aren't being used, while still exposing those values if they are set up. This will print them even if they aren't being actively used, but are set up and could be with other changes in the config. Change-Id: Ia3ea76e6cb6b3347fd082112a1eaa8d594e06ca2 --- M src/arch/arm/fastmodel/SConscript 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/arch/arm/fastmodel/SConscript b/src/arch/arm/fastmodel/SConscript index 884f970..5226a78 100644 --- a/src/arch/arm/fastmodel/SConscript +++ b/src/arch/arm/fastmodel/SConscript @@ -61,13 +61,15 @@ env['ENV']['SYSTEMC_HOME'] = systemc_home.abspath def extract_var(name): -if name not in env['CONF']: -error('Error: %s is not set' % name) -print('%s = %s' % (name, env[name])) +val = env['CONF'].get(name, None) +if val is None: +error('%s is not set' % name) +if val: +print('%s = %s' % (name, env['CONF'][name])) # Make sure the value of this variable shows up as an environment variable # for commands scons runs. -env['ENV'][name] = env[name] -return env[name] +env['ENV'][name] = val +return val pvlib_home, maxcore_home, armlmd_license_file = \ list(map(extract_var, ('PVLIB_HOME', 'MAXCORE_HOME', -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/58354 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ia3ea76e6cb6b3347fd082112a1eaa8d594e06ca2 Gerrit-Change-Number: 58354 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black Gerrit-MessageType: newchange ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s