2013-12-19 17:10:14 +00:00
|
|
|
#pragma once
|
|
|
|
#include "types.h"
|
|
|
|
|
2019-05-11 20:09:52 +00:00
|
|
|
enum VMemType {
|
|
|
|
MemType4GB,
|
|
|
|
MemType512MB,
|
|
|
|
MemTypeError
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vmem_mapping {
|
2019-05-23 09:40:33 +00:00
|
|
|
u64 start_address, end_address;
|
|
|
|
u64 memoffset, memsize;
|
2019-05-11 20:09:52 +00:00
|
|
|
bool allow_writes;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Platform specific vmemory API
|
|
|
|
// To initialize (maybe) the vmem subsystem
|
|
|
|
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr);
|
|
|
|
// To reset the on-demand allocated pages.
|
|
|
|
void vmem_platform_reset_mem(void *ptr, unsigned size_bytes);
|
|
|
|
// To handle a fault&allocate an ondemand page.
|
|
|
|
void vmem_platform_ondemand_page(void *address, unsigned size_bytes);
|
|
|
|
// To create the mappings in the address space.
|
|
|
|
void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps);
|
|
|
|
// Just tries to wipe as much as possible in the relevant area.
|
|
|
|
void vmem_platform_destroy();
|
2019-05-12 17:47:11 +00:00
|
|
|
// Given a block of data in the .text section, prepares it for JIT action.
|
2019-05-12 20:02:57 +00:00
|
|
|
// both code_area and size are page aligned. Returns success.
|
|
|
|
bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code_area_rwx);
|
|
|
|
// Same as above but uses two address spaces one with RX and RW protections.
|
|
|
|
// Note: this function doesnt have to be implemented, it's a fallback for the above one.
|
|
|
|
bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code_area_rw, uintptr_t *rx_offset);
|
2019-05-12 21:25:43 +00:00
|
|
|
// This might not need an implementation (ie x86/64 cpus).
|
|
|
|
void vmem_platform_flush_cache(void *icache_start, void *icache_end, void *dcache_start, void *dcache_end);
|
2019-05-11 20:09:52 +00:00
|
|
|
|
|
|
|
// Note: if you want to disable vmem magic in any given platform, implement the
|
|
|
|
// above functions as empty functions and make vmem_platform_init return MemTypeError.
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
//Typedef's
|
|
|
|
//ReadMem
|
|
|
|
typedef u8 DYNACALL _vmem_ReadMem8FP(u32 Address);
|
|
|
|
typedef u16 DYNACALL _vmem_ReadMem16FP(u32 Address);
|
|
|
|
typedef u32 DYNACALL _vmem_ReadMem32FP(u32 Address);
|
|
|
|
//WriteMem
|
|
|
|
typedef void DYNACALL _vmem_WriteMem8FP(u32 Address,u8 data);
|
|
|
|
typedef void DYNACALL _vmem_WriteMem16FP(u32 Address,u16 data);
|
|
|
|
typedef void DYNACALL _vmem_WriteMem32FP(u32 Address,u32 data);
|
|
|
|
|
|
|
|
//our own handle type :)
|
|
|
|
typedef u32 _vmem_handler;
|
|
|
|
|
|
|
|
//Functions
|
|
|
|
|
|
|
|
//init/reset/term
|
|
|
|
void _vmem_init();
|
|
|
|
void _vmem_reset();
|
|
|
|
void _vmem_term();
|
|
|
|
|
|
|
|
//functions to register and map handlers/memory
|
|
|
|
_vmem_handler _vmem_register_handler(_vmem_ReadMem8FP* read8,_vmem_ReadMem16FP* read16,_vmem_ReadMem32FP* read32, _vmem_WriteMem8FP* write8,_vmem_WriteMem16FP* write16,_vmem_WriteMem32FP* write32);
|
|
|
|
|
|
|
|
#define _vmem_register_handler_Template(read,write) _vmem_register_handler \
|
|
|
|
(read<1,u8>,read<2,u16>,read<4,u32>, \
|
|
|
|
write<1,u8>,write<2,u16>,write<4,u32>)
|
|
|
|
|
|
|
|
#define _vmem_register_handler_Template1(read,write,extra_Tparam) _vmem_register_handler \
|
|
|
|
(read<1,u8,extra_Tparam>,read<2,u16,extra_Tparam>,read<4,u32,extra_Tparam>, \
|
|
|
|
write<1,u8,extra_Tparam>,write<2,u16,extra_Tparam>,write<4,u32,extra_Tparam>)
|
|
|
|
|
|
|
|
#define _vmem_register_handler_Template2(read,write,etp1,etp2) _vmem_register_handler \
|
|
|
|
(read<1,u8,etp1,etp2>,read<2,u16,etp1,etp2>,read<4,u32,etp1,etp2>, \
|
|
|
|
write<1,u8,etp1,etp2>,write<2,u16,etp1,etp2>,write<4,u32,etp1,etp2>)
|
|
|
|
|
|
|
|
void _vmem_map_handler(_vmem_handler Handler,u32 start,u32 end);
|
|
|
|
void _vmem_map_block(void* base,u32 start,u32 end,u32 mask);
|
|
|
|
void _vmem_mirror_mapping(u32 new_region,u32 start,u32 size);
|
|
|
|
|
2019-06-24 20:56:07 +00:00
|
|
|
#define _vmem_map_block_mirror(base, start, end, blck_size) { \
|
|
|
|
u32 block_size = (blck_size) >> 24; \
|
|
|
|
u32 map_sz = (end) - (start) + 1; \
|
|
|
|
/* verify((map_sz % block_size) == 0); */ \
|
|
|
|
for (u32 _maip = (start); _maip <= (end); _maip += block_size) \
|
|
|
|
_vmem_map_block((base), _maip, _maip + block_size - 1, blck_size - 1); \
|
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
//ReadMem(s)
|
|
|
|
u32 DYNACALL _vmem_ReadMem8SX32(u32 Address);
|
|
|
|
u32 DYNACALL _vmem_ReadMem16SX32(u32 Address);
|
|
|
|
u8 DYNACALL _vmem_ReadMem8(u32 Address);
|
|
|
|
u16 DYNACALL _vmem_ReadMem16(u32 Address);
|
|
|
|
u32 DYNACALL _vmem_ReadMem32(u32 Address);
|
|
|
|
u64 DYNACALL _vmem_ReadMem64(u32 Address);
|
2019-04-15 16:02:34 +00:00
|
|
|
template<typename T, typename Trv> Trv DYNACALL _vmem_readt(u32 addr);
|
2013-12-19 17:10:14 +00:00
|
|
|
//WriteMem(s)
|
|
|
|
void DYNACALL _vmem_WriteMem8(u32 Address,u8 data);
|
|
|
|
void DYNACALL _vmem_WriteMem16(u32 Address,u16 data);
|
|
|
|
void DYNACALL _vmem_WriteMem32(u32 Address,u32 data);
|
|
|
|
void DYNACALL _vmem_WriteMem64(u32 Address,u64 data);
|
2019-04-15 16:02:34 +00:00
|
|
|
template<typename T> void DYNACALL _vmem_writet(u32 addr, T data);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2013-12-24 00:56:44 +00:00
|
|
|
//should be called at start up to ensure it will succeed :)
|
2013-12-19 17:10:14 +00:00
|
|
|
bool _vmem_reserve();
|
|
|
|
void _vmem_release();
|
|
|
|
|
|
|
|
//dynarec helpers
|
|
|
|
void _vmem_get_ptrs(u32 sz,bool write,void*** vmap,void*** func);
|
|
|
|
void* _vmem_get_ptr2(u32 addr,u32& mask);
|
2015-08-11 22:58:50 +00:00
|
|
|
void* _vmem_read_const(u32 addr,bool& ismem,u32 sz);
|
2019-06-10 11:57:10 +00:00
|
|
|
void* _vmem_write_const(u32 addr,bool& ismem,u32 sz);
|
2015-08-11 22:58:50 +00:00
|
|
|
|
|
|
|
extern u8* virt_ram_base;
|
2019-05-23 09:40:33 +00:00
|
|
|
extern bool vmem_4gb_space;
|
2015-08-11 22:58:50 +00:00
|
|
|
|
|
|
|
static inline bool _nvmem_enabled() {
|
|
|
|
return virt_ram_base != 0;
|
|
|
|
}
|
2019-05-23 09:40:33 +00:00
|
|
|
static inline bool _nvmem_4gb_space() {
|
|
|
|
return vmem_4gb_space;
|
|
|
|
}
|
2019-04-15 16:02:34 +00:00
|
|
|
void _vmem_bm_reset();
|
2019-05-24 16:19:33 +00:00
|
|
|
void _vmem_enable_mmu(bool enable);
|
2019-05-23 09:40:33 +00:00
|
|
|
|
|
|
|
#define MAP_RAM_START_OFFSET 0
|
|
|
|
#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE)
|
|
|
|
#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE)
|
2019-06-19 12:49:14 +00:00
|
|
|
|
|
|
|
void _vmem_protect_vram(u32 addr, u32 size);
|
|
|
|
void _vmem_unprotect_vram(u32 addr, u32 size);
|
|
|
|
u32 _vmem_get_vram_offset(void *addr);
|