From 3730c53c9ea994b36db8a2d6a60de9fad8e992ab Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 16 Sep 2014 02:58:56 +0400 Subject: [PATCH] cellSpursAttributeEnableSystemWorkload --- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 125 ++++++++++++++++------- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 19 +++- 2 files changed, 104 insertions(+), 40 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 189527fd65..d008d86a97 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -3,6 +3,7 @@ #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Callback.h" +#include "Emu/SysCalls/lv2/sys_spu.h" #include "Emu/Cell/SPURSManager.h" #include "cellSpurs.h" @@ -20,18 +21,18 @@ s64 spursInit( s32 nSpus, s32 spuPriority, s32 ppuPriority, - u32 flags, + u32 flags, // SpursAttrFlags const char prefix[], u32 prefixSize, u32 container, - u32 arg11, - u32 arg12, - u32 arg13) + const u8 swlPriority[], + u32 swlMaxSpu, + u32 swlIsPreem) { // internal function #ifdef PRX_DEBUG return cb_caller, u32, u32, s32, s32, s32, u32, u32, u32, u32, u32, u32, u32>::call(GetCurrentPPUThread(), libsre + 0x74E4, libsre_rtoc, - spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, Memory.RealToVirtualAddr(prefix), prefixSize, container, arg11, arg12, arg13); + spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, Memory.RealToVirtualAddr(prefix), prefixSize, container, Memory.RealToVirtualAddr(swlPriority), swlMaxSpu, swlIsPreem); #else //spurs->spurs = new SPURSManager(attr); return CELL_OK; @@ -53,11 +54,11 @@ s64 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s3 nSpus, spuPriority, ppuPriority, - exitIfNoWork ? 1 : 0, + exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE, nullptr, 0, 0, - 0, + nullptr, 0, 0); #endif @@ -90,13 +91,13 @@ s64 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptrm.nSpus, attr->m.spuPriority, attr->m.ppuPriority, - (u32)attr->m.flags | (attr->m.exitIfNoWork ? 1 : 0), + attr->m.flags.ToLE() | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0), attr->m.prefix, attr->m.prefixSize, attr->m.container, - attr.addr() + 0x38, - attr->_u32[16], - attr->_u32[17]); + attr->m.swlPriority, + attr->m.swlMaxSpu, + attr->m.swlIsPreem); #endif } @@ -127,13 +128,13 @@ s64 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptrm.nSpus, attr->m.spuPriority, attr->m.ppuPriority, - (u32)attr->m.flags | (attr->m.exitIfNoWork ? 1 : 0) | 4, + attr->m.flags.ToLE() | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0) | 4, // +add unknown flag attr->m.prefix, attr->m.prefixSize, attr->m.container, - attr.addr() + 0x38, - attr->_u32[16], - attr->_u32[17]); + attr->m.swlPriority, + attr->m.swlMaxSpu, + attr->m.swlIsPreem); #endif } @@ -180,13 +181,14 @@ s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr { return CELL_SPURS_CORE_ERROR_ALIGN; } - if ((u32)attr->m.flags & 0x20000000) // check unknown flag + + if (attr->m.flags.ToLE() & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) { return CELL_SPURS_CORE_ERROR_STAT; } - attr->_u32[11] = container; - attr->m.flags |= 0x40000000; // set unknown flag + attr->m.container = container; + attr->m.flags |= SAF_SPU_MEMORY_CONTAINER_SET; return CELL_OK; #endif } @@ -220,11 +222,21 @@ s64 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr attr) { -#ifdef PRX_DEBUG cellSpurs->Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr()); + +#ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x7150, libsre_rtoc); #else - UNIMPLEMENTED_FUNC(cellSpurs); + if (!attr) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + if (attr.addr() % 8) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + attr->m.flags |= SAF_SPU_PRINTF_ENABLED; return CELL_OK; #endif } @@ -245,45 +257,82 @@ s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s3 return CELL_SPURS_CORE_ERROR_ALIGN; } - if (type == 0x18) + if (type == SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT) { - if (attr->m.flags & 0x40000000) // check unknown flag + if (attr->m.flags.ToLE() & SAF_SPU_MEMORY_CONTAINER_SET) { return CELL_SPURS_CORE_ERROR_STAT; } - - attr->m.flags |= 0x20000000; // set unknown flag - return CELL_OK; + attr->m.flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set } - else if (type) + else if (type == SYS_SPU_THREAD_GROUP_TYPE_NORMAL) + { + attr->m.flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear + } + else { return CELL_SPURS_CORE_ERROR_INVAL; } - else // if type == 0 - { - attr->m.flags &= ~0x20000000; // clear unknown flag - return CELL_OK; - } + return CELL_OK; #endif } -s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) +s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) { cellSpurs->Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", attr.addr(), priority.addr(), maxSpu, isPreemptible.addr()); -#ifdef PRX_DEBUG +#ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xF410, libsre_rtoc); #else - for (s32 i = 0; i < CELL_SPURS_MAX_SPU; i++) + if (!attr) { - if (priority[i] != 1 || maxSpu == 0) + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + if (attr.addr() % 8) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + const u32 nSpus = attr->m.nSpus; + if (!nSpus) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + for (u32 i = 0; i < nSpus; i++) + { + if ((*priority)[i] == 1) { - cellSpurs->Error("cellSpursAttributeEnableSystemWorkload : CELL_SPURS_CORE_ERROR_INVAL"); - return CELL_SPURS_CORE_ERROR_INVAL; + if (!maxSpu) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + if (nSpus == 1 || attr->m.exitIfNoWork) + { + return CELL_SPURS_CORE_ERROR_PERM; + } + if (attr->m.flags.ToLE() & SAF_SYSTEM_WORKLOAD_ENABLED) + { + return CELL_SPURS_CORE_ERROR_BUSY; + } + + attr->m.flags |= SAF_SYSTEM_WORKLOAD_ENABLED; // set flag + *(u64*)attr->m.swlPriority = *(u64*)*priority; // copy system workload priorities + + u32 isPreem = 0; // generate mask from isPreemptible values + for (u32 j = 0; j < nSpus; j++) + { + if ((*isPreemptible)[j]) + { + isPreem |= (1 << j); + } + } + attr->m.swlMaxSpu = maxSpu; // write max spu for system workload + attr->m.swlIsPreem = isPreem; // write isPreemptible mask + return CELL_OK; } } - return CELL_OK; + return CELL_SPURS_CORE_ERROR_INVAL; #endif } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index bfa1520751..c01d38c5c3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -91,6 +91,17 @@ struct CellSpurs2 SPURSManager *spurs; }; +enum SpursAttrFlags : u32 +{ + SAF_NONE = 0x0, + SAF_EXIT_IF_NO_WORK = 0x1, + + SAF_SYSTEM_WORKLOAD_ENABLED = 0x02000000, + SAF_SPU_PRINTF_ENABLED = 0x10000000, + SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT = 0x20000000, + SAF_SPU_MEMORY_CONTAINER_SET = 0x40000000, +}; + struct CellSpursAttribute { static const uint align = 8; @@ -113,9 +124,13 @@ struct CellSpursAttribute bool exitIfNoWork; // 0x14 char prefix[15]; // 0x15 (not a NTS) be_t prefixSize; // 0x24 - be_t flags; // 0x28 + be_t flags; // 0x28 (SpursAttrFlags) be_t container; // 0x2C - // ... + be_t unk0; // 0x30 + be_t unk1; // 0x34 + u8 swlPriority[8]; // 0x38 + be_t swlMaxSpu; // 0x40 + be_t swlIsPreem; // 0x44 } m; // alternative implementation