mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
Compare commits
4 commits
7099a71b06
...
00c55e9688
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00c55e9688 | ||
|
|
e514fa02ff | ||
|
|
c648a13d42 | ||
|
|
0fb7aeb9b4 |
3
.github/workflows/rpcsx.yml
vendored
3
.github/workflows/rpcsx.yml
vendored
|
|
@ -26,9 +26,6 @@ jobs:
|
|||
libsox-dev g++-14 ninja-build libasound2-dev nasm libudev-dev \
|
||||
libxcb1-dev libx11-dev libwayland-dev libxkbcommon-dev libxrandr-dev \
|
||||
libxinerama-dev libxcursor-dev libxi-dev libxext-dev
|
||||
cmake -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_INSTALL_PREFIX=/usr
|
||||
cmake --build build -j$(($(nproc) + 2))
|
||||
sudo cmake --build build
|
||||
|
||||
- name: Build RPCSX
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -141,6 +141,11 @@ option(WITHOUT_OPENGL "Disable OpenGL" OFF)
|
|||
option(WITHOUT_OPENGLEW "Disable OpenGLEW" OFF)
|
||||
option(WITHOUT_OPENAL "Disable OpenAL" OFF)
|
||||
option(COMPILE_FFMPEG "Compile FFmpeg" ON)
|
||||
option(USE_FS_GS_SYSCALL "Use the arch_prctl syscall to interact with fsbase and gsbase instead of x86 instructions. Used for compatibility with some systems, but comes at a performance cost." OFF)
|
||||
|
||||
if(USE_FS_GS_SYSCALL)
|
||||
add_definitions(-DUSE_FS_GS_SYSCALL)
|
||||
endif()
|
||||
|
||||
# rpcs3 options
|
||||
option(USE_NATIVE_INSTRUCTIONS "USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages." ON)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ template <int Group> struct IoDeviceWithIoctl : IoDevice {
|
|||
void addIoctl(ErrorCode (*handler)(Thread *thread, InstanceT *device,
|
||||
T &arg)) {
|
||||
constexpr auto id = ioctl::id(Cmd);
|
||||
assert(ioctlTable[id].handler == unhandledIoctl);
|
||||
assert(ioctlTable[id].handler == nullptr);
|
||||
|
||||
IoctlHandlerEntry &entry = ioctlTable[id];
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ template <int Group> struct IoDeviceWithIoctl : IoDevice {
|
|||
|
||||
void addIoctl(ErrorCode (*handler)(Thread *thread, InstanceT *device)) {
|
||||
constexpr auto id = ioctl::id(Cmd);
|
||||
assert(ioctlTable[id].handler == unhandledIoctl);
|
||||
assert(ioctlTable[id].handler == nullptr);
|
||||
|
||||
IoctlHandlerEntry &entry = ioctlTable[id];
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ template <int Group> struct IoDeviceWithIoctl : IoDevice {
|
|||
void addIoctl(std::pair<ErrorCode, T> (*handler)(Thread *thread,
|
||||
InstanceT *device)) {
|
||||
constexpr auto id = ioctl::id(Cmd);
|
||||
assert(ioctlTable[id].handler == unhandledIoctl);
|
||||
assert(ioctlTable[id].handler == nullptr);
|
||||
|
||||
IoctlHandlerEntry &entry = ioctlTable[id];
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ T *knew(Args &&...args) {
|
|||
struct DynamicObject final : T {
|
||||
using T::T;
|
||||
|
||||
void operator delete(void *pointer) { kfree(pointer, sizeof(T)); }
|
||||
void operator delete(void *pointer) {
|
||||
kfree(pointer, sizeof(DynamicObject));
|
||||
}
|
||||
};
|
||||
|
||||
auto loc = static_cast<DynamicObject *>(
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ void Cache::ShaderResources::loadResources(
|
|||
rx::die("failed to evaluate pointer");
|
||||
}
|
||||
|
||||
bufferMemoryTable.map(*pointerBase + *pointerOffset,
|
||||
*pointerBase + *pointerOffset + pointer.size,
|
||||
bufferMemoryTable.map(rx::AddressRange::fromBeginSize(
|
||||
*pointerBase + *pointerOffset, pointer.size),
|
||||
Access::Read);
|
||||
resourceSlotToAddress.emplace_back(slotOffset + pointer.resourceSlot,
|
||||
*pointerBase + *pointerOffset);
|
||||
|
|
@ -200,8 +200,9 @@ void Cache::ShaderResources::loadResources(
|
|||
it.beginAddress() == buffer.address() && it.size() == buffer.size()) {
|
||||
it.get() |= bufferRes.access;
|
||||
} else {
|
||||
bufferMemoryTable.map(buffer.address(), buffer.address() + buffer.size(),
|
||||
bufferRes.access);
|
||||
bufferMemoryTable.map(
|
||||
rx::AddressRange::fromBeginSize(buffer.address(), buffer.size()),
|
||||
bufferRes.access);
|
||||
}
|
||||
resourceSlotToAddress.emplace_back(slotOffset + bufferRes.resourceSlot,
|
||||
buffer.address());
|
||||
|
|
@ -262,7 +263,8 @@ void Cache::ShaderResources::loadResources(
|
|||
it.get().second |= imageBuffer.access;
|
||||
} else {
|
||||
imageMemoryTable.map(
|
||||
tbuffer.address(), tbuffer.address() + info.totalTiledSize,
|
||||
rx::AddressRange::fromBeginSize(tbuffer.address(),
|
||||
info.totalTiledSize),
|
||||
{ImageBufferKey::createFrom(tbuffer), imageBuffer.access});
|
||||
}
|
||||
resourceSlotToAddress.emplace_back(slotOffset + imageBuffer.resourceSlot,
|
||||
|
|
@ -1489,8 +1491,7 @@ Cache::Buffer Cache::Tag::getBuffer(rx::AddressRange range, Access access) {
|
|||
|
||||
mParent->flushBuffers(range);
|
||||
|
||||
it = table.map(range.beginAddress(), range.endAddress(), nullptr, false,
|
||||
true);
|
||||
it = table.map(range, nullptr, false, true);
|
||||
}
|
||||
|
||||
if (it.get() == nullptr) {
|
||||
|
|
@ -1837,8 +1838,7 @@ Cache::ImageBuffer Cache::Tag::getImageBuffer(const ImageBufferKey &key,
|
|||
flushed.clear();
|
||||
}
|
||||
|
||||
auto it =
|
||||
table.map(range.beginAddress(), range.endAddress(), nullptr, false, true);
|
||||
auto it = table.map(range, nullptr, false, true);
|
||||
|
||||
if (it.get() == nullptr) {
|
||||
auto cached = std::make_shared<CachedImageBuffer>();
|
||||
|
|
@ -1945,8 +1945,7 @@ Cache::Image Cache::Tag::getImage(const ImageKey &key, Access access) {
|
|||
flushed.clear();
|
||||
}
|
||||
|
||||
auto it = table.map(storeRange.beginAddress(), storeRange.endAddress(),
|
||||
nullptr, false, true);
|
||||
auto it = table.map(storeRange, nullptr, false, true);
|
||||
|
||||
if (it.get() == nullptr) {
|
||||
VkImageUsageFlags usage =
|
||||
|
|
@ -2787,15 +2786,13 @@ void Cache::flush(Tag &tag, rx::AddressRange range) {
|
|||
void Cache::trackUpdate(EntryType type, rx::AddressRange range,
|
||||
std::shared_ptr<Entry> entry, TagId tagId,
|
||||
bool watchChanges) {
|
||||
if (auto it = mSyncTable.map(range.beginAddress(), range.endAddress(), {},
|
||||
false, true);
|
||||
it.get() < tagId) {
|
||||
if (auto it = mSyncTable.map(range, {}, false, true); it.get() < tagId) {
|
||||
it.get() = tagId;
|
||||
}
|
||||
|
||||
entry->tagId = tagId;
|
||||
auto &table = getTable(type);
|
||||
table.map(range.beginAddress(), range.endAddress(), std::move(entry));
|
||||
table.map(range, std::move(entry));
|
||||
|
||||
if (watchChanges) {
|
||||
mDevice->watchWrites(mVmId, range.beginAddress(), range.size());
|
||||
|
|
@ -2803,9 +2800,7 @@ void Cache::trackUpdate(EntryType type, rx::AddressRange range,
|
|||
}
|
||||
|
||||
void Cache::trackWrite(rx::AddressRange range, TagId tagId, bool lockMemory) {
|
||||
if (auto it = mSyncTable.map(range.beginAddress(), range.endAddress(), {},
|
||||
false, true);
|
||||
it.get() < tagId) {
|
||||
if (auto it = mSyncTable.map(range, {}, false, true); it.get() < tagId) {
|
||||
it.get() = tagId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -641,7 +641,7 @@ void Device::protectMemory(std::uint32_t pid, std::uint64_t address,
|
|||
|
||||
auto vmSlot = vmSlotIt.get();
|
||||
|
||||
process.vmTable.map(address, address + size,
|
||||
process.vmTable.map(rx::AddressRange::fromBeginSize(address, size),
|
||||
VmMapSlot{
|
||||
.memoryType = vmSlot.memoryType,
|
||||
.prot = static_cast<int>(prot),
|
||||
|
|
@ -1004,7 +1004,7 @@ void Device::mapMemory(std::uint32_t pid, std::uint64_t address,
|
|||
int prot, std::int64_t offset) {
|
||||
auto &process = processInfo[pid];
|
||||
|
||||
process.vmTable.map(address, address + size,
|
||||
process.vmTable.map(rx::AddressRange::fromBeginSize(address, size),
|
||||
VmMapSlot{
|
||||
.memoryType = memoryType >= 0 ? dmemIndex : -1,
|
||||
.prot = prot,
|
||||
|
|
|
|||
|
|
@ -1832,7 +1832,8 @@ gcn::deserialize(gcn::Context &context, const gcn::Environment &environment,
|
|||
std::function<std::uint32_t(std::uint64_t)> readMemory) {
|
||||
readMemory = [&context,
|
||||
readMemory = std::move(readMemory)](std::uint64_t address) {
|
||||
context.memoryMap.map(address, address + sizeof(std::uint32_t));
|
||||
context.memoryMap.map(
|
||||
rx::AddressRange::fromBeginSize(address, sizeof(std::uint32_t)));
|
||||
return readMemory(address);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ public:
|
|||
auto properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
mMemory = DeviceMemory::CreateExternalHostMemory(data, size, properties);
|
||||
table.map(0, size);
|
||||
table.map(rx::AddressRange::fromBeginSize(0, size));
|
||||
// debugName = "direct";
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +337,7 @@ public:
|
|||
vkMapMemory(context->device, memory.getHandle(), 0, size, 0, &data));
|
||||
|
||||
mMemory = std::move(memory);
|
||||
table.map(0, size);
|
||||
table.map(rx::AddressRange::fromBeginSize(0, size));
|
||||
mData = reinterpret_cast<char *>(data);
|
||||
// debugName = "host";
|
||||
}
|
||||
|
|
@ -347,7 +347,7 @@ public:
|
|||
auto properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
mMemory = DeviceMemory::Allocate(size, ~0, properties);
|
||||
table.map(0, size);
|
||||
table.map(rx::AddressRange::fromBeginSize(0, size));
|
||||
// debugName = "local";
|
||||
}
|
||||
|
||||
|
|
@ -397,7 +397,7 @@ public:
|
|||
|
||||
void deallocate(DeviceMemoryRef memory) {
|
||||
std::lock_guard lock(mMtx);
|
||||
table.map(memory.offset, memory.offset + memory.size);
|
||||
table.map(rx::AddressRange::fromBeginSize(memory.offset, memory.size));
|
||||
}
|
||||
|
||||
void dump() {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static orbis::ErrorCode blockpool_ioctl(orbis::File *file,
|
|||
ORBIS_RET_ON_ERROR(
|
||||
dmem->allocate(&start, args->searchEnd, args->len, 1, args->flags));
|
||||
|
||||
blockPool->pool.map(start, start + args->len);
|
||||
blockPool->pool.map(rx::AddressRange::fromBeginSize(start, args->len));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,8 +144,9 @@ static orbis::ErrorCode dmem_ioctl(orbis::File *file, std::uint64_t request,
|
|||
ORBIS_LOG_WARNING("dmem releaseDirectMemory", device->index, args->address,
|
||||
args->size);
|
||||
|
||||
device->allocations.map(args->address, args->address + args->size,
|
||||
{.memoryType = -1u});
|
||||
device->allocations.map(
|
||||
rx::AddressRange::fromBeginSize(args->address, args->size),
|
||||
{.memoryType = -1u});
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
@ -303,7 +304,7 @@ orbis::ErrorCode DmemDevice::allocate(std::uint64_t *start,
|
|||
}
|
||||
}
|
||||
|
||||
allocations.map(offset, offset + len,
|
||||
allocations.map(rx::AddressRange::fromBeginSize(offset, len),
|
||||
{
|
||||
.memoryType = memoryType,
|
||||
});
|
||||
|
|
@ -319,7 +320,7 @@ orbis::ErrorCode DmemDevice::allocate(std::uint64_t *start,
|
|||
}
|
||||
|
||||
orbis::ErrorCode DmemDevice::release(std::uint64_t start, std::uint64_t size) {
|
||||
allocations.unmap(start, start + size);
|
||||
allocations.unmap(rx::AddressRange::fromBeginSize(start, size));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,9 +39,16 @@ static auto setContext = [] {
|
|||
|
||||
static __attribute__((no_stack_protector)) void
|
||||
handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
||||
#ifndef USE_FS_GS_SYSCALL
|
||||
if (auto hostFs = _readgsbase_u64()) {
|
||||
_writefsbase_u64(hostFs);
|
||||
}
|
||||
#else
|
||||
uint64_t hostFs = 0;
|
||||
if (syscall(SYS_arch_prctl, ARCH_GET_GS, &hostFs) == 0 && hostFs) {
|
||||
syscall(SYS_arch_prctl, ARCH_SET_FS, hostFs);
|
||||
}
|
||||
#endif
|
||||
|
||||
// rx::printStackTrace(reinterpret_cast<ucontext_t *>(ucontext),
|
||||
// rx::thread::g_current, 1);
|
||||
|
|
@ -58,7 +65,11 @@ handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
|||
|
||||
thread = orbis::g_currentThread;
|
||||
thread->context = prevContext;
|
||||
#ifndef USE_FS_GS_SYSCALL
|
||||
_writefsbase_u64(thread->fsBase);
|
||||
#else
|
||||
syscall(SYS_arch_prctl, ARCH_SET_FS, thread->fsBase);
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((no_stack_protector)) static void
|
||||
|
|
@ -149,7 +160,11 @@ handleSigUser(int sig, siginfo_t *info, void *ucontext) {
|
|||
}
|
||||
|
||||
if (inGuestCode) {
|
||||
#ifndef USE_FS_GS_SYSCALL
|
||||
_writefsbase_u64(thread->fsBase);
|
||||
#else
|
||||
syscall(SYS_arch_prctl, ARCH_SET_FS, thread->fsBase);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,6 +404,7 @@ void rx::thread::setupThisThread() {
|
|||
void rx::thread::invoke(orbis::Thread *thread) {
|
||||
orbis::g_currentThread = thread;
|
||||
|
||||
#ifndef USE_FS_GS_SYSCALL
|
||||
std::uint64_t hostFs = _readfsbase_u64();
|
||||
_writegsbase_u64(hostFs);
|
||||
|
||||
|
|
@ -397,4 +413,15 @@ void rx::thread::invoke(orbis::Thread *thread) {
|
|||
|
||||
::setContext(context->uc_mcontext);
|
||||
_writefsbase_u64(hostFs);
|
||||
#else
|
||||
std::uint64_t hostFs;
|
||||
syscall(SYS_arch_prctl, ARCH_GET_FS, &hostFs);
|
||||
syscall(SYS_arch_prctl, ARCH_SET_GS, hostFs);
|
||||
|
||||
syscall(SYS_arch_prctl, ARCH_SET_FS, thread->fsBase);
|
||||
auto context = reinterpret_cast<ucontext_t *>(thread->context);
|
||||
|
||||
::setContext(context->uc_mcontext);
|
||||
syscall(SYS_arch_prctl, ARCH_SET_FS, hostFs);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
10
rpcsx/vm.cpp
10
rpcsx/vm.cpp
|
|
@ -776,8 +776,8 @@ constexpr auto kMainDirectMemorySize =
|
|||
kPhysicalMemorySize - kFlexibleMemorySize;
|
||||
|
||||
void *vm::map(void *addr, std::uint64_t len, std::int32_t prot,
|
||||
std::int32_t flags, std::int32_t internalFlags, orbis::IoDevice *device,
|
||||
std::uint64_t offset) {
|
||||
std::int32_t flags, std::int32_t internalFlags,
|
||||
orbis::IoDevice *device, std::uint64_t offset) {
|
||||
std::println(stderr, "vm::map(addr = {}, len = {}, prot = {}, flags = {})",
|
||||
addr, len, mapProtToString(prot), mapFlagsToString(flags));
|
||||
|
||||
|
|
@ -966,7 +966,7 @@ void *vm::map(void *addr, std::uint64_t len, std::int32_t prot,
|
|||
info.flags = flags;
|
||||
info.offset = offset;
|
||||
|
||||
gMapInfo.map(address, address + len, info);
|
||||
gMapInfo.map(rx::AddressRange::fromBeginSize(address, len), info);
|
||||
}
|
||||
|
||||
if (auto thr = orbis::g_currentThread) {
|
||||
|
|
@ -1034,7 +1034,7 @@ bool vm::unmap(void *addr, std::uint64_t size) {
|
|||
std::println(stderr, "ignoring unmapping {:x}-{:x}", address,
|
||||
address + size);
|
||||
}
|
||||
gMapInfo.unmap(address, address + size);
|
||||
gMapInfo.unmap(rx::AddressRange::fromBeginSize(address, size));
|
||||
return rx::mem::unmap(addr, size);
|
||||
}
|
||||
|
||||
|
|
@ -1218,5 +1218,5 @@ void vm::setName(std::uint64_t start, std::uint64_t size, const char *name) {
|
|||
|
||||
std::strncpy(info.name, name, sizeof(info.name));
|
||||
|
||||
gMapInfo.map(start, size, info);
|
||||
gMapInfo.map(rx::AddressRange::fromBeginSize(start, size), info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
|
||||
void clear() { mAreas.clear(); }
|
||||
|
||||
AreaInfo queryArea(std::uint64_t address) const {
|
||||
[[nodiscard]] AreaInfo queryArea(std::uint64_t address) const {
|
||||
auto it = mAreas.lower_bound(address);
|
||||
assert(it != mAreas.end());
|
||||
std::uint64_t endAddress = 0;
|
||||
|
|
@ -84,9 +84,10 @@ public:
|
|||
return {startAddress, endAddress};
|
||||
}
|
||||
|
||||
void map(std::uint64_t beginAddress, std::uint64_t endAddress) {
|
||||
auto [beginIt, beginInserted] = mAreas.emplace(beginAddress, Kind::O);
|
||||
auto [endIt, endInserted] = mAreas.emplace(endAddress, Kind::X);
|
||||
void map(rx::AddressRange range) {
|
||||
auto [beginIt, beginInserted] =
|
||||
mAreas.emplace(range.beginAddress(), Kind::O);
|
||||
auto [endIt, endInserted] = mAreas.emplace(range.endAddress(), Kind::X);
|
||||
|
||||
if (!beginInserted) {
|
||||
if (beginIt->second == Kind::X) {
|
||||
|
|
@ -313,9 +314,8 @@ public:
|
|||
};
|
||||
|
||||
template <typename T> class Payload<T *> {
|
||||
static constexpr std::uintptr_t
|
||||
kCloseOpenBit = alignof(T) > 1 ? 1
|
||||
: (1ull << (sizeof(std::uintptr_t) * 8 - 1));
|
||||
static constexpr std::uintptr_t kCloseOpenBit =
|
||||
alignof(T) > 1 ? 1 : (1ull << (sizeof(std::uintptr_t) * 8 - 1));
|
||||
static constexpr std::uintptr_t kClose = 0;
|
||||
std::uintptr_t value = kClose;
|
||||
|
||||
|
|
@ -368,9 +368,8 @@ public:
|
|||
};
|
||||
|
||||
template <typename T> class Payload<Ref<T>> {
|
||||
static constexpr std::uintptr_t
|
||||
kCloseOpenBit = alignof(T) > 1 ? 1
|
||||
: (1ull << (sizeof(std::uintptr_t) * 8 - 1));
|
||||
static constexpr std::uintptr_t kCloseOpenBit =
|
||||
alignof(T) > 1 ? 1 : (1ull << (sizeof(std::uintptr_t) * 8 - 1));
|
||||
static constexpr std::uintptr_t kClose = 0;
|
||||
std::uintptr_t value = kClose;
|
||||
|
||||
|
|
@ -465,14 +464,14 @@ class MemoryTableWithPayload {
|
|||
|
||||
public:
|
||||
class AreaInfo : public rx::AddressRange {
|
||||
PayloadT &payload;
|
||||
Payload<PayloadT> &payload;
|
||||
|
||||
public:
|
||||
AreaInfo(PayloadT &payload, rx::AddressRange range)
|
||||
AreaInfo(Payload<PayloadT> &payload, rx::AddressRange range)
|
||||
: payload(payload), AddressRange(range) {}
|
||||
|
||||
PayloadT *operator->() { return &payload; }
|
||||
PayloadT &get() { return payload; }
|
||||
decltype(auto) operator->() { return &payload.get(); }
|
||||
decltype(auto) get() { return payload.get(); }
|
||||
};
|
||||
|
||||
class iterator {
|
||||
|
|
@ -484,7 +483,7 @@ public:
|
|||
iterator() = default;
|
||||
iterator(map_iterator it) : it(it) {}
|
||||
|
||||
AreaInfo operator*() const { return {it->second.get(), range()}; }
|
||||
AreaInfo operator*() const { return {it->second, range()}; }
|
||||
|
||||
rx::AddressRange range() const {
|
||||
return rx::AddressRange::fromBeginEnd(beginAddress(), endAddress());
|
||||
|
|
@ -494,8 +493,8 @@ public:
|
|||
std::uint64_t endAddress() const { return std::next(it)->first; }
|
||||
std::uint64_t size() const { return endAddress() - beginAddress(); }
|
||||
|
||||
PayloadT &get() const { return it->second.get(); }
|
||||
PayloadT *operator->() const { return &it->second.get(); }
|
||||
decltype(auto) get() const { return it->second.get(); }
|
||||
decltype(auto) operator->() const { return &it->second.get(); }
|
||||
iterator &operator++() {
|
||||
++it;
|
||||
|
||||
|
|
@ -570,13 +569,13 @@ public:
|
|||
return endAddress < address ? mAreas.end() : it;
|
||||
}
|
||||
|
||||
iterator map(std::uint64_t beginAddress, std::uint64_t endAddress,
|
||||
PayloadT payload, bool merge = true, bool noOverride = false) {
|
||||
assert(beginAddress < endAddress);
|
||||
iterator map(rx::AddressRange range, PayloadT payload, bool merge = true,
|
||||
bool noOverride = false) {
|
||||
assert(range.beginAddress() < range.endAddress());
|
||||
auto [beginIt, beginInserted] =
|
||||
mAreas.emplace(beginAddress, payload_type::createOpen(payload));
|
||||
mAreas.emplace(range.beginAddress(), payload_type::createOpen(payload));
|
||||
auto [endIt, endInserted] =
|
||||
mAreas.emplace(endAddress, payload_type::createClose());
|
||||
mAreas.emplace(range.endAddress(), payload_type::createClose());
|
||||
|
||||
bool seenOpen = false;
|
||||
bool endCollision = false;
|
||||
|
|
@ -685,9 +684,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void unmap(std::uint64_t beginAddress, std::uint64_t endAddress) {
|
||||
void unmap(rx::AddressRange range) {
|
||||
// FIXME: can be optimized
|
||||
unmap(map(beginAddress, endAddress, PayloadT{}, false));
|
||||
unmap(map(range, PayloadT{}, false));
|
||||
}
|
||||
};
|
||||
} // namespace rx
|
||||
|
|
|
|||
Loading…
Reference in a new issue