android: support 4KB and 16KB page sizes on 64-bit platforms
This commit is contained in:
parent
f3e0f09ca9
commit
6ea61b9084
|
@ -1330,6 +1330,7 @@ if(NOT LIBRETRO)
|
||||||
shell/android-studio/flycast/src/main/jni/src/android_keyboard.h)
|
shell/android-studio/flycast/src/main/jni/src/android_keyboard.h)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE android log)
|
target_link_libraries(${PROJECT_NAME} PRIVATE android log)
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
string(TIMESTAMP YEAR "%Y")
|
string(TIMESTAMP YEAR "%Y")
|
||||||
string(REGEX MATCH "^[^-]+" TAG_VERSION ${GIT_VERSION})
|
string(REGEX MATCH "^[^-]+" TAG_VERSION ${GIT_VERSION})
|
||||||
|
|
|
@ -26,16 +26,14 @@
|
||||||
#include "hw/pvr/elan.h"
|
#include "hw/pvr/elan.h"
|
||||||
#include "rend/TexCache.h"
|
#include "rend/TexCache.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace memwatch
|
namespace memwatch
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Page
|
struct Page
|
||||||
{
|
{
|
||||||
Page() {
|
std::unique_ptr<u8[]> data = std::make_unique<u8[]>(PAGE_SIZE);
|
||||||
// don't initialize data
|
|
||||||
}
|
|
||||||
u8 data[PAGE_SIZE];
|
|
||||||
};
|
};
|
||||||
using PageMap = std::unordered_map<u32, Page>;
|
using PageMap = std::unordered_map<u32, Page>;
|
||||||
|
|
||||||
|
@ -77,7 +75,7 @@ public:
|
||||||
if (offset == (u32)-1)
|
if (offset == (u32)-1)
|
||||||
return false;
|
return false;
|
||||||
offset &= ~PAGE_MASK;
|
offset &= ~PAGE_MASK;
|
||||||
auto rv = pages.emplace(offset, Page());
|
auto rv = pages.try_emplace(offset);
|
||||||
if (!rv.second)
|
if (!rv.second)
|
||||||
// already saved
|
// already saved
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -32,8 +32,9 @@ typedef std::map<void*, RuntimeBlockInfoPtr> bm_Map;
|
||||||
static bm_Set all_temp_blocks;
|
static bm_Set all_temp_blocks;
|
||||||
static bm_List del_blocks;
|
static bm_List del_blocks;
|
||||||
|
|
||||||
bool unprotected_pages[RAM_SIZE_MAX/PAGE_SIZE];
|
static u32 pageCount;
|
||||||
static std::set<RuntimeBlockInfo*> blocks_per_page[RAM_SIZE_MAX/PAGE_SIZE];
|
bool *unprotected_pages;
|
||||||
|
static std::set<RuntimeBlockInfo*> *blocks_per_page;
|
||||||
|
|
||||||
static bm_Map blkmap;
|
static bm_Map blkmap;
|
||||||
// Stats
|
// Stats
|
||||||
|
@ -302,10 +303,10 @@ void bm_ResetCache()
|
||||||
// blkmap includes temp blocks as well
|
// blkmap includes temp blocks as well
|
||||||
all_temp_blocks.clear();
|
all_temp_blocks.clear();
|
||||||
|
|
||||||
for (auto& block_list : blocks_per_page)
|
for (size_t i = 0; i < pageCount; i++)
|
||||||
block_list.clear();
|
blocks_per_page[i].clear();
|
||||||
|
|
||||||
memset(unprotected_pages, 0, sizeof(unprotected_pages));
|
memset(unprotected_pages, 0, pageCount);
|
||||||
|
|
||||||
#ifdef DYNA_OPROF
|
#ifdef DYNA_OPROF
|
||||||
if (oprofHandle)
|
if (oprofHandle)
|
||||||
|
@ -337,6 +338,10 @@ void bm_ResetTempCache(bool full)
|
||||||
|
|
||||||
void bm_Init()
|
void bm_Init()
|
||||||
{
|
{
|
||||||
|
pageCount = RAM_SIZE_MAX / PAGE_SIZE;
|
||||||
|
unprotected_pages = new bool[pageCount];
|
||||||
|
blocks_per_page = new std::set<RuntimeBlockInfo*>[pageCount];
|
||||||
|
|
||||||
#ifdef DYNA_OPROF
|
#ifdef DYNA_OPROF
|
||||||
oprofHandle=op_open_agent();
|
oprofHandle=op_open_agent();
|
||||||
if (oprofHandle==0)
|
if (oprofHandle==0)
|
||||||
|
@ -354,6 +359,8 @@ void bm_Term()
|
||||||
oprofHandle=0;
|
oprofHandle=0;
|
||||||
#endif
|
#endif
|
||||||
bm_Reset();
|
bm_Reset();
|
||||||
|
delete[] unprotected_pages;
|
||||||
|
delete[] blocks_per_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bm_WriteBlockMap(const std::string& file)
|
void bm_WriteBlockMap(const std::string& file)
|
||||||
|
|
|
@ -86,7 +86,7 @@ void bm_Term();
|
||||||
void bm_vmem_pagefill(void** ptr,u32 size_bytes);
|
void bm_vmem_pagefill(void** ptr,u32 size_bytes);
|
||||||
static inline bool bm_IsRamPageProtected(u32 addr)
|
static inline bool bm_IsRamPageProtected(u32 addr)
|
||||||
{
|
{
|
||||||
extern bool unprotected_pages[RAM_SIZE_MAX/PAGE_SIZE];
|
extern bool *unprotected_pages;
|
||||||
addr &= RAM_MASK;
|
addr &= RAM_MASK;
|
||||||
return !unprotected_pages[addr / PAGE_SIZE];
|
return !unprotected_pages[addr / PAGE_SIZE];
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,13 +226,13 @@ static_assert(sizeof(Sh4Context) == 512, "Invalid Sh4Context size");
|
||||||
// For other systems we could use PAGE_SIZE, except on windows that has a 64 KB granularity for memory mapping
|
// For other systems we could use PAGE_SIZE, except on windows that has a 64 KB granularity for memory mapping
|
||||||
#define FPCB_PAD 64_KB
|
#define FPCB_PAD 64_KB
|
||||||
#endif
|
#endif
|
||||||
struct alignas(PAGE_SIZE) Sh4RCB
|
struct Sh4RCB
|
||||||
{
|
{
|
||||||
void* fpcb[FPCB_SIZE];
|
void* fpcb[FPCB_SIZE];
|
||||||
u8 _pad[FPCB_PAD - sizeof(Sh4Context)];
|
u8 _pad[FPCB_PAD - sizeof(Sh4Context)];
|
||||||
Sh4Context cntx;
|
Sh4Context cntx;
|
||||||
};
|
};
|
||||||
static_assert((sizeof(Sh4RCB) % PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of PAGE_SIZE");
|
static_assert((sizeof(Sh4RCB) % MAX_PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of MAX_PAGE_SIZE");
|
||||||
|
|
||||||
extern Sh4RCB* p_sh4rcb;
|
extern Sh4RCB* p_sh4rcb;
|
||||||
#define Sh4cntx (p_sh4rcb->cntx)
|
#define Sh4cntx (p_sh4rcb->cntx)
|
||||||
|
|
|
@ -171,7 +171,7 @@ void common_linux_setup()
|
||||||
signal(SIGINT, sigintHandler);
|
signal(SIGINT, sigintHandler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_LOG(BOOT, "Linux paging: %ld %08X %08X", sysconf(_SC_PAGESIZE), PAGE_SIZE, PAGE_MASK);
|
DEBUG_LOG(BOOT, "Linux paging: sysconf %ld PAGE_SIZE %ld PAGE_MASK %lX", sysconf(_SC_PAGESIZE), (unsigned long)PAGE_SIZE, (long)PAGE_MASK);
|
||||||
verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1));
|
verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,12 @@ const std::array<f32, 16> D_Adjust_LoD_Bias = {
|
||||||
0.f, -4.f, -2.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f
|
0.f, -4.f, -2.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<vram_block*> VramLocks[VRAM_SIZE_MAX / PAGE_SIZE];
|
static std::vector<vram_block*> *VramLocks;
|
||||||
|
|
||||||
|
static inline void initVramLocks() {
|
||||||
|
if (VramLocks == nullptr)
|
||||||
|
VramLocks = new std::vector<vram_block*>[VRAM_SIZE_MAX / PAGE_SIZE];
|
||||||
|
}
|
||||||
|
|
||||||
//List functions
|
//List functions
|
||||||
//
|
//
|
||||||
|
@ -76,7 +81,7 @@ static std::mutex vramlist_lock;
|
||||||
|
|
||||||
bool VramLockedWriteOffset(size_t offset)
|
bool VramLockedWriteOffset(size_t offset)
|
||||||
{
|
{
|
||||||
if (offset >= VRAM_SIZE)
|
if (offset >= VRAM_SIZE || VramLocks == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t addr_hash = offset / PAGE_SIZE;
|
size_t addr_hash = offset / PAGE_SIZE;
|
||||||
|
@ -292,6 +297,8 @@ bool BaseTextureCacheData::Delete()
|
||||||
|
|
||||||
BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw)
|
BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw)
|
||||||
{
|
{
|
||||||
|
initVramLocks();
|
||||||
|
|
||||||
if (tcw.VQ_Comp == 1 && tcw.MipMapped == 1)
|
if (tcw.VQ_Comp == 1 && tcw.MipMapped == 1)
|
||||||
// Star Wars Demolition
|
// Star Wars Demolition
|
||||||
tcw.ScanOrder = 0;
|
tcw.ScanOrder = 0;
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static std::string user_config_dir;
|
static std::string user_config_dir;
|
||||||
|
@ -205,6 +207,10 @@ void cResetEvent::Wait()
|
||||||
state = false;
|
state = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__ANDROID__) && (HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64)
|
||||||
|
const unsigned long PAGE_SIZE = (unsigned long)sysconf(_SC_PAGESIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
void RamRegion::serialize(Serializer &ser) const {
|
void RamRegion::serialize(Serializer &ser) const {
|
||||||
ser.serialize(data, size);
|
ser.serialize(data, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,22 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) && (HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64)
|
||||||
#include <sys/mman.h>
|
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
|
#undef PAGE_SIZE
|
||||||
|
extern const unsigned long PAGE_SIZE;
|
||||||
|
#define MAX_PAGE_SIZE 16384ul
|
||||||
#elif defined(__APPLE__) && defined(__aarch64__)
|
#elif defined(__APPLE__) && defined(__aarch64__)
|
||||||
#define PAGE_SIZE 16384
|
#define PAGE_SIZE 16384ul
|
||||||
#elif !defined(PAGE_SIZE)
|
#elif !defined(PAGE_SIZE)
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096ul
|
||||||
#endif
|
#endif
|
||||||
#ifndef PAGE_MASK
|
#ifndef PAGE_MASK
|
||||||
#define PAGE_MASK (PAGE_SIZE-1)
|
#define PAGE_MASK (PAGE_SIZE-1)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MAX_PAGE_SIZE
|
||||||
|
#define MAX_PAGE_SIZE PAGE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
class cThread
|
class cThread
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue