Improved FRES and FRSQRTE results (tested with ppu_fpu).

Implemented and improved several SC_Memory syscalls.

Started working in sceNp module.
This commit is contained in:
Hykem 2014-03-15 19:45:43 +00:00
parent 65eb873597
commit c4a9c874d1
7 changed files with 517 additions and 260 deletions

View File

@ -3404,62 +3404,11 @@ private:
}
void FRES(u32 frd, u32 frb, bool rc)
{
double res;
#ifdef _MSC_VER
if(_fpclass(CPU.FPR[frb]) >= _FPCLASS_NZ)
#else
if(_fpclass(CPU.FPR[frb]) == FP_ZERO || std::signbit(CPU.FPR[frb]) == 0)
#endif
{
res = static_cast<float>(1.0 / CPU.FPR[frb]);
if(FPRdouble::IsINF(res) && CPU.FPR[frb] != 0.0)
{
if(res > 0.0)
{
(u64&)res = 0x47EFFFFFE0000000ULL;
}
else
{
(u64&)res = 0xC7EFFFFFE0000000ULL;
}
}
}
else
{
u64 v = CPU.FPR[frb];
if(v == 0ULL)
{
v = 0x7FF0000000000000ULL;
}
else if(v == 0x8000000000000000ULL)
{
v = 0xFFF0000000000000ULL;
}
else if(FPRdouble::IsNaN(CPU.FPR[frb]))
{
v = 0x7FF8000000000000ULL;
}
else if(CPU.FPR[frb] < 0.0)
{
v = 0x8000000000000000ULL;
}
else
{
v = 0ULL;
}
res = (double&)v;
}
if(CPU.FPR[frb] == 0.0)
{
CPU.SetFPSCRException(FPSCR_ZX);
}
CPU.FPR[frd] = res;
CPU.FPR[frd] = static_cast<float>(1.0 / CPU.FPR[frb]);
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FMULS(u32 frd, u32 fra, u32 frc, bool rc)
@ -3790,7 +3739,12 @@ private:
}
void FRSQRTE(u32 frd, u32 frb, bool rc)
{
CPU.FPR[frd] = 1.0f / (float)sqrt(CPU.FPR[frb]);
if(CPU.FPR[frb] == 0.0)
{
CPU.SetFPSCRException(FPSCR_ZX);
}
CPU.FPR[frd] = static_cast<float>(1.0 / sqrt(CPU.FPR[frb]));
if(rc) UNK("frsqrte.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{

View File

@ -7,6 +7,37 @@
void sceNp_init();
Module sceNp(0x0016, sceNp_init);
int sceNpInit(u32 mem_size, u32 mem_addr)
{
sceNp.Log("sceNpInit(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr);
return CELL_OK;
}
int sceNpTerm()
{
sceNp.Log("sceNpTerm");
return CELL_OK;
}
int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr)
{
sceNp.Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x)", k_licensee_addr, drm_path_addr);
wxString k_licensee_str;
wxString drm_path = Memory.ReadString(drm_path_addr);
u8 k_licensee[0x10];
for(int i = 0; i < 0x10; i++)
{
k_licensee[i] = Memory.Read8(k_licensee_addr + i);
k_licensee_str += wxString::Format("%02x", k_licensee[i]);
}
sceNp.Warning("sceNpDrmIsAvailable: Found DRM license file at %s", drm_path.c_str());
sceNp.Warning("sceNpDrmIsAvailable: Using k_licensee 0x%s", k_licensee_str);
return CELL_OK;
}
int sceNpManagerGetStatus(mem32_t status)
{
sceNp.Log("sceNpManagerGetStatus(status_addr=0x%x)", status.GetAddr());
@ -22,5 +53,8 @@ int sceNpManagerGetStatus(mem32_t status)
void sceNp_init()
{
sceNp.AddFunc(0xbd28fdbf, sceNpInit);
sceNp.AddFunc(0x4885aa18, sceNpTerm);
sceNp.AddFunc(0xad218faf, sceNpDrmIsAvailable);
sceNp.AddFunc(0xa7bff757, sceNpManagerGetStatus);
}

View File

@ -167,7 +167,9 @@ void sysPrxForUser_init()
sysPrxForUser.AddFunc(0x44265c08, _sys_heap_memalign);
sysPrxForUser.AddFunc(0xb257540b, sys_mmapper_allocate_memory);
sysPrxForUser.AddFunc(0x70258515, sys_mmapper_allocate_memory_from_container);
sysPrxForUser.AddFunc(0xdc578057, sys_mmapper_map_memory);
sysPrxForUser.AddFunc(0x4643ba6e, sys_mmapper_unmap_memory);
sysPrxForUser.AddFunc(0x409ad939, sys_mmapper_free_memory);
sysPrxForUser.AddFunc(0x1ed454ce, sys_spu_elf_get_information);

View File

@ -148,13 +148,28 @@ static func_caller* sc_table[1024] =
bind_func(sys_vm_get_statistics), //312 (0x138)
null_func, null_func, //314
null_func, null_func, null_func, null_func, null_func, //319
null_func, null_func, null_func, null_func, bind_func(sys_memory_container_create), //324
bind_func(sys_memory_container_destroy), null_func, null_func, null_func, null_func, //329
bind_func(sys_mmapper_allocate_address), null_func, null_func, null_func, null_func, //334
null_func, null_func, null_func, null_func, null_func, //339
null_func, bind_func(sys_memory_container_create), bind_func(sys_memory_container_destroy), null_func, null_func, //344
null_func, null_func, null_func, bind_func(sys_memory_allocate), bind_func(sys_memory_free), //349
null_func, bind_func(sys_memory_get_page_attribute), bind_func(sys_memory_get_user_memory_size), null_func, null_func, //354
null_func, null_func, null_func, null_func, //323
bind_func(sys_memory_container_create), //324
bind_func(sys_memory_container_destroy), //325
bind_func(sys_mmapper_allocate_fixed_address), //326
bind_func(sys_mmapper_enable_page_fault_notification), //327
null_func, null_func, //329
bind_func(sys_mmapper_allocate_address), //330
bind_func(sys_mmapper_free_address), //331
null_func, null_func, null_func, null_func, //335
bind_func(sys_mmapper_change_address_access_right), //336
bind_func(sys_mmapper_search_and_map), //337
null_func, null_func, null_func, //340
bind_func(sys_memory_container_create), //341
bind_func(sys_memory_container_destroy), //342
bind_func(sys_memory_container_get_size), //343
null_func, null_func, null_func, null_func, //347
bind_func(sys_memory_allocate), //348
bind_func(sys_memory_free), //349
bind_func(sys_memory_allocate_from_container), //350
bind_func(sys_memory_get_page_attribute), //351
bind_func(sys_memory_get_user_memory_size), //352
null_func, null_func, //354
null_func, null_func, null_func, null_func, null_func, //359
null_func, null_func, null_func, null_func, null_func, //364
null_func, null_func, null_func, null_func, null_func, //369

View File

@ -223,16 +223,25 @@ extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
extern int sys_ppu_thread_get_id(const u32 id_addr);
//memory
extern int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr);
extern int sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_addr_addr);
extern int sys_memory_free(u32 start_addr);
extern int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> attr);
extern int sys_memory_get_user_memory_size(u32 mem_info_addr);
extern int sys_memory_container_create(mem32_t cid, u32 yield_size);
extern int sys_memory_container_destroy(u32 cid);
extern int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr);
extern int sys_memory_free(u32 start_addr);
extern int sys_memory_get_user_memory_size(u32 mem_info_addr);
extern int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> a);
extern int sys_memory_container_get_size(u32 mem_info_addr, u32 cid);
extern int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr);
extern int sys_mmapper_allocate_fixed_address();
extern int sys_mmapper_allocate_memory(u32 size, u64 flags, mem32_t mem_id);
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
extern int sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, mem32_t mem_id);
extern int sys_mmapper_change_address_access_right(u32 start_addr, u64 flags);
extern int sys_mmapper_free_address(u32 start_addr);
extern int sys_mmapper_free_memory(u32 mem_id);
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
extern int sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_addr);
extern int sys_mmapper_unmap_memory(u32 start_addr, u32 mem_id_addr);
extern int sys_mmapper_enable_page_fault_notification(u32 start_addr, u32 q_id);
//vm
extern int sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr);

View File

@ -3,50 +3,13 @@
#include "SC_Memory.h"
SysCallBase sc_mem("memory");
int sys_memory_container_create(mem32_t cid, u32 yield_size)
{
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size);
if (!cid.IsGood())
{
return CELL_EFAULT;
}
yield_size &= ~0xfffff; //round down to 1 MB granularity
u64 addr = Memory.Alloc(yield_size, 0x100000); //1 MB alignment
if(!addr)
{
return CELL_ENOMEM;
}
cid = sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size));
sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue());
return CELL_OK;
}
int sys_memory_container_destroy(u32 cid)
{
sc_mem.Warning("sys_memory_container_destroy(cid=%d)", cid);
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
{
return CELL_ESRCH;
}
Memory.Free(ct->addr);
Emu.GetIdManager().RemoveID(cid);
return CELL_OK;
}
std::map<u32, u32> mmapper_info_map;
int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
{
//0x30000100;
sc_mem.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags);
// Check page size.
u32 addr;
switch(flags)
{
@ -63,119 +26,64 @@ int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
default: return CELL_EINVAL;
}
if(!addr) return CELL_ENOMEM;
if(!addr)
return CELL_ENOMEM;
// Write back the start address of the allocated area.
sc_mem.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", addr, size);
Memory.Write32(alloc_addr_addr, addr);
return CELL_OK;
}
int sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_addr_addr)
{
sc_mem.Log("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%x)", size, cid, flags);
// Check if this container ID is valid.
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
return CELL_ESRCH;
// Check page size.
switch(flags)
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN;
ct->addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN;
ct->addr = Memory.Alloc(size, 0x10000);
break;
default: return CELL_EINVAL;
}
// Store the address and size in the container.
if(!ct->addr)
return CELL_ENOMEM;
ct->size = size;
// Write back the start address of the allocated area.
sc_mem.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", ct->addr, ct->size);
Memory.Write32(alloc_addr_addr, ct->addr);
return CELL_OK;
}
int sys_memory_free(u32 start_addr)
{
sc_mem.Log("sys_memory_free(start_addr=0x%x)", start_addr);
if(!Memory.Free(start_addr)) return CELL_EFAULT;
// Release the allocated memory.
if(!Memory.Free(start_addr))
return CELL_EFAULT;
return CELL_OK;
}
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
if(!Memory.IsGoodAddr(alloc_addr)) return CELL_EFAULT;
if(!alignment)
alignment = 1;
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
default:
case SYS_MEMORY_PAGE_SIZE_1M:
if(Memory.AlignAddr(size, alignment) & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(Memory.AlignAddr(size, alignment) & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
}
Memory.Write32(alloc_addr, addr);
return CELL_OK;
}
int sys_mmapper_allocate_memory(u32 size, u64 flags, mem32_t mem_id)
{
sc_mem.Warning("sys_mmapper_allocate_memory(size=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, flags, mem_id.GetAddr());
if(!mem_id.IsGood()) return CELL_EFAULT;
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
default:
return CELL_EINVAL;
}
if(!addr)
return CELL_ENOMEM;
mem_id = sc_mem.GetNewId(new mmapper_info(addr, size, flags));
return CELL_OK;
}
int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
{
sc_mem.Warning("sys_mmapper_map_memory(start_addr=0x%x, mem_id=0x%x, flags=0x%llx)", start_addr, mem_id, flags);
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info)) return CELL_ESRCH;
if(!Memory.Map(start_addr, info->addr, info->size))
{
sc_mem.Error("sys_mmapper_map_memory failed!");
}
return CELL_OK;
}
int sys_mmapper_free_memory(u32 mem_id)
{
sc_mem.Warning("sys_mmapper_free_memory(mem_id=0x%x)", mem_id);
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info)) return CELL_ESRCH;
Memory.Free(info->addr);
return CELL_OK;
}
int sys_memory_get_user_memory_size(u32 mem_info_addr)
{
sc_mem.Warning("sys_memory_get_user_memory_size(mem_info_addr=0x%x)", mem_info_addr);
sys_memory_info info;
info.total_user_memory = re(Memory.GetUserMemTotalSize());
info.available_user_memory = re(Memory.GetUserMemAvailSize());
Memory.WriteData(mem_info_addr, info);
return CELL_OK;
}
int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> attr)
{
sc_mem.Warning("sys_memory_get_page_attribute(addr=0x%x, attr_addr=0x%x)", addr, attr.GetAddr());
@ -183,6 +91,7 @@ int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> attr)
if (!attr.IsGood())
return CELL_EFAULT;
// TODO: Implement per thread page attribute setting.
attr->attribute = 0;
attr->page_size = 0;
attr->access_right = 0;
@ -190,3 +99,327 @@ int sys_memory_get_page_attribute(u32 addr, mem_ptr_t<sys_page_attr_t> attr)
return CELL_OK;
}
int sys_memory_get_user_memory_size(u32 mem_info_addr)
{
sc_mem.Warning("sys_memory_get_user_memory_size(mem_info_addr=0x%x)", mem_info_addr);
// Fetch the user memory available.
sys_memory_info info;
info.total_user_memory = re(Memory.GetUserMemTotalSize());
info.available_user_memory = re(Memory.GetUserMemAvailSize());
Memory.WriteData(mem_info_addr, info);
return CELL_OK;
}
int sys_memory_container_create(mem32_t cid, u32 yield_size)
{
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size);
if (!cid.IsGood())
return CELL_EFAULT;
yield_size &= ~0xfffff; //round down to 1 MB granularity
u64 addr = Memory.Alloc(yield_size, 0x100000); //1 MB alignment
if(!addr)
return CELL_ENOMEM;
// Wrap the allocated memory in a memory container.
MemoryContainerInfo *ct = new MemoryContainerInfo(addr, yield_size);
cid = sc_mem.GetNewId(ct);
sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue());
return CELL_OK;
}
int sys_memory_container_destroy(u32 cid)
{
sc_mem.Warning("sys_memory_container_destroy(cid=%d)", cid);
// Check if this container ID is valid.
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
return CELL_ESRCH;
// Release the allocated memory and remove the ID.
Memory.Free(ct->addr);
Emu.GetIdManager().RemoveID(cid);
return CELL_OK;
}
int sys_memory_container_get_size(u32 mem_info_addr, u32 cid)
{
sc_mem.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=%d)", mem_info_addr, cid);
// Check if this container ID is valid.
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
return CELL_ESRCH;
// HACK: Return all memory.
sys_memory_info info;
info.total_user_memory = re(ct->size);
info.available_user_memory = re(ct->size);
Memory.WriteData(mem_info_addr, info);
return CELL_OK;
}
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)",
size, flags, alignment, alloc_addr);
if(!Memory.IsGoodAddr(alloc_addr))
return CELL_EFAULT;
// Check for valid alignment.
if(alignment > 0x80000000)
return CELL_EALIGN;
// Check page size.
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
default:
case SYS_MEMORY_PAGE_SIZE_1M:
if(Memory.AlignAddr(size, alignment) & 0xfffff)
return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(Memory.AlignAddr(size, alignment) & 0xffff)
return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
}
// Write back the start address of the allocated area.
Memory.Write32(alloc_addr, addr);
return CELL_OK;
}
int sys_mmapper_allocate_fixed_address()
{
sc_mem.Warning("sys_mmapper_allocate_fixed_address");
// Allocate a fixed size from user memory.
if (!Memory.Alloc(SYS_MMAPPER_FIXED_SIZE, 0x100000))
return CELL_EEXIST;
return CELL_OK;
}
int sys_mmapper_allocate_memory(u32 size, u64 flags, mem32_t mem_id)
{
sc_mem.Warning("sys_mmapper_allocate_memory(size=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, flags, mem_id.GetAddr());
if(!mem_id.IsGood())
return CELL_EFAULT;
// Check page granularity.
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff)
return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff)
return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
default:
return CELL_EINVAL;
}
if(!addr)
return CELL_ENOMEM;
// Generate a new mem ID.
mem_id = sc_mem.GetNewId(new mmapper_info(addr, size, flags));
return CELL_OK;
}
int sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, mem32_t mem_id)
{
sc_mem.Warning("sys_mmapper_allocate_memory_from_container(size=0x%x, cid=%d, flags=0x%llx, mem_id_addr=0x%x)",
size, cid, flags, mem_id.GetAddr());
if(!mem_id.IsGood())
return CELL_EFAULT;
// Check if this container ID is valid.
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
return CELL_ESRCH;
// Check page granularity.
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff)
return CELL_EALIGN;
ct->addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff)
return CELL_EALIGN;
ct->addr = Memory.Alloc(size, 0x10000);
break;
default:
return CELL_EINVAL;
}
if(!ct->addr)
return CELL_ENOMEM;
ct->size = size;
// Generate a new mem ID.
mem_id = sc_mem.GetNewId(new mmapper_info(ct->addr, ct->size, flags));
return CELL_OK;
}
int sys_mmapper_change_address_access_right(u32 start_addr, u64 flags)
{
sc_mem.Warning("sys_mmapper_change_address_access_right(start_addr=0x%x, flags=0x%llx)", start_addr, flags);
if (!Memory.IsGoodAddr(start_addr))
return CELL_EINVAL;
// TODO
return CELL_OK;
}
int sys_mmapper_free_address(u32 start_addr)
{
sc_mem.Warning("sys_mmapper_free_address(start_addr=0x%x)", start_addr);
if(!Memory.IsGoodAddr(start_addr))
return CELL_EINVAL;
// Free the address.
Memory.Free(start_addr);
return CELL_OK;
}
int sys_mmapper_free_memory(u32 mem_id)
{
sc_mem.Warning("sys_mmapper_free_memory(mem_id=0x%x)", mem_id);
// Check if this mem ID is valid.
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info))
return CELL_ESRCH;
// Release the allocated memory and remove the ID.
Memory.Free(info->addr);
Emu.GetIdManager().RemoveID(mem_id);
return CELL_OK;
}
int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
{
sc_mem.Warning("sys_mmapper_map_memory(start_addr=0x%x, mem_id=0x%x, flags=0x%llx)", start_addr, mem_id, flags);
// Check if this mem ID is valid.
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info))
return CELL_ESRCH;
// Map the memory into the process address.
if(!Memory.Map(start_addr, info->addr, info->size))
sc_mem.Error("sys_mmapper_map_memory failed!");
// Keep track of mapped addresses.
mmapper_info_map[mem_id] = start_addr;
return CELL_OK;
}
int sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_addr)
{
sc_mem.Warning("sys_mmapper_search_and_map(start_addr=0x%x, mem_id=0x%x, flags=0x%llx, alloc_addr=0x%x)",
start_addr, mem_id, flags, alloc_addr);
if(!Memory.IsGoodAddr(alloc_addr))
return CELL_EFAULT;
// Check if this mem ID is valid.
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info))
return CELL_ESRCH;
// Search for a mappable address.
u32 addr;
bool found;
for (int i = 0; i < SYS_MMAPPER_FIXED_SIZE; i += 0x100000)
{
addr = start_addr + i;
found = Memory.Map(addr, info->addr, info->size);
if(found)
{
sc_mem.Warning("Found and mapped address 0x%x", addr);
break;
}
}
// Check if the address is valid.
if (!Memory.IsGoodAddr(addr) || !found)
return CELL_ENOMEM;
// Write back the start address of the allocated area.
Memory.Write32(alloc_addr, addr);
// Keep track of mapped addresses.
mmapper_info_map[mem_id] = addr;
return CELL_OK;
}
int sys_mmapper_unmap_memory(u32 start_addr, u32 mem_id_addr)
{
sc_mem.Warning("sys_mmapper_unmap_memory(start_addr=0x%x, mem_id_addr=0x%x)", start_addr, mem_id_addr);
if (!Memory.IsGoodAddr(start_addr))
return CELL_EINVAL;
if (!Memory.IsGoodAddr(mem_id_addr))
return CELL_EFAULT;
// Write back the mem ID of the unmapped area.
u32 mem_id = mmapper_info_map.find(start_addr)->first;
Memory.Write32(mem_id_addr, mem_id);
return CELL_OK;
}
int sys_mmapper_enable_page_fault_notification(u32 start_addr, u32 q_id)
{
sc_mem.Warning("sys_mmapper_enable_page_fault_notification(start_addr=0x%x, q_id=0x%x)", start_addr, q_id);
if (!Memory.IsGoodAddr(start_addr))
return CELL_EINVAL;
// TODO
return CELL_OK;
}

View File

@ -1,6 +1,15 @@
#pragma once
#define SYS_MEMORY_CONTAINER_ID_INVALID 0xFFFFFFFF
#define SYS_MEMORY_ACCESS_RIGHT_NONE 0x00000000000000F0ULL
#define SYS_MEMORY_ACCESS_RIGHT_PPU_THREAD 0x0000000000000008ULL
#define SYS_MEMORY_ACCESS_RIGHT_HANDLER 0x0000000000000004ULL
#define SYS_MEMORY_ACCESS_RIGHT_SPU_THREAD 0x0000000000000002ULL
#define SYS_MEMORY_ACCESS_RIGHT_SPU_RAW 0x0000000000000001ULL
#define SYS_MEMORY_ATTR_READ_ONLY 0x0000000000080000ULL
#define SYS_MEMORY_ATTR_READ_WRITE 0x0000000000040000ULL
#define SYS_MMAPPER_FIXED_ADDR 0xB0000000
#define SYS_MMAPPER_FIXED_SIZE 0x10000000
#define SYS_VM_TEST_INVALID 0x0000ULL
#define SYS_VM_TEST_UNUSED 0x0001ULL
#define SYS_VM_TEST_ALLOCATED 0x0002ULL
@ -12,6 +21,21 @@ enum
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
};
struct sys_memory_info
{
u32 total_user_memory;
u32 available_user_memory;
};
struct sys_page_attr_t
{
u64 attribute;
u64 access_right;
u32 page_size;
u32 pad;
};
struct MemoryContainerInfo
{
u64 addr;
@ -42,12 +66,6 @@ struct mmapper_info
}
};
struct sys_memory_info
{
u32 total_user_memory;
u32 available_user_memory;
};
struct sys_vm_statistics {
u64 vm_crash_ppu;
u64 vm_crash_spu;
@ -57,11 +75,3 @@ struct sys_vm_statistics {
u32 physical_mem_used;
u64 timestamp;
};
struct sys_page_attr_t
{
u64 attribute;
u64 access_right;
u32 page_size;
u32 pad;
};