Skip to content

Commit

Permalink
lv2: Do not lose r3 data on syscalls
Browse files Browse the repository at this point in the history
Allows to get the ID of the lv2 sync objects in the debugger by looking at r3's content.
  • Loading branch information
elad335 committed Mar 22, 2020
1 parent 2925465 commit 17adaf2
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 40 deletions.
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/Modules/sys_spinlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ error_code sys_spinlock_lock(ppu_thread& ppu, vm::ptr<atomic_be_t<u32>> lock)
}
}

return not_an_error(ppu.gpr[3]);
return CELL_OK;
}

s32 sys_spinlock_trylock(vm::ptr<atomic_be_t<u32>> lock)
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/Cell/PPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ class ppu_thread : public cpu_thread
cmd64 cmd_get(u32 index) { return cmd_queue[cmd_queue.peek() + index].load(); }

u64 start_time{0}; // Sleep start timepoint
u64 syscall_ec{0}; // Syscalls' custom data (usually an error code)
const char* current_function{}; // Current function name for diagnosis, optimized for speed.
const char* last_function{}; // Sticky copy of current_function, is not cleared on function return

Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_cond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
else
{
// Further function result
ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

std::lock_guard lock(cond->mutex->mutex);

Expand Down Expand Up @@ -269,7 +269,7 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
// TODO: Is EBUSY returned after reqeueing, on sys_cond_destroy?
cond->waiters--;

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;

// Own or requeue
if (cond->mutex->try_own(ppu, ppu.id))
Expand Down Expand Up @@ -299,5 +299,5 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
// Restore the recursive value
cond->mutex->lock_count = cond.ret;

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}
10 changes: 5 additions & 5 deletions rpcs3/Emu/Cell/lv2/sys_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
{
for (auto cpu : queue->sq)
{
static_cast<ppu_thread&>(*cpu).gpr[3] = CELL_ECANCELED;
static_cast<ppu_thread&>(*cpu).syscall_ec = CELL_ECANCELED;
queue->append(cpu);
}

Expand Down Expand Up @@ -239,7 +239,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e

sys_event.trace("sys_event_queue_receive(equeue_id=0x%x, *0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout);

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

const auto queue = idm::get<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
{
Expand Down Expand Up @@ -279,7 +279,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
return CELL_OK;
}

// If cancelled, gpr[3] will be non-zero. Other registers must contain event data.
// If cancelled, syscall_ec will be non-zero. Other registers must contain event data.
while (!ppu.state.test_and_reset(cpu_flag::signal))
{
if (ppu.is_stopped())
Expand All @@ -299,7 +299,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
continue;
}

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -309,7 +309,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_event_queue_drain(ppu_thread& ppu, u32 equeue_id)
Expand Down
17 changes: 9 additions & 8 deletions rpcs3/Emu/Cell/lv2/sys_event_flag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,14 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
sys_event_flag.trace("sys_event_flag_wait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x, timeout=0x%llx)", id, bitptn, mode, result, timeout);

// Fix function arguments for external access
ppu.gpr[3] = -1;
// TODO: Avoid using registers
ppu.syscall_ec = -1;
ppu.gpr[4] = bitptn;
ppu.gpr[5] = mode;
ppu.gpr[6] = 0;

// Always set result
if (result) *result = ppu.gpr[6];
if (result) *result = 0;

if (!lv2_event_flag::check_mode(mode))
{
Expand Down Expand Up @@ -179,7 +180,7 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
}

flag->waiters--;
ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
ppu.gpr[6] = flag->pattern;
break;
}
Expand All @@ -196,7 +197,7 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
}

if (result) *result = ppu.gpr[6];
return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_event_flag_trywait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm::ptr<u64> result)
Expand Down Expand Up @@ -284,12 +285,12 @@ error_code sys_event_flag_set(u32 id, u64 bitptn)

if (lv2_event_flag::check_pattern(value, pattern, mode, &ppu.gpr[6]))
{
ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;
count++;
}
else
{
ppu.gpr[3] = -1;
ppu.syscall_ec = -1;
}
}

Expand All @@ -306,7 +307,7 @@ error_code sys_event_flag_set(u32 id, u64 bitptn)
{
auto& ppu = static_cast<ppu_thread&>(*cpu);

if (ppu.gpr[3] == CELL_OK)
if (ppu.syscall_ec == CELL_OK)
{
flag->waiters--;
flag->append(cpu);
Expand Down Expand Up @@ -375,7 +376,7 @@ error_code sys_event_flag_cancel(ppu_thread& ppu, u32 id, vm::ptr<u32> num)
{
auto& ppu = static_cast<ppu_thread&>(*thread);

ppu.gpr[3] = CELL_ECANCELED;
ppu.syscall_ec = CELL_ECANCELED;
ppu.gpr[6] = pattern;

flag->waiters--;
Expand Down
10 changes: 5 additions & 5 deletions rpcs3/Emu/Cell/lv2/sys_lwcond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ error_code _sys_lwcond_signal(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id, u3

if (mode == 2)
{
static_cast<ppu_thread*>(result)->gpr[3] = CELL_EBUSY;
static_cast<ppu_thread*>(result)->syscall_ec = CELL_EBUSY;
}

if (mode == 1)
Expand Down Expand Up @@ -221,7 +221,7 @@ error_code _sys_lwcond_signal_all(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id

if (mode == 2)
{
static_cast<ppu_thread*>(cpu)->gpr[3] = CELL_EBUSY;
static_cast<ppu_thread*>(cpu)->syscall_ec = CELL_EBUSY;
}

if (mode == 1)
Expand Down Expand Up @@ -270,7 +270,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id

sys_lwcond.trace("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

std::shared_ptr<lv2_lwmutex> mutex;

Expand Down Expand Up @@ -333,7 +333,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id

cond->waiters--;

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -344,5 +344,5 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
}

// Return cause
return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}
12 changes: 6 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)

sys_lwmutex.trace("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

const auto mutex = idm::get<lv2_obj, lv2_lwmutex>(lwmutex_id, [&](lv2_lwmutex& mutex)
{
Expand All @@ -97,7 +97,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
{
if (old == (1 << 31))
{
ppu.gpr[3] = CELL_EBUSY;
ppu.syscall_ec = CELL_EBUSY;
}

return true;
Expand All @@ -115,7 +115,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)

if (mutex.ret)
{
return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

while (!ppu.state.test_and_reset(cpu_flag::signal))
Expand All @@ -137,7 +137,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
continue;
}

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -147,7 +147,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code _sys_lwmutex_trylock(ppu_thread& ppu, u32 lwmutex_id)
Expand Down Expand Up @@ -224,7 +224,7 @@ error_code _sys_lwmutex_unlock2(ppu_thread& ppu, u32 lwmutex_id)

if (const auto cpu = mutex.schedule<ppu_thread>(mutex.sq, mutex.protocol))
{
static_cast<ppu_thread*>(cpu)->gpr[3] = CELL_EBUSY;
static_cast<ppu_thread*>(cpu)->syscall_ec = CELL_EBUSY;
mutex.awake(cpu);
return;
}
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
return CELL_OK;
}

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

while (!ppu.state.test_and_reset(cpu_flag::signal))
{
Expand All @@ -172,7 +172,7 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
continue;
}

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -182,7 +182,7 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_mutex_trylock(ppu_thread& ppu, u32 mutex_id)
Expand Down
12 changes: 6 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_rwlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
return CELL_OK;
}

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

while (!ppu.state.test_and_reset(cpu_flag::signal))
{
Expand All @@ -147,7 +147,7 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
continue;
}

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -157,7 +157,7 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_rwlock_tryrlock(ppu_thread& ppu, u32 rw_lock_id)
Expand Down Expand Up @@ -323,7 +323,7 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
return CELL_EDEADLK;
}

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

while (!ppu.state.test_and_reset(cpu_flag::signal))
{
Expand Down Expand Up @@ -362,7 +362,7 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
lv2_obj::awake_all();
}

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -372,7 +372,7 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_rwlock_trywlock(ppu_thread& ppu, u32 rw_lock_id)
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
return CELL_OK;
}

ppu.gpr[3] = CELL_OK;
ppu.syscall_ec = CELL_OK;

while (!ppu.state.test_and_reset(cpu_flag::signal))
{
Expand Down Expand Up @@ -146,7 +146,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
}
});

ppu.gpr[3] = CELL_ETIMEDOUT;
ppu.syscall_ec = CELL_ETIMEDOUT;
break;
}
}
Expand All @@ -156,7 +156,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
}
}

return not_an_error(ppu.gpr[3]);
return not_an_error(ppu.syscall_ec);
}

error_code sys_semaphore_trywait(ppu_thread& ppu, u32 sem_id)
Expand Down

0 comments on commit 17adaf2

Please sign in to comment.