mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-09 12:20:04 +00:00
Remove memory ref from tests
This commit is contained in:
parent
e00a49e1e5
commit
af82841622
9 changed files with 88 additions and 247 deletions
|
@ -100,8 +100,6 @@ add_library(citra_common STATIC
|
|||
math_util.h
|
||||
memory_detect.cpp
|
||||
memory_detect.h
|
||||
memory_ref.h
|
||||
memory_ref.cpp
|
||||
microprofile.cpp
|
||||
microprofile.h
|
||||
microprofileui.h
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// Copyright 2020 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/memory_ref.h"
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright 2020 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
/// Abstract host-side memory - for example a static buffer, or local vector
|
||||
class BackingMem {
|
||||
public:
|
||||
virtual ~BackingMem() = default;
|
||||
virtual u8* GetPtr() = 0;
|
||||
virtual const u8* GetPtr() const = 0;
|
||||
virtual std::size_t GetSize() const = 0;
|
||||
};
|
||||
|
||||
/// Backing memory implemented by a local buffer
|
||||
class BufferMem : public BackingMem {
|
||||
public:
|
||||
BufferMem() = default;
|
||||
explicit BufferMem(std::size_t size) : data(size) {}
|
||||
|
||||
u8* GetPtr() override {
|
||||
return data.data();
|
||||
}
|
||||
|
||||
const u8* GetPtr() const override {
|
||||
return data.data();
|
||||
}
|
||||
|
||||
std::size_t GetSize() const override {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
std::vector<u8>& Vector() {
|
||||
return data;
|
||||
}
|
||||
|
||||
const std::vector<u8>& Vector() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<u8> data;
|
||||
};
|
||||
|
||||
/**
|
||||
* A managed reference to host-side memory.
|
||||
* Fast enough to be used everywhere instead of u8*
|
||||
* Supports serialization.
|
||||
*/
|
||||
class MemoryRef {
|
||||
public:
|
||||
MemoryRef() = default;
|
||||
MemoryRef(std::nullptr_t) {}
|
||||
|
||||
MemoryRef(std::shared_ptr<BackingMem> backing_mem_)
|
||||
: backing_mem(std::move(backing_mem_)), offset(0) {
|
||||
Init();
|
||||
}
|
||||
MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u64 offset_)
|
||||
: backing_mem(std::move(backing_mem_)), offset(offset_) {
|
||||
ASSERT(offset <= backing_mem->GetSize());
|
||||
Init();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return cptr != nullptr;
|
||||
}
|
||||
|
||||
operator u8*() {
|
||||
return cptr;
|
||||
}
|
||||
|
||||
u8* GetPtr() {
|
||||
return cptr;
|
||||
}
|
||||
|
||||
operator const u8*() const {
|
||||
return cptr;
|
||||
}
|
||||
|
||||
const u8* GetPtr() const {
|
||||
return cptr;
|
||||
}
|
||||
|
||||
std::span<u8> GetWriteBytes(std::size_t size) {
|
||||
return std::span{cptr, std::min(size, csize)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::span<const T> GetReadBytes(std::size_t size) const {
|
||||
const auto* cptr_t = reinterpret_cast<T*>(cptr);
|
||||
return std::span{cptr_t, std::min(size, csize) / sizeof(T)};
|
||||
}
|
||||
|
||||
std::size_t GetSize() const {
|
||||
return csize;
|
||||
}
|
||||
|
||||
MemoryRef& operator+=(u32 offset_by) {
|
||||
ASSERT(offset_by < csize);
|
||||
offset += offset_by;
|
||||
Init();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MemoryRef operator+(u32 offset_by) const {
|
||||
ASSERT(offset_by < csize);
|
||||
return MemoryRef(backing_mem, offset + offset_by);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<BackingMem> backing_mem{};
|
||||
u64 offset{};
|
||||
// Cached values for speed
|
||||
u8* cptr{};
|
||||
std::size_t csize{};
|
||||
|
||||
void Init() {
|
||||
if (backing_mem) {
|
||||
cptr = backing_mem->GetPtr() + offset;
|
||||
csize = static_cast<std::size_t>(backing_mem->GetSize() - offset);
|
||||
} else {
|
||||
cptr = nullptr;
|
||||
csize = 0;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -4,19 +4,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Configuration memory stores various hardware/kernel configuration settings. This memory page is
|
||||
// read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/
|
||||
// bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm
|
||||
// putting this as a subset of HLE for now.
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/memory_ref.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace ConfigMem {
|
||||
|
||||
/**
|
||||
* Configuration memory stores various hardware/kernel configuration settings. This memory page is
|
||||
* read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/
|
||||
* bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm
|
||||
* putting this as a subset of HLE for now.
|
||||
*/
|
||||
struct ConfigMemDef {
|
||||
u8 kernel_unk; // 0
|
||||
u8 kernel_version_rev; // 1
|
||||
|
@ -48,20 +48,20 @@ struct ConfigMemDef {
|
|||
static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE,
|
||||
"Config Memory structure size is wrong");
|
||||
|
||||
class Handler : public BackingMem {
|
||||
class Handler {
|
||||
public:
|
||||
Handler();
|
||||
ConfigMemDef& GetConfigMem();
|
||||
|
||||
u8* GetPtr() override {
|
||||
u8* GetPtr() {
|
||||
return reinterpret_cast<u8*>(&config_mem);
|
||||
}
|
||||
|
||||
const u8* GetPtr() const override {
|
||||
const u8* GetPtr() const {
|
||||
return reinterpret_cast<const u8*>(&config_mem);
|
||||
}
|
||||
|
||||
std::size_t GetSize() const override {
|
||||
std::size_t GetSize() const {
|
||||
return sizeof(config_mem);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/shared_page.h"
|
||||
#include "core/hle/service/ptm/ptm.h"
|
||||
#include "core/movie.h"
|
||||
|
||||
namespace SharedPage {
|
||||
|
||||
|
|
|
@ -4,19 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* The shared page stores various runtime configuration settings. This memory page is
|
||||
* read-only for user processes (there is a bit in the header that grants the process
|
||||
* write access, according to 3dbrew; this is not emulated)
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/memory_ref.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
|
@ -66,6 +58,11 @@ enum class WifiState : u8 {
|
|||
Disabled = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* The shared page stores various runtime configuration settings. This memory page is
|
||||
* read-only for user processes (there is a bit in the header that grants the process
|
||||
* write access, according to 3dbrew; this is not emulated)
|
||||
*/
|
||||
struct SharedPageDef {
|
||||
// Most of these names are taken from the 3dbrew page linked above.
|
||||
u32_le date_time_counter; // 0
|
||||
|
@ -91,7 +88,7 @@ struct SharedPageDef {
|
|||
static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE,
|
||||
"Shared page structure size is wrong");
|
||||
|
||||
class Handler : public BackingMem {
|
||||
class Handler {
|
||||
public:
|
||||
Handler(Core::Timing& timing, u64 override_init_time);
|
||||
|
||||
|
@ -111,15 +108,15 @@ public:
|
|||
|
||||
SharedPageDef& GetSharedPage();
|
||||
|
||||
u8* GetPtr() override {
|
||||
u8* GetPtr() {
|
||||
return reinterpret_cast<u8*>(&shared_page);
|
||||
}
|
||||
|
||||
const u8* GetPtr() const override {
|
||||
const u8* GetPtr() const {
|
||||
return reinterpret_cast<const u8*>(&shared_page);
|
||||
}
|
||||
|
||||
std::size_t GetSize() const override {
|
||||
std::size_t GetSize() const {
|
||||
return sizeof(shared_page);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <map>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "common/memory_ref.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/memory.h"
|
||||
|
|
|
@ -143,74 +143,70 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
|||
}
|
||||
|
||||
SECTION("translates StaticBuffer descriptors") {
|
||||
auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef buffer{mem};
|
||||
std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xAB);
|
||||
auto mem = std::vector<u8>(Memory::CITRA_PAGE_SIZE);
|
||||
std::fill(mem.begin(), mem.end(), 0xAB);
|
||||
|
||||
VAddr target_address = 0x10000000;
|
||||
auto result = process->vm_manager.MapBackingMemory(
|
||||
target_address, buffer, static_cast<u32>(buffer.GetSize()), MemoryState::Private);
|
||||
target_address, mem.data(), static_cast<u32>(mem.size()), MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
const u32_le input[]{
|
||||
IPC::MakeHeader(0, 0, 2),
|
||||
IPC::StaticBufferDesc(buffer.GetSize(), 0),
|
||||
IPC::StaticBufferDesc(mem.size(), 0),
|
||||
target_address,
|
||||
};
|
||||
|
||||
context.PopulateFromIncomingCommandBuffer(input, process);
|
||||
|
||||
CHECK(context.GetStaticBuffer(0) == mem->Vector());
|
||||
CHECK(context.GetStaticBuffer(0) == mem);
|
||||
|
||||
REQUIRE(process->vm_manager.UnmapRange(
|
||||
target_address, static_cast<u32>(buffer.GetSize())) == ResultSuccess);
|
||||
REQUIRE(process->vm_manager.UnmapRange(target_address, static_cast<u32>(mem.size())) ==
|
||||
ResultSuccess);
|
||||
}
|
||||
|
||||
SECTION("translates MappedBuffer descriptors") {
|
||||
auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef buffer{mem};
|
||||
std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xCD);
|
||||
std::vector<u8> mem(Memory::CITRA_PAGE_SIZE);
|
||||
std::fill(mem.begin(), mem.end(), 0xCD);
|
||||
|
||||
VAddr target_address = 0x10000000;
|
||||
auto result = process->vm_manager.MapBackingMemory(
|
||||
target_address, buffer, static_cast<u32>(buffer.GetSize()), MemoryState::Private);
|
||||
target_address, mem.data(), static_cast<u32>(mem.size()), MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
const u32_le input[]{
|
||||
IPC::MakeHeader(0, 0, 2),
|
||||
IPC::MappedBufferDesc(buffer.GetSize(), IPC::R),
|
||||
IPC::MappedBufferDesc(mem.size(), IPC::R),
|
||||
target_address,
|
||||
};
|
||||
|
||||
context.PopulateFromIncomingCommandBuffer(input, process);
|
||||
|
||||
std::vector<u8> other_buffer(buffer.GetSize());
|
||||
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize());
|
||||
std::vector<u8> other_buffer(mem.size());
|
||||
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, mem.size());
|
||||
|
||||
CHECK(other_buffer == mem->Vector());
|
||||
CHECK(other_buffer == mem);
|
||||
|
||||
REQUIRE(process->vm_manager.UnmapRange(
|
||||
target_address, static_cast<u32>(buffer.GetSize())) == ResultSuccess);
|
||||
REQUIRE(process->vm_manager.UnmapRange(target_address, static_cast<u32>(mem.size())) ==
|
||||
ResultSuccess);
|
||||
}
|
||||
|
||||
SECTION("translates mixed params") {
|
||||
auto mem_static = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef buffer_static{mem_static};
|
||||
std::fill(buffer_static.GetPtr(), buffer_static.GetPtr() + buffer_static.GetSize(), 0xCE);
|
||||
std::vector<u8> buffer_static(Memory::CITRA_PAGE_SIZE);
|
||||
std::fill(buffer_static.begin(), buffer_static.end(), 0xCE);
|
||||
|
||||
auto mem_mapped = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef buffer_mapped{mem_mapped};
|
||||
std::fill(buffer_mapped.GetPtr(), buffer_mapped.GetPtr() + buffer_mapped.GetSize(), 0xDF);
|
||||
std::vector<u8> buffer_mapped(Memory::CITRA_PAGE_SIZE);
|
||||
std::fill(buffer_mapped.begin(), buffer_mapped.end(), 0xDF);
|
||||
|
||||
VAddr target_address_static = 0x10000000;
|
||||
auto result = process->vm_manager.MapBackingMemory(
|
||||
target_address_static, buffer_static, static_cast<u32>(buffer_static.GetSize()),
|
||||
target_address_static, buffer_static.data(), static_cast<u32>(buffer_static.size()),
|
||||
MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
VAddr target_address_mapped = 0x20000000;
|
||||
result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped,
|
||||
static_cast<u32>(buffer_mapped.GetSize()),
|
||||
result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped.data(),
|
||||
static_cast<u32>(buffer_mapped.size()),
|
||||
MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
|
@ -225,9 +221,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
|||
a_handle,
|
||||
IPC::CallingPidDesc(),
|
||||
0,
|
||||
IPC::StaticBufferDesc(buffer_static.GetSize(), 0),
|
||||
IPC::StaticBufferDesc(buffer_static.size(), 0),
|
||||
target_address_static,
|
||||
IPC::MappedBufferDesc(buffer_mapped.GetSize(), IPC::R),
|
||||
IPC::MappedBufferDesc(buffer_mapped.size(), IPC::R),
|
||||
target_address_mapped,
|
||||
};
|
||||
|
||||
|
@ -238,16 +234,16 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
|||
CHECK(output[2] == 0xABCDEF00);
|
||||
CHECK(context.GetIncomingHandle(output[4]) == a);
|
||||
CHECK(output[6] == process->process_id);
|
||||
CHECK(context.GetStaticBuffer(0) == mem_static->Vector());
|
||||
std::vector<u8> other_buffer(buffer_mapped.GetSize());
|
||||
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.GetSize());
|
||||
CHECK(other_buffer == mem_mapped->Vector());
|
||||
CHECK(context.GetStaticBuffer(0) == buffer_static);
|
||||
std::vector<u8> other_buffer(buffer_mapped.size());
|
||||
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.size());
|
||||
CHECK(other_buffer == buffer_mapped);
|
||||
|
||||
REQUIRE(process->vm_manager.UnmapRange(target_address_static,
|
||||
static_cast<u32>(buffer_static.GetSize())) ==
|
||||
static_cast<u32>(buffer_static.size())) ==
|
||||
ResultSuccess);
|
||||
REQUIRE(process->vm_manager.UnmapRange(target_address_mapped,
|
||||
static_cast<u32>(buffer_mapped.GetSize())) ==
|
||||
static_cast<u32>(buffer_mapped.size())) ==
|
||||
ResultSuccess);
|
||||
}
|
||||
}
|
||||
|
@ -337,13 +333,12 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
|||
|
||||
context.AddStaticBuffer(0, input_buffer);
|
||||
|
||||
auto output_mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef output_buffer{output_mem};
|
||||
std::vector<u8> output_buffer(Memory::CITRA_PAGE_SIZE);
|
||||
|
||||
VAddr target_address = 0x10000000;
|
||||
auto result = process->vm_manager.MapBackingMemory(
|
||||
target_address, output_buffer, static_cast<u32>(output_buffer.GetSize()),
|
||||
MemoryState::Private);
|
||||
auto result = process->vm_manager.MapBackingMemory(target_address, output_buffer.data(),
|
||||
static_cast<u32>(output_buffer.size()),
|
||||
MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
input[0] = IPC::MakeHeader(0, 0, 2);
|
||||
|
@ -354,33 +349,31 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
|||
// target address
|
||||
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2> output_cmdbuff;
|
||||
// Set up the output StaticBuffer
|
||||
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] =
|
||||
IPC::StaticBufferDesc(output_buffer.GetSize(), 0);
|
||||
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] = IPC::StaticBufferDesc(output_buffer.size(), 0);
|
||||
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address;
|
||||
|
||||
context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process);
|
||||
|
||||
CHECK(output_mem->Vector() == input_buffer);
|
||||
CHECK(output_buffer == input_buffer);
|
||||
REQUIRE(process->vm_manager.UnmapRange(
|
||||
target_address, static_cast<u32>(output_buffer.GetSize())) == ResultSuccess);
|
||||
target_address, static_cast<u32>(output_buffer.size())) == ResultSuccess);
|
||||
}
|
||||
|
||||
SECTION("translates StaticBuffer descriptors") {
|
||||
std::vector<u8> input_buffer(Memory::CITRA_PAGE_SIZE);
|
||||
std::fill(input_buffer.begin(), input_buffer.end(), 0xAB);
|
||||
|
||||
auto output_mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef output_buffer{output_mem};
|
||||
std::vector<u8> output_buffer(Memory::CITRA_PAGE_SIZE);
|
||||
|
||||
VAddr target_address = 0x10000000;
|
||||
auto result = process->vm_manager.MapBackingMemory(
|
||||
target_address, output_buffer, static_cast<u32>(output_buffer.GetSize()),
|
||||
MemoryState::Private);
|
||||
auto result = process->vm_manager.MapBackingMemory(target_address, output_buffer.data(),
|
||||
static_cast<u32>(output_buffer.size()),
|
||||
MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
const u32_le input_cmdbuff[]{
|
||||
IPC::MakeHeader(0, 0, 2),
|
||||
IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W),
|
||||
IPC::MappedBufferDesc(output_buffer.size(), IPC::W),
|
||||
target_address,
|
||||
};
|
||||
|
||||
|
@ -389,16 +382,16 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
|||
context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size());
|
||||
|
||||
input[0] = IPC::MakeHeader(0, 0, 2);
|
||||
input[1] = IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W);
|
||||
input[1] = IPC::MappedBufferDesc(output_buffer.size(), IPC::W);
|
||||
input[2] = 0;
|
||||
|
||||
context.WriteToOutgoingCommandBuffer(output, *process);
|
||||
|
||||
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W));
|
||||
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.size(), IPC::W));
|
||||
CHECK(output[2] == target_address);
|
||||
CHECK(output_mem->Vector() == input_buffer);
|
||||
CHECK(output_buffer == input_buffer);
|
||||
REQUIRE(process->vm_manager.UnmapRange(
|
||||
target_address, static_cast<u32>(output_buffer.GetSize())) == ResultSuccess);
|
||||
target_address, static_cast<u32>(output_buffer.size())) == ResultSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
#include "core/memory.h"
|
||||
|
||||
TEST_CASE("Memory Basics", "[kernel][memory]") {
|
||||
auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE);
|
||||
MemoryRef block{mem};
|
||||
auto mem = std::make_unique<u8[]>(Memory::CITRA_PAGE_SIZE);
|
||||
Core::Timing timing(1, 100);
|
||||
Core::System system;
|
||||
Memory::MemorySystem memory{system};
|
||||
|
@ -23,28 +22,26 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
SECTION("mapping memory") {
|
||||
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
||||
auto manager = std::make_unique<Kernel::VMManager>(memory, process);
|
||||
auto result =
|
||||
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
||||
Kernel::MemoryState::Private);
|
||||
auto result = manager->MapBackingMemory(
|
||||
Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
||||
CHECK(vma != manager->vma_map.end());
|
||||
CHECK(vma->second.size == static_cast<u32>(block.GetSize()));
|
||||
CHECK(vma->second.size == Memory::CITRA_PAGE_SIZE);
|
||||
CHECK(vma->second.type == Kernel::VMAType::BackingMemory);
|
||||
CHECK(vma->second.backing_memory == block.GetPtr());
|
||||
CHECK(vma->second.backing_memory == mem.get());
|
||||
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
||||
}
|
||||
|
||||
SECTION("unmapping memory") {
|
||||
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
||||
auto manager = std::make_unique<Kernel::VMManager>(memory, process);
|
||||
auto result =
|
||||
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
||||
Kernel::MemoryState::Private);
|
||||
auto result = manager->MapBackingMemory(
|
||||
Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
Result code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
||||
Result code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE);
|
||||
REQUIRE(code == ResultSuccess);
|
||||
|
||||
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
||||
|
@ -56,12 +53,11 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
SECTION("changing memory permissions") {
|
||||
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
||||
auto manager = std::make_unique<Kernel::VMManager>(memory, process);
|
||||
auto result =
|
||||
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
||||
Kernel::MemoryState::Private);
|
||||
auto result = manager->MapBackingMemory(
|
||||
Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
Result code = manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()),
|
||||
Result code = manager->ReprotectRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE,
|
||||
Kernel::VMAPermission::Execute);
|
||||
CHECK(code == ResultSuccess);
|
||||
|
||||
|
@ -69,28 +65,26 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
CHECK(vma != manager->vma_map.end());
|
||||
CHECK(vma->second.permissions == Kernel::VMAPermission::Execute);
|
||||
|
||||
code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
||||
code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE);
|
||||
REQUIRE(code == ResultSuccess);
|
||||
}
|
||||
|
||||
SECTION("changing memory state") {
|
||||
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
||||
auto manager = std::make_unique<Kernel::VMManager>(memory, process);
|
||||
auto result =
|
||||
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
||||
Kernel::MemoryState::Private);
|
||||
auto result = manager->MapBackingMemory(
|
||||
Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private);
|
||||
REQUIRE(result.Code() == ResultSuccess);
|
||||
|
||||
SECTION("reprotect memory range") {
|
||||
Result code =
|
||||
manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()),
|
||||
Kernel::VMAPermission::ReadWrite);
|
||||
Result code = manager->ReprotectRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE,
|
||||
Kernel::VMAPermission::ReadWrite);
|
||||
REQUIRE(code == ResultSuccess);
|
||||
}
|
||||
|
||||
SECTION("with invalid address") {
|
||||
Result code = manager->ChangeMemoryState(
|
||||
0xFFFFFFFF, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked,
|
||||
0xFFFFFFFF, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Locked,
|
||||
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
||||
Kernel::VMAPermission::Execute);
|
||||
CHECK(code == Kernel::ResultInvalidAddress);
|
||||
|
@ -98,7 +92,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
|
||||
SECTION("ignoring the original permissions") {
|
||||
Result code = manager->ChangeMemoryState(
|
||||
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
||||
Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private,
|
||||
Kernel::VMAPermission::None, Kernel::MemoryState::Locked,
|
||||
Kernel::VMAPermission::Write);
|
||||
CHECK(code == ResultSuccess);
|
||||
|
@ -111,7 +105,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
|
||||
SECTION("enforcing the original permissions with correct expectations") {
|
||||
Result code = manager->ChangeMemoryState(
|
||||
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
||||
Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private,
|
||||
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
||||
Kernel::VMAPermission::Execute);
|
||||
CHECK(code == ResultSuccess);
|
||||
|
@ -124,7 +118,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
|
||||
SECTION("with incorrect permission expectations") {
|
||||
Result code = manager->ChangeMemoryState(
|
||||
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
||||
Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private,
|
||||
Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased,
|
||||
Kernel::VMAPermission::Execute);
|
||||
CHECK(code == Kernel::ResultInvalidAddressState);
|
||||
|
@ -137,7 +131,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
|
||||
SECTION("with incorrect state expectations") {
|
||||
Result code = manager->ChangeMemoryState(
|
||||
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked,
|
||||
Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Locked,
|
||||
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
||||
Kernel::VMAPermission::Execute);
|
||||
CHECK(code == Kernel::ResultInvalidAddressState);
|
||||
|
@ -148,7 +142,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|||
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
||||
}
|
||||
|
||||
Result code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
||||
Result code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE);
|
||||
REQUIRE(code == ResultSuccess);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue