Various fixes (Trophy, Gcm corrections, stack alloc) (#2894)

* Fixed sys_get_random_number generating less bytes than needed, and ceiling the buffer size in 0x1000 instead of failing
* Corrected alignment check in libgcm
* Now calling callback of sceNpManagerRegisterCallback
* Fixed trophies
This commit is contained in:
Ofek 2017-09-02 14:43:44 +03:00 committed by Ivan
parent d3f13ab8a3
commit caab400258
7 changed files with 45 additions and 20 deletions

View File

@ -595,7 +595,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
return CELL_GCM_ERROR_INVALID_VALUE; return CELL_GCM_ERROR_INVALID_VALUE;
} }
if (offset & 0xffff || size & 0xffff || pitch & 0xf) if (offset & 0xffff || size & 0xffff || pitch & 0xff)
{ {
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT; return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@ -603,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
{ {
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT"); cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM");
return CELL_GCM_ERROR_INVALID_ENUM; return CELL_GCM_ERROR_INVALID_ENUM;
} }
@ -1171,7 +1171,7 @@ s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segment
const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put; const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put;
const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get; const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get;
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2) if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000)
{ {
return CELL_GCM_ERROR_FAILURE; return CELL_GCM_ERROR_FAILURE;
} }
@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
return CELL_GCM_ERROR_INVALID_VALUE; return CELL_GCM_ERROR_INVALID_VALUE;
} }
if (offset & 0xffff || size & 0xffff || pitch & 0xf) if (offset & 0xffff || size & 0xffff || pitch & 0xff)
{ {
cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT"); cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT; return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@ -1485,4 +1485,4 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
// Special // Special
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN; REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
}); });

View File

@ -8,6 +8,7 @@
#include "Crypto/unself.h" #include "Crypto/unself.h"
#include "cellRtc.h" #include "cellRtc.h"
#include "sceNp.h" #include "sceNp.h"
#include "cellSysutil.h"
logs::channel sceNp("sceNp"); logs::channel sceNp("sceNp");
@ -905,13 +906,23 @@ s32 sceNpLookupTitleSmallStorageAsync()
s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr<void> arg) s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr<void> arg)
{ {
sceNp.todo("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg); sceNp.warning("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
if (!callback) if (!callback)
{ {
return SCE_NP_ERROR_INVALID_ARGUMENT; return SCE_NP_ERROR_INVALID_ARGUMENT;
} }
sysutil_register_cb([=](ppu_thread& ppu)->s32
{
callback(ppu, SCE_NP_MANAGER_STATUS_OFFLINE, CELL_OK, arg.addr());
return CELL_OK;
});
// TODO:
// * Save the callback somewhere for future updates once network is implemented
// * If register is called again, created cb needs to be canceled
return CELL_OK; return CELL_OK;
} }

View File

@ -557,9 +557,14 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
verify(HERE), !fs::get_virtual_device(path); verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc; rXmlDocument doc;
doc.Load(path); doc.Load(path);
auto trophy_base = doc.GetRoot();
if (trophy_base->GetChildren()->GetName() == "trophyconf")
{
trophy_base = trophy_base->GetChildren();
}
bool found = false; bool found = false;
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) { for (std::shared_ptr<rXmlNode> n = trophy_base->GetChildren(); n; n = n->GetNext()) {
if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str()))) if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str())))
{ {
found = true; found = true;

View File

@ -53,12 +53,14 @@ s32 sys_get_random_number(vm::ptr<u8> addr, u64 size)
{ {
sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size); sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size);
if (size > 4096) if (size > 0x1000)
size = 4096;
for (u32 i = 0; i < (u32)size - 1; i++)
{ {
addr[i] = rand() % 256; return CELL_EINVAL;
}
for (u32 i = 0; i < (u32)size; i++)
{
addr[i] = rand() & 0xff;
} }
return CELL_OK; return CELL_OK;

View File

@ -280,15 +280,16 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
if (!stack_addr) if (!stack_addr)
{ {
// Allocate stack + gap between stacks // Allocate stack + gap between stacks
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096; auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack);
if (!new_stack_base)
if (!stack_addr)
{ {
fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size); fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size);
} }
const_cast<u32&>(stack_addr) = new_stack_base + 4096;
// Make the gap inaccessible // Make the gap inaccessible
vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable); vm::page_protect(new_stack_base, 4096, 0, 0, vm::page_readable + vm::page_writable);
gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200; gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200;

View File

@ -9,9 +9,9 @@ bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configp
{ {
const std::string& path = vfs::get(filepath); const std::string& path = vfs::get(filepath);
if (!fs::is_file(path)) if (!Generate(filepath, configpath))
{ {
Generate(filepath, configpath); return false;
} }
if (!m_file.open(path, fs::read)) if (!m_file.open(path, fs::read))
@ -147,7 +147,13 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con
m_table4.clear(); m_table4.clear();
m_table6.clear(); m_table6.clear();
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) auto trophy_base = doc.GetRoot();
if (trophy_base->GetChildren()->GetName() == "trophyconf")
{
trophy_base = trophy_base->GetChildren();
}
for (std::shared_ptr<rXmlNode> n = trophy_base->GetChildren(); n; n = n->GetNext())
{ {
if (n->GetName() == "trophy") if (n->GetName() == "trophy")
{ {

View File

@ -22,7 +22,7 @@ bool TRPLoader::Install(const std::string& dest, bool show)
return false; return false;
} }
std::vector<char> buffer; buffer.reserve(65536); std::vector<char> buffer(65536);
for (const TRPEntry& entry : m_entries) for (const TRPEntry& entry : m_entries)
{ {