mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-13 13:37:02 +00:00
The core of the machine-type support is the new operations table, kvm_ops_t. This acts as a standard C-style virtual table decoupling the generic KVM core logic from target specific hardware emualtion. The kvm_t VM instance now points to an ops table, which defines the "personality" of the guest. A kvm_probe() factory function has been added to initialize a kvm_t instance with the correct ops table for a given machine type (eg, Switch 1). The ops table's .mmio_read and .mmio_write function pointers are the link between the armv8 CPU core and this new MMIO dispatcher. When a physical memory access is determined to be MMIO, the VM will call the appropriate function pointer, which in turn will use the MMIO dispatcher to find and execute the correct device handler. The initial implementation for the Switch 1 target (targets/switch1/hardware/probe.cpp) is a stub. The bootstrapping logic will be added in subsequent patches. Signed-off-by: Ronald Caesar <github43132@proton.me>
134 lines
3.3 KiB
C++
134 lines
3.3 KiB
C++
// Copyright 2025 Xenon Emulator Project. All rights reserved.
|
|
|
|
#include "PathUtil.h"
|
|
#include "common/Logging/Log.h"
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include <fstream>
|
|
#include <unordered_map>
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#endif // _WIN32
|
|
#ifdef __APPLE__
|
|
#include <libproc.h>
|
|
#include <unistd.h>
|
|
#endif // __APPLE__
|
|
|
|
namespace Base
|
|
{
|
|
namespace FS
|
|
{
|
|
|
|
const fs::path GetBinaryDirectory()
|
|
{
|
|
fs::path fspath = {};
|
|
#ifdef _WIN32
|
|
char path[256];
|
|
GetModuleFileNameA(nullptr, path, sizeof(path));
|
|
fspath = path;
|
|
#elif __linux__
|
|
fspath = fs::canonical("/proc/self/exe");
|
|
#elif __APPLE__
|
|
pid_t pid = getpid();
|
|
char path[PROC_PIDPATHINFO_MAXSIZE];
|
|
// While this is fine for a raw executable,
|
|
// an application bundle is read-only and these files
|
|
// should instead be placed in Application Support.
|
|
proc_pidpath(pid, path, sizeof(path));
|
|
fspath = path;
|
|
#else
|
|
// Unknown, just return rootdir
|
|
fspath = fs::current_path() / "Pound";
|
|
#endif
|
|
return fs::weakly_canonical(fmt::format("{}/..", fspath.string()));
|
|
}
|
|
|
|
static auto UserPaths = []
|
|
{
|
|
auto currentDir = fs::current_path();
|
|
auto binaryDir = GetBinaryDirectory();
|
|
bool nixos = false;
|
|
|
|
std::unordered_map<PathType, fs::path> paths;
|
|
|
|
const auto insert_path = [&](PathType pound_path, const fs::path& new_path, bool create = true)
|
|
{
|
|
if (create && !fs::exists(new_path))
|
|
fs::create_directory(new_path);
|
|
|
|
paths.insert_or_assign(pound_path, new_path);
|
|
};
|
|
|
|
insert_path(PathType::BinaryDir, binaryDir, false);
|
|
// If we are in the nix store, it's read-only. Change to currentDir if needed
|
|
if (binaryDir.string().find("/nix/store/") != std::string::npos)
|
|
{
|
|
nixos = true;
|
|
}
|
|
if (nixos)
|
|
{
|
|
currentDir /= "files";
|
|
insert_path(PathType::RootDir, currentDir);
|
|
insert_path(PathType::FirmwareDir, currentDir / FW_DIR);
|
|
insert_path(PathType::LogDir, currentDir / LOG_DIR);
|
|
}
|
|
else
|
|
{
|
|
insert_path(PathType::RootDir, currentDir, false);
|
|
insert_path(PathType::FirmwareDir, binaryDir / FW_DIR);
|
|
insert_path(PathType::LogDir, binaryDir / LOG_DIR);
|
|
}
|
|
return paths;
|
|
}();
|
|
|
|
std::string PathToUTF8String(const fs::path& path)
|
|
{
|
|
const auto u8_string = path.u8string();
|
|
return std::string{u8_string.begin(), u8_string.end()};
|
|
}
|
|
|
|
const fs::path& GetUserPath(PathType pound_path)
|
|
{
|
|
return UserPaths.at(pound_path);
|
|
}
|
|
|
|
std::string GetUserPathString(PathType pound_path)
|
|
{
|
|
return PathToUTF8String(GetUserPath(pound_path));
|
|
}
|
|
|
|
std::vector<FileInfo> ListFilesFromPath(const fs::path& path)
|
|
{
|
|
std::vector<FileInfo> fileList;
|
|
|
|
fs::path _path = fs::weakly_canonical(path);
|
|
|
|
for (auto& entry : fs::directory_iterator{_path})
|
|
{
|
|
FileInfo fileInfo;
|
|
if (entry.is_directory())
|
|
{
|
|
fileInfo.fileSize = 0;
|
|
fileInfo.fileType = FileType::Directory;
|
|
}
|
|
else
|
|
{
|
|
fileInfo.fileSize = fs::file_size(_path);
|
|
fileInfo.fileType = FileType::File;
|
|
}
|
|
|
|
fileInfo.filePath = entry.path();
|
|
fileInfo.fileName = entry.path().filename();
|
|
fileList.push_back(fileInfo);
|
|
}
|
|
|
|
return fileList;
|
|
}
|
|
|
|
void SetUserPath(PathType pound_path, const fs::path& new_path)
|
|
{
|
|
UserPaths.insert_or_assign(pound_path, new_path);
|
|
}
|
|
} // namespace FS
|
|
} // namespace Base
|