mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-02 19:13:36 +00:00
vm::var rewritten
This commit is contained in:
parent
9c8773252a
commit
fcd6b64f8f
@ -438,7 +438,7 @@ namespace vm
|
||||
}
|
||||
};
|
||||
|
||||
u32 stack_push(CPUThread& cpu, u32 size, u32 align, u32& old_pos);
|
||||
u32 stack_push(CPUThread& cpu, u32 size, u32 align_v, u32& old_pos);
|
||||
void stack_pop(CPUThread& cpu, u32 addr, u32 old_pos);
|
||||
}
|
||||
|
||||
|
@ -4,657 +4,123 @@ class CPUThread;
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename T>
|
||||
class var
|
||||
template<typename T> class page_alloc_t
|
||||
{
|
||||
u32 m_addr;
|
||||
u32 m_size;
|
||||
u32 m_align;
|
||||
T* m_ptr;
|
||||
|
||||
public:
|
||||
var(u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
: m_size(size)
|
||||
, m_align(align)
|
||||
{
|
||||
alloc();
|
||||
}
|
||||
|
||||
var(const var& r)
|
||||
: m_size(r.m_size)
|
||||
, m_align(r.m_align)
|
||||
{
|
||||
alloc();
|
||||
*m_ptr = *r.m_ptr;
|
||||
}
|
||||
|
||||
~var()
|
||||
{
|
||||
dealloc();
|
||||
}
|
||||
|
||||
void alloc()
|
||||
{
|
||||
m_addr = vm::alloc(size(), vm::main, std::max<u32>(m_align, 4096));
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
}
|
||||
|
||||
void dealloc()
|
||||
{
|
||||
if (m_addr)
|
||||
if (m_addr && !vm::dealloc(m_addr))
|
||||
{
|
||||
vm::dealloc(m_addr);
|
||||
m_addr = 0;
|
||||
m_ptr = vm::get_ptr<T>(0u);
|
||||
if (!std::uncaught_exception()) // don't throw during stack unwinding
|
||||
{
|
||||
throw EXCEPTION("Deallocation failed (addr=0x%x)", m_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static var make(u32 addr, u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
{
|
||||
var res;
|
||||
|
||||
res.m_addr = addr;
|
||||
res.m_size = size;
|
||||
res.m_align = align;
|
||||
res.m_ptr = vm::get_ptr<T>(addr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
T* operator -> ()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* operator -> () const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* get_ptr()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* get_ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& value()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
const T& value() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
u32 addr() const
|
||||
{
|
||||
return m_addr;
|
||||
}
|
||||
|
||||
u32 size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/*
|
||||
operator const ref<T>() const
|
||||
{
|
||||
return addr();
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename AT> operator _ptr_base<T, AT>() const
|
||||
{
|
||||
return _ptr_base<T, AT>::make(m_addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<const T, AT>() const
|
||||
{
|
||||
return _ptr_base<const T, AT>::make(m_addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<void, AT>() const
|
||||
{
|
||||
return _ptr_base<void, AT>::make(m_addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<const void, AT>() const
|
||||
{
|
||||
return _ptr_base<const void, AT>::make(m_addr);
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
operator const T&() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class var<T[]>
|
||||
{
|
||||
u32 m_addr;
|
||||
u32 m_count;
|
||||
u32 m_size;
|
||||
u32 m_align;
|
||||
T* m_ptr;
|
||||
|
||||
public:
|
||||
var(u32 count, u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
: m_count(count)
|
||||
, m_size(size)
|
||||
, m_align(align)
|
||||
page_alloc_t()
|
||||
: m_addr(0)
|
||||
{
|
||||
alloc();
|
||||
}
|
||||
|
||||
~var()
|
||||
page_alloc_t(vm::memory_location_t location, u32 count = 1)
|
||||
: m_addr(alloc(sizeof32(T) * count, location, std::max<u32>(alignof32(T), 4096)))
|
||||
{
|
||||
dealloc();
|
||||
}
|
||||
|
||||
var(const var& r)
|
||||
: m_size(r.m_size)
|
||||
, m_align(r.m_align)
|
||||
page_alloc_t(const page_alloc_t&) = delete;
|
||||
|
||||
page_alloc_t(page_alloc_t&& other)
|
||||
: m_addr(other.m_addr)
|
||||
{
|
||||
alloc();
|
||||
memcpy(m_ptr, r.m_ptr, size());
|
||||
other.m_addr = 0;
|
||||
}
|
||||
|
||||
void alloc()
|
||||
~page_alloc_t() noexcept(false) // allow exceptions
|
||||
{
|
||||
m_addr = vm::alloc(size(), vm::main, std::max<u32>(m_align, 4096));
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
this->dealloc();
|
||||
}
|
||||
|
||||
void dealloc()
|
||||
page_alloc_t& operator =(const page_alloc_t&) = delete;
|
||||
|
||||
page_alloc_t& operator =(page_alloc_t&& other)
|
||||
{
|
||||
if (m_addr)
|
||||
{
|
||||
vm::dealloc(m_addr);
|
||||
m_addr = 0;
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
std::swap(m_addr, other.m_addr);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
static var make(u32 addr, u32 count, u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
{
|
||||
var res;
|
||||
|
||||
res.m_addr = addr;
|
||||
res.m_count = count;
|
||||
res.m_size = size;
|
||||
res.m_align = align;
|
||||
res.m_ptr = vm::get_ptr<T>(addr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
T* begin()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* begin() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* end()
|
||||
{
|
||||
return m_ptr + count();
|
||||
}
|
||||
|
||||
const T* end() const
|
||||
{
|
||||
return m_ptr + count();
|
||||
}
|
||||
|
||||
T* operator -> ()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& get()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T& get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* operator -> () const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
uint addr() const
|
||||
u32 get_addr() const
|
||||
{
|
||||
return m_addr;
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return m_count * m_size;
|
||||
}
|
||||
|
||||
uint count() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
operator const T1() const
|
||||
{
|
||||
return T1(*m_ptr);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
operator T1()
|
||||
{
|
||||
return T1(*m_ptr);
|
||||
}
|
||||
|
||||
operator const T&() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
operator const T*() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
operator T*()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& operator [](int index)
|
||||
{
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
const T& operator [](int index) const
|
||||
{
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
T& at(uint index)
|
||||
{
|
||||
if (index >= count())
|
||||
throw std::out_of_range(std::to_string(index) + " >= " + count());
|
||||
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
const T& at(uint index) const
|
||||
{
|
||||
if (index >= count())
|
||||
throw std::out_of_range(std::to_string(index) + " >= " + count());
|
||||
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
T* ptr()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
operator const ptr<T>() const
|
||||
{
|
||||
return addr();
|
||||
}
|
||||
*/
|
||||
template<typename NT>
|
||||
NT* To(uint offset = 0)
|
||||
{
|
||||
return (NT*)(m_ptr + offset);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int _count>
|
||||
class var<T[_count]>
|
||||
|
||||
template<typename T> class stack_alloc_t
|
||||
{
|
||||
u32 m_addr;
|
||||
u32 m_size;
|
||||
u32 m_align;
|
||||
T* m_ptr;
|
||||
|
||||
public:
|
||||
var(u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
: m_size(size)
|
||||
, m_align(align)
|
||||
{
|
||||
alloc();
|
||||
}
|
||||
|
||||
~var()
|
||||
{
|
||||
dealloc();
|
||||
}
|
||||
|
||||
var(const var& r)
|
||||
: m_size(r.m_size)
|
||||
, m_align(r.m_align)
|
||||
{
|
||||
alloc();
|
||||
memcpy(m_ptr, r.m_ptr, size());
|
||||
}
|
||||
|
||||
void alloc()
|
||||
{
|
||||
m_addr = vm::alloc(size(), vm::main, std::max<u32>(m_align, 4096));
|
||||
m_ptr = vm::get_ptr<T>(m_addr);
|
||||
}
|
||||
|
||||
void dealloc()
|
||||
{
|
||||
if (m_addr)
|
||||
{
|
||||
vm::dealloc(m_addr);
|
||||
m_addr = 0;
|
||||
m_ptr = vm::get_ptr<T>(0u);
|
||||
}
|
||||
}
|
||||
|
||||
T* operator -> ()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* begin()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* begin() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* end()
|
||||
{
|
||||
return m_ptr + count();
|
||||
}
|
||||
|
||||
const T* end() const
|
||||
{
|
||||
return m_ptr + count();
|
||||
}
|
||||
|
||||
T& get()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T& get() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
const T* operator -> () const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
uint addr() const
|
||||
{
|
||||
return m_addr;
|
||||
}
|
||||
|
||||
force_inline uint count() const
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
uint size() const
|
||||
{
|
||||
return _count * m_size;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
operator const T1() const
|
||||
{
|
||||
return T1(*m_ptr);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
operator T1()
|
||||
{
|
||||
return T1(*m_ptr);
|
||||
}
|
||||
|
||||
operator const T&() const
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
operator const T*() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
operator T*()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& operator [](uint index)
|
||||
{
|
||||
assert(index < count());
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
const T& operator [](uint index) const
|
||||
{
|
||||
assert(index < count());
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
T& at(uint index)
|
||||
{
|
||||
if (index >= count())
|
||||
throw std::out_of_range(std::to_string(index) + " >= " + count());
|
||||
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
const T& at(uint index) const
|
||||
{
|
||||
if (index >= count())
|
||||
throw std::out_of_range(std::to_string(index) + " >= " + count());
|
||||
|
||||
return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index);
|
||||
}
|
||||
|
||||
/*
|
||||
operator const ptr<T>() const
|
||||
{
|
||||
return addr();
|
||||
}
|
||||
*/
|
||||
template<typename NT>
|
||||
NT* To(uint offset = 0)
|
||||
{
|
||||
return (NT*)(m_ptr + offset);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class stackvar
|
||||
{
|
||||
struct stack_allocation
|
||||
{
|
||||
T* ptr;
|
||||
u32 addr;
|
||||
u32 size;
|
||||
u32 align;
|
||||
u32 old_pos;
|
||||
|
||||
stack_allocation(CPUThread& CPU, u32 size, u32 align)
|
||||
: size(size)
|
||||
, align(align)
|
||||
{
|
||||
addr = stack_push(CPU, size, align, old_pos);
|
||||
ptr = vm::get_ptr<T>(addr);
|
||||
}
|
||||
|
||||
private:
|
||||
stack_allocation() = delete;
|
||||
stack_allocation(const stack_allocation&) = delete;
|
||||
stack_allocation(stack_allocation&&) = delete;
|
||||
stack_allocation& operator = (const stack_allocation&) = delete;
|
||||
stack_allocation& operator = (stack_allocation&&) = delete;
|
||||
|
||||
} const m_data;
|
||||
u32 m_old_pos;
|
||||
|
||||
CPUThread& m_thread;
|
||||
|
||||
public:
|
||||
stackvar(CPUThread& CPU, u32 size = sizeof32(T), u32 align = alignof32(T))
|
||||
: m_data(CPU, size, align)
|
||||
, m_thread(CPU)
|
||||
stack_alloc_t() = delete;
|
||||
|
||||
stack_alloc_t(CPUThread& thread, u32 count = 1)
|
||||
: m_thread(thread)
|
||||
{
|
||||
m_addr = vm::stack_push(thread, sizeof32(T) * count, alignof32(T), m_old_pos);
|
||||
}
|
||||
|
||||
stackvar(const stackvar& r)
|
||||
: m_data(r.m_thread, r.m_data.m_size, r.m_data.m_align)
|
||||
, m_thread(r.m_thread)
|
||||
~stack_alloc_t() noexcept(false) // allow exceptions
|
||||
{
|
||||
*m_data.ptr = *r.m_data.ptr;
|
||||
}
|
||||
|
||||
stackvar(stackvar&& r) = delete;
|
||||
|
||||
~stackvar() noexcept(false) // allow exceptions
|
||||
{
|
||||
if (!std::uncaught_exception()) // don't call during stack unwinding
|
||||
if (!std::uncaught_exception()) // don't call during stack unwinding (it's pointless anyway)
|
||||
{
|
||||
stack_pop(m_thread, m_data.addr, m_data.old_pos);
|
||||
vm::stack_pop(m_thread, m_addr, m_old_pos);
|
||||
}
|
||||
}
|
||||
|
||||
stackvar& operator = (const stackvar& r)
|
||||
{
|
||||
*m_data.ptr = *r.m_data.ptr;
|
||||
return *this;
|
||||
}
|
||||
stack_alloc_t(const stack_alloc_t&) = delete;
|
||||
|
||||
stackvar& operator = (stackvar&& r) = delete;
|
||||
stack_alloc_t(stack_alloc_t&&) = delete;
|
||||
|
||||
T* operator -> ()
|
||||
{
|
||||
return m_data.ptr;
|
||||
}
|
||||
stack_alloc_t& operator =(const stack_alloc_t&) = delete;
|
||||
|
||||
const T* operator -> () const
|
||||
{
|
||||
return m_data.ptr;
|
||||
}
|
||||
stack_alloc_t& operator =(stack_alloc_t&&) = delete;
|
||||
|
||||
T* get_ptr()
|
||||
u32 get_addr() const
|
||||
{
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
const T* get_ptr() const
|
||||
{
|
||||
return m_data.ptr;
|
||||
}
|
||||
|
||||
T& value()
|
||||
{
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
const T& value() const
|
||||
{
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
T& operator [](u32 index)
|
||||
{
|
||||
return m_data.ptr[index];
|
||||
}
|
||||
|
||||
const T& operator [](u32 index) const
|
||||
{
|
||||
return m_data.ptr[index];
|
||||
}
|
||||
|
||||
u32 addr() const
|
||||
{
|
||||
return m_data.addr;
|
||||
}
|
||||
|
||||
u32 size() const
|
||||
{
|
||||
return m_data.size;
|
||||
}
|
||||
|
||||
/*
|
||||
operator const ref<T>() const
|
||||
{
|
||||
return addr();
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename AT> operator _ptr_base<T, AT>() const
|
||||
{
|
||||
return _ptr_base<T, AT>::make(m_data.addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<const T, AT>() const
|
||||
{
|
||||
return _ptr_base<const T, AT>::make(m_data.addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<void, AT>() const
|
||||
{
|
||||
return _ptr_base<void, AT>::make(m_data.addr);
|
||||
}
|
||||
|
||||
template<typename AT> operator _ptr_base<const void, AT>() const
|
||||
{
|
||||
return _ptr_base<const void, AT>::make(m_data.addr);
|
||||
}
|
||||
|
||||
operator T&()
|
||||
{
|
||||
return *m_data.ptr;
|
||||
}
|
||||
|
||||
operator const T&() const
|
||||
{
|
||||
return *m_data.ptr;
|
||||
return m_addr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, template<typename> class A> class _var_base final : public _ptr_base<T>, private A<T>
|
||||
{
|
||||
using _ptr_base<T>::m_addr;
|
||||
|
||||
using allocator = A<T>;
|
||||
|
||||
public:
|
||||
template<typename... Args, typename = std::enable_if_t<std::is_constructible<A<T>, Args...>::value>> _var_base(Args&&... args)
|
||||
: allocator(std::forward<Args>(args)...)
|
||||
{
|
||||
m_addr = allocator::get_addr();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, template<typename> class A = vm::stack_alloc_t> using varl = _var_base<to_le_t<T>, A>;
|
||||
|
||||
template<typename T, template<typename> class A = vm::stack_alloc_t> using varb = _var_base<to_be_t<T>, A>;
|
||||
|
||||
namespace ps3
|
||||
{
|
||||
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varb<T, A>;
|
||||
}
|
||||
|
||||
namespace psv
|
||||
{
|
||||
template<typename T, template<typename> class A = vm::stack_alloc_t> using var = varl<T, A>;
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ s32 cellFontOpenFontset(PPUThread& ppu, vm::ptr<CellFontLibrary> library, vm::pt
|
||||
return CELL_FONT_ERROR_NO_SUPPORT_FONTSET;
|
||||
}
|
||||
|
||||
vm::stackvar<char> f(ppu, (u32)file.length() + 1, 1);
|
||||
const vm::var<char> f(ppu, (u32)file.length() + 1);
|
||||
memcpy(f.get_ptr(), file.c_str(), file.size() + 1);
|
||||
s32 ret = cellFontOpenFontFile(library, f, 0, 0, font); //TODO: Find the correct values of subNum, uniqueId
|
||||
font->origin = CELL_FONT_OPEN_FONTSET;
|
||||
|
@ -24,20 +24,20 @@ s32 cellFsOpen(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> a
|
||||
return sys_fs_open(path, flags, fd, flags & CELL_FS_O_CREAT ? CELL_FS_S_IRUSR | CELL_FS_S_IWUSR : 0, arg, size);
|
||||
}
|
||||
|
||||
s32 cellFsRead(PPUThread& CPU, u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
|
||||
s32 cellFsRead(PPUThread& ppu, u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
|
||||
{
|
||||
cellFs.Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
|
||||
|
||||
// call the syscall
|
||||
return sys_fs_read(fd, buf, nbytes, nread ? nread : vm::stackvar<be_t<u64>>(CPU));
|
||||
return sys_fs_read(fd, buf, nbytes, nread ? nread : vm::var<u64>(ppu));
|
||||
}
|
||||
|
||||
s32 cellFsWrite(PPUThread& CPU, u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
|
||||
s32 cellFsWrite(PPUThread& ppu, u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
|
||||
{
|
||||
cellFs.Log("cellFsWrite(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite);
|
||||
|
||||
// call the syscall
|
||||
return sys_fs_write(fd, buf, nbytes, nwrite ? nwrite : vm::stackvar<be_t<u64>>(CPU));
|
||||
return sys_fs_write(fd, buf, nbytes, nwrite ? nwrite : vm::var<u64>(ppu));
|
||||
}
|
||||
|
||||
s32 cellFsClose(u32 fd)
|
||||
@ -147,22 +147,22 @@ s32 cellFsFsync(u32 fd)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFsFGetBlockSize(PPUThread& CPU, u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
|
||||
s32 cellFsFGetBlockSize(PPUThread& ppu, u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
|
||||
{
|
||||
cellFs.Log("cellFsFGetBlockSize(fd=0x%x, sector_size=*0x%x, block_size=*0x%x)", fd, sector_size, block_size);
|
||||
|
||||
// call the syscall
|
||||
return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar<be_t<u64>>(CPU), vm::stackvar<be_t<u64>>(CPU)) : CELL_FS_EFAULT;
|
||||
return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::var<u64>(ppu), vm::var<u64>(ppu)) : CELL_FS_EFAULT;
|
||||
}
|
||||
|
||||
s32 cellFsGetBlockSize(PPUThread& CPU, vm::cptr<char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
|
||||
s32 cellFsGetBlockSize(PPUThread& ppu, vm::cptr<char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
|
||||
{
|
||||
cellFs.Warning("cellFsGetBlockSize(path=*0x%x, sector_size=*0x%x, block_size=*0x%x) -> sys_fs_get_block_size()", path, sector_size, block_size);
|
||||
|
||||
// TODO
|
||||
|
||||
// call the syscall
|
||||
return sys_fs_get_block_size(path, sector_size, block_size, vm::stackvar<be_t<u64>>(CPU));
|
||||
return sys_fs_get_block_size(path, sector_size, block_size, vm::var<u64>(ppu));
|
||||
}
|
||||
|
||||
s32 cellFsTruncate(vm::cptr<char> path, u64 size)
|
||||
@ -526,9 +526,9 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
|
||||
{
|
||||
const auto func = file->st_callback.exchange({}).func;
|
||||
|
||||
Emu.GetCallbackManager().Async([=](CPUThread& CPU)
|
||||
Emu.GetCallbackManager().Async([=](CPUThread& ppu)
|
||||
{
|
||||
func(static_cast<PPUThread&>(CPU), fd, available);
|
||||
func(static_cast<PPUThread&>(ppu), fd, available);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -824,7 +824,7 @@ s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFsSdataOpen(PPUThread& CPU, vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> arg, u64 size)
|
||||
s32 cellFsSdataOpen(PPUThread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> arg, u64 size)
|
||||
{
|
||||
cellFs.Log("cellFsSdataOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx)", path, flags, fd, arg, size);
|
||||
|
||||
@ -833,7 +833,7 @@ s32 cellFsSdataOpen(PPUThread& CPU, vm::cptr<char> path, s32 flags, vm::ptr<u32>
|
||||
return CELL_FS_EINVAL;
|
||||
}
|
||||
|
||||
return cellFsOpen(path, CELL_FS_O_RDONLY, fd, vm::stackvar<be_t<u64>>(CPU), 8);
|
||||
return cellFsOpen(path, CELL_FS_O_RDONLY, fd, vm::var<u64>(ppu), 8);
|
||||
|
||||
// Don't implement sdata decryption in this function, it should be done in sys_fs_open() syscall or somewhere else
|
||||
|
||||
@ -892,9 +892,9 @@ void fsAio(vm::ptr<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
|
||||
}
|
||||
|
||||
// should be executed directly by FS AIO thread
|
||||
Emu.GetCallbackManager().Async([=](CPUThread& CPU)
|
||||
Emu.GetCallbackManager().Async([=](CPUThread& ppu)
|
||||
{
|
||||
func(static_cast<PPUThread&>(CPU), aio, error, xid, result);
|
||||
func(static_cast<PPUThread&>(ppu), aio, error, xid, result);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ struct content_permission_t final
|
||||
}
|
||||
};
|
||||
|
||||
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
|
||||
s32 cellHddGameCheck(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
|
||||
{
|
||||
cellGame.Warning("cellHddGameCheck(version=%d, dirName=*0x%x, errDialog=%d, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
|
||||
@ -64,10 +64,20 @@ s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 er
|
||||
return CELL_HDDGAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
vm::stackvar<CellHddGameSystemFileParam> param(CPU);
|
||||
vm::stackvar<CellHddGameCBResult> result(CPU);
|
||||
vm::stackvar<CellHddGameStatGet> get(CPU);
|
||||
vm::stackvar<CellHddGameStatSet> set(CPU);
|
||||
struct _stack_t
|
||||
{
|
||||
CellHddGameSystemFileParam param;
|
||||
CellHddGameCBResult result;
|
||||
CellHddGameStatGet get;
|
||||
CellHddGameStatSet set;
|
||||
};
|
||||
|
||||
const vm::var<_stack_t> stack(ppu);
|
||||
|
||||
const auto param = stack.of(&_stack_t::param);
|
||||
const auto result = stack.of(&_stack_t::result);
|
||||
const auto get = stack.of(&_stack_t::get);
|
||||
const auto set = stack.of(&_stack_t::set);
|
||||
|
||||
get->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST;
|
||||
@ -366,7 +376,7 @@ s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||
s32 cellGameDataCheckCreate2(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||
{
|
||||
cellGame.Warning("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
|
||||
@ -395,11 +405,20 @@ s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName
|
||||
return CELL_GAMEDATA_ERROR_BROKEN;
|
||||
}
|
||||
|
||||
vm::stackvar<CellGameDataCBResult> cbResult(CPU);
|
||||
vm::stackvar<CellGameDataStatGet> cbGet(CPU);
|
||||
vm::stackvar<CellGameDataStatSet> cbSet(CPU);
|
||||
struct _stack_t
|
||||
{
|
||||
CellGameDataCBResult result;
|
||||
CellGameDataStatGet get;
|
||||
CellGameDataStatSet set;
|
||||
};
|
||||
|
||||
cbGet.value() = {};
|
||||
const vm::var<_stack_t> stack(ppu);
|
||||
|
||||
const auto cbResult = stack.of(&_stack_t::result);
|
||||
const auto cbGet = stack.of(&_stack_t::get);
|
||||
const auto cbSet = stack.of(&_stack_t::set);
|
||||
|
||||
*cbGet = {};
|
||||
|
||||
// TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||
cbGet->hddFreeSizeKB = 40000000; //40 GB
|
||||
@ -424,7 +443,7 @@ s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName
|
||||
strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE"));
|
||||
// TODO: write lang titles
|
||||
|
||||
funcStat(CPU, cbResult, cbGet, cbSet);
|
||||
funcStat(ppu, cbResult, cbGet, cbSet);
|
||||
|
||||
if (cbSet->setParam)
|
||||
{
|
||||
@ -463,12 +482,12 @@ s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr<char> dirName
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||
s32 cellGameDataCheckCreate(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||
{
|
||||
cellGame.Warning("cellGameDataCheckCreate(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
|
||||
// TODO: almost identical, the only difference is that this function will always calculate the size of game data
|
||||
return cellGameDataCheckCreate2(CPU, version, dirName, errDialog, funcStat, container);
|
||||
return cellGameDataCheckCreate2(ppu, version, dirName, errDialog, funcStat, container);
|
||||
}
|
||||
|
||||
s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CELL_GAME_PATH_MAX]> tmp_contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> tmp_usrdirPath)
|
||||
|
@ -162,9 +162,9 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
{
|
||||
const s32 status = g_msg_dialog->status;
|
||||
|
||||
Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32
|
||||
Emu.GetCallbackManager().Register([=](CPUThread& cpu) -> s32
|
||||
{
|
||||
callback(static_cast<PPUThread&>(CPU), status, userData);
|
||||
callback(static_cast<PPUThread&>(cpu), status, userData);
|
||||
return CELL_OK;
|
||||
});
|
||||
}
|
||||
@ -180,7 +180,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellMsgDialogOpenErrorCode(PPUThread& CPU, u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam)
|
||||
s32 cellMsgDialogOpenErrorCode(PPUThread& ppu, u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam)
|
||||
{
|
||||
cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", errorCode, callback, userData, extParam);
|
||||
|
||||
@ -254,9 +254,9 @@ s32 cellMsgDialogOpenErrorCode(PPUThread& CPU, u32 errorCode, vm::ptr<CellMsgDia
|
||||
|
||||
error.append(fmt::format("\n(%08x)", errorCode));
|
||||
|
||||
vm::stackvar<char> message(CPU, error.size() + 1);
|
||||
const vm::var<char> message(ppu, error.size() + 1);
|
||||
|
||||
memcpy(message.get_ptr(), error.c_str(), message.size());
|
||||
std::memcpy(message.get_ptr(), error.c_str(), error.size() + 1);
|
||||
|
||||
return cellMsgDialogOpen2(CELL_MSGDIALOG_DIALOG_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, message, callback, userData, extParam);
|
||||
}
|
||||
|
@ -711,7 +711,7 @@ void SetFlipHandler(vm::ptr<void(u32)> handler)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellRescSetDisplayMode(PPUThread& CPU, u32 displayMode)
|
||||
s32 cellRescSetDisplayMode(PPUThread& ppu, u32 displayMode)
|
||||
{
|
||||
cellResc.Warning("cellRescSetDisplayMode(displayMode=%d)", displayMode);
|
||||
|
||||
@ -762,7 +762,7 @@ s32 cellRescSetDisplayMode(PPUThread& CPU, u32 displayMode)
|
||||
else m_pCFragmentShader = m_pCFragmentShaderArray[RESC_SHADER_DEFAULT_BILINEAR];
|
||||
}*/
|
||||
|
||||
vm::stackvar<CellVideoOutConfiguration> videocfg(CPU);
|
||||
const vm::var<CellVideoOutConfiguration> videocfg(ppu);
|
||||
videocfg->resolutionId = RescBufferMode2SysutilResolutionId(s_rescInternalInstance->m_dstMode);
|
||||
videocfg->format = RescDstFormat2SysutilFormat(s_rescInternalInstance->m_pRescDsts->format );
|
||||
videocfg->aspect = CELL_VIDEO_OUT_ASPECT_AUTO;
|
||||
@ -980,7 +980,7 @@ s32 cellRescSetSrc(s32 idx, vm::ptr<CellRescSrc> src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 cellRescSetConvertAndFlip(PPUThread& CPU, vm::ptr<CellGcmContextData> cntxt, s32 idx)
|
||||
s32 cellRescSetConvertAndFlip(PPUThread& ppu, vm::ptr<CellGcmContextData> cntxt, s32 idx)
|
||||
{
|
||||
cellResc.Log("cellRescSetConvertAndFlip(cntxt=*0x%x, idx=0x%x)", cntxt, idx);
|
||||
|
||||
@ -1013,7 +1013,7 @@ s32 cellRescSetConvertAndFlip(PPUThread& CPU, vm::ptr<CellGcmContextData> cntxt,
|
||||
|
||||
//TODO: ?
|
||||
|
||||
cellGcmSetPrepareFlip(CPU, cntxt, idx);
|
||||
cellGcmSetPrepareFlip(ppu, cntxt, idx);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -1027,7 +1027,7 @@ s32 cellRescSetWaitFlip()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRescSetBufferAddress(PPUThread& CPU, vm::ptr<u32> colorBuffers, vm::ptr<u32> vertexArray, vm::ptr<u32> fragmentShader)
|
||||
s32 cellRescSetBufferAddress(PPUThread& ppu, vm::ptr<u32> colorBuffers, vm::ptr<u32> vertexArray, vm::ptr<u32> fragmentShader)
|
||||
{
|
||||
cellResc.Warning("cellRescSetBufferAddress(colorBuffers=*0x%x, vertexArray=*0x%x, fragmentShader=*0x%x)", colorBuffers, vertexArray, fragmentShader);
|
||||
|
||||
@ -1047,12 +1047,12 @@ s32 cellRescSetBufferAddress(PPUThread& CPU, vm::ptr<u32> colorBuffers, vm::ptr<
|
||||
s_rescInternalInstance->m_vertexArrayEA = vertexArray.addr();
|
||||
s_rescInternalInstance->m_fragmentUcodeEA = fragmentShader.addr();
|
||||
|
||||
vm::stackvar<be_t<u32>> dstOffset(CPU);
|
||||
const vm::var<u32> dstOffset(ppu);
|
||||
cellGcmAddressToOffset(s_rescInternalInstance->m_colorBuffersEA, dstOffset);
|
||||
|
||||
for (s32 i=0; i<GetNumColorBuffers(); i++)
|
||||
{
|
||||
s_rescInternalInstance->m_dstOffsets[i] = dstOffset.value() + i * s_rescInternalInstance->m_dstBufInterval;
|
||||
s_rescInternalInstance->m_dstOffsets[i] = *dstOffset + i * s_rescInternalInstance->m_dstBufInterval;
|
||||
}
|
||||
|
||||
for (s32 i=0; i<GetNumColorBuffers(); i++)
|
||||
|
@ -53,11 +53,32 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
return CELL_SAVEDATA_ERROR_BUSY;
|
||||
}
|
||||
|
||||
struct _stack_t
|
||||
{
|
||||
CellSaveDataCBResult result;
|
||||
CellSaveDataListGet listGet;
|
||||
CellSaveDataListSet listSet;
|
||||
CellSaveDataFixedSet fixedSet;
|
||||
CellSaveDataStatGet statGet;
|
||||
CellSaveDataStatSet statSet;
|
||||
CellSaveDataFileGet fileGet;
|
||||
CellSaveDataFileSet fileSet;
|
||||
};
|
||||
|
||||
const vm::var<_stack_t> stack(ppu);
|
||||
|
||||
const auto result = stack.of(&_stack_t::result);
|
||||
const auto listGet = stack.of(&_stack_t::listGet);
|
||||
const auto listSet = stack.of(&_stack_t::listSet);
|
||||
const auto fixedSet = stack.of(&_stack_t::fixedSet);
|
||||
const auto statGet = stack.of(&_stack_t::statGet);
|
||||
const auto statSet = stack.of(&_stack_t::statSet);
|
||||
const auto fileGet = stack.of(&_stack_t::fileGet);
|
||||
const auto fileSet = stack.of(&_stack_t::fileSet);
|
||||
|
||||
// path of the specified user (00000001 by default)
|
||||
const std::string base_dir = fmt::format("/dev_hdd0/home/%08d/savedata/", userId ? userId : 1u);
|
||||
|
||||
vm::stackvar<CellSaveDataCBResult> result(ppu);
|
||||
|
||||
result->userdata = userdata; // probably should be assigned only once (allows the callback to change it)
|
||||
|
||||
SaveDataEntry save_entry;
|
||||
@ -66,8 +87,6 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
{
|
||||
std::vector<SaveDataEntry> save_entries;
|
||||
|
||||
vm::stackvar<CellSaveDataListGet> listGet(ppu);
|
||||
|
||||
listGet->dirNum = 0;
|
||||
listGet->dirListNum = 0;
|
||||
listGet->dirList.set(setBuf->buf.addr());
|
||||
@ -177,8 +196,6 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
|
||||
if (funcList)
|
||||
{
|
||||
vm::stackvar<CellSaveDataListSet> listSet(ppu);
|
||||
|
||||
// List Callback
|
||||
funcList(ppu, result, listGet, listSet);
|
||||
|
||||
@ -289,8 +306,6 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
|
||||
if (funcFixed)
|
||||
{
|
||||
vm::stackvar<CellSaveDataFixedSet> fixedSet(ppu);
|
||||
|
||||
// Fixed Callback
|
||||
funcFixed(ppu, result, listGet, fixedSet);
|
||||
|
||||
@ -346,9 +361,6 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
|
||||
// Get save stats
|
||||
{
|
||||
vm::stackvar<CellSaveDataStatGet> statGet(ppu);
|
||||
vm::stackvar<CellSaveDataStatSet> statSet(ppu);
|
||||
|
||||
std::string dir_local_path;
|
||||
|
||||
Emu.GetVFS().GetDevice(dir_path, dir_local_path);
|
||||
@ -488,8 +500,6 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt
|
||||
}
|
||||
|
||||
// Enter the loop where the save files are read/created/deleted
|
||||
vm::stackvar<CellSaveDataFileGet> fileGet(ppu);
|
||||
vm::stackvar<CellSaveDataFileSet> fileSet(ppu);
|
||||
|
||||
fileGet->excSize = 0;
|
||||
memset(fileGet->reserved, 0, sizeof(fileGet->reserved));
|
||||
|
@ -283,7 +283,7 @@ bool spursIsLibProfLoaded()
|
||||
/// Create an LV2 event queue and attach it to the SPURS instance
|
||||
s32 spursCreateLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::ptr<u32> queueId, vm::ptr<u8> port, s32 size, vm::cptr<char> name)
|
||||
{
|
||||
vm::stackvar<sys_event_queue_attribute_t> attr(ppu);
|
||||
const vm::var<sys_event_queue_attribute_t> attr(ppu);
|
||||
|
||||
auto sys_event_queue_attribute_initialize = [](vm::ptr<sys_event_queue_attribute_t> attr)
|
||||
{
|
||||
@ -294,18 +294,17 @@ s32 spursCreateLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::ptr<u
|
||||
|
||||
sys_event_queue_attribute_initialize(attr);
|
||||
std::memcpy(attr->name, name.get_ptr(), sizeof(attr->name));
|
||||
|
||||
if (s32 rc = sys_event_queue_create(queueId, attr, SYS_EVENT_QUEUE_LOCAL, size))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
vm::stackvar<u8> _port(ppu);
|
||||
if (s32 rc = spursAttachLv2EventQueue(ppu, spurs, *queueId, _port, 1 /*isDynamic*/, true /*spursCreated*/))
|
||||
if (s32 rc = spursAttachLv2EventQueue(ppu, spurs, *queueId, port, 1 /*isDynamic*/, true /*spursCreated*/))
|
||||
{
|
||||
sys_event_queue_destroy(*queueId, SYS_EVENT_QUEUE_DESTROY_FORCE);
|
||||
}
|
||||
|
||||
*port = _port;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -350,8 +349,7 @@ s32 spursAttachLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpurs> spurs, u32 queue
|
||||
portMask |= 1ull << (i);
|
||||
}
|
||||
|
||||
vm::stackvar<u8> connectedPort(ppu);
|
||||
if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, portMask, connectedPort))
|
||||
if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, portMask, port))
|
||||
{
|
||||
if (res == CELL_EISCONN)
|
||||
{
|
||||
@ -361,10 +359,9 @@ s32 spursAttachLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpurs> spurs, u32 queue
|
||||
return res;
|
||||
}
|
||||
|
||||
*port = connectedPort;
|
||||
if (!spursCreated)
|
||||
{
|
||||
spurs->spuPortBits |= 1ull << connectedPort;
|
||||
spurs->spuPortBits |= 1ull << *port;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -633,10 +630,8 @@ void spursEventHelperEntry(PPUThread& ppu)
|
||||
|
||||
bool terminate = false;
|
||||
|
||||
vm::stackvar<sys_event_t> eventArray(ppu, sizeof32(sys_event_t) * 8);
|
||||
vm::stackvar<be_t<u32>> count(ppu);
|
||||
|
||||
vm::ptr<sys_event_t> events = eventArray;
|
||||
const vm::var<sys_event_t> events(ppu, 8);
|
||||
const vm::var<u32> count(ppu);
|
||||
|
||||
while (!terminate)
|
||||
{
|
||||
@ -731,7 +726,7 @@ void spursEventHelperEntry(PPUThread& ppu)
|
||||
/// Create the SPURS event helper thread
|
||||
s32 spursCreateSpursEventHelper(PPUThread& ppu, vm::ptr<CellSpurs> spurs, u32 ppuPriority)
|
||||
{
|
||||
vm::stackvar<char> evqName(ppu, 8);
|
||||
const vm::var<char> evqName(ppu, 8);
|
||||
memcpy(evqName.get_ptr(), "_spuPrv", 8);
|
||||
|
||||
if (s32 rc = spursCreateLv2EventQueue(ppu, spurs, spurs.of(&CellSpurs::eventQueue), spurs.of(&CellSpurs::spuPort), 0x2A /*size*/, evqName))
|
||||
@ -855,7 +850,7 @@ s32 spursStopEventHelper(PPUThread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
|
||||
if (sys_ppu_thread_join(ppu, (u32)spurs->ppu1, vm::stackvar<be_t<u64>>(ppu)) != CELL_OK)
|
||||
if (sys_ppu_thread_join(ppu, (u32)spurs->ppu1, vm::var<u64>(ppu)) != CELL_OK)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
@ -914,7 +909,7 @@ s32 spursJoinHandlerThread(PPUThread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
|
||||
if (s32 rc = sys_ppu_thread_join(ppu, (u32)spurs->ppu0, vm::stackvar<be_t<u64>>(ppu)))
|
||||
if (s32 rc = sys_ppu_thread_join(ppu, (u32)spurs->ppu0, vm::var<u64>(ppu)))
|
||||
{
|
||||
throw EXCEPTION("sys_ppu_thread_join() failed (0x%x)", rc);
|
||||
}
|
||||
@ -940,17 +935,17 @@ s32 spursInit(
|
||||
u32 swlMaxSpu,
|
||||
u32 swlIsPreem)
|
||||
{
|
||||
vm::stackvar<be_t<u32>> sem(ppu);
|
||||
vm::stackvar<sys_semaphore_attribute_t> semAttr(ppu);
|
||||
vm::stackvar<sys_lwcond_attribute_t> lwCondAttr(ppu);
|
||||
vm::stackvar<sys_lwmutex_attribute_t> lwMutexAttr(ppu);
|
||||
vm::stackvar<be_t<u32>> spuTgId(ppu);
|
||||
vm::stackvar<char> spuTgName(ppu, 128);
|
||||
vm::stackvar<sys_spu_thread_group_attribute> spuTgAttr(ppu);
|
||||
vm::stackvar<sys_spu_thread_argument> spuThArgs(ppu);
|
||||
vm::stackvar<be_t<u32>> spuThreadId(ppu);
|
||||
vm::stackvar<sys_spu_thread_attribute> spuThAttr(ppu);
|
||||
vm::stackvar<char> spuThName(ppu, 128);
|
||||
vm::var<u32> sem(ppu);
|
||||
vm::var<sys_semaphore_attribute_t> semAttr(ppu);
|
||||
vm::var<sys_lwcond_attribute_t> lwCondAttr(ppu);
|
||||
vm::var<sys_lwmutex_attribute_t> lwMutexAttr(ppu);
|
||||
vm::var<u32> spuTgId(ppu);
|
||||
vm::var<char> spuTgName(ppu, 128);
|
||||
vm::var<sys_spu_thread_group_attribute> spuTgAttr(ppu);
|
||||
vm::var<sys_spu_thread_argument> spuThArgs(ppu);
|
||||
vm::var<u32> spuThreadId(ppu);
|
||||
vm::var<sys_spu_thread_attribute> spuThAttr(ppu);
|
||||
vm::var<char> spuThName(ppu, 128);
|
||||
|
||||
if (!spurs)
|
||||
{
|
||||
@ -1047,7 +1042,7 @@ s32 spursInit(
|
||||
return rollback(), rc;
|
||||
}
|
||||
|
||||
spurs->wklF1[i].sem = sem.value();
|
||||
spurs->wklF1[i].sem = *sem;
|
||||
|
||||
if (isSecond)
|
||||
{
|
||||
@ -1056,7 +1051,7 @@ s32 spursInit(
|
||||
return rollback(), rc;
|
||||
}
|
||||
|
||||
spurs->wklF2[i].sem = sem.value();
|
||||
spurs->wklF2[i].sem = *sem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1068,7 +1063,7 @@ s32 spursInit(
|
||||
return rollback(), rc;
|
||||
}
|
||||
|
||||
spurs->semPrv = sem.value();
|
||||
spurs->semPrv = *sem;
|
||||
|
||||
spurs->unk11 = -1;
|
||||
spurs->unk12 = -1;
|
||||
@ -1128,7 +1123,7 @@ s32 spursInit(
|
||||
return rollback(), rc;
|
||||
}
|
||||
|
||||
spurs->spuTG = spuTgId.value();
|
||||
spurs->spuTG = *spuTgId;
|
||||
|
||||
// Initialise all SPUs in the SPU thread group
|
||||
memcpy(spuThName.get_ptr(), spurs->prefix, spurs->prefixSize);
|
||||
@ -1153,7 +1148,7 @@ s32 spursInit(
|
||||
return rollback(), rc;
|
||||
}
|
||||
|
||||
const auto spuThread = idm::get<SPUThread>(spurs->spus[num] = spuThreadId.value());
|
||||
const auto spuThread = idm::get<SPUThread>(spurs->spus[num] = *spuThreadId);
|
||||
|
||||
// entry point cannot be initialized immediately because SPU LS will be rewritten by sys_spu_thread_group_start()
|
||||
spuThread->custom_task = [spurs](SPUThread& spu)
|
||||
@ -2874,7 +2869,7 @@ s32 cellSpursEventFlagSet(PPUThread& ppu, vm::ptr<CellSpursEventFlag> eventFlag,
|
||||
if (pendingRecv & (0x8000 >> i))
|
||||
{
|
||||
eventFlag->pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i];
|
||||
vm::stackvar<vm::bptr<CellSpursTaskset>> taskset(ppu);
|
||||
const vm::var<vm::ptr<CellSpursTaskset>> taskset(ppu);
|
||||
if (eventFlag->isIwl)
|
||||
{
|
||||
cellSpursLookUpTasksetAddress(ppu, vm::ptr<CellSpurs>::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]);
|
||||
@ -2884,7 +2879,7 @@ s32 cellSpursEventFlagSet(PPUThread& ppu, vm::ptr<CellSpursEventFlag> eventFlag,
|
||||
taskset->set((u32)eventFlag->addr);
|
||||
}
|
||||
|
||||
auto rc = _cellSpursSendSignal(ppu, taskset.value(), eventFlag->waitingTaskId[i]);
|
||||
auto rc = _cellSpursSendSignal(ppu, *taskset, eventFlag->waitingTaskId[i]);
|
||||
if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT)
|
||||
{
|
||||
return CELL_SPURS_TASK_ERROR_FATAL;
|
||||
@ -3111,9 +3106,9 @@ s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpursEvent
|
||||
spurs = taskset->spurs;
|
||||
}
|
||||
|
||||
vm::stackvar<be_t<u32>> eventQueueId(ppu);
|
||||
vm::stackvar<u8> port(ppu);
|
||||
vm::stackvar<char> evqName(ppu, 8);
|
||||
vm::var<u32> eventQueueId(ppu);
|
||||
vm::var<u8> port(ppu);
|
||||
vm::var<char> evqName(ppu, 8);
|
||||
memcpy(evqName.get_ptr(), "_spuEvF", 8);
|
||||
|
||||
auto failure = [](s32 rc) -> s32
|
||||
@ -3129,30 +3124,30 @@ s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& ppu, vm::ptr<CellSpursEvent
|
||||
|
||||
auto success = [&]
|
||||
{
|
||||
eventFlag->eventQueueId = eventQueueId;
|
||||
eventFlag->spuPort = port;
|
||||
eventFlag->eventQueueId = *eventQueueId;
|
||||
eventFlag->spuPort = *port;
|
||||
};
|
||||
|
||||
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
|
||||
{
|
||||
vm::stackvar<be_t<u32>> eventPortId(ppu);
|
||||
vm::var<u32> eventPortId(ppu);
|
||||
|
||||
s32 rc = sys_event_port_create(eventPortId, SYS_EVENT_PORT_LOCAL, 0);
|
||||
if (rc == CELL_OK)
|
||||
{
|
||||
rc = sys_event_port_connect_local(eventPortId.value(), eventQueueId.value());
|
||||
rc = sys_event_port_connect_local(*eventPortId, *eventQueueId);
|
||||
if (rc == CELL_OK)
|
||||
{
|
||||
eventFlag->eventPortId = eventPortId;
|
||||
eventFlag->eventPortId = *eventPortId;
|
||||
return success(), CELL_OK;
|
||||
}
|
||||
|
||||
sys_event_port_destroy(eventPortId.value());
|
||||
sys_event_port_destroy(*eventPortId);
|
||||
}
|
||||
|
||||
if (spursDetachLv2EventQueue(spurs, port, true /*spursCreated*/) == CELL_OK)
|
||||
if (spursDetachLv2EventQueue(spurs, *port, true /*spursCreated*/) == CELL_OK)
|
||||
{
|
||||
sys_event_queue_destroy(eventQueueId.value(), SYS_EVENT_QUEUE_DESTROY_FORCE);
|
||||
sys_event_queue_destroy(*eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE);
|
||||
}
|
||||
|
||||
return failure(rc);
|
||||
@ -3401,7 +3396,7 @@ s32 spursCreateTaskset(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::ptr<CellSpu
|
||||
taskset->enable_clear_ls = enable_clear_ls > 0 ? 1 : 0;
|
||||
taskset->size = size;
|
||||
|
||||
vm::stackvar<CellSpursWorkloadAttribute> wkl_attr(ppu);
|
||||
const vm::var<CellSpursWorkloadAttribute> wkl_attr(ppu);
|
||||
_cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::cptr<void>::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/,
|
||||
taskset.addr(), priority, 8 /*min_contention*/, max_contention);
|
||||
// TODO: Check return code
|
||||
@ -3412,12 +3407,12 @@ s32 spursCreateTaskset(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::ptr<CellSpu
|
||||
// TODO: cellSpursWorkloadAttributeSetShutdownCompletionEventHook(wkl_attr, hook, taskset);
|
||||
// TODO: Check return code
|
||||
|
||||
vm::stackvar<be_t<u32>> wid(ppu);
|
||||
vm::var<u32> wid(ppu);
|
||||
cellSpursAddWorkloadWithAttribute(spurs, wid, wkl_attr);
|
||||
// TODO: Check return code
|
||||
|
||||
taskset->wkl_flag_wait_task = 0x80;
|
||||
taskset->wid = wid.value();
|
||||
taskset->wid = *wid;
|
||||
// TODO: cellSpursSetExceptionEventHandler(spurs, wid, hook, taskset);
|
||||
// TODO: Check return code
|
||||
|
||||
@ -3632,20 +3627,18 @@ s32 cellSpursCreateTask(PPUThread& ppu, vm::ptr<CellSpursTaskset> taskset, vm::p
|
||||
return CELL_SPURS_TASK_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
vm::stackvar<be_t<u32>> tmpTaskId(ppu);
|
||||
auto rc = spursCreateTask(taskset, tmpTaskId, elf, context, size, lsPattern, argument);
|
||||
auto rc = spursCreateTask(taskset, taskId, elf, context, size, lsPattern, argument);
|
||||
if (rc != CELL_OK)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = spursTaskStart(ppu, taskset, tmpTaskId.value());
|
||||
rc = spursTaskStart(ppu, taskset, *taskId);
|
||||
if (rc != CELL_OK)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
*taskId = tmpTaskId;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -3859,7 +3852,7 @@ s32 cellSpursCreateTaskset2(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::ptr<Ce
|
||||
{
|
||||
cellSpurs.Warning("cellSpursCreateTaskset2(spurs=*0x%x, taskset=*0x%x, attr=*0x%x)", spurs, taskset, attr);
|
||||
|
||||
vm::stackvar<CellSpursTasksetAttribute2> tmp_attr(ppu);
|
||||
const vm::var<CellSpursTasksetAttribute2> tmp_attr(ppu);
|
||||
|
||||
if (!attr)
|
||||
{
|
||||
@ -3973,14 +3966,14 @@ s32 cellSpursLookUpTasksetAddress(PPUThread& ppu, vm::ptr<CellSpurs> spurs, vm::
|
||||
return CELL_SPURS_TASK_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
vm::stackvar<be_t<u64>> data(ppu);
|
||||
vm::var<u64> data(ppu);
|
||||
if (s32 rc = cellSpursGetWorkloadData(spurs, data, id))
|
||||
{
|
||||
// Convert policy module error code to a task error code
|
||||
return rc ^ 0x100;
|
||||
}
|
||||
|
||||
taskset->set((u32)data.value());
|
||||
taskset->set((u32)*data);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue, vm:
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
vm::stackvar<be_t<s32>> position(ppu);
|
||||
const vm::var<s32> position(ppu);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -1096,7 +1096,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue, vm:
|
||||
|
||||
const s32 depth = queue->m_depth;
|
||||
const s32 size = queue->m_size;
|
||||
const s32 pos = position.value();
|
||||
const s32 pos = *position;
|
||||
const u32 addr = VM_CAST((u64)((queue->m_buffer.addr() & ~1ull) + size * (pos >= depth ? pos - depth : pos)));
|
||||
std::memcpy(vm::get_ptr<void>(addr), buffer.get_ptr(), size);
|
||||
|
||||
@ -1373,7 +1373,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue, vm::
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
vm::stackvar<be_t<s32>> position(ppu);
|
||||
const vm::var<s32> position(ppu);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -1402,7 +1402,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> queue, vm::
|
||||
|
||||
const s32 depth = queue->m_depth;
|
||||
const s32 size = queue->m_size;
|
||||
const s32 pos = position.value();
|
||||
const s32 pos = *position;
|
||||
const u32 addr = VM_CAST((u64)((queue->m_buffer.addr() & ~1) + size * (pos >= depth ? pos - depth : pos)));
|
||||
std::memcpy(buffer.get_ptr(), vm::get_ptr<void>(addr), size);
|
||||
|
||||
|
@ -213,7 +213,7 @@ void vdecOpen(u32 vdec_id) // TODO: call from the constructor
|
||||
vdec.vdecCb = idm::make_ptr<PPUThread>(fmt::format("VideoDecoder[0x%x] Thread", vdec_id));
|
||||
vdec.vdecCb->prio = 1001;
|
||||
vdec.vdecCb->stack_size = 0x10000;
|
||||
vdec.vdecCb->custom_task = [sptr](PPUThread& CPU)
|
||||
vdec.vdecCb->custom_task = [sptr](PPUThread& ppu)
|
||||
{
|
||||
VideoDecoder& vdec = *sptr;
|
||||
VdecTask& task = vdec.task;
|
||||
@ -767,7 +767,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVdecGetPictureExt(PPUThread& CPU, u32 handle, vm::cptr<CellVdecPicFormat2> format2, vm::ptr<u8> outBuff, u32 arg4)
|
||||
s32 cellVdecGetPictureExt(PPUThread& ppu, u32 handle, vm::cptr<CellVdecPicFormat2> format2, vm::ptr<u8> outBuff, u32 arg4)
|
||||
{
|
||||
cellVdec.Warning("cellVdecGetPictureExt(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4);
|
||||
|
||||
@ -776,7 +776,7 @@ s32 cellVdecGetPictureExt(PPUThread& CPU, u32 handle, vm::cptr<CellVdecPicFormat
|
||||
throw EXCEPTION("Unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format2->unk0, format2->unk1);
|
||||
}
|
||||
|
||||
vm::stackvar<CellVdecPicFormat> format(CPU);
|
||||
const vm::var<CellVdecPicFormat> format(ppu);
|
||||
format->formatType = format2->formatType;
|
||||
format->colorMatrixType = format2->colorMatrixType;
|
||||
format->alpha = format2->alpha;
|
||||
|
@ -98,7 +98,7 @@ s32 sys_interrupt_thread_disestablish(PPUThread& ppu, u32 ih)
|
||||
{
|
||||
sysPrxForUser.Todo("sys_interrupt_thread_disestablish(ih=0x%x)", ih);
|
||||
|
||||
return _sys_interrupt_thread_disestablish(ppu, ih, vm::stackvar<be_t<u64>>(ppu));
|
||||
return _sys_interrupt_thread_disestablish(ppu, ih, vm::var<u64>(ppu));
|
||||
}
|
||||
|
||||
s32 sys_process_is_stack(u32 p)
|
||||
|
@ -118,7 +118,7 @@ namespace sys_net
|
||||
be_t<s32> _h_errno;
|
||||
};
|
||||
|
||||
thread_local vm::var<tls_data_t> g_tls_data;
|
||||
thread_local vm::var<tls_data_t, vm::page_alloc_t> g_tls_data; // TODO
|
||||
|
||||
// Functions
|
||||
s32 accept(s32 s, vm::ptr<sockaddr> addr, vm::ptr<u32> paddrlen)
|
||||
@ -492,9 +492,7 @@ namespace sys_net
|
||||
{
|
||||
libnet.Warning("_sys_net_errno_loc()");
|
||||
|
||||
const vm::ptr<tls_data_t> tls = g_tls_data;
|
||||
|
||||
return tls.of(&tls_data_t::_errno);
|
||||
return g_tls_data.of(&tls_data_t::_errno);
|
||||
}
|
||||
|
||||
s32 sys_net_set_resolver_configurations()
|
||||
|
@ -16,7 +16,7 @@ s32 sys_ppu_thread_create(PPUThread& ppu, vm::ptr<u64> thread_id, u32 entry, u64
|
||||
// (return CELL_ENOMEM if failed)
|
||||
// ...
|
||||
|
||||
vm::stackvar<ppu_thread_param_t> attr(ppu);
|
||||
const vm::var<ppu_thread_param_t> attr(ppu);
|
||||
|
||||
attr->entry = entry;
|
||||
attr->tls = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user