mirror of
https://github.com/SysRay/psOff_public.git
synced 2024-11-22 22:09:39 +00:00
dump
This commit is contained in:
parent
fbf46eb9aa
commit
935df442ad
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.24)
|
||||
include(ExternalProject)
|
||||
|
||||
set(PSOFF_LIB_VERSION v.0.0)
|
||||
set(PSOFF_RENDER_VERSION v.0.5-nightly_17.04.24)
|
||||
|
||||
set(ProjectName psOff_${CMAKE_BUILD_TYPE})
|
||||
project(${ProjectName} VERSION 0.0.1)
|
||||
@ -66,6 +67,19 @@ ExternalProject_Add(third_party
|
||||
URL https://github.com/SysRay/psOff_thirdParty/releases/download/${PSOFF_LIB_VERSION}/psOff-3rd.zip
|
||||
)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
ExternalProject_Add(renderer
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
PREFIX ${CMAKE_BINARY_DIR}/renderer
|
||||
BUILD_IN_SOURCE 1
|
||||
URL https://github.com/SysRay/psOff_Renderer/releases/download/${PSOFF_RENDER_VERSION}/psOff-renderer.zip
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_BINARY_DIR}/renderer/src/renderer/emulator.exe DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
endif()
|
||||
|
||||
set(TEST_BENCH OFF CACHE BOOL "Enable testing")
|
||||
|
||||
if(TEST_BENCH)
|
||||
|
@ -39,6 +39,8 @@ target_link_libraries(core PRIVATE
|
||||
OptickCore
|
||||
psOff_utility
|
||||
config_emu.lib
|
||||
onecore.lib
|
||||
VulkanMemoryAllocator
|
||||
${Vulkan_LIBRARIES}
|
||||
)
|
||||
|
||||
@ -48,4 +50,4 @@ ADD_CUSTOM_COMMAND(TARGET core POST_BUILD
|
||||
${CMAKE_BINARY_DIR}/lib)
|
||||
|
||||
install(FILES $<TARGET_PDB_FILE:core> DESTINATION debug OPTIONAL)
|
||||
install(TARGETS core LIBRARY DESTINATION .)
|
||||
install(TARGETS core LIBRARY DESTINATION .)
|
@ -1,5 +1,10 @@
|
||||
add_library(dmem OBJECT
|
||||
dmem.cpp
|
||||
directmem.cpp
|
||||
)
|
||||
|
||||
add_dependencies(dmem third_party psOff_utility)
|
||||
add_dependencies(dmem third_party psOff_utility)
|
||||
|
||||
target_include_directories(dmem PRIVATE
|
||||
${Vulkan_INCLUDE_DIRS}
|
||||
)
|
419
core/dmem/directmem.cpp
Normal file
419
core/dmem/directmem.cpp
Normal file
@ -0,0 +1,419 @@
|
||||
#define __APICALL_EXTERN
|
||||
#include "dmem.h"
|
||||
#undef __APICALL_EXTERN
|
||||
|
||||
#include "core/imports/exports/procParam.h"
|
||||
#include "core/imports/imports_runtime.h"
|
||||
#include "core/kernel/filesystem.h"
|
||||
#include "core/videoout/videoout.h"
|
||||
#include "logging.h"
|
||||
#include "modules/libkernel/codes.h"
|
||||
#include "modules/libkernel/dmem.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <map>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
#include <windows.h>
|
||||
|
||||
#undef min
|
||||
LOG_DEFINE_MODULE(DirectMemory);
|
||||
|
||||
namespace {
|
||||
constexpr uint64_t DIRECTMEM_START = 0x100000000u;
|
||||
|
||||
enum class MemoryState {
|
||||
Free,
|
||||
Reserved,
|
||||
Commited,
|
||||
};
|
||||
|
||||
struct MemoryMapping {
|
||||
uint64_t addr = 0;
|
||||
|
||||
uint64_t heapAddr = 0; // addr for MemoryInfo
|
||||
|
||||
uint64_t size = 0;
|
||||
uint64_t alignment = 0;
|
||||
|
||||
VmaVirtualAllocation vmaAlloc;
|
||||
};
|
||||
|
||||
struct MemoryInfo {
|
||||
uint64_t addr = 0;
|
||||
void* allocAddr = nullptr;
|
||||
|
||||
uint64_t size = 0;
|
||||
uint64_t alignment = 0;
|
||||
|
||||
int memoryType = 0;
|
||||
int prot = 0;
|
||||
|
||||
VmaVirtualAllocation vmaAlloc;
|
||||
VmaVirtualBlock vmaBlock = nullptr;
|
||||
|
||||
MemoryState state = MemoryState::Free;
|
||||
};
|
||||
|
||||
bool checkIsGPU(int protection) {
|
||||
return (protection & 0xf0) > 0;
|
||||
}
|
||||
|
||||
DWORD convProtection(int prot) {
|
||||
switch (prot & 0xf) {
|
||||
case 0: return PAGE_NOACCESS;
|
||||
case 1: return PAGE_READONLY;
|
||||
case 2:
|
||||
case 3: return PAGE_READWRITE;
|
||||
case 4: return PAGE_EXECUTE;
|
||||
case 5: return PAGE_EXECUTE_READ;
|
||||
case 6:
|
||||
case 7: return PAGE_EXECUTE_READWRITE;
|
||||
}
|
||||
|
||||
if (checkIsGPU(prot)) {
|
||||
return PAGE_READWRITE; // special case: cpu read/writes gpumemory on host memory
|
||||
}
|
||||
|
||||
return PAGE_NOACCESS;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class DirectMemory: public IDirectMemory {
|
||||
boost::mutex m_mutexInt;
|
||||
|
||||
std::map<uint64_t, MemoryInfo> m_objects;
|
||||
std::map<uint64_t, MemoryMapping> m_mappings;
|
||||
|
||||
uint64_t m_allocSize = 0;
|
||||
uint64_t m_usedSize = 0;
|
||||
|
||||
uint64_t m_sdkVersion = 0;
|
||||
|
||||
VmaVirtualBlock m_virtualDeviceMemory;
|
||||
|
||||
uint64_t getSDKVersion() {
|
||||
if (m_sdkVersion == 0) {
|
||||
auto* procParam = (ProcParam*)accessRuntimeExport()->mainModuleInfo().procParamAddr;
|
||||
m_sdkVersion = procParam->header.sdkVersion;
|
||||
}
|
||||
|
||||
return m_sdkVersion;
|
||||
}
|
||||
|
||||
int retNoMem() {
|
||||
if (m_sdkVersion < 0x3500000) return getErr(ErrCode::_EINVAL);
|
||||
return getErr(ErrCode::_ENOMEM);
|
||||
}
|
||||
|
||||
MemoryInfo* getMemoryInfo(uint64_t len, uint64_t alignment, int prot, VmaVirtualAllocation& outAlloc, uint64_t& outAddr);
|
||||
|
||||
public:
|
||||
DirectMemory() {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
VmaVirtualBlockCreateInfo blockCreateInfo = {
|
||||
.size = SCE_KERNEL_MAIN_DMEM_SIZE,
|
||||
};
|
||||
|
||||
if (auto result = vmaCreateVirtualBlock(&blockCreateInfo, &m_virtualDeviceMemory); result != VK_SUCCESS) {
|
||||
LOG_CRIT(L"vmaCreateVirtualBlock err:%S", string_VkResult(result));
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~DirectMemory() { deinit(); }
|
||||
|
||||
// ### Interface
|
||||
int alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) final;
|
||||
int free(off_t start, size_t len) final;
|
||||
|
||||
int map(uint64_t vaddr, off_t directMemoryOffset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) final;
|
||||
int unmap(uint64_t vaddr, uint64_t size) final;
|
||||
|
||||
virtual int reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) final;
|
||||
|
||||
uint64_t size() const final;
|
||||
|
||||
int getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) final;
|
||||
|
||||
void deinit() final;
|
||||
};
|
||||
|
||||
IDirectMemory& accessDirectMemory() {
|
||||
static DirectMemory obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
MemoryInfo* DirectMemory::getMemoryInfo(uint64_t len, uint64_t alignment, int prot, VmaVirtualAllocation& outAlloc, uint64_t& outAddr) {
|
||||
if (m_objects.empty()) return nullptr;
|
||||
|
||||
VmaVirtualAllocationCreateInfo allocCreateInfo = {
|
||||
.size = len,
|
||||
.alignment = alignment,
|
||||
};
|
||||
|
||||
for (auto& item: m_objects) {
|
||||
if (item.second.state == MemoryState::Reserved) continue;
|
||||
|
||||
if (item.second.state == MemoryState::Commited && prot != item.second.prot) continue;
|
||||
|
||||
if (auto result = vmaVirtualAllocate(item.second.vmaBlock, &allocCreateInfo, &outAlloc, &outAddr); result == VK_SUCCESS) {
|
||||
return &item.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int DirectMemory::alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
|
||||
if ((alignment > 0 && !util::isPowerOfTwo(alignment)) || (len % SCE_KERNEL_PAGE_SIZE != 0) || (alignment % SCE_KERNEL_PAGE_SIZE != 0))
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
|
||||
boost::unique_lock lock(m_mutexInt);
|
||||
|
||||
VmaVirtualAllocationCreateInfo allocCreateInfo = {
|
||||
.size = len,
|
||||
.alignment = alignment,
|
||||
};
|
||||
|
||||
// Get block from device memory
|
||||
VmaVirtualAllocation alloc;
|
||||
|
||||
if (auto result = vmaVirtualAllocate(m_virtualDeviceMemory, &allocCreateInfo, &alloc, outAddr); result != VK_SUCCESS) {
|
||||
LOG_ERR(L"Alloc Error| len:0x%08llx alignment:0x%08llx memorytype:%d err:%d", len, alignment, memoryType, GetLastError());
|
||||
return getErr(ErrCode::_ENOMEM);
|
||||
}
|
||||
// - check devicememory
|
||||
|
||||
*outAddr += DIRECTMEM_START; // For debugging info
|
||||
|
||||
// Device has space -> Create allocation
|
||||
VmaVirtualBlockCreateInfo blockCreateInfo = {
|
||||
.size = len,
|
||||
};
|
||||
VmaVirtualBlock block;
|
||||
|
||||
if (auto result = vmaCreateVirtualBlock(&blockCreateInfo, &block); result != VK_SUCCESS) {
|
||||
LOG_ERR(L"Alloc Error| len:0x%08llx alignment:0x%08llx memorytype:%d err:%d", len, alignment, memoryType, GetLastError());
|
||||
return getErr(ErrCode::_ENOMEM);
|
||||
}
|
||||
// -
|
||||
|
||||
m_allocSize += len;
|
||||
m_objects.emplace(std::make_pair(
|
||||
*outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = memoryType, .vmaAlloc = alloc, .vmaBlock = block}));
|
||||
|
||||
LOG_DEBUG(L"-> Allocated: len:0x%08llx alignment:0x%08llx memorytype:%d -> 0x%08llx", len, alignment, memoryType, *outAddr);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int DirectMemory::free(off_t start, size_t len) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
|
||||
boost::unique_lock lock(m_mutexInt);
|
||||
|
||||
uint64_t addr = DIRECTMEM_START + start;
|
||||
|
||||
m_allocSize -= len;
|
||||
|
||||
// Find the object
|
||||
if (m_objects.empty()) return Ok;
|
||||
|
||||
auto itHeap = m_objects.lower_bound(addr);
|
||||
if (itHeap == m_objects.end() || (itHeap != m_objects.begin() && itHeap->first != addr)) --itHeap; // Get the correct item
|
||||
|
||||
if (!(itHeap->first <= addr && (itHeap->first + itHeap->second.size >= addr))) return Ok; // Can't be found
|
||||
//-
|
||||
|
||||
LOG_DEBUG(L"free| addr:0x%08llx len:0x%08llx heap -> addr:0x%08llx len:0x%08llx", addr, len, itHeap->first, itHeap->second.size);
|
||||
|
||||
// special: Check reserve if full reservation or commits
|
||||
if (itHeap->second.state == MemoryState::Reserved) {
|
||||
// todo
|
||||
VirtualFree((void*)itHeap->second.addr, itHeap->second.size, 0);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
if (itHeap->first != addr || itHeap->second.size != len) {
|
||||
LOG_ERR(L"free Error| start:0x%08llx len:0x%08llx != start:0x%08llx len:0x%08llx", addr, len, itHeap->first, itHeap->second.size);
|
||||
}
|
||||
|
||||
if (checkIsGPU(itHeap->second.prot)) {
|
||||
// todo
|
||||
|
||||
} else {
|
||||
if (itHeap->second.allocAddr != 0) VirtualFree(itHeap->second.allocAddr, itHeap->second.size, 0);
|
||||
}
|
||||
|
||||
{
|
||||
std::list<uint64_t> dump;
|
||||
for (auto& item: m_mappings) {
|
||||
if (item.second.heapAddr == itHeap->first) {
|
||||
m_usedSize -= item.second.size;
|
||||
LOG_TRACE(L"Missing unmap for addr:0x%08llx len:0x%08llx, force unmap", item.second.addr, item.second.size);
|
||||
|
||||
vmaVirtualFree(itHeap->second.vmaBlock, item.second.vmaAlloc);
|
||||
unregisterMapping(item.first);
|
||||
dump.push_back(item.first);
|
||||
}
|
||||
|
||||
for (auto item: dump) {
|
||||
m_mappings.erase(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vmaDestroyVirtualBlock(itHeap->second.vmaBlock);
|
||||
vmaVirtualFree(m_virtualDeviceMemory, itHeap->second.vmaAlloc);
|
||||
|
||||
m_objects.erase(itHeap);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
|
||||
boost::unique_lock lock(m_mutexInt);
|
||||
if (flags & (int)filesystem::SceMapMode::VOID_) {
|
||||
LOG_CRIT(L"todo void map");
|
||||
}
|
||||
if (flags & (int)filesystem::SceMapMode::FIXED) {
|
||||
LOG_CRIT(L"todo fixed map");
|
||||
}
|
||||
|
||||
VmaVirtualAllocation alloc = nullptr;
|
||||
|
||||
// search for free space
|
||||
uint64_t fakeAddrOffset = 0;
|
||||
MemoryInfo* info = getMemoryInfo(len, alignment, prot, alloc, fakeAddrOffset);
|
||||
if (info == nullptr) return retNoMem();
|
||||
// -
|
||||
|
||||
// Check if Commit needed
|
||||
if (info->state == MemoryState::Free) {
|
||||
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
|
||||
MEM_EXTENDED_PARAMETER extendedParams = {0};
|
||||
|
||||
addressReqs.Alignment = 0; // 64 KB alignment
|
||||
addressReqs.LowestStartingAddress = (PVOID)DIRECTMEM_START;
|
||||
addressReqs.HighestEndingAddress = (PVOID)0;
|
||||
|
||||
extendedParams.Type = MemExtendedParameterAddressRequirements;
|
||||
extendedParams.Pointer = &addressReqs;
|
||||
|
||||
void* ptr = VirtualAlloc2(NULL, 0, info->size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, convProtection(prot), &extendedParams, 1);
|
||||
if (ptr == 0) {
|
||||
auto const err = GetLastError();
|
||||
LOG_ERR(L"Commit Error| addr:0x%08llx len:0x%08llx err:%d", info->addr, info->size, GetLastError());
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
info->allocAddr = ptr;
|
||||
info->state = MemoryState::Commited;
|
||||
LOG_DEBUG(L"Commit| addr:0x%08llx len:0x%08llx prot:%d ->", info->addr, info->size, prot, ptr);
|
||||
}
|
||||
// - commit
|
||||
|
||||
*outAddr = (uint64_t)info->allocAddr + fakeAddrOffset;
|
||||
m_mappings.emplace(
|
||||
std::make_pair(*outAddr, MemoryMapping {.addr = *outAddr, .heapAddr = info->addr, .size = len, .alignment = alignment, .vmaAlloc = alloc}));
|
||||
registerMapping(*outAddr, MappingType::Direct);
|
||||
m_usedSize += len;
|
||||
|
||||
LOG_DEBUG(L"-> Map: start:0x%08llx(0x%lx) len:0x%08llx alignment:0x%08llx prot:%d -> 0x%08llx", vaddr, offset, len, alignment, prot, *outAddr);
|
||||
|
||||
if (checkIsGPU(prot)) {
|
||||
if (!accessVideoOut().notify_allocHeap(*outAddr, len, prot)) {
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int DirectMemory::reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
|
||||
boost::unique_lock lock(m_mutexInt);
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
|
||||
MEM_EXTENDED_PARAMETER extendedParams = {0};
|
||||
|
||||
addressReqs.Alignment = alignment;
|
||||
addressReqs.LowestStartingAddress = (PVOID)0x100000000;
|
||||
addressReqs.HighestEndingAddress = (PVOID)0;
|
||||
|
||||
extendedParams.Type = MemExtendedParameterAddressRequirements;
|
||||
extendedParams.Pointer = &addressReqs;
|
||||
|
||||
*outAddr = (uint64_t)VirtualAlloc2(NULL, 0, len, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_NOACCESS, &extendedParams, 1);
|
||||
if (*outAddr == 0) {
|
||||
auto const err = GetLastError();
|
||||
LOG_ERR(L"Reserve Error| addr:0x%08llx len:0x%08llx align:0x%08llx flags:0x%x err:%d", start, len, alignment, flags, GetLastError());
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
LOG_DEBUG(L"-> Reserve: start:0x%08llx len:0x%08llx alignment:0x%08llx flags:0x%x -> 0x%08llx", start, len, alignment, flags, *outAddr);
|
||||
|
||||
m_objects.emplace(
|
||||
std::make_pair(*outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = 0, .state = MemoryState::Reserved}));
|
||||
return Ok;
|
||||
}
|
||||
|
||||
int DirectMemory::unmap(uint64_t vaddr, uint64_t size) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
|
||||
boost::unique_lock lock(m_mutexInt);
|
||||
|
||||
// Find the object
|
||||
if (m_mappings.empty()) return Ok;
|
||||
|
||||
auto itItem = m_mappings.lower_bound(vaddr);
|
||||
if (itItem == m_mappings.end() || (itItem != m_mappings.begin() && itItem->first != vaddr)) --itItem; // Get the correct item
|
||||
|
||||
if (!(itItem->first <= vaddr && (itItem->first + itItem->second.size >= vaddr))) {
|
||||
LOG_ERR(L"Couldn't find mapping for 0x%08llx 0x%08llx", vaddr, size);
|
||||
return -1;
|
||||
}
|
||||
//-
|
||||
|
||||
if (auto it = m_objects.find(itItem->second.heapAddr); it != m_objects.end()) {
|
||||
vmaVirtualFree(it->second.vmaBlock, itItem->second.vmaAlloc);
|
||||
} else {
|
||||
LOG_ERR(L"Couldn't find Heap for 0x%08llx", itItem->second.heapAddr);
|
||||
}
|
||||
|
||||
LOG_DEBUG(L"unmap| 0x%08llx 0x%08llx", vaddr, size);
|
||||
m_usedSize -= itItem->second.size;
|
||||
|
||||
m_mappings.erase(itItem);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
uint64_t DirectMemory::size() const {
|
||||
return m_allocSize;
|
||||
}
|
||||
|
||||
int DirectMemory::getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
||||
LOG_USE_MODULE(DirectMemory);
|
||||
LOG_ERR(L"availableSize: start:0x%08llx end:0x%08llx alignment:0x%08llx", start, end, alignment);
|
||||
|
||||
*startOut = m_usedSize;
|
||||
*sizeOut = m_allocSize - m_usedSize;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void DirectMemory::deinit() {
|
||||
for (auto& item: m_objects) {
|
||||
if (checkIsGPU(item.second.prot)) {
|
||||
// done by gpuMemoryManager
|
||||
} else {
|
||||
// memory::free(item.first);
|
||||
}
|
||||
}
|
||||
m_objects.clear();
|
||||
}
|
@ -36,159 +36,6 @@ auto getData() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Allocates the sections (memory pool is done internally (in app))
|
||||
class PhysicalMemory: public IPhysicalMemory {
|
||||
std::mutex m_mutex_int;
|
||||
|
||||
std::unordered_map<uint64_t, MemoryInfo> m_objects;
|
||||
|
||||
public:
|
||||
PhysicalMemory() = default;
|
||||
|
||||
virtual ~PhysicalMemory() { deinit(); }
|
||||
|
||||
uint64_t alloc(uint64_t vaddr, size_t len, int memoryTye) final;
|
||||
bool reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) final;
|
||||
uintptr_t commit(uint64_t base, uint64_t offset, size_t len, size_t alignment, int prot) final;
|
||||
bool Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) final;
|
||||
bool Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) final;
|
||||
bool Unmap(uint64_t vaddr, uint64_t size) final;
|
||||
void deinit() final;
|
||||
};
|
||||
|
||||
IPhysicalMemory& accessPysicalMemory() {
|
||||
static PhysicalMemory inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
uint64_t PhysicalMemory::alloc(uint64_t vaddr, size_t len, int prot) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
m_allocSize += len;
|
||||
LOG_DEBUG(L"Alloc: 0x%08llx len:0x%08llx prot:%d curSize=0x%08llx", vaddr, len, prot, m_allocSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
|
||||
auto const isGpu = memoryType == 3;
|
||||
*outAddr = memory::reserve(start, len, alignment, isGpu);
|
||||
|
||||
{
|
||||
std::unique_lock const lock(m_mutex_int);
|
||||
m_availableSize -= len;
|
||||
}
|
||||
|
||||
LOG_DEBUG(L"Reserve| start:0x%08llx size:%08llx alignment:%llu memType:%d -> @%08llx", start, len, alignment, memoryType, *outAddr);
|
||||
return *outAddr != 0;
|
||||
}
|
||||
|
||||
uintptr_t PhysicalMemory::commit(uint64_t base, uint64_t vaddr, size_t len, size_t alignment, int prot) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
|
||||
uintptr_t addr = 0;
|
||||
|
||||
auto [protCPU, protGPU] = util::getMemoryProtection(prot);
|
||||
|
||||
if (protGPU != 0) {
|
||||
addr = memory::allocGPUMemory(base, 0, len, alignment);
|
||||
} else {
|
||||
addr = memory::commit(base, 0, len, alignment, prot);
|
||||
}
|
||||
|
||||
m_objects[addr] = MemoryInfo {.isGpu = protGPU != 0, .size = len};
|
||||
|
||||
if (protGPU != 0) {
|
||||
if (!accessVideoOut().notify_allocHeap(addr, len, prot)) {
|
||||
LOG_ERR(L"Commit| Couldn't allocHeap| base:0x%08llx offset:0x%08llx size:%08llx alignment:%llu prot:%d -> @%08llx", base, vaddr, len, alignment, prot,
|
||||
addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG(L"Commit| base:0x%08llx offset:0x%08llx size:%08llx alignment:%llu prot:%d -> @%08llx", base, vaddr, len, alignment, prot, addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
|
||||
bool mapped = false;
|
||||
*outAddr = 0;
|
||||
{
|
||||
std::unique_lock const lock(m_mutex_int);
|
||||
|
||||
auto [protCPU, protGPU] = util::getMemoryProtection(prot);
|
||||
|
||||
if (allocFixed) {
|
||||
if (memory::allocFixed(physAddr, len, prot)) {
|
||||
*outAddr = physAddr;
|
||||
}
|
||||
} else {
|
||||
*outAddr = memory::allocAligned(physAddr, len, prot, alignment);
|
||||
}
|
||||
|
||||
m_objects[*outAddr] = MemoryInfo {.isGpu = protGPU != 0, .size = len};
|
||||
|
||||
if (protGPU != 0) {
|
||||
if (!accessVideoOut().notify_allocHeap(*outAddr, len, prot)) {
|
||||
LOG_ERR(L"Map| Couldn't allocHeap vaddr:0x%08llx physAddr:0x%08llx len:0x%08llx prot:0x%x -> out:0x%08llx", vaddr, physAddr, len, prot, *outAddr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (*outAddr == NULL) {
|
||||
return false;
|
||||
}
|
||||
m_availableSize -= len;
|
||||
}
|
||||
|
||||
LOG_INFO(L"Map| vaddr:0x%08llx physAddr:0x%08llx len:0x%08llx prot:0x%x -> out:0x%08llx", vaddr, physAddr, len, prot, *outAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
||||
m_allocSize -= len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Unmap(uint64_t vaddr, uint64_t size) {
|
||||
LOG_USE_MODULE(MemoryManager);
|
||||
|
||||
if (auto it = m_objects.find(vaddr); it != m_objects.end()) {
|
||||
if (it->second.isGpu) {
|
||||
// if(isGPU) accessGpuMemory().freeHeap(vaddr); // todo, notify free (should free host memory aswell)
|
||||
memory::free(vaddr);
|
||||
} else {
|
||||
memory::free(vaddr);
|
||||
}
|
||||
} else {
|
||||
LOG_ERR(L"Unmap not in map: vaddr:0x%08llx len:%lld", vaddr, size);
|
||||
memory::free(vaddr);
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock const lock(m_mutex_int);
|
||||
m_availableSize += size;
|
||||
}
|
||||
|
||||
LOG_INFO(L"Unmap: vaddr:0x%08llx len:%lld", vaddr, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhysicalMemory::deinit() {
|
||||
for (auto& item: m_objects) {
|
||||
if (item.second.isGpu) {
|
||||
// done by gpuMemoryManager
|
||||
} else {
|
||||
memory::free(item.first);
|
||||
}
|
||||
}
|
||||
|
||||
m_objects.clear();
|
||||
}
|
||||
|
||||
class FlexibleMemory: public IFlexibleMemory {
|
||||
uint64_t m_totalAllocated = 0;
|
||||
std::mutex m_mutex_int;
|
||||
|
@ -4,35 +4,30 @@
|
||||
|
||||
enum class GpuMemoryMode { NoAccess, Read, Write, ReadWrite };
|
||||
|
||||
enum class MappingType { None, File, Flexible, Fixed };
|
||||
enum class MappingType { None, File, Flexible, Fixed, Direct };
|
||||
|
||||
class IPhysicalMemory {
|
||||
CLASS_NO_COPY(IPhysicalMemory);
|
||||
class IDirectMemory {
|
||||
CLASS_NO_COPY(IDirectMemory);
|
||||
CLASS_NO_MOVE(IDirectMemory);
|
||||
|
||||
protected:
|
||||
IPhysicalMemory() = default;
|
||||
uint64_t m_availableSize = 5000000000llu; // todo get from system memory
|
||||
size_t m_allocSize = 0;
|
||||
IDirectMemory() = default;
|
||||
|
||||
public:
|
||||
virtual ~IPhysicalMemory() = default;
|
||||
virtual ~IDirectMemory() = default;
|
||||
|
||||
void getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
||||
*startOut = size() - m_availableSize;
|
||||
*sizeOut = m_availableSize;
|
||||
}
|
||||
virtual int alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) = 0;
|
||||
virtual int free(off_t start, size_t len) = 0;
|
||||
|
||||
virtual uint64_t alloc(uint64_t vaddr, size_t len, int memoryType) = 0;
|
||||
virtual int map(uint64_t vaddr, off_t directMemoryOffset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) = 0;
|
||||
virtual int unmap(uint64_t vaddr, uint64_t size) = 0;
|
||||
|
||||
virtual bool reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) = 0;
|
||||
virtual uintptr_t commit(uint64_t base, uint64_t offset, size_t len, size_t alignment, int prot) = 0;
|
||||
virtual int reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) = 0;
|
||||
|
||||
virtual bool Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) = 0;
|
||||
virtual bool Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) = 0;
|
||||
virtual bool Unmap(uint64_t vaddr, uint64_t size) = 0;
|
||||
virtual void deinit() = 0;
|
||||
virtual uint64_t size() const = 0;
|
||||
virtual int getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) = 0;
|
||||
|
||||
uint64_t const size() const { return m_allocSize; } // use system ram
|
||||
virtual void deinit() = 0;
|
||||
};
|
||||
|
||||
class IFlexibleMemory {
|
||||
@ -82,6 +77,7 @@ __APICALL void registerMapping(uint64_t vaddr, MappingType type);
|
||||
*/
|
||||
__APICALL MappingType unregisterMapping(uint64_t vaddr);
|
||||
|
||||
__APICALL IPhysicalMemory& accessPysicalMemory();
|
||||
__APICALL IDirectMemory& accessDirectMemory();
|
||||
|
||||
__APICALL IFlexibleMemory& accessFlexibleMemory();
|
||||
#undef __APICALL
|
@ -157,6 +157,10 @@ int munmap(void* addr, size_t len) {
|
||||
return UnmapViewOfFile(addr) != 0 ? Ok : -1;
|
||||
} break;
|
||||
|
||||
case MappingType::Direct: {
|
||||
return accessDirectMemory().unmap((uint64_t)addr, len);
|
||||
} break;
|
||||
|
||||
case MappingType::Flexible: {
|
||||
return accessFlexibleMemory().destroy((uint64_t)addr, len) != 0 ? Ok : -1;
|
||||
} break;
|
||||
@ -166,7 +170,7 @@ int munmap(void* addr, size_t len) {
|
||||
} break;
|
||||
|
||||
case MappingType::None: {
|
||||
LOG_ERR(L"munmap unkown 0x%08llx 0x%08llx", addr, len);
|
||||
LOG_ERR(L"munmap unkown 0x%08llx 0x%08llx type:%d", addr, len, type);
|
||||
} break;
|
||||
}
|
||||
return -1;
|
||||
@ -729,4 +733,4 @@ int64_t lwfsLseek(int fd, int64_t offset, int whence) {
|
||||
size_t lwfsWrite(int fd, const void* buf, size_t nbytes) {
|
||||
return Ok;
|
||||
}
|
||||
} // namespace filesystem
|
||||
} // namespace filesystem
|
@ -126,12 +126,17 @@ std::optional<ImageData> ImageHandler::getImage_blocking() {
|
||||
|
||||
VkResult result = VK_SUCCESS;
|
||||
for (; numTries >= 0; --numTries) {
|
||||
if (result = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, imageData.semImageReady, VK_NULL_HANDLE, &imageData.index); result != VK_SUCCESS) {
|
||||
// toggle every 1ms
|
||||
if (result = vkAcquireNextImageKHR(m_device, m_swapchain, (uint64_t)1e6, imageData.semImageReady, VK_NULL_HANDLE, &imageData.index);
|
||||
result != VK_SUCCESS) {
|
||||
if (result == VK_NOT_READY) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
||||
} else if (result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
recreate();
|
||||
++numTries;
|
||||
} else if (result == VK_TIMEOUT) {
|
||||
if (m_stop) return {};
|
||||
++numTries;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
@ -303,4 +308,4 @@ void ImageHandler::deinit() {
|
||||
if (m_swapchain != nullptr) vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
|
||||
|
||||
printf("deinit ImageHandler| done\n");
|
||||
}
|
||||
}
|
@ -278,7 +278,10 @@ class VideoOut: public IVideoOut, private IEventsGraphics {
|
||||
|
||||
void getSafeAreaRatio(float* area) final {
|
||||
auto ext = m_imageHandler.get()->getExtent();
|
||||
if (area != nullptr) *area = ext.width / (float)ext.height;
|
||||
if (area != nullptr) {
|
||||
*area = 0.781298f; // todo check what's up here
|
||||
//*area = (float)ext.height / (float)ext.width;
|
||||
}
|
||||
}
|
||||
|
||||
vulkan::DeviceInfo* getDeviceInfo() final { return &m_vulkanObj->deviceInfo; }
|
||||
@ -489,8 +492,8 @@ int VideoOut::SDLInit(uint32_t flags) {
|
||||
m_condSDL2.notify_one();
|
||||
|
||||
lock.lock();
|
||||
m_condDone.wait(lock, [=] { return result; });
|
||||
return result;
|
||||
m_condDone.wait(lock, [=] { return result >= 0; });
|
||||
return result == 0 ? Ok : -1;
|
||||
}
|
||||
|
||||
void VideoOut::transferDisplay(ImageData const& imageData, vulkan::SwapchainData::DisplayBuffers& displayBufferMeta, VkSemaphore waitSema, size_t waitValue) {
|
||||
@ -670,7 +673,7 @@ int VideoOut::registerBuffers(int handle, int startIndex, void* const* addresses
|
||||
bufferSet.buffers[n].bufferAlign = displaySizeAlign;
|
||||
LOG_INFO(L"+bufferset[%d] buffer:%d vaddr:0x%08llx-0x%08llx", setIndex, n, (uint64_t)addresses[n], (uint64_t)addresses[n] + displaySizeAlign);
|
||||
|
||||
auto [format, colorSpace] = vulkan::getDisplayFormat(m_vulkanObj);
|
||||
auto [format, _] = vulkan::getDisplayFormat(m_vulkanObj);
|
||||
if (!m_graphics->registerDisplayBuffer(bufferSet.buffers[n].bufferVaddr, VkExtent2D {.width = _att->width, .height = _att->height}, _att->pitchInPixel,
|
||||
format))
|
||||
return -1;
|
||||
@ -986,4 +989,4 @@ uint64_t getImageAlignment(VkFormat format, VkExtent3D const& extent) {
|
||||
vkGetImageMemoryRequirements(device, image, &reqs);
|
||||
vkDestroyImage(device, image, nullptr);
|
||||
return reqs.alignment;
|
||||
}
|
||||
}
|
@ -34,17 +34,21 @@ std::pair<VkFormat, VkColorSpaceKHR> getDisplayFormat(VulkanObj* obj) {
|
||||
if (obj->surfaceCapabilities.formats.empty()) {
|
||||
return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||
}
|
||||
|
||||
VkFormat format = obj->surfaceCapabilities.formats[0].format;
|
||||
VkColorSpaceKHR imageColorSpace = obj->surfaceCapabilities.formats[0].colorSpace;
|
||||
if (obj->surfaceCapabilities.format_unorm_bgra32) {
|
||||
format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
} else if (obj->surfaceCapabilities.format_srgb_bgra32) {
|
||||
format = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
bool found = false;
|
||||
for (auto const& format: obj->surfaceCapabilities.formats) {
|
||||
if (format.format == VK_FORMAT_R8G8B8A8_SRGB) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return {format, imageColorSpace};
|
||||
|
||||
if (!found) {
|
||||
LOG_USE_MODULE(vulkanHelper);
|
||||
for (auto const& format: obj->surfaceCapabilities.formats) {
|
||||
LOG_ERR(L"format %S", string_VkFormat(format.format));
|
||||
}
|
||||
LOG_CRIT(L"VK_FORMAT_B8G8R8A8_SRGB not supported");
|
||||
}
|
||||
return {VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||
}
|
||||
|
||||
void submitDisplayTransfer(SwapchainData::DisplayBuffers const* displayBuffer, ImageData const& imageData, QueueInfo const* queue, VkSemaphore waitSema,
|
||||
@ -217,4 +221,4 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(VkDevice devi
|
||||
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) {
|
||||
static auto fn = (PFN_vkGetMemoryHostPointerPropertiesEXT)vkGetInstanceProcAddr(vulkan::getVkInstance(), "vkGetMemoryHostPointerPropertiesEXT");
|
||||
return fn(device, handleType, pHostPointer, pMemoryHostPointerProperties);
|
||||
}
|
||||
}
|
@ -14,7 +14,8 @@ constexpr uint8_t SCE_KERNEL_PROT_GPU_WRITE = 0x20;
|
||||
constexpr uint8_t SCE_KERNEL_PROT_GPU_RW = 0x30;
|
||||
constexpr uint8_t SCE_KERNEL_PROT_GPU_ALL = 0x30;
|
||||
|
||||
constexpr uint32_t SCE_KERNEL_PAGE_SIZE = 16384;
|
||||
constexpr uint32_t SCE_KERNEL_PAGE_SIZE = 16384;
|
||||
constexpr uint64_t SCE_KERNEL_MAIN_DMEM_SIZE = 0x180000000;
|
||||
|
||||
constexpr uint32_t SCE_KERNEL_AIO_SCHED_WINDOW_MAX = 128;
|
||||
constexpr uint32_t SCE_KERNEL_AIO_DELAYED_COUNT_MAX = 128;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "assert.h"
|
||||
#include "common.h"
|
||||
#include "core/dmem/dmem.h"
|
||||
#include "core/kernel/filesystem.h"
|
||||
#include "core/memory/memory.h"
|
||||
#include "core/videoout/videoout.h"
|
||||
#include "logging.h"
|
||||
@ -18,7 +19,7 @@ extern "C" {
|
||||
EXPORT SYSV_ABI size_t sceKernelGetDirectMemorySize() {
|
||||
LOG_USE_MODULE(dmem);
|
||||
|
||||
auto size = accessPysicalMemory().size();
|
||||
auto size = accessDirectMemory().size();
|
||||
LOG_DEBUG(L"%S size:0x%08llx", __FUNCTION__, size);
|
||||
return size;
|
||||
}
|
||||
@ -56,56 +57,41 @@ EXPORT SYSV_ABI int32_t sceKernelGetPrtAperture(int index, void** addr, size_t*
|
||||
return Ok;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelAllocateDirectMemory(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, int memoryType, off_t* physAddrOut) {
|
||||
EXPORT SYSV_ABI int32_t sceKernelAllocateDirectMemory(uint64_t searchStart, uint64_t searchEnd, size_t len, size_t alignment, int memoryType,
|
||||
uint64_t* physAddrOut) {
|
||||
if (len == 0 || physAddrOut == nullptr) {
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
accessPysicalMemory().alloc(0, len, memoryType);
|
||||
*physAddrOut = 1; // done with map
|
||||
return Ok;
|
||||
return accessDirectMemory().alloc(len, alignment, memoryType, physAddrOut);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, off_t* physAddrOut) {
|
||||
EXPORT SYSV_ABI int32_t sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, uint64_t* physAddrOut) {
|
||||
if (len == 0 || physAddrOut == nullptr) {
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
*physAddrOut = 1; // done with map
|
||||
return Ok;
|
||||
return accessDirectMemory().alloc(len, alignment, memoryType, physAddrOut);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelReleaseDirectMemory(off_t start, size_t len) {
|
||||
uint64_t vaddr = 0;
|
||||
uint64_t size = 0;
|
||||
|
||||
bool result = accessPysicalMemory().Release(start, len, &vaddr, &size);
|
||||
return Ok;
|
||||
return accessDirectMemory().free(start, len);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelCheckedReleaseDirectMemory(off_t start, size_t len) {
|
||||
uint64_t vaddr = 0;
|
||||
uint64_t size = 0;
|
||||
|
||||
bool result = accessPysicalMemory().Release(start, len, &vaddr, &size);
|
||||
return Ok;
|
||||
return accessDirectMemory().free(start, len);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapNamedDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t alignment,
|
||||
const char* name) {
|
||||
if (!accessPysicalMemory().Map(*addr, directMemoryStart, len, prot, flags == 0x10, alignment, addr)) {
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapNamedDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t offset, size_t alignment, const char* name) {
|
||||
return accessDirectMemory().map(*addr, offset, len, prot, flags, alignment, addr);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t maxPageSize) {
|
||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, directMemoryStart, maxPageSize, nullptr);
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t offset, size_t maxPageSize) {
|
||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, offset, maxPageSize, nullptr);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory2(uint64_t* addr, size_t len, int type, int prot, int flags, off_t directMemoryStart, size_t maxPageSize) {
|
||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, directMemoryStart, maxPageSize, nullptr);
|
||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory2(uint64_t* addr, size_t len, int type, int prot, int flags, off_t offset, size_t maxPageSize) {
|
||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, offset, maxPageSize, nullptr);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelGetDirectMemoryType(off_t start, int* memoryType, off_t* regionStartOut, off_t* regionEndOut) {
|
||||
@ -114,30 +100,38 @@ EXPORT SYSV_ABI int32_t sceKernelGetDirectMemoryType(off_t start, int* memoryTyp
|
||||
return Ok;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap(SceKernelBatchMapEntry* items, int size, int* count) {
|
||||
struct BatchMapEntry {
|
||||
uint64_t start;
|
||||
uint32_t physAddr;
|
||||
size_t length;
|
||||
uint8_t prot;
|
||||
uint8_t type;
|
||||
short pad1;
|
||||
int operation;
|
||||
};
|
||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap2(SceKernelBatchMapEntry* entries, int numberOfEntries, int* numberOfEntriesOut, int flags) {
|
||||
LOG_USE_MODULE(dmem);
|
||||
for (*numberOfEntriesOut = 0; *numberOfEntriesOut < numberOfEntries; ++*numberOfEntriesOut) {
|
||||
auto& batchEntry = (entries)[*numberOfEntriesOut];
|
||||
|
||||
for (*count = 0; *count < size; ++*count) {
|
||||
auto& batchEntry = ((BatchMapEntry*)items)[*count];
|
||||
|
||||
uint64_t addr = accessPysicalMemory().commit(batchEntry.start, batchEntry.physAddr, batchEntry.length, 0, batchEntry.prot);
|
||||
if (addr == 0) {
|
||||
return getErr(ErrCode::_ENOMEM);
|
||||
switch (batchEntry.operation) {
|
||||
case SceKernelMapOp::MAP_DIRECT: {
|
||||
auto res = accessDirectMemory().map(batchEntry.start, batchEntry.physAddr, batchEntry.length, batchEntry.prot, flags, 0, &batchEntry.start);
|
||||
if (res != Ok) {
|
||||
return res;
|
||||
}
|
||||
} break;
|
||||
case SceKernelMapOp::UNMAP: {
|
||||
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||
} break;
|
||||
case SceKernelMapOp::PROTECT: {
|
||||
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||
} break;
|
||||
case SceKernelMapOp::MAP_FLEXIBLE: {
|
||||
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||
} break;
|
||||
case SceKernelMapOp::TYPE_PROTECT: {
|
||||
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap2(SceKernelBatchMapEntry* entries, int numberOfEntries, int* numberOfEntriesOut, int flags) {
|
||||
return sceKernelBatchMap(entries, numberOfEntries, numberOfEntriesOut);
|
||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap(SceKernelBatchMapEntry* items, int size, int* count) {
|
||||
return sceKernelBatchMap2(items, size, count, (int)filesystem::SceMapMode::NO_OVERWRITE);
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelJitCreateSharedMemory(const char* name, size_t len, int maxProt, int* fdOut) {
|
||||
@ -226,17 +220,11 @@ EXPORT SYSV_ABI int32_t sceKernelSetVirtualRangeName(void* start, size_t len, co
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int sceKernelReserveVirtualRange(uintptr_t* addr, size_t len, int flags, size_t alignment) {
|
||||
auto const inAddr = *addr;
|
||||
|
||||
if (len == 0) {
|
||||
if (addr == nullptr || len == 0) {
|
||||
return getErr(ErrCode::_EINVAL);
|
||||
}
|
||||
|
||||
if (!accessPysicalMemory().reserve(inAddr, len, alignment, addr, 1)) {
|
||||
return getErr(ErrCode::_EAGAIN);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
return accessDirectMemory().reserve(*addr, len, alignment, flags, addr);
|
||||
}
|
||||
|
||||
struct QueryInfo {
|
||||
@ -278,7 +266,7 @@ EXPORT SYSV_ABI int32_t sceKernelMtypeprotect(const void* addr, size_t size, int
|
||||
}
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelAvailableDirectMemorySize(off_t start, off_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
||||
accessPysicalMemory().getAvailableSize(start, end, alignment, startOut, sizeOut);
|
||||
accessDirectMemory().getAvailableSize(start, end, alignment, startOut, sizeOut);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
@ -318,7 +306,8 @@ EXPORT SYSV_ABI int32_t sceKernelMemoryPoolDecommit(void* addr, size_t len, int
|
||||
|
||||
EXPORT SYSV_ABI int32_t sceKernelMemoryPoolExpand(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, off_t* physAddrOut) {
|
||||
LOG_USE_MODULE(dmem);
|
||||
LOG_ERR(L"todo %S| start:0x%08llx end:0x%08llx, len:0x%08llx align:0x%08llx", __FUNCTION__, searchStart, searchEnd, len, alignment);
|
||||
*physAddrOut = memory::reserve(0, len, alignment, false);
|
||||
LOG_DEBUG(L"PoolReserve| start:0x%08llx, len:0x%08llx align:0x%08llx-> out:0x%08llx", searchStart, len, alignment, *physAddrOut);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,22 @@
|
||||
#include <modules_include/common.h>
|
||||
|
||||
enum class SceKernelMemoryType { WB_ONION = 0, WC_GARLIC = 3, WB_GARLIC, MEMORY_TYPE_END };
|
||||
enum class SceKernelMapOp : int {
|
||||
MAP_DIRECT,
|
||||
UNMAP,
|
||||
PROTECT,
|
||||
MAP_FLEXIBLE,
|
||||
TYPE_PROTECT,
|
||||
};
|
||||
|
||||
struct SceKernelBatchMapEntry {
|
||||
uint64_t start;
|
||||
uint32_t physAddr;
|
||||
size_t length;
|
||||
uint8_t prot;
|
||||
uint8_t type;
|
||||
short pad1;
|
||||
int operation;
|
||||
uint64_t start;
|
||||
uint32_t physAddr;
|
||||
size_t length;
|
||||
uint8_t prot;
|
||||
uint8_t type;
|
||||
short pad1;
|
||||
SceKernelMapOp operation;
|
||||
};
|
||||
|
||||
struct SceKernelVirtualQueryInfo {
|
||||
@ -78,4 +85,4 @@ struct SceKernelMemoryPoolBlockStats {
|
||||
int availableCachedBlocks;
|
||||
int allocatedFlushedBlocks;
|
||||
int allocatedCachedBlocks;
|
||||
};
|
||||
};
|
@ -18,4 +18,6 @@ include_directories(
|
||||
${PRJ_SRC_DIR}/tools/logging
|
||||
)
|
||||
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(core)
|
||||
|
||||
install(TARGETS semaphore_test RUNTIME DESTINATION .)
|
@ -14,12 +14,4 @@ target_link_libraries(semaphore_test PRIVATE
|
||||
logging_stub.lib
|
||||
libboost_thread
|
||||
libboost_chrono
|
||||
)
|
||||
|
||||
set_target_properties(semaphore_test
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/."
|
||||
)
|
@ -52,8 +52,11 @@ void setThreadName(std::string_view name, void* nativeHandle) {
|
||||
}
|
||||
|
||||
int getPageSize(void) {
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwPageSize;
|
||||
static int pageSize = [] {
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwPageSize;
|
||||
}();
|
||||
return pageSize;
|
||||
}
|
||||
} // namespace util
|
@ -88,6 +88,11 @@ constexpr std::uint64_t alignDown(uint64_t value, uint64_t alignment) {
|
||||
return value & ~(alignment - 1);
|
||||
}
|
||||
|
||||
constexpr bool isPowerOfTwo(int n) {
|
||||
if (n == 0) return false;
|
||||
return (n & (n - 1)) == 0;
|
||||
}
|
||||
|
||||
void setThreadName(std::string_view name);
|
||||
void setThreadName(std::string_view name, void* nativeHandle);
|
||||
|
||||
@ -103,4 +108,4 @@ int getPageSize(void);
|
||||
|
||||
#define CLASS_NO_MOVE(name) \
|
||||
name(name&&) noexcept = delete; \
|
||||
name& operator=(name&&) noexcept = delete
|
||||
name& operator=(name&&) noexcept = delete
|
Loading…
Reference in New Issue
Block a user