2014-03-07 22:31:08 +01:00
|
|
|
#include "stdafx.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/Memory/Memory.h"
|
2014-09-30 00:28:02 +02:00
|
|
|
#include "Emu/System.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/SysCalls/Modules.h"
|
2014-11-10 01:21:50 +01:00
|
|
|
#include "Emu/SysCalls/CB_FUNC.h"
|
2015-05-27 05:11:59 +02:00
|
|
|
#include "Emu/IdManager.h"
|
|
|
|
|
#include "Emu/Event.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
#include "Emu/CPU/CPUThreadManager.h"
|
2014-09-19 02:19:22 +02:00
|
|
|
#include "Emu/Cell/SPUThread.h"
|
2015-03-02 22:09:20 +01:00
|
|
|
#include "Emu/SysCalls/lv2/sleep_queue.h"
|
2014-12-22 01:56:04 +01:00
|
|
|
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
|
|
|
|
|
#include "Emu/SysCalls/lv2/sys_lwcond.h"
|
|
|
|
|
#include "Emu/SysCalls/lv2/sys_spu.h"
|
2014-09-19 13:27:51 +02:00
|
|
|
#include "Emu/SysCalls/lv2/sys_ppu_thread.h"
|
2014-09-19 02:19:22 +02:00
|
|
|
#include "Emu/SysCalls/lv2/sys_memory.h"
|
|
|
|
|
#include "Emu/SysCalls/lv2/sys_process.h"
|
|
|
|
|
#include "Emu/SysCalls/lv2/sys_semaphore.h"
|
|
|
|
|
#include "Emu/SysCalls/lv2/sys_event.h"
|
|
|
|
|
#include "sysPrxForUser.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "cellSpurs.h"
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2015-02-18 17:22:06 +01:00
|
|
|
extern Module cellSpurs;
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2015-02-02 04:32:38 +01:00
|
|
|
bool spursKernelEntry(SPUThread & spu);
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, u32 id);
|
|
|
|
|
s32 _cellSpursSendSignal(vm::ptr<CellSpursTaskset> taskset, u32 taskID);
|
2015-01-03 11:29:22 +01:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursCreateLv2EventQueue(vm::ptr<CellSpurs> spurs, u32& queue_id, vm::ptr<u8> port, s32 size, u64 name_u64)
|
2014-09-23 01:07:40 +02:00
|
|
|
{
|
2015-05-28 21:13:35 +02:00
|
|
|
auto queue = Emu.GetEventManager().MakeEventQueue(SYS_SYNC_FIFO, SYS_PPU_QUEUE, name_u64, 0, size);
|
2015-05-27 05:11:59 +02:00
|
|
|
|
|
|
|
|
if (!queue) // rough
|
2014-09-23 01:07:40 +02:00
|
|
|
{
|
2015-05-27 05:11:59 +02:00
|
|
|
return CELL_EAGAIN;
|
2014-09-23 01:07:40 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-28 21:13:35 +02:00
|
|
|
queue_id = Emu.GetIdManager().add(std::move(queue));
|
2015-05-27 05:11:59 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
if (s32 res = spursAttachLv2EventQueue(spurs, queue_id, port, 1, true))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"spursAttachLv2EventQueue() failed");
|
|
|
|
|
}
|
2015-05-27 05:11:59 +02:00
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursInit(
|
2014-09-19 02:19:22 +02:00
|
|
|
vm::ptr<CellSpurs> spurs,
|
|
|
|
|
const u32 revision,
|
|
|
|
|
const u32 sdkVersion,
|
|
|
|
|
const s32 nSpus,
|
|
|
|
|
const s32 spuPriority,
|
|
|
|
|
const s32 ppuPriority,
|
2014-09-16 00:58:56 +02:00
|
|
|
u32 flags, // SpursAttrFlags
|
2014-09-15 20:17:30 +02:00
|
|
|
const char prefix[],
|
2014-09-19 02:19:22 +02:00
|
|
|
const u32 prefixSize,
|
|
|
|
|
const u32 container,
|
2014-09-16 00:58:56 +02:00
|
|
|
const u8 swlPriority[],
|
2014-09-19 02:19:22 +02:00
|
|
|
const u32 swlMaxSpu,
|
|
|
|
|
const u32 swlIsPreem)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-09-19 02:19:22 +02:00
|
|
|
// SPURS initialization (asserts should actually rollback and return the error instead)
|
|
|
|
|
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-19 02:19:22 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
if (prefixSize > CELL_SPURS_NAME_MAX_LENGTH)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
if (process_is_spu_lock_line_reservation_address(spurs.addr(), SYS_MEMORY_ACCESS_RIGHT_SPU_THR) != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-24 20:44:26 +02:00
|
|
|
const bool isSecond = (flags & SAF_SECOND_VERSION) != 0;
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
|
|
|
|
std::string name(prefix, prefixSize); // initialize name string
|
|
|
|
|
|
|
|
|
|
if (!isSecond)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklMskA.write_relaxed(be_t<u32>::make(0xffff));
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xCC = 0;
|
|
|
|
|
spurs->xCD = 0;
|
|
|
|
|
spurs->sysSrvMsgUpdateTrace = 0;
|
2014-09-19 02:19:22 +02:00
|
|
|
for (u32 i = 0; i < 8; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvWorkload[i] = -1;
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
2014-10-02 12:29:20 +02:00
|
|
|
|
|
|
|
|
// default or system workload:
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklInfoSysSrv.addr.set(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD);
|
|
|
|
|
spurs->wklInfoSysSrv.arg = 0;
|
|
|
|
|
spurs->wklInfoSysSrv.uniqueId.write_relaxed(0xff);
|
2014-09-19 02:19:22 +02:00
|
|
|
u32 sem;
|
|
|
|
|
for (u32 i = 0; i < 0x10; i++)
|
|
|
|
|
{
|
2015-06-19 17:49:38 +02:00
|
|
|
sem = Emu.GetIdManager().make<lv2_sema_t>(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0);
|
2014-09-23 01:07:40 +02:00
|
|
|
assert(sem && ~sem); // should rollback if semaphore creation failed and return the error
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklF1[i].sem = sem;
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
|
|
|
|
if (isSecond)
|
|
|
|
|
{
|
|
|
|
|
for (u32 i = 0; i < 0x10; i++)
|
|
|
|
|
{
|
2015-06-19 17:49:38 +02:00
|
|
|
sem = Emu.GetIdManager().make<lv2_sema_t>(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0);
|
2014-09-19 02:19:22 +02:00
|
|
|
assert(sem && ~sem);
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklF2[i].sem = sem;
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
|
|
|
|
}
|
2015-06-19 17:49:38 +02:00
|
|
|
sem = Emu.GetIdManager().make<lv2_sema_t>(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuPrv", 0);
|
2014-09-19 02:19:22 +02:00
|
|
|
assert(sem && ~sem);
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->semPrv = sem;
|
|
|
|
|
spurs->unk11 = -1;
|
|
|
|
|
spurs->unk12 = -1;
|
|
|
|
|
spurs->unk13 = 0;
|
|
|
|
|
spurs->nSpus = nSpus;
|
|
|
|
|
spurs->spuPriority = spuPriority;
|
2015-02-18 23:54:31 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->spuImg.addr = Memory.MainMem.AllocAlign(0x40000, 4096);
|
|
|
|
|
spurs->spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
|
|
|
|
s32 tgt = SYS_SPU_THREAD_GROUP_TYPE_NORMAL;
|
|
|
|
|
if (flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT)
|
|
|
|
|
{
|
|
|
|
|
tgt = SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT;
|
|
|
|
|
}
|
|
|
|
|
else if (flags & SAF_UNKNOWN_FLAG_0)
|
|
|
|
|
{
|
|
|
|
|
tgt = 0xC02;
|
|
|
|
|
}
|
|
|
|
|
if (flags & SAF_SPU_MEMORY_CONTAINER_SET) tgt |= SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER;
|
|
|
|
|
if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) tgt |= SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM;
|
|
|
|
|
if (flags & SAF_UNKNOWN_FLAG_7) tgt |= 0x102;
|
|
|
|
|
if (flags & SAF_UNKNOWN_FLAG_8) tgt |= 0xC02;
|
|
|
|
|
if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800;
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->spuTG = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container);
|
|
|
|
|
assert(spurs->spuTG.data());
|
2014-09-19 02:19:22 +02:00
|
|
|
|
|
|
|
|
name += "CellSpursKernel0";
|
2014-09-24 20:44:26 +02:00
|
|
|
for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++)
|
2014-09-19 02:19:22 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->spus[num] = spu_thread_initialize(spurs->spuTG, num, vm::ptr<sys_spu_image>::make(spurs.addr() + offsetof(CellSpurs, spuImg)),
|
2015-04-13 19:39:38 +02:00
|
|
|
name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0, [spurs](SPUThread& SPU)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
SPU.RegisterHleFunction(spurs->spuImg.entry_point, spursKernelEntry);
|
|
|
|
|
SPU.FastCall(spurs->spuImg.entry_point);
|
2015-04-13 19:39:38 +02:00
|
|
|
});
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags & SAF_SPU_PRINTF_ENABLED)
|
|
|
|
|
{
|
|
|
|
|
// spu_printf: attach group
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spu_printf_agcb || spu_printf_agcb(spurs->spuTG) != CELL_OK)
|
2014-09-19 02:19:22 +02:00
|
|
|
{
|
|
|
|
|
// remove flag if failed
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->flags &= ~SAF_SPU_PRINTF_ENABLED;
|
2014-09-19 02:19:22 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
lwmutex_create(spurs->mutex, false, SYS_SYNC_PRIORITY, *(u64*)"_spuPrv");
|
|
|
|
|
lwcond_create(spurs->cond, spurs->mutex, *(u64*)"_spuPrv");
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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<u32>::make(-1));
|
|
|
|
|
spurs->xD64 = {};
|
|
|
|
|
spurs->xD65 = {};
|
|
|
|
|
spurs->xD66 = {};
|
|
|
|
|
spurs->ppuPriority = ppuPriority;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
|
|
|
|
u32 queue;
|
2015-02-18 23:54:31 +01:00
|
|
|
if (s32 res = spursCreateLv2EventQueue(spurs, queue, vm::ptr<u8>::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv"))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"spursCreateLv2EventQueue() failed");
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->queue = queue;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2015-05-27 05:11:59 +02:00
|
|
|
u32 port = Emu.GetIdManager().make<lv2_event_port_t>(SYS_EVENT_PORT_LOCAL, 0);
|
2014-09-19 02:19:22 +02:00
|
|
|
assert(port && ~port);
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->port = port;
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2014-12-06 13:48:08 +01:00
|
|
|
if (s32 res = sys_event_port_connect_local(port, queue))
|
|
|
|
|
{
|
|
|
|
|
assert(!"sys_event_port_connect_local() failed");
|
|
|
|
|
}
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2014-09-19 13:27:51 +02:00
|
|
|
name = std::string(prefix, prefixSize);
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU)
|
2014-09-24 20:44:26 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->flags & SAF_UNKNOWN_FLAG_30)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-09-19 13:27:51 +02:00
|
|
|
|
2014-09-30 00:28:02 +02:00
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (Emu.IsStopped())
|
|
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("SPURS Handler Thread 0 aborted");
|
2014-09-30 00:28:02 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->flags1 & SF1_EXIT_IF_NO_WORK)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_lock() failed");
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->xD66.read_relaxed())
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex()))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_unlock() failed");
|
|
|
|
|
}
|
2014-09-30 00:28:02 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else while (true)
|
|
|
|
|
{
|
2014-12-09 17:13:03 +01:00
|
|
|
if (Emu.IsStopped()) break;
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xD64.exchange(0);
|
|
|
|
|
if (spurs->exception.data() == 0)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
|
|
|
|
bool do_break = false;
|
|
|
|
|
for (u32 i = 0; i < 16; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->wklState1[i].read_relaxed() == 2 &&
|
|
|
|
|
*((u64 *)spurs->wklInfo1[i].priority) != 0 &&
|
|
|
|
|
spurs->wklMaxContention[i].read_relaxed() & 0xf
|
2014-09-30 00:28:02 +02:00
|
|
|
)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->wklReadyCount1[i].read_relaxed() ||
|
|
|
|
|
spurs->wklSignal1.read_relaxed() & (0x8000u >> i) ||
|
|
|
|
|
(spurs->wklFlag.flag.read_relaxed() == 0 &&
|
|
|
|
|
spurs->wklFlagReceiver.read_relaxed() == (u8)i
|
2014-11-02 00:19:14 +01:00
|
|
|
))
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
|
|
|
|
do_break = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->flags1 & SF1_32_WORKLOADS) for (u32 i = 0; i < 16; i++)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->wklState2[i].read_relaxed() == 2 &&
|
|
|
|
|
*((u64 *)spurs->wklInfo2[i].priority) != 0 &&
|
|
|
|
|
spurs->wklMaxContention[i].read_relaxed() & 0xf0
|
2014-09-30 00:28:02 +02:00
|
|
|
)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
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
|
2014-11-02 00:19:14 +01:00
|
|
|
))
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
|
|
|
|
do_break = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (do_break) break; // from while
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xD65.exchange(1);
|
|
|
|
|
if (spurs->xD64.read_relaxed() == 0)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwcond_wait(CPU, spurs->get_lwcond(), 0))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwcond_wait() failed");
|
|
|
|
|
}
|
2014-09-30 00:28:02 +02:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xD65.exchange(0);
|
|
|
|
|
if (spurs->xD66.read_relaxed())
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex()))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_unlock() failed");
|
|
|
|
|
}
|
2014-09-30 00:28:02 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-09 17:13:03 +01:00
|
|
|
|
|
|
|
|
if (Emu.IsStopped()) continue;
|
|
|
|
|
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex()))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_unlock() failed");
|
|
|
|
|
}
|
2014-09-30 00:28:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Emu.IsStopped()) continue;
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (s32 res = sys_spu_thread_group_start(spurs->spuTG))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_spu_thread_group_start() failed");
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (s32 res = sys_spu_thread_group_join(spurs->spuTG, vm::null, vm::null))
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
|
|
|
|
if (res == CELL_ESTAT)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-12-06 13:48:08 +01:00
|
|
|
assert(!"sys_spu_thread_group_join() failed");
|
2014-09-30 00:28:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Emu.IsStopped()) continue;
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0)
|
2014-09-30 00:28:02 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
assert(spurs->xD66.read_relaxed() == 1 || Emu.IsStopped());
|
2014-09-30 00:28:02 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-04 22:51:14 +01:00
|
|
|
});
|
2014-09-24 20:44:26 +02:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU)
|
2014-09-24 20:44:26 +02:00
|
|
|
{
|
2015-02-18 23:54:31 +01:00
|
|
|
// TODO
|
2014-09-24 20:44:26 +02:00
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
});
|
2014-09-19 13:27:51 +02:00
|
|
|
|
2014-09-19 21:11:43 +02:00
|
|
|
// enable exception event handler
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->enableEH.compare_and_swap_test(be_t<u32>::make(0), be_t<u32>::make(1)))
|
2014-09-19 21:11:43 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (s32 res = sys_spu_thread_group_connect_event(spurs->spuTG, spurs->queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_spu_thread_group_connect_event() failed");
|
|
|
|
|
}
|
2014-09-19 21:11:43 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->traceBuffer.set(0);
|
2014-09-19 21:11:43 +02:00
|
|
|
// can also use cellLibprof if available (omitted)
|
|
|
|
|
|
|
|
|
|
// some unknown subroutine
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sub3.unk1 = spurs.addr() + 0xc9;
|
|
|
|
|
spurs->sub3.unk2 = 3; // unknown const
|
|
|
|
|
spurs->sub3.port = (u64)spurs->port;
|
2014-09-19 21:11:43 +02:00
|
|
|
|
2015-02-11 21:11:49 +01:00
|
|
|
if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) // initialize system workload (disabled)
|
2014-09-19 21:11:43 +02:00
|
|
|
{
|
2014-09-24 20:44:26 +02:00
|
|
|
s32 res = CELL_OK;
|
2015-02-18 23:54:31 +01:00
|
|
|
// TODO
|
2014-09-19 21:11:43 +02:00
|
|
|
assert(res == CELL_OK);
|
|
|
|
|
}
|
|
|
|
|
else if (flags & SAF_EXIT_IF_NO_WORK) // wakeup
|
|
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
return spursWakeUp(GetCurrentPPUThread(), spurs);
|
2014-09-19 21:11:43 +02:00
|
|
|
}
|
2014-09-25 23:41:35 +02:00
|
|
|
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursInitialize(vm::ptr<CellSpurs> spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
|
2014-09-15 17:04:09 +02:00
|
|
|
spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 17:04:09 +02:00
|
|
|
return spursInit(
|
2014-09-19 02:19:22 +02:00
|
|
|
spurs,
|
2014-09-15 17:04:09 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
nSpus,
|
|
|
|
|
spuPriority,
|
|
|
|
|
ppuPriority,
|
2014-09-16 00:58:56 +02:00
|
|
|
exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE,
|
2014-09-15 20:17:30 +02:00
|
|
|
nullptr,
|
2014-09-15 17:04:09 +02:00
|
|
|
0,
|
|
|
|
|
0,
|
2014-09-16 00:58:56 +02:00
|
|
|
nullptr,
|
2014-09-15 17:04:09 +02:00
|
|
|
0,
|
|
|
|
|
0);
|
2014-03-30 22:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursInitializeWithAttribute(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursAttribute> attr)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 17:04:09 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 17:04:09 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->revision > 2)
|
2014-09-15 17:04:09 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spursInit(
|
2014-09-19 02:19:22 +02:00
|
|
|
spurs,
|
2015-06-21 16:48:21 +02:00
|
|
|
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);
|
2014-03-30 22:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursInitializeWithAttribute2(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursAttribute> attr)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 17:04:09 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 17:04:09 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->revision > 2)
|
2014-09-15 17:04:09 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spursInit(
|
|
|
|
|
spurs,
|
2015-06-21 16:48:21 +02:00
|
|
|
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);
|
2014-09-15 17:04:09 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursAttributeInitialize(vm::ptr<CellSpursAttribute> attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
|
2014-09-15 17:04:09 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
|
2014-09-15 20:17:30 +02:00
|
|
|
attr.addr(), revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 20:17:30 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr<CellSpursAttribute> attr, u32 container)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-04-14 04:00:31 +02:00
|
|
|
cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.addr(), container);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 20:17:30 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-09-16 00:58:56 +02:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT)
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
2014-06-08 11:10:31 +02:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->container = container;
|
|
|
|
|
attr->flags |= SAF_SPU_MEMORY_CONTAINER_SET;
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttributeSetNamePrefix(vm::ptr<CellSpursAttribute> attr, vm::ptr<const char> prefix, u32 size)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 20:17:30 +02:00
|
|
|
if (!attr || !prefix)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-07 04:22:29 +02:00
|
|
|
if (size > CELL_SPURS_NAME_MAX_LENGTH)
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
2014-06-04 20:52:30 +02:00
|
|
|
}
|
2014-03-30 22:09:49 +02:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
memcpy(attr->prefix, prefix.get_ptr(), size);
|
|
|
|
|
attr->prefixSize = size;
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr<CellSpursAttribute> attr)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-16 00:58:56 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-16 00:58:56 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->flags |= SAF_SPU_PRINTF_ENABLED;
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttributeSetSpuThreadGroupType(vm::ptr<CellSpursAttribute> attr, s32 type)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-15 20:17:30 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2014-09-16 00:58:56 +02:00
|
|
|
if (type == SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT)
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->flags & SAF_SPU_MEMORY_CONTAINER_SET)
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set
|
2014-09-15 20:17:30 +02:00
|
|
|
}
|
2014-09-16 00:58:56 +02:00
|
|
|
else if (type == SYS_SPU_THREAD_GROUP_TYPE_NORMAL)
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear
|
2014-09-15 20:17:30 +02:00
|
|
|
}
|
2014-09-16 00:58:56 +02:00
|
|
|
else
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
2014-09-16 00:58:56 +02:00
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
2014-09-15 20:17:30 +02:00
|
|
|
}
|
2014-09-16 00:58:56 +02:00
|
|
|
return CELL_OK;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttributeEnableSystemWorkload(vm::ptr<CellSpursAttribute> attr, vm::ptr<const u8[8]> priority, u32 maxSpu, vm::ptr<const bool[8]> isPreemptible)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)",
|
2014-09-02 03:05:13 +02:00
|
|
|
attr.addr(), priority.addr(), maxSpu, isPreemptible.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-16 00:58:56 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-06-02 10:09:36 +02:00
|
|
|
{
|
2014-09-16 00:58:56 +02:00
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
const u32 nSpus = attr->nSpus;
|
|
|
|
|
|
2014-09-16 00:58:56 +02:00
|
|
|
if (!nSpus)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
|
2014-09-16 00:58:56 +02:00
|
|
|
for (u32 i = 0; i < nSpus; i++)
|
|
|
|
|
{
|
|
|
|
|
if ((*priority)[i] == 1)
|
2014-06-02 10:09:36 +02:00
|
|
|
{
|
2014-09-16 00:58:56 +02:00
|
|
|
if (!maxSpu)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (nSpus == 1 || attr->exitIfNoWork)
|
2014-09-16 00:58:56 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_PERM;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->flags & SAF_SYSTEM_WORKLOAD_ENABLED)
|
2014-09-16 00:58:56 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->flags |= SAF_SYSTEM_WORKLOAD_ENABLED; // set flag
|
|
|
|
|
*(u64*)attr->swlPriority = *(u64*)*priority; // copy system workload priorities
|
2014-09-16 00:58:56 +02:00
|
|
|
|
|
|
|
|
u32 isPreem = 0; // generate mask from isPreemptible values
|
|
|
|
|
for (u32 j = 0; j < nSpus; j++)
|
|
|
|
|
{
|
|
|
|
|
if ((*isPreemptible)[j])
|
|
|
|
|
{
|
|
|
|
|
isPreem |= (1 << j);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->swlMaxSpu = maxSpu; // write max spu for system workload
|
|
|
|
|
attr->swlIsPreem = isPreem; // write isPreemptible mask
|
2014-09-16 00:58:56 +02:00
|
|
|
return CELL_OK;
|
2014-06-02 10:09:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
2014-09-16 00:58:56 +02:00
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursFinalize(vm::ptr<CellSpurs> spurs)
|
2014-09-15 20:17:30 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Todo("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-11-02 00:19:14 +01:00
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-11-02 00:19:14 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->xD66.read_relaxed())
|
2014-11-02 00:19:14 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
// TODO
|
2014-11-02 00:19:14 +01:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursAttachLv2EventQueue(vm::ptr<CellSpurs> spurs, u32 queue, vm::ptr<u8> port, s32 isDynamic, bool wasCreated)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
if (!spurs || !port)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception.data())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s32 sdk_ver;
|
2014-12-06 13:48:08 +01:00
|
|
|
if (s32 res = process_get_sdk_version(process_getpid(), sdk_ver))
|
|
|
|
|
{
|
|
|
|
|
assert(!"process_get_sdk_version() failed");
|
|
|
|
|
}
|
2014-09-25 23:41:35 +02:00
|
|
|
if (sdk_ver == -1) sdk_ver = 0x460000;
|
|
|
|
|
|
|
|
|
|
u8 _port = 0x3f;
|
|
|
|
|
u64 port_mask = 0;
|
|
|
|
|
|
|
|
|
|
if (isDynamic == 0)
|
|
|
|
|
{
|
|
|
|
|
_port = *port;
|
|
|
|
|
if (_port > 0x3f)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
if (sdk_ver > 0x17ffff && _port > 0xf)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u32 i = isDynamic ? 0x10 : _port; i <= _port; i++)
|
|
|
|
|
{
|
|
|
|
|
port_mask |= 1ull << (i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(port_mask); // zero mask will return CELL_EINVAL
|
2015-06-21 16:48:21 +02:00
|
|
|
if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, port_mask, port))
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
if (res == CELL_EISCONN)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!wasCreated)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->spups |= be_t<u64>::make(1ull << *port); // atomic bitwise or
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAttachLv2EventQueue(vm::ptr<CellSpurs> spurs, u32 queue, vm::ptr<u8> port, s32 isDynamic)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-04-14 04:00:31 +02:00
|
|
|
cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%d)",
|
2014-09-25 23:41:35 +02:00
|
|
|
spurs.addr(), queue, port.addr(), isDynamic);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
return spursAttachLv2EventQueue(spurs, queue, port, isDynamic, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursDetachLv2EventQueue(vm::ptr<CellSpurs> spurs, u8 port)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetSpuGuid()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-09-15 20:17:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetSpuThreadGroupId(vm::ptr<CellSpurs> spurs, vm::ptr<u32> group)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.addr(), group.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
|
|
|
|
if (!spurs || !group)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-10-10 20:41:57 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*group = spurs->spuTG;
|
2014-10-10 20:41:57 +02:00
|
|
|
return CELL_OK;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetNumSpuThread(vm::ptr<CellSpurs> spurs, vm::ptr<u32> nThreads)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), nThreads.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
|
|
|
|
if (!spurs || !nThreads)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-10-10 20:41:57 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*nThreads = (u32)spurs->nSpus;
|
2014-10-10 20:41:57 +02:00
|
|
|
return CELL_OK;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetSpuThreadId(vm::ptr<CellSpurs> spurs, vm::ptr<u32> thread, vm::ptr<u32> nThreads)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), thread.addr(), nThreads.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
|
|
|
|
if (!spurs || !thread || !nThreads)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-10-10 20:41:57 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
const u32 count = std::min<u32>(*nThreads, spurs->nSpus);
|
2014-10-10 20:41:57 +02:00
|
|
|
for (u32 i = 0; i < count; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
thread[i] = spurs->spus[i];
|
2014-10-10 20:41:57 +02:00
|
|
|
}
|
|
|
|
|
*nThreads = count;
|
|
|
|
|
return CELL_OK;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSetMaxContention(vm::ptr<CellSpurs> spurs, u32 workloadId, u32 maxContention)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSetPriorities(vm::ptr<CellSpurs> spurs, u32 workloadId, vm::ptr<const u8> priorities)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSetPreemptionVictimHints(vm::ptr<CellSpurs> spurs, vm::ptr<const bool> isPreemptible)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEnableExceptionEventHandler(vm::ptr<CellSpurs> spurs, bool flag)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-09-25 23:41:35 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr<CellSpurs> spurs, u32 eaHandler_addr, u32 arg_addr)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr<CellSpurs> spurs)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetInfo(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursInfo> info)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursWakeUp(PPUThread& CPU, vm::ptr<CellSpurs> spurs)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception.data())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xD64.exchange(1);
|
|
|
|
|
if (spurs->xD65.read_sync())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_lock() failed");
|
|
|
|
|
}
|
2015-03-09 20:56:55 +01:00
|
|
|
if (s32 res = sys_lwcond_signal(CPU, spurs->get_lwcond()))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwcond_signal() failed");
|
|
|
|
|
}
|
2014-12-23 00:31:11 +01:00
|
|
|
if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex()))
|
2014-12-06 13:48:08 +01:00
|
|
|
{
|
|
|
|
|
assert(!"sys_lwmutex_unlock() failed");
|
|
|
|
|
}
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr<CellSpurs> spurs)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x)", __FUNCTION__, spurs.addr());
|
2014-09-25 23:41:35 +02:00
|
|
|
|
2014-12-23 00:31:11 +01:00
|
|
|
return spursWakeUp(CPU, spurs);
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s32 spursAddWorkload(
|
|
|
|
|
vm::ptr<CellSpurs> spurs,
|
|
|
|
|
vm::ptr<u32> wid,
|
|
|
|
|
vm::ptr<const void> pm,
|
|
|
|
|
u32 size,
|
|
|
|
|
u64 data,
|
|
|
|
|
const u8 priorityTable[],
|
|
|
|
|
u32 minContention,
|
|
|
|
|
u32 maxContention,
|
2014-09-27 20:49:33 +02:00
|
|
|
vm::ptr<const char> nameClass,
|
|
|
|
|
vm::ptr<const char> nameInstance,
|
2014-09-25 23:41:35 +02:00
|
|
|
vm::ptr<CellSpursShutdownCompletionEventHook> hook,
|
|
|
|
|
vm::ptr<void> hookArg)
|
|
|
|
|
{
|
2014-09-27 20:49:33 +02:00
|
|
|
if (!spurs || !wid || !pm)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned() || pm % 16)
|
2014-09-27 20:49:33 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
if (minContention == 0 || *(u64*)priorityTable & 0xf0f0f0f0f0f0f0f0ull) // check if some priority > 15
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception.data())
|
2014-09-27 20:49:33 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 wnum;
|
2015-06-21 16:48:21 +02:00
|
|
|
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<u32>& value)
|
2014-09-27 20:49:33 +02:00
|
|
|
{
|
|
|
|
|
wnum = cntlz32(~(u32)value); // found empty position
|
|
|
|
|
if (wnum < wmax)
|
|
|
|
|
{
|
|
|
|
|
value |= (u32)(0x80000000ull >> wnum); // set workload bit
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
*wid = wnum; // store workload id
|
|
|
|
|
if (wnum >= wmax)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_AGAIN;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-30 00:28:02 +02:00
|
|
|
u32 index = wnum & 0xf;
|
2014-09-27 20:49:33 +02:00
|
|
|
if (wnum <= 15)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-12-31 21:21:22 +01:00
|
|
|
for (u32 i = 0; i < 8; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklInfo1[wnum].priority[i] = priorityTable[i];
|
2014-12-31 21:21:22 +01:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
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);
|
2014-09-27 20:49:33 +02:00
|
|
|
if (hook)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklF1[wnum].hook = hook;
|
|
|
|
|
spurs->wklF1[wnum].hookArg = hookArg;
|
|
|
|
|
spurs->wklEvent1[wnum] |= 2;
|
2014-09-27 20:49:33 +02:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->flags1 & SF1_32_WORKLOADS) == 0)
|
2014-09-27 20:49:33 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0);
|
|
|
|
|
spurs->wklMinContention[wnum] = minContention > 8 ? 8 : minContention;
|
2014-09-27 20:49:33 +02:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklReadyCount1[wnum].write_relaxed(0);
|
2014-09-28 21:10:13 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-12-31 21:21:22 +01:00
|
|
|
for (u32 i = 0; i < 8; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklInfo2[index].priority[i] = priorityTable[i];
|
2014-12-31 21:21:22 +01:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
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);
|
2014-09-28 21:10:13 +02:00
|
|
|
if (hook)
|
2014-09-27 20:49:33 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklF2[index].hook = hook;
|
|
|
|
|
spurs->wklF2[index].hookArg = hookArg;
|
|
|
|
|
spurs->wklEvent2[index] |= 2;
|
2014-09-27 20:49:33 +02:00
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0);
|
2014-09-28 21:10:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wnum <= 15)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklMaxContention[wnum].atomic_op([maxContention](u8& v)
|
2014-09-30 21:06:04 +02:00
|
|
|
{
|
|
|
|
|
v &= ~0xf;
|
|
|
|
|
v |= (maxContention > 8 ? 8 : maxContention);
|
|
|
|
|
});
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklSignal1._and_not({ be_t<u16>::make(0x8000 >> index) }); // clear bit in wklFlag1
|
2014-09-27 20:49:33 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklMaxContention[index].atomic_op([maxContention](u8& v)
|
2014-09-30 21:06:04 +02:00
|
|
|
{
|
|
|
|
|
v &= ~0xf0;
|
|
|
|
|
v |= (maxContention > 8 ? 8 : maxContention) << 4;
|
|
|
|
|
});
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklSignal2._and_not({ be_t<u16>::make(0x8000 >> index) }); // clear bit in wklFlag2
|
2014-09-28 21:10:13 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklFlagReceiver.compare_and_swap(wnum, 0xff);
|
2014-09-28 21:10:13 +02:00
|
|
|
|
|
|
|
|
u32 res_wkl;
|
2015-06-21 16:48:21 +02:00
|
|
|
CellSpurs::WorkloadInfo& wkl = wnum <= 15 ? spurs->wklInfo1[wnum] : spurs->wklInfo2[wnum & 0xf];
|
|
|
|
|
spurs->wklMskB.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t<u32>& v)
|
2014-09-28 21:10:13 +02:00
|
|
|
{
|
2015-01-14 00:08:00 +01:00
|
|
|
const u32 mask = v & ~(0x80000000u >> wnum);
|
2014-09-28 21:10:13 +02:00
|
|
|
res_wkl = 0;
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0, m = 0x80000000, k = 0; i < 32; i++, m >>= 1)
|
|
|
|
|
{
|
|
|
|
|
if (mask & m)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
CellSpurs::WorkloadInfo& current = i <= 15 ? spurs->wklInfo1[i] : spurs->wklInfo2[i & 0xf];
|
2014-12-21 20:37:53 +01:00
|
|
|
if (current.addr.addr() == wkl.addr.addr())
|
2014-09-28 21:10:13 +02:00
|
|
|
{
|
|
|
|
|
// if a workload with identical policy module found
|
2014-12-21 20:37:53 +01:00
|
|
|
res_wkl = current.uniqueId.read_relaxed();
|
2014-09-28 21:10:13 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2014-12-21 20:37:53 +01:00
|
|
|
k |= 0x80000000 >> current.uniqueId.read_relaxed();
|
2014-09-28 21:10:13 +02:00
|
|
|
res_wkl = cntlz32(~k);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-09-27 20:49:33 +02:00
|
|
|
|
2014-12-21 20:37:53 +01:00
|
|
|
wkl.uniqueId.exchange((u8)res_wkl);
|
2014-09-29 17:39:44 +02:00
|
|
|
v = mask | (0x80000000u >> wnum);
|
2014-09-28 21:10:13 +02:00
|
|
|
});
|
|
|
|
|
assert(res_wkl <= 31);
|
|
|
|
|
|
2014-12-31 21:21:22 +01:00
|
|
|
spurs->wklState(wnum).exchange(2);
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvMsgUpdateWorkload.exchange(0xff);
|
|
|
|
|
spurs->sysSrvMessage.exchange(0xff);
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAddWorkload(
|
2014-09-25 23:41:35 +02:00
|
|
|
vm::ptr<CellSpurs> spurs,
|
|
|
|
|
vm::ptr<u32> wid,
|
|
|
|
|
vm::ptr<const void> pm,
|
|
|
|
|
u32 size,
|
|
|
|
|
u64 data,
|
|
|
|
|
vm::ptr<const u8[8]> priorityTable,
|
|
|
|
|
u32 minContention,
|
|
|
|
|
u32 maxContention)
|
|
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)",
|
2014-09-25 23:41:35 +02:00
|
|
|
__FUNCTION__, spurs.addr(), wid.addr(), pm.addr(), size, data, priorityTable.addr(), minContention, maxContention);
|
|
|
|
|
|
|
|
|
|
return spursAddWorkload(
|
|
|
|
|
spurs,
|
|
|
|
|
wid,
|
|
|
|
|
pm,
|
|
|
|
|
size,
|
|
|
|
|
data,
|
|
|
|
|
*priorityTable,
|
|
|
|
|
minContention,
|
|
|
|
|
maxContention,
|
2015-04-21 22:26:21 +02:00
|
|
|
vm::null,
|
|
|
|
|
vm::null,
|
|
|
|
|
vm::null,
|
|
|
|
|
vm::null);
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursWorkloadAttributeInitialize(
|
2014-09-25 23:41:35 +02:00
|
|
|
vm::ptr<CellSpursWorkloadAttribute> attr,
|
|
|
|
|
u32 revision,
|
|
|
|
|
u32 sdkVersion,
|
|
|
|
|
vm::ptr<const void> pm,
|
|
|
|
|
u32 size,
|
|
|
|
|
u64 data,
|
|
|
|
|
vm::ptr<const u8[8]> priorityTable,
|
|
|
|
|
u32 minContention,
|
|
|
|
|
u32 maxContention)
|
|
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)",
|
2014-09-25 23:41:35 +02:00
|
|
|
__FUNCTION__, attr.addr(), revision, sdkVersion, pm.addr(), size, data, priorityTable.addr(), minContention, maxContention);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
if (!pm)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (pm % 16)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
if (minContention == 0 || *(u64*)*priorityTable & 0xf0f0f0f0f0f0f0f0ull) // check if some priority > 15
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursWorkloadAttributeSetName(vm::ptr<CellSpursWorkloadAttribute> attr, vm::ptr<const char> nameClass, vm::ptr<const char> nameInstance)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr_addr=0x%x, nameClass_addr=0x%x, nameInstance_addr=0x%x)", __FUNCTION__, attr.addr(), nameClass.addr(), nameInstance.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->nameClass = nameClass;
|
|
|
|
|
attr->nameInstance = nameInstance;
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr<CellSpursWorkloadAttribute> attr, vm::ptr<CellSpursShutdownCompletionEventHook> hook, vm::ptr<void> arg)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr_addr=0x%x, hook_addr=0x%x, arg=0x%x)", __FUNCTION__, attr.addr(), hook.addr(), arg.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
if (!attr || !hook)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->hook = hook;
|
|
|
|
|
attr->hookArg = arg;
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAddWorkloadWithAttribute(vm::ptr<CellSpurs> spurs, const vm::ptr<u32> wid, vm::ptr<const CellSpursWorkloadAttribute> attr)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, attr_addr=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), attr.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->revision != be_t<u32>::make(1))
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spursAddWorkload(
|
|
|
|
|
spurs,
|
|
|
|
|
wid,
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->pm,
|
|
|
|
|
attr->size,
|
|
|
|
|
attr->data,
|
|
|
|
|
attr->priority,
|
|
|
|
|
attr->minContention,
|
|
|
|
|
attr->maxContention,
|
|
|
|
|
attr->nameClass,
|
|
|
|
|
attr->nameInstance,
|
|
|
|
|
attr->hook,
|
|
|
|
|
attr->hookArg);
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursRemoveWorkload()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
2014-03-07 22:31:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursWaitForWorkloadShutdown()
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursShutdownWorkload()
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursWorkloadFlagReceiver(vm::ptr<CellSpurs> spurs, u32 wid, u32 is_set)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, is_set=%d)", __FUNCTION__, spurs.addr(), wid, is_set);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-29 17:39:44 +02:00
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u))
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception.data())
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (s32 res = spurs->wklFlag.flag.atomic_op_sync(0, [spurs, wid, is_set](be_t<u32>& flag) -> s32
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
if (is_set)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->wklFlagReceiver.read_relaxed() != 0xff)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->wklFlagReceiver.read_relaxed() != wid)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
flag = -1;
|
|
|
|
|
return 0;
|
|
|
|
|
}))
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklFlagReceiver.atomic_op([wid, is_set](u8& FR)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
if (is_set)
|
|
|
|
|
{
|
|
|
|
|
if (FR == 0xff)
|
|
|
|
|
{
|
|
|
|
|
FR = (u8)wid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (FR == wid)
|
|
|
|
|
{
|
|
|
|
|
FR = 0xff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return CELL_OK;
|
2014-03-30 22:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-14 23:52:22 +02:00
|
|
|
s32 cellSpursGetWorkloadFlag(vm::ptr<CellSpurs> spurs, vm::pptr<CellSpursWorkloadFlag> flag)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, flag_addr=0x%x)", __FUNCTION__, spurs.addr(), flag.addr());
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-29 17:39:44 +02:00
|
|
|
if (!spurs || !flag)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
flag->set(vm::get_addr(&spurs->wklFlag));
|
2014-09-29 17:39:44 +02:00
|
|
|
return CELL_OK;
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSendWorkloadSignal(vm::ptr<CellSpurs> spurs, u32 workloadId)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0))
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u8 state;
|
|
|
|
|
if (workloadId >= CELL_SPURS_MAX_WORKLOAD)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
state = spurs->wklState2[workloadId & 0x0F].read_relaxed();
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
state = spurs->wklState1[workloadId].read_relaxed();
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state != SPURS_WKL_STATE_RUNNABLE)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (workloadId >= CELL_SPURS_MAX_WORKLOAD)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklSignal2 |= be_t<u16>::make(0x8000 >> (workloadId & 0x0F));
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklSignal1 |= be_t<u16>::make(0x8000 >> workloadId);
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetWorkloadData(vm::ptr<CellSpurs> spurs, vm::ptr<u64> data, u32 workloadId)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId);
|
2015-01-23 20:11:29 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs || !data)
|
2015-01-23 20:11:29 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2015-01-23 20:11:29 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0))
|
2015-01-23 20:11:29 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0)
|
2015-01-23 20:11:29 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception)
|
2015-01-23 20:11:29 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (workloadId >= CELL_SPURS_MAX_WORKLOAD)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
*data = spurs->wklInfo2[workloadId & 0x0F].arg;
|
2015-01-23 20:11:29 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
*data = spurs->wklInfo1[workloadId].arg;
|
2015-01-23 20:11:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-09-25 23:41:35 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursReadyCountStore(vm::ptr<CellSpurs> spurs, u32 wid, u32 value)
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, value=0x%x)", __FUNCTION__, spurs.addr(), wid, value);
|
2014-10-10 20:41:57 +02:00
|
|
|
|
2014-09-29 17:39:44 +02:00
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u) || value > 0xff)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_INVAL;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((spurs->wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_SRCH;
|
|
|
|
|
}
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->exception.data() || spurs->wklState(wid).read_relaxed() != 2)
|
2014-09-29 17:39:44 +02:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_POLICY_MODULE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-21 20:37:53 +01:00
|
|
|
if (wid < CELL_SPURS_MAX_WORKLOAD)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklReadyCount1[wid].exchange((u8)value);
|
2014-12-21 20:37:53 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->wklIdleSpuCountOrReadyCount2[wid].exchange((u8)value);
|
2014-12-21 20:37:53 +01:00
|
|
|
}
|
2014-09-29 17:39:44 +02:00
|
|
|
return CELL_OK;
|
2014-09-25 23:41:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursReadyCountAdd()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursReadyCountCompareAndSwap()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursReadyCountSwap()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursRequestIdleSpu()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetWorkloadInfo()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursWorkloadFlagReceiver2()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSetExceptionEventHandler()
|
2014-09-25 23:41:35 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursUnsetExceptionEventHandler()
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursEventFlagInitialize(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, vm::ptr<CellSpursEventFlag> eventFlag, u32 flagClearMode, u32 flagDirection)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)",
|
2014-09-02 03:05:13 +02:00
|
|
|
spurs.addr(), taskset.addr(), eventFlag.addr(), flagClearMode, flagDirection);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((!taskset && !spurs) || !eventFlag)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned() || !taskset.aligned() || !eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset.addr() && taskset->wid >= CELL_SPURS_MAX_WORKLOAD2)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flagDirection > CELL_SPURS_EVENT_FLAG_LAST || flagClearMode > CELL_SPURS_EVENT_FLAG_CLEAR_LAST)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
memset(eventFlag.get_ptr(), 0, sizeof(CellSpursEventFlag));
|
|
|
|
|
eventFlag->direction = flagDirection;
|
|
|
|
|
eventFlag->clearMode = flagClearMode;
|
|
|
|
|
eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT;
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
if (taskset.addr())
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->addr = taskset.addr();
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->isIwl = 1;
|
|
|
|
|
eventFlag->addr = spurs.addr();
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr<CellSpursEventFlag> eventFlag)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
if (!eventFlag)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_AGAIN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->spuPort != CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vm::ptr<CellSpurs> spurs;
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->isIwl == 1)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs.set((u32)eventFlag->addr);
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
auto taskset = vm::ptr<CellSpursTaskset>::make((u32)eventFlag->addr);
|
|
|
|
|
spurs.set((u32)taskset->spurs.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 eventQueueId;
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::var<u8> port;
|
|
|
|
|
auto rc = spursCreateLv2EventQueue(spurs, eventQueueId, port, 1, *((u64 *)"_spuEvF"));
|
2015-01-20 20:17:20 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code
|
2015-01-20 20:17:20 +01:00
|
|
|
return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF));
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::var<be_t<u32>> eventPortId;
|
2015-06-19 17:49:38 +02:00
|
|
|
rc = sys_event_port_create(vm::ref<u32>::make(eventPortId.addr()), SYS_EVENT_PORT_LOCAL, 0);
|
2015-01-20 20:17:20 +01:00
|
|
|
if (rc == CELL_OK)
|
|
|
|
|
{
|
2015-01-22 22:31:46 +01:00
|
|
|
rc = sys_event_port_connect_local(eventPortId.value(), eventQueueId);
|
2015-01-20 20:17:20 +01:00
|
|
|
if (rc == CELL_OK)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->eventPortId = eventPortId;
|
2015-01-20 20:17:20 +01:00
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-22 22:31:46 +01:00
|
|
|
sys_event_port_destroy(eventPortId.value());
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Implement the following
|
|
|
|
|
// if (spursDetachLv2EventQueue(spurs, port, 1) == CELL_OK)
|
|
|
|
|
// {
|
|
|
|
|
// sys_event_queue_destroy(eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE);
|
|
|
|
|
// }
|
2015-01-23 19:47:37 +01:00
|
|
|
|
|
|
|
|
// Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code
|
2015-01-20 20:17:20 +01:00
|
|
|
return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success:
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->eventQueueId = eventQueueId;
|
|
|
|
|
eventFlag->spuPort = port;
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr<CellSpursEventFlag> eventFlag)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
if (!eventFlag)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_AGAIN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->ppuWaitMask || eventFlag->ppuPendingRecv)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
auto port = eventFlag->spuPort;
|
|
|
|
|
eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT;
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
vm::ptr<CellSpurs> spurs;
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->isIwl == 1)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs.set((u32)eventFlag->addr);
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
auto taskset = vm::ptr<CellSpursTaskset>::make((u32)eventFlag->addr);
|
|
|
|
|
spurs.set((u32)taskset->spurs.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if(eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
sys_event_port_disconnect(eventFlag->eventPortId);
|
|
|
|
|
sys_event_port_destroy(eventFlag->eventPortId);
|
2015-01-20 20:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 rc = CELL_OK;
|
2015-01-20 20:17:20 +01:00
|
|
|
// TODO: Implement the following
|
|
|
|
|
// auto rc = spursDetachLv2EventQueue(spurs, port, 1);
|
|
|
|
|
// if (rc == CELL_OK)
|
|
|
|
|
// {
|
2015-06-21 16:48:21 +02:00
|
|
|
// rc = sys_event_queue_destroy(eventFlag->eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE);
|
2015-01-20 20:17:20 +01:00
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code
|
2015-01-20 20:17:20 +01:00
|
|
|
return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF));
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursEventFlagWait(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<u16> mask, u32 mode, u32 block)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag || !mask)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode > CELL_SPURS_EVENT_FLAG_WAIT_MODE_LAST)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (block && eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->ppuWaitMask || eventFlag->ppuPendingRecv)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 relevantEvents = eventFlag->events & *mask;
|
|
|
|
|
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Make sure the wait mask and mode specified does not conflict with that of the already waiting tasks.
|
|
|
|
|
// Conflict scenarios:
|
|
|
|
|
// OR vs OR - A conflict never occurs
|
|
|
|
|
// OR vs AND - A conflict occurs if the masks for the two tasks overlap
|
|
|
|
|
// AND vs AND - A conflict occurs if the masks for the two tasks are not the same
|
|
|
|
|
|
|
|
|
|
// Determine the set of all already waiting tasks whose wait mode/mask can possibly conflict with the specified wait mode/mask.
|
|
|
|
|
// 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.
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~eventFlag->spuTaskPendingRecv;
|
2015-01-23 19:47:37 +01:00
|
|
|
if (mode == CELL_SPURS_EVENT_FLAG_OR)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
relevantWaitSlots &= eventFlag->spuTaskWaitMode;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1;
|
|
|
|
|
while (relevantWaitSlots)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
if (relevantWaitSlots & 0x0001)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->spuTaskWaitMask[i] & *mask && eventFlag->spuTaskWaitMask[i] != *mask)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_AGAIN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
relevantWaitSlots >>= 1;
|
2015-01-22 22:31:46 +01:00
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
// There is no need to block if all bits required by the wait operation have already been set or
|
|
|
|
|
// if the wait mode is OR and atleast one of the bits required by the wait operation has been set.
|
2015-01-22 22:31:46 +01:00
|
|
|
bool recv;
|
2015-01-23 19:47:37 +01:00
|
|
|
if ((*mask & ~relevantEvents) == 0 || (mode == CELL_SPURS_EVENT_FLAG_OR && relevantEvents))
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// If the clear flag is AUTO then clear the bits comnsumed by this thread
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->events &= ~relevantEvents;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recv = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// If we reach here it means that the conditions for this thread have not been met.
|
|
|
|
|
// If this is a try wait operation then do not block but return an error code.
|
2015-01-22 22:31:46 +01:00
|
|
|
if (block == 0)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->ppuWaitSlotAndMode = 0;
|
|
|
|
|
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Find an unsed wait slot
|
|
|
|
|
int i = 0;
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 spuTaskUsedWaitSlots = eventFlag->spuTaskUsedWaitSlots;
|
2015-01-23 19:47:37 +01:00
|
|
|
while (spuTaskUsedWaitSlots & 0x0001)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
spuTaskUsedWaitSlots >>= 1;
|
2015-01-22 22:31:46 +01:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
if (i == CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Event flag has no empty wait slots
|
2015-01-22 22:31:46 +01:00
|
|
|
return CELL_SPURS_TASK_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
// Mark the found wait slot as used by this thread
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->ppuWaitSlotAndMode = (CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1 - i) << 4;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
// Save the wait mask and mode for this thread
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->ppuWaitSlotAndMode |= mode;
|
|
|
|
|
eventFlag->ppuWaitMask = *mask;
|
2015-01-23 19:47:37 +01:00
|
|
|
recv = true;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
u16 receivedEventFlag;
|
2015-01-22 22:31:46 +01:00
|
|
|
if (recv) {
|
2015-01-23 19:47:37 +01:00
|
|
|
// Block till something happens
|
2015-03-04 05:42:04 +01:00
|
|
|
vm::var<sys_event_t> data;
|
2015-06-21 16:48:21 +02:00
|
|
|
auto rc = sys_event_queue_receive(GetCurrentPPUThread(), eventFlag->eventQueueId, data, 0);
|
2015-01-22 22:31:46 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
int i = 0;
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
i = eventFlag->ppuWaitSlotAndMode >> 4;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
receivedEventFlag = eventFlag->pendingRecvTaskEvents[i];
|
|
|
|
|
eventFlag->ppuPendingRecv = 0;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
*mask = receivedEventFlag;
|
2015-01-20 20:17:20 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagWait(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<u16> mask, u32 mode)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.addr(), mask.addr(), mode);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
return _cellSpursEventFlagWait(eventFlag, mask, mode, 1/*block*/);
|
2014-06-02 05:09:42 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagClear(vm::ptr<CellSpursEventFlag> eventFlag, u16 bits)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->events &= ~bits;
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagSet(vm::ptr<CellSpursEventFlag> eventFlag, u16 bits)
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_PPU2SPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_PERM;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
u16 ppuEventFlag = 0;
|
|
|
|
|
bool send = false;
|
|
|
|
|
int ppuWaitSlot = 0;
|
|
|
|
|
u16 eventsToClear = 0;
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY && eventFlag->ppuWaitMask)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 ppuRelevantEvents = (eventFlag->events | bits) & eventFlag->ppuWaitMask;
|
2015-01-23 19:47:37 +01:00
|
|
|
|
|
|
|
|
// 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
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((eventFlag->ppuWaitMask & ~ppuRelevantEvents) == 0 ||
|
|
|
|
|
((eventFlag->ppuWaitSlotAndMode & 0x0F) == CELL_SPURS_EVENT_FLAG_OR && ppuRelevantEvents != 0))
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->ppuPendingRecv = 1;
|
|
|
|
|
eventFlag->ppuWaitMask = 0;
|
2015-01-23 19:47:37 +01:00
|
|
|
ppuEventFlag = ppuRelevantEvents;
|
|
|
|
|
eventsToClear = ppuRelevantEvents;
|
2015-06-21 16:48:21 +02:00
|
|
|
ppuWaitSlot = eventFlag->ppuWaitSlotAndMode >> 4;
|
2015-01-23 19:47:37 +01:00
|
|
|
send = true;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1;
|
|
|
|
|
int j = 0;
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~eventFlag->spuTaskPendingRecv;
|
2015-01-23 19:47:37 +01:00
|
|
|
u16 spuTaskPendingRecv = 0;
|
|
|
|
|
u16 pendingRecvTaskEvents[16];
|
|
|
|
|
while (relevantWaitSlots)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
if (relevantWaitSlots & 0x0001)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
u16 spuTaskRelevantEvents = (eventFlag->events | bits) & eventFlag->spuTaskWaitMask[i];
|
2015-01-23 19:47:37 +01:00
|
|
|
|
|
|
|
|
// 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
|
2015-06-21 16:48:21 +02:00
|
|
|
if ((eventFlag->spuTaskWaitMask[i] & ~spuTaskRelevantEvents) == 0 ||
|
|
|
|
|
(((eventFlag->spuTaskWaitMode >> j) & 0x0001) == CELL_SPURS_EVENT_FLAG_OR && spuTaskRelevantEvents != 0))
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
eventsToClear |= spuTaskRelevantEvents;
|
|
|
|
|
spuTaskPendingRecv |= 1 << j;
|
|
|
|
|
pendingRecvTaskEvents[j] = spuTaskRelevantEvents;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
relevantWaitSlots >>= 1;
|
2015-01-22 22:31:46 +01:00
|
|
|
i--;
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->events |= bits;
|
|
|
|
|
eventFlag->spuTaskPendingRecv |= spuTaskPendingRecv;
|
2015-01-23 19:47:37 +01:00
|
|
|
|
|
|
|
|
// If the clear flag is AUTO then clear the bits comnsumed by all tasks marked to be unblocked
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->events &= ~eventsToClear;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (send)
|
|
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Signal the PPU thread to be woken up
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEventFlag;
|
|
|
|
|
if (sys_event_port_send(eventFlag->eventPortId, 0, 0, 0) != CELL_OK)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 19:47:37 +01:00
|
|
|
if (spuTaskPendingRecv)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
// Signal each SPU task whose conditions have been met to be woken up
|
|
|
|
|
for (int i = 0; i < CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS; i++)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-01-23 19:47:37 +01:00
|
|
|
if (spuTaskPendingRecv & (0x8000 >> i))
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i];
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::var<u32> taskset;
|
2015-06-21 16:48:21 +02:00
|
|
|
if (eventFlag->isIwl)
|
2015-01-22 22:31:46 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs>::make((u32)eventFlag->addr),
|
2015-01-23 19:47:37 +01:00
|
|
|
vm::ptr<CellSpursTaskset>::make(taskset.addr()),
|
2015-06-21 16:48:21 +02:00
|
|
|
eventFlag->waitingTaskWklId[i]);
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset.value() = (u32)eventFlag->addr;
|
2015-01-22 22:31:46 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
auto rc = _cellSpursSendSignal(vm::ptr<CellSpursTaskset>::make(taskset.addr()), eventFlag->waitingTaskId[i]);
|
2015-01-22 22:31:46 +01:00
|
|
|
if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagTryWait(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<u16> mask, u32 mode)
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.addr(), mask.addr(), mode);
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
return _cellSpursEventFlagWait(eventFlag, mask, mode, 0/*block*/);
|
2014-06-04 18:03:31 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagGetDirection(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<u32> direction)
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag || !direction)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*direction = eventFlag->direction;
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagGetClearMode(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<u32> clear_mode)
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag || !clear_mode)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*clear_mode = eventFlag->clearMode;
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursEventFlagGetTasksetAddress(vm::ptr<CellSpursEventFlag> eventFlag, vm::ptr<CellSpursTaskset> taskset)
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr());
|
2015-01-20 20:17:20 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag || !taskset)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!eventFlag.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset.set(eventFlag->isIwl ? 0 : eventFlag->addr);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
2014-06-07 11:32:15 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursLFQueueInitialize()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursLFQueuePushBody()
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
2014-06-04 20:52:30 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursLFQueueDetachLv2EventQueue()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
2014-06-04 20:52:30 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursLFQueueAttachLv2EventQueue()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursLFQueuePopBody()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursLFQueueGetTasksetAddress()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursQueueInitialize()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueuePopBody()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueuePushBody()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueAttachLv2EventQueue()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueDetachLv2EventQueue()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueGetTasksetAddress()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueClear()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueDepth()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueGetEntrySize()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueSize()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursQueueGetDirection()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateJobChainWithAttribute()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateJobChain()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJoinJobChain()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursKickJobChain()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursJobChainAttributeInitialize()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetJobChainId()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainSetExceptionEventHandler()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainUnsetExceptionEventHandler()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetJobChainInfo()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainGetSpursAddress()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursCreateTaskset(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, u64 args, vm::ptr<const u8[8]> priority,
|
2014-12-12 21:12:09 +01:00
|
|
|
u32 max_contention, vm::ptr<const char> name, u32 size, s32 enable_clear_ls)
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs || !taskset)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned() || !taskset.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-13 19:52:31 +01:00
|
|
|
memset(taskset.get_ptr(), 0, size);
|
2014-12-10 05:42:13 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->spurs = spurs;
|
|
|
|
|
taskset->args = args;
|
|
|
|
|
taskset->enable_clear_ls = enable_clear_ls > 0 ? 1 : 0;
|
|
|
|
|
taskset->size = size;
|
2014-12-12 21:12:09 +01:00
|
|
|
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::var<CellSpursWorkloadAttribute> wkl_attr;
|
2015-02-02 21:43:32 +01:00
|
|
|
_cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::ptr<const void>::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/,
|
2014-12-12 21:12:09 +01:00
|
|
|
taskset.addr(), priority, 8 /*min_contention*/, max_contention);
|
|
|
|
|
// TODO: Check return code
|
|
|
|
|
|
2015-04-21 22:26:21 +02:00
|
|
|
cellSpursWorkloadAttributeSetName(wkl_attr, vm::null, name);
|
2014-12-12 21:12:09 +01:00
|
|
|
// TODO: Check return code
|
|
|
|
|
|
|
|
|
|
// TODO: cellSpursWorkloadAttributeSetShutdownCompletionEventHook(wkl_attr, hook, taskset);
|
|
|
|
|
// TODO: Check return code
|
|
|
|
|
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::var<be_t<u32>> wid;
|
2015-04-21 22:26:21 +02:00
|
|
|
cellSpursAddWorkloadWithAttribute(spurs, vm::ptr<u32>::make(wid.addr()), wkl_attr);
|
2014-12-12 21:12:09 +01:00
|
|
|
// TODO: Check return code
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->wkl_flag_wait_task = 0x80;
|
|
|
|
|
taskset->wid = wid.value();
|
2014-12-12 21:12:09 +01:00
|
|
|
// TODO: cellSpursSetExceptionEventHandler(spurs, wid, hook, taskset);
|
|
|
|
|
// TODO: Check return code
|
|
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTasksetWithAttribute(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, vm::ptr<CellSpursTasksetAttribute> attr)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
2015-04-10 13:14:33 +02:00
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
2014-12-10 05:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->revision != CELL_SPURS_TASKSET_ATTRIBUTE_REVISION)
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
auto rc = spursCreateTaskset(spurs, taskset, attr->args, vm::ptr<const u8[8]>::make(attr.addr() + offsetof(CellSpursTasksetAttribute, priority)),
|
|
|
|
|
attr->max_contention, vm::ptr<const char>::make(attr->name.addr()), attr->taskset_size, attr->enable_clear_ls);
|
2014-12-12 21:12:09 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (attr->taskset_size >= sizeof32(CellSpursTaskset2))
|
2014-12-12 21:12:09 +01:00
|
|
|
{
|
|
|
|
|
// TODO: Implement this
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
2014-08-21 11:56:02 +02:00
|
|
|
}
|
2014-06-02 07:42:30 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTaskset(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, u64 args, vm::ptr<const u8[8]> priority, u32 maxContention)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)",
|
2014-09-02 03:05:13 +02:00
|
|
|
spurs.addr(), taskset.addr(), args, priority.addr(), maxContention);
|
2014-06-04 20:52:30 +02:00
|
|
|
|
2015-04-21 22:26:21 +02:00
|
|
|
return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::null, 6400/*CellSpursTaskset::size*/, 0);
|
2014-03-30 22:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJoinTaskset(vm::ptr<CellSpursTaskset> taskset)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetTasksetId(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u32> wid)
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, wid=0x%x)", taskset.addr(), wid.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-13 19:52:31 +01:00
|
|
|
if (!taskset || !wid)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD)
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*wid = taskset->wid;
|
2014-03-07 22:31:08 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursShutdownTaskset(vm::ptr<CellSpursTaskset> taskset)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-03-30 22:09:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2014-12-13 22:49:06 +01:00
|
|
|
u32 _cellSpursGetSdkVersion()
|
|
|
|
|
{
|
2015-02-19 21:46:25 +01:00
|
|
|
// Commenting this out for now since process_get_sdk_version does not return
|
|
|
|
|
// the correct SDK version and instead returns a version too high for the game
|
|
|
|
|
// and causes SPURS to fail.
|
|
|
|
|
//s32 sdk_version;
|
|
|
|
|
|
|
|
|
|
//if (process_get_sdk_version(process_getpid(), sdk_version) != CELL_OK)
|
|
|
|
|
//{
|
|
|
|
|
// throw __FUNCTION__;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//return sdk_version;
|
|
|
|
|
return 1;
|
2014-12-13 22:49:06 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursCreateTask(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u32> task_id, vm::ptr<u32> elf_addr, vm::ptr<u32> context_addr, u32 context_size, vm::ptr<CellSpursTaskLsPattern> ls_pattern, vm::ptr<CellSpursTaskArgument> arg)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
|
|
|
|
if (!taskset || !elf_addr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (elf_addr % 16)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto sdk_version = _cellSpursGetSdkVersion();
|
|
|
|
|
if (sdk_version < 0x27FFFF)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (context_addr % 16)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (context_addr % 128)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 alloc_ls_blocks = 0;
|
|
|
|
|
if (context_addr.addr() != 0)
|
|
|
|
|
{
|
|
|
|
|
if (context_size < CELL_SPURS_TASK_EXECUTION_CONTEXT_SIZE)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alloc_ls_blocks = context_size > 0x3D400 ? 0x7A : ((context_size - 0x400) >> 11);
|
|
|
|
|
if (ls_pattern.addr() != 0)
|
|
|
|
|
{
|
2015-02-19 21:23:05 +01:00
|
|
|
u128 ls_pattern_128 = u128::from64r(ls_pattern->_u64[0], ls_pattern->_u64[1]);
|
2015-02-19 19:24:57 +01:00
|
|
|
u32 ls_blocks = 0;
|
2015-02-04 16:29:34 +01:00
|
|
|
for (auto i = 0; i < 128; i++)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
2015-02-19 19:24:57 +01:00
|
|
|
if (ls_pattern_128._bit[i])
|
2015-02-02 21:43:32 +01:00
|
|
|
{
|
|
|
|
|
ls_blocks++;
|
2014-12-13 22:49:06 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ls_blocks > alloc_ls_blocks)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-04 16:29:34 +01:00
|
|
|
u128 _0 = u128::from32(0);
|
2015-02-19 19:24:57 +01:00
|
|
|
if ((ls_pattern_128 & u128::from32r(0xFC000000)) != _0)
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
|
|
|
|
// Prevent save/restore to SPURS management area
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
alloc_ls_blocks = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Verify the ELF header is proper and all its load segments are at address >= 0x3000
|
|
|
|
|
|
|
|
|
|
u32 tmp_task_id;
|
|
|
|
|
for (tmp_task_id = 0; tmp_task_id < CELL_SPURS_MAX_TASK; tmp_task_id++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset->enabled.value()._bit[tmp_task_id])
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
auto enabled = taskset->enabled.value();
|
2015-02-02 21:43:32 +01:00
|
|
|
enabled._bit[tmp_task_id] = true;
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->enabled = enabled;
|
2014-12-13 22:49:06 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tmp_task_id >= CELL_SPURS_MAX_TASK)
|
|
|
|
|
{
|
2015-04-10 13:14:33 +02:00
|
|
|
return CELL_SPURS_TASK_ERROR_AGAIN;
|
2014-12-13 22:49:06 +01:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2015-02-04 16:29:34 +01:00
|
|
|
if (ls_pattern.addr())
|
2014-12-13 22:49:06 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->task_info[tmp_task_id].ls_pattern = *ls_pattern;
|
2014-12-13 22:49:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*task_id = tmp_task_id;
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursTaskStart(vm::ptr<CellSpursTaskset> taskset, u32 taskId)
|
2015-02-02 21:43:32 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
auto pendingReady = taskset->pending_ready.value();
|
2015-02-02 21:43:32 +01:00
|
|
|
pendingReady._bit[taskId] = true;
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->pending_ready = pendingReady;
|
2015-02-02 21:43:32 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid);
|
|
|
|
|
auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->spurs);
|
2015-02-02 21:43:32 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT)
|
|
|
|
|
{
|
|
|
|
|
rc = CELL_SPURS_TASK_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTask(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u32> taskId, u32 elf_addr, u32 context_addr, u32 context_size, vm::ptr<CellSpursTaskLsPattern> lsPattern,
|
2014-09-02 03:05:13 +02:00
|
|
|
vm::ptr<CellSpursTaskArgument> argument)
|
2014-03-30 22:09:49 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%d, lsPattern_addr=0x%x, argument_addr=0x%x)",
|
2015-02-02 21:43:32 +01:00
|
|
|
taskset.addr(), taskId.addr(), elf_addr, context_addr, context_size, lsPattern.addr(), argument.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2015-02-02 21:43:32 +01:00
|
|
|
if (!taskset)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2015-02-02 21:43:32 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-12 20:02:02 +01:00
|
|
|
vm::var<be_t<u32>> tmpTaskId;
|
2015-02-02 21:43:32 +01:00
|
|
|
auto rc = spursCreateTask(taskset, tmpTaskId, vm::ptr<u32>::make(elf_addr), vm::ptr<u32>::make(context_addr), context_size, lsPattern, argument);
|
2015-02-19 21:23:05 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-12 20:02:02 +01:00
|
|
|
rc = spursTaskStart(taskset, tmpTaskId->value());
|
2015-02-19 21:23:05 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*taskId = tmpTaskId;
|
|
|
|
|
return CELL_OK;
|
2014-03-30 22:09:49 +02:00
|
|
|
}
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursSendSignal(vm::ptr<CellSpursTaskset> taskset, u32 taskId)
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2015-01-20 20:17:20 +01:00
|
|
|
if (!taskset)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskId >= CELL_SPURS_MAX_TASK || taskset->wid >= CELL_SPURS_MAX_WORKLOAD2)
|
2015-01-20 20:17:20 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-01 21:02:40 +01:00
|
|
|
auto _0 = be_t<u128>::make(u128::from32(0));
|
2015-06-21 16:48:21 +02:00
|
|
|
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<u128>::make(~taskset->enabled.value())) != _0;
|
2015-01-20 20:17:20 +01:00
|
|
|
|
|
|
|
|
if (invalid)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_SRCH;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
auto shouldSignal = (taskset->waiting & be_t<u128>::make(~taskset->signalled.value()) & be_t<u128>::make(u128::fromBit(taskId))) != _0 ? true : false;
|
|
|
|
|
auto signalled = taskset->signalled.value();
|
2015-02-03 06:33:49 +01:00
|
|
|
signalled._bit[taskId] = true;
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->signalled = signalled;
|
2015-01-20 20:17:20 +01:00
|
|
|
if (shouldSignal)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid);
|
|
|
|
|
auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->spurs);
|
2015-01-20 20:17:20 +01:00
|
|
|
if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
2014-06-04 20:52:30 +02:00
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTaskWithAttribute()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetAttributeSetName(vm::ptr<CellSpursTasksetAttribute> attr, vm::ptr<const char> name)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr=0x%x, name=0x%x)", __FUNCTION__, attr.addr(), name.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
if (!attr || !name)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->name = name;
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr<CellSpursTasksetAttribute> attr, u32 size)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr=0x%x, size=0x%x)", __FUNCTION__, attr.addr(), size);
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (size != sizeof32(CellSpursTaskset) && size != sizeof32(CellSpursTaskset2))
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->taskset_size = size;
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr<CellSpursTasksetAttribute> attr, s32 enable)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attr=0x%x, enable=%d)", __FUNCTION__, attr.addr(), enable);
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attr->enable_clear_ls = enable ? 1 : 0;
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursTasksetAttribute2Initialize(vm::ptr<CellSpursTasksetAttribute2> attribute, u32 revision)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision);
|
2015-02-18 23:54:31 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
memset(attribute.get_ptr(), 0, sizeof(CellSpursTasksetAttribute2));
|
|
|
|
|
attribute->revision = revision;
|
|
|
|
|
attribute->name = vm::null;
|
|
|
|
|
attribute->args = 0;
|
2014-08-10 18:05:41 +02:00
|
|
|
|
2014-08-21 11:56:02 +02:00
|
|
|
for (s32 i = 0; i < 8; i++)
|
2014-08-10 18:05:41 +02:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
attribute->priority[i] = 1;
|
2014-08-10 18:05:41 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attribute->max_contention = 8;
|
|
|
|
|
attribute->enable_clear_ls = 0;
|
|
|
|
|
attribute->task_name_buffer.set(0);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskExitCodeGet()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskExitCodeInitialize()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskExitCodeTryGet()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskGetLoadableSegmentPattern()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskGetReadOnlyAreaPattern()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskGenerateLsPattern()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursTaskAttributeInitialize()
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskAttributeSetExitCodeContainer()
|
2014-06-04 20:52:30 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 20:52:30 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursTaskAttribute2Initialize(vm::ptr<CellSpursTaskAttribute2> attribute, u32 revision)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision);
|
2014-08-10 21:06:51 +02:00
|
|
|
|
|
|
|
|
attribute->revision = revision;
|
|
|
|
|
attribute->sizeContext = 0;
|
2015-01-02 16:29:57 +01:00
|
|
|
attribute->eaContext = 0;
|
2015-02-19 19:24:57 +01:00
|
|
|
|
2014-08-21 11:56:02 +02:00
|
|
|
for (s32 c = 0; c < 4; c++)
|
2014-08-10 21:06:51 +02:00
|
|
|
{
|
2015-02-19 19:24:57 +01:00
|
|
|
attribute->lsPattern._u32[c] = 0;
|
2014-08-10 21:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
attribute->name = vm::null;
|
2014-08-10 21:06:51 +02:00
|
|
|
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
2014-08-21 11:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTaskGetContextSaveAreaSize()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTaskset2(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset2> taskset, vm::ptr<CellSpursTasksetAttribute2> attr)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2015-01-22 22:31:46 +01:00
|
|
|
vm::ptr<CellSpursTasksetAttribute2> tmp_attr;
|
|
|
|
|
|
2014-12-12 21:12:09 +01:00
|
|
|
if (!attr)
|
|
|
|
|
{
|
2015-01-22 22:31:46 +01:00
|
|
|
attr.set(tmp_attr.addr());
|
2014-12-12 21:12:09 +01:00
|
|
|
_cellSpursTasksetAttribute2Initialize(attr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
auto rc = spursCreateTaskset(spurs, vm::ptr<CellSpursTaskset>::make(taskset.addr()), attr->args,
|
|
|
|
|
vm::ptr<const u8[8]>::make(attr.addr() + offsetof(CellSpursTasksetAttribute, priority)),
|
|
|
|
|
attr->max_contention, attr->name, sizeof32(CellSpursTaskset2), (u8)attr->enable_clear_ls);
|
|
|
|
|
|
2014-12-12 21:12:09 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attr->task_name_buffer.aligned())
|
2014-12-12 21:12:09 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Implement rest of the function
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTask2()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJoinTask2()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTryJoinTask2()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursDestroyTaskset2()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursCreateTask2WithBinInfo()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr<CellSpursTaskset> taskset, vm::ptr<u64> handler, vm::ptr<u64> arg)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(taskset=0x5x, handler=0x%x, arg=0x%x)", __FUNCTION__, taskset.addr(), handler.addr(), arg.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-13 19:52:31 +01:00
|
|
|
if (!taskset || !handler)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD)
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset->exception_handler)
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->exception_handler = handler;
|
|
|
|
|
taskset->exception_handler_arg = arg;
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr<CellSpursTaskset> taskset)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(taskset=0x%x)", __FUNCTION__, taskset.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-13 19:52:31 +01:00
|
|
|
if (!taskset)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD)
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
taskset->exception_handler.set(0);
|
|
|
|
|
taskset->exception_handler_arg.set(0);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursLookUpTasksetAddress(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset, u32 id)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, id=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), id);
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2015-01-23 20:11:29 +01:00
|
|
|
if (taskset.addr() == 0)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vm::var<be_t<u64>> data;
|
2015-04-21 22:26:21 +02:00
|
|
|
auto rc = cellSpursGetWorkloadData(spurs, data, id);
|
2015-01-23 20:11:29 +01:00
|
|
|
if (rc != CELL_OK)
|
|
|
|
|
{
|
|
|
|
|
// Convert policy module error code to a task error code
|
|
|
|
|
return rc ^ 0x100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
taskset.set((u32)data.value());
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTasksetGetSpursAddress(vm::ptr<const CellSpursTaskset> taskset, vm::ptr<u32> spurs)
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(taskset=0x%x, spurs=0x%x)", __FUNCTION__, taskset.addr(), spurs.addr());
|
2014-12-14 07:37:46 +01:00
|
|
|
|
2014-12-13 19:52:31 +01:00
|
|
|
if (!taskset || !spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!taskset.aligned())
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD)
|
2014-12-13 19:52:31 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
*spurs = (u32)taskset->spurs.addr();
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetTasksetInfo()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursTasksetAttributeInitialize(vm::ptr<CellSpursTasksetAttribute> attribute, u32 revision, u32 sdk_version, u64 args, vm::ptr<const u8> priority, u32 max_contention)
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2015-02-18 17:22:06 +01:00
|
|
|
cellSpurs.Warning("%s(attribute=0x%x, revision=%d, skd_version=%d, args=0x%llx, priority=0x%x, max_contention=%d)",
|
2014-12-14 07:37:46 +01:00
|
|
|
__FUNCTION__, attribute.addr(), revision, sdk_version, args, priority.addr(), max_contention);
|
|
|
|
|
|
2014-12-10 05:42:13 +01:00
|
|
|
if (!attribute)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!attribute.aligned())
|
2014-12-10 05:42:13 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
if (priority[i] > 0xF)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_TASK_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobGuardInitialize()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainAttributeSetName()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursShutdownJobChain()
|
2014-06-02 05:09:42 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-02 05:09:42 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainAttributeSetHaltOnError()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainAttributeSetJobTypeMemoryCheck()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobGuardNotify()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobGuardReset()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursRunJobChain()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobChainGetError()
|
2014-06-04 18:03:31 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-06-04 18:03:31 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursGetJobPipelineInfo()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobSetMaxGrab()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursJobHeaderSetJobbin2Param()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAddUrgentCommand()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursAddUrgentCall()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursBarrierInitialize()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursBarrierGetTasksetAddress()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 _cellSpursSemaphoreInitialize()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursSemaphoreGetTasksetAddress()
|
2014-08-21 11:56:02 +02:00
|
|
|
{
|
2014-08-27 15:11:34 +02:00
|
|
|
UNIMPLEMENTED_FUNC(cellSpurs);
|
2014-08-21 11:56:02 +02:00
|
|
|
return CELL_OK;
|
2014-06-02 05:09:42 +02:00
|
|
|
}
|
|
|
|
|
|
2014-12-31 21:21:22 +01:00
|
|
|
bool spursIsLibProfLoaded()
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void spursTraceStatusUpdate(vm::ptr<CellSpurs> spurs)
|
|
|
|
|
{
|
2015-03-04 05:42:04 +01:00
|
|
|
LV2_LOCK;
|
2014-12-31 21:21:22 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->xCC != 0)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->xCD = 1;
|
|
|
|
|
spurs->sysSrvMsgUpdateTrace = (1 << spurs->nSpus) - 1;
|
|
|
|
|
spurs->sysSrvMessage.write_relaxed(0xFF);
|
|
|
|
|
sys_semaphore_wait((u32)spurs->semPrv, 0);
|
2014-12-31 21:21:22 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursTraceInitialize(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTraceInfo> buffer, u32 size, u32 mode, u32 updateStatus)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs || !buffer)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned() || !buffer.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (size < sizeof32(CellSpursTraceInfo) || mode & ~(CELL_SPURS_TRACE_MODE_FLAG_MASK))
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_INVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (spurs->traceBuffer)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->traceDataSize = size - sizeof32(CellSpursTraceInfo);
|
2014-12-31 21:21:22 +01:00
|
|
|
for (u32 i = 0; i < 8; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
buffer->spu_thread[i] = spurs->spus[i];
|
2014-12-31 21:21:22 +01:00
|
|
|
buffer->count[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
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;
|
2014-12-31 21:21:22 +01:00
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
u32 spuTraceDataCount = (u32)((spurs->traceDataSize / sizeof32(CellSpursTracePacket)) / spurs->nSpus);
|
2014-12-31 21:21:22 +01:00
|
|
|
for (u32 i = 0, j = 8; i < 6; i++)
|
|
|
|
|
{
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->traceStartIndex[i] = j;
|
2014-12-31 21:21:22 +01:00
|
|
|
j += spuTraceDataCount;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvTraceControl = 0;
|
2014-12-31 21:21:22 +01:00
|
|
|
if (updateStatus)
|
|
|
|
|
{
|
|
|
|
|
spursTraceStatusUpdate(spurs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTraceInitialize(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTraceInfo> buffer, u32 size, u32 mode)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (spursIsLibProfLoaded())
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return spursTraceInitialize(spurs, buffer, size, mode, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursTraceStart(vm::ptr<CellSpurs> spurs, u32 updateStatus)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs->traceBuffer)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvTraceControl = 1;
|
2014-12-31 21:21:22 +01:00
|
|
|
if (updateStatus)
|
|
|
|
|
{
|
|
|
|
|
spursTraceStatusUpdate(spurs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTraceStart(vm::ptr<CellSpurs> spurs)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
return spursTraceStart(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP);
|
2014-12-31 21:21:22 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 spursTraceStop(vm::ptr<CellSpurs> spurs, u32 updateStatus)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs->traceBuffer)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvTraceControl = 2;
|
2014-12-31 21:21:22 +01:00
|
|
|
if (updateStatus)
|
|
|
|
|
{
|
|
|
|
|
spursTraceStatusUpdate(spurs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTraceStop(vm::ptr<CellSpurs> spurs)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
return spursTraceStop(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP);
|
2014-12-31 21:21:22 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-18 23:54:31 +01:00
|
|
|
s32 cellSpursTraceFinalize(vm::ptr<CellSpurs> spurs)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
if (!spurs)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs.aligned())
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
if (!spurs->traceBuffer)
|
2014-12-31 21:21:22 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SPURS_CORE_ERROR_STAT;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
spurs->sysSrvTraceControl = 0;
|
|
|
|
|
spurs->traceMode = 0;
|
|
|
|
|
spurs->traceBuffer.set(0);
|
2014-12-31 21:21:22 +01:00
|
|
|
spursTraceStatusUpdate(spurs);
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-18 17:22:06 +01:00
|
|
|
Module cellSpurs("cellSpurs", []()
|
2014-03-07 22:31:08 +01:00
|
|
|
{
|
2014-06-04 18:03:31 +02:00
|
|
|
// Core
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, cellSpursInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursFinalize);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursAttributeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttributeSetMemoryContainerForSpuThread);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttributeSetNamePrefix);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttributeEnableSpuPrintfIfAvailable);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttributeSetSpuThreadGroupType);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttributeEnableSystemWorkload);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetSpuThreadGroupId);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetNumSpuThread);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetSpuThreadId);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSetMaxContention);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSetPriorities);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSetPreemptionVictimHints);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAttachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursDetachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEnableExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSetGlobalExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursUnsetGlobalExceptionEventHandler);
|
2014-12-13 19:52:31 +01:00
|
|
|
REG_FUNC(cellSpurs, cellSpursSetExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursUnsetExceptionEventHandler);
|
2014-06-04 18:03:31 +02:00
|
|
|
|
|
|
|
|
// Event flag
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, _cellSpursEventFlagInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagAttachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagDetachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagWait);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagClear);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagSet);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagTryWait);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagGetDirection);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagGetClearMode);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursEventFlagGetTasksetAddress);
|
2014-03-07 22:31:08 +01:00
|
|
|
|
2014-06-04 18:03:31 +02:00
|
|
|
// Taskset
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTaskset);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTasksetWithAttribute);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursTasksetAttributeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursTasksetAttribute2Initialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetAttributeSetName);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetAttributeSetTasksetSize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetAttributeEnableClearLS);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJoinTaskset);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetTasksetId);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursShutdownTaskset);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTask);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTaskWithAttribute);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursTaskAttributeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursTaskAttribute2Initialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskAttributeSetExitCodeContainer);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskExitCodeGet);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskExitCodeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskExitCodeTryGet);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskGetLoadableSegmentPattern);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskGetReadOnlyAreaPattern);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskGenerateLsPattern);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTaskGetContextSaveAreaSize);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursSendSignal);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTaskset2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTask2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJoinTask2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTryJoinTask2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursDestroyTaskset2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateTask2WithBinInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursLookUpTasksetAddress);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetGetSpursAddress);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetTasksetInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetSetExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTasksetUnsetExceptionEventHandler);
|
2014-06-04 18:03:31 +02:00
|
|
|
|
|
|
|
|
// Job Chain
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateJobChain);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursCreateJobChainWithAttribute);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursShutdownJobChain);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJoinJobChain);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursKickJobChain);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursRunJobChain);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainGetError);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursJobChainAttributeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetName);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetHaltOnError);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetJobTypeMemoryCheck);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetJobChainId);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainSetExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainUnsetExceptionEventHandler);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetJobChainInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobChainGetSpursAddress);
|
2014-06-02 05:09:42 +02:00
|
|
|
|
2014-06-04 18:03:31 +02:00
|
|
|
// Job Guard
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, cellSpursJobGuardInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobGuardNotify);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobGuardReset);
|
2014-06-04 18:03:31 +02:00
|
|
|
|
2014-08-08 16:50:42 +02:00
|
|
|
// LFQueue
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, _cellSpursLFQueueInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursLFQueuePushBody);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursLFQueueAttachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursLFQueueDetachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursLFQueuePopBody);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursLFQueueGetTasksetAddress);
|
2014-08-08 16:50:42 +02:00
|
|
|
|
|
|
|
|
// Queue
|
2014-08-21 11:56:02 +02:00
|
|
|
REG_FUNC(cellSpurs, _cellSpursQueueInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueuePopBody);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueuePushBody);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueAttachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueDetachLv2EventQueue);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueGetTasksetAddress);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueClear);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueDepth);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueGetEntrySize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueSize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursQueueGetDirection);
|
|
|
|
|
|
|
|
|
|
// Workload
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursWorkloadAttributeSetName);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursWorkloadAttributeSetShutdownCompletionEventHook);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAddWorkloadWithAttribute);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAddWorkload);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursShutdownWorkload);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursWaitForWorkloadShutdown);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursRemoveWorkload);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursReadyCountStore);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetWorkloadFlag);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursWorkloadFlagReceiver);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursWorkloadAttributeInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSendWorkloadSignal);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetWorkloadData);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursReadyCountAdd);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursReadyCountCompareAndSwap);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursReadyCountSwap);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursRequestIdleSpu);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetWorkloadInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetSpuGuid);
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursWorkloadFlagReceiver2);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursGetJobPipelineInfo);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobSetMaxGrab);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursJobHeaderSetJobbin2Param);
|
|
|
|
|
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursWakeUp);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAddUrgentCommand);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursAddUrgentCall);
|
|
|
|
|
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursBarrierInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursBarrierGetTasksetAddress);
|
|
|
|
|
|
|
|
|
|
REG_FUNC(cellSpurs, _cellSpursSemaphoreInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursSemaphoreGetTasksetAddress);
|
|
|
|
|
|
2014-12-31 21:21:22 +01:00
|
|
|
// Trace
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTraceInitialize);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTraceStart);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTraceStop);
|
|
|
|
|
REG_FUNC(cellSpurs, cellSpursTraceFinalize);
|
2015-02-18 17:22:06 +01:00
|
|
|
});
|