mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	tests: Arm testing framework
This commit is contained in:
		
							parent
							
								
									c6a2e519ef
								
							
						
					
					
						commit
						567c3a2ee7
					
				
					 3 changed files with 208 additions and 0 deletions
				
			
		|  | @ -1,5 +1,6 @@ | ||||||
| set(SRCS | set(SRCS | ||||||
|             common/param_package.cpp |             common/param_package.cpp | ||||||
|  |             core/arm/arm_test_common.cpp | ||||||
|             core/file_sys/path_parser.cpp |             core/file_sys/path_parser.cpp | ||||||
|             core/hle/kernel/hle_ipc.cpp |             core/hle/kernel/hle_ipc.cpp | ||||||
|             glad.cpp |             glad.cpp | ||||||
|  | @ -7,6 +8,7 @@ set(SRCS | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
| set(HEADERS | set(HEADERS | ||||||
|  |             core/arm/arm_test_common.h | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
| create_directory_groups(${SRCS} ${HEADERS}) | create_directory_groups(${SRCS} ${HEADERS}) | ||||||
|  |  | ||||||
							
								
								
									
										123
									
								
								src/tests/core/arm/arm_test_common.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/tests/core/arm/arm_test_common.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,123 @@ | ||||||
|  | // Copyright 2016 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include "core/core.h" | ||||||
|  | #include "core/memory_setup.h" | ||||||
|  | #include "tests/core/arm/arm_test_common.h" | ||||||
|  | 
 | ||||||
|  | namespace ArmTests { | ||||||
|  | 
 | ||||||
|  | TestEnvironment::TestEnvironment(bool mutable_memory_) | ||||||
|  |         : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { | ||||||
|  |     Memory::MapIoRegion(0x00000000, 0x80000000, test_memory); | ||||||
|  |     Memory::MapIoRegion(0x80000000, 0x80000000, test_memory); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TestEnvironment::~TestEnvironment() { | ||||||
|  |     Memory::UnmapRegion(0x80000000, 0x80000000); | ||||||
|  |     Memory::UnmapRegion(0x00000000, 0x80000000); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) { | ||||||
|  |     SetMemory32(vaddr + 0, static_cast<u32>(value)); | ||||||
|  |     SetMemory32(vaddr + 4, static_cast<u32>(value >> 32)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::SetMemory32(VAddr vaddr, u32 value) { | ||||||
|  |     SetMemory16(vaddr + 0, static_cast<u16>(value)); | ||||||
|  |     SetMemory16(vaddr + 2, static_cast<u16>(value >> 16)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::SetMemory16(VAddr vaddr, u16 value) { | ||||||
|  |     SetMemory8(vaddr + 0, static_cast<u8>(value)); | ||||||
|  |     SetMemory8(vaddr + 1, static_cast<u8>(value >> 8)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::SetMemory8(VAddr vaddr, u8 value) { | ||||||
|  |     test_memory->data[vaddr] = value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<WriteRecord> TestEnvironment::GetWriteRecords() const { | ||||||
|  |     return write_records; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::ClearWriteRecords() { | ||||||
|  |     write_records.clear(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TestEnvironment::TestMemory::~TestMemory() {} | ||||||
|  | 
 | ||||||
|  | bool TestEnvironment::TestMemory::IsValidAddress(VAddr addr) { | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | u8 TestEnvironment::TestMemory::Read8(VAddr addr) { | ||||||
|  |     auto iter = data.find(addr); | ||||||
|  |     if (iter == data.end()) { | ||||||
|  |         return addr; // Some arbitrary data
 | ||||||
|  |     } | ||||||
|  |     return iter->second; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | u16 TestEnvironment::TestMemory::Read16(VAddr addr) { | ||||||
|  |     return Read8(addr) | static_cast<u16>(Read8(addr + 1)) << 8; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | u32 TestEnvironment::TestMemory::Read32(VAddr addr) { | ||||||
|  |     return Read16(addr) | static_cast<u32>(Read16(addr + 2)) << 16; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | u64 TestEnvironment::TestMemory::Read64(VAddr addr) { | ||||||
|  |     return Read32(addr) | static_cast<u64>(Read32(addr + 4)) << 32; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool TestEnvironment::TestMemory::ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) { | ||||||
|  |     VAddr addr = src_addr; | ||||||
|  |     u8* data = static_cast<u8*>(dest_buffer); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < size; i++, addr++, data++) { | ||||||
|  |         *data = Read8(addr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::TestMemory::Write8(VAddr addr, u8 data) { | ||||||
|  |     env->write_records.emplace_back(8, addr, data); | ||||||
|  |     if (env->mutable_memory) | ||||||
|  |         env->SetMemory8(addr, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::TestMemory::Write16(VAddr addr, u16 data) { | ||||||
|  |     env->write_records.emplace_back(16, addr, data); | ||||||
|  |     if (env->mutable_memory) | ||||||
|  |         env->SetMemory16(addr, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::TestMemory::Write32(VAddr addr, u32 data) { | ||||||
|  |     env->write_records.emplace_back(32, addr, data); | ||||||
|  |     if (env->mutable_memory) | ||||||
|  |         env->SetMemory32(addr, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TestEnvironment::TestMemory::Write64(VAddr addr, u64 data) { | ||||||
|  |     env->write_records.emplace_back(64, addr, data); | ||||||
|  |     if (env->mutable_memory) | ||||||
|  |         env->SetMemory64(addr, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool TestEnvironment::TestMemory::WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) { | ||||||
|  |     VAddr addr = dest_addr; | ||||||
|  |     const u8* data = static_cast<const u8*>(src_buffer); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < size; i++, addr++, data++) { | ||||||
|  |         env->write_records.emplace_back(8, addr, *data); | ||||||
|  |         if (env->mutable_memory) | ||||||
|  |             env->SetMemory8(addr, *data); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace ArmTests
 | ||||||
							
								
								
									
										83
									
								
								src/tests/core/arm/arm_test_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/tests/core/arm/arm_test_common.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,83 @@ | ||||||
|  | // Copyright 2016 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include <tuple> | ||||||
|  | #include <unordered_map> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "core/mmio.h" | ||||||
|  | 
 | ||||||
|  | namespace ArmTests { | ||||||
|  | 
 | ||||||
|  | struct WriteRecord { | ||||||
|  |     WriteRecord(size_t size, VAddr addr, u64 data) : size(size), addr(addr), data(data) {} | ||||||
|  |     size_t size; | ||||||
|  |     VAddr addr; | ||||||
|  |     u64 data; | ||||||
|  |     bool operator==(const WriteRecord& o) const { | ||||||
|  |         return std::tie(size, addr, data) == std::tie(o.size, o.addr, o.data); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class TestEnvironment final { | ||||||
|  | public: | ||||||
|  |     /*
 | ||||||
|  |      * Inititalise test environment | ||||||
|  |      * @param mutable_memory If false, writes to memory can never be read back. (Memory is immutable.) | ||||||
|  |      */ | ||||||
|  |     explicit TestEnvironment(bool mutable_memory = false); | ||||||
|  | 
 | ||||||
|  |     /// Shutdown test environment
 | ||||||
|  |     ~TestEnvironment(); | ||||||
|  | 
 | ||||||
|  |     /// Sets value at memory location vaddr.
 | ||||||
|  |     void SetMemory8(VAddr vaddr, u8 value); | ||||||
|  |     void SetMemory16(VAddr vaddr, u16 value); | ||||||
|  |     void SetMemory32(VAddr vaddr, u32 value); | ||||||
|  |     void SetMemory64(VAddr vaddr, u64 value); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Whenever Memory::Write{8,16,32,64} is called within the test environment, | ||||||
|  |      * a new write-record is made. | ||||||
|  |      * @returns A vector of write records made since they were last cleared. | ||||||
|  |      */ | ||||||
|  |     std::vector<WriteRecord> GetWriteRecords() const; | ||||||
|  | 
 | ||||||
|  |     /// Empties the internal write-record store.
 | ||||||
|  |     void ClearWriteRecords(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     friend struct TestMemory; | ||||||
|  |     struct TestMemory final : Memory::MMIORegion { | ||||||
|  |         explicit TestMemory(TestEnvironment* env_) : env(env_) {} | ||||||
|  |         TestEnvironment* env; | ||||||
|  | 
 | ||||||
|  |         ~TestMemory() override; | ||||||
|  | 
 | ||||||
|  |         bool IsValidAddress(VAddr addr) override; | ||||||
|  | 
 | ||||||
|  |         u8 Read8(VAddr addr) override; | ||||||
|  |         u16 Read16(VAddr addr) override; | ||||||
|  |         u32 Read32(VAddr addr) override; | ||||||
|  |         u64 Read64(VAddr addr) override; | ||||||
|  | 
 | ||||||
|  |         bool ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) override; | ||||||
|  | 
 | ||||||
|  |         void Write8(VAddr addr, u8 data) override; | ||||||
|  |         void Write16(VAddr addr, u16 data) override; | ||||||
|  |         void Write32(VAddr addr, u32 data) override; | ||||||
|  |         void Write64(VAddr addr, u64 data) override; | ||||||
|  | 
 | ||||||
|  |         bool WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) override; | ||||||
|  | 
 | ||||||
|  |         std::unordered_map<VAddr, u8> data; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     bool mutable_memory; | ||||||
|  |     std::shared_ptr<TestMemory> test_memory; | ||||||
|  |     std::vector<WriteRecord> write_records; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace ArmTests
 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue