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;
}
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
{
cellGcmSys.error("cellGcmSetTileInfo: 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)))
{
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
cellGcmSys.error("cellGcmSetTileInfo: 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& 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;
}
@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
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");
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@ -1485,4 +1485,4 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
// Special
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
});
});

View File

@ -8,6 +8,7 @@
#include "Crypto/unself.h"
#include "cellRtc.h"
#include "sceNp.h"
#include "cellSysutil.h"
logs::channel sceNp("sceNp");
@ -905,13 +906,23 @@ s32 sceNpLookupTitleSmallStorageAsync()
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)
{
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;
}

View File

@ -557,9 +557,14 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc;
doc.Load(path);
auto trophy_base = doc.GetRoot();
if (trophy_base->GetChildren()->GetName() == "trophyconf")
{
trophy_base = trophy_base->GetChildren();
}
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())))
{
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);
if (size > 4096)
size = 4096;
for (u32 i = 0; i < (u32)size - 1; i++)
if (size > 0x1000)
{
addr[i] = rand() % 256;
return CELL_EINVAL;
}
for (u32 i = 0; i < (u32)size; i++)
{
addr[i] = rand() & 0xff;
}
return CELL_OK;

View File

@ -280,15 +280,16 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
if (!stack_addr)
{
// Allocate stack + gap between stacks
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096;
if (!stack_addr)
auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack);
if (!new_stack_base)
{
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
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;

View File

@ -9,9 +9,9 @@ bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configp
{
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))
@ -147,7 +147,13 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con
m_table4.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")
{

View File

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