mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40: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.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/logging/log.h" | ||||
| 
 | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/mem_map.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| SharedPtr<Process> Process::Create(std::string name, u64 program_id) { | ||||
|     SharedPtr<Process> process(new Process); | ||||
| 
 | ||||
|     process->svc_access_mask.set(); | ||||
|     process->name = std::move(name); | ||||
|     process->program_id = program_id; | ||||
| 
 | ||||
|     return process; | ||||
| } | ||||
| 
 | ||||
| void Process::ParseKernelCaps(const u32 * kernel_caps, size_t len) { | ||||
|     //UNIMPLEMENTED();
 | ||||
| void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | ||||
|     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) { | ||||
|  |  | |||
|  | @ -14,10 +14,11 @@ | |||
| namespace Kernel { | ||||
| 
 | ||||
| struct StaticAddressMapping { | ||||
|     // Address and size must be 4K-aligned
 | ||||
|     // Address and size must be page-aligned
 | ||||
|     VAddr address; | ||||
|     u32 size; | ||||
|     bool writable; | ||||
|     bool unk_flag; | ||||
| }; | ||||
| 
 | ||||
| enum class MemoryRegion { | ||||
|  |  | |||
|  | @ -231,6 +231,7 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|     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; | ||||
| 
 | ||||
|     Load3DSXFile(*file, Memory::EXEFS_CODE_VADDR); | ||||
|  |  | |||
|  | @ -351,6 +351,7 @@ ResultStatus AppLoader_ELF::Load() { | |||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|     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; | ||||
| 
 | ||||
|     ElfReader elf_reader(&buffer[0]); | ||||
|  |  | |||
|  | @ -141,6 +141,7 @@ ResultStatus LoadFile(const std::string& filename) { | |||
|     case FileType::BIN: | ||||
|     { | ||||
|         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; | ||||
| 
 | ||||
|         size_t size = (size_t)file->GetSize(); | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ namespace Memory { | |||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| const u32 PAGE_SIZE = 0x1000; | ||||
| 
 | ||||
| enum : u32 { | ||||
|     BOOTROM_SIZE                = 0x00010000,   ///< Bootrom (super secret code/data @ 0x8000) size
 | ||||
|     BOOTROM_PADDR               = 0x00000000,   ///< Bootrom physical address
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue