mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Process: Support parsing of exheader kernel caps
This commit is contained in:
		
							parent
							
								
									326ec51261
								
							
						
					
					
						commit
						2af30d465f
					
				
					 6 changed files with 77 additions and 4 deletions
				
			
		|  | @ -3,24 +3,91 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
|  | #include "common/common_funcs.h" | ||||||
|  | #include "common/logging/log.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
|  | #include "core/mem_map.h" | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| SharedPtr<Process> Process::Create(std::string name, u64 program_id) { | SharedPtr<Process> Process::Create(std::string name, u64 program_id) { | ||||||
|     SharedPtr<Process> process(new Process); |     SharedPtr<Process> process(new Process); | ||||||
| 
 | 
 | ||||||
|     process->svc_access_mask.set(); |  | ||||||
|     process->name = std::move(name); |     process->name = std::move(name); | ||||||
|     process->program_id = program_id; |     process->program_id = program_id; | ||||||
| 
 | 
 | ||||||
|     return process; |     return process; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Process::ParseKernelCaps(const u32 * kernel_caps, size_t len) { | void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | ||||||
|     //UNIMPLEMENTED();
 |     for (int i = 0; i < len; ++i) { | ||||||
|  |         u32 descriptor = kernel_caps[i]; | ||||||
|  |         u32 type = descriptor >> 20; | ||||||
|  | 
 | ||||||
|  |         if (descriptor == 0xFFFFFFFF) { | ||||||
|  |             // Unused descriptor entry
 | ||||||
|  |             continue; | ||||||
|  |         } else if ((type & 0xF00) == 0xE00) { // 0x0FFF
 | ||||||
|  |             // Allowed interrupts list
 | ||||||
|  |             LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); | ||||||
|  |         } else if ((type & 0xF80) == 0xF00) { // 0x07FF
 | ||||||
|  |             // Allowed syscalls mask
 | ||||||
|  |             unsigned int index = ((descriptor >> 24) & 7) * 24; | ||||||
|  |             u32 bits = descriptor & 0xFFFFFF; | ||||||
|  | 
 | ||||||
|  |             while (bits && index < svc_access_mask.size()) { | ||||||
|  |                 svc_access_mask.set(index, bits & 1); | ||||||
|  |                 ++index; bits >>= 1; | ||||||
|  |             } | ||||||
|  |         } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF
 | ||||||
|  |             // Handle table size
 | ||||||
|  |             handle_table_size = descriptor & 0x3FF; | ||||||
|  |         } else if ((type & 0xFF8) == 0xFF0) { // 0x007F
 | ||||||
|  |             // Misc. flags
 | ||||||
|  |             bool allow_debug       = descriptor & BIT(0); | ||||||
|  |             bool force_debug       = descriptor & BIT(1); | ||||||
|  |             bool allow_nonalphanum = descriptor & BIT(2); | ||||||
|  |             shared_page_writable   = descriptor & BIT(3); | ||||||
|  |             privileged_priority    = descriptor & BIT(4); | ||||||
|  |             bool allow_main_args   = descriptor & BIT(5); | ||||||
|  |             bool shared_device_mem = descriptor & BIT(6); | ||||||
|  |             bool runnable_on_sleep = descriptor & BIT(7); | ||||||
|  |             loaded_high            = descriptor & BIT(12); | ||||||
|  |             memory_region = MemoryRegion((descriptor >> 8) & 0xF); | ||||||
|  |         } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
 | ||||||
|  |             // Mapped memory range
 | ||||||
|  |             if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) { | ||||||
|  |                 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             u32 end_desc = kernel_caps[i+1]; | ||||||
|  |             ++i; // Skip over the second descriptor on the next iteration
 | ||||||
|  | 
 | ||||||
|  |             StaticAddressMapping mapping; | ||||||
|  |             mapping.address = descriptor << 12; | ||||||
|  |             mapping.size = (end_desc << 12) - mapping.address; | ||||||
|  |             mapping.writable = descriptor & BIT(20); | ||||||
|  |             mapping.unk_flag = end_desc & BIT(20); | ||||||
|  | 
 | ||||||
|  |             static_address_mappings.push_back(mapping); | ||||||
|  |         } else if ((type & 0xFFF) == 0xFFE) { // 0x000F
 | ||||||
|  |             // Mapped memory page
 | ||||||
|  |             StaticAddressMapping mapping; | ||||||
|  |             mapping.address = descriptor << 12; | ||||||
|  |             mapping.size = Memory::PAGE_SIZE; | ||||||
|  |             mapping.writable = true; // TODO: Not sure if correct
 | ||||||
|  |             mapping.unk_flag = false; | ||||||
|  |         } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF
 | ||||||
|  |             // Kernel version
 | ||||||
|  |             int minor = descriptor & 0xFF; | ||||||
|  |             int major = (descriptor >> 8) & 0xFF; | ||||||
|  |             LOG_INFO(Loader, "ExHeader kernel version ignored: %d.%d", major, minor); | ||||||
|  |         } else { | ||||||
|  |             LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | ||||||
|  |  | ||||||
|  | @ -14,10 +14,11 @@ | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| struct StaticAddressMapping { | struct StaticAddressMapping { | ||||||
|     // Address and size must be 4K-aligned
 |     // Address and size must be page-aligned
 | ||||||
|     VAddr address; |     VAddr address; | ||||||
|     u32 size; |     u32 size; | ||||||
|     bool writable; |     bool writable; | ||||||
|  |     bool unk_flag; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum class MemoryRegion { | enum class MemoryRegion { | ||||||
|  |  | ||||||
|  | @ -231,6 +231,7 @@ ResultStatus AppLoader_THREEDSX::Load() { | ||||||
|         return ResultStatus::Error; |         return ResultStatus::Error; | ||||||
| 
 | 
 | ||||||
|     Kernel::g_current_process = Kernel::Process::Create(filename, 0); |     Kernel::g_current_process = Kernel::Process::Create(filename, 0); | ||||||
|  |     Kernel::g_current_process->svc_access_mask.set(); | ||||||
|     Kernel::g_current_process->static_address_mappings = default_address_mappings; |     Kernel::g_current_process->static_address_mappings = default_address_mappings; | ||||||
| 
 | 
 | ||||||
|     Load3DSXFile(*file, Memory::EXEFS_CODE_VADDR); |     Load3DSXFile(*file, Memory::EXEFS_CODE_VADDR); | ||||||
|  |  | ||||||
|  | @ -351,6 +351,7 @@ ResultStatus AppLoader_ELF::Load() { | ||||||
|         return ResultStatus::Error; |         return ResultStatus::Error; | ||||||
| 
 | 
 | ||||||
|     Kernel::g_current_process = Kernel::Process::Create(filename, 0); |     Kernel::g_current_process = Kernel::Process::Create(filename, 0); | ||||||
|  |     Kernel::g_current_process->svc_access_mask.set(); | ||||||
|     Kernel::g_current_process->static_address_mappings = default_address_mappings; |     Kernel::g_current_process->static_address_mappings = default_address_mappings; | ||||||
| 
 | 
 | ||||||
|     ElfReader elf_reader(&buffer[0]); |     ElfReader elf_reader(&buffer[0]); | ||||||
|  |  | ||||||
|  | @ -141,6 +141,7 @@ ResultStatus LoadFile(const std::string& filename) { | ||||||
|     case FileType::BIN: |     case FileType::BIN: | ||||||
|     { |     { | ||||||
|         Kernel::g_current_process = Kernel::Process::Create(filename_filename, 0); |         Kernel::g_current_process = Kernel::Process::Create(filename_filename, 0); | ||||||
|  |         Kernel::g_current_process->svc_access_mask.set(); | ||||||
|         Kernel::g_current_process->static_address_mappings = default_address_mappings; |         Kernel::g_current_process->static_address_mappings = default_address_mappings; | ||||||
| 
 | 
 | ||||||
|         size_t size = (size_t)file->GetSize(); |         size_t size = (size_t)file->GetSize(); | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ namespace Memory { | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
|  | const u32 PAGE_SIZE = 0x1000; | ||||||
|  | 
 | ||||||
| enum : u32 { | enum : u32 { | ||||||
|     BOOTROM_SIZE                = 0x00010000,   ///< Bootrom (super secret code/data @ 0x8000) size
 |     BOOTROM_SIZE                = 0x00010000,   ///< Bootrom (super secret code/data @ 0x8000) size
 | ||||||
|     BOOTROM_PADDR               = 0x00000000,   ///< Bootrom physical address
 |     BOOTROM_PADDR               = 0x00000000,   ///< Bootrom physical address
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue