mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
SPU: don't allocate SPU LS in vm::main
Create its own shared memory object. Use vm::spu to allocate all SPU types. Use vm::writer_lock for shm::map_critical.
This commit is contained in:
parent
b1710bb712
commit
eaf0bbc108
5 changed files with 45 additions and 24 deletions
|
@ -28,7 +28,7 @@ inline void try_start(spu_thread& spu)
|
|||
|
||||
bool spu_thread::read_reg(const u32 addr, u32& value)
|
||||
{
|
||||
const u32 offset = addr - this->offset - RAW_SPU_PROB_OFFSET;
|
||||
const u32 offset = addr - (RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index) - RAW_SPU_PROB_OFFSET;
|
||||
|
||||
spu_log.trace("RawSPU[%u]: Read32(0x%x, offset=0x%x)", index, addr, offset);
|
||||
|
||||
|
@ -165,7 +165,7 @@ bool spu_thread::read_reg(const u32 addr, u32& value)
|
|||
|
||||
bool spu_thread::write_reg(const u32 addr, const u32 value)
|
||||
{
|
||||
const u32 offset = addr - this->offset - RAW_SPU_PROB_OFFSET;
|
||||
const u32 offset = addr - (RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index) - RAW_SPU_PROB_OFFSET;
|
||||
|
||||
spu_log.trace("RawSPU[%u]: Write32(0x%x, offset=0x%x, value=0x%x)", index, addr, offset, value);
|
||||
|
||||
|
@ -321,7 +321,7 @@ bool spu_thread::write_reg(const u32 addr, const u32 value)
|
|||
|
||||
void spu_load_exec(const spu_exec_object& elf)
|
||||
{
|
||||
auto ls0 = vm::cast(vm::falloc(RAW_SPU_BASE_ADDR, SPU_LS_SIZE, vm::spu));
|
||||
auto ls0 = vm::addr_t{RAW_SPU_BASE_ADDR};
|
||||
|
||||
spu_thread::g_raw_spu_ctr++;
|
||||
|
||||
|
@ -333,7 +333,7 @@ void spu_load_exec(const spu_exec_object& elf)
|
|||
}
|
||||
}
|
||||
|
||||
auto spu = idm::make_ptr<named_thread<spu_thread>>("TEST_SPU", ls0, nullptr, 0, "", 0);
|
||||
auto spu = idm::make_ptr<named_thread<spu_thread>>("TEST_SPU", nullptr, 0, "", 0);
|
||||
|
||||
spu_thread::g_raw_spu_id[0] = spu->id;
|
||||
|
||||
|
|
|
@ -1384,6 +1384,8 @@ std::string spu_thread::dump_misc() const
|
|||
fmt::append(ret, "...chunk-0x%05x", (name & 0xffff) * 4);
|
||||
}
|
||||
|
||||
const u32 offset = group ? SPU_FAKE_BASE_ADDR + (id & 0xffffff) * SPU_LS_SIZE : RAW_SPU_BASE_ADDR + index * RAW_SPU_OFFSET;
|
||||
|
||||
fmt::append(ret, "\n[%s]", ch_mfc_cmd);
|
||||
fmt::append(ret, "\nLocal Storage: 0x%08x..0x%08x", offset, offset + 0x3ffff);
|
||||
|
||||
|
@ -1624,16 +1626,19 @@ void spu_thread::cpu_task()
|
|||
spu_thread::~spu_thread()
|
||||
{
|
||||
{
|
||||
const auto [_, shm] = vm::get(vm::any, offset)->get(offset);
|
||||
vm::writer_lock(0);
|
||||
|
||||
for (s32 i = -1; i < 2; i++)
|
||||
{
|
||||
// Unmap LS mirrors
|
||||
shm->unmap_critical(ls + (i * SPU_LS_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
// Deallocate Local Storage
|
||||
vm::dealloc_verbose_nothrow(offset);
|
||||
if (!group)
|
||||
{
|
||||
// Deallocate local storage (thread groups are handled in sys_spu.cpp)
|
||||
vm::dealloc_verbose_nothrow(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, vm::spu);
|
||||
}
|
||||
|
||||
// Release LS mirrors area
|
||||
|
@ -1653,14 +1658,25 @@ spu_thread::~spu_thread()
|
|||
perf_log.notice("Perf stats for PUTLLC reload: successs %u, failure %u", last_succ, last_fail);
|
||||
}
|
||||
|
||||
spu_thread::spu_thread(vm::addr_t _ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated, u32 option)
|
||||
spu_thread::spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated, u32 option)
|
||||
: cpu_thread(idm::last_id())
|
||||
, index(index)
|
||||
, shm(std::make_shared<utils::shm>(SPU_LS_SIZE))
|
||||
, ls([&]()
|
||||
{
|
||||
const auto [_, shm] = vm::get(vm::any, _ls)->get(_ls);
|
||||
const auto addr = static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 5));
|
||||
|
||||
if (!group)
|
||||
{
|
||||
vm::get(vm::spu)->falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, SPU_LS_SIZE, &shm);
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::get(vm::spu)->falloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (cpu_thread::id & 0xffffff), SPU_LS_SIZE, &shm);
|
||||
}
|
||||
|
||||
vm::writer_lock(0);
|
||||
|
||||
for (u32 i = 1; i < 4; i++)
|
||||
{
|
||||
// Map LS mirrors
|
||||
|
@ -1672,7 +1688,6 @@ spu_thread::spu_thread(vm::addr_t _ls, lv2_spu_group* group, u32 index, std::str
|
|||
return addr + (SPU_LS_SIZE * 2);
|
||||
}())
|
||||
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
||||
, offset(_ls)
|
||||
, group(group)
|
||||
, option(option)
|
||||
, lv2_id(lv2_id)
|
||||
|
@ -1837,7 +1852,7 @@ void spu_thread::do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8*
|
|||
|
||||
if (offset + args.size - 1 < SPU_LS_SIZE) // LS access
|
||||
{
|
||||
eal = spu.offset + offset; // redirect access
|
||||
eal = SPU_FAKE_BASE_ADDR * (spu.id & 0xffffff) + offset; // redirect access
|
||||
}
|
||||
else if (!is_get && args.size == 4 && (offset == SYS_SPU_THREAD_SNR1 || offset == SYS_SPU_THREAD_SNR2))
|
||||
{
|
||||
|
|
|
@ -14,6 +14,11 @@ struct lv2_event_queue;
|
|||
struct lv2_spu_group;
|
||||
struct lv2_int_tag;
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class shm;
|
||||
}
|
||||
|
||||
// JIT Block
|
||||
using spu_function_t = void(*)(spu_thread&, void*, u8*);
|
||||
|
||||
|
@ -157,6 +162,8 @@ enum : u32
|
|||
RAW_SPU_OFFSET = 0x00100000,
|
||||
RAW_SPU_LS_OFFSET = 0x00000000,
|
||||
RAW_SPU_PROB_OFFSET = 0x00040000,
|
||||
|
||||
SPU_FAKE_BASE_ADDR = 0xE8000000,
|
||||
};
|
||||
|
||||
struct spu_channel
|
||||
|
@ -629,9 +636,9 @@ public:
|
|||
|
||||
static const u32 id_base = 0x02000000; // TODO (used to determine thread type)
|
||||
static const u32 id_step = 1;
|
||||
static const u32 id_count = 2048;
|
||||
static const u32 id_count = (0xF0000000 - SPU_FAKE_BASE_ADDR) / SPU_LS_SIZE;
|
||||
|
||||
spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated = false, u32 option = 0);
|
||||
spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated = false, u32 option = 0);
|
||||
|
||||
u32 pc = 0;
|
||||
|
||||
|
@ -730,10 +737,10 @@ public:
|
|||
atomic_t<u32> last_exit_status; // Value to be written in exit_status after checking group termination
|
||||
|
||||
const u32 index; // SPU index
|
||||
std::shared_ptr<utils::shm> shm; // SPU memory
|
||||
const std::add_pointer_t<u8> ls; // SPU LS pointer
|
||||
const spu_type thread_type;
|
||||
private:
|
||||
const u32 offset; // SPU LS offset
|
||||
lv2_spu_group* const group; // SPU Thread Group (only safe to access in the spu thread itself)
|
||||
public:
|
||||
const u32 option; // sys_spu_thread_initialize option
|
||||
|
|
|
@ -399,8 +399,6 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
sys_spu.warning("Unimplemented SPU Thread options (0x%x)", option);
|
||||
}
|
||||
|
||||
const vm::addr_t ls_addr{verify("SPU LS" HERE, vm::alloc(SPU_LS_SIZE, vm::main))};
|
||||
|
||||
const u32 inited = group->init;
|
||||
|
||||
const u32 tid = (inited << 24) | (group_id & 0xffffff);
|
||||
|
@ -414,7 +412,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
|
|||
fmt::append(full_name, "%s ", thread_name);
|
||||
}
|
||||
|
||||
const auto spu = std::make_shared<named_thread<spu_thread>>(full_name, ls_addr, group.get(), spu_num, thread_name, tid, false, option);
|
||||
const auto spu = std::make_shared<named_thread<spu_thread>>(full_name, group.get(), spu_num, thread_name, tid, false, option);
|
||||
group->threads[inited] = spu;
|
||||
group->threads_map[spu_num] = static_cast<s8>(inited);
|
||||
return spu;
|
||||
|
@ -683,6 +681,9 @@ error_code sys_spu_thread_group_destroy(ppu_thread& ppu, u32 id)
|
|||
{
|
||||
if (auto thread = t.get())
|
||||
{
|
||||
// Deallocate LS
|
||||
vm::get(vm::spu)->dealloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (thread->id & 0xffffff), &thread->shm);
|
||||
|
||||
// Remove ID from IDM (destruction will occur in group destructor)
|
||||
idm::remove<named_thread<spu_thread>>(thread->id);
|
||||
}
|
||||
|
@ -1845,9 +1846,7 @@ error_code sys_raw_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<void> at
|
|||
index = 0;
|
||||
}
|
||||
|
||||
const vm::addr_t ls_addr{verify(HERE, vm::falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, SPU_LS_SIZE, vm::spu))};
|
||||
|
||||
const u32 tid = idm::make<named_thread<spu_thread>>(fmt::format("RawSPU[0x%x] ", index), ls_addr, nullptr, index, "", index);
|
||||
const u32 tid = idm::make<named_thread<spu_thread>>(fmt::format("RawSPU[0x%x] ", index), nullptr, index, "", index);
|
||||
|
||||
spu_thread::g_raw_spu_id[index] = verify("RawSPU ID" HERE, tid);
|
||||
|
||||
|
@ -1893,9 +1892,9 @@ error_code sys_isolated_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<voi
|
|||
index = 0;
|
||||
}
|
||||
|
||||
const vm::addr_t ls_addr{verify(HERE, vm::falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, SPU_LS_SIZE, vm::spu))};
|
||||
const vm::addr_t ls_addr{RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index};
|
||||
|
||||
const auto thread = idm::make_ptr<named_thread<spu_thread>>(fmt::format("IsoSPU[0x%x] ", index), ls_addr, nullptr, index, "", index, true);
|
||||
const auto thread = idm::make_ptr<named_thread<spu_thread>>(fmt::format("IsoSPU[0x%x] ", index), nullptr, index, "", index, true);
|
||||
|
||||
thread->gpr[3] = v128::from64(0, arg1);
|
||||
thread->gpr[4] = v128::from64(0, arg2);
|
||||
|
|
|
@ -1313,10 +1313,10 @@ namespace vm
|
|||
return {addr, nullptr};
|
||||
}
|
||||
|
||||
// Special path
|
||||
// Special case
|
||||
if (m_common)
|
||||
{
|
||||
return {this->addr, m_common};
|
||||
return {addr, nullptr};
|
||||
}
|
||||
|
||||
// Range check
|
||||
|
|
Loading…
Add table
Reference in a new issue