55#include " Emu/CPU/CPUThread.h"
66#include " Emu/Cell/ErrorCodes.h"
77#include " Emu/Cell/SPUThread.h"
8+ #include " Emu/Cell/PPUThread.h"
89#include " Emu/IdManager.h"
910
1011#include " util/asm.hpp"
@@ -247,17 +248,37 @@ error_code sys_memory_free(cpu_thread& cpu, u32 addr)
247248 return CELL_OK;
248249}
249250
250- error_code sys_memory_get_page_attribute (cpu_thread& cpu , u32 addr, vm::ptr<sys_page_attr_t > attr)
251+ error_code sys_memory_get_page_attribute (ppu_thread& ppu , u32 addr, vm::ptr<sys_page_attr_t > attr)
251252{
252- cpu .state += cpu_flag::wait;
253+ ppu .state += cpu_flag::wait;
253254
254255 sys_memory.trace (" sys_memory_get_page_attribute(addr=0x%x, attr=*0x%x)" , addr, attr);
255256
256- vm::writer_lock rlock;
257+ if ((addr >> 28 ) == (ppu.stack_addr >> 28 ))
258+ {
259+ // Stack address: fast path
260+ if (!(addr >= ppu.stack_addr && addr < ppu.stack_addr + ppu.stack_size ) && !vm::check_addr (addr))
261+ {
262+ return { CELL_EINVAL, addr };
263+ }
264+
265+ if (!vm::check_addr (attr.addr (), vm::page_readable, attr.size ()))
266+ {
267+ return CELL_EFAULT;
268+ }
257269
258- if (!vm::check_addr (addr) || addr >= SPU_FAKE_BASE_ADDR)
270+ attr->attribute = 0x40000ull ; // SYS_MEMORY_PROT_READ_WRITEs
271+ attr->access_right = SYS_MEMORY_ACCESS_RIGHT_PPU_THR;
272+ attr->page_size = 4096 ;
273+ attr->pad = 0 ; // Always write 0
274+ return CELL_OK;
275+ }
276+
277+ const auto [ok, vm_flags] = vm::get_addr_flags (addr);
278+
279+ if (!ok || addr >= SPU_FAKE_BASE_ADDR)
259280 {
260- return CELL_EINVAL;
281+ return { CELL_EINVAL, addr } ;
261282 }
262283
263284 if (!vm::check_addr (attr.addr (), vm::page_readable, attr.size ()))
@@ -266,19 +287,20 @@ error_code sys_memory_get_page_attribute(cpu_thread& cpu, u32 addr, vm::ptr<sys_
266287 }
267288
268289 attr->attribute = 0x40000ull ; // SYS_MEMORY_PROT_READ_WRITE (TODO)
269- attr->access_right = addr >> 28 == 0xdu ? SYS_MEMORY_ACCESS_RIGHT_PPU_THR : SYS_MEMORY_ACCESS_RIGHT_ANY;// ( TODO)
290+ attr->access_right = SYS_MEMORY_ACCESS_RIGHT_ANY; // TODO: Report accurately
270291
271- if (vm::check_addr (addr, vm::page_1m_size) )
292+ if (vm_flags & vm::page_1m_size)
272293 {
273294 attr->page_size = 0x100000 ;
274295 }
275- else if (vm::check_addr (addr, vm::page_64k_size) )
296+ else if (vm_flags & vm::page_64k_size)
276297 {
277298 attr->page_size = 0x10000 ;
278299 }
279300 else
280301 {
281- attr->page_size = 4096 ;
302+ // attr->page_size = 4096;
303+ fmt::throw_exception (" Unreachable" );
282304 }
283305
284306 attr->pad = 0 ; // Always write 0
0 commit comments