예제 #1
0
s32 sys_ppu_thread_create(vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname)
{
	sysPrxForUser.warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=%s)",
		thread_id, entry, arg, prio, stacksize, flags, threadname);

	// Allocate TLS
	const u32 tls_addr = ppu_alloc_tls();

	if (!tls_addr)
	{
		return CELL_ENOMEM;
	}

	// Call the syscall
	if (s32 res = _sys_ppu_thread_create(thread_id, vm::make_var(ppu_thread_param_t{ entry, tls_addr + 0x7030 }), arg, 0, prio, stacksize, flags, threadname))
	{
		return res;
	}

	if (flags & SYS_PPU_THREAD_CREATE_INTERRUPT)
	{
		return CELL_OK;
	}

	// Run the thread
	if (s32 res = sys_ppu_thread_start(static_cast<u32>(*thread_id)))
	{
		return res;
	}

	// Dirty hack for sound: confirm the creation of _mxr000 event queue
	if (threadname && std::memcmp(threadname.get_ptr(), "_cellsurMixerMain", 18) == 0)
	{
		while (!idm::select<lv2_event_queue>([](u32, lv2_event_queue& eq)
		{
			return eq.name == "_mxr000\0"_u64;
		}))
		{
			thread_ctrl::sleep(50000);
		}
	}

	return CELL_OK;
}
예제 #2
0
void sys_initialize_tls(PPUThread& 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
	g_tls_size = Emu.GetTLSMemsz() + TLS_SYS;
	g_tls_addr = vm::alloc(0x20000, vm::main) + 0x30;
	g_tls_max = (0xffd0 / g_tls_size) + (0x10000 / g_tls_size);
	g_tls_map = std::make_unique<atomic_t<bool>[]>(g_tls_max);

	// Allocate TLS for main thread
	ppu.GPR[13] = ppu_alloc_tls() + 0x7000 + TLS_SYS;

	sysPrxForUser.notice("TLS initialized (addr=0x%x, size=0x%x, max=0x%zu)", g_tls_addr - 0x30, g_tls_size, g_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;
}