mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
SPURS: Implement some portions of spurs initialization
Conflicts: rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp rpcs3/Emu/SysCalls/Modules/cellSpurs.h rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp rpcs3/Emu/SysCalls/lv2/sys_event.cpp rpcs3/Emu/SysCalls/lv2/sys_event.h rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp rpcs3/Emu/SysCalls/lv2/sys_semaphore.h rpcs3/Emu/SysCalls/lv2/sys_spu.cpp rpcs3/Emu/SysCalls/lv2/sys_spu.h
This commit is contained in:
parent
5b7f701878
commit
46e4f2d48c
13 changed files with 1408 additions and 738 deletions
File diff suppressed because it is too large
Load diff
|
@ -94,43 +94,38 @@ enum
|
||||||
// SPURS defines.
|
// SPURS defines.
|
||||||
enum SPURSKernelInterfaces
|
enum SPURSKernelInterfaces
|
||||||
{
|
{
|
||||||
CELL_SPURS_MAX_SPU = 8,
|
CELL_SPURS_MAX_SPU = 8,
|
||||||
CELL_SPURS_MAX_WORKLOAD = 16,
|
CELL_SPURS_MAX_WORKLOAD = 16,
|
||||||
CELL_SPURS_MAX_WORKLOAD2 = 32,
|
CELL_SPURS_MAX_WORKLOAD2 = 32,
|
||||||
CELL_SPURS_SYS_SERVICE_WORKLOAD_ID = 32,
|
CELL_SPURS_SYS_SERVICE_WORKLOAD_ID = 32,
|
||||||
CELL_SPURS_MAX_PRIORITY = 16,
|
CELL_SPURS_MAX_PRIORITY = 16,
|
||||||
CELL_SPURS_NAME_MAX_LENGTH = 15,
|
CELL_SPURS_NAME_MAX_LENGTH = 15,
|
||||||
CELL_SPURS_SIZE = 4096,
|
CELL_SPURS_SIZE = 4096,
|
||||||
CELL_SPURS_SIZE2 = 8192,
|
CELL_SPURS_SIZE2 = 8192,
|
||||||
CELL_SPURS_ALIGN = 128,
|
CELL_SPURS_INTERRUPT_VECTOR = 0x0,
|
||||||
CELL_SPURS_ATTRIBUTE_SIZE = 512,
|
CELL_SPURS_LOCK_LINE = 0x80,
|
||||||
CELL_SPURS_ATTRIBUTE_ALIGN = 8,
|
CELL_SPURS_KERNEL_DMA_TAG_ID = 31,
|
||||||
CELL_SPURS_INTERRUPT_VECTOR = 0x0,
|
CELL_SPURS_KERNEL1_ENTRY_ADDR = 0x818,
|
||||||
CELL_SPURS_LOCK_LINE = 0x80,
|
CELL_SPURS_KERNEL2_ENTRY_ADDR = 0x848,
|
||||||
CELL_SPURS_KERNEL_DMA_TAG_ID = 31,
|
CELL_SPURS_KERNEL1_EXIT_ADDR = 0x808,
|
||||||
CELL_SPURS_KERNEL1_ENTRY_ADDR = 0x818,
|
CELL_SPURS_KERNEL2_EXIT_ADDR = 0x838,
|
||||||
CELL_SPURS_KERNEL2_ENTRY_ADDR = 0x848,
|
|
||||||
CELL_SPURS_KERNEL1_EXIT_ADDR = 0x808,
|
|
||||||
CELL_SPURS_KERNEL2_EXIT_ADDR = 0x838,
|
|
||||||
CELL_SPURS_KERNEL1_SELECT_WORKLOAD_ADDR = 0x290,
|
CELL_SPURS_KERNEL1_SELECT_WORKLOAD_ADDR = 0x290,
|
||||||
CELL_SPURS_KERNEL2_SELECT_WORKLOAD_ADDR = 0x290,
|
CELL_SPURS_KERNEL2_SELECT_WORKLOAD_ADDR = 0x290,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RangeofEventQueuePortNumbers
|
enum RangeofEventQueuePortNumbers
|
||||||
{
|
{
|
||||||
CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15,
|
CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15,
|
||||||
CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16,
|
CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16,
|
||||||
CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63,
|
CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpursAttrFlags : u32
|
enum SpursAttrFlags : u32
|
||||||
{
|
{
|
||||||
SAF_NONE = 0x0,
|
SAF_NONE = 0x00000000,
|
||||||
|
SAF_EXIT_IF_NO_WORK = 0x00000001,
|
||||||
SAF_EXIT_IF_NO_WORK = 0x1,
|
SAF_UNKNOWN_FLAG_30 = 0x00000002,
|
||||||
SAF_UNKNOWN_FLAG_30 = 0x2,
|
SAF_SECOND_VERSION = 0x00000004,
|
||||||
SAF_SECOND_VERSION = 0x4,
|
|
||||||
|
|
||||||
SAF_UNKNOWN_FLAG_9 = 0x00400000,
|
SAF_UNKNOWN_FLAG_9 = 0x00400000,
|
||||||
SAF_UNKNOWN_FLAG_8 = 0x00800000,
|
SAF_UNKNOWN_FLAG_8 = 0x00800000,
|
||||||
SAF_UNKNOWN_FLAG_7 = 0x01000000,
|
SAF_UNKNOWN_FLAG_7 = 0x01000000,
|
||||||
|
@ -143,8 +138,7 @@ enum SpursAttrFlags : u32
|
||||||
|
|
||||||
enum SpursFlags1 : u8
|
enum SpursFlags1 : u8
|
||||||
{
|
{
|
||||||
SF1_NONE = 0x0,
|
SF1_NONE = 0x00,
|
||||||
|
|
||||||
SF1_32_WORKLOADS = 0x40,
|
SF1_32_WORKLOADS = 0x40,
|
||||||
SF1_EXIT_IF_NO_WORK = 0x80,
|
SF1_EXIT_IF_NO_WORK = 0x80,
|
||||||
};
|
};
|
||||||
|
@ -416,9 +410,10 @@ struct set_alignment(128) CellSpurs
|
||||||
{
|
{
|
||||||
struct _sub_str1
|
struct _sub_str1
|
||||||
{
|
{
|
||||||
u8 unk0[0x20]; // 0x00 - SPU exceptionh handler 0x08 - SPU exception handler args
|
u8 unk0[0x20]; // 0x00 - SPU exception handler 0x08 - SPU exception handler args
|
||||||
be_t<u64> sem; // 0x20
|
be_t<u64> sem; // 0x20
|
||||||
u8 unk1[0x8];
|
be_t<u32> x28; // 0x28
|
||||||
|
be_t<u32> x2C; // 0x2C
|
||||||
vm::bptr<CellSpursShutdownCompletionEventHook, u64> hook; // 0x30
|
vm::bptr<CellSpursShutdownCompletionEventHook, u64> hook; // 0x30
|
||||||
vm::bptr<void, u64> hookArg; // 0x38
|
vm::bptr<void, u64> hookArg; // 0x38
|
||||||
u8 unk2[0x40];
|
u8 unk2[0x40];
|
||||||
|
@ -426,26 +421,38 @@ struct set_alignment(128) CellSpurs
|
||||||
|
|
||||||
CHECK_SIZE(_sub_str1, 128);
|
CHECK_SIZE(_sub_str1, 128);
|
||||||
|
|
||||||
struct _sub_str2 // Event port multiplexer
|
struct EventPortMux;
|
||||||
|
|
||||||
|
using EventHandlerCallback = func_def<void(vm::ptr<EventPortMux>, u64 data)>;
|
||||||
|
|
||||||
|
struct EventHandlerListNode
|
||||||
{
|
{
|
||||||
be_t<u32> unk0; // 0x00 Outstanding requests
|
vm::bptr<EventHandlerListNode, u64> next;
|
||||||
be_t<u32> unk1; // 0x04
|
be_t<u64> data;
|
||||||
be_t<u32> unk2; // 0x08
|
vm::bptr<EventHandlerCallback, u64> handler;
|
||||||
be_t<u32> unk3; // 0x0C
|
|
||||||
be_t<u64> port; // 0x10
|
|
||||||
u8 unk_[0x68]; // 0x18 - The first u64 seems to be the start of a linked list. The linked list struct seems to be {u64 next; u64 data; u64 handler}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CHECK_SIZE(_sub_str2, 128);
|
struct EventPortMux
|
||||||
|
{
|
||||||
|
atomic_be_t<u32> reqPending; // 0x00
|
||||||
|
be_t<u32> spuPort; // 0x04
|
||||||
|
be_t<u32> x08; // 0x08
|
||||||
|
be_t<u32> x0C; // 0x0C
|
||||||
|
be_t<u64> eventPort; // 0x10
|
||||||
|
atomic_be_t<vm::ptr<EventHandlerListNode, u64>> handlerList; // 0x18
|
||||||
|
u8 x20[0x80 - 0x20]; // 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
CHECK_SIZE(EventPortMux, 128);
|
||||||
|
|
||||||
struct WorkloadInfo
|
struct WorkloadInfo
|
||||||
{
|
{
|
||||||
vm::bcptr<void, u64> addr; // Address of the executable
|
vm::bcptr<void, u64> addr; // 0x00 Address of the executable
|
||||||
be_t<u64> arg; // spu argument
|
be_t<u64> arg; // 0x08 Argument
|
||||||
be_t<u32> size;
|
be_t<u32> size; // 0x10 Size of the executable
|
||||||
atomic_be_t<u8> uniqueId; // The unique id is the same for all workloads with the same addr
|
atomic_be_t<u8> uniqueId; // 0x14 Unique id of the workload. It is the same for all workloads with the same addr.
|
||||||
u8 pad[3];
|
u8 pad[3];
|
||||||
u8 priority[8];
|
u8 priority[8]; // 0x18 Priority of the workload on each SPU
|
||||||
};
|
};
|
||||||
|
|
||||||
CHECK_SIZE(WorkloadInfo, 32);
|
CHECK_SIZE(WorkloadInfo, 32);
|
||||||
|
@ -463,26 +470,26 @@ struct set_alignment(128) CellSpurs
|
||||||
u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused.
|
u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused.
|
||||||
atomic_be_t<u8> wklMaxContention[0x10]; // 0x50 Max SPUs that may be allocated to each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16.
|
atomic_be_t<u8> wklMaxContention[0x10]; // 0x50 Max SPUs that may be allocated to each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16.
|
||||||
CellSpursWorkloadFlag wklFlag; // 0x60
|
CellSpursWorkloadFlag wklFlag; // 0x60
|
||||||
atomic_be_t<u16> wklSignal1; // 0x70 (bitset for 0..15 wids)
|
atomic_be_t<u16> wklSignal1; // 0x70 Bitset for 0..15 wids
|
||||||
atomic_be_t<u8> sysSrvMessage; // 0x72
|
atomic_be_t<u8> sysSrvMessage; // 0x72
|
||||||
u8 spuIdling; // 0x73
|
u8 spuIdling; // 0x73
|
||||||
u8 flags1; // 0x74 Type is SpursFlags1
|
u8 flags1; // 0x74 Type is SpursFlags1
|
||||||
u8 sysSrvTraceControl; // 0x75
|
u8 sysSrvTraceControl; // 0x75
|
||||||
u8 nSpus; // 0x76
|
u8 nSpus; // 0x76
|
||||||
atomic_be_t<u8> wklFlagReceiver; // 0x77
|
atomic_be_t<u8> wklFlagReceiver; // 0x77
|
||||||
atomic_be_t<u16> wklSignal2; // 0x78 (bitset for 16..32 wids)
|
atomic_be_t<u16> wklSignal2; // 0x78 Bitset for 16..32 wids
|
||||||
u8 x7A[6]; // 0x7A
|
u8 x7A[6]; // 0x7A
|
||||||
atomic_be_t<u8> wklState1[0x10]; // 0x80 SPURS_WKL_STATE_*
|
atomic_be_t<u8> wklState1[0x10]; // 0x80 SPURS_WKL_STATE_*
|
||||||
u8 wklStatus1[0x10]; // 0x90
|
u8 wklStatus1[0x10]; // 0x90
|
||||||
u8 wklEvent1[0x10]; // 0xA0
|
atomic_be_t<u8> wklEvent1[0x10]; // 0xA0
|
||||||
atomic_be_t<u32> wklMskA; // 0xB0 - System service - Available workloads (32*u1)
|
atomic_be_t<u32> wklEnabled; // 0xB0
|
||||||
atomic_be_t<u32> wklMskB; // 0xB4 - System service - Available module id
|
atomic_be_t<u32> wklMskB; // 0xB4 - System service - Available module id
|
||||||
u32 xB8; // 0xB8
|
u32 xB8; // 0xB8
|
||||||
u8 sysSrvExitBarrier; // 0xBC
|
u8 sysSrvExitBarrier; // 0xBC
|
||||||
atomic_be_t<u8> sysSrvMsgUpdateWorkload; // 0xBD
|
atomic_be_t<u8> sysSrvMsgUpdateWorkload; // 0xBD
|
||||||
u8 xBE; // 0xBE
|
u8 xBE; // 0xBE
|
||||||
u8 sysSrvMsgTerminate; // 0xBF
|
u8 sysSrvMsgTerminate; // 0xBF
|
||||||
u8 sysSrvWorkload[8]; // 0xC0
|
u8 sysSrvPreemptWklId[8]; // 0xC0 Id of the workload that was preempted by the system workload on each SPU
|
||||||
u8 sysSrvOnSpu; // 0xC8
|
u8 sysSrvOnSpu; // 0xC8
|
||||||
u8 spuPort; // 0xC9
|
u8 spuPort; // 0xC9
|
||||||
u8 xCA; // 0xCA
|
u8 xCA; // 0xCA
|
||||||
|
@ -493,7 +500,7 @@ struct set_alignment(128) CellSpurs
|
||||||
u8 xCF; // 0xCF
|
u8 xCF; // 0xCF
|
||||||
atomic_be_t<u8> wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_*
|
atomic_be_t<u8> wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_*
|
||||||
u8 wklStatus2[0x10]; // 0xE0
|
u8 wklStatus2[0x10]; // 0xE0
|
||||||
u8 wklEvent2[0x10]; // 0xF0
|
atomic_be_t<u8> wklEvent2[0x10]; // 0xF0
|
||||||
_sub_str1 wklF1[0x10]; // 0x100
|
_sub_str1 wklF1[0x10]; // 0x100
|
||||||
vm::bptr<CellSpursTraceInfo, u64> traceBuffer; // 0x900
|
vm::bptr<CellSpursTraceInfo, u64> traceBuffer; // 0x900
|
||||||
be_t<u32> traceStartIndex[6]; // 0x908
|
be_t<u32> traceStartIndex[6]; // 0x908
|
||||||
|
@ -508,16 +515,16 @@ struct set_alignment(128) CellSpurs
|
||||||
u8 unknown4[0xB00 - 0x998];
|
u8 unknown4[0xB00 - 0x998];
|
||||||
WorkloadInfo wklInfo1[0x10]; // 0xB00
|
WorkloadInfo wklInfo1[0x10]; // 0xB00
|
||||||
WorkloadInfo wklInfoSysSrv; // 0xD00
|
WorkloadInfo wklInfoSysSrv; // 0xD00
|
||||||
be_t<u64> ppu0; // 0xD20
|
be_t<u64> ppu0; // 0xD20 Handler thread
|
||||||
be_t<u64> ppu1; // 0xD28
|
be_t<u64> ppu1; // 0xD28
|
||||||
be_t<u32> spuTG; // 0xD30 - SPU thread group
|
be_t<u32> spuTG; // 0xD30 SPU thread group
|
||||||
be_t<u32> spus[8]; // 0xD34
|
be_t<u32> spus[8]; // 0xD34
|
||||||
u8 unknown3[0xD5C - 0xD54];
|
u8 unknown3[0xD5C - 0xD54];
|
||||||
be_t<u32> queue; // 0xD5C - Event queue
|
be_t<u32> eventQueue; // 0xD5C
|
||||||
be_t<u32> port; // 0xD60 - Event port
|
be_t<u32> eventPort; // 0xD60
|
||||||
atomic_be_t<u8> xD64; // 0xD64 - SPURS handler dirty
|
atomic_be_t<u8> handlerDirty; // 0xD64
|
||||||
atomic_be_t<u8> xD65; // 0xD65 - SPURS handler waiting
|
atomic_be_t<u8> handlerWaiting; // 0xD65
|
||||||
atomic_be_t<u8> xD66; // 0xD66 - SPURS handler exiting
|
atomic_be_t<u8> handlerExiting; // 0xD66
|
||||||
atomic_be_t<u32> enableEH; // 0xD68
|
atomic_be_t<u32> enableEH; // 0xD68
|
||||||
be_t<u32> exception; // 0xD6C
|
be_t<u32> exception; // 0xD6C
|
||||||
sys_spu_image spuImg; // 0xD70
|
sys_spu_image spuImg; // 0xD70
|
||||||
|
@ -529,12 +536,12 @@ struct set_alignment(128) CellSpurs
|
||||||
be_t<u32> unk5; // 0xD9C
|
be_t<u32> unk5; // 0xD9C
|
||||||
be_t<u32> revision; // 0xDA0
|
be_t<u32> revision; // 0xDA0
|
||||||
be_t<u32> sdkVersion; // 0xDA4
|
be_t<u32> sdkVersion; // 0xDA4
|
||||||
atomic_be_t<u64> spups; // 0xDA8 - SPU port bits
|
atomic_be_t<u64> spuPortBits; // 0xDA8
|
||||||
sys_lwmutex_t mutex; // 0xDB0
|
sys_lwmutex_t mutex; // 0xDB0
|
||||||
sys_lwcond_t cond; // 0xDC8
|
sys_lwcond_t cond; // 0xDC8
|
||||||
u8 unknown9[0xE00 - 0xDD0];
|
u8 unknown9[0xE00 - 0xDD0];
|
||||||
_sub_str4 wklH1[0x10]; // 0xE00
|
_sub_str4 wklH1[0x10]; // 0xE00
|
||||||
_sub_str2 sub3; // 0xF00
|
EventPortMux eventPortMux; // 0xF00
|
||||||
u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args
|
u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args
|
||||||
WorkloadInfo wklInfo2[0x10]; // 0x1000
|
WorkloadInfo wklInfo2[0x10]; // 0x1000
|
||||||
_sub_str1 wklF2[0x10]; // 0x1200
|
_sub_str1 wklF2[0x10]; // 0x1200
|
||||||
|
@ -552,16 +559,6 @@ struct set_alignment(128) CellSpurs
|
||||||
return wklState1[wid & 0xf];
|
return wklState1[wid & 0xf];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
force_inline vm::ptr<sys_lwmutex_t> get_lwmutex()
|
|
||||||
{
|
|
||||||
return vm::ptr<sys_lwmutex_t>::make(vm::get_addr(&mutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
force_inline vm::ptr<sys_lwcond_t> get_lwcond()
|
|
||||||
{
|
|
||||||
return vm::ptr<sys_lwcond_t>::make(vm::get_addr(&cond));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CHECK_SIZE_ALIGN(CellSpurs, 0x2000, 128);
|
CHECK_SIZE_ALIGN(CellSpurs, 0x2000, 128);
|
||||||
|
@ -888,5 +885,6 @@ struct SpursTasksetContext
|
||||||
|
|
||||||
CHECK_SIZE(SpursTasksetContext, 0x900);
|
CHECK_SIZE(SpursTasksetContext, 0x900);
|
||||||
|
|
||||||
s32 spursAttachLv2EventQueue(vm::ptr<CellSpurs> spurs, u32 queue, vm::ptr<u8> port, s32 isDynamic, bool wasCreated);
|
class SpursModuleExit
|
||||||
s32 spursWakeUp(PPUThread& CPU, vm::ptr<CellSpurs> spurs);
|
{
|
||||||
|
};
|
||||||
|
|
|
@ -11,82 +11,75 @@
|
||||||
#include "Loader/ELF32.h"
|
#include "Loader/ELF32.h"
|
||||||
#include "Emu/FS/vfsStreamMemory.h"
|
#include "Emu/FS/vfsStreamMemory.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
// Types
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class SpursModuleExit {
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Function prototypes
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// SPURS utility functions
|
|
||||||
//
|
|
||||||
void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId);
|
|
||||||
u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status);
|
|
||||||
void cellSpursModuleExit(SPUThread & spu);
|
|
||||||
|
|
||||||
bool spursDma(SPUThread & spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag);
|
|
||||||
u32 spursDmaGetCompletionStatus(SPUThread & spu, u32 tagMask);
|
|
||||||
u32 spursDmaWaitForCompletion(SPUThread & spu, u32 tagMask, bool waitForAll = true);
|
|
||||||
void spursHalt(SPUThread & spu);
|
|
||||||
|
|
||||||
//
|
|
||||||
// SPURS Kernel functions
|
|
||||||
//
|
|
||||||
bool spursKernel1SelectWorkload(SPUThread & spu);
|
|
||||||
bool spursKernel2SelectWorkload(SPUThread & spu);
|
|
||||||
void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus);
|
|
||||||
bool spursKernelWorkloadExit(SPUThread & spu);
|
|
||||||
bool spursKernelEntry(SPUThread & spu);
|
|
||||||
|
|
||||||
//
|
|
||||||
// SPURS System Service functions
|
|
||||||
//
|
|
||||||
bool spursSysServiceEntry(SPUThread & spu);
|
|
||||||
// TODO: Exit
|
|
||||||
void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt);
|
|
||||||
void spursSysServiceMain(SPUThread & spu, u32 pollStatus);
|
|
||||||
void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt);
|
|
||||||
void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt);
|
|
||||||
// TODO: Deactivate workload
|
|
||||||
void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelContext * ctxt, u32 wklShutdownBitSet);
|
|
||||||
void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt);
|
|
||||||
void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4);
|
|
||||||
// TODO: Deactivate trace
|
|
||||||
// TODO: System workload entry
|
|
||||||
void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelContext * ctxt);
|
|
||||||
|
|
||||||
//
|
|
||||||
// SPURS Taskset Policy Module functions
|
|
||||||
//
|
|
||||||
bool spursTasksetEntry(SPUThread & spu);
|
|
||||||
bool spursTasksetSyscallEntry(SPUThread & spu);
|
|
||||||
void spursTasksetResumeTask(SPUThread & spu);
|
|
||||||
void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs);
|
|
||||||
s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * isWaiting);
|
|
||||||
void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus);
|
|
||||||
bool spursTasksetPollStatus(SPUThread & spu);
|
|
||||||
void spursTasksetExit(SPUThread & spu);
|
|
||||||
void spursTasksetOnTaskExit(SPUThread & spu, u64 addr, u32 taskId, s32 exitCode, u64 args);
|
|
||||||
s32 spursTasketSaveTaskContext(SPUThread & spu);
|
|
||||||
void spursTasksetDispatch(SPUThread & spu);
|
|
||||||
s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args);
|
|
||||||
void spursTasksetInit(SPUThread & spu, u32 pollStatus);
|
|
||||||
s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Externs
|
// Externs
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
extern Module cellSpurs;
|
extern Module cellSpurs;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
|
// Function prototypes
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//
|
||||||
// SPURS utility functions
|
// SPURS utility functions
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//
|
||||||
|
static void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId);
|
||||||
|
static u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status);
|
||||||
|
static void cellSpursModuleExit(SPUThread & spu);
|
||||||
|
|
||||||
|
static bool spursDma(SPUThread & spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag);
|
||||||
|
static u32 spursDmaGetCompletionStatus(SPUThread & spu, u32 tagMask);
|
||||||
|
static u32 spursDmaWaitForCompletion(SPUThread & spu, u32 tagMask, bool waitForAll = true);
|
||||||
|
static void spursHalt(SPUThread & spu);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPURS kernel functions
|
||||||
|
//
|
||||||
|
static bool spursKernel1SelectWorkload(SPUThread & spu);
|
||||||
|
static bool spursKernel2SelectWorkload(SPUThread & spu);
|
||||||
|
static void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus);
|
||||||
|
static bool spursKernelWorkloadExit(SPUThread & spu);
|
||||||
|
bool spursKernelEntry(SPUThread & spu);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPURS system workload functions
|
||||||
|
//
|
||||||
|
static bool spursSysServiceEntry(SPUThread & spu);
|
||||||
|
// TODO: Exit
|
||||||
|
static void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt);
|
||||||
|
static void spursSysServiceMain(SPUThread & spu, u32 pollStatus);
|
||||||
|
static void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt);
|
||||||
|
static void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt);
|
||||||
|
// TODO: Deactivate workload
|
||||||
|
static void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelContext * ctxt, u32 wklShutdownBitSet);
|
||||||
|
static void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt);
|
||||||
|
static void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4);
|
||||||
|
// TODO: Deactivate trace
|
||||||
|
// TODO: System workload entry
|
||||||
|
static void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelContext * ctxt);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPURS taskset policy module functions
|
||||||
|
//
|
||||||
|
static bool spursTasksetEntry(SPUThread & spu);
|
||||||
|
static bool spursTasksetSyscallEntry(SPUThread & spu);
|
||||||
|
static void spursTasksetResumeTask(SPUThread & spu);
|
||||||
|
static void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs);
|
||||||
|
static s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * isWaiting);
|
||||||
|
static void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus);
|
||||||
|
static bool spursTasksetPollStatus(SPUThread & spu);
|
||||||
|
static void spursTasksetExit(SPUThread & spu);
|
||||||
|
static void spursTasksetOnTaskExit(SPUThread & spu, u64 addr, u32 taskId, s32 exitCode, u64 args);
|
||||||
|
static s32 spursTasketSaveTaskContext(SPUThread & spu);
|
||||||
|
static void spursTasksetDispatch(SPUThread & spu);
|
||||||
|
static s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args);
|
||||||
|
static void spursTasksetInit(SPUThread & spu, u32 pollStatus);
|
||||||
|
static s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// SPURS utility functions
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Output trace information
|
/// Output trace information
|
||||||
void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId) {
|
void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId) {
|
||||||
|
@ -160,9 +153,9 @@ void spursHalt(SPUThread & spu) {
|
||||||
spu.halt();
|
spu.halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
// SPURS kernel functions
|
// SPURS kernel functions
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Select a workload to run
|
/// Select a workload to run
|
||||||
bool spursKernel1SelectWorkload(SPUThread & spu) {
|
bool spursKernel1SelectWorkload(SPUThread & spu) {
|
||||||
|
@ -582,9 +575,9 @@ bool spursKernelEntry(SPUThread & spu) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
// SPURS system workload functions
|
// SPURS system workload functions
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Entry point of the system service
|
/// Entry point of the system service
|
||||||
bool spursSysServiceEntry(SPUThread & spu) {
|
bool spursSysServiceEntry(SPUThread & spu) {
|
||||||
|
@ -931,14 +924,14 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC
|
||||||
for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) {
|
for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) {
|
||||||
if (wklShutdownBitSet & (0x80000000u >> i)) {
|
if (wklShutdownBitSet & (0x80000000u >> i)) {
|
||||||
spurs->wklEvent1[i] |= 0x01;
|
spurs->wklEvent1[i] |= 0x01;
|
||||||
if (spurs->wklEvent1[i] & 0x02 || spurs->wklEvent1[i] & 0x10) {
|
if (spurs->wklEvent1[i].read_relaxed() & 0x02 || spurs->wklEvent1[i].read_relaxed() & 0x10) {
|
||||||
wklNotifyBitSet |= 0x80000000u >> i;
|
wklNotifyBitSet |= 0x80000000u >> i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wklShutdownBitSet & (0x8000 >> i)) {
|
if (wklShutdownBitSet & (0x8000 >> i)) {
|
||||||
spurs->wklEvent2[i] |= 0x01;
|
spurs->wklEvent2[i] |= 0x01;
|
||||||
if (spurs->wklEvent2[i] & 0x02 || spurs->wklEvent2[i] & 0x10) {
|
if (spurs->wklEvent2[i].read_relaxed() & 0x02 || spurs->wklEvent2[i].read_relaxed() & 0x10) {
|
||||||
wklNotifyBitSet |= 0x8000 >> i;
|
wklNotifyBitSet |= 0x8000 >> i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1022,13 +1015,13 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte
|
||||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() {
|
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() {
|
||||||
auto spurs = ctxt->spurs.priv_ptr();
|
auto spurs = ctxt->spurs.priv_ptr();
|
||||||
|
|
||||||
if (spurs->sysSrvWorkload[ctxt->spuNum] == 0xFF) {
|
if (spurs->sysSrvPreemptWklId[ctxt->spuNum] == 0xFF) {
|
||||||
do_return = true;
|
do_return = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wklId = spurs->sysSrvWorkload[ctxt->spuNum];
|
wklId = spurs->sysSrvPreemptWklId[ctxt->spuNum];
|
||||||
spurs->sysSrvWorkload[ctxt->spuNum] = 0xFF;
|
spurs->sysSrvPreemptWklId[ctxt->spuNum] = 0xFF;
|
||||||
|
|
||||||
memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128);
|
memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128);
|
||||||
});
|
});
|
||||||
|
@ -1066,9 +1059,9 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte
|
||||||
ctxt->wklCurrentId = wklIdSaved;
|
ctxt->wklCurrentId = wklIdSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
// SPURS taskset policy module functions
|
// SPURS taskset policy module functions
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum SpursTasksetRequest {
|
enum SpursTasksetRequest {
|
||||||
SPURS_TASKSET_REQUEST_POLL_SIGNAL = -1,
|
SPURS_TASKSET_REQUEST_POLL_SIGNAL = -1,
|
||||||
|
|
|
@ -41,3 +41,5 @@ s32 sys_lwcond_signal(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||||
s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||||
s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
||||||
s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
||||||
|
|
||||||
|
void sys_ppu_thread_exit(PPUThread& CPU, u64 val);
|
||||||
|
|
|
@ -28,6 +28,12 @@ enum
|
||||||
SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //???
|
SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //???
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// attr_pshared
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SYS_SYNC_NOT_PROCESS_SHARED = 0x200
|
||||||
|
};
|
||||||
|
|
||||||
class sleep_queue_t
|
class sleep_queue_t
|
||||||
{
|
{
|
||||||
std::vector<u32> m_waiting;
|
std::vector<u32> m_waiting;
|
||||||
|
|
|
@ -13,6 +13,13 @@
|
||||||
|
|
||||||
SysCallBase sys_event("sys_event");
|
SysCallBase sys_event("sys_event");
|
||||||
|
|
||||||
|
void sys_event_queue_attribute_initialize(vm::ptr<sys_event_queue_attr> attr)
|
||||||
|
{
|
||||||
|
attr->protocol = SYS_SYNC_PRIORITY;
|
||||||
|
attr->type = SYS_PPU_QUEUE;
|
||||||
|
attr->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr> attr, u64 event_queue_key, s32 size)
|
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr> attr, u64 event_queue_key, s32 size)
|
||||||
{
|
{
|
||||||
sys_event.Warning("sys_event_queue_create(equeue_id=*0x%x, attr=*0x%x, event_queue_key=0x%llx, size=%d)", equeue_id, attr, event_queue_key, size);
|
sys_event.Warning("sys_event_queue_create(equeue_id=*0x%x, attr=*0x%x, event_queue_key=0x%llx, size=%d)", equeue_id, attr, event_queue_key, size);
|
||||||
|
|
|
@ -15,12 +15,24 @@ enum : s32
|
||||||
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
|
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Event Queue Ipc Key
|
||||||
|
enum : u64
|
||||||
|
{
|
||||||
|
SYS_EVENT_QUEUE_LOCAL = 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
// Event Port Type
|
// Event Port Type
|
||||||
enum : s32
|
enum : s32
|
||||||
{
|
{
|
||||||
SYS_EVENT_PORT_LOCAL = 1,
|
SYS_EVENT_PORT_LOCAL = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Event Port Name
|
||||||
|
enum : u64
|
||||||
|
{
|
||||||
|
SYS_EVENT_PORT_NO_NAME = 0,
|
||||||
|
};
|
||||||
|
|
||||||
// Event Source Type
|
// Event Source Type
|
||||||
enum : u32
|
enum : u32
|
||||||
{
|
{
|
||||||
|
@ -31,8 +43,9 @@ enum : u32
|
||||||
// Event Source Key
|
// Event Source Key
|
||||||
enum : u64
|
enum : u64
|
||||||
{
|
{
|
||||||
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501,
|
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501ull,
|
||||||
SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502, // ???
|
SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502ull,
|
||||||
|
SYS_SPU_THREAD_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sys_event_queue_attr
|
struct sys_event_queue_attr
|
||||||
|
@ -129,6 +142,8 @@ REG_ID_TYPE(lv2_event_port_t, 0x0E); // SYS_EVENT_PORT_OBJECT
|
||||||
|
|
||||||
class PPUThread;
|
class PPUThread;
|
||||||
|
|
||||||
|
void sys_event_queue_attribute_initialize(vm::ptr<sys_event_queue_attr> attr);
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr> attr, u64 event_queue_key, s32 size);
|
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attr> attr, u64 event_queue_key, s32 size);
|
||||||
s32 sys_event_queue_destroy(u32 equeue_id, s32 mode);
|
s32 sys_event_queue_destroy(u32 equeue_id, s32 mode);
|
||||||
|
|
|
@ -12,6 +12,13 @@
|
||||||
|
|
||||||
SysCallBase sys_lwmutex("sys_lwmutex");
|
SysCallBase sys_lwmutex("sys_lwmutex");
|
||||||
|
|
||||||
|
void sys_lwmutex_attribute_initialize(vm::ptr<sys_lwmutex_attribute_t> attr)
|
||||||
|
{
|
||||||
|
attr->protocol = SYS_SYNC_PRIORITY;
|
||||||
|
attr->recursive = SYS_SYNC_NOT_RECURSIVE;
|
||||||
|
attr->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
void lwmutex_create(sys_lwmutex_t& lwmutex, bool recursive, u32 protocol, u64 name)
|
void lwmutex_create(sys_lwmutex_t& lwmutex, bool recursive, u32 protocol, u64 name)
|
||||||
{
|
{
|
||||||
lwmutex.lock_var = { { lwmutex::free, lwmutex::zero } };
|
lwmutex.lock_var = { { lwmutex::free, lwmutex::zero } };
|
||||||
|
|
|
@ -90,9 +90,7 @@ struct lv2_lwmutex_t
|
||||||
REG_ID_TYPE(lv2_lwmutex_t, 0x95); // SYS_LWMUTEX_OBJECT
|
REG_ID_TYPE(lv2_lwmutex_t, 0x95); // SYS_LWMUTEX_OBJECT
|
||||||
|
|
||||||
// Aux
|
// Aux
|
||||||
void lwmutex_create(sys_lwmutex_t& lwmutex, bool recursive, u32 protocol, u64 name);
|
void sys_lwmutex_attribute_initialize(vm::ptr<sys_lwmutex_attribute_t> attr);
|
||||||
|
|
||||||
class PPUThread;
|
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6);
|
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6);
|
||||||
|
|
|
@ -12,6 +12,15 @@
|
||||||
|
|
||||||
SysCallBase sys_semaphore("sys_semaphore");
|
SysCallBase sys_semaphore("sys_semaphore");
|
||||||
|
|
||||||
|
void sys_semaphore_attribute_initialize(vm::ptr<sys_semaphore_attribute_t> attr)
|
||||||
|
{
|
||||||
|
attr->protocol = SYS_SYNC_PRIORITY;
|
||||||
|
attr->pshared = SYS_SYNC_NOT_PROCESS_SHARED;
|
||||||
|
attr->ipc_key = 0;
|
||||||
|
attr->flags = 0;
|
||||||
|
attr->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
s32 sys_semaphore_create(vm::ptr<u32> sem, vm::ptr<sys_semaphore_attribute_t> attr, s32 initial_val, s32 max_val)
|
s32 sys_semaphore_create(vm::ptr<u32> sem, vm::ptr<sys_semaphore_attribute_t> attr, s32 initial_val, s32 max_val)
|
||||||
{
|
{
|
||||||
sys_semaphore.Warning("sys_semaphore_create(sem=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem, attr, initial_val, max_val);
|
sys_semaphore.Warning("sys_semaphore_create(sem=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem, attr, initial_val, max_val);
|
||||||
|
|
|
@ -41,6 +41,9 @@ struct lv2_sema_t
|
||||||
|
|
||||||
REG_ID_TYPE(lv2_sema_t, 0x96); // SYS_SEMAPHORE_OBJECT
|
REG_ID_TYPE(lv2_sema_t, 0x96); // SYS_SEMAPHORE_OBJECT
|
||||||
|
|
||||||
|
// Aux
|
||||||
|
void sys_semaphore_attribute_initialize(vm::ptr<sys_semaphore_attribute_t> attr);
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
s32 sys_semaphore_create(vm::ptr<u32> sem, vm::ptr<sys_semaphore_attribute_t> attr, s32 initial_val, s32 max_val);
|
s32 sys_semaphore_create(vm::ptr<u32> sem, vm::ptr<sys_semaphore_attribute_t> attr, s32 initial_val, s32 max_val);
|
||||||
s32 sys_semaphore_destroy(u32 sem);
|
s32 sys_semaphore_destroy(u32 sem);
|
||||||
|
|
|
@ -465,6 +465,13 @@ s32 sys_spu_thread_group_yield(u32 id)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sys_spu_thread_group_attribute_initialize(vm::ptr<sys_spu_thread_group_attribute> attr)
|
||||||
|
{
|
||||||
|
attr->name = vm::null;
|
||||||
|
attr->nsize = 0;
|
||||||
|
attr->type = SYS_SPU_THREAD_GROUP_TYPE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
s32 sys_spu_thread_group_terminate(u32 id, s32 value)
|
s32 sys_spu_thread_group_terminate(u32 id, s32 value)
|
||||||
{
|
{
|
||||||
sys_spu.Warning("sys_spu_thread_group_terminate(id=0x%x, value=0x%x)", id, value);
|
sys_spu.Warning("sys_spu_thread_group_terminate(id=0x%x, value=0x%x)", id, value);
|
||||||
|
|
|
@ -216,10 +216,12 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep);
|
||||||
s32 spu_image_import(sys_spu_image& img, u32 src, u32 type);
|
s32 spu_image_import(sys_spu_image& img, u32 src, u32 type);
|
||||||
u32 spu_thread_group_create(const std::string& name, u32 num, s32 prio, s32 type, u32 container);
|
u32 spu_thread_group_create(const std::string& name, u32 num, s32 prio, s32 type, u32 container);
|
||||||
u32 spu_thread_initialize(u32 group, u32 spu_num, vm::ptr<sys_spu_image> img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function<void(SPUThread&)> task = nullptr);
|
u32 spu_thread_initialize(u32 group, u32 spu_num, vm::ptr<sys_spu_image> img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function<void(SPUThread&)> task = nullptr);
|
||||||
|
void sys_spu_thread_group_attribute_initialize(vm::ptr<sys_spu_thread_group_attribute> attr);
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
||||||
s32 sys_spu_image_open(vm::ptr<sys_spu_image> img, vm::cptr<char> path);
|
s32 sys_spu_image_open(vm::ptr<sys_spu_image> img, vm::cptr<char> path);
|
||||||
|
s32 sys_spu_image_close(vm::ptr<sys_spu_image> img);
|
||||||
s32 sys_spu_thread_initialize(vm::ptr<u32> thread, u32 group, u32 spu_num, vm::ptr<sys_spu_image> img, vm::ptr<sys_spu_thread_attribute> attr, vm::ptr<sys_spu_thread_argument> arg);
|
s32 sys_spu_thread_initialize(vm::ptr<u32> thread, u32 group, u32 spu_num, vm::ptr<sys_spu_image> img, vm::ptr<sys_spu_thread_attribute> attr, vm::ptr<sys_spu_thread_argument> arg);
|
||||||
s32 sys_spu_thread_set_argument(u32 id, vm::ptr<sys_spu_thread_argument> arg);
|
s32 sys_spu_thread_set_argument(u32 id, vm::ptr<sys_spu_thread_argument> arg);
|
||||||
s32 sys_spu_thread_group_create(vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_spu_thread_group_attribute> attr);
|
s32 sys_spu_thread_group_create(vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_spu_thread_group_attribute> attr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue