mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-17 20:35:18 +00:00
Memory cleanup, page flags implemented
RSXCMDMem, SPRXMem, MmaperMem removed MainMem range fixed
This commit is contained in:
parent
0eebfb0aaa
commit
267de68441
23 changed files with 259 additions and 260 deletions
|
|
@ -4,55 +4,8 @@
|
|||
#include "Memory.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
MemoryBase Memory;
|
||||
|
||||
void MemoryBase::RegisterPages(u32 addr, u32 size)
|
||||
{
|
||||
assert(size && (size | addr) % 4096 == 0);
|
||||
|
||||
LV2_LOCK(0);
|
||||
|
||||
//LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%x, size=0x%x)", addr, size);
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (m_pages[i])
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Page already registered (addr=0x%x)", i * 4096);
|
||||
Emu.Pause();
|
||||
}
|
||||
m_pages[i] = 1; // TODO: define page parameters
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBase::UnregisterPages(u32 addr, u32 size)
|
||||
{
|
||||
assert(size && (size | addr) % 4096 == 0);
|
||||
|
||||
LV2_LOCK(0);
|
||||
|
||||
//LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%x, size=0x%x)", addr, size);
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (!m_pages[i])
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Page not registered (addr=0x%x)", i * 4096);
|
||||
Emu.Pause();
|
||||
}
|
||||
m_pages[i] = 0; // TODO: define page parameters
|
||||
}
|
||||
}
|
||||
|
||||
u32 MemoryBase::InitRawSPU(MemoryBlock* raw_spu)
|
||||
{
|
||||
LV2_LOCK(0);
|
||||
|
|
@ -93,7 +46,6 @@ void MemoryBase::Init(MemoryType type)
|
|||
if (m_inited) return;
|
||||
m_inited = true;
|
||||
|
||||
memset(m_pages, 0, sizeof(m_pages));
|
||||
memset(RawSPUMem, 0, sizeof(RawSPUMem));
|
||||
|
||||
LOG_NOTICE(MEMORY, "Initializing memory: base_addr = 0x%llx, priv_addr = 0x%llx", (u64)vm::g_base_addr, (u64)vm::g_priv_addr);
|
||||
|
|
@ -111,11 +63,8 @@ void MemoryBase::Init(MemoryType type)
|
|||
switch (type)
|
||||
{
|
||||
case Memory_PS3:
|
||||
MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000));
|
||||
MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000));
|
||||
MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000));
|
||||
MemoryBlocks.push_back(SPRXMem.SetRange(0x50000000, 0x10000000));
|
||||
MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000));
|
||||
MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x1FFF0000));
|
||||
MemoryBlocks.push_back(UserMemory = Userspace.SetRange(0x20000000, 0x10000000));
|
||||
MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000));
|
||||
MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000));
|
||||
break;
|
||||
|
|
@ -189,7 +138,7 @@ bool MemoryBase::Map(const u32 addr, const u32 size)
|
|||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (m_pages[i])
|
||||
if (vm::check_addr(i * 4096, 4096))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -220,45 +169,15 @@ bool MemoryBase::Unmap(const u32 addr)
|
|||
MemBlockInfo::MemBlockInfo(u32 addr, u32 size)
|
||||
: MemInfo(addr, size)
|
||||
{
|
||||
assert(size && (size | addr) % 4096 == 0);
|
||||
|
||||
void* real_addr = vm::get_ptr(addr);
|
||||
void* priv_addr = vm::get_priv_ptr(addr);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE))
|
||||
#else
|
||||
if (mprotect(real_addr, size, PROT_READ | PROT_WRITE) || mprotect(priv_addr, size, PROT_READ | PROT_WRITE))
|
||||
#endif
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%x, size=0x%x)", addr, size);
|
||||
Emu.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory.RegisterPages(addr, size);
|
||||
|
||||
mem = real_addr;
|
||||
memset(mem, 0, size); // ???
|
||||
}
|
||||
vm::page_map(addr, size, vm::page_readable | vm::page_writable | vm::page_executable);
|
||||
}
|
||||
|
||||
void MemBlockInfo::Free()
|
||||
{
|
||||
if (mem)
|
||||
if (addr && size)
|
||||
{
|
||||
Memory.UnregisterPages(addr, size);
|
||||
#ifdef _WIN32
|
||||
DWORD old;
|
||||
|
||||
if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(addr), size, PAGE_NOACCESS, &old))
|
||||
#else
|
||||
if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(addr), size, PROT_NONE))
|
||||
#endif
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%x, size=0x%x)", addr, size);
|
||||
Emu.Pause();
|
||||
}
|
||||
vm::page_unmap(addr, size);
|
||||
addr = size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -277,21 +196,14 @@ void MemoryBlock::Init()
|
|||
{
|
||||
range_start = 0;
|
||||
range_size = 0;
|
||||
|
||||
mem = vm::get_ptr<u8>(0u);
|
||||
}
|
||||
|
||||
void MemoryBlock::InitMemory()
|
||||
{
|
||||
if (!range_size)
|
||||
{
|
||||
mem = vm::get_ptr<u8>(range_start);
|
||||
}
|
||||
else
|
||||
if (range_size)
|
||||
{
|
||||
Free();
|
||||
mem_inf = new MemBlockInfo(range_start, range_size);
|
||||
mem = (u8*)mem_inf->mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,16 +30,12 @@ namespace vm
|
|||
class MemoryBase
|
||||
{
|
||||
std::vector<MemoryBlock*> MemoryBlocks;
|
||||
u32 m_pages[0x100000000 / 4096]; // information about every page
|
||||
|
||||
public:
|
||||
MemoryBlock* UserMemory;
|
||||
|
||||
DynamicMemoryBlock MainMem;
|
||||
DynamicMemoryBlock SPRXMem;
|
||||
DynamicMemoryBlock PRXMem;
|
||||
DynamicMemoryBlock RSXCMDMem;
|
||||
DynamicMemoryBlock MmaperMem;
|
||||
DynamicMemoryBlock Userspace;
|
||||
DynamicMemoryBlock RSXFBMem;
|
||||
DynamicMemoryBlock StackMem;
|
||||
MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET];
|
||||
|
|
@ -82,27 +78,6 @@ public:
|
|||
|
||||
void Init(MemoryType type);
|
||||
|
||||
bool IsGoodAddr(const u32 addr)
|
||||
{
|
||||
return m_pages[addr / 4096] != 0; // TODO: define page parameters
|
||||
}
|
||||
|
||||
bool IsGoodAddr(const u32 addr, const u32 size)
|
||||
{
|
||||
if (!size || addr + size - 1 < addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++)
|
||||
{
|
||||
if (!m_pages[i]) return false; // TODO: define page parameters
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Close();
|
||||
|
||||
__noinline void WriteMMIO32(u32 addr, const u32 data);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ struct MemInfo
|
|||
|
||||
struct MemBlockInfo : public MemInfo
|
||||
{
|
||||
void *mem;
|
||||
|
||||
MemBlockInfo(u32 addr, u32 size);
|
||||
|
||||
void Free();
|
||||
|
|
@ -32,27 +30,26 @@ struct MemBlockInfo : public MemInfo
|
|||
|
||||
MemBlockInfo(MemBlockInfo &&other)
|
||||
: MemInfo(other.addr,other.size)
|
||||
, mem(other.mem)
|
||||
{
|
||||
other.mem = nullptr;
|
||||
other.addr = 0;
|
||||
other.size = 0;
|
||||
}
|
||||
|
||||
MemBlockInfo& operator =(MemBlockInfo &other) = delete;
|
||||
|
||||
MemBlockInfo& operator =(MemBlockInfo &&other)
|
||||
{
|
||||
this->Free();
|
||||
Free();
|
||||
this->addr = other.addr;
|
||||
this->size = other.size;
|
||||
this->mem = other.mem;
|
||||
other.mem = nullptr;
|
||||
other.addr = 0;
|
||||
other.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MemBlockInfo()
|
||||
{
|
||||
Free();
|
||||
mem = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -76,7 +73,6 @@ struct VirtualMemInfo : public MemInfo
|
|||
class MemoryBlock
|
||||
{
|
||||
protected:
|
||||
u8* mem;
|
||||
u32 range_start;
|
||||
u32 range_size;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ namespace vm
|
|||
|
||||
void* const g_base_addr = (atexit(finalize), initialize());
|
||||
|
||||
std::array<atomic_le_t<u8>, 0x100000000ull / 4096> g_page_info = {}; // information about every page
|
||||
|
||||
class reservation_mutex_t
|
||||
{
|
||||
std::atomic<NamedThreadBase*> m_owner;
|
||||
|
|
@ -211,6 +213,12 @@ namespace vm
|
|||
{
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
u8 flags = g_page_info[addr >> 12].read_relaxed();
|
||||
if (!(flags & page_writable) || !(flags & page_allocated) || (flags & page_no_reservations))
|
||||
{
|
||||
throw fmt::format("vm::reservation_acquire(addr=0x%x, size=0x%x) failed (invalid page flags: 0x%x)", addr, size, flags);
|
||||
}
|
||||
|
||||
// silent unlocking to prevent priority boost for threads going to break reservation
|
||||
//g_reservation_mutex.do_notify = false;
|
||||
|
||||
|
|
@ -272,13 +280,9 @@ namespace vm
|
|||
{
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
if (!check_addr(addr))
|
||||
{
|
||||
LV2_LOCK(0);
|
||||
|
||||
if (!Memory.IsGoodAddr(addr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_writing)
|
||||
|
|
@ -335,11 +339,157 @@ namespace vm
|
|||
_reservation_break(addr);
|
||||
}
|
||||
|
||||
bool check_addr(u32 addr)
|
||||
void page_map(u32 addr, u32 size, u8 flags)
|
||||
{
|
||||
// Checking address before using it is unsafe.
|
||||
// The only safe way to check it is to protect both actions (checking and using) with mutex that is used for mapping/allocation.
|
||||
return false;
|
||||
assert(size && (size | addr) % 4096 == 0 && flags < page_allocated);
|
||||
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (g_page_info[i].read_relaxed())
|
||||
{
|
||||
throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (already mapped at 0x%x)", addr, size, flags, i * 4096);
|
||||
}
|
||||
}
|
||||
|
||||
void* real_addr = vm::get_ptr(addr);
|
||||
void* priv_addr = vm::get_priv_ptr(addr);
|
||||
|
||||
#ifdef _WIN32
|
||||
auto protection = flags & page_writable ? PAGE_READWRITE : (flags & page_readable ? PAGE_READONLY : PAGE_NOACCESS);
|
||||
if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, protection))
|
||||
#else
|
||||
auto protection = flags & page_writable ? PROT_WRITE | PROT_READ : (flags & page_readable ? PROT_READ : PROT_NONE);
|
||||
if (mprotect(priv_addr, size, PROT_READ | PROT_WRITE) || mprotect(real_addr, size, protection))
|
||||
#endif
|
||||
{
|
||||
throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (API)", addr, size, flags);
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (g_page_info[i].exchange(flags | page_allocated))
|
||||
{
|
||||
throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (concurrent access at 0x%x)", addr, size, flags, i * 4096);
|
||||
}
|
||||
}
|
||||
|
||||
memset(priv_addr, 0, size); // ???
|
||||
}
|
||||
|
||||
bool page_protect(u32 addr, u32 size, u8 flags_test, u8 flags_set, u8 flags_clear)
|
||||
{
|
||||
u8 flags_inv = flags_set & flags_clear;
|
||||
|
||||
assert(size && (size | addr) % 4096 == 0);
|
||||
|
||||
flags_test |= page_allocated;
|
||||
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if ((g_page_info[i].read_relaxed() & flags_test) != (flags_test | page_allocated))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags_inv && !flags_set && !flags_clear)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
_reservation_break(i * 4096);
|
||||
|
||||
const u8 f1 = g_page_info[i]._or(flags_set & ~flags_inv) & (page_writable | page_readable);
|
||||
g_page_info[i]._and_not(flags_clear & ~flags_inv);
|
||||
const u8 f2 = (g_page_info[i] ^= flags_inv) & (page_writable | page_readable);
|
||||
|
||||
if (f1 != f2)
|
||||
{
|
||||
void* real_addr = vm::get_ptr(i * 4096);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD old;
|
||||
|
||||
auto protection = f2 & page_writable ? PAGE_READWRITE : (f2 & page_readable ? PAGE_READONLY : PAGE_NOACCESS);
|
||||
if (!VirtualProtect(real_addr, size, protection, &old))
|
||||
#else
|
||||
auto protection = f2 & page_writable ? PROT_WRITE | PROT_READ : (f2 & page_readable ? PROT_READ : PROT_NONE);
|
||||
if (mprotect(real_addr, size, protection))
|
||||
#endif
|
||||
{
|
||||
throw fmt::format("vm::page_protect(addr=0x%x, size=0x%x, flags_test=0x%x, flags_set=0x%x, flags_clear=0x%x) failed (API)", addr, size, flags_test, flags_set, flags_clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void page_unmap(u32 addr, u32 size)
|
||||
{
|
||||
assert(size && (size | addr) % 4096 == 0);
|
||||
|
||||
std::lock_guard<reservation_mutex_t> lock(g_reservation_mutex);
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
if (!(g_page_info[i].read_relaxed() & page_allocated))
|
||||
{
|
||||
throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (not mapped at 0x%x)", addr, size, i * 4096);
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
{
|
||||
_reservation_break(i * 4096);
|
||||
|
||||
if (!(g_page_info[i].exchange(0) & page_allocated))
|
||||
{
|
||||
throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (concurrent access at 0x%x)", addr, size, i * 4096);
|
||||
}
|
||||
}
|
||||
|
||||
void* real_addr = vm::get_ptr(addr);
|
||||
void* priv_addr = vm::get_priv_ptr(addr);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD old;
|
||||
|
||||
if (!VirtualProtect(real_addr, size, PAGE_NOACCESS, &old) || !VirtualProtect(priv_addr, size, PAGE_NOACCESS, &old))
|
||||
#else
|
||||
if (mprotect(real_addr, size, PROT_NONE) || mprotect(priv_addr, size, PROT_NONE))
|
||||
#endif
|
||||
{
|
||||
throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (API)", addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
// Not checked if address is writable/readable. Checking address before using it is unsafe.
|
||||
// The only safe way to check it is to protect both actions (checking and using) with mutex that is used for mapping/allocation.
|
||||
bool check_addr(u32 addr, u32 size)
|
||||
{
|
||||
assert(size);
|
||||
|
||||
if (addr + (size - 1) < addr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++)
|
||||
{
|
||||
if ((g_page_info[i].read_sync() & page_allocated) != page_allocated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
|
@ -406,6 +556,19 @@ namespace vm
|
|||
Memory.MainMem.Free(addr);
|
||||
}
|
||||
|
||||
u32 user_space_alloc(u32 size)
|
||||
{
|
||||
return Memory.Userspace.AllocAlign(size, 1);
|
||||
}
|
||||
u32 user_space_fixed_alloc(u32 addr, u32 size)
|
||||
{
|
||||
return Memory.Userspace.AllocFixed(addr, size) ? addr : 0;
|
||||
}
|
||||
void user_space_dealloc(u32 addr)
|
||||
{
|
||||
Memory.Userspace.Free(addr);
|
||||
}
|
||||
|
||||
u32 g_stack_offset = 0;
|
||||
|
||||
u32 stack_alloc(u32 size)
|
||||
|
|
@ -421,32 +584,6 @@ namespace vm
|
|||
Memory.StackMem.Free(addr);
|
||||
}
|
||||
|
||||
u32 sprx_alloc(u32 size)
|
||||
{
|
||||
return Memory.SPRXMem.AllocAlign(size, 1);
|
||||
}
|
||||
u32 sprx_fixed_alloc(u32 addr, u32 size)
|
||||
{
|
||||
return Memory.SPRXMem.AllocFixed(Memory.SPRXMem.GetStartAddr() + addr, size) ? Memory.SPRXMem.GetStartAddr() + addr : 0;
|
||||
}
|
||||
void sprx_dealloc(u32 addr)
|
||||
{
|
||||
Memory.SPRXMem.Free(addr);
|
||||
}
|
||||
|
||||
u32 user_space_alloc(u32 size)
|
||||
{
|
||||
return Memory.PRXMem.AllocAlign(size, 1);
|
||||
}
|
||||
u32 user_space_fixed_alloc(u32 addr, u32 size)
|
||||
{
|
||||
return Memory.PRXMem.AllocFixed(addr, size) ? addr : 0;
|
||||
}
|
||||
void user_space_dealloc(u32 addr)
|
||||
{
|
||||
Memory.PRXMem.Free(addr);
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
Memory.Init(Memory_PS3);
|
||||
|
|
@ -471,13 +608,9 @@ namespace vm
|
|||
|
||||
location_info g_locations[memory_location_count] =
|
||||
{
|
||||
{ 0x00010000, 0x2FFF0000, ps3::main_alloc, ps3::main_fixed_alloc, ps3::main_dealloc },
|
||||
{ 0x00010000, 0x1FFF0000, ps3::main_alloc, ps3::main_fixed_alloc, ps3::main_dealloc },
|
||||
{ 0x20000000, 0x10000000, ps3::user_space_alloc, ps3::user_space_fixed_alloc, ps3::user_space_dealloc },
|
||||
{ 0xD0000000, 0x10000000, ps3::stack_alloc, ps3::stack_fixed_alloc, ps3::stack_dealloc },
|
||||
|
||||
//remove me
|
||||
{ 0x00010000, 0x2FFF0000, ps3::sprx_alloc, ps3::sprx_fixed_alloc, ps3::sprx_dealloc },
|
||||
|
||||
{ 0x30000000, 0x10000000, ps3::user_space_alloc, ps3::user_space_fixed_alloc, ps3::user_space_dealloc },
|
||||
};
|
||||
|
||||
void close()
|
||||
|
|
|
|||
|
|
@ -8,16 +8,24 @@ namespace vm
|
|||
enum memory_location : uint
|
||||
{
|
||||
main,
|
||||
user_space,
|
||||
stack,
|
||||
|
||||
//remove me
|
||||
sprx,
|
||||
|
||||
user_space,
|
||||
|
||||
memory_location_count
|
||||
};
|
||||
|
||||
enum page_info_t : u8
|
||||
{
|
||||
page_readable = (1 << 0),
|
||||
page_writable = (1 << 1),
|
||||
page_executable = (1 << 2),
|
||||
|
||||
page_fault_notification = (1 << 3),
|
||||
page_no_reservations = (1 << 4),
|
||||
|
||||
page_allocated = (1 << 7),
|
||||
};
|
||||
|
||||
static void set_stack_size(u32 size) {}
|
||||
static void initialize_stack() {}
|
||||
|
||||
|
|
@ -34,11 +42,23 @@ namespace vm
|
|||
bool reservation_acquire(void* data, u32 addr, u32 size, const std::function<void()>& callback = nullptr);
|
||||
// attempt to atomically update reserved memory
|
||||
bool reservation_update(u32 addr, const void* data, u32 size);
|
||||
// for internal use
|
||||
bool reservation_query(u32 addr, bool is_writing);
|
||||
// for internal use
|
||||
void reservation_free();
|
||||
// perform complete operation
|
||||
void reservation_op(u32 addr, u32 size, std::function<void()> proc);
|
||||
|
||||
// for internal use
|
||||
void page_map(u32 addr, u32 size, u8 flags);
|
||||
// for internal use
|
||||
bool page_protect(u32 addr, u32 size, u8 flags_test = 0, u8 flags_set = 0, u8 flags_clear = 0);
|
||||
// for internal use
|
||||
void page_unmap(u32 addr, u32 size);
|
||||
|
||||
// unsafe address check
|
||||
bool check_addr(u32 addr, u32 size = 1);
|
||||
|
||||
bool map(u32 addr, u32 size, u32 flags);
|
||||
bool unmap(u32 addr, u32 size = 0, u32 flags = 0);
|
||||
u32 alloc(u32 size, memory_location location = user_space);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace vm
|
|||
|
||||
void alloc()
|
||||
{
|
||||
m_addr = vm::cast(Memory.Alloc(size(), m_align));
|
||||
m_addr = Memory.Alloc(size(), m_align);
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ namespace vm
|
|||
|
||||
void alloc()
|
||||
{
|
||||
m_addr = vm::cast(Memory.Alloc(size(), m_align));
|
||||
m_addr = Memory.Alloc(size(), m_align);
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue