From e896da806444aee8723f1dc6878fb076f99235e7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 21 Jun 2015 17:48:21 +0300 Subject: [PATCH] Added .aligned() method for vm::ptr Added set_alignment() macro for setting alignment Added alignof32() macro similar to sizeof32() Added CHECK_SIZE, CHECK_ALIGN macro with static_assert Minor refactoring --- Utilities/BEType.h | 2 +- Utilities/GNU.h | 6 + rpcs3/Emu/ARMv7/Modules/sceGxm.cpp | 16 +- rpcs3/Emu/ARMv7/Modules/sceVoice.cpp | 8 +- rpcs3/Emu/Memory/vm_ptr.h | 10 + rpcs3/Emu/SysCalls/Modules/cellAdec.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 6 +- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 60 +- rpcs3/Emu/SysCalls/Modules/cellPamf.h | 14 +- rpcs3/Emu/SysCalls/Modules/cellSail.h | 4 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 958 ++++++++++---------- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 890 +++++++++--------- rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp | 332 +++---- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 72 +- rpcs3/Emu/SysCalls/Modules/cellSync.h | 28 +- rpcs3/Emu/SysCalls/Modules/cellSync2.h | 8 +- rpcs3/Emu/SysCalls/lv2/sys_spu.h | 2 +- rpcs3/stdafx.h | 21 +- 18 files changed, 1202 insertions(+), 1237 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index d478e04d92..ef298fdf93 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -388,7 +388,7 @@ union u128 } }; -static_assert(__alignof(u128) == 16 && sizeof(u128) == 16, "Wrong u128 size or alignment"); +CHECK_SIZE_ALIGN(u128, 16, 16); static force_inline u128 sync_val_compare_and_swap(volatile u128* dest, u128 comp, u128 exch) { diff --git a/Utilities/GNU.h b/Utilities/GNU.h index 64a45acb63..1335bba3b4 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -26,6 +26,12 @@ #define force_inline __attribute__((always_inline)) #endif +#if defined(_MSC_VER) +#define set_alignment(x) _CRT_ALIGN(x) +#else +#define set_alignment(x) __attribute__((aligned(x))) +#endif + template void strcpy_trunc(char(&dst)[size], const std::string& src) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp b/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp index 14a3358a64..d8f3730e6c 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp @@ -453,15 +453,15 @@ s32 sceGxmDepthStencilSurfaceInitDisabled(vm::ptr sur throw __FUNCTION__; } -//float sceGxmDepthStencilSurfaceGetBackgroundDepth(vm::ptr surface) -//{ -// throw __FUNCTION__; -//} +float sceGxmDepthStencilSurfaceGetBackgroundDepth(vm::ptr surface) +{ + throw __FUNCTION__; +} -//void sceGxmDepthStencilSurfaceSetBackgroundDepth(vm::ptr surface, float backgroundDepth) -//{ -// throw __FUNCTION__; -//} +void sceGxmDepthStencilSurfaceSetBackgroundDepth(vm::ptr surface, float backgroundDepth) +{ + throw __FUNCTION__; +} u8 sceGxmDepthStencilSurfaceGetBackgroundStencil(vm::ptr surface) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp b/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp index 7fc1dbf90b..9d4949c0fb 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp @@ -79,10 +79,10 @@ s32 sceVoiceGetMuteFlag(u32 portId, vm::ptr bMuted) throw __FUNCTION__; } -//s32 sceVoiceSetVolume(u32 portId, float volume) -//{ -// throw __FUNCTION__; -//} +s32 sceVoiceSetVolume(u32 portId, float volume) +{ + throw __FUNCTION__; +} s32 sceVoiceGetVolume(u32 portId, vm::ptr volume) { diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 0eb033c20f..a691b7b405 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -68,6 +68,16 @@ namespace vm return m_addr != 0; } + bool aligned() const + { + return m_addr % alignof32(T) == 0; + } + + bool operator %(to_ne_t alignment) + { + return m_addr % alignment != 0; + } + _ptr_base& operator =(const _ptr_base&) = default; }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index c4144879ec..713798fb41 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1096,7 +1096,7 @@ struct OMAHeader // OMA Header } }; -static_assert(sizeof(OMAHeader) == 96, "Wrong OMAHeader size"); +CHECK_SIZE(OMAHeader, 96); class AudioDecoder { diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index e857e9acf8..9ebfb31270 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -867,7 +867,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } @@ -900,7 +900,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } @@ -963,7 +963,7 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index bfad4c783c..bf5e8a5084 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -1218,7 +1218,7 @@ s32 cellGcmCallback(vm::ptr context, u32 count) context->end = newCommandBuffer.second; // Wait for rsx to "release" the new command buffer - while (true) + while (!Emu.IsStopped()) { u32 getPos = ctrl.get.read_sync().value(); if (isInCommandBufferExcept(getPos, newCommandBuffer.first, newCommandBuffer.second)) @@ -1232,24 +1232,24 @@ s32 cellGcmCallback(vm::ptr context, u32 count) return CELL_OK; - if (0) - { - auto& ctrl = vm::get_ref(gcm_info.control_addr); - be_t res = be_t::make(context->current - context->begin - ctrl.put.read_relaxed()); + //if (0) + //{ + // auto& ctrl = vm::get_ref(gcm_info.control_addr); + // be_t res = be_t::make(context->current - context->begin - ctrl.put.read_relaxed()); - if (res != 0) - { - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); - } + // if (res != 0) + // { + // GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); + // } - memmove(vm::get_ptr(context->begin), vm::get_ptr(context->current - res), res); + // memmove(vm::get_ptr(context->begin), vm::get_ptr(context->current - res), res); - context->current = context->begin + res; - ctrl.put.write_relaxed(res); - ctrl.get.write_relaxed(be_t::make(0)); + // context->current = context->begin + res; + // ctrl.put.write_relaxed(res); + // ctrl.get.write_relaxed(be_t::make(0)); - return CELL_OK; - } + // return CELL_OK; + //} //auto& ctrl = vm::get_ref(gcm_info.control_addr); @@ -1261,23 +1261,23 @@ s32 cellGcmCallback(vm::ptr context, u32 count) //cmd[3] = 0; // some incrementing by module value //context->current += 0x10; - if (0) - { - const u32 address = context->begin; - const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits - assert(upper != 0xFFFF); - const u32 offset = (upper << 20) | (address & 0xFFFFF); - vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | offset); // set JUMP cmd + //if (0) + //{ + // const u32 address = context->begin; + // const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits + // assert(upper != 0xFFFF); + // const u32 offset = (upper << 20) | (address & 0xFFFFF); + // vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | offset); // set JUMP cmd - auto& ctrl = vm::get_ref(gcm_info.control_addr); - ctrl.put.exchange(be_t::make(offset)); - } - else - { - vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT | (0)); - } + // auto& ctrl = vm::get_ref(gcm_info.control_addr); + // ctrl.put.exchange(be_t::make(offset)); + //} + //else + //{ + // vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT | (0)); + //} - context->current = context->begin; // rewind to the beginning + //context->current = context->begin; // rewind to the beginning // TODO: something is missing return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.h b/rpcs3/Emu/SysCalls/Modules/cellPamf.h index 87eae0c9f6..213d83c83b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.h @@ -200,7 +200,7 @@ struct CellPamfAvcInfo u8 maxMeanBitrate; }; -static_assert(sizeof(CellPamfAvcInfo) == 0x20, "Invalid CellPamfAvcInfo size"); +CHECK_SIZE(CellPamfAvcInfo, 0x20); // M2V (MPEG2 Video) Specific Information struct CellPamfM2vInfo @@ -223,7 +223,7 @@ struct CellPamfM2vInfo u8 matrixCoefficients; }; -static_assert(sizeof(CellPamfM2vInfo) == 0x18, "Invalid CellPamfM2vInfo size"); +CHECK_SIZE(CellPamfM2vInfo, 0x18); // ATRAC3+ Audio Specific Information struct CellPamfAtrac3plusInfo @@ -232,7 +232,7 @@ struct CellPamfAtrac3plusInfo u8 numberOfChannels; }; -static_assert(sizeof(CellPamfAtrac3plusInfo) == 8, "Invalid CellPamfAtrac3plusInfo size"); +CHECK_SIZE(CellPamfAtrac3plusInfo, 8); // AC3 Audio Specific Information struct CellPamfAc3Info @@ -241,7 +241,7 @@ struct CellPamfAc3Info u8 numberOfChannels; }; -static_assert(sizeof(CellPamfAc3Info) == 8, "Invalid CellPamfAc3Info size"); +CHECK_SIZE(CellPamfAc3Info, 8); // LPCM Audio Specific Information struct CellPamfLpcmInfo @@ -337,7 +337,7 @@ struct PamfStreamHeader }; }; -static_assert(sizeof(PamfStreamHeader) == 48, "Invalid PamfStreamHeader size"); +CHECK_SIZE(PamfStreamHeader, 48); struct PamfHeader { @@ -379,7 +379,7 @@ struct PamfEpHeader be_t rpnOffset; }; -static_assert(sizeof(PamfEpHeader) == 12, "Invalid PamfEpHeader size"); +CHECK_SIZE(PamfEpHeader, 12); #pragma pack(pop) @@ -392,6 +392,6 @@ struct CellPamfReader u32 internalData[28]; }; -static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size"); +CHECK_SIZE(CellPamfReader, 128); s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute); \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.h b/rpcs3/Emu/SysCalls/Modules/cellSail.h index a8fab2b6e9..e8eee799b3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.h @@ -1043,7 +1043,7 @@ struct CellSailDescriptor be_t internalData[31]; }; -static_assert(sizeof(CellSailDescriptor) == 0x100, "Invalid CellSailDescriptor size"); +CHECK_SIZE(CellSailDescriptor, 0x100); struct CellSailStartCommand { @@ -1110,4 +1110,4 @@ struct CellSailPlayer be_t internalData[26]; }; -static_assert(sizeof(CellSailPlayer) == 0x100, "Invalid CellSailPlayer size"); \ No newline at end of file +CHECK_SIZE(CellSailPlayer, 0x100); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 9af59c5bb8..8671a67c7d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -66,7 +66,7 @@ s32 spursInit( { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } @@ -80,39 +80,39 @@ s32 spursInit( } const bool isSecond = (flags & SAF_SECOND_VERSION) != 0; - memset(spurs.get_ptr(), 0, CellSpurs::size1 + isSecond * CellSpurs::size2); - spurs->m.revision = revision; - spurs->m.sdkVersion = sdkVersion; - spurs->m.ppu0 = 0xffffffffull; - spurs->m.ppu1 = 0xffffffffull; - spurs->m.flags = flags; - memcpy(spurs->m.prefix, prefix, prefixSize); - spurs->m.prefixSize = (u8)prefixSize; + memset(spurs.get_ptr(), 0, isSecond ? CELL_SPURS_SIZE2 : CELL_SPURS_SIZE); + spurs->revision = revision; + spurs->sdkVersion = sdkVersion; + spurs->ppu0 = 0xffffffffull; + spurs->ppu1 = 0xffffffffull; + spurs->flags = flags; + memcpy(spurs->prefix, prefix, prefixSize); + spurs->prefixSize = (u8)prefixSize; std::string name(prefix, prefixSize); // initialize name string if (!isSecond) { - spurs->m.wklMskA.write_relaxed(be_t::make(0xffff)); + spurs->wklMskA.write_relaxed(be_t::make(0xffff)); } - spurs->m.xCC = 0; - spurs->m.xCD = 0; - spurs->m.sysSrvMsgUpdateTrace = 0; + spurs->xCC = 0; + spurs->xCD = 0; + spurs->sysSrvMsgUpdateTrace = 0; for (u32 i = 0; i < 8; i++) { - spurs->m.sysSrvWorkload[i] = -1; + spurs->sysSrvWorkload[i] = -1; } // default or system workload: - spurs->m.wklInfoSysSrv.addr.set(be_t::make(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD)); - spurs->m.wklInfoSysSrv.arg = 0; - spurs->m.wklInfoSysSrv.uniqueId.write_relaxed(0xff); + spurs->wklInfoSysSrv.addr.set(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD); + spurs->wklInfoSysSrv.arg = 0; + spurs->wklInfoSysSrv.uniqueId.write_relaxed(0xff); u32 sem; for (u32 i = 0; i < 0x10; i++) { sem = Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0); assert(sem && ~sem); // should rollback if semaphore creation failed and return the error - spurs->m.wklF1[i].sem = sem; + spurs->wklF1[i].sem = sem; } if (isSecond) { @@ -120,20 +120,20 @@ s32 spursInit( { sem = Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0); assert(sem && ~sem); - spurs->m.wklF2[i].sem = sem; + spurs->wklF2[i].sem = sem; } } sem = Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuPrv", 0); assert(sem && ~sem); - spurs->m.semPrv = sem; - spurs->m.unk11 = -1; - spurs->m.unk12 = -1; - spurs->m.unk13 = 0; - spurs->m.nSpus = nSpus; - spurs->m.spuPriority = spuPriority; + spurs->semPrv = sem; + spurs->unk11 = -1; + spurs->unk12 = -1; + spurs->unk13 = 0; + spurs->nSpus = nSpus; + spurs->spuPriority = spuPriority; - spurs->m.spuImg.addr = Memory.MainMem.AllocAlign(0x40000, 4096); - spurs->m.spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; + spurs->spuImg.addr = Memory.MainMem.AllocAlign(0x40000, 4096); + spurs->spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; s32 tgt = SYS_SPU_THREAD_GROUP_TYPE_NORMAL; if (flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) @@ -149,51 +149,51 @@ s32 spursInit( if (flags & SAF_UNKNOWN_FLAG_7) tgt |= 0x102; if (flags & SAF_UNKNOWN_FLAG_8) tgt |= 0xC02; if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800; - spurs->m.spuTG = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container); - assert(spurs->m.spuTG.data()); + spurs->spuTG = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container); + assert(spurs->spuTG.data()); name += "CellSpursKernel0"; for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++) { - spurs->m.spus[num] = spu_thread_initialize(spurs->m.spuTG, num, vm::ptr::make(spurs.addr() + offsetof(CellSpurs, m.spuImg)), + spurs->spus[num] = spu_thread_initialize(spurs->spuTG, num, vm::ptr::make(spurs.addr() + offsetof(CellSpurs, spuImg)), name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0, [spurs](SPUThread& SPU) { - SPU.RegisterHleFunction(spurs->m.spuImg.entry_point, spursKernelEntry); - SPU.FastCall(spurs->m.spuImg.entry_point); + SPU.RegisterHleFunction(spurs->spuImg.entry_point, spursKernelEntry); + SPU.FastCall(spurs->spuImg.entry_point); }); } if (flags & SAF_SPU_PRINTF_ENABLED) { // spu_printf: attach group - if (!spu_printf_agcb || spu_printf_agcb(spurs->m.spuTG) != CELL_OK) + if (!spu_printf_agcb || spu_printf_agcb(spurs->spuTG) != CELL_OK) { // remove flag if failed - spurs->m.flags &= ~SAF_SPU_PRINTF_ENABLED; + spurs->flags &= ~SAF_SPU_PRINTF_ENABLED; } } - lwmutex_create(spurs->m.mutex, false, SYS_SYNC_PRIORITY, *(u64*)"_spuPrv"); - lwcond_create(spurs->m.cond, spurs->m.mutex, *(u64*)"_spuPrv"); + lwmutex_create(spurs->mutex, false, SYS_SYNC_PRIORITY, *(u64*)"_spuPrv"); + lwcond_create(spurs->cond, spurs->mutex, *(u64*)"_spuPrv"); - spurs->m.flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_32_WORKLOADS : 0); - spurs->m.wklFlagReceiver.write_relaxed(0xff); - spurs->m.wklFlag.flag.write_relaxed(be_t::make(-1)); - spurs->_u8[0xD64] = 0; - spurs->_u8[0xD65] = 0; - spurs->_u8[0xD66] = 0; - spurs->m.ppuPriority = ppuPriority; + spurs->flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_32_WORKLOADS : 0); + spurs->wklFlagReceiver.write_relaxed(0xff); + spurs->wklFlag.flag.write_relaxed(be_t::make(-1)); + spurs->xD64 = {}; + spurs->xD65 = {}; + spurs->xD66 = {}; + spurs->ppuPriority = ppuPriority; u32 queue; if (s32 res = spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv")) { assert(!"spursCreateLv2EventQueue() failed"); } - spurs->m.queue = queue; + spurs->queue = queue; u32 port = Emu.GetIdManager().make(SYS_EVENT_PORT_LOCAL, 0); assert(port && ~port); - spurs->m.port = port; + spurs->port = port; if (s32 res = sys_event_port_connect_local(port, queue)) { @@ -202,9 +202,9 @@ s32 spursInit( name = std::string(prefix, prefixSize); - spurs->m.ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU) + spurs->ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU) { - if (spurs->m.flags & SAF_UNKNOWN_FLAG_30) + if (spurs->flags & SAF_UNKNOWN_FLAG_30) { return; } @@ -217,13 +217,13 @@ s32 spursInit( return; } - if (spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) + if (spurs->flags1 & SF1_EXIT_IF_NO_WORK) { if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0)) { assert(!"sys_lwmutex_lock() failed"); } - if (spurs->m.xD66.read_relaxed()) + if (spurs->xD66.read_relaxed()) { if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) { @@ -235,21 +235,21 @@ s32 spursInit( { if (Emu.IsStopped()) break; - spurs->m.xD64.exchange(0); - if (spurs->m.exception.data() == 0) + spurs->xD64.exchange(0); + if (spurs->exception.data() == 0) { bool do_break = false; for (u32 i = 0; i < 16; i++) { - if (spurs->m.wklState1[i].read_relaxed() == 2 && - *((u64 *)spurs->m.wklInfo1[i].priority) != 0 && - spurs->m.wklMaxContention[i].read_relaxed() & 0xf + if (spurs->wklState1[i].read_relaxed() == 2 && + *((u64 *)spurs->wklInfo1[i].priority) != 0 && + spurs->wklMaxContention[i].read_relaxed() & 0xf ) { - if (spurs->m.wklReadyCount1[i].read_relaxed() || - spurs->m.wklSignal1.read_relaxed() & (0x8000u >> i) || - (spurs->m.wklFlag.flag.read_relaxed() == 0 && - spurs->m.wklFlagReceiver.read_relaxed() == (u8)i + if (spurs->wklReadyCount1[i].read_relaxed() || + spurs->wklSignal1.read_relaxed() & (0x8000u >> i) || + (spurs->wklFlag.flag.read_relaxed() == 0 && + spurs->wklFlagReceiver.read_relaxed() == (u8)i )) { do_break = true; @@ -257,17 +257,17 @@ s32 spursInit( } } } - if (spurs->m.flags1 & SF1_32_WORKLOADS) for (u32 i = 0; i < 16; i++) + if (spurs->flags1 & SF1_32_WORKLOADS) for (u32 i = 0; i < 16; i++) { - if (spurs->m.wklState2[i].read_relaxed() == 2 && - *((u64 *)spurs->m.wklInfo2[i].priority) != 0 && - spurs->m.wklMaxContention[i].read_relaxed() & 0xf0 + if (spurs->wklState2[i].read_relaxed() == 2 && + *((u64 *)spurs->wklInfo2[i].priority) != 0 && + spurs->wklMaxContention[i].read_relaxed() & 0xf0 ) { - if (spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() || - spurs->m.wklSignal2.read_relaxed() & (0x8000u >> i) || - (spurs->m.wklFlag.flag.read_relaxed() == 0 && - spurs->m.wklFlagReceiver.read_relaxed() == (u8)i + 0x10 + if (spurs->wklIdleSpuCountOrReadyCount2[i].read_relaxed() || + spurs->wklSignal2.read_relaxed() & (0x8000u >> i) || + (spurs->wklFlag.flag.read_relaxed() == 0 && + spurs->wklFlagReceiver.read_relaxed() == (u8)i + 0x10 )) { do_break = true; @@ -278,16 +278,16 @@ s32 spursInit( if (do_break) break; // from while } - spurs->m.xD65.exchange(1); - if (spurs->m.xD64.read_relaxed() == 0) + spurs->xD65.exchange(1); + if (spurs->xD64.read_relaxed() == 0) { if (s32 res = sys_lwcond_wait(CPU, spurs->get_lwcond(), 0)) { assert(!"sys_lwcond_wait() failed"); } } - spurs->m.xD65.exchange(0); - if (spurs->m.xD66.read_relaxed()) + spurs->xD65.exchange(0); + if (spurs->xD66.read_relaxed()) { if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) { @@ -307,11 +307,11 @@ s32 spursInit( if (Emu.IsStopped()) continue; - if (s32 res = sys_spu_thread_group_start(spurs->m.spuTG)) + if (s32 res = sys_spu_thread_group_start(spurs->spuTG)) { assert(!"sys_spu_thread_group_start() failed"); } - if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::null, vm::null)) + if (s32 res = sys_spu_thread_group_join(spurs->spuTG, vm::null, vm::null)) { if (res == CELL_ESTAT) { @@ -322,36 +322,36 @@ s32 spursInit( if (Emu.IsStopped()) continue; - if ((spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) == 0) + if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0) { - assert(spurs->m.xD66.read_relaxed() == 1 || Emu.IsStopped()); + assert(spurs->xD66.read_relaxed() == 1 || Emu.IsStopped()); return; } } }); - spurs->m.ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU) + spurs->ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU) { // TODO }); // enable exception event handler - if (spurs->m.enableEH.compare_and_swap_test(be_t::make(0), be_t::make(1))) + if (spurs->enableEH.compare_and_swap_test(be_t::make(0), be_t::make(1))) { - if (s32 res = sys_spu_thread_group_connect_event(spurs->m.spuTG, spurs->m.queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION)) + if (s32 res = sys_spu_thread_group_connect_event(spurs->spuTG, spurs->queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION)) { assert(!"sys_spu_thread_group_connect_event() failed"); } } - spurs->m.traceBuffer.set(0); + spurs->traceBuffer.set(0); // can also use cellLibprof if available (omitted) // some unknown subroutine - spurs->m.sub3.unk1 = spurs.addr() + 0xc9; - spurs->m.sub3.unk2 = 3; // unknown const - spurs->m.sub3.port = (u64)spurs->m.port; + spurs->sub3.unk1 = spurs.addr() + 0xc9; + spurs->sub3.unk2 = 3; // unknown const + spurs->sub3.port = (u64)spurs->port; if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) // initialize system workload (disabled) { @@ -396,29 +396,29 @@ s32 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptrm.revision > 2) + if (attr->revision > 2) { return CELL_SPURS_CORE_ERROR_INVAL; } return spursInit( spurs, - attr->m.revision, - attr->m.sdkVersion, - attr->m.nSpus, - attr->m.spuPriority, - attr->m.ppuPriority, - attr->m.flags | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0), - attr->m.prefix, - attr->m.prefixSize, - attr->m.container, - attr->m.swlPriority, - attr->m.swlMaxSpu, - attr->m.swlIsPreem); + attr->revision, + attr->sdkVersion, + attr->nSpus, + attr->spuPriority, + attr->ppuPriority, + attr->flags | (attr->exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0), + attr->prefix, + attr->prefixSize, + attr->container, + attr->swlPriority, + attr->swlMaxSpu, + attr->swlIsPreem); } s32 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptr attr) @@ -429,29 +429,29 @@ s32 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptrm.revision > 2) + if (attr->revision > 2) { return CELL_SPURS_CORE_ERROR_INVAL; } return spursInit( spurs, - attr->m.revision, - attr->m.sdkVersion, - attr->m.nSpus, - attr->m.spuPriority, - attr->m.ppuPriority, - attr->m.flags | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0) | SAF_SECOND_VERSION, - attr->m.prefix, - attr->m.prefixSize, - attr->m.container, - attr->m.swlPriority, - attr->m.swlMaxSpu, - attr->m.swlIsPreem); + attr->revision, + attr->sdkVersion, + attr->nSpus, + attr->spuPriority, + attr->ppuPriority, + attr->flags | (attr->exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0) | SAF_SECOND_VERSION, + attr->prefix, + attr->prefixSize, + attr->container, + attr->swlPriority, + attr->swlMaxSpu, + attr->swlIsPreem); } s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) @@ -463,18 +463,18 @@ s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - memset(attr.get_ptr(), 0, attr->size); - attr->m.revision = revision; - attr->m.sdkVersion = sdkVersion; - attr->m.nSpus = nSpus; - attr->m.spuPriority = spuPriority; - attr->m.ppuPriority = ppuPriority; - attr->m.exitIfNoWork = exitIfNoWork; + memset(attr.get_ptr(), 0, sizeof(CellSpursAttribute)); + attr->revision = revision; + attr->sdkVersion = sdkVersion; + attr->nSpus = nSpus; + attr->spuPriority = spuPriority; + attr->ppuPriority = ppuPriority; + attr->exitIfNoWork = exitIfNoWork; return CELL_OK; } @@ -486,18 +486,18 @@ s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (attr->m.flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) + if (attr->flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) { return CELL_SPURS_CORE_ERROR_STAT; } - attr->m.container = container; - attr->m.flags |= SAF_SPU_MEMORY_CONTAINER_SET; + attr->container = container; + attr->flags |= SAF_SPU_MEMORY_CONTAINER_SET; return CELL_OK; } @@ -509,7 +509,7 @@ s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr attr, vm::ptrm.prefix, prefix.get_ptr(), size); - attr->m.prefixSize = size; + memcpy(attr->prefix, prefix.get_ptr(), size); + attr->prefixSize = size; return CELL_OK; } @@ -532,12 +532,12 @@ s32 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr att { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - attr->m.flags |= SAF_SPU_PRINTF_ENABLED; + attr->flags |= SAF_SPU_PRINTF_ENABLED; return CELL_OK; } @@ -549,22 +549,22 @@ s32 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s3 { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } if (type == SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT) { - if (attr->m.flags & SAF_SPU_MEMORY_CONTAINER_SET) + if (attr->flags & SAF_SPU_MEMORY_CONTAINER_SET) { return CELL_SPURS_CORE_ERROR_STAT; } - attr->m.flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set + attr->flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set } else if (type == SYS_SPU_THREAD_GROUP_TYPE_NORMAL) { - attr->m.flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear + attr->flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear } else { @@ -582,16 +582,18 @@ s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - const u32 nSpus = attr->_u32[2]; + const u32 nSpus = attr->nSpus; + if (!nSpus) { return CELL_SPURS_CORE_ERROR_INVAL; } + for (u32 i = 0; i < nSpus; i++) { if ((*priority)[i] == 1) @@ -600,17 +602,17 @@ s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: { return CELL_SPURS_CORE_ERROR_INVAL; } - if (nSpus == 1 || attr->m.exitIfNoWork) + if (nSpus == 1 || attr->exitIfNoWork) { return CELL_SPURS_CORE_ERROR_PERM; } - if (attr->m.flags & SAF_SYSTEM_WORKLOAD_ENABLED) + if (attr->flags & 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 + attr->flags |= SAF_SYSTEM_WORKLOAD_ENABLED; // set flag + *(u64*)attr->swlPriority = *(u64*)*priority; // copy system workload priorities u32 isPreem = 0; // generate mask from isPreemptible values for (u32 j = 0; j < nSpus; j++) @@ -620,8 +622,8 @@ s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: isPreem |= (1 << j); } } - attr->m.swlMaxSpu = maxSpu; // write max spu for system workload - attr->m.swlIsPreem = isPreem; // write isPreemptible mask + attr->swlMaxSpu = maxSpu; // write max spu for system workload + attr->swlIsPreem = isPreem; // write isPreemptible mask return CELL_OK; } } @@ -636,11 +638,11 @@ s32 cellSpursFinalize(vm::ptr spurs) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (spurs->m.xD66.read_relaxed()) + if (spurs->xD66.read_relaxed()) { return CELL_SPURS_CORE_ERROR_STAT; } @@ -656,11 +658,11 @@ s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (spurs->m.exception.data()) + if (spurs->exception.data()) { return CELL_SPURS_CORE_ERROR_STAT; } @@ -694,7 +696,7 @@ s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po } assert(port_mask); // zero mask will return CELL_EINVAL - if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->m.spuTG, queue, port_mask, port)) + if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, port_mask, port)) { if (res == CELL_EISCONN) { @@ -705,7 +707,7 @@ s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po if (!wasCreated) { - spurs->m.spups |= be_t::make(1ull << *port); // atomic bitwise or + spurs->spups |= be_t::make(1ull << *port); // atomic bitwise or } return CELL_OK; } @@ -738,12 +740,12 @@ s32 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - *group = spurs->m.spuTG; + *group = spurs->spuTG; return CELL_OK; } @@ -755,12 +757,12 @@ s32 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - *nThreads = (u32)spurs->m.nSpus; + *nThreads = (u32)spurs->nSpus; return CELL_OK; } @@ -772,15 +774,15 @@ s32 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::p { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - const u32 count = std::min(*nThreads, spurs->m.nSpus); + const u32 count = std::min(*nThreads, spurs->nSpus); for (u32 i = 0; i < count; i++) { - thread[i] = spurs->m.spus[i]; + thread[i] = spurs->spus[i]; } *nThreads = count; return CELL_OK; @@ -834,17 +836,17 @@ s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (spurs->m.exception.data()) + if (spurs->exception.data()) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } - spurs->m.xD64.exchange(1); - if (spurs->m.xD65.read_sync()) + spurs->xD64.exchange(1); + if (spurs->xD65.read_sync()) { if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0)) { @@ -887,7 +889,7 @@ s32 spursAddWorkload( { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128 || pm.addr() % 16) + if (!spurs.aligned() || pm % 16) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } @@ -895,14 +897,14 @@ s32 spursAddWorkload( { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if (spurs->m.exception.data()) + if (spurs->exception.data()) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } u32 wnum; - const u32 wmax = spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u; // TODO: check if can be changed - spurs->m.wklMskA.atomic_op([spurs, wmax, &wnum](be_t& value) + const u32 wmax = spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u; // TODO: check if can be changed + spurs->wklMskA.atomic_op([spurs, wmax, &wnum](be_t& value) { wnum = cntlz32(~(u32)value); // found empty position if (wnum < wmax) @@ -920,86 +922,86 @@ s32 spursAddWorkload( u32 index = wnum & 0xf; if (wnum <= 15) { - assert((spurs->m.wklCurrentContention[wnum] & 0xf) == 0); - assert((spurs->m.wklPendingContention[wnum] & 0xf) == 0); - spurs->m.wklState1[wnum].write_relaxed(1); - spurs->m.wklStatus1[wnum] = 0; - spurs->m.wklEvent1[wnum] = 0; - spurs->m.wklInfo1[wnum].addr = pm; - spurs->m.wklInfo1[wnum].arg = data; - spurs->m.wklInfo1[wnum].size = size; + assert((spurs->wklCurrentContention[wnum] & 0xf) == 0); + assert((spurs->wklPendingContention[wnum] & 0xf) == 0); + spurs->wklState1[wnum].write_relaxed(1); + spurs->wklStatus1[wnum] = 0; + spurs->wklEvent1[wnum] = 0; + spurs->wklInfo1[wnum].addr = pm; + spurs->wklInfo1[wnum].arg = data; + spurs->wklInfo1[wnum].size = size; for (u32 i = 0; i < 8; i++) { - spurs->m.wklInfo1[wnum].priority[i] = priorityTable[i]; + spurs->wklInfo1[wnum].priority[i] = priorityTable[i]; } - spurs->m.wklH1[wnum].nameClass = nameClass; - spurs->m.wklH1[wnum].nameInstance = nameInstance; - memset(spurs->m.wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id - memset(spurs->m.wklF1[wnum].unk1, 0, 0x58); + spurs->wklH1[wnum].nameClass = nameClass; + spurs->wklH1[wnum].nameInstance = nameInstance; + memset(spurs->wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(spurs->wklF1[wnum].unk1, 0, 0x58); if (hook) { - spurs->m.wklF1[wnum].hook = hook; - spurs->m.wklF1[wnum].hookArg = hookArg; - spurs->m.wklEvent1[wnum] |= 2; + spurs->wklF1[wnum].hook = hook; + spurs->wklF1[wnum].hookArg = hookArg; + spurs->wklEvent1[wnum] |= 2; } - if ((spurs->m.flags1 & SF1_32_WORKLOADS) == 0) + if ((spurs->flags1 & SF1_32_WORKLOADS) == 0) { - spurs->m.wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); - spurs->m.wklMinContention[wnum] = minContention > 8 ? 8 : minContention; + spurs->wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); + spurs->wklMinContention[wnum] = minContention > 8 ? 8 : minContention; } - spurs->m.wklReadyCount1[wnum].write_relaxed(0); + spurs->wklReadyCount1[wnum].write_relaxed(0); } else { - assert((spurs->m.wklCurrentContention[index] & 0xf0) == 0); - assert((spurs->m.wklPendingContention[index] & 0xf0) == 0); - spurs->m.wklState2[index].write_relaxed(1); - spurs->m.wklStatus2[index] = 0; - spurs->m.wklEvent2[index] = 0; - spurs->m.wklInfo2[index].addr = pm; - spurs->m.wklInfo2[index].arg = data; - spurs->m.wklInfo2[index].size = size; + assert((spurs->wklCurrentContention[index] & 0xf0) == 0); + assert((spurs->wklPendingContention[index] & 0xf0) == 0); + spurs->wklState2[index].write_relaxed(1); + spurs->wklStatus2[index] = 0; + spurs->wklEvent2[index] = 0; + spurs->wklInfo2[index].addr = pm; + spurs->wklInfo2[index].arg = data; + spurs->wklInfo2[index].size = size; for (u32 i = 0; i < 8; i++) { - spurs->m.wklInfo2[index].priority[i] = priorityTable[i]; + spurs->wklInfo2[index].priority[i] = priorityTable[i]; } - spurs->m.wklH2[index].nameClass = nameClass; - spurs->m.wklH2[index].nameInstance = nameInstance; - memset(spurs->m.wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id - memset(spurs->m.wklF2[index].unk1, 0, 0x58); + spurs->wklH2[index].nameClass = nameClass; + spurs->wklH2[index].nameInstance = nameInstance; + memset(spurs->wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(spurs->wklF2[index].unk1, 0, 0x58); if (hook) { - spurs->m.wklF2[index].hook = hook; - spurs->m.wklF2[index].hookArg = hookArg; - spurs->m.wklEvent2[index] |= 2; + spurs->wklF2[index].hook = hook; + spurs->wklF2[index].hookArg = hookArg; + spurs->wklEvent2[index] |= 2; } - spurs->m.wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); + spurs->wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); } if (wnum <= 15) { - spurs->m.wklMaxContention[wnum].atomic_op([maxContention](u8& v) + spurs->wklMaxContention[wnum].atomic_op([maxContention](u8& v) { v &= ~0xf; v |= (maxContention > 8 ? 8 : maxContention); }); - spurs->m.wklSignal1._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag1 + spurs->wklSignal1._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag1 } else { - spurs->m.wklMaxContention[index].atomic_op([maxContention](u8& v) + spurs->wklMaxContention[index].atomic_op([maxContention](u8& v) { v &= ~0xf0; v |= (maxContention > 8 ? 8 : maxContention) << 4; }); - spurs->m.wklSignal2._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag2 + spurs->wklSignal2._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag2 } - spurs->m.wklFlagReceiver.compare_and_swap(wnum, 0xff); + spurs->wklFlagReceiver.compare_and_swap(wnum, 0xff); u32 res_wkl; - CellSpurs::WorkloadInfo& wkl = wnum <= 15 ? spurs->m.wklInfo1[wnum] : spurs->m.wklInfo2[wnum & 0xf]; - spurs->m.wklMskB.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t& v) + CellSpurs::WorkloadInfo& wkl = wnum <= 15 ? spurs->wklInfo1[wnum] : spurs->wklInfo2[wnum & 0xf]; + spurs->wklMskB.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t& v) { const u32 mask = v & ~(0x80000000u >> wnum); res_wkl = 0; @@ -1008,7 +1010,7 @@ s32 spursAddWorkload( { if (mask & m) { - CellSpurs::WorkloadInfo& current = i <= 15 ? spurs->m.wklInfo1[i] : spurs->m.wklInfo2[i & 0xf]; + CellSpurs::WorkloadInfo& current = i <= 15 ? spurs->wklInfo1[i] : spurs->wklInfo2[i & 0xf]; if (current.addr.addr() == wkl.addr.addr()) { // if a workload with identical policy module found @@ -1029,8 +1031,8 @@ s32 spursAddWorkload( assert(res_wkl <= 31); spurs->wklState(wnum).exchange(2); - spurs->m.sysSrvMsgUpdateWorkload.exchange(0xff); - spurs->m.sysSrvMessage.exchange(0xff); + spurs->sysSrvMsgUpdateWorkload.exchange(0xff); + spurs->sysSrvMessage.exchange(0xff); return CELL_OK; } @@ -1080,7 +1082,7 @@ s32 _cellSpursWorkloadAttributeInitialize( { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } @@ -1088,7 +1090,7 @@ s32 _cellSpursWorkloadAttributeInitialize( { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (pm.addr() % 16) + if (pm % 16) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } @@ -1097,15 +1099,15 @@ s32 _cellSpursWorkloadAttributeInitialize( return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - memset(attr.get_ptr(), 0, CellSpursWorkloadAttribute::size); - attr->m.revision = revision; - attr->m.sdkVersion = sdkVersion; - attr->m.pm = pm; - attr->m.size = size; - attr->m.data = data; - *(u64*)attr->m.priority = *(u64*)*priorityTable; - attr->m.minContention = minContention; - attr->m.maxContention = maxContention; + memset(attr.get_ptr(), 0, sizeof(CellSpursWorkloadAttribute)); + attr->revision = revision; + attr->sdkVersion = sdkVersion; + attr->pm = pm; + attr->size = size; + attr->data = data; + *(u64*)attr->priority = *(u64*)*priorityTable; + attr->minContention = minContention; + attr->maxContention = maxContention; return CELL_OK; } @@ -1117,13 +1119,13 @@ s32 cellSpursWorkloadAttributeSetName(vm::ptr attr, { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - attr->m.nameClass = nameClass; - attr->m.nameInstance = nameInstance; + attr->nameClass = nameClass; + attr->nameInstance = nameInstance; return CELL_OK; } @@ -1135,13 +1137,13 @@ s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptrm.hook = hook; - attr->m.hookArg = arg; + attr->hook = hook; + attr->hookArg = arg; return CELL_OK; } @@ -1153,11 +1155,11 @@ s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptrm.revision != be_t::make(1)) + if (attr->revision != be_t::make(1)) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } @@ -1165,16 +1167,16 @@ s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptrm.pm, - attr->m.size, - attr->m.data, - attr->m.priority, - attr->m.minContention, - attr->m.maxContention, - attr->m.nameClass, - attr->m.nameInstance, - attr->m.hook, - attr->m.hookArg); + attr->pm, + attr->size, + attr->data, + attr->priority, + attr->minContention, + attr->maxContention, + attr->nameClass, + attr->nameInstance, + attr->hook, + attr->hookArg); } s32 cellSpursRemoveWorkload() @@ -1203,34 +1205,34 @@ s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (wid >= (spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u)) + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u)) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) + if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } - if (spurs->m.exception.data()) + if (spurs->exception.data()) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } - if (s32 res = spurs->m.wklFlag.flag.atomic_op_sync(0, [spurs, wid, is_set](be_t& flag) -> s32 + if (s32 res = spurs->wklFlag.flag.atomic_op_sync(0, [spurs, wid, is_set](be_t& flag) -> s32 { if (is_set) { - if (spurs->m.wklFlagReceiver.read_relaxed() != 0xff) + if (spurs->wklFlagReceiver.read_relaxed() != 0xff) { return CELL_SPURS_POLICY_MODULE_ERROR_BUSY; } } else { - if (spurs->m.wklFlagReceiver.read_relaxed() != wid) + if (spurs->wklFlagReceiver.read_relaxed() != wid) { return CELL_SPURS_POLICY_MODULE_ERROR_PERM; } @@ -1242,7 +1244,7 @@ s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set return res; } - spurs->m.wklFlagReceiver.atomic_op([wid, is_set](u8& FR) + spurs->wklFlagReceiver.atomic_op([wid, is_set](u8& FR) { if (is_set) { @@ -1270,12 +1272,12 @@ s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::pptrset(vm::get_addr(&spurs->m.wklFlag)); + flag->set(vm::get_addr(&spurs->wklFlag)); return CELL_OK; } @@ -1283,27 +1285,27 @@ s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) { cellSpurs.Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId); - if (spurs.addr() == 0) + if (!spurs) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->m.flags1 & SF1_32_WORKLOADS) == 0)) + if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0)) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) + if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } - if (spurs->m.exception) + if (spurs->exception) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } @@ -1311,11 +1313,11 @@ s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) u8 state; if (workloadId >= CELL_SPURS_MAX_WORKLOAD) { - state = spurs->m.wklState2[workloadId & 0x0F].read_relaxed(); + state = spurs->wklState2[workloadId & 0x0F].read_relaxed(); } else { - state = spurs->m.wklState1[workloadId].read_relaxed(); + state = spurs->wklState1[workloadId].read_relaxed(); } if (state != SPURS_WKL_STATE_RUNNABLE) @@ -1325,11 +1327,11 @@ s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) if (workloadId >= CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklSignal2 |= be_t::make(0x8000 >> (workloadId & 0x0F)); + spurs->wklSignal2 |= be_t::make(0x8000 >> (workloadId & 0x0F)); } else { - spurs->m.wklSignal1 |= be_t::make(0x8000 >> workloadId); + spurs->wklSignal1 |= be_t::make(0x8000 >> workloadId); } return CELL_OK; @@ -1339,38 +1341,38 @@ s32 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 wo { cellSpurs.Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId); - if (spurs.addr() == 0 || data.addr() == 0) + if (!spurs || !data) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->m.flags1 & SF1_32_WORKLOADS) == 0)) + if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0)) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) + if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } - if (spurs->m.exception) + if (spurs->exception) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } if (workloadId >= CELL_SPURS_MAX_WORKLOAD) { - *data = spurs->m.wklInfo2[workloadId & 0x0F].arg; + *data = spurs->wklInfo2[workloadId & 0x0F].arg; } else { - *data = spurs->m.wklInfo1[workloadId].arg; + *data = spurs->wklInfo1[workloadId].arg; } return CELL_OK; @@ -1384,30 +1386,30 @@ s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (wid >= (spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u) || value > 0xff) + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u) || value > 0xff) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) + if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } - if (spurs->m.exception.data() || spurs->wklState(wid).read_relaxed() != 2) + if (spurs->exception.data() || spurs->wklState(wid).read_relaxed() != 2) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } if (wid < CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklReadyCount1[wid].exchange((u8)value); + spurs->wklReadyCount1[wid].exchange((u8)value); } else { - spurs->m.wklIdleSpuCountOrReadyCount2[wid].exchange((u8)value); + spurs->wklIdleSpuCountOrReadyCount2[wid].exchange((u8)value); } return CELL_OK; } @@ -1465,22 +1467,17 @@ s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptrm.wid >= CELL_SPURS_MAX_WORKLOAD2) + if (taskset.addr() && taskset->wid >= CELL_SPURS_MAX_WORKLOAD2) { return CELL_SPURS_TASK_ERROR_INVAL; } @@ -1490,19 +1487,19 @@ s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptrm.direction = flagDirection; - eventFlag->m.clearMode = flagClearMode; - eventFlag->m.spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; + memset(eventFlag.get_ptr(), 0, sizeof(CellSpursEventFlag)); + eventFlag->direction = flagDirection; + eventFlag->clearMode = flagClearMode; + eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; if (taskset.addr()) { - eventFlag->m.addr = taskset.addr(); + eventFlag->addr = taskset.addr(); } else { - eventFlag->m.isIwl = 1; - eventFlag->m.addr = spurs.addr(); + eventFlag->isIwl = 1; + eventFlag->addr = spurs.addr(); } return CELL_OK; @@ -1517,30 +1514,30 @@ s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_AGAIN; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - if (eventFlag->m.spuPort != CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + if (eventFlag->spuPort != CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) { return CELL_SPURS_TASK_ERROR_STAT; } vm::ptr spurs; - if (eventFlag->m.isIwl == 1) + if (eventFlag->isIwl == 1) { - spurs.set((u32)eventFlag->m.addr); + spurs.set((u32)eventFlag->addr); } else { - auto taskset = vm::ptr::make((u32)eventFlag->m.addr); - spurs.set((u32)taskset->m.spurs.addr()); + auto taskset = vm::ptr::make((u32)eventFlag->addr); + spurs.set((u32)taskset->spurs.addr()); } u32 eventQueueId; @@ -1552,7 +1549,7 @@ s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF)); } - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { vm::var> eventPortId; rc = sys_event_port_create(vm::ref::make(eventPortId.addr()), SYS_EVENT_PORT_LOCAL, 0); @@ -1561,7 +1558,7 @@ s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) rc = sys_event_port_connect_local(eventPortId.value(), eventQueueId); if (rc == CELL_OK) { - eventFlag->m.eventPortId = eventPortId; + eventFlag->eventPortId = eventPortId; goto success; } @@ -1579,8 +1576,8 @@ s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) } success: - eventFlag->m.eventQueueId = eventQueueId; - eventFlag->m.spuPort = port; + eventFlag->eventQueueId = eventQueueId; + eventFlag->spuPort = port; return CELL_OK; } @@ -1593,44 +1590,44 @@ s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_AGAIN; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - if (eventFlag->m.spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + if (eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) { return CELL_SPURS_TASK_ERROR_STAT; } - if (eventFlag->m.ppuWaitMask || eventFlag->m.ppuPendingRecv) + if (eventFlag->ppuWaitMask || eventFlag->ppuPendingRecv) { return CELL_SPURS_TASK_ERROR_BUSY; } - auto port = eventFlag->m.spuPort; - eventFlag->m.spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; + auto port = eventFlag->spuPort; + eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; vm::ptr spurs; - if (eventFlag->m.isIwl == 1) + if (eventFlag->isIwl == 1) { - spurs.set((u32)eventFlag->m.addr); + spurs.set((u32)eventFlag->addr); } else { - auto taskset = vm::ptr::make((u32)eventFlag->m.addr); - spurs.set((u32)taskset->m.spurs.addr()); + auto taskset = vm::ptr::make((u32)eventFlag->addr); + spurs.set((u32)taskset->spurs.addr()); } - if(eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + if(eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { - sys_event_port_disconnect(eventFlag->m.eventPortId); - sys_event_port_destroy(eventFlag->m.eventPortId); + sys_event_port_disconnect(eventFlag->eventPortId); + sys_event_port_destroy(eventFlag->eventPortId); } s32 rc = CELL_OK; @@ -1638,7 +1635,7 @@ s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) // auto rc = spursDetachLv2EventQueue(spurs, port, 1); // if (rc == CELL_OK) // { - // rc = sys_event_queue_destroy(eventFlag->m.eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE); + // rc = sys_event_queue_destroy(eventFlag->eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE); // } if (rc != CELL_OK) @@ -1652,12 +1649,12 @@ s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) { - if (eventFlag.addr() == 0 || mask.addr() == 0) + if (!eventFlag || !mask) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -1667,23 +1664,23 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr return CELL_SPURS_TASK_ERROR_INVAL; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - if (block && eventFlag->m.spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + if (block && eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) { return CELL_SPURS_TASK_ERROR_STAT; } - if (eventFlag->m.ppuWaitMask || eventFlag->m.ppuPendingRecv) + if (eventFlag->ppuWaitMask || eventFlag->ppuPendingRecv) { return CELL_SPURS_TASK_ERROR_BUSY; } - u16 relevantEvents = eventFlag->m.events & *mask; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + u16 relevantEvents = eventFlag->events & *mask; + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { // Make sure the wait mask and mode specified does not conflict with that of the already waiting tasks. // Conflict scenarios: @@ -1695,10 +1692,10 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr // This set is equal to 'set of all tasks waiting' - 'set of all tasks whose wait conditions have been met'. // If the wait mode is OR, we prune the set of all tasks that are waiting in OR mode from the set since a conflict cannot occur // with an already waiting task in OR mode. - u16 relevantWaitSlots = eventFlag->m.spuTaskUsedWaitSlots & ~eventFlag->m.spuTaskPendingRecv; + u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~eventFlag->spuTaskPendingRecv; if (mode == CELL_SPURS_EVENT_FLAG_OR) { - relevantWaitSlots &= eventFlag->m.spuTaskWaitMode; + relevantWaitSlots &= eventFlag->spuTaskWaitMode; } int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; @@ -1706,7 +1703,7 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr { if (relevantWaitSlots & 0x0001) { - if (eventFlag->m.spuTaskWaitMask[i] & *mask && eventFlag->m.spuTaskWaitMask[i] != *mask) + if (eventFlag->spuTaskWaitMask[i] & *mask && eventFlag->spuTaskWaitMask[i] != *mask) { return CELL_SPURS_TASK_ERROR_AGAIN; } @@ -1723,9 +1720,9 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr if ((*mask & ~relevantEvents) == 0 || (mode == CELL_SPURS_EVENT_FLAG_OR && relevantEvents)) { // If the clear flag is AUTO then clear the bits comnsumed by this thread - if (eventFlag->m.clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) + if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) { - eventFlag->m.events &= ~relevantEvents; + eventFlag->events &= ~relevantEvents; } recv = false; @@ -1739,12 +1736,12 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr return CELL_SPURS_TASK_ERROR_BUSY; } - eventFlag->m.ppuWaitSlotAndMode = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + eventFlag->ppuWaitSlotAndMode = 0; + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { // Find an unsed wait slot int i = 0; - u16 spuTaskUsedWaitSlots = eventFlag->m.spuTaskUsedWaitSlots; + u16 spuTaskUsedWaitSlots = eventFlag->spuTaskUsedWaitSlots; while (spuTaskUsedWaitSlots & 0x0001) { spuTaskUsedWaitSlots >>= 1; @@ -1758,12 +1755,12 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr } // Mark the found wait slot as used by this thread - eventFlag->m.ppuWaitSlotAndMode = (CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1 - i) << 4; + eventFlag->ppuWaitSlotAndMode = (CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1 - i) << 4; } // Save the wait mask and mode for this thread - eventFlag->m.ppuWaitSlotAndMode |= mode; - eventFlag->m.ppuWaitMask = *mask; + eventFlag->ppuWaitSlotAndMode |= mode; + eventFlag->ppuWaitMask = *mask; recv = true; } @@ -1771,20 +1768,20 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr if (recv) { // Block till something happens vm::var data; - auto rc = sys_event_queue_receive(GetCurrentPPUThread(), eventFlag->m.eventQueueId, data, 0); + auto rc = sys_event_queue_receive(GetCurrentPPUThread(), eventFlag->eventQueueId, data, 0); if (rc != CELL_OK) { assert(0); } int i = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { - i = eventFlag->m.ppuWaitSlotAndMode >> 4; + i = eventFlag->ppuWaitSlotAndMode >> 4; } - receivedEventFlag = eventFlag->m.pendingRecvTaskEvents[i]; - eventFlag->m.ppuPendingRecv = 0; + receivedEventFlag = eventFlag->pendingRecvTaskEvents[i]; + eventFlag->ppuPendingRecv = 0; } *mask = receivedEventFlag; @@ -1802,17 +1799,17 @@ s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) { cellSpurs.Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); - if (eventFlag.addr() == 0) + if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - eventFlag->m.events &= ~bits; + eventFlag->events &= ~bits; return CELL_OK; } @@ -1820,17 +1817,17 @@ s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) { cellSpurs.Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); - if (eventFlag.addr() == 0) + if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_PPU2SPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_PPU2SPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } @@ -1839,39 +1836,39 @@ s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) bool send = false; int ppuWaitSlot = 0; u16 eventsToClear = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY && eventFlag->m.ppuWaitMask) + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY && eventFlag->ppuWaitMask) { - u16 ppuRelevantEvents = (eventFlag->m.events | bits) & eventFlag->m.ppuWaitMask; + u16 ppuRelevantEvents = (eventFlag->events | bits) & eventFlag->ppuWaitMask; // Unblock the waiting PPU thread if either all the bits being waited by the thread have been set or // if the wait mode of the thread is OR and atleast one bit the thread is waiting on has been set - if ((eventFlag->m.ppuWaitMask & ~ppuRelevantEvents) == 0 || - ((eventFlag->m.ppuWaitSlotAndMode & 0x0F) == CELL_SPURS_EVENT_FLAG_OR && ppuRelevantEvents != 0)) + if ((eventFlag->ppuWaitMask & ~ppuRelevantEvents) == 0 || + ((eventFlag->ppuWaitSlotAndMode & 0x0F) == CELL_SPURS_EVENT_FLAG_OR && ppuRelevantEvents != 0)) { - eventFlag->m.ppuPendingRecv = 1; - eventFlag->m.ppuWaitMask = 0; + eventFlag->ppuPendingRecv = 1; + eventFlag->ppuWaitMask = 0; ppuEventFlag = ppuRelevantEvents; eventsToClear = ppuRelevantEvents; - ppuWaitSlot = eventFlag->m.ppuWaitSlotAndMode >> 4; + ppuWaitSlot = eventFlag->ppuWaitSlotAndMode >> 4; send = true; } } int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; int j = 0; - u16 relevantWaitSlots = eventFlag->m.spuTaskUsedWaitSlots & ~eventFlag->m.spuTaskPendingRecv; + u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~eventFlag->spuTaskPendingRecv; u16 spuTaskPendingRecv = 0; u16 pendingRecvTaskEvents[16]; while (relevantWaitSlots) { if (relevantWaitSlots & 0x0001) { - u16 spuTaskRelevantEvents = (eventFlag->m.events | bits) & eventFlag->m.spuTaskWaitMask[i]; + u16 spuTaskRelevantEvents = (eventFlag->events | bits) & eventFlag->spuTaskWaitMask[i]; // Unblock the waiting SPU task if either all the bits being waited by the task have been set or // if the wait mode of the task is OR and atleast one bit the thread is waiting on has been set - if ((eventFlag->m.spuTaskWaitMask[i] & ~spuTaskRelevantEvents) == 0 || - (((eventFlag->m.spuTaskWaitMode >> j) & 0x0001) == CELL_SPURS_EVENT_FLAG_OR && spuTaskRelevantEvents != 0)) + if ((eventFlag->spuTaskWaitMask[i] & ~spuTaskRelevantEvents) == 0 || + (((eventFlag->spuTaskWaitMode >> j) & 0x0001) == CELL_SPURS_EVENT_FLAG_OR && spuTaskRelevantEvents != 0)) { eventsToClear |= spuTaskRelevantEvents; spuTaskPendingRecv |= 1 << j; @@ -1884,20 +1881,20 @@ s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) j++; } - eventFlag->m.events |= bits; - eventFlag->m.spuTaskPendingRecv |= spuTaskPendingRecv; + eventFlag->events |= bits; + eventFlag->spuTaskPendingRecv |= spuTaskPendingRecv; // If the clear flag is AUTO then clear the bits comnsumed by all tasks marked to be unblocked - if (eventFlag->m.clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) + if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) { - eventFlag->m.events &= ~eventsToClear; + eventFlag->events &= ~eventsToClear; } if (send) { // Signal the PPU thread to be woken up - eventFlag->m.pendingRecvTaskEvents[ppuWaitSlot] = ppuEventFlag; - if (sys_event_port_send(eventFlag->m.eventPortId, 0, 0, 0) != CELL_OK) + eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEventFlag; + if (sys_event_port_send(eventFlag->eventPortId, 0, 0, 0) != CELL_OK) { assert(0); } @@ -1910,20 +1907,20 @@ s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) { if (spuTaskPendingRecv & (0x8000 >> i)) { - eventFlag->m.pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i]; + eventFlag->pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i]; vm::var taskset; - if (eventFlag->m.isIwl) + if (eventFlag->isIwl) { - cellSpursLookUpTasksetAddress(vm::ptr::make((u32)eventFlag->m.addr), + cellSpursLookUpTasksetAddress(vm::ptr::make((u32)eventFlag->addr), vm::ptr::make(taskset.addr()), - eventFlag->m.waitingTaskWklId[i]); + eventFlag->waitingTaskWklId[i]); } else { - taskset.value() = (u32)eventFlag->m.addr; + taskset.value() = (u32)eventFlag->addr; } - auto rc = _cellSpursSendSignal(vm::ptr::make(taskset.addr()), eventFlag->m.waitingTaskId[i]); + auto rc = _cellSpursSendSignal(vm::ptr::make(taskset.addr()), eventFlag->waitingTaskId[i]); if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT) { return CELL_SPURS_TASK_ERROR_FATAL; @@ -1951,17 +1948,17 @@ s32 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::pt { cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr()); - if (eventFlag.addr() == 0 || direction.addr() == 0) + if (!eventFlag || !direction) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - *direction = eventFlag->m.direction; + *direction = eventFlag->direction; return CELL_OK; } @@ -1969,17 +1966,17 @@ s32 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::pt { cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr()); - if (eventFlag.addr() == 0 || clear_mode.addr() == 0) + if (!eventFlag || !clear_mode) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - *clear_mode = eventFlag->m.clearMode; + *clear_mode = eventFlag->clearMode; return CELL_OK; } @@ -1987,17 +1984,17 @@ s32 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, v { cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr()); - if (eventFlag.addr() == 0 || taskset.addr() == 0) + if (!eventFlag || !taskset) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - taskset.set(eventFlag->m.isIwl ? 0 : eventFlag->m.addr); + taskset.set(eventFlag->isIwl ? 0 : eventFlag->addr); return CELL_OK; } @@ -2171,17 +2168,17 @@ s32 spursCreateTaskset(vm::ptr spurs, vm::ptr tasks return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align || taskset.addr() % CellSpursTaskset::align) + if (!spurs.aligned() || !taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } memset(taskset.get_ptr(), 0, size); - taskset->m.spurs = spurs; - taskset->m.args = args; - taskset->m.enable_clear_ls = enable_clear_ls > 0 ? 1 : 0; - taskset->m.size = size; + taskset->spurs = spurs; + taskset->args = args; + taskset->enable_clear_ls = enable_clear_ls > 0 ? 1 : 0; + taskset->size = size; vm::var wkl_attr; _cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::ptr::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/, @@ -2198,8 +2195,8 @@ s32 spursCreateTaskset(vm::ptr spurs, vm::ptr tasks cellSpursAddWorkloadWithAttribute(spurs, vm::ptr::make(wid.addr()), wkl_attr); // TODO: Check return code - taskset->m.wkl_flag_wait_task = 0x80; - taskset->m.wid = wid.value(); + taskset->wkl_flag_wait_task = 0x80; + taskset->wid = wid.value(); // TODO: cellSpursSetExceptionEventHandler(spurs, wid, hook, taskset); // TODO: Check return code @@ -2215,20 +2212,20 @@ s32 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptrm.revision != CELL_SPURS_TASKSET_ATTRIBUTE_REVISION) + if (attr->revision != CELL_SPURS_TASKSET_ATTRIBUTE_REVISION) { return CELL_SPURS_TASK_ERROR_INVAL; } - auto rc = spursCreateTaskset(spurs, taskset, attr->m.args, vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)), - attr->m.max_contention, vm::ptr::make(attr->m.name.addr()), attr->m.taskset_size, attr->m.enable_clear_ls); + auto rc = spursCreateTaskset(spurs, taskset, attr->args, vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, priority)), + attr->max_contention, vm::ptr::make(attr->name.addr()), attr->taskset_size, attr->enable_clear_ls); - if (attr->m.taskset_size >= CellSpursTaskset2::size) + if (attr->taskset_size >= sizeof32(CellSpursTaskset2)) { // TODO: Implement this } @@ -2261,17 +2258,17 @@ s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) { return CELL_SPURS_TASK_ERROR_INVAL; } - *wid = taskset->m.wid; + *wid = taskset->wid; return CELL_OK; } @@ -2304,7 +2301,7 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (elf_addr.addr() % 16) + if (elf_addr % 16) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -2312,14 +2309,14 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: auto sdk_version = _cellSpursGetSdkVersion(); if (sdk_version < 0x27FFFF) { - if (context_addr.addr() % 16) + if (context_addr % 16) { return CELL_SPURS_TASK_ERROR_ALIGN; } } else { - if (context_addr.addr() % 128) + if (context_addr % 128) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -2369,11 +2366,11 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: u32 tmp_task_id; for (tmp_task_id = 0; tmp_task_id < CELL_SPURS_MAX_TASK; tmp_task_id++) { - if (!taskset->m.enabled.value()._bit[tmp_task_id]) + if (!taskset->enabled.value()._bit[tmp_task_id]) { - auto enabled = taskset->m.enabled.value(); + auto enabled = taskset->enabled.value(); enabled._bit[tmp_task_id] = true; - taskset->m.enabled = enabled; + taskset->enabled = enabled; break; } } @@ -2383,12 +2380,12 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: return CELL_SPURS_TASK_ERROR_AGAIN; } - taskset->m.task_info[tmp_task_id].elf_addr.set(elf_addr.addr()); - taskset->m.task_info[tmp_task_id].context_save_storage_and_alloc_ls_blocks = (context_addr.addr() | alloc_ls_blocks); - taskset->m.task_info[tmp_task_id].args = *arg; + taskset->task_info[tmp_task_id].elf_addr.set(elf_addr.addr()); + taskset->task_info[tmp_task_id].context_save_storage_and_alloc_ls_blocks = (context_addr.addr() | alloc_ls_blocks); + taskset->task_info[tmp_task_id].args = *arg; if (ls_pattern.addr()) { - taskset->m.task_info[tmp_task_id].ls_pattern = *ls_pattern; + taskset->task_info[tmp_task_id].ls_pattern = *ls_pattern; } *task_id = tmp_task_id; @@ -2397,12 +2394,12 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: s32 spursTaskStart(vm::ptr taskset, u32 taskId) { - auto pendingReady = taskset->m.pending_ready.value(); + auto pendingReady = taskset->pending_ready.value(); pendingReady._bit[taskId] = true; - taskset->m.pending_ready = pendingReady; + taskset->pending_ready = pendingReady; - cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); + cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); + auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->spurs); if (rc != CELL_OK) { if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) @@ -2429,7 +2426,7 @@ s32 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -2458,34 +2455,34 @@ s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskId >= CELL_SPURS_MAX_TASK || taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD2) + if (taskId >= CELL_SPURS_MAX_TASK || taskset->wid >= CELL_SPURS_MAX_WORKLOAD2) { return CELL_SPURS_TASK_ERROR_INVAL; } auto _0 = be_t::make(u128::from32(0)); - auto disabled = taskset->m.enabled.value()._bit[taskId] ? false : true; - auto invalid = (taskset->m.ready & taskset->m.pending_ready) != _0 || (taskset->m.running & taskset->m.waiting) != _0 || disabled || - ((taskset->m.running | taskset->m.ready | taskset->m.pending_ready | taskset->m.waiting | taskset->m.signalled) & be_t::make(~taskset->m.enabled.value())) != _0; + auto disabled = taskset->enabled.value()._bit[taskId] ? false : true; + auto invalid = (taskset->ready & taskset->pending_ready) != _0 || (taskset->running & taskset->waiting) != _0 || disabled || + ((taskset->running | taskset->ready | taskset->pending_ready | taskset->waiting | taskset->signalled) & be_t::make(~taskset->enabled.value())) != _0; if (invalid) { return CELL_SPURS_TASK_ERROR_SRCH; } - auto shouldSignal = (taskset->m.waiting & be_t::make(~taskset->m.signalled.value()) & be_t::make(u128::fromBit(taskId))) != _0 ? true : false; - auto signalled = taskset->m.signalled.value(); + auto shouldSignal = (taskset->waiting & be_t::make(~taskset->signalled.value()) & be_t::make(u128::fromBit(taskId))) != _0 ? true : false; + auto signalled = taskset->signalled.value(); signalled._bit[taskId] = true; - taskset->m.signalled = signalled; + taskset->signalled = signalled; if (shouldSignal) { - cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); + cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); + auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->spurs); if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) { return CELL_SPURS_TASK_ERROR_STAT; @@ -2515,12 +2512,12 @@ s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (attr.addr() % CellSpursTasksetAttribute::align) + if (!attr.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - attr->m.name = name; + attr->name = name; return CELL_OK; } @@ -2533,17 +2530,17 @@ s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr a return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (attr.addr() % CellSpursTasksetAttribute::align) + if (!attr.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (size != 6400/*CellSpursTaskset::size*/ && size != CellSpursTaskset2::size) + if (size != sizeof32(CellSpursTaskset) && size != sizeof32(CellSpursTaskset2)) { return CELL_SPURS_TASK_ERROR_INVAL; } - attr->m.taskset_size = size; + attr->taskset_size = size; return CELL_OK; } @@ -2556,12 +2553,12 @@ s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr at return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (attr.addr() % CellSpursTasksetAttribute::align) + if (!attr.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - attr->m.enable_clear_ls = enable ? 1 : 0; + attr->enable_clear_ls = enable ? 1 : 0; return CELL_OK; } @@ -2569,19 +2566,19 @@ s32 _cellSpursTasksetAttribute2Initialize(vm::ptr at { cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); - memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute2::size); - attribute->m.revision = revision; - attribute->m.name = vm::null; - attribute->m.args = 0; + memset(attribute.get_ptr(), 0, sizeof(CellSpursTasksetAttribute2)); + attribute->revision = revision; + attribute->name = vm::null; + attribute->args = 0; for (s32 i = 0; i < 8; i++) { - attribute->m.priority[i] = 1; + attribute->priority[i] = 1; } - attribute->m.max_contention = 8; - attribute->m.enable_clear_ls = 0; - attribute->m.task_name_buffer.set(0); + attribute->max_contention = 8; + attribute->enable_clear_ls = 0; + attribute->task_name_buffer.set(0); return CELL_OK; } @@ -2646,7 +2643,7 @@ s32 _cellSpursTaskAttribute2Initialize(vm::ptr attribut attribute->lsPattern._u32[c] = 0; } - attribute->name_addr = 0; + attribute->name = vm::null; return CELL_OK; } @@ -2669,15 +2666,16 @@ s32 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr _cellSpursTasksetAttribute2Initialize(attr, 0); } - auto rc = spursCreateTaskset(spurs, vm::ptr::make(taskset.addr()), attr->m.args, - vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)), - attr->m.max_contention, attr->m.name, CellSpursTaskset2::size, (u8)attr->m.enable_clear_ls); + auto rc = spursCreateTaskset(spurs, vm::ptr::make(taskset.addr()), attr->args, + vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, priority)), + attr->max_contention, attr->name, sizeof32(CellSpursTaskset2), (u8)attr->enable_clear_ls); + if (rc != CELL_OK) { return rc; } - if (attr->m.task_name_buffer.addr() % CellSpursTaskNameBuffer::align) + if (!attr->task_name_buffer.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -2725,23 +2723,23 @@ s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) { return CELL_SPURS_TASK_ERROR_INVAL; } - if (taskset->m.exception_handler) + if (taskset->exception_handler) { return CELL_SPURS_TASK_ERROR_BUSY; } - taskset->m.exception_handler = handler; - taskset->m.exception_handler_arg = arg; + taskset->exception_handler = handler; + taskset->exception_handler_arg = arg; return CELL_OK; } @@ -2754,18 +2752,18 @@ s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) { return CELL_SPURS_TASK_ERROR_INVAL; } - taskset->m.exception_handler.set(0); - taskset->m.exception_handler_arg.set(0); + taskset->exception_handler.set(0); + taskset->exception_handler_arg.set(0); return CELL_OK; } @@ -2799,17 +2797,17 @@ s32 cellSpursTasksetGetSpursAddress(vm::ptr taskset, vm: return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (taskset.addr() % CellSpursTaskset::align) + if (!taskset.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) { return CELL_SPURS_TASK_ERROR_INVAL; } - *spurs = (u32)taskset->m.spurs.addr(); + *spurs = (u32)taskset->spurs.addr(); return CELL_OK; } @@ -2829,7 +2827,7 @@ s32 _cellSpursTasksetAttributeInitialize(vm::ptr attr return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (attribute.addr() % CellSpursTasksetAttribute::align) + if (!attribute.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -2842,13 +2840,13 @@ s32 _cellSpursTasksetAttributeInitialize(vm::ptr attr } } - memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute::size); - attribute->m.revision = revision; - attribute->m.sdk_version = sdk_version; - attribute->m.args = args; - memcpy(attribute->m.priority, priority.get_ptr(), 8); - attribute->m.taskset_size = 6400/*CellSpursTaskset::size*/; - attribute->m.max_contention = max_contention; + memset(attribute.get_ptr(), 0, sizeof(CellSpursTasksetAttribute)); + attribute->revision = revision; + attribute->sdk_version = sdk_version; + attribute->args = args; + memcpy(attribute->priority, priority.get_ptr(), 8); + attribute->taskset_size = 6400/*CellSpursTaskset::size*/; + attribute->max_contention = max_contention; return CELL_OK; } @@ -2969,12 +2967,12 @@ void spursTraceStatusUpdate(vm::ptr spurs) { LV2_LOCK; - if (spurs->m.xCC != 0) + if (spurs->xCC != 0) { - spurs->m.xCD = 1; - spurs->m.sysSrvMsgUpdateTrace = (1 << spurs->m.nSpus) - 1; - spurs->m.sysSrvMessage.write_relaxed(0xFF); - sys_semaphore_wait((u32)spurs->m.semPrv, 0); + spurs->xCD = 1; + spurs->sysSrvMsgUpdateTrace = (1 << spurs->nSpus) - 1; + spurs->sysSrvMessage.write_relaxed(0xFF); + sys_semaphore_wait((u32)spurs->semPrv, 0); } } @@ -2985,41 +2983,41 @@ s32 spursTraceInitialize(vm::ptr spurs, vm::ptr b return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align || buffer.addr() % CellSpursTraceInfo::align) + if (!spurs.aligned() || !buffer.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (size < CellSpursTraceInfo::size || mode & ~(CELL_SPURS_TRACE_MODE_FLAG_MASK)) + if (size < sizeof32(CellSpursTraceInfo) || mode & ~(CELL_SPURS_TRACE_MODE_FLAG_MASK)) { return CELL_SPURS_CORE_ERROR_INVAL; } - if (spurs->m.traceBuffer) + if (spurs->traceBuffer) { return CELL_SPURS_CORE_ERROR_STAT; } - spurs->m.traceDataSize = size - CellSpursTraceInfo::size; + spurs->traceDataSize = size - sizeof32(CellSpursTraceInfo); for (u32 i = 0; i < 8; i++) { - buffer->spu_thread[i] = spurs->m.spus[i]; + buffer->spu_thread[i] = spurs->spus[i]; buffer->count[i] = 0; } - buffer->spu_thread_grp = spurs->m.spuTG; - buffer->nspu = spurs->m.nSpus; - spurs->m.traceBuffer.set(buffer.addr() | (mode & CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER ? 1 : 0)); - spurs->m.traceMode = mode; + buffer->spu_thread_grp = spurs->spuTG; + buffer->nspu = spurs->nSpus; + spurs->traceBuffer.set(buffer.addr() | (mode & CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER ? 1 : 0)); + spurs->traceMode = mode; - u32 spuTraceDataCount = (u32)((spurs->m.traceDataSize / CellSpursTracePacket::size) / spurs->m.nSpus); + u32 spuTraceDataCount = (u32)((spurs->traceDataSize / sizeof32(CellSpursTracePacket)) / spurs->nSpus); for (u32 i = 0, j = 8; i < 6; i++) { - spurs->m.traceStartIndex[i] = j; + spurs->traceStartIndex[i] = j; j += spuTraceDataCount; } - spurs->m.sysSrvTraceControl = 0; + spurs->sysSrvTraceControl = 0; if (updateStatus) { spursTraceStatusUpdate(spurs); @@ -3045,17 +3043,17 @@ s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (!spurs->m.traceBuffer) + if (!spurs->traceBuffer) { return CELL_SPURS_CORE_ERROR_STAT; } - spurs->m.sysSrvTraceControl = 1; + spurs->sysSrvTraceControl = 1; if (updateStatus) { spursTraceStatusUpdate(spurs); @@ -3071,12 +3069,12 @@ s32 cellSpursTraceStart(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - return spursTraceStart(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); + return spursTraceStart(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) @@ -3086,17 +3084,17 @@ s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (!spurs->m.traceBuffer) + if (!spurs->traceBuffer) { return CELL_SPURS_CORE_ERROR_STAT; } - spurs->m.sysSrvTraceControl = 2; + spurs->sysSrvTraceControl = 2; if (updateStatus) { spursTraceStatusUpdate(spurs); @@ -3112,12 +3110,12 @@ s32 cellSpursTraceStop(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - return spursTraceStop(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); + return spursTraceStop(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } s32 cellSpursTraceFinalize(vm::ptr spurs) @@ -3127,19 +3125,19 @@ s32 cellSpursTraceFinalize(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % CellSpurs::align) + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (!spurs->m.traceBuffer) + if (!spurs->traceBuffer) { return CELL_SPURS_CORE_ERROR_STAT; } - spurs->m.sysSrvTraceControl = 0; - spurs->m.traceMode = 0; - spurs->m.traceBuffer.set(0); + spurs->sysSrvTraceControl = 0; + spurs->traceMode = 0; + spurs->traceBuffer.set(0); spursTraceStatusUpdate(spurs); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 986f45f1ed..0093d8a6e3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -2,6 +2,9 @@ namespace vm { using namespace ps3; } +struct CellSpurs; +struct CellSpursTaskset; + // Core return codes. enum { @@ -259,127 +262,158 @@ enum SpursEventFlagConstants CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT = 0xFF, }; -class SPURSManager; -class SPURSManagerEventFlag; -class SPURSManagerTaskset; -struct CellSpurs; - -struct CellSpursAttribute -{ - static const uint align = 8; - static const uint size = 512; - - union - { - // raw data - u8 _u8[size]; - struct { be_t _u32[size / sizeof(u32)]; }; - - // real data - struct - { - be_t revision; // 0x0 - be_t sdkVersion; // 0x4 - be_t nSpus; // 0x8 - be_t spuPriority; // 0xC - be_t ppuPriority; // 0x10 - bool exitIfNoWork; // 0x14 - char prefix[15]; // 0x15 (not a NTS) - be_t prefixSize; // 0x24 - 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; - }; -}; - -struct CellSpursWorkloadFlag +struct set_alignment(16) CellSpursWorkloadFlag { be_t unused0; be_t unused1; atomic_be_t flag; }; -typedef void(CellSpursShutdownCompletionEventHook)(vm::ptr, u32 wid, vm::ptr arg); +CHECK_SIZE_ALIGN(CellSpursWorkloadFlag, 16, 16); + +struct CellSpursInfo +{ + be_t nSpus; + be_t spuThreadGroupPriority; + be_t ppuThreadPriority; + bool exitIfNoWork; + bool spurs2; + u8 padding24[2]; + vm::bptr traceBuffer; + be_t padding32; + be_t traceBufferSize; + be_t traceMode; + be_t spuThreadGroup; + be_t spuThreads[8]; + be_t spursHandlerThread0; + be_t spursHandlerThread1; + char namePrefix[16]; + be_t namePrefixLength; + be_t deadlineMissCounter; + be_t deadlineMeetCounter; + u8 padding[164]; +}; + +CHECK_SIZE(CellSpursInfo, 280); + +struct set_alignment(8) CellSpursAttribute +{ + be_t revision; // 0x0 + be_t sdkVersion; // 0x4 + be_t nSpus; // 0x8 + be_t spuPriority; // 0xC + be_t ppuPriority; // 0x10 + bool exitIfNoWork; // 0x14 + char prefix[15]; // 0x15 (not a NTS) + be_t prefixSize; // 0x24 + 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 + u8 padding[440]; +}; + +CHECK_SIZE_ALIGN(CellSpursAttribute, 512, 8); + +using CellSpursShutdownCompletionEventHook = func_def spurs, u32 wid, vm::ptr arg)>; struct CellSpursTraceInfo { - static const u32 size = 0x80; - static const u32 align = 16; - be_t spu_thread[8]; // 0x00 be_t count[8]; // 0x20 be_t spu_thread_grp; // 0x40 be_t nspu; // 0x44 - //u8 padding[]; + u8 padding[56]; }; -struct CellSpursTracePacket -{ - static const u32 size = 16; +CHECK_SIZE(CellSpursTraceInfo, 128); - struct - { - u8 tag; - u8 length; - u8 spu; - u8 workload; - be_t time; - } header; +struct CellSpursTraceHeader +{ + u8 tag; + u8 length; + u8 spu; + u8 workload; + be_t time; +}; + +struct CellSpursTraceControlData +{ + be_t incident; + be_t reserved; +}; + +struct CellSpursTraceServiceData +{ + be_t incident; + be_t reserved; +}; + +struct CellSpursTraceTaskData +{ + be_t incident; + be_t taskId; +}; + +struct CellSpursTraceJobData +{ + u8 reserved[3]; + u8 binLSAhigh8; + be_t jobDescriptor; +}; + +struct CellSpursTraceLoadData +{ + be_t ea; + be_t ls; + be_t size; +}; + +struct CellSpursTraceMapData +{ + be_t offset; + be_t ls; + be_t size; +}; + +struct CellSpursTraceStartData +{ + char module[4]; + be_t level; + be_t ls; +}; + +struct set_alignment(16) CellSpursTracePacket +{ + CellSpursTraceHeader header; union { - struct - { - be_t incident; - be_t reserved; - } service; + CellSpursTraceControlData control; + CellSpursTraceServiceData service; + CellSpursTraceTaskData task; + CellSpursTraceJobData job; - struct - { - be_t ea; - be_t ls; - be_t size; - } load; - - struct - { - be_t offset; - be_t ls; - be_t size; - } map; - - struct - { - s8 module[4]; - be_t level; - be_t ls; - } start; - - struct - { - be_t incident; - be_t taskId; - } task; + CellSpursTraceLoadData load; + CellSpursTraceMapData map; + CellSpursTraceStartData start; + be_t stop; be_t user; be_t guid; - be_t stop; - } data; + be_t raw; + } + data; }; -// Core CellSpurs structures -struct CellSpurs -{ - static const uint align = 128; - static const uint size = 0x2000; // size of CellSpurs2 - static const uint size1 = 0x1000; // size of CellSpurs - static const uint size2 = 0x1000; +CHECK_SIZE_ALIGN(CellSpursTracePacket, 16, 16); +// Core CellSpurs structures +struct set_alignment(128) CellSpurs +{ struct _sub_str1 { u8 unk0[0x20]; // 0x00 - SPU exceptionh handler 0x08 - SPU exception handler args @@ -390,7 +424,7 @@ struct CellSpurs u8 unk2[0x40]; }; - static_assert(sizeof(_sub_str1) == 0x80, "Wrong _sub_str1 size"); + CHECK_SIZE(_sub_str1, 128); struct _sub_str2 // Event port multiplexer { @@ -402,11 +436,11 @@ struct CellSpurs 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} }; - static_assert(sizeof(_sub_str2) == 0x80, "Wrong _sub_str2 size"); + CHECK_SIZE(_sub_str2, 128); struct WorkloadInfo { - vm::bptr addr; // Address of the executable + vm::bcptr addr; // Address of the executable be_t arg; // spu argument be_t size; atomic_be_t uniqueId; // The unique id is the same for all workloads with the same addr @@ -414,201 +448,179 @@ struct CellSpurs u8 priority[8]; }; - static_assert(sizeof(WorkloadInfo) == 0x20, "Wrong WorkloadInfo size"); + CHECK_SIZE(WorkloadInfo, 32); struct _sub_str4 { - static const uint size = 0x10; - - vm::bptr nameClass; - vm::bptr nameInstance; + vm::bcptr nameClass; + vm::bcptr nameInstance; }; - union - { - // raw data - u8 _u8[size]; - std::array, size / sizeof(u32)> _u32; - - // real data - struct - { - atomic_be_t wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids). - atomic_be_t wklIdleSpuCountOrReadyCount2[0x10]; // 0x10 SPURS1: Number of idle SPUs requested by each workload (0..15 wids). SPURS2: Number of SPUs requested by each workload (16..31 wids). - u8 wklCurrentContention[0x10]; // 0x20 Number of SPUs used by each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. - u8 wklPendingContention[0x10]; // 0x30 Number of SPUs that are pending to context switch to the workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. - u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused. - atomic_be_t 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 - atomic_be_t wklSignal1; // 0x70 (bitset for 0..15 wids) - atomic_be_t sysSrvMessage; // 0x72 - u8 spuIdling; // 0x73 - u8 flags1; // 0x74 Type is SpursFlags1 - u8 sysSrvTraceControl; // 0x75 - u8 nSpus; // 0x76 - atomic_be_t wklFlagReceiver; // 0x77 - atomic_be_t wklSignal2; // 0x78 (bitset for 16..32 wids) - u8 x7A[6]; // 0x7A - atomic_be_t wklState1[0x10]; // 0x80 SPURS_WKL_STATE_* - u8 wklStatus1[0x10]; // 0x90 - u8 wklEvent1[0x10]; // 0xA0 - atomic_be_t wklMskA; // 0xB0 - System service - Available workloads (32*u1) - atomic_be_t wklMskB; // 0xB4 - System service - Available module id - u32 xB8; // 0xB8 - u8 sysSrvExitBarrier; // 0xBC - atomic_be_t sysSrvMsgUpdateWorkload; // 0xBD - u8 xBE; // 0xBE - u8 sysSrvMsgTerminate; // 0xBF - u8 sysSrvWorkload[8]; // 0xC0 - u8 sysSrvOnSpu; // 0xC8 - u8 spuPort; // 0xC9 - u8 xCA; // 0xCA - u8 xCB; // 0xCB - u8 xCC; // 0xCC - u8 xCD; // 0xCD - u8 sysSrvMsgUpdateTrace; // 0xCE - u8 xCF; // 0xCF - atomic_be_t wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_* - u8 wklStatus2[0x10]; // 0xE0 - u8 wklEvent2[0x10]; // 0xF0 - _sub_str1 wklF1[0x10]; // 0x100 - vm::bptr traceBuffer; // 0x900 - be_t traceStartIndex[6]; // 0x908 - u8 unknown7[0x948 - 0x920]; // 0x920 - be_t traceDataSize; // 0x948 - be_t traceMode; // 0x950 - u8 unknown8[0x980 - 0x954]; // 0x954 - be_t semPrv; // 0x980 - be_t unk11; // 0x988 - be_t unk12; // 0x98C - be_t unk13; // 0x990 - u8 unknown4[0xB00 - 0x998]; - WorkloadInfo wklInfo1[0x10]; // 0xB00 - WorkloadInfo wklInfoSysSrv; // 0xD00 - be_t ppu0; // 0xD20 - be_t ppu1; // 0xD28 - be_t spuTG; // 0xD30 - SPU thread group - be_t spus[8]; // 0xD34 - u8 unknown3[0xD5C - 0xD54]; - be_t queue; // 0xD5C - Event queue - be_t port; // 0xD60 - Event port - atomic_be_t xD64; // 0xD64 - SPURS handler dirty - atomic_be_t xD65; // 0xD65 - SPURS handler waiting - atomic_be_t xD66; // 0xD66 - SPURS handler exiting - atomic_be_t enableEH; // 0xD68 - be_t exception; // 0xD6C - sys_spu_image spuImg; // 0xD70 - be_t flags; // 0xD80 - be_t spuPriority; // 0xD84 - be_t ppuPriority; // 0xD88 - char prefix[0x0f]; // 0xD8C - u8 prefixSize; // 0xD9B - be_t unk5; // 0xD9C - be_t revision; // 0xDA0 - be_t sdkVersion; // 0xDA4 - atomic_be_t spups; // 0xDA8 - SPU port bits - sys_lwmutex_t mutex; // 0xDB0 - sys_lwcond_t cond; // 0xDC8 - u8 unknown9[0xE00 - 0xDD0]; - _sub_str4 wklH1[0x10]; // 0xE00 - _sub_str2 sub3; // 0xF00 - u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args - WorkloadInfo wklInfo2[0x10]; // 0x1000 - _sub_str1 wklF2[0x10]; // 0x1200 - _sub_str4 wklH2[0x10]; // 0x1A00 - } m; - }; + atomic_be_t wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids). + atomic_be_t wklIdleSpuCountOrReadyCount2[0x10]; // 0x10 SPURS1: Number of idle SPUs requested by each workload (0..15 wids). SPURS2: Number of SPUs requested by each workload (16..31 wids). + u8 wklCurrentContention[0x10]; // 0x20 Number of SPUs used by each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. + u8 wklPendingContention[0x10]; // 0x30 Number of SPUs that are pending to context switch to the workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. + u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused. + atomic_be_t 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 + atomic_be_t wklSignal1; // 0x70 (bitset for 0..15 wids) + atomic_be_t sysSrvMessage; // 0x72 + u8 spuIdling; // 0x73 + u8 flags1; // 0x74 Type is SpursFlags1 + u8 sysSrvTraceControl; // 0x75 + u8 nSpus; // 0x76 + atomic_be_t wklFlagReceiver; // 0x77 + atomic_be_t wklSignal2; // 0x78 (bitset for 16..32 wids) + u8 x7A[6]; // 0x7A + atomic_be_t wklState1[0x10]; // 0x80 SPURS_WKL_STATE_* + u8 wklStatus1[0x10]; // 0x90 + u8 wklEvent1[0x10]; // 0xA0 + atomic_be_t wklMskA; // 0xB0 - System service - Available workloads (32*u1) + atomic_be_t wklMskB; // 0xB4 - System service - Available module id + u32 xB8; // 0xB8 + u8 sysSrvExitBarrier; // 0xBC + atomic_be_t sysSrvMsgUpdateWorkload; // 0xBD + u8 xBE; // 0xBE + u8 sysSrvMsgTerminate; // 0xBF + u8 sysSrvWorkload[8]; // 0xC0 + u8 sysSrvOnSpu; // 0xC8 + u8 spuPort; // 0xC9 + u8 xCA; // 0xCA + u8 xCB; // 0xCB + u8 xCC; // 0xCC + u8 xCD; // 0xCD + u8 sysSrvMsgUpdateTrace; // 0xCE + u8 xCF; // 0xCF + atomic_be_t wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_* + u8 wklStatus2[0x10]; // 0xE0 + u8 wklEvent2[0x10]; // 0xF0 + _sub_str1 wklF1[0x10]; // 0x100 + vm::bptr traceBuffer; // 0x900 + be_t traceStartIndex[6]; // 0x908 + u8 unknown7[0x948 - 0x920]; // 0x920 + be_t traceDataSize; // 0x948 + be_t traceMode; // 0x950 + u8 unknown8[0x980 - 0x954]; // 0x954 + be_t semPrv; // 0x980 + be_t unk11; // 0x988 + be_t unk12; // 0x98C + be_t unk13; // 0x990 + u8 unknown4[0xB00 - 0x998]; + WorkloadInfo wklInfo1[0x10]; // 0xB00 + WorkloadInfo wklInfoSysSrv; // 0xD00 + be_t ppu0; // 0xD20 + be_t ppu1; // 0xD28 + be_t spuTG; // 0xD30 - SPU thread group + be_t spus[8]; // 0xD34 + u8 unknown3[0xD5C - 0xD54]; + be_t queue; // 0xD5C - Event queue + be_t port; // 0xD60 - Event port + atomic_be_t xD64; // 0xD64 - SPURS handler dirty + atomic_be_t xD65; // 0xD65 - SPURS handler waiting + atomic_be_t xD66; // 0xD66 - SPURS handler exiting + atomic_be_t enableEH; // 0xD68 + be_t exception; // 0xD6C + sys_spu_image spuImg; // 0xD70 + be_t flags; // 0xD80 + be_t spuPriority; // 0xD84 + be_t ppuPriority; // 0xD88 + char prefix[0x0f]; // 0xD8C + u8 prefixSize; // 0xD9B + be_t unk5; // 0xD9C + be_t revision; // 0xDA0 + be_t sdkVersion; // 0xDA4 + atomic_be_t spups; // 0xDA8 - SPU port bits + sys_lwmutex_t mutex; // 0xDB0 + sys_lwcond_t cond; // 0xDC8 + u8 unknown9[0xE00 - 0xDD0]; + _sub_str4 wklH1[0x10]; // 0xE00 + _sub_str2 sub3; // 0xF00 + u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args + WorkloadInfo wklInfo2[0x10]; // 0x1000 + _sub_str1 wklF2[0x10]; // 0x1200 + _sub_str4 wklH2[0x10]; // 0x1A00 + u8 unknown_[0x2000 - 0x1B00]; force_inline atomic_be_t& wklState(const u32 wid) { if (wid & 0x10) { - return m.wklState2[wid & 0xf]; + return wklState2[wid & 0xf]; } else { - return m.wklState1[wid & 0xf]; + return wklState1[wid & 0xf]; } } force_inline vm::ptr get_lwmutex() { - return vm::ptr::make(vm::get_addr(&m.mutex)); + return vm::ptr::make(vm::get_addr(&mutex)); } force_inline vm::ptr get_lwcond() { - return vm::ptr::make(vm::get_addr(&m.cond)); + return vm::ptr::make(vm::get_addr(&cond)); } }; -typedef CellSpurs CellSpurs2; +CHECK_SIZE_ALIGN(CellSpurs, 0x2000, 128); + +using CellSpurs2 = CellSpurs; + +struct CellSpursExceptionInfo +{ + be_t spu_thread; + be_t spu_npc; + be_t cause; + be_t option; +}; + +// Exception handler +using CellSpursGlobalExceptionEventHandler = func_def spurs, vm::cptr info, u32 id, vm::ptr arg)>; struct CellSpursWorkloadAttribute { - static const uint align = 8; - static const uint size = 512; - - union - { - // raw data - u8 _u8[size]; - - // real data - struct - { - be_t revision; - be_t sdkVersion; - vm::bptr pm; - be_t size; - be_t data; - u8 priority[8]; - be_t minContention; - be_t maxContention; - vm::bptr nameClass; - vm::bptr nameInstance; - vm::bptr hook; - vm::bptr hookArg; - } m; - }; + be_t revision; + be_t sdkVersion; + vm::bcptr pm; + be_t size; + be_t data; + u8 priority[8]; + be_t minContention; + be_t maxContention; + vm::bcptr nameClass; + vm::bcptr nameInstance; + vm::bptr hook; + vm::bptr hookArg; + u8 padding[456]; }; -struct CellSpursEventFlag +CHECK_SIZE_ALIGN(CellSpursWorkloadAttribute, 512, 8); + +struct set_alignment(128) CellSpursEventFlag { - static const u32 align = 128; - static const u32 size = 128; - - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t events; // 0x00 Event bits - be_t spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks - be_t ppuWaitMask; // 0x04 Wait mask for blocked PPU thread - u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread - u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked - be_t spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise - be_t spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise - u8 spuPort; // 0x0C - u8 isIwl; // 0x0D - u8 direction; // 0x0E - u8 clearMode; // 0x0F - be_t spuTaskWaitMask[16]; // 0x10 Wait mask for blocked SPU tasks - be_t pendingRecvTaskEvents[16]; // 0x30 The value of event flag when the wait condition for the thread/task was met - u8 waitingTaskId[16]; // 0x50 Task id of waiting SPU threads - u8 waitingTaskWklId[16]; // 0x60 Workload id of waiting SPU threads - be_t addr; // 0x70 - be_t eventPortId; // 0x78 - be_t eventQueueId; // 0x7C - } m; - }; + be_t events; // 0x00 Event bits + be_t spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks + be_t ppuWaitMask; // 0x04 Wait mask for blocked PPU thread + u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread + u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked + be_t spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise + be_t spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise + u8 spuPort; // 0x0C + u8 isIwl; // 0x0D + u8 direction; // 0x0E + u8 clearMode; // 0x0F + be_t spuTaskWaitMask[16]; // 0x10 Wait mask for blocked SPU tasks + be_t pendingRecvTaskEvents[16]; // 0x30 The value of event flag when the wait condition for the thread/task was met + u8 waitingTaskId[16]; // 0x50 Task id of waiting SPU threads + u8 waitingTaskWklId[16]; // 0x60 Workload id of waiting SPU threads + be_t addr; // 0x70 + be_t eventPortId; // 0x78 + be_t eventQueueId; // 0x7C }; -static_assert(sizeof(CellSpursEventFlag) == CellSpursEventFlag::size, "Wrong CellSpursEventFlag size"); +CHECK_SIZE_ALIGN(CellSpursEventFlag, 128, 128); union CellSpursTaskArgument { @@ -622,11 +634,85 @@ union CellSpursTaskLsPattern be_t _u64[2]; }; -struct CellSpursTaskset +struct set_alignment(16) CellSpursTaskAttribute { - static const u32 align = 128; - static const u32 size = 6400; + u8 reserved[256]; +}; +CHECK_SIZE_ALIGN(CellSpursTaskAttribute, 256, 16); + +struct set_alignment(16) CellSpursTaskAttribute2 +{ + be_t revision; + be_t sizeContext; + be_t eaContext; + CellSpursTaskLsPattern lsPattern; + vm::bcptr name; + + u8 reserved[220]; +}; + +CHECK_SIZE_ALIGN(CellSpursTaskAttribute2, 256, 16); + +// Exception handler +using CellSpursTasksetExceptionEventHandler = func_def spurs, vm::ptr taskset, u32 idTask, vm::cptr info, vm::ptr arg)>; + +struct set_alignment(128) CellSpursTaskExitCode +{ + u8 skip[128]; +}; + +CHECK_SIZE_ALIGN(CellSpursTaskExitCode, 128, 128); + +struct CellSpursTaskInfo +{ + CellSpursTaskLsPattern lsPattern; + CellSpursTaskArgument argument; + vm::bptr eaElf; + vm::bptr eaContext; + be_t sizeContext; + u8 state; + u8 hasSignal; + u8 padding[2]; + vm::bcptr eaTaskExitCode; + u8 guid[8]; + u8 reserved[12]; +}; + +CHECK_SIZE(CellSpursTaskInfo, 72); + +struct CellSpursTasksetInfo +{ + CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; + be_t argument; + be_t idWorkload; + be_t idLastScheduledTask; + vm::bcptr name; + vm::bptr exceptionEventHandler; + vm::bptr exceptionEventHandlerArgument; + be_t sizeTaskset; + u8 reserved[112]; +}; + +CHECK_SIZE(CellSpursTasksetInfo, 9360); + +struct set_alignment(8) CellSpursTasksetAttribute +{ + be_t revision; // 0x00 + be_t sdk_version; // 0x04 + be_t args; // 0x08 + u8 priority[8]; // 0x10 + be_t max_contention; // 0x18 + vm::bcptr name; // 0x1C + be_t taskset_size; // 0x20 + be_t enable_clear_ls; // 0x24 + u8 reserved[472]; +}; + +CHECK_SIZE_ALIGN(CellSpursTasksetAttribute, 512, 8); + +struct set_alignment(128) CellSpursTaskset +{ struct TaskInfo { CellSpursTaskArgument args; // 0x00 @@ -635,105 +721,36 @@ struct CellSpursTaskset CellSpursTaskLsPattern ls_pattern; // 0x20 }; - static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size"); + CHECK_SIZE(TaskInfo, 48); - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t running; // 0x00 - be_t ready; // 0x10 - be_t pending_ready; // 0x20 - be_t enabled; // 0x30 - be_t signalled; // 0x40 - be_t waiting; // 0x50 - vm::bptr spurs; // 0x60 - be_t args; // 0x68 - u8 enable_clear_ls; // 0x70 - u8 x71; // 0x71 - u8 wkl_flag_wait_task; // 0x72 - u8 last_scheduled_task; // 0x73 - be_t wid; // 0x74 - be_t x78; // 0x78 - TaskInfo task_info[128]; // 0x80 - vm::bptr exception_handler; // 0x1880 - vm::bptr exception_handler_arg; // 0x1888 - be_t size; // 0x1890 - u32 unk2; // 0x1894 - u32 event_flag_id1; // 0x1898 - u32 event_flag_id2; // 0x189C - u8 unk3[0x60]; // 0x18A0 - } m; - }; + be_t running; // 0x00 + be_t ready; // 0x10 + be_t pending_ready; // 0x20 + be_t enabled; // 0x30 + be_t signalled; // 0x40 + be_t waiting; // 0x50 + vm::bptr spurs; // 0x60 + be_t args; // 0x68 + u8 enable_clear_ls; // 0x70 + u8 x71; // 0x71 + u8 wkl_flag_wait_task; // 0x72 + u8 last_scheduled_task; // 0x73 + be_t wid; // 0x74 + be_t x78; // 0x78 + TaskInfo task_info[128]; // 0x80 + vm::bptr exception_handler; // 0x1880 + vm::bptr exception_handler_arg; // 0x1888 + be_t size; // 0x1890 + u32 unk2; // 0x1894 + u32 event_flag_id1; // 0x1898 + u32 event_flag_id2; // 0x189C + u8 unk3[0x60]; // 0x18A0 }; -static_assert(sizeof(CellSpursTaskset) == CellSpursTaskset::size, "Wrong CellSpursTaskset size"); +CHECK_SIZE_ALIGN(CellSpursTaskset, 128 * 50, 128); -struct CellSpursInfo +struct set_alignment(128) CellSpursTaskset2 { - be_t nSpus; - be_t spuThreadGroupPriority; - be_t ppuThreadPriority; - bool exitIfNoWork; - bool spurs2; - be_t traceBuffer_addr; //void *traceBuffer; - be_t traceBufferSize; - be_t traceMode; - be_t spuThreadGroup; //typedef u32 sys_spu_thread_group_t; - be_t spuThreads[8]; //typedef u32 sys_spu_thread_t; - be_t spursHandlerThread0; - be_t spursHandlerThread1; - s8 namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1]; - be_t namePrefixLength; - be_t deadlineMissCounter; - be_t deadlineMeetCounter; - //u8 padding[]; -}; - -struct CellSpursExceptionInfo -{ - be_t spu_thread; - be_t spu_npc; - be_t cause; - be_t option; -}; - -// Exception handlers. -//typedef void (*CellSpursGlobalExceptionEventHandler)(vm::ptr spurs, vm::ptr info, -// u32 id, vm::ptr arg); -// -//typedef void (*CellSpursTasksetExceptionEventHandler)(vm::ptr spurs, vm::ptr taskset, -// u32 idTask, vm::ptr info, vm::ptr arg); - -struct CellSpursTaskNameBuffer -{ - static const u32 align = 16; - - char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; -}; - -struct CellSpursTasksetInfo -{ - //CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; - be_t argument; - be_t idWorkload; - be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId - be_t name_addr; - be_t exceptionEventHandler_addr; - be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument - be_t sizeTaskset; - //be_t reserved[]; -}; - -struct CellSpursTaskset2 -{ - static const u32 align = 128; - static const u32 size = 10496; - struct TaskInfo { CellSpursTaskArgument args; @@ -742,135 +759,60 @@ struct CellSpursTaskset2 CellSpursTaskLsPattern ls_pattern; }; - static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size"); + CHECK_SIZE(TaskInfo, 48); - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t running_set[4]; // 0x00 - be_t ready_set[4]; // 0x10 - be_t ready2_set[4]; // 0x20 - TODO: Find out what this is - be_t enabled_set[4]; // 0x30 - be_t signal_received_set[4]; // 0x40 - be_t waiting_set[4]; // 0x50 - vm::bptr spurs; // 0x60 - be_t args; // 0x68 - u8 enable_clear_ls; // 0x70 - u8 x71; // 0x71 - u8 x72; // 0x72 - u8 last_scheduled_task; // 0x73 - be_t wid; // 0x74 - be_t x78; // 0x78 - TaskInfo task_info[128]; // 0x80 - vm::bptr exception_handler; // 0x1880 - vm::bptr exception_handler_arg; // 0x1888 - be_t size; // 0x1890 - u32 unk2; // 0x1894 - u32 event_flag_id1; // 0x1898 - u32 event_flag_id2; // 0x189C - u8 unk3[0x1980 - 0x18A0]; // 0x18A0 - be_t task_exit_code[128]; // 0x1980 - u8 unk4[0x2900 - 0x2180]; // 0x2180 - } m; - }; + be_t running_set[4]; // 0x00 + be_t ready_set[4]; // 0x10 + be_t ready2_set[4]; // 0x20 - TODO: Find out what this is + be_t enabled_set[4]; // 0x30 + be_t signal_received_set[4]; // 0x40 + be_t waiting_set[4]; // 0x50 + vm::bptr spurs; // 0x60 + be_t args; // 0x68 + u8 enable_clear_ls; // 0x70 + u8 x71; // 0x71 + u8 x72; // 0x72 + u8 last_scheduled_task; // 0x73 + be_t wid; // 0x74 + be_t x78; // 0x78 + TaskInfo task_info[128]; // 0x80 + vm::bptr exception_handler; // 0x1880 + vm::bptr exception_handler_arg; // 0x1888 + be_t size; // 0x1890 + u32 unk2; // 0x1894 + u32 event_flag_id1; // 0x1898 + u32 event_flag_id2; // 0x189C + u8 unk3[0x1980 - 0x18A0]; // 0x18A0 + be_t task_exit_code[128]; // 0x1980 + u8 unk4[0x2900 - 0x2180]; // 0x2180 }; -static_assert(sizeof(CellSpursTaskset2) == CellSpursTaskset2::size, "Wrong CellSpursTaskset2 size"); +CHECK_SIZE_ALIGN(CellSpursTaskset2, 128 * 82, 128); -struct CellSpursTasksetAttribute +struct set_alignment(16) CellSpursTaskNameBuffer { - static const u32 align = 8; - static const u32 size = 512; - - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t revision; // 0x00 - be_t sdk_version; // 0x04 - be_t args; // 0x08 - u8 priority[8]; // 0x10 - be_t max_contention; // 0x18 - vm::bptr name; // 0x1C - be_t taskset_size; // 0x20 - be_t enable_clear_ls; // 0x24 - } m; - }; + char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; }; -struct CellSpursTasksetAttribute2 +struct set_alignment(8) CellSpursTasksetAttribute2 { - static const u32 align = 8; - static const u32 size = 512; - - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t revision; // 0x00 - vm::bptr name; // 0x04 - be_t args; // 0x08 - u8 priority[8]; // 0x10 - be_t max_contention; // 0x18 - be_t enable_clear_ls; // 0x1C - vm::bptr task_name_buffer; // 0x20 - } m; - }; + be_t revision; // 0x00 + vm::bcptr name; // 0x04 + be_t args; // 0x08 + u8 priority[8]; // 0x10 + be_t max_contention; // 0x18 + be_t enable_clear_ls; // 0x1C + vm::bptr task_name_buffer; // 0x20 + u8 reserved[472]; }; -struct CellSpursTraceTaskData -{ - be_t incident; - be_t task; -}; +CHECK_SIZE_ALIGN(CellSpursTasksetAttribute2, 512, 8); -struct CellSpursTaskAttribute2 -{ - be_t revision; - be_t sizeContext; - be_t eaContext; - CellSpursTaskLsPattern lsPattern; - be_t name_addr; - //be_t __reserved__[]; -}; - -struct CellSpursTaskExitCode -{ - unsigned char skip[128]; -}; - -struct CellSpursTaskInfo -{ - CellSpursTaskLsPattern lsPattern; - CellSpursTaskArgument argument; - const be_t eaElf_addr; //void *eaElf - const be_t eaContext_addr; //void *eaContext - be_t sizeContext; - u8 state; - u8 hasSignal; - const be_t CellSpursTaskExitCode_addr; - u8 guid[8]; - //be_t reserved[]; -}; - -struct CellSpursTaskBinInfo +struct set_alignment(16) CellSpursTaskBinInfo { be_t eaElf; be_t sizeContext; - be_t __reserved__; + be_t reserved; CellSpursTaskLsPattern lsPattern; }; @@ -911,7 +853,7 @@ struct SpursKernelContext be_t guid[4]; // 0x280 }; -static_assert(sizeof(SpursKernelContext) == 0x190, "Incorrect size for SpursKernelContext"); +CHECK_SIZE(SpursKernelContext, 0x190); // The SPURS taskset policy module context. This resides at 0x2700 of the LS. struct SpursTasksetContext @@ -944,7 +886,7 @@ struct SpursTasksetContext u8 x2FD8[0x3000 - 0x2FD8]; // 0x2FD8 }; -static_assert(sizeof(SpursTasksetContext) == 0x900, "Incorrect size for SpursTasksetContext"); +CHECK_SIZE(SpursTasksetContext, 0x900); s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated); s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index cae4a7bb7e..71fd67bbb5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -83,7 +83,7 @@ u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status) { auto ctxt = vm::get_ptr(spu.offset + 0x100); spu.GPR[3]._u32[3] = 1; - if (ctxt->spurs->m.flags1 & SF1_32_WORKLOADS) { + if (ctxt->spurs->flags1 & SF1_32_WORKLOADS) { spursKernel2SelectWorkload(spu); } else { spursKernel1SelectWorkload(spu); @@ -168,12 +168,12 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { u8 contention[CELL_SPURS_MAX_WORKLOAD]; u8 pendingContention[CELL_SPURS_MAX_WORKLOAD]; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - contention[i] = spurs->m.wklCurrentContention[i] - ctxt->wklLocContention[i]; + contention[i] = spurs->wklCurrentContention[i] - ctxt->wklLocContention[i]; // If this is a poll request then the number of SPUs pending to context switch is also added to the contention presumably // to prevent unnecessary jumps to the kernel if (isPoll) { - pendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + pendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; if (i != ctxt->wklCurrentId) { contention[i] += pendingContention[i]; } @@ -185,21 +185,21 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { // The system service has the highest priority. Select the system service if // the system service message bit for this SPU is set. - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { ctxt->spuIdling = 0; if (!isPoll || ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { // Clear the message bit - spurs->m.sysSrvMessage.write_relaxed(spurs->m.sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); + spurs->sysSrvMessage.write_relaxed(spurs->sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); } } else { // Caclulate the scheduling weight for each workload u16 maxWeight = 0; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { u16 runnable = ctxt->wklRunnable1 & (0x8000 >> i); - u16 wklSignal = spurs->m.wklSignal1.read_relaxed() & (0x8000 >> i); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = spurs->m.wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklReadyCount1[i].read_relaxed(); - u8 idleSpuCount = spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed(); + u16 wklSignal = spurs->wklSignal1.read_relaxed() & (0x8000 >> i); + u8 wklFlag = spurs->wklFlag.flag.read_relaxed() == 0 ? spurs->wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; + u8 readyCount = spurs->wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklReadyCount1[i].read_relaxed(); + u8 idleSpuCount = spurs->wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklIdleSpuCountOrReadyCount2[i].read_relaxed(); u8 requestCount = readyCount + idleSpuCount; // For a workload to be considered for scheduling: @@ -209,7 +209,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { // 4. The number of SPUs allocated to it must be less than the number of SPUs requested (i.e. readyCount) // OR the workload must be signalled // OR the workload flag is 0 and the workload is configured as the wokload flag receiver - if (runnable && ctxt->priority[i] != 0 && spurs->m.wklMaxContention[i].read_relaxed() > contention[i]) { + if (runnable && ctxt->priority[i] != 0 && spurs->wklMaxContention[i].read_relaxed() > contention[i]) { if (wklFlag || wklSignal || (readyCount != 0 && requestCount > contention[i])) { // The scheduling weight of the workload is formed from the following parameters in decreasing order of priority: // 1. Wokload signal set or workload flag or ready count > contention @@ -222,7 +222,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { u16 weight = (wklFlag || wklSignal || (readyCount > contention[i])) ? 0x8000 : 0; weight |= (u16)(ctxt->priority[i] & 0x7F) << 16; weight |= i == ctxt->wklCurrentId ? 0x80 : 0x00; - weight |= (contention[i] > 0 && spurs->m.wklMinContention[i] > contention[i]) ? 0x40 : 0x00; + weight |= (contention[i] > 0 && spurs->wklMinContention[i] > contention[i]) ? 0x40 : 0x00; weight |= ((CELL_SPURS_MAX_SPU - contention[i]) & 0x0F) << 2; weight |= ctxt->wklUniqueId[i] == ctxt->wklCurrentId ? 0x02 : 0x00; weight |= 0x01; @@ -244,12 +244,12 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { if (!isPoll || wklSelectedId == ctxt->wklCurrentId) { // Clear workload signal for the selected workload - spurs->m.wklSignal1.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); - spurs->m.wklSignal2.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); + spurs->wklSignal1.write_relaxed(be_t::make(spurs->wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); + spurs->wklSignal2.write_relaxed(be_t::make(spurs->wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); // If the selected workload is the wklFlag workload then pull the wklFlag to all 1s - if (wklSelectedId == spurs->m.wklFlagReceiver.read_relaxed()) { - spurs->m.wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); + if (wklSelectedId == spurs->wklFlagReceiver.read_relaxed()) { + spurs->wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); } } } @@ -262,8 +262,8 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklCurrentContention[i] = contention[i]; - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklCurrentContention[i] = contention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocContention[i] = 0; ctxt->wklLocPendingContention[i] = 0; } @@ -281,7 +281,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = pendingContention[i]; + spurs->wklPendingContention[i] = pendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } @@ -291,7 +291,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } else { // Not called by kernel and no context switch is required for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } } @@ -325,13 +325,13 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { u8 contention[CELL_SPURS_MAX_WORKLOAD2]; u8 pendingContention[CELL_SPURS_MAX_WORKLOAD2]; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD2; i++) { - contention[i] = spurs->m.wklCurrentContention[i & 0x0F] - ctxt->wklLocContention[i & 0x0F]; + contention[i] = spurs->wklCurrentContention[i & 0x0F] - ctxt->wklLocContention[i & 0x0F]; contention[i] = i < CELL_SPURS_MAX_WORKLOAD ? contention[i] & 0x0F : contention[i] >> 4; // If this is a poll request then the number of SPUs pending to context switch is also added to the contention presumably // to prevent unnecessary jumps to the kernel if (isPoll) { - pendingContention[i] = spurs->m.wklPendingContention[i & 0x0F] - ctxt->wklLocPendingContention[i & 0x0F]; + pendingContention[i] = spurs->wklPendingContention[i & 0x0F] - ctxt->wklLocPendingContention[i & 0x0F]; pendingContention[i] = i < CELL_SPURS_MAX_WORKLOAD ? pendingContention[i] & 0x0F : pendingContention[i] >> 4; if (i != ctxt->wklCurrentId) { contention[i] += pendingContention[i]; @@ -344,12 +344,12 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { // The system service has the highest priority. Select the system service if // the system service message bit for this SPU is set. - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { // Not sure what this does. Possibly Mark the SPU as in use. ctxt->spuIdling = 0; if (!isPoll || ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { // Clear the message bit - spurs->m.sysSrvMessage.write_relaxed(spurs->m.sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); + spurs->sysSrvMessage.write_relaxed(spurs->sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); } } else { // Caclulate the scheduling weight for each workload @@ -358,10 +358,10 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { auto j = i & 0x0F; u16 runnable = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->wklRunnable1 & (0x8000 >> j) : ctxt->wklRunnable2 & (0x8000 >> j); u8 priority = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->priority[j] & 0x0F : ctxt->priority[j] >> 4; - u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklMaxContention[j].read_relaxed() & 0x0F : spurs->m.wklMaxContention[j].read_relaxed() >> 4; - u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->m.wklSignal2.read_relaxed() & (0x8000 >> j); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[j].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[j].read_relaxed(); + u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklMaxContention[j].read_relaxed() & 0x0F : spurs->wklMaxContention[j].read_relaxed() >> 4; + u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->wklSignal2.read_relaxed() & (0x8000 >> j); + u8 wklFlag = spurs->wklFlag.flag.read_relaxed() == 0 ? spurs->wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; + u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[j].read_relaxed() : spurs->wklIdleSpuCountOrReadyCount2[j].read_relaxed(); // For a workload to be considered for scheduling: // 1. Its priority must be greater than 0 @@ -396,12 +396,12 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { if (!isPoll || wklSelectedId == ctxt->wklCurrentId) { // Clear workload signal for the selected workload - spurs->m.wklSignal1.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); - spurs->m.wklSignal2.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); + spurs->wklSignal1.write_relaxed(be_t::make(spurs->wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); + spurs->wklSignal2.write_relaxed(be_t::make(spurs->wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); // If the selected workload is the wklFlag workload then pull the wklFlag to all 1s - if (wklSelectedId == spurs->m.wklFlagReceiver.read_relaxed()) { - spurs->m.wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); + if (wklSelectedId == spurs->wklFlagReceiver.read_relaxed()) { + spurs->wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); } } } @@ -414,8 +414,8 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < (CELL_SPURS_MAX_WORKLOAD2 >> 1); i++) { - spurs->m.wklCurrentContention[i] = contention[i] | (contention[i + 0x10] << 4); - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklCurrentContention[i] = contention[i] | (contention[i + 0x10] << 4); + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocContention[i] = 0; ctxt->wklLocPendingContention[i] = 0; } @@ -430,7 +430,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < (CELL_SPURS_MAX_WORKLOAD2 >> 1); i++) { - spurs->m.wklPendingContention[i] = pendingContention[i] | (pendingContention[i + 0x10] << 4); + spurs->wklPendingContention[i] = pendingContention[i] | (pendingContention[i + 0x10] << 4); ctxt->wklLocPendingContention[i] = 0; } @@ -438,7 +438,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } else { // Not called by kernel and no context switch is required for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } } @@ -455,15 +455,15 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { /// SPURS kernel dispatch workload void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; auto pollStatus = (u32)widAndPollStatus; auto wid = (u32)(widAndPollStatus >> 32); // DMA in the workload info for the selected workload - auto wklInfoOffset = wid < CELL_SPURS_MAX_WORKLOAD ? &ctxt->spurs->m.wklInfo1[wid] : - wid < CELL_SPURS_MAX_WORKLOAD2 && isKernel2 ? &ctxt->spurs->m.wklInfo2[wid & 0xf] : - &ctxt->spurs->m.wklInfoSysSrv; + auto wklInfoOffset = wid < CELL_SPURS_MAX_WORKLOAD ? &ctxt->spurs->wklInfo1[wid] : + wid < CELL_SPURS_MAX_WORKLOAD2 && isKernel2 ? &ctxt->spurs->wklInfo2[wid & 0xf] : + &ctxt->spurs->wklInfoSysSrv; memcpy(vm::get_ptr(spu.offset + 0x3FFE0), wklInfoOffset, 0x20); @@ -503,7 +503,7 @@ void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus) { /// SPURS kernel workload exit bool spursKernelWorkloadExit(SPUThread & spu) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; // Select next workload to run spu.GPR[3].clear(); @@ -533,7 +533,7 @@ bool spursKernelEntry(SPUThread & spu) { ctxt->spuNum = spu.GPR[3]._u32[3]; ctxt->spurs.set(spu.GPR[4]._u64[1]); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; // Initialise the SPURS context to its initial values ctxt->dmaTagId = CELL_SPURS_KERNEL_DMA_TAG_ID; @@ -598,30 +598,30 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { // Find the number of SPUs that are idling in this SPURS instance u32 nIdlingSpus = 0; for (u32 i = 0; i < 8; i++) { - if (spurs->m.spuIdling & (1 << i)) { + if (spurs->spuIdling & (1 << i)) { nIdlingSpus++; } } - bool allSpusIdle = nIdlingSpus == spurs->m.nSpus ? true: false; - bool exitIfNoWork = spurs->m.flags1 & SF1_EXIT_IF_NO_WORK ? true : false; + bool allSpusIdle = nIdlingSpus == spurs->nSpus ? true: false; + bool exitIfNoWork = spurs->flags1 & SF1_EXIT_IF_NO_WORK ? true : false; shouldExit = allSpusIdle && exitIfNoWork; // Check if any workloads can be scheduled bool foundReadyWorkload = false; - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { foundReadyWorkload = true; } else { - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD2; i++) { u32 j = i & 0x0F; u16 runnable = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->wklRunnable1 & (0x8000 >> j) : ctxt->wklRunnable2 & (0x8000 >> j); u8 priority = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->priority[j] & 0x0F : ctxt->priority[j] >> 4; - u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklMaxContention[j].read_relaxed() & 0x0F : spurs->m.wklMaxContention[j].read_relaxed() >> 4; - u8 contention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklCurrentContention[j] & 0x0F : spurs->m.wklCurrentContention[j] >> 4; - u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->m.wklSignal2.read_relaxed() & (0x8000 >> j); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[j].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[j].read_relaxed(); + u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklMaxContention[j].read_relaxed() & 0x0F : spurs->wklMaxContention[j].read_relaxed() >> 4; + u8 contention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklCurrentContention[j] & 0x0F : spurs->wklCurrentContention[j] >> 4; + u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->wklSignal2.read_relaxed() & (0x8000 >> j); + u8 wklFlag = spurs->wklFlag.flag.read_relaxed() == 0 ? spurs->wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; + u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[j].read_relaxed() : spurs->wklIdleSpuCountOrReadyCount2[j].read_relaxed(); if (runnable && priority > 0 && maxContention > contention) { if (wklFlag || wklSignal || readyCount > contention) { @@ -633,14 +633,14 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { } else { for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { u16 runnable = ctxt->wklRunnable1 & (0x8000 >> i); - u16 wklSignal = spurs->m.wklSignal1.read_relaxed() & (0x8000 >> i); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = spurs->m.wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklReadyCount1[i].read_relaxed(); - u8 idleSpuCount = spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed(); + u16 wklSignal = spurs->wklSignal1.read_relaxed() & (0x8000 >> i); + u8 wklFlag = spurs->wklFlag.flag.read_relaxed() == 0 ? spurs->wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; + u8 readyCount = spurs->wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklReadyCount1[i].read_relaxed(); + u8 idleSpuCount = spurs->wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklIdleSpuCountOrReadyCount2[i].read_relaxed(); u8 requestCount = readyCount + idleSpuCount; - if (runnable && ctxt->priority[i] != 0 && spurs->m.wklMaxContention[i].read_relaxed() > spurs->m.wklCurrentContention[i]) { - if (wklFlag || wklSignal || (readyCount != 0 && requestCount > spurs->m.wklCurrentContention[i])) { + if (runnable && ctxt->priority[i] != 0 && spurs->wklMaxContention[i].read_relaxed() > spurs->wklCurrentContention[i]) { + if (wklFlag || wklSignal || (readyCount != 0 && requestCount > spurs->wklCurrentContention[i])) { foundReadyWorkload = true; break; } @@ -649,11 +649,11 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { } } - bool spuIdling = spurs->m.spuIdling & (1 << ctxt->spuNum) ? true : false; + bool spuIdling = spurs->spuIdling & (1 << ctxt->spuNum) ? true : false; if (foundReadyWorkload && shouldExit == false) { - spurs->m.spuIdling &= ~(1 << ctxt->spuNum); + spurs->spuIdling &= ~(1 << ctxt->spuNum); } else { - spurs->m.spuIdling |= 1 << ctxt->spuNum; + spurs->spuIdling |= 1 << ctxt->spuNum; } // If all SPUs are idling and the exit_if_no_work flag is set then the SPU thread group must exit. Otherwise wait for external events. @@ -677,7 +677,7 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - if (ctxt->spurs.addr() % CellSpurs::align) { + if (!ctxt->spurs.aligned()) { assert(!"spursSysServiceMain(): invalid spurs alignment"); //spursHalt(spu); //return; @@ -689,19 +689,19 @@ void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { vm::reservation_acquire(vm::get_ptr(spu.offset + 0x100), vm::cast(ctxt->spurs.addr()), 128); - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); // Halt if already initialised - if (spurs->m.sysSrvOnSpu & (1 << ctxt->spuNum)) { + if (spurs->sysSrvOnSpu & (1 << ctxt->spuNum)) { assert(!"spursSysServiceMain(): already initialized"); //spursHalt(spu); //return; } - spurs->m.sysSrvOnSpu |= 1 << ctxt->spuNum; + spurs->sysSrvOnSpu |= 1 << ctxt->spuNum; - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); ctxt->traceBuffer = 0; @@ -779,27 +779,27 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt) bool updateWorkload = false; bool terminate = false; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); // Terminate request - if (spurs->m.sysSrvMsgTerminate & (1 << ctxt->spuNum)) { - spurs->m.sysSrvOnSpu &= ~(1 << ctxt->spuNum); + if (spurs->sysSrvMsgTerminate & (1 << ctxt->spuNum)) { + spurs->sysSrvOnSpu &= ~(1 << ctxt->spuNum); terminate = true; } // Update workload message - if (spurs->m.sysSrvMsgUpdateWorkload.read_relaxed() & (1 << ctxt->spuNum)) { - spurs->m.sysSrvMsgUpdateWorkload &= ~(1 << ctxt->spuNum); + if (spurs->sysSrvMsgUpdateWorkload.read_relaxed() & (1 << ctxt->spuNum)) { + spurs->sysSrvMsgUpdateWorkload &= ~(1 << ctxt->spuNum); updateWorkload = true; } // Update trace message - if (spurs->m.sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) { updateTrace = true; } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); // Process update workload message @@ -821,9 +821,9 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt) /// Activate a workload void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) { auto spurs = vm::get_ptr(spu.offset + 0x100); - memcpy(vm::get_ptr(spu.offset + 0x30000), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklInfo1))), 0x200); - if (spurs->m.flags1 & SF1_32_WORKLOADS) { - memcpy(vm::get_ptr(spu.offset + 0x30200), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklInfo2))), 0x200); + memcpy(vm::get_ptr(spu.offset + 0x30000), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklInfo1))), 0x200); + if (spurs->flags1 & SF1_32_WORKLOADS) { + memcpy(vm::get_ptr(spu.offset + 0x30200), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklInfo2))), 0x200); } u32 wklShutdownBitSet = 0; @@ -836,7 +836,7 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) ctxt->priority[i] = wklInfo1[i].priority[ctxt->spuNum] == 0 ? 0 : 0x10 - wklInfo1[i].priority[ctxt->spuNum]; ctxt->wklUniqueId[i] = wklInfo1[i].uniqueId.read_relaxed(); - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { auto wklInfo2 = vm::get_ptr(spu.offset + 0x30200); // Copy the priority of the workload for this SPU to the LS @@ -846,50 +846,50 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) } } - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { // Update workload status and runnable flag based on the workload state - auto wklStatus = spurs->m.wklStatus1[i]; - if (spurs->m.wklState1[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { - spurs->m.wklStatus1[i] |= 1 << ctxt->spuNum; + auto wklStatus = spurs->wklStatus1[i]; + if (spurs->wklState1[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { + spurs->wklStatus1[i] |= 1 << ctxt->spuNum; ctxt->wklRunnable1 |= 0x8000 >> i; } else { - spurs->m.wklStatus1[i] &= ~(1 << ctxt->spuNum); + spurs->wklStatus1[i] &= ~(1 << ctxt->spuNum); } // If the workload is shutting down and if this is the last SPU from which it is being removed then // add it to the shutdown bit set - if (spurs->m.wklState1[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { - if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->m.wklStatus1[i] == 0)) { - spurs->m.wklState1[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); + if (spurs->wklState1[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { + if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->wklStatus1[i] == 0)) { + spurs->wklState1[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); wklShutdownBitSet |= 0x80000000u >> i; } } - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { // Update workload status and runnable flag based on the workload state - wklStatus = spurs->m.wklStatus2[i]; - if (spurs->m.wklState2[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { - spurs->m.wklStatus2[i] |= 1 << ctxt->spuNum; + wklStatus = spurs->wklStatus2[i]; + if (spurs->wklState2[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { + spurs->wklStatus2[i] |= 1 << ctxt->spuNum; ctxt->wklRunnable2 |= 0x8000 >> i; } else { - spurs->m.wklStatus2[i] &= ~(1 << ctxt->spuNum); + spurs->wklStatus2[i] &= ~(1 << ctxt->spuNum); } // If the workload is shutting down and if this is the last SPU from which it is being removed then // add it to the shutdown bit set - if (spurs->m.wklState2[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { - if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->m.wklStatus2[i] == 0)) { - spurs->m.wklState2[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); + if (spurs->wklState2[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { + if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->wklStatus2[i] == 0)) { + spurs->wklState2[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); wklShutdownBitSet |= 0x8000 >> i; } } } } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (wklShutdownBitSet) { @@ -903,28 +903,28 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC // workloads that have a shutdown completion hook registered u32 wklNotifyBitSet; u8 spuPort; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); wklNotifyBitSet = 0; - spuPort = spurs->m.spuPort;; + spuPort = spurs->spuPort;; for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { if (wklShutdownBitSet & (0x80000000u >> i)) { - spurs->m.wklEvent1[i] |= 0x01; - if (spurs->m.wklEvent1[i] & 0x02 || spurs->m.wklEvent1[i] & 0x10) { + spurs->wklEvent1[i] |= 0x01; + if (spurs->wklEvent1[i] & 0x02 || spurs->wklEvent1[i] & 0x10) { wklNotifyBitSet |= 0x80000000u >> i; } } if (wklShutdownBitSet & (0x8000 >> i)) { - spurs->m.wklEvent2[i] |= 0x01; - if (spurs->m.wklEvent2[i] & 0x02 || spurs->m.wklEvent2[i] & 0x10) { + spurs->wklEvent2[i] |= 0x01; + if (spurs->wklEvent2[i] & 0x02 || spurs->wklEvent2[i] & 0x10) { wklNotifyBitSet |= 0x8000 >> i; } } } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (wklNotifyBitSet) { @@ -935,7 +935,7 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC /// Update the trace count for this SPU void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt) { if (ctxt->traceBuffer) { - auto traceInfo = vm::ptr::make((u32)(ctxt->traceBuffer - (ctxt->spurs->m.traceStartIndex[ctxt->spuNum] << 4))); + auto traceInfo = vm::ptr::make((u32)(ctxt->traceBuffer - (ctxt->spurs->traceStartIndex[ctxt->spuNum] << 4))); traceInfo->count[ctxt->spuNum] = ctxt->traceMsgCount; } } @@ -945,51 +945,51 @@ void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 bool notify; u8 sysSrvMsgUpdateTrace; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); - sysSrvMsgUpdateTrace = spurs->m.sysSrvMsgUpdateTrace; - spurs->m.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum); - spurs->m.xCC &= ~(1 << ctxt->spuNum); - spurs->m.xCC |= arg2 << ctxt->spuNum; + sysSrvMsgUpdateTrace = spurs->sysSrvMsgUpdateTrace; + spurs->sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum); + spurs->xCC &= ~(1 << ctxt->spuNum); + spurs->xCC |= arg2 << ctxt->spuNum; notify = false; - if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->m.sysSrvMsgUpdateTrace == 0) && (spurs->m.xCD != 0)) { - spurs->m.xCD = 0; + if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->sysSrvMsgUpdateTrace == 0) && (spurs->xCD != 0)) { + spurs->xCD = 0; notify = true; } - if (arg4 && spurs->m.xCD != 0) { - spurs->m.xCD = 0; + if (arg4 && spurs->xCD != 0) { + spurs->xCD = 0; notify = true; } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); // Get trace parameters from CellSpurs and store them in the LS if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) || (arg3 != 0)) { - vm::reservation_acquire(vm::get_ptr(spu.offset + 0x80), vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.traceBuffer)), 128); - auto spurs = vm::get_ptr(spu.offset + 0x80 - offsetof(CellSpurs, m.traceBuffer)); + vm::reservation_acquire(vm::get_ptr(spu.offset + 0x80), vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, traceBuffer)), 128); + auto spurs = vm::get_ptr(spu.offset + 0x80 - offsetof(CellSpurs, traceBuffer)); - if (ctxt->traceMsgCount != 0xFF || spurs->m.traceBuffer.addr() == 0) { + if (ctxt->traceMsgCount != 0xFF || spurs->traceBuffer.addr() == 0) { spursSysServiceTraceSaveCount(spu, ctxt); } else { - memcpy(vm::get_ptr(spu.offset + 0x2C00), vm::get_ptr(spurs->m.traceBuffer.addr() & -0x4), 0x80); + memcpy(vm::get_ptr(spu.offset + 0x2C00), vm::get_ptr(spurs->traceBuffer.addr() & -0x4), 0x80); auto traceBuffer = vm::get_ptr(spu.offset + 0x2C00); ctxt->traceMsgCount = traceBuffer->count[ctxt->spuNum]; } - ctxt->traceBuffer = spurs->m.traceBuffer.addr() + (spurs->m.traceStartIndex[ctxt->spuNum] << 4); - ctxt->traceMaxCount = spurs->m.traceStartIndex[1] - spurs->m.traceStartIndex[0]; + ctxt->traceBuffer = spurs->traceBuffer.addr() + (spurs->traceStartIndex[ctxt->spuNum] << 4); + ctxt->traceMaxCount = spurs->traceStartIndex[1] - spurs->traceStartIndex[0]; if (ctxt->traceBuffer == 0) { ctxt->traceMsgCount = 0; } } if (notify) { - auto spurs = vm::get_ptr(spu.offset + 0x2D80 - offsetof(CellSpurs, m.wklState1)); - sys_spu_thread_send_event(spu, spurs->m.spuPort, 2, 0); + auto spurs = vm::get_ptr(spu.offset + 0x2D80 - offsetof(CellSpurs, wklState1)); + sys_spu_thread_send_event(spu, spurs->spuPort, 2, 0); } } @@ -999,18 +999,18 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte bool do_return = false; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); - if (spurs->m.sysSrvWorkload[ctxt->spuNum] == 0xFF) { + if (spurs->sysSrvWorkload[ctxt->spuNum] == 0xFF) { do_return = true; return; } - wklId = spurs->m.sysSrvWorkload[ctxt->spuNum]; - spurs->m.sysSrvWorkload[ctxt->spuNum] = 0xFF; + wklId = spurs->sysSrvWorkload[ctxt->spuNum]; + spurs->sysSrvWorkload[ctxt->spuNum] = 0xFF; - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (do_return) return; @@ -1021,11 +1021,11 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte auto spurs = ctxt->spurs.priv_ptr(); if (wklId >= CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x10; - spurs->m.wklReadyCount1[wklId & 0x0F].write_relaxed(spurs->m.wklReadyCount1[wklId & 0x0F].read_relaxed() - 1); + spurs->wklCurrentContention[wklId & 0x0F] -= 0x10; + spurs->wklReadyCount1[wklId & 0x0F].write_relaxed(spurs->wklReadyCount1[wklId & 0x0F].read_relaxed() - 1); } else { - spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x01; - spurs->m.wklIdleSpuCountOrReadyCount2[wklId & 0x0F].write_relaxed(spurs->m.wklIdleSpuCountOrReadyCount2[wklId & 0x0F].read_relaxed() - 1); + spurs->wklCurrentContention[wklId & 0x0F] -= 0x01; + spurs->wklIdleSpuCountOrReadyCount2[wklId & 0x0F].write_relaxed(spurs->wklIdleSpuCountOrReadyCount2[wklId & 0x0F].read_relaxed() - 1); } memcpy(vm::get_ptr(spu.offset + 0x100), spurs, 128); @@ -1135,8 +1135,8 @@ void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs) { spu.GPR[2].clear(); spu.GPR[3] = u128::from64r(taskArgs._u64[0], taskArgs._u64[1]); - spu.GPR[4]._u64[1] = taskset->m.args; - spu.GPR[4]._u64[0] = taskset->m.spurs.addr(); + spu.GPR[4]._u64[1] = taskset->args; + spu.GPR[4]._u64[0] = taskset->spurs.addr(); for (auto i = 5; i < 128; i++) { spu.GPR[i].clear(); } @@ -1156,15 +1156,15 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * // Verify taskset state is valid auto _0 = be_t::make(u128::from32(0)); - if ((taskset->m.waiting & taskset->m.running) != _0 || (taskset->m.ready & taskset->m.pending_ready) != _0 || - ((taskset->m.running | taskset->m.ready | taskset->m.pending_ready | taskset->m.signalled | taskset->m.waiting) & be_t::make(~taskset->m.enabled.value())) != _0) { + if ((taskset->waiting & taskset->running) != _0 || (taskset->ready & taskset->pending_ready) != _0 || + ((taskset->running | taskset->ready | taskset->pending_ready | taskset->signalled | taskset->waiting) & be_t::make(~taskset->enabled.value())) != _0) { assert(!"Invalid taskset state"); //spursHalt(spu); //return CELL_OK; } // Find the number of tasks that have become ready since the last iteration - auto newlyReadyTasks = (taskset->m.signalled | taskset->m.pending_ready).value() & ~taskset->m.ready.value(); + auto newlyReadyTasks = (taskset->signalled | taskset->pending_ready).value() & ~taskset->ready.value(); numNewlyReadyTasks = 0; for (auto i = 0; i < 128; i++) { if (newlyReadyTasks._bit[i]) { @@ -1174,11 +1174,11 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * u128 readyButNotRunning; u8 selectedTaskId; - auto running = taskset->m.running.value(); - auto waiting = taskset->m.waiting.value(); - auto enabled = taskset->m.enabled.value(); - auto signalled = (taskset->m.signalled & (taskset->m.ready | taskset->m.pending_ready)).value(); - auto ready = (taskset->m.signalled | taskset->m.ready | taskset->m.pending_ready).value(); + auto running = taskset->running.value(); + auto waiting = taskset->waiting.value(); + auto enabled = taskset->enabled.value(); + auto signalled = (taskset->signalled & (taskset->ready | taskset->pending_ready)).value(); + auto ready = (taskset->signalled | taskset->ready | taskset->pending_ready).value(); switch (request) { case SPURS_TASKSET_REQUEST_POLL_SIGNAL: @@ -1207,20 +1207,20 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * break; case SPURS_TASKSET_REQUEST_POLL: readyButNotRunning = ready & ~running; - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { - readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->m.wkl_flag_wait_task)); + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->wkl_flag_wait_task)); } rc = readyButNotRunning != _0 ? 1 : 0; break; case SPURS_TASKSET_REQUEST_WAIT_WKL_FLAG: - if (taskset->m.wkl_flag_wait_task == 0x81) { + if (taskset->wkl_flag_wait_task == 0x81) { // A workload flag is already pending so consume it - taskset->m.wkl_flag_wait_task = 0x80; + taskset->wkl_flag_wait_task = 0x80; rc = 0; - } else if (taskset->m.wkl_flag_wait_task == 0x80) { + } else if (taskset->wkl_flag_wait_task == 0x80) { // No tasks are waiting for the workload flag. Mark this task as waiting for the workload flag. - taskset->m.wkl_flag_wait_task = ctxt->taskId; + taskset->wkl_flag_wait_task = ctxt->taskId; running._bit[ctxt->taskId] = false; waiting._bit[ctxt->taskId] = true; rc = 1; @@ -1232,25 +1232,25 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * break; case SPURS_TASKSET_REQUEST_SELECT_TASK: readyButNotRunning = ready & ~running; - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { - readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->m.wkl_flag_wait_task)); + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->wkl_flag_wait_task)); } // Select a task from the readyButNotRunning set to run. Start from the task after the last scheduled task to ensure fairness. - for (selectedTaskId = taskset->m.last_scheduled_task + 1; selectedTaskId < 128; selectedTaskId++) { + for (selectedTaskId = taskset->last_scheduled_task + 1; selectedTaskId < 128; selectedTaskId++) { if (readyButNotRunning._bit[selectedTaskId]) { break; } } if (selectedTaskId == 128) { - for (selectedTaskId = 0; selectedTaskId < taskset->m.last_scheduled_task + 1; selectedTaskId++) { + for (selectedTaskId = 0; selectedTaskId < taskset->last_scheduled_task + 1; selectedTaskId++) { if (readyButNotRunning._bit[selectedTaskId]) { break; } } - if (selectedTaskId == taskset->m.last_scheduled_task + 1) { + if (selectedTaskId == taskset->last_scheduled_task + 1) { selectedTaskId = CELL_SPURS_MAX_TASK; } } @@ -1258,20 +1258,20 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * *taskId = selectedTaskId; *isWaiting = waiting._bit[selectedTaskId < CELL_SPURS_MAX_TASK ? selectedTaskId : 0] ? 1 : 0; if (selectedTaskId != CELL_SPURS_MAX_TASK) { - taskset->m.last_scheduled_task = selectedTaskId; + taskset->last_scheduled_task = selectedTaskId; running._bit[selectedTaskId] = true; waiting._bit[selectedTaskId] = false; } break; case SPURS_TASKSET_REQUEST_RECV_WKL_FLAG: - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { // There is a task waiting for the workload flag - taskset->m.wkl_flag_wait_task = 0x80; + taskset->wkl_flag_wait_task = 0x80; rc = 1; numNewlyReadyTasks++; } else { // No tasks are waiting for the workload flag - taskset->m.wkl_flag_wait_task = 0x81; + taskset->wkl_flag_wait_task = 0x81; rc = 0; } break; @@ -1281,12 +1281,12 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * //return CELL_OK; } - taskset->m.pending_ready = _0; - taskset->m.running = running; - taskset->m.waiting = waiting; - taskset->m.enabled = enabled; - taskset->m.signalled = signalled; - taskset->m.ready = ready; + taskset->pending_ready = _0; + taskset->running = running; + taskset->waiting = waiting; + taskset->enabled = enabled; + taskset->signalled = signalled; + taskset->ready = ready; memcpy(vm::get_ptr(spu.offset + 0x2700), taskset, 128); }); @@ -1295,14 +1295,14 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * vm::reservation_op(vm::cast(kernelCtxt->spurs.addr()), 128, [&]() { auto spurs = kernelCtxt->spurs.priv_ptr(); - s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].read_relaxed(); + s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[kernelCtxt->wklCurrentId].read_relaxed() : spurs->wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].read_relaxed(); readyCount += numNewlyReadyTasks; readyCount = readyCount < 0 ? 0 : readyCount > 0xFF ? 0xFF : readyCount; if (kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].write_relaxed(readyCount); + spurs->wklReadyCount1[kernelCtxt->wklCurrentId].write_relaxed(readyCount); } else { - spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].write_relaxed(readyCount); + spurs->wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].write_relaxed(readyCount); } memcpy(vm::get_ptr(spu.offset + 0x100), spurs, 128); @@ -1433,7 +1433,7 @@ void spursTasksetDispatch(SPUThread & spu) { ctxt->taskId = taskId; // DMA in the task info for the selected task - memcpy(vm::get_ptr(spu.offset + 0x2780), &ctxt->taskset->m.task_info[taskId], sizeof(CellSpursTaskset::TaskInfo)); + memcpy(vm::get_ptr(spu.offset + 0x2780), &ctxt->taskset->task_info[taskId], sizeof(CellSpursTaskset::TaskInfo)); auto taskInfo = vm::get_ptr(spu.offset + 0x2780); auto elfAddr = taskInfo->elf_addr.addr().value(); taskInfo->elf_addr.set(taskInfo->elf_addr.addr() & 0xFFFFFFFFFFFFFFF8ull); @@ -1469,7 +1469,7 @@ void spursTasksetDispatch(SPUThread & spu) { ctxt->x2FD4 = elfAddr & 5; // TODO: Figure this out if ((elfAddr & 5) == 1) { - memcpy(vm::get_ptr(spu.offset + 0x2FC0), &((CellSpursTaskset2*)(ctxt->taskset.get_ptr()))->m.task_exit_code[taskId], 0x10); + memcpy(vm::get_ptr(spu.offset + 0x2FC0), &((CellSpursTaskset2*)(ctxt->taskset.get_ptr()))->task_exit_code[taskId], 0x10); } // Trace - GUID @@ -1486,7 +1486,7 @@ void spursTasksetDispatch(SPUThread & spu) { spursTasksetStartTask(spu, taskInfo->args); } else { - if (taskset->m.enable_clear_ls) { + if (taskset->enable_clear_ls) { memset(vm::get_ptr(spu.offset + CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP); } @@ -1557,7 +1557,7 @@ s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args) { spursTasksetProcessRequest(spu, SPURS_TASKSET_REQUEST_DESTROY_TASK, nullptr, nullptr); } - auto addr = ctxt->x2FD4 == 4 ? taskset->m.x78 : ctxt->x2FC0; + auto addr = ctxt->x2FD4 == 4 ? taskset->x78 : ctxt->x2FC0; auto args = ctxt->x2FD4 == 4 ? 0 : ctxt->x2FC8; spursTasksetOnTaskExit(spu, addr, ctxt->taskId, ctxt->taskExitCode, args); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index db6ec1be46..bdfa28615c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -26,7 +26,7 @@ s32 syncMutexInitialize(vm::ptr mutex) return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -52,7 +52,7 @@ s32 cellSyncMutexLock(vm::ptr mutex) return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -80,7 +80,7 @@ s32 cellSyncMutexTryLock(vm::ptr mutex) return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -100,7 +100,7 @@ s32 cellSyncMutexUnlock(vm::ptr mutex) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -119,7 +119,7 @@ s32 syncBarrierInitialize(vm::ptr barrier, u16 total_count) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -169,7 +169,7 @@ s32 cellSyncBarrierNotify(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -192,7 +192,7 @@ s32 cellSyncBarrierTryNotify(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -235,7 +235,7 @@ s32 cellSyncBarrierWait(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -258,7 +258,7 @@ s32 cellSyncBarrierTryWait(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -279,7 +279,7 @@ s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16 || buffer.addr() % 128) + if (!rwm.aligned() || buffer % 128) { return CELL_SYNC_ERROR_ALIGN; } @@ -335,7 +335,7 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -369,7 +369,7 @@ s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -411,7 +411,7 @@ s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -446,7 +446,7 @@ s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -478,7 +478,7 @@ s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 si { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32 || buffer.addr() % 16) + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } @@ -533,7 +533,7 @@ s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -571,7 +571,7 @@ s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffe { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -630,7 +630,7 @@ s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -668,7 +668,7 @@ s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -721,7 +721,7 @@ s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -757,7 +757,7 @@ s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -794,7 +794,7 @@ s32 cellSyncQueueSize(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -815,7 +815,7 @@ s32 cellSyncQueueClear(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -931,7 +931,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 { return CELL_SYNC_ERROR_INVAL; } - if (queue.addr() % 128 || buffer.addr() % 16) + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } @@ -1144,7 +1144,7 @@ s32 _cellSyncLFQueueGetPushPointer2(vm::ptr queue, vm::ptr return result; } -s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal) +s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, std::function fpSendSignal) { if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU) { @@ -1285,7 +1285,7 @@ s32 _cellSyncLFQueueCompletePushPointer(vm::ptr queue, s32 poin return syncLFQueueCompletePushPointer(queue, pointer, fpSendSignal); } -s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal) +s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, std::function fpSendSignal) { throw __FUNCTION__; } @@ -1307,7 +1307,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128 || buffer.addr() % 16) + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } @@ -1490,7 +1490,7 @@ s32 _cellSyncLFQueueGetPopPointer2(vm::ptr queue, vm::ptr return result; } -s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) +s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, std::function fpSendSignal, u32 noQueueFull) { if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU) { @@ -1631,7 +1631,7 @@ s32 _cellSyncLFQueueCompletePopPointer(vm::ptr queue, s32 point return syncLFQueueCompletePopPointer(queue, pointer, fpSendSignal, noQueueFull); } -s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) +s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, std::function fpSendSignal, u32 noQueueFull) { throw __FUNCTION__; } @@ -1653,7 +1653,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128 || buffer.addr() % 16) + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } @@ -1717,7 +1717,7 @@ s32 cellSyncLFQueueClear(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -1767,7 +1767,7 @@ s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -1802,7 +1802,7 @@ s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -1819,7 +1819,7 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::p { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -1837,7 +1837,7 @@ s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr queue, vm::ptr sync_var; }; -static_assert(sizeof(CellSyncMutex) == 4, "CellSyncMutex: wrong size"); +CHECK_SIZE_ALIGN(CellSyncMutex, 4, 4); -struct CellSyncBarrier +struct set_alignment(4) CellSyncBarrier { struct data_t { @@ -61,9 +61,9 @@ struct CellSyncBarrier atomic_be_t data; }; -static_assert(sizeof(CellSyncBarrier) == 4, "CellSyncBarrier: wrong size"); +CHECK_SIZE_ALIGN(CellSyncBarrier, 4, 4); -struct CellSyncRwm +struct set_alignment(16) CellSyncRwm { struct data_t { @@ -76,9 +76,9 @@ struct CellSyncRwm vm::bptr m_buffer; }; -static_assert(sizeof(CellSyncRwm) == 16, "CellSyncRwm: wrong size"); +CHECK_SIZE_ALIGN(CellSyncRwm, 16, 16); -struct CellSyncQueue +struct set_alignment(32) CellSyncQueue { struct data_t { @@ -93,7 +93,7 @@ struct CellSyncQueue be_t reserved; }; -static_assert(sizeof(CellSyncQueue) == 32, "CellSyncQueue: wrong size"); +CHECK_SIZE_ALIGN(CellSyncQueue, 32, 32); enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection { @@ -103,7 +103,7 @@ enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection CELL_SYNC_QUEUE_ANY2ANY = 3, // SPU/PPU to SPU/PPU }; -struct CellSyncLFQueue +struct set_alignment(128) CellSyncLFQueue { struct pop1_t { @@ -188,7 +188,7 @@ struct CellSyncLFQueue } }; -static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); +CHECK_SIZE_ALIGN(CellSyncLFQueue, 128, 128); s32 syncMutexInitialize(vm::ptr mutex); @@ -201,11 +201,11 @@ s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 si s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal); s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); -s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal); -s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal); +s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, std::function fpSendSignal); +s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, std::function fpSendSignal); s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue); s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); -s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); -s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); +s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, std::function fpSendSignal, u32 noQueueFull); +s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, std::function fpSendSignal, u32 noQueueFull); s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue); s32 syncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.h b/rpcs3/Emu/SysCalls/Modules/cellSync2.h index d50fade99d..557562b8d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.h @@ -41,7 +41,7 @@ struct CellSync2MutexAttribute u8 reserved[86]; }; -static_assert(sizeof(CellSync2MutexAttribute) == 128, "Wrong CellSync2MutexAttribute size"); +CHECK_SIZE(CellSync2MutexAttribute, 128); struct CellSync2CondAttribute { @@ -51,7 +51,7 @@ struct CellSync2CondAttribute u8 reserved[90]; }; -static_assert(sizeof(CellSync2CondAttribute) == 128, "Wrong CellSync2CondAttribute size"); +CHECK_SIZE(CellSync2CondAttribute, 128); struct CellSync2SemaphoreAttribute { @@ -62,7 +62,7 @@ struct CellSync2SemaphoreAttribute u8 reserved[88]; }; -static_assert(sizeof(CellSync2SemaphoreAttribute) == 128, "Wrong CellSync2SemaphoreAttribute size"); +CHECK_SIZE(CellSync2SemaphoreAttribute, 128); struct CellSync2QueueAttribute { @@ -76,4 +76,4 @@ struct CellSync2QueueAttribute u8 reserved[76]; }; -static_assert(sizeof(CellSync2QueueAttribute) == 128, "Wrong CellSync2QueueAttribute size"); +CHECK_SIZE(CellSync2QueueAttribute, 128); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index ca2f3d5180..1e7a49c519 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -99,7 +99,7 @@ struct sys_spu_segment }; }; -static_assert(sizeof(sys_spu_segment) == 0x18, "Wrong sys_spu_segment size"); +CHECK_SIZE(sys_spu_segment, 0x18); enum : u32 { diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index ef87727c8e..222c0c06e1 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -64,20 +64,25 @@ template::value>> in // return 32 bit sizeof() to avoid widening/narrowing conversions with size_t #define sizeof32(type) sizeof32_t::value +// return 32 bit alignof() to avoid widening/narrowing conversions with size_t +#define alignof32(type) alignof32_t<__alignof(type)>::value + template struct sizeof32_t { - static_assert(Size <= UINT32_MAX, "sizeof32() error: sizeof() is too big"); + static_assert(Size <= UINT32_MAX, "sizeof32() error: size is too big"); static const u32 value = static_cast(Size); }; +template struct alignof32_t +{ + static_assert(Align <= UINT32_MAX, "alignof32() error: alignment is too big"); + + static const u32 value = static_cast(Align); +}; + template using func_def = T; // workaround for MSVC bug: `using X = func_def;` instead of `using X = void();` -#include "Utilities/BEType.h" -#include "Utilities/StrFmt.h" - -#include "Emu/Memory/atomic.h" - template struct ID_type; #define REG_ID_TYPE(t, id) template<> struct ID_type { static const u32 type = id; } @@ -89,3 +94,7 @@ template struct ID_type; #define _PRGNAME_ "RPCS3" #define _PRGVER_ "0.0.0.5" + +#include "Utilities/BEType.h" +#include "Utilities/StrFmt.h" +#include "Emu/Memory/atomic.h"