Skip to content

Commit

Permalink
Merge branch 'master' into ugh-reserve-gcm
Browse files Browse the repository at this point in the history
  • Loading branch information
kd-11 committed Feb 15, 2020
2 parents 735354e + 4018b83 commit 4186f25
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 261 deletions.
31 changes: 12 additions & 19 deletions rpcs3/Emu/Cell/Modules/cellGcmSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ u32 gcmIoOffsetToAddress(u32 ioOffset)
{
const u32 upper12Bits = g_fxo->get<gcm_config>()->offsetTable.eaAddress[ioOffset >> 20];

if (static_cast<s16>(upper12Bits) < 0)
if (upper12Bits > 0xBFF)
{
return 0;
}
Expand Down Expand Up @@ -891,26 +891,22 @@ error_code cellGcmAddressToOffset(u32 address, vm::ptr<u32> offset)
{
cellGcmSys.trace("cellGcmAddressToOffset(address=0x%x, offset=*0x%x)", address, offset);

// Address not on main memory or local memory
if (address >= 0xD0000000)
{
return CELL_GCM_ERROR_FAILURE;
}
const auto cfg = g_fxo->get<gcm_config>();

u32 result;

// Address in local memory
if ((address >> 28) == 0xC)
// Test if address is within local memory
if (const u32 offs = address - cfg->local_addr; offs < cfg->local_size)
{
result = address - rsx::constants::local_mem_base;
result = offs;
}
// Address in main memory else check
else
{
const u32 upper12Bits = g_fxo->get<gcm_config>()->offsetTable.ioAddress[address >> 20];
const u32 upper12Bits = cfg->offsetTable.ioAddress[address >> 20];

// If the address is mapped in IO
if (upper12Bits != 0xFFFF)
if (upper12Bits << 20 < rsx::get_current_renderer()->main_mem_size)
{
result = (upper12Bits << 20) | (address & 0xFFFFF);
}
Expand Down Expand Up @@ -1035,7 +1031,7 @@ error_code cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
// Use the offset table to find the next free io address
for (u32 io = 0, end = (rsx::get_current_renderer()->main_mem_size - cfg->reserved_size) >> 20, unmap_count = 1; io < end; unmap_count++)
{
if (static_cast<s16>(cfg->offsetTable.eaAddress[io + unmap_count - 1]) < 0)
if (cfg->offsetTable.eaAddress[io + unmap_count - 1] > 0xBFF)
{
if (unmap_count >= (size >> 20))
{
Expand Down Expand Up @@ -1088,17 +1084,13 @@ error_code cellGcmUnmapEaIoAddress(u32 ea)
const auto cfg = g_fxo->get<gcm_config>();
std::lock_guard lock(cfg->gcmio_mutex);

if (const u32 size = cfg->IoMapTable[ea >> 20])
if (u32 size = cfg->IoMapTable[ea >>= 20], io = cfg->offsetTable.ioAddress[ea]; size && io <= 0xBFF)
{
u32 io = cfg->offsetTable.ioAddress[ea];

if (auto error = sys_rsx_context_iounmap(0x55555555, io, size))
if (auto error = sys_rsx_context_iounmap(0x55555555, io << 20, size << 20))
{
return error;
}

ea >>= 20, io >>= 20;

const auto render = rsx::get_current_renderer();

for (u32 i = 0; i < size; i++)
Expand All @@ -1123,7 +1115,7 @@ error_code cellGcmUnmapIoAddress(u32 io)

if (u32 ea = cfg->offsetTable.eaAddress[io >>= 20], size = cfg->IoMapTable[ea]; size)
{
if (auto error = sys_rsx_context_iounmap(0x55555555, io, size))
if (auto error = sys_rsx_context_iounmap(0x55555555, io, size << 20))
{
return error;
}
Expand All @@ -1135,6 +1127,7 @@ error_code cellGcmUnmapIoAddress(u32 io)
cfg->offsetTable.eaAddress[io + i] = 0xFFFF;
}

cfg->IoMapTable[ea] = 0;
return CELL_OK;
}

Expand Down
98 changes: 57 additions & 41 deletions rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,28 +156,27 @@ void fmt_class_string<SceNpTrophyError>::format(std::string& out, u64 arg)

// Helpers

void show_trophy_notification(u32 context, u32 handle, u32 trophyId, const std::string& context_name)
static error_code NpTrophyGetTrophyInfo(const trophy_context_t* ctxt, s32 trophyId, SceNpTrophyDetails* details, SceNpTrophyData* data);

static void show_trophy_notification(const trophy_context_t* ctxt, s32 trophyId)
{
// Get icon for the notification.
const std::string padded_trophy_id = fmt::format("%03u", trophyId);
const std::string trophy_icon_path = "/dev_hdd0/home/" + Emu.GetUsr() + "/trophy/" + context_name + "/TROP" + padded_trophy_id + ".PNG";
const std::string trophy_icon_path = "/dev_hdd0/home/" + Emu.GetUsr() + "/trophy/" + ctxt->trp_name + "/TROP" + padded_trophy_id + ".PNG";
fs::file trophy_icon_file = fs::file(vfs::get(trophy_icon_path));
std::vector<uchar> trophy_icon_data;
trophy_icon_file.read(trophy_icon_data, trophy_icon_file.size());

vm::var<SceNpTrophyDetails> details({ 0 });
vm::var<SceNpTrophyData> _({ 0 });
SceNpTrophyDetails details{};

const s32 ret = sceNpTrophyGetTrophyInfo(context, handle, trophyId, details, _);
if (ret != CELL_OK)
if (const auto ret = NpTrophyGetTrophyInfo(ctxt, trophyId, &details, nullptr))
{
sceNpTrophy.error("Failed to get info for trophy dialog. Error code %x", ret);
*details = SceNpTrophyDetails();
sceNpTrophy.error("Failed to get info for trophy dialog. Error code 0x%x", +ret);
}

if (auto trophy_notification_dialog = Emu.GetCallbacks().get_trophy_notification_dialog())
{
trophy_notification_dialog->ShowTrophyNotification(*details, trophy_icon_data);
trophy_notification_dialog->ShowTrophyNotification(details, trophy_icon_data);
}
}

Expand Down Expand Up @@ -644,18 +643,29 @@ error_code sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr<u64>
return error;
}

u64 space = 0;

if (!fs::is_dir(vfs::get("/dev_hdd0/home/" + Emu.GetUsr() + "/trophy/" + ctxt->trp_name)))
{
TRPLoader trp(ctxt->trp_stream);

if (trp.LoadHeader())
{
*reqspace = trp.GetRequiredSpace();
return CELL_OK;
space = trp.GetRequiredSpace();
}
else
{
sceNpTrophy.error("sceNpTrophyGetRequiredDiskSpace(): Failed to load trophy header! (trp_name=%s)", ctxt->trp_name);
}
}
else
{
sceNpTrophy.warning("sceNpTrophyGetRequiredDiskSpace(): Trophy config is already installed (trp_name=%s)", ctxt->trp_name);
}

sceNpTrophy.warning("sceNpTrophyGetRequiredDiskSpace(): reqspace is 0x%llx", space);

*reqspace = 0;
*reqspace = space;
return CELL_OK;
}

Expand Down Expand Up @@ -864,7 +874,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
if (platinumId)
{
*platinumId = unlocked_platinum_id;
sceNpTrophy.warning("sceNpTrophyUnlockTrophy: platinumId was set to %d)", unlocked_platinum_id);
sceNpTrophy.warning("sceNpTrophyUnlockTrophy: platinumId was set to %d", unlocked_platinum_id);
}

const std::string trophyPath = "/dev_hdd0/home/" + Emu.GetUsr() + "/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
Expand All @@ -873,12 +883,12 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
if (g_cfg.misc.show_trophy_popups)
{
// Enqueue popup for the regular trophy
show_trophy_notification(context, handle, trophyId, ctxt->trp_name);
show_trophy_notification(ctxt, trophyId);

if (unlocked_platinum_id != SCE_NP_TROPHY_INVALID_TROPHY_ID)
{
// Enqueue popup for the holy platinum trophy
show_trophy_notification(context, handle, unlocked_platinum_id, ctxt->trp_name);
show_trophy_notification(ctxt, unlocked_platinum_id);
}
}

Expand Down Expand Up @@ -942,29 +952,11 @@ error_code sceNpTrophyGetTrophyDetails()
return CELL_OK;
}

error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data)
static error_code NpTrophyGetTrophyInfo(const trophy_context_t* ctxt, s32 trophyId, SceNpTrophyDetails* details, SceNpTrophyData* data)
{
sceNpTrophy.warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details=*0x%x, data=*0x%x)", context, handle, trophyId, details, data);

if (trophyId < 0 || trophyId > 127) // max 128 trophies
{
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
}

const auto trophy_manager = g_fxo->get<sce_np_trophy_manager>();

std::shared_lock lock(trophy_manager->mtx);

if (!trophy_manager->is_initialized)
{
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
}

const auto [ctxt, error] = trophy_manager->get_context_ex(context, handle);

if (error)
if (!details && !data)
{
return error;
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
}

if (!ctxt->tropusr)
Expand All @@ -973,11 +965,6 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
return SCE_NP_TROPHY_ERROR_CONTEXT_NOT_REGISTERED;
}

if (!details && !data)
{
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
}

fs::file config(vfs::get("/dev_hdd0/home/" + Emu.GetUsr() + "/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));

if (!config)
Expand Down Expand Up @@ -1048,6 +1035,7 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
data->unlocked = unlocked;
data->timestamp = ctxt->tropusr->GetTrophyTimestamp(trophyId);
}

break;
}
}
Expand All @@ -1060,6 +1048,34 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
return CELL_OK;
}

error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data)
{
sceNpTrophy.warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details=*0x%x, data=*0x%x)", context, handle, trophyId, details, data);

if (trophyId < 0 || trophyId > 127) // max 128 trophies
{
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
}

const auto trophy_manager = g_fxo->get<sce_np_trophy_manager>();

std::shared_lock lock(trophy_manager->mtx);

if (!trophy_manager->is_initialized)
{
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
}

const auto [ctxt, error] = trophy_manager->get_context_ex(context, handle);

if (error)
{
return error;
}

return NpTrophyGetTrophyInfo(ctxt, trophyId, details ? details.get_ptr() : nullptr, data ? data.get_ptr() : nullptr);
}

error_code sceNpTrophyGetGameProgress(u32 context, u32 handle, vm::ptr<s32> percentage)
{
sceNpTrophy.warning("sceNpTrophyGetGameProgress(context=0x%x, handle=0x%x, percentage=*0x%x)", context, handle, percentage);
Expand Down
10 changes: 3 additions & 7 deletions rpcs3/Emu/IdManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@ id_manager::id_map::pointer idm::allocate_id(const id_manager::id_key& info, u32
{
// Try to emplace back
const u32 _next = base + step * ::size32(vec);

if (_next >= base && _next < base + step * count)
{
g_id = _next;
vec.emplace_back(id_manager::id_key(_next, info.type()), nullptr);
return &vec.back();
}
g_id = _next;
vec.emplace_back(id_manager::id_key(_next, info.type()), nullptr);
return &vec.back();
}

// Check all IDs starting from "next id" (TODO)
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/IdManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace id_manager
static const u32 invalid = -+!base;

// Note: full 32 bits range cannot be used at current implementation
static_assert(count > 0 && step > 0 && u64{step} * count + base < u64{UINT32_MAX} + (base != 0 ? 1 : 0), "ID traits: invalid object range");
static_assert(count && step && u64{step} * (count - 1) + base < u64{UINT32_MAX} + (base != 0 ? 1 : 0), "ID traits: invalid object range");
};

// Correct usage testing
Expand Down
15 changes: 5 additions & 10 deletions rpcs3/Emu/RSX/RSXFIFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ namespace rsx
}
}

void FIFO_control::set_put(u32 put)
{
m_ctrl->put = put;
}

void FIFO_control::set_get(u32 get)
{
if (m_ctrl->get == get)
Expand Down Expand Up @@ -401,7 +396,7 @@ namespace rsx
}
case FIFO::FIFO_ERROR:
{
rsx_log.error("FIFO error: possible desync event (last cmd = 0x%x)", fifo_ctrl->last_cmd());
rsx_log.error("FIFO error: possible desync event (last cmd = 0x%x)", get_fifo_cmd());
recover_fifo();
return;
}
Expand Down Expand Up @@ -451,8 +446,8 @@ namespace rsx
if (fifo_ret_addr != RSX_CALL_STACK_EMPTY)
{
// Only one layer is allowed in the call stack.
rsx_log.error("FIFO: CALL found inside a subroutine. Discarding subroutine");
fifo_ctrl->set_get(std::exchange(fifo_ret_addr, RSX_CALL_STACK_EMPTY));
rsx_log.error("FIFO: CALL found inside a subroutine (last cmd = 0x%x)", get_fifo_cmd());
recover_fifo();
return;
}

Expand All @@ -465,8 +460,8 @@ namespace rsx
{
if (fifo_ret_addr == RSX_CALL_STACK_EMPTY)
{
rsx_log.error("FIFO: RET found without corresponding CALL. Discarding queue");
fifo_ctrl->set_get(ctrl->put);
rsx_log.error("FIFO: RET found without corresponding CALL (last cmd = 0x%x)", get_fifo_cmd());
recover_fifo();
return;
}

Expand Down
7 changes: 3 additions & 4 deletions rpcs3/Emu/RSX/RSXFIFO.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ namespace rsx
{
private:
RsxDmaControl* m_ctrl = nullptr;
rsx::rsx_iomap_table* m_iotable;
const rsx::rsx_iomap_table* m_iotable;
u32 m_internal_get = 0;

u32 m_memwatch_addr = 0;
Expand All @@ -129,12 +129,11 @@ namespace rsx
FIFO_control(rsx::thread* pctrl);
~FIFO_control() = default;

u32 get_pos() { return m_internal_get; }
u32 last_cmd() { return m_cmd; }
u32 get_pos() const { return m_internal_get; }
u32 last_cmd() const { return m_cmd; }
void sync_get() { m_ctrl->get.release(m_internal_get); }
void inc_get(bool wait);
void set_get(u32 get);
void set_put(u32 put);
void abort();
template <bool = true> u32 read_put();

Expand Down
5 changes: 4 additions & 1 deletion rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2340,7 +2340,7 @@ namespace rsx
}
}

u32 thread::get_fifo_cmd()
u32 thread::get_fifo_cmd() const
{
// Last fifo cmd for logging and utility
return fifo_ctrl->last_cmd();
Expand Down Expand Up @@ -3263,6 +3263,9 @@ namespace rsx
return result_none;

const auto memory_end = memory_address + memory_range;

AUDIT(memory_end >= memory_address);

u32 sync_address = 0;
occlusion_query_info* query = nullptr;

Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/RSXThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ namespace rsx
atomic_t<bool> external_interrupt_ack{ false };
void flush_fifo();
void recover_fifo();
void fifo_wake_delay(u64 div = 1);
u32 get_fifo_cmd();
static void fifo_wake_delay(u64 div = 1);
u32 get_fifo_cmd() const;

// Performance approximation counters
struct
Expand Down

0 comments on commit 4186f25

Please sign in to comment.