mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Memory: move Read/Write8/16/32/64 and ReadCString into class
This commit is contained in:
		
							parent
							
								
									1ec9ed6827
								
							
						
					
					
						commit
						323990d402
					
				
					 11 changed files with 119 additions and 99 deletions
				
			
		|  | @ -72,33 +72,34 @@ private: | |||
| class DynarmicUserCallbacks final : public Dynarmic::A32::UserCallbacks { | ||||
| public: | ||||
|     explicit DynarmicUserCallbacks(ARM_Dynarmic& parent) | ||||
|         : parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system) {} | ||||
|         : parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system), | ||||
|           memory(parent.system.Memory()) {} | ||||
|     ~DynarmicUserCallbacks() = default; | ||||
| 
 | ||||
|     std::uint8_t MemoryRead8(VAddr vaddr) override { | ||||
|         return Memory::Read8(vaddr); | ||||
|         return memory.Read8(vaddr); | ||||
|     } | ||||
|     std::uint16_t MemoryRead16(VAddr vaddr) override { | ||||
|         return Memory::Read16(vaddr); | ||||
|         return memory.Read16(vaddr); | ||||
|     } | ||||
|     std::uint32_t MemoryRead32(VAddr vaddr) override { | ||||
|         return Memory::Read32(vaddr); | ||||
|         return memory.Read32(vaddr); | ||||
|     } | ||||
|     std::uint64_t MemoryRead64(VAddr vaddr) override { | ||||
|         return Memory::Read64(vaddr); | ||||
|         return memory.Read64(vaddr); | ||||
|     } | ||||
| 
 | ||||
|     void MemoryWrite8(VAddr vaddr, std::uint8_t value) override { | ||||
|         Memory::Write8(vaddr, value); | ||||
|         memory.Write8(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite16(VAddr vaddr, std::uint16_t value) override { | ||||
|         Memory::Write16(vaddr, value); | ||||
|         memory.Write16(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite32(VAddr vaddr, std::uint32_t value) override { | ||||
|         Memory::Write32(vaddr, value); | ||||
|         memory.Write32(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite64(VAddr vaddr, std::uint64_t value) override { | ||||
|         Memory::Write64(vaddr, value); | ||||
|         memory.Write64(vaddr, value); | ||||
|     } | ||||
| 
 | ||||
|     void InterpreterFallback(VAddr pc, std::size_t num_instructions) override { | ||||
|  | @ -159,6 +160,7 @@ public: | |||
|     ARM_Dynarmic& parent; | ||||
|     Core::Timing& timing; | ||||
|     Kernel::SVCContext svc_context; | ||||
|     Memory::MemorySystem& memory; | ||||
| }; | ||||
| 
 | ||||
| ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode) | ||||
|  |  | |||
|  | @ -811,7 +811,7 @@ MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64)); | |||
| static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, | ||||
|                                                     ARM_INST_PTR& inst_base) { | ||||
|     u32 inst_size = 4; | ||||
|     u32 inst = Memory::Read32(phys_addr & 0xFFFFFFFC); | ||||
|     u32 inst = Core::System::GetInstance().Memory().Read32(phys_addr & 0xFFFFFFFC); | ||||
| 
 | ||||
|     // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM
 | ||||
|     // instruction
 | ||||
|  |  | |||
|  | @ -191,13 +191,13 @@ static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) { | |||
| u8 ARMul_State::ReadMemory8(u32 address) const { | ||||
|     CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); | ||||
| 
 | ||||
|     return Memory::Read8(address); | ||||
|     return Core::System::GetInstance().Memory().Read8(address); | ||||
| } | ||||
| 
 | ||||
| u16 ARMul_State::ReadMemory16(u32 address) const { | ||||
|     CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); | ||||
| 
 | ||||
|     u16 data = Memory::Read16(address); | ||||
|     u16 data = Core::System::GetInstance().Memory().Read16(address); | ||||
| 
 | ||||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap16(data); | ||||
|  | @ -208,7 +208,7 @@ u16 ARMul_State::ReadMemory16(u32 address) const { | |||
| u32 ARMul_State::ReadMemory32(u32 address) const { | ||||
|     CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); | ||||
| 
 | ||||
|     u32 data = Memory::Read32(address); | ||||
|     u32 data = Core::System::GetInstance().Memory().Read32(address); | ||||
| 
 | ||||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap32(data); | ||||
|  | @ -219,7 +219,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const { | |||
| u64 ARMul_State::ReadMemory64(u32 address) const { | ||||
|     CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); | ||||
| 
 | ||||
|     u64 data = Memory::Read64(address); | ||||
|     u64 data = Core::System::GetInstance().Memory().Read64(address); | ||||
| 
 | ||||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap64(data); | ||||
|  | @ -230,7 +230,7 @@ u64 ARMul_State::ReadMemory64(u32 address) const { | |||
| void ARMul_State::WriteMemory8(u32 address, u8 data) { | ||||
|     CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); | ||||
| 
 | ||||
|     Memory::Write8(address, data); | ||||
|     Core::System::GetInstance().Memory().Write8(address, data); | ||||
| } | ||||
| 
 | ||||
| void ARMul_State::WriteMemory16(u32 address, u16 data) { | ||||
|  | @ -239,7 +239,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) { | |||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap16(data); | ||||
| 
 | ||||
|     Memory::Write16(address, data); | ||||
|     Core::System::GetInstance().Memory().Write16(address, data); | ||||
| } | ||||
| 
 | ||||
| void ARMul_State::WriteMemory32(u32 address, u32 data) { | ||||
|  | @ -248,7 +248,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) { | |||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap32(data); | ||||
| 
 | ||||
|     Memory::Write32(address, data); | ||||
|     Core::System::GetInstance().Memory().Write32(address, data); | ||||
| } | ||||
| 
 | ||||
| void ARMul_State::WriteMemory64(u32 address, u64 data) { | ||||
|  | @ -257,7 +257,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) { | |||
|     if (InBigEndianMode()) | ||||
|         data = Common::swap64(data); | ||||
| 
 | ||||
|     Memory::Write64(address, data); | ||||
|     Core::System::GetInstance().Memory().Write64(address, data); | ||||
| } | ||||
| 
 | ||||
| // Reads from the CP15 registers. Used with implementation of the MRC instruction.
 | ||||
|  |  | |||
|  | @ -49,9 +49,10 @@ static inline std::enable_if_t<std::is_integral_v<T>> CompOp(const GatewayCheat: | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static inline void LoadOffsetOp(const GatewayCheat::CheatLine& line, State& state) { | ||||
| static inline void LoadOffsetOp(Memory::MemorySystem& memory, const GatewayCheat::CheatLine& line, | ||||
|                                 State& state) { | ||||
|     u32 addr = line.address + state.offset; | ||||
|     state.offset = Memory::Read32(addr); | ||||
|     state.offset = memory.Read32(addr); | ||||
| } | ||||
| 
 | ||||
| static inline void LoopOp(const GatewayCheat::CheatLine& line, State& state) { | ||||
|  | @ -154,7 +155,7 @@ static inline void PatchOp(const GatewayCheat::CheatLine& line, State& state, Co | |||
|             state.current_line_nr++; | ||||
|         } | ||||
|         first = !first; | ||||
|         Memory::Write32(addr, tmp); | ||||
|         system.Memory().Write32(addr, tmp); | ||||
|         addr += 4; | ||||
|         num_bytes -= 4; | ||||
|     } | ||||
|  | @ -162,7 +163,7 @@ static inline void PatchOp(const GatewayCheat::CheatLine& line, State& state, Co | |||
|         u32 tmp = (first ? cheat_lines[state.current_line_nr].first | ||||
|                          : cheat_lines[state.current_line_nr].value) >> | ||||
|                   bit_offset; | ||||
|         Memory::Write8(addr, tmp); | ||||
|         system.Memory().Write8(addr, tmp); | ||||
|         addr += 1; | ||||
|         num_bytes -= 1; | ||||
|         bit_offset += 8; | ||||
|  | @ -205,6 +206,14 @@ GatewayCheat::~GatewayCheat() = default; | |||
| void GatewayCheat::Execute(Core::System& system) { | ||||
|     State state; | ||||
| 
 | ||||
|     Memory::MemorySystem& memory = system.Memory(); | ||||
|     auto Read8 = [&memory](VAddr addr) { return memory.Read8(addr); }; | ||||
|     auto Read16 = [&memory](VAddr addr) { return memory.Read16(addr); }; | ||||
|     auto Read32 = [&memory](VAddr addr) { return memory.Read32(addr); }; | ||||
|     auto Write8 = [&memory](VAddr addr, u8 value) { memory.Write8(addr, value); }; | ||||
|     auto Write16 = [&memory](VAddr addr, u16 value) { memory.Write16(addr, value); }; | ||||
|     auto Write32 = [&memory](VAddr addr, u32 value) { memory.Write32(addr, value); }; | ||||
| 
 | ||||
|     for (state.current_line_nr = 0; state.current_line_nr < cheat_lines.size(); | ||||
|          state.current_line_nr++) { | ||||
|         auto line = cheat_lines[state.current_line_nr]; | ||||
|  | @ -247,63 +256,61 @@ void GatewayCheat::Execute(Core::System& system) { | |||
|             break; | ||||
|         case CheatType::Write32: | ||||
|             // 0XXXXXXX YYYYYYYY - word[XXXXXXX+offset] = YYYYYYYY
 | ||||
|             WriteOp<u32>(line, state, &Memory::Write32, system); | ||||
|             WriteOp<u32>(line, state, Write32, system); | ||||
|             break; | ||||
|         case CheatType::Write16: | ||||
|             // 1XXXXXXX 0000YYYY - half[XXXXXXX+offset] = YYYY
 | ||||
|             WriteOp<u16>(line, state, &Memory::Write16, system); | ||||
|             WriteOp<u16>(line, state, Write16, system); | ||||
|             break; | ||||
|         case CheatType::Write8: | ||||
|             // 2XXXXXXX 000000YY - byte[XXXXXXX+offset] = YY
 | ||||
|             WriteOp<u8>(line, state, &Memory::Write8, system); | ||||
|             WriteOp<u8>(line, state, Write8, system); | ||||
|             break; | ||||
|         case CheatType::GreaterThan32: | ||||
|             // 3XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY > word[XXXXXXX]   ;unsigned
 | ||||
|             CompOp<u32>(line, state, &Memory::Read32, | ||||
|                         [&line](u32 val) -> bool { return line.value > val; }); | ||||
|             CompOp<u32>(line, state, Read32, [&line](u32 val) -> bool { return line.value > val; }); | ||||
|             break; | ||||
|         case CheatType::LessThan32: | ||||
|             // 4XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY < word[XXXXXXX]   ;unsigned
 | ||||
|             CompOp<u32>(line, state, &Memory::Read32, | ||||
|                         [&line](u32 val) -> bool { return line.value < val; }); | ||||
|             CompOp<u32>(line, state, Read32, [&line](u32 val) -> bool { return line.value < val; }); | ||||
|             break; | ||||
|         case CheatType::EqualTo32: | ||||
|             // 5XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY == word[XXXXXXX]   ;unsigned
 | ||||
|             CompOp<u32>(line, state, &Memory::Read32, | ||||
|             CompOp<u32>(line, state, Read32, | ||||
|                         [&line](u32 val) -> bool { return line.value == val; }); | ||||
|             break; | ||||
|         case CheatType::NotEqualTo32: | ||||
|             // 6XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY != word[XXXXXXX]   ;unsigned
 | ||||
|             CompOp<u32>(line, state, &Memory::Read32, | ||||
|             CompOp<u32>(line, state, Read32, | ||||
|                         [&line](u32 val) -> bool { return line.value != val; }); | ||||
|             break; | ||||
|         case CheatType::GreaterThan16WithMask: | ||||
|             // 7XXXXXXX ZZZZYYYY - Execute next block IF YYYY > ((not ZZZZ) AND half[XXXXXXX])
 | ||||
|             CompOp<u16>(line, state, &Memory::Read16, [&line](u16 val) -> bool { | ||||
|             CompOp<u16>(line, state, Read16, [&line](u16 val) -> bool { | ||||
|                 return static_cast<u16>(line.value) > (static_cast<u16>(~line.value >> 16) & val); | ||||
|             }); | ||||
|             break; | ||||
|         case CheatType::LessThan16WithMask: | ||||
|             // 8XXXXXXX ZZZZYYYY - Execute next block IF YYYY < ((not ZZZZ) AND half[XXXXXXX])
 | ||||
|             CompOp<u16>(line, state, &Memory::Read16, [&line](u16 val) -> bool { | ||||
|             CompOp<u16>(line, state, Read16, [&line](u16 val) -> bool { | ||||
|                 return static_cast<u16>(line.value) < (static_cast<u16>(~line.value >> 16) & val); | ||||
|             }); | ||||
|             break; | ||||
|         case CheatType::EqualTo16WithMask: | ||||
|             // 9XXXXXXX ZZZZYYYY - Execute next block IF YYYY = ((not ZZZZ) AND half[XXXXXXX])
 | ||||
|             CompOp<u16>(line, state, &Memory::Read16, [&line](u16 val) -> bool { | ||||
|             CompOp<u16>(line, state, Read16, [&line](u16 val) -> bool { | ||||
|                 return static_cast<u16>(line.value) == (static_cast<u16>(~line.value >> 16) & val); | ||||
|             }); | ||||
|             break; | ||||
|         case CheatType::NotEqualTo16WithMask: | ||||
|             // AXXXXXXX ZZZZYYYY - Execute next block IF YYYY <> ((not ZZZZ) AND half[XXXXXXX])
 | ||||
|             CompOp<u16>(line, state, &Memory::Read16, [&line](u16 val) -> bool { | ||||
|             CompOp<u16>(line, state, Read16, [&line](u16 val) -> bool { | ||||
|                 return static_cast<u16>(line.value) != (static_cast<u16>(~line.value >> 16) & val); | ||||
|             }); | ||||
|             break; | ||||
|         case CheatType::LoadOffset: | ||||
|             // BXXXXXXX 00000000 - offset = word[XXXXXXX+offset]
 | ||||
|             LoadOffsetOp(line, state); | ||||
|             LoadOffsetOp(system.Memory(), line, state); | ||||
|             break; | ||||
|         case CheatType::Loop: { | ||||
|             // C0000000 YYYYYYYY - LOOP next block YYYYYYYY times
 | ||||
|  | @ -343,32 +350,32 @@ void GatewayCheat::Execute(Core::System& system) { | |||
|         } | ||||
|         case CheatType::IncrementiveWrite32: { | ||||
|             // D6000000 XXXXXXXX – (32bit) [XXXXXXXX+offset] = reg ; offset += 4
 | ||||
|             IncrementiveWriteOp<u32>(line, state, &Memory::Write32, system); | ||||
|             IncrementiveWriteOp<u32>(line, state, Write32, system); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::IncrementiveWrite16: { | ||||
|             // D7000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xffff ; offset += 2
 | ||||
|             IncrementiveWriteOp<u16>(line, state, &Memory::Write16, system); | ||||
|             IncrementiveWriteOp<u16>(line, state, Write16, system); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::IncrementiveWrite8: { | ||||
|             // D8000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xff ; offset++
 | ||||
|             IncrementiveWriteOp<u8>(line, state, &Memory::Write8, system); | ||||
|             IncrementiveWriteOp<u8>(line, state, Write8, system); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::Load32: { | ||||
|             // D9000000 XXXXXXXX – reg = [XXXXXXXX+offset]
 | ||||
|             LoadOp<u32>(line, state, &Memory::Read32); | ||||
|             LoadOp<u32>(line, state, Read32); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::Load16: { | ||||
|             // DA000000 XXXXXXXX – reg = [XXXXXXXX+offset] & 0xFFFF
 | ||||
|             LoadOp<u16>(line, state, &Memory::Read16); | ||||
|             LoadOp<u16>(line, state, Read16); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::Load8: { | ||||
|             // DB000000 XXXXXXXX – reg = [XXXXXXXX+offset] & 0xFF
 | ||||
|             LoadOp<u8>(line, state, &Memory::Read8); | ||||
|             LoadOp<u8>(line, state, Read8); | ||||
|             break; | ||||
|         } | ||||
|         case CheatType::AddOffset: { | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ SharedPtr<Thread> AddressArbiter::ResumeHighestPriorityThread(VAddr address) { | |||
|     return thread; | ||||
| } | ||||
| 
 | ||||
| AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel) {} | ||||
| AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} | ||||
| AddressArbiter::~AddressArbiter() {} | ||||
| 
 | ||||
| SharedPtr<AddressArbiter> KernelSystem::CreateAddressArbiter(std::string name) { | ||||
|  | @ -103,31 +103,31 @@ ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, Arbitratio | |||
| 
 | ||||
|     // Wait current thread (acquire the arbiter)...
 | ||||
|     case ArbitrationType::WaitIfLessThan: | ||||
|         if ((s32)Memory::Read32(address) < value) { | ||||
|         if ((s32)kernel.memory.Read32(address) < value) { | ||||
|             WaitThread(std::move(thread), address); | ||||
|         } | ||||
|         break; | ||||
|     case ArbitrationType::WaitIfLessThanWithTimeout: | ||||
|         if ((s32)Memory::Read32(address) < value) { | ||||
|         if ((s32)kernel.memory.Read32(address) < value) { | ||||
|             thread->wakeup_callback = timeout_callback; | ||||
|             thread->WakeAfterDelay(nanoseconds); | ||||
|             WaitThread(std::move(thread), address); | ||||
|         } | ||||
|         break; | ||||
|     case ArbitrationType::DecrementAndWaitIfLessThan: { | ||||
|         s32 memory_value = Memory::Read32(address); | ||||
|         s32 memory_value = kernel.memory.Read32(address); | ||||
|         if (memory_value < value) { | ||||
|             // Only change the memory value if the thread should wait
 | ||||
|             Memory::Write32(address, (s32)memory_value - 1); | ||||
|             kernel.memory.Write32(address, (s32)memory_value - 1); | ||||
|             WaitThread(std::move(thread), address); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: { | ||||
|         s32 memory_value = Memory::Read32(address); | ||||
|         s32 memory_value = kernel.memory.Read32(address); | ||||
|         if (memory_value < value) { | ||||
|             // Only change the memory value if the thread should wait
 | ||||
|             Memory::Write32(address, (s32)memory_value - 1); | ||||
|             kernel.memory.Write32(address, (s32)memory_value - 1); | ||||
|             thread->wakeup_callback = timeout_callback; | ||||
|             thread->WakeAfterDelay(nanoseconds); | ||||
|             WaitThread(std::move(thread), address); | ||||
|  |  | |||
|  | @ -52,6 +52,8 @@ private: | |||
|     explicit AddressArbiter(KernelSystem& kernel); | ||||
|     ~AddressArbiter() override; | ||||
| 
 | ||||
|     KernelSystem& kernel; | ||||
| 
 | ||||
|     /// Puts the thread to wait on the specified arbitration address under this address arbiter.
 | ||||
|     void WaitThread(SharedPtr<Thread> thread, VAddr wait_address); | ||||
| 
 | ||||
|  |  | |||
|  | @ -352,7 +352,7 @@ ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) { | |||
| 
 | ||||
|     static constexpr std::size_t PortNameMaxLength = 11; | ||||
|     // Read 1 char beyond the max allowed port name to detect names that are too long.
 | ||||
|     std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | ||||
|     std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); | ||||
|     if (port_name.size() > PortNameMaxLength) | ||||
|         return ERR_PORT_NAME_TOO_LONG; | ||||
| 
 | ||||
|  | @ -467,7 +467,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle | |||
|     std::vector<ObjectPtr> objects(handle_count); | ||||
| 
 | ||||
|     for (int i = 0; i < handle_count; ++i) { | ||||
|         Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | ||||
|         Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); | ||||
|         auto object = kernel.GetCurrentProcess()->handle_table.Get<WaitObject>(handle); | ||||
|         if (object == nullptr) | ||||
|             return ERR_INVALID_HANDLE; | ||||
|  | @ -636,7 +636,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
|     SharedPtr<Process> current_process = kernel.GetCurrentProcess(); | ||||
| 
 | ||||
|     for (int i = 0; i < handle_count; ++i) { | ||||
|         Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | ||||
|         Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); | ||||
|         auto object = current_process->handle_table.Get<WaitObject>(handle); | ||||
|         if (object == nullptr) | ||||
|             return ERR_INVALID_HANDLE; | ||||
|  | @ -646,7 +646,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co | |||
|     // We are also sending a command reply.
 | ||||
|     // Do not send a reply if the command id in the command buffer is 0xFFFF.
 | ||||
|     Thread* thread = kernel.GetThreadManager().GetCurrentThread(); | ||||
|     u32 cmd_buff_header = Memory::Read32(thread->GetCommandBufferAddress()); | ||||
|     u32 cmd_buff_header = memory.Read32(thread->GetCommandBufferAddress()); | ||||
|     IPC::Header header{cmd_buff_header}; | ||||
|     if (reply_target != 0 && header.command_id != 0xFFFF) { | ||||
|         auto session = current_process->handle_table.Get<ServerSession>(reply_target); | ||||
|  | @ -832,9 +832,9 @@ ResultCode SVC::GetResourceLimitCurrentValues(VAddr values, Handle resource_limi | |||
|         return ERR_INVALID_HANDLE; | ||||
| 
 | ||||
|     for (unsigned int i = 0; i < name_count; ++i) { | ||||
|         u32 name = Memory::Read32(names + i * sizeof(u32)); | ||||
|         u32 name = memory.Read32(names + i * sizeof(u32)); | ||||
|         s64 value = resource_limit->GetCurrentResourceValue(name); | ||||
|         Memory::Write64(values + i * sizeof(u64), value); | ||||
|         memory.Write64(values + i * sizeof(u64), value); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
|  | @ -852,9 +852,9 @@ ResultCode SVC::GetResourceLimitLimitValues(VAddr values, Handle resource_limit_ | |||
|         return ERR_INVALID_HANDLE; | ||||
| 
 | ||||
|     for (unsigned int i = 0; i < name_count; ++i) { | ||||
|         u32 name = Memory::Read32(names + i * sizeof(u32)); | ||||
|         u32 name = memory.Read32(names + i * sizeof(u32)); | ||||
|         s64 value = resource_limit->GetMaxResourceValue(name); | ||||
|         Memory::Write64(values + i * sizeof(u64), value); | ||||
|         memory.Write64(values + i * sizeof(u64), value); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
|  |  | |||
|  | @ -71,11 +71,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc | |||
|         break; | ||||
|     case RelocationType::AbsoluteAddress: | ||||
|     case RelocationType::AbsoluteAddress2: | ||||
|         Memory::Write32(target_address, symbol_address + addend); | ||||
|         memory.Write32(target_address, symbol_address + addend); | ||||
|         Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); | ||||
|         break; | ||||
|     case RelocationType::RelativeAddress: | ||||
|         Memory::Write32(target_address, symbol_address + addend - target_future_address); | ||||
|         memory.Write32(target_address, symbol_address + addend - target_future_address); | ||||
|         Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); | ||||
|         break; | ||||
|     case RelocationType::ThumbBranch: | ||||
|  | @ -98,7 +98,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc | |||
|     case RelocationType::AbsoluteAddress: | ||||
|     case RelocationType::AbsoluteAddress2: | ||||
|     case RelocationType::RelativeAddress: | ||||
|         Memory::Write32(target_address, 0); | ||||
|         memory.Write32(target_address, 0); | ||||
|         Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); | ||||
|         break; | ||||
|     case RelocationType::ThumbBranch: | ||||
|  | @ -188,7 +188,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const { | |||
|     ExportNamedSymbolEntry symbol_entry; | ||||
|     GetEntry(found_id, symbol_entry); | ||||
| 
 | ||||
|     if (Memory::ReadCString(symbol_entry.name_offset, export_strings_size) != name) | ||||
|     if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name) | ||||
|         return 0; | ||||
| 
 | ||||
|     return SegmentTagToAddress(symbol_entry.symbol_position); | ||||
|  | @ -761,7 +761,7 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) { | |||
|             ResultCode result = ForEachAutoLinkCRO( | ||||
|                 process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> { | ||||
|                     std::string symbol_name = | ||||
|                         Memory::ReadCString(entry.name_offset, import_strings_size); | ||||
|                         memory.ReadCString(entry.name_offset, import_strings_size); | ||||
|                     u32 symbol_address = source.FindExportNamedSymbol(symbol_name); | ||||
| 
 | ||||
|                     if (symbol_address != 0) { | ||||
|  | @ -858,7 +858,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { | |||
|     for (u32 i = 0; i < import_module_num; ++i) { | ||||
|         ImportModuleEntry entry; | ||||
|         GetEntry(i, entry); | ||||
|         std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); | ||||
|         std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size); | ||||
| 
 | ||||
|         ResultCode result = ForEachAutoLinkCRO( | ||||
|             process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> { | ||||
|  | @ -921,7 +921,7 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { | |||
| 
 | ||||
|         if (!relocation_entry.is_batch_resolved) { | ||||
|             std::string symbol_name = | ||||
|                 Memory::ReadCString(entry.name_offset, target_import_strings_size); | ||||
|                 memory.ReadCString(entry.name_offset, target_import_strings_size); | ||||
|             u32 symbol_address = FindExportNamedSymbol(symbol_name); | ||||
|             if (symbol_address != 0) { | ||||
|                 LOG_TRACE(Service_LDR, "    exports symbol \"{}\"", symbol_name); | ||||
|  | @ -952,7 +952,7 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { | |||
| 
 | ||||
|         if (relocation_entry.is_batch_resolved) { | ||||
|             std::string symbol_name = | ||||
|                 Memory::ReadCString(entry.name_offset, target_import_strings_size); | ||||
|                 memory.ReadCString(entry.name_offset, target_import_strings_size); | ||||
|             u32 symbol_address = FindExportNamedSymbol(symbol_name); | ||||
|             if (symbol_address != 0) { | ||||
|                 LOG_TRACE(Service_LDR, "    unexports symbol \"{}\"", symbol_name); | ||||
|  | @ -976,7 +976,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { | |||
|         ImportModuleEntry entry; | ||||
|         target.GetEntry(i, entry); | ||||
| 
 | ||||
|         if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) | ||||
|         if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name) | ||||
|             continue; | ||||
| 
 | ||||
|         LOG_INFO(Service_LDR, "CRO \"{}\" exports {} indexed symbols to \"{}\"", module_name, | ||||
|  | @ -1025,7 +1025,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { | |||
|         ImportModuleEntry entry; | ||||
|         target.GetEntry(i, entry); | ||||
| 
 | ||||
|         if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) | ||||
|         if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name) | ||||
|             continue; | ||||
| 
 | ||||
|         LOG_DEBUG(Service_LDR, "CRO \"{}\" unexports indexed symbols to \"{}\"", module_name, | ||||
|  | @ -1069,7 +1069,7 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { | |||
|         Memory::ReadBlock(process, relocation_addr, &relocation_entry, | ||||
|                           sizeof(ExternalRelocationEntry)); | ||||
| 
 | ||||
|         if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { | ||||
|         if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { | ||||
|             ResultCode result = ForEachAutoLinkCRO( | ||||
|                 process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> { | ||||
|                     u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); | ||||
|  | @ -1108,9 +1108,9 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { | |||
|  * @param size the size of the string (table), including the terminating 0 | ||||
|  * @returns ResultCode RESULT_SUCCESS if the size matches, otherwise error code. | ||||
|  */ | ||||
| static ResultCode VerifyStringTableLength(VAddr address, u32 size) { | ||||
| static ResultCode VerifyStringTableLength(Memory::MemorySystem& memory, VAddr address, u32 size) { | ||||
|     if (size != 0) { | ||||
|         if (Memory::Read8(address + size - 1) != 0) | ||||
|         if (memory.Read8(address + size - 1) != 0) | ||||
|             return CROFormatError(0x0B); | ||||
|     } | ||||
|     return RESULT_SUCCESS; | ||||
|  | @ -1126,7 +1126,7 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment | |||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     result = VerifyStringTableLength(GetField(ModuleNameOffset), GetField(ModuleNameSize)); | ||||
|     result = VerifyStringTableLength(memory, GetField(ModuleNameOffset), GetField(ModuleNameSize)); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error verifying module name {:08X}", result.raw); | ||||
|         return result; | ||||
|  | @ -1155,7 +1155,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment | |||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     result = VerifyStringTableLength(GetField(ExportStringsOffset), GetField(ExportStringsSize)); | ||||
|     result = | ||||
|         VerifyStringTableLength(memory, GetField(ExportStringsOffset), GetField(ExportStringsSize)); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error verifying export strings {:08X}", result.raw); | ||||
|         return result; | ||||
|  | @ -1191,7 +1192,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment | |||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     result = VerifyStringTableLength(GetField(ImportStringsOffset), GetField(ImportStringsSize)); | ||||
|     result = | ||||
|         VerifyStringTableLength(memory, GetField(ImportStringsOffset), GetField(ImportStringsSize)); | ||||
|     if (result.IsError()) { | ||||
|         LOG_ERROR(Service_LDR, "Error verifying import strings {:08X}", result.raw); | ||||
|         return result; | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ public: | |||
|         : module_address(cro_address), process(process), memory(memory) {} | ||||
| 
 | ||||
|     std::string ModuleName() const { | ||||
|         return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); | ||||
|         return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); | ||||
|     } | ||||
| 
 | ||||
|     u32 GetFileSize() const { | ||||
|  | @ -408,11 +408,11 @@ private: | |||
|     } | ||||
| 
 | ||||
|     u32 GetField(HeaderField field) const { | ||||
|         return Memory::Read32(Field(field)); | ||||
|         return memory.Read32(Field(field)); | ||||
|     } | ||||
| 
 | ||||
|     void SetField(HeaderField field, u32 value) { | ||||
|         Memory::Write32(Field(field), value); | ||||
|         memory.Write32(Field(field), value); | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ template <typename T> | |||
| T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr); | ||||
| 
 | ||||
| template <typename T> | ||||
| T Read(const VAddr vaddr) { | ||||
| T MemorySystem::Read(const VAddr vaddr) { | ||||
|     const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | ||||
|     if (page_pointer) { | ||||
|         // NOTE: Avoid adding any extra logic to this fast-path block
 | ||||
|  | @ -152,7 +152,7 @@ template <typename T> | |||
| void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const T data); | ||||
| 
 | ||||
| template <typename T> | ||||
| void Write(const VAddr vaddr, const T data) { | ||||
| void MemorySystem::Write(const VAddr vaddr, const T data) { | ||||
|     u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | ||||
|     if (page_pointer) { | ||||
|         // NOTE: Avoid adding any extra logic to this fast-path block
 | ||||
|  | @ -224,7 +224,7 @@ u8* MemorySystem::GetPointer(const VAddr vaddr) { | |||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| std::string ReadCString(VAddr vaddr, std::size_t max_length) { | ||||
| std::string MemorySystem::ReadCString(VAddr vaddr, std::size_t max_length) { | ||||
|     std::string string; | ||||
|     string.reserve(max_length); | ||||
|     for (std::size_t i = 0; i < max_length; ++i) { | ||||
|  | @ -417,19 +417,19 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { | |||
|     CheckRegion(VRAM_VADDR, VRAM_VADDR_END, VRAM_PADDR); | ||||
| } | ||||
| 
 | ||||
| u8 Read8(const VAddr addr) { | ||||
| u8 MemorySystem::Read8(const VAddr addr) { | ||||
|     return Read<u8>(addr); | ||||
| } | ||||
| 
 | ||||
| u16 Read16(const VAddr addr) { | ||||
| u16 MemorySystem::Read16(const VAddr addr) { | ||||
|     return Read<u16_le>(addr); | ||||
| } | ||||
| 
 | ||||
| u32 Read32(const VAddr addr) { | ||||
| u32 MemorySystem::Read32(const VAddr addr) { | ||||
|     return Read<u32_le>(addr); | ||||
| } | ||||
| 
 | ||||
| u64 Read64(const VAddr addr) { | ||||
| u64 MemorySystem::Read64(const VAddr addr) { | ||||
|     return Read<u64_le>(addr); | ||||
| } | ||||
| 
 | ||||
|  | @ -483,19 +483,19 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Write8(const VAddr addr, const u8 data) { | ||||
| void MemorySystem::Write8(const VAddr addr, const u8 data) { | ||||
|     Write<u8>(addr, data); | ||||
| } | ||||
| 
 | ||||
| void Write16(const VAddr addr, const u16 data) { | ||||
| void MemorySystem::Write16(const VAddr addr, const u16 data) { | ||||
|     Write<u16_le>(addr, data); | ||||
| } | ||||
| 
 | ||||
| void Write32(const VAddr addr, const u32 data) { | ||||
| void MemorySystem::Write32(const VAddr addr, const u32 data) { | ||||
|     Write<u32_le>(addr, data); | ||||
| } | ||||
| 
 | ||||
| void Write64(const VAddr addr, const u64 data) { | ||||
| void MemorySystem::Write64(const VAddr addr, const u64 data) { | ||||
|     Write<u64_le>(addr, data); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -180,16 +180,6 @@ enum : VAddr { | |||
| 
 | ||||
| extern std::array<u8, Memory::FCRAM_N3DS_SIZE> fcram; | ||||
| 
 | ||||
| u8 Read8(VAddr addr); | ||||
| u16 Read16(VAddr addr); | ||||
| u32 Read32(VAddr addr); | ||||
| u64 Read64(VAddr addr); | ||||
| 
 | ||||
| void Write8(VAddr addr, u8 data); | ||||
| void Write16(VAddr addr, u16 data); | ||||
| void Write32(VAddr addr, u32 data); | ||||
| void Write64(VAddr addr, u64 data); | ||||
| 
 | ||||
| void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, std::size_t size); | ||||
| void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, | ||||
|                 std::size_t size); | ||||
|  | @ -198,8 +188,6 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, | |||
| void CopyBlock(const Kernel::Process& src_process, const Kernel::Process& dest_process, | ||||
|                VAddr src_addr, VAddr dest_addr, std::size_t size); | ||||
| 
 | ||||
| std::string ReadCString(VAddr vaddr, std::size_t max_length); | ||||
| 
 | ||||
| /**
 | ||||
|  * Mark each page touching the region as cached. | ||||
|  */ | ||||
|  | @ -241,6 +229,18 @@ public: | |||
|     void SetCurrentPageTable(PageTable* page_table); | ||||
|     PageTable* GetCurrentPageTable(); | ||||
| 
 | ||||
|     u8 Read8(VAddr addr); | ||||
|     u16 Read16(VAddr addr); | ||||
|     u32 Read32(VAddr addr); | ||||
|     u64 Read64(VAddr addr); | ||||
| 
 | ||||
|     void Write8(VAddr addr, u8 data); | ||||
|     void Write16(VAddr addr, u16 data); | ||||
|     void Write32(VAddr addr, u32 data); | ||||
|     void Write64(VAddr addr, u64 data); | ||||
| 
 | ||||
|     std::string ReadCString(VAddr vaddr, std::size_t max_length); | ||||
| 
 | ||||
|     /// Determines if the given VAddr is valid for the specified process.
 | ||||
|     bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); | ||||
| 
 | ||||
|  | @ -255,6 +255,13 @@ public: | |||
| 
 | ||||
|     /// Gets offset in FCRAM from a pointer inside FCRAM range
 | ||||
|     u32 GetFCRAMOffset(u8* pointer); | ||||
| 
 | ||||
| private: | ||||
|     template <typename T> | ||||
|     T Read(const VAddr vaddr); | ||||
| 
 | ||||
|     template <typename T> | ||||
|     void Write(const VAddr vaddr, const T data); | ||||
| }; | ||||
| 
 | ||||
| } // namespace Memory
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue