sys_ppu_thread_once rewritten

sys_initialize_tls moved
sys_interrupt_thread_disestablish moved
This commit is contained in:
Nekotekina 2017-05-09 03:56:32 +03:00
parent 450d45354c
commit 5ffb4766b0
4 changed files with 141 additions and 117 deletions

View file

@ -14,87 +14,6 @@ extern fs::file g_tty;
vm::gvar<s32> sys_prx_version; // ???
static u32 s_tls_addr = 0; // TLS image address
static u32 s_tls_file = 0; // TLS image size
static u32 s_tls_zero = 0; // TLS zeroed area size (TLS mem size - TLS image size)
static u32 s_tls_size = 0; // Size of TLS area per thread
static u32 s_tls_area = 0; // Start of TLS memory area
static u32 s_tls_max = 0; // Max number of threads
static std::unique_ptr<atomic_t<bool>[]> s_tls_map; // I'd like to make it std::vector but it won't work
u32 ppu_alloc_tls()
{
u32 addr = 0;
for (u32 i = 0; i < s_tls_max; i++)
{
if (!s_tls_map[i] && s_tls_map[i].exchange(true) == false)
{
// Default (small) TLS allocation
addr = s_tls_area + i * s_tls_size;
break;
}
}
if (!addr)
{
// Alternative (big) TLS allocation
addr = vm::alloc(s_tls_size, vm::main);
}
std::memset(vm::base(addr), 0, 0x30); // Clear system area (TODO)
std::memcpy(vm::base(addr + 0x30), vm::base(s_tls_addr), s_tls_file); // Copy TLS image
std::memset(vm::base(addr + 0x30 + s_tls_file), 0, s_tls_zero); // Clear the rest
return addr;
}
void ppu_free_tls(u32 addr)
{
// Calculate TLS position
const u32 i = (addr - s_tls_area) / s_tls_size;
if (addr < s_tls_area || i >= s_tls_max || (addr - s_tls_area) % s_tls_size)
{
// Alternative TLS allocation detected
vm::dealloc_verbose_nothrow(addr, vm::main);
return;
}
if (s_tls_map[i].exchange(false) == false)
{
sysPrxForUser.error("ppu_free_tls(0x%x): deallocation failed", addr);
return;
}
}
void sys_initialize_tls(ppu_thread& ppu, u64 main_thread_id, u32 tls_seg_addr, u32 tls_seg_size, u32 tls_mem_size)
{
sysPrxForUser.notice("sys_initialize_tls(thread_id=0x%llx, addr=*0x%x, size=0x%x, mem_size=0x%x)", main_thread_id, tls_seg_addr, tls_seg_size, tls_mem_size);
// Uninitialized TLS expected.
if (ppu.gpr[13] != 0) return;
// Initialize TLS memory
s_tls_addr = tls_seg_addr;
s_tls_file = tls_seg_size;
s_tls_zero = tls_mem_size - tls_seg_size;
s_tls_size = tls_mem_size + 0x30; // 0x30 is system area size
s_tls_area = vm::alloc(0x40000, vm::main) + 0x30;
s_tls_max = (0x40000 - 0x30) / s_tls_size;
s_tls_map = std::make_unique<atomic_t<bool>[]>(s_tls_max);
// Allocate TLS for main thread
ppu.gpr[13] = ppu_alloc_tls() + 0x7000 + 0x30;
sysPrxForUser.notice("TLS initialized (addr=0x%x, size=0x%x, max=0x%x)", s_tls_area - 0x30, s_tls_size, s_tls_max);
// TODO
g_spu_printf_agcb = vm::null;
g_spu_printf_dgcb = vm::null;
g_spu_printf_atcb = vm::null;
g_spu_printf_dtcb = vm::null;
}
s64 sys_time_get_system_time()
{
sysPrxForUser.trace("sys_time_get_system_time()");
@ -114,24 +33,6 @@ s64 _sys_process_at_Exitspawn()
return CELL_OK;
}
s32 sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih)
{
sysPrxForUser.notice("sys_interrupt_thread_disestablish(ih=0x%x)", ih);
vm::var<u64> r13;
// Call the syscall
if (s32 res = _sys_interrupt_thread_disestablish(ppu, ih, r13))
{
return res;
}
// Deallocate TLS
ppu_free_tls(vm::cast(*r13, HERE) - 0x7030);
return CELL_OK;
}
s32 sys_process_is_stack(u32 p)
{
sysPrxForUser.trace("sys_process_is_stack(p=0x%x)", p);
@ -329,8 +230,6 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf
REG_FUNC(sysPrxForUser, sys_initialize_tls);
REG_FUNC(sysPrxForUser, sys_time_get_system_time);
// TODO: split syscalls and liblv2 functions
@ -340,8 +239,6 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
REG_FUNC(sysPrxForUser, sys_process_is_stack);
REG_FUNC(sysPrxForUser, sys_process_get_paramsfo); // 0xe75c40f2
REG_FUNC(sysPrxForUser, sys_interrupt_thread_disestablish);
REG_FUNC(sysPrxForUser, sys_get_random_number);
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);