Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
hoholee12 authored Jul 23, 2023
2 parents cf785e2 + fce8e0f commit e01f9ba
Show file tree
Hide file tree
Showing 16 changed files with 244 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1635,7 +1635,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
if (!g_tls_access_violation_recovered)
{
vm_log.notice("\n%s", dump_useful_thread_info());
vm_log.error("Access violation %s location 0x%x (%s)", is_writing ? "writing" : "reading", addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
vm_log.error("[%s] Access violation %s location 0x%x (%s)", is_writing ? "writing" : "reading", cpu->get_name(), addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
}

// TODO:
Expand Down
21 changes: 14 additions & 7 deletions rpcs3/Emu/CPU/CPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,19 @@ bool cpu_thread::check_state() noexcept
return store;
}

if (s_tls_thread_slot == umax)
{
if (cpu_flag::wait - state)
{
// Force wait flag (must be set during ownership of s_cpu_lock), this makes the atomic op fail as a side effect
state += cpu_flag::wait;
store = true;
}

// Restore thread in the suspend list
cpu_counter::add(this);
}

if (flags & cpu_flag::wait)
{
flags -= cpu_flag::wait;
Expand Down Expand Up @@ -845,12 +858,6 @@ bool cpu_thread::check_state() noexcept

if (escape)
{
if (s_tls_thread_slot == umax && !retval)
{
// Restore thread in the suspend list
cpu_counter::add(this);
}

if (cpu_can_stop && state0 & cpu_flag::pending)
{
// Execute pending work
Expand Down Expand Up @@ -999,7 +1006,7 @@ cpu_thread& cpu_thread::operator=(thread_state)
{
if (u32 resv = atomic_storage<u32>::load(thread->raddr))
{
vm::reservation_notifier(resv).notify_one();
vm::reservation_notifier(resv).notify_all(-128);
}
}
}
Expand Down
12 changes: 1 addition & 11 deletions rpcs3/Emu/Cell/Modules/cellGem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,7 @@ struct gem_config_data
[[maybe_unused]] const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellGem);

ar(attribute, vc_attribute, status_flags, enable_pitch_correction, inertial_counter, controllers
, connected_controllers, update_started, camera_frame, memory_ptr);

if (version == 1 && !ar.is_writing())
{
u32 ts = ar;
start_timestamp_us = ts;
}
else
{
ar(start_timestamp_us);
}
, connected_controllers, update_started, camera_frame, memory_ptr, start_timestamp_us);
}

gem_config_data(utils::serial& ar)
Expand Down
12 changes: 6 additions & 6 deletions rpcs3/Emu/Cell/PPUAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void ppu_module::validate(u32 reloc)

if (size && size != funcs[index].size)
{
if (size + 4 != funcs[index].size || *ensure(get_ptr<u32>(addr + size)) != ppu_instructions::NOP())
if (size + 4 != funcs[index].size || get_ref<u32>(addr + size) != ppu_instructions::NOP())
{
ppu_validator.error("%s.yml : function size mismatch at 0x%x(size=0x%x) (0x%x, 0x%x)", path, found, funcs[index].size, addr, size);
}
Expand Down Expand Up @@ -733,7 +733,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
// Register TOC from entry point
if (entry && !lib_toc)
{
lib_toc = *ensure(get_ptr<u32>(entry)) ? *ensure(get_ptr<u32>(entry + 4)) : *ensure(get_ptr<u32>(entry + 20));
lib_toc = get_ref<u32>(entry) ? get_ref<u32>(entry + 4) : get_ref<u32>(entry + 20);
}

// Secondary attempt
Expand Down Expand Up @@ -1425,7 +1425,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
for (vm::cptr<u32> _ptr = vm::cast(block.first); _ptr.addr() < block.first + block.second;)
{
const u32 iaddr = _ptr.addr();
const ppu_opcode_t op{*ensure(get_ptr<u32>(_ptr++))};
const ppu_opcode_t op{get_ref<u32>(_ptr++)};
const ppu_itype::type type = s_ppu_itype.decode(op.opcode);

if (type == ppu_itype::B || type == ppu_itype::BC)
Expand Down Expand Up @@ -1499,7 +1499,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
for (vm::cptr<u32> _ptr = vm::cast(start); _ptr.addr() < next;)
{
const u32 addr = _ptr.addr();
const ppu_opcode_t op{*ensure(get_ptr<u32>(_ptr++))};
const ppu_opcode_t op{get_ref<u32>(_ptr++)};
const ppu_itype::type type = s_ppu_itype.decode(op.opcode);

if (type == ppu_itype::UNK)
Expand Down Expand Up @@ -1641,7 +1641,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
continue;
}

const u32 target = *ensure(get_ptr<u32>(rel.addr));
const u32 target = get_ref<u32>(rel.addr);

if (target % 4 || target < start || target >= end)
{
Expand Down Expand Up @@ -1718,7 +1718,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b

for (; i_pos < lim; i_pos += 4)
{
const u32 opc = *ensure(get_ptr<u32>(i_pos));
const u32 opc = get_ref<u32>(i_pos);

switch (auto type = s_ppu_itype.decode(opc))
{
Expand Down
37 changes: 36 additions & 1 deletion rpcs3/Emu/Cell/PPUAnalyser.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <deque>
#include "util/types.hpp"
#include "util/endian.hpp"
#include "util/asm.hpp"
#include "util/to_endian.hpp"

#include "Utilities/bit_set.h"
Expand Down Expand Up @@ -127,7 +128,7 @@ struct ppu_module
const u32 seg_size = seg.size;
const u32 seg_addr = seg.addr;

if (seg_size >= std::max<usz>(size_bytes, 1) && addr <= seg_addr + seg_size - size_bytes)
if (seg_size >= std::max<usz>(size_bytes, 1) && addr <= utils::align<u32>(seg_addr + seg_size, 0x10000) - size_bytes)
{
return reinterpret_cast<to_be_t<T>*>(static_cast<u8*>(seg.ptr) + (addr - seg_addr));
}
Expand All @@ -148,6 +149,40 @@ struct ppu_module
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
return get_ptr<T>(addr.addr(), u32{size_element});
}

template <typename T>
to_be_t<T>& get_ref(u32 addr,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>(addr, u32{size_element}))
{
return *ptr;
}

fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc{line, col, file, func});
return *std::add_pointer_t<to_be_t<T>>{};
}

template <typename T, typename U> requires requires (const U& obj) { +obj.size() * 0; }
to_be_t<T>& get_ref(U&& addr,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>(addr.addr(), u32{size_element}))
{
return *ptr;
}

fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr.addr(), src_loc{line, col, file, func});
return *std::add_pointer_t<to_be_t<T>>{};
}
};

struct main_ppu_module : public ppu_module
Expand Down
16 changes: 1 addition & 15 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2030,21 +2030,7 @@ void ppu_thread::serialize_common(utils::serial& ar)
{
[[maybe_unused]] const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), ppu);

ar(gpr, fpr, cr, fpscr.bits, lr, ctr, vrsave, cia, xer, sat, nj);

if (ar.is_writing())
{
ar(prio.load().all);
}
else if (version < 2)
{
prio.raw().all = 0;
prio.raw().prio = ar.operator s32();
}
else
{
ar(prio.raw().all);
}
ar(gpr, fpr, cr, fpscr.bits, lr, ctr, vrsave, cia, xer, sat, nj, prio.raw().all);

ar(optional_savestate_state, vr);

Expand Down
5 changes: 1 addition & 4 deletions rpcs3/Emu/Cell/lv2/sys_net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,7 @@ lv2_socket::lv2_socket(utils::serial& ar, lv2_socket_type _type)

const s32 version = GET_SERIALIZATION_VERSION(lv2_net);

if (version >= 2)
{
ar(so_rcvtimeo, so_sendtimeo);
}
ar(so_rcvtimeo, so_sendtimeo);

lv2_id = idm::last_id();

Expand Down
18 changes: 2 additions & 16 deletions rpcs3/Emu/Cell/lv2/sys_prx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,7 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
{
std::basic_string<bool> loaded_flags, external_flags;

if (version >= 4)
{
ar(loaded_flags);
ar(external_flags);
}
ar(loaded_flags, external_flags);

fs::file file{path.substr(0, path.size() - (offset ? fmt::format("_x%x", offset).size() : 0))};

Expand All @@ -328,21 +324,11 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
prx->m_loaded_flags = std::move(loaded_flags);
prx->m_external_loaded_flags = std::move(external_flags);

if (version == 2 && (state == PRX_STATE_STARTED || state == PRX_STATE_STARTING))
{
prx->load_exports();
}

if (version >= 4 && state <= PRX_STATE_STARTED)
if (state <= PRX_STATE_STARTED)
{
prx->restore_exports();
}

if (version == 1)
{
prx->load_exports();
}

ensure(prx);
}
else
Expand Down
18 changes: 4 additions & 14 deletions rpcs3/Emu/Cell/lv2/sys_spu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,7 @@ lv2_spu_group::lv2_spu_group(utils::serial& ar) noexcept
{
std::common_type_t<decltype(lv2_spu_group::prio)> prio{};

if (GET_SERIALIZATION_VERSION(spu) < 3)
{
prio.prio = ar.operator s32();
}
else
{
ar(prio.all);
}
ar(prio.all);

return prio;
}())
Expand Down Expand Up @@ -387,10 +380,7 @@ struct spu_limits_t

spu_limits_t(utils::serial& ar) noexcept
{
if (GET_SERIALIZATION_VERSION(spu) >= 2)
{
ar(max_raw, max_spu);
}
ar(max_raw, max_spu);
}

void save(utils::serial& ar)
Expand Down Expand Up @@ -1407,7 +1397,7 @@ error_code sys_spu_thread_group_terminate(ppu_thread& ppu, u32 id, s32 value)
if (prev_resv && prev_resv != resv)
{
// Batch reservation notifications if possible
vm::reservation_notifier(prev_resv).notify_all();
vm::reservation_notifier(prev_resv).notify_all(-128);
}

prev_resv = resv;
Expand All @@ -1417,7 +1407,7 @@ error_code sys_spu_thread_group_terminate(ppu_thread& ppu, u32 id, s32 value)

if (prev_resv)
{
vm::reservation_notifier(prev_resv).notify_all();
vm::reservation_notifier(prev_resv).notify_all(-128);
}

group->exit_status = value;
Expand Down
9 changes: 3 additions & 6 deletions rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,13 +506,10 @@ namespace rsx
ar(u32{0});
}
}
else if (version > 1)
else if (u32 count = ar)
{
if (u32 count = ar)
{
restore_fifo_count = count;
ar(restore_fifo_cmd);
}
restore_fifo_count = count;
ar(restore_fifo_cmd);
}
}

Expand Down
13 changes: 9 additions & 4 deletions rpcs3/Emu/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ extern std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const
extern bool ppu_load_rel_exec(const ppu_rel_object&);
extern bool is_savestate_version_compatible(const std::vector<std::pair<u16, u16>>& data, bool is_boot_check);
extern std::vector<std::pair<u16, u16>> read_used_savestate_versions();
std::string get_savestate_path(std::string_view title_id, std::string_view boot_path);
std::string get_savestate_file(std::string_view title_id, std::string_view boot_path, s64 abs_id, s64 rel_id);

extern void send_close_home_menu_cmds();

Expand Down Expand Up @@ -492,7 +492,7 @@ void Emulator::Init()

make_path_verbose(fs::get_cache_dir() + "shaderlog/", false);
make_path_verbose(fs::get_cache_dir() + "spu_progs/", false);
make_path_verbose(fs::get_cache_dir() + "/savestates/", false);
make_path_verbose(fs::get_parent_dir(get_savestate_file("NO_ID", "/NO_FILE", -1, -1)), false);
make_path_verbose(fs::get_config_dir() + "captures/", false);
make_path_verbose(fs::get_config_dir() + "sounds/", false);
make_path_verbose(patch_engine::get_patches_path(), false);
Expand Down Expand Up @@ -2180,7 +2180,7 @@ void Emulator::FixGuestTime()
// Mark a known savestate location and the one we try to boot (in case we boot a moved/copied savestate)
if (g_cfg.savestate.suspend_emu)
{
for (std::string old_path : std::initializer_list<std::string>{m_ar ? m_path_old : "", m_title_id.empty() ? "" : get_savestate_path(m_title_id, m_path_old)})
for (std::string old_path : std::initializer_list<std::string>{m_ar ? m_path_old : "", m_title_id.empty() ? "" : get_savestate_file(m_title_id, m_path_old, 0, 0)})
{
if (old_path.empty())
{
Expand Down Expand Up @@ -2841,7 +2841,12 @@ void Emulator::Kill(bool allow_autoexit, bool savestate)

if (savestate)
{
const std::string path = get_savestate_path(m_title_id, m_path);
const std::string path = get_savestate_file(m_title_id, m_path, 0, 0);

if (!fs::create_path(fs::get_parent_dir(path)))
{
sys_log.error("Failed to create savestate directory! (path='%s', %s)", fs::get_parent_dir(path), fs::g_tls_error);
}

fs::pending_file file(path);

Expand Down
Loading

0 comments on commit e01f9ba

Please sign in to comment.