2017-01-27 02:17:31 +01:00
|
|
|
|
#include "stdafx.h"
|
2014-09-08 02:54:17 +02:00
|
|
|
|
#include "Emu/System.h"
|
2016-03-21 20:42:14 +01:00
|
|
|
|
#include "Emu/Cell/PPUModule.h"
|
2014-08-23 22:40:04 +02:00
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
#include "Emu/Cell/lv2/sys_interrupt.h"
|
|
|
|
|
|
#include "Emu/Cell/lv2/sys_process.h"
|
2014-08-01 01:52:43 +02:00
|
|
|
|
#include "sysPrxForUser.h"
|
2013-06-30 10:46:29 +02:00
|
|
|
|
|
2016-05-13 15:55:34 +02:00
|
|
|
|
logs::channel sysPrxForUser("sysPrxForUser", logs::level::notice);
|
2013-06-30 10:46:29 +02:00
|
|
|
|
|
2015-07-06 01:21:15 +02:00
|
|
|
|
extern u64 get_system_time();
|
|
|
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
|
extern fs::file g_tty;
|
|
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
vm::gvar<s32> sys_prx_version; // ???
|
|
|
|
|
|
|
2016-07-19 01:33:25 +02:00
|
|
|
|
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
|
2015-01-30 21:01:13 +01:00
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
u32 ppu_alloc_tls()
|
2014-10-05 23:21:00 +02:00
|
|
|
|
{
|
2016-07-19 01:33:25 +02:00
|
|
|
|
for (u32 i = 0; i < s_tls_max; i++)
|
2016-03-21 20:42:14 +01:00
|
|
|
|
{
|
2016-07-19 01:33:25 +02:00
|
|
|
|
if (!s_tls_map[i] && s_tls_map[i].exchange(true) == false)
|
2016-03-21 20:42:14 +01:00
|
|
|
|
{
|
2016-07-19 01:33:25 +02:00
|
|
|
|
const u32 addr = s_tls_area + i * s_tls_size; // Calculate TLS address
|
|
|
|
|
|
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
|
2016-03-21 20:42:14 +01:00
|
|
|
|
return addr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-19 01:33:25 +02:00
|
|
|
|
sysPrxForUser.error("ppu_alloc_tls(): out of TLS memory (max=%zu)", s_tls_max);
|
2016-03-21 20:42:14 +01:00
|
|
|
|
return 0;
|
2014-10-05 23:21:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
void ppu_free_tls(u32 addr)
|
2015-01-30 21:01:13 +01:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
// Calculate TLS position
|
2016-07-19 01:33:25 +02:00
|
|
|
|
const u32 i = (addr - s_tls_area) / s_tls_size;
|
2015-02-01 08:09:24 +01:00
|
|
|
|
|
2016-07-19 01:33:25 +02:00
|
|
|
|
if (addr < s_tls_area || i >= s_tls_max || (addr - s_tls_area) % s_tls_size)
|
2015-02-01 08:09:24 +01:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
sysPrxForUser.error("ppu_free_tls(0x%x): invalid address", addr);
|
|
|
|
|
|
return;
|
2015-01-30 22:30:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-19 01:33:25 +02:00
|
|
|
|
if (s_tls_map[i].exchange(false) == false)
|
2015-01-30 21:01:13 +01:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
sysPrxForUser.error("ppu_free_tls(0x%x): deallocation failed", addr);
|
|
|
|
|
|
return;
|
2015-01-30 21:01:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-27 23:43:22 +02:00
|
|
|
|
void sys_initialize_tls(ppu_thread& ppu, u64 main_thread_id, u32 tls_seg_addr, u32 tls_seg_size, u32 tls_mem_size)
|
2015-01-30 21:01:13 +01:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
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.
|
2016-07-27 23:43:22 +02:00
|
|
|
|
if (ppu.gpr[13] != 0) return;
|
2016-03-21 20:42:14 +01:00
|
|
|
|
|
|
|
|
|
|
// Initialize TLS memory
|
2016-07-19 01:33:25 +02:00
|
|
|
|
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(0x20000, vm::main) + 0x30;
|
|
|
|
|
|
s_tls_max = (0xffd0 / s_tls_size) + (0x10000 / s_tls_size);
|
|
|
|
|
|
s_tls_map = std::make_unique<atomic_t<bool>[]>(s_tls_max);
|
2016-03-21 20:42:14 +01:00
|
|
|
|
|
|
|
|
|
|
// Allocate TLS for main thread
|
2016-07-27 23:43:22 +02:00
|
|
|
|
ppu.gpr[13] = ppu_alloc_tls() + 0x7000 + 0x30;
|
2015-08-19 13:04:58 +02:00
|
|
|
|
|
2016-07-19 01:33:25 +02:00
|
|
|
|
sysPrxForUser.notice("TLS initialized (addr=0x%x, size=0x%x, max=0x%x)", s_tls_area - 0x30, s_tls_size, s_tls_max);
|
2016-03-21 20:42:14 +01:00
|
|
|
|
|
|
|
|
|
|
// 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;
|
2015-01-30 21:01:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
s64 sys_time_get_system_time()
|
2014-06-25 00:38:34 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sysPrxForUser.trace("sys_time_get_system_time()");
|
2014-06-25 00:38:34 +02:00
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
return get_system_time();
|
2014-06-25 00:38:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-08-20 02:32:25 +02:00
|
|
|
|
s64 _sys_process_atexitspawn()
|
2013-06-30 10:46:29 +02:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
sysPrxForUser.todo("_sys_process_atexitspawn()");
|
2013-12-24 18:34:51 +01:00
|
|
|
|
return CELL_OK;
|
2013-06-30 10:46:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-08-20 02:32:25 +02:00
|
|
|
|
s64 _sys_process_at_Exitspawn()
|
2013-06-30 10:46:29 +02:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
sysPrxForUser.todo("_sys_process_at_Exitspawn");
|
2013-12-24 18:34:51 +01:00
|
|
|
|
return CELL_OK;
|
2013-06-30 10:46:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-07-27 23:43:22 +02:00
|
|
|
|
s32 sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih)
|
2015-03-02 22:09:20 +01:00
|
|
|
|
{
|
2016-03-21 20:42:14 +01:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2015-03-02 22:09:20 +01:00
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
// Deallocate TLS
|
|
|
|
|
|
ppu_free_tls(vm::cast(*r13, HERE) - 0x7030);
|
|
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
2015-03-02 22:09:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-03-14 21:28:59 +01:00
|
|
|
|
s32 sys_process_is_stack(u32 p)
|
2013-12-11 23:13:28 +01:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sysPrxForUser.trace("sys_process_is_stack(p=0x%x)", p);
|
2013-12-11 23:13:28 +01:00
|
|
|
|
|
2014-07-20 19:13:35 +02:00
|
|
|
|
// prx: compare high 4 bits with "0xD"
|
2015-07-11 22:44:53 +02:00
|
|
|
|
return (p >> 28) == 0xD;
|
2013-12-11 23:13:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
s32 sys_process_get_paramsfo(vm::ptr<char> buffer)
|
2013-12-25 18:28:10 +01:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sysPrxForUser.warning("sys_process_get_paramsfo(buffer=*0x%x)", buffer);
|
2015-06-13 03:31:45 +02:00
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
// prx: load some data (0x40 bytes) previously set by _sys_process_get_paramsfo syscall
|
|
|
|
|
|
return _sys_process_get_paramsfo(buffer);
|
2013-12-25 18:28:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-03-14 21:28:59 +01:00
|
|
|
|
s32 sys_get_random_number(vm::ptr<u8> addr, u64 size)
|
2014-09-12 14:18:27 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size);
|
2014-09-12 14:18:27 +02:00
|
|
|
|
|
2014-09-12 17:11:04 +02:00
|
|
|
|
if (size > 4096)
|
|
|
|
|
|
size = 4096;
|
|
|
|
|
|
|
2014-10-24 15:24:09 +02:00
|
|
|
|
for (u32 i = 0; i < (u32)size - 1; i++)
|
2014-09-25 21:27:40 +02:00
|
|
|
|
{
|
|
|
|
|
|
addr[i] = rand() % 256;
|
|
|
|
|
|
}
|
2014-09-12 14:18:27 +02:00
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-27 02:17:31 +01:00
|
|
|
|
s32 __sys_look_ctype_table()
|
|
|
|
|
|
{
|
|
|
|
|
|
UNIMPLEMENTED_FUNC(sysPrxForUser);
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
s32 console_getc()
|
2015-04-12 03:36:25 +02:00
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-04-12 03:36:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
s32 console_putc()
|
2015-04-12 03:36:25 +02:00
|
|
|
|
{
|
2016-08-08 18:01:06 +02:00
|
|
|
|
fmt::throw_exception("Unimplemented" HERE);
|
2015-04-12 03:36:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-09-13 09:26:01 +02:00
|
|
|
|
s32 console_write(vm::ptr<char> data, u32 len)
|
2015-04-12 03:36:25 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sysPrxForUser.warning("console_write(data=*0x%x, len=%d)", data, len);
|
2015-09-10 16:30:14 +02:00
|
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
|
if (g_tty)
|
|
|
|
|
|
{
|
|
|
|
|
|
g_tty.write(data.get_ptr(), len);
|
|
|
|
|
|
}
|
2015-09-13 09:26:01 +02:00
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
2015-04-12 03:36:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-14 13:03:04 +01:00
|
|
|
|
s32 sys_lv2coredump_D725F320()
|
|
|
|
|
|
{
|
|
|
|
|
|
fmt::raw_error(__func__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s32 sys_crashdump_52696620()
|
|
|
|
|
|
{
|
|
|
|
|
|
fmt::raw_error(__func__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s32 sys_crashdump_B20F87B3()
|
|
|
|
|
|
{
|
|
|
|
|
|
fmt::raw_error(__func__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-04-12 03:36:25 +02:00
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
extern void sysPrxForUser_sys_lwmutex_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_lwcond_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_ppu_thread_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_prx_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_heap_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_spinlock_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_mmapper_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_mempool_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_spu_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_game_init();
|
|
|
|
|
|
extern void sysPrxForUser_sys_libc_init();
|
2015-07-06 01:21:15 +02:00
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
|
2013-06-30 10:46:29 +02:00
|
|
|
|
{
|
2017-03-14 13:03:04 +01:00
|
|
|
|
static ppu_static_module sys_lv2coredump("sys_lv2coredump", []()
|
|
|
|
|
|
{
|
|
|
|
|
|
REG_FNID(sys_lv2coredump, 0xD725F320, sys_lv2coredump_D725F320);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
static ppu_static_module sys_crashdump("sys_crashdump", []()
|
|
|
|
|
|
{
|
|
|
|
|
|
REG_FNID(sys_crashdump, 0x52696620, sys_crashdump_52696620);
|
|
|
|
|
|
REG_FNID(sys_crashdump, 0xB20F87B3, sys_crashdump_B20F87B3);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
sysPrxForUser_sys_lwmutex_init();
|
|
|
|
|
|
sysPrxForUser_sys_lwcond_init();
|
|
|
|
|
|
sysPrxForUser_sys_ppu_thread_init();
|
|
|
|
|
|
sysPrxForUser_sys_prx_init();
|
|
|
|
|
|
sysPrxForUser_sys_heap_init();
|
|
|
|
|
|
sysPrxForUser_sys_spinlock_init();
|
|
|
|
|
|
sysPrxForUser_sys_mmapper_init();
|
|
|
|
|
|
sysPrxForUser_sys_mempool_init();
|
|
|
|
|
|
sysPrxForUser_sys_spu_init();
|
|
|
|
|
|
sysPrxForUser_sys_game_init();
|
|
|
|
|
|
sysPrxForUser_sys_libc_init();
|
2014-05-02 08:30:32 +02:00
|
|
|
|
|
2016-03-21 20:42:14 +01:00
|
|
|
|
REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_initialize_tls);
|
2015-03-09 20:56:55 +01:00
|
|
|
|
|
2015-02-20 14:58:40 +01:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_time_get_system_time);
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
// TODO: split syscalls and liblv2 functions
|
2015-02-20 14:58:40 +01:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_process_exit);
|
|
|
|
|
|
REG_FUNC(sysPrxForUser, _sys_process_atexitspawn);
|
|
|
|
|
|
REG_FUNC(sysPrxForUser, _sys_process_at_Exitspawn);
|
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_process_is_stack);
|
2015-08-02 04:15:49 +02:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_process_get_paramsfo); // 0xe75c40f2
|
2015-02-20 14:58:40 +01:00
|
|
|
|
|
2015-03-02 22:09:20 +01:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_interrupt_thread_disestablish);
|
|
|
|
|
|
|
2015-02-20 14:58:40 +01:00
|
|
|
|
REG_FUNC(sysPrxForUser, sys_get_random_number);
|
|
|
|
|
|
|
2017-01-27 02:17:31 +01:00
|
|
|
|
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
|
|
|
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
|
REG_FUNC(sysPrxForUser, console_getc);
|
|
|
|
|
|
REG_FUNC(sysPrxForUser, console_putc);
|
|
|
|
|
|
REG_FUNC(sysPrxForUser, console_write);
|
2015-02-20 14:58:40 +01:00
|
|
|
|
});
|