summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-27 11:15:34 -0500
committerGravatar GitHub2018-12-27 11:15:34 -0500
commit795335af0f37ce25da3c3ca8eeab62c50f87d366 (patch)
tree48bde2f34a4e9c87dc96f83bfbeeeee96b72b9e6 /src/core/hle/kernel/process.cpp
parentMerge pull request #1892 from Tinob/master (diff)
parentkernel/process: Hook up the process capability parser to the process itself (diff)
downloadyuzu-795335af0f37ce25da3c3ca8eeab62c50f87d366.tar.gz
yuzu-795335af0f37ce25da3c3ca8eeab62c50f87d366.tar.xz
yuzu-795335af0f37ce25da3c3ca8eeab62c50f87d366.zip
Merge pull request #1928 from lioncash/caps
kernel: Handle kernel capability descriptors
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
-rw-r--r--src/core/hle/kernel/process.cpp80
1 files changed, 5 insertions, 75 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 5356a4a3f..4f209a979 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -28,13 +28,11 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
28 SharedPtr<Process> process(new Process(kernel)); 28 SharedPtr<Process> process(new Process(kernel));
29 29
30 process->name = std::move(name); 30 process->name = std::move(name);
31 process->flags.raw = 0;
32 process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
33 process->resource_limit = kernel.GetSystemResourceLimit(); 31 process->resource_limit = kernel.GetSystemResourceLimit();
34 process->status = ProcessStatus::Created; 32 process->status = ProcessStatus::Created;
35 process->program_id = 0; 33 process->program_id = 0;
36 process->process_id = kernel.CreateNewProcessID(); 34 process->process_id = kernel.CreateNewProcessID();
37 process->svc_access_mask.set(); 35 process->capabilities.InitializeForMetadatalessProcess();
38 36
39 std::mt19937 rng(Settings::values.rng_seed.value_or(0)); 37 std::mt19937 rng(Settings::values.rng_seed.value_or(0));
40 std::uniform_int_distribution<u64> distribution; 38 std::uniform_int_distribution<u64> distribution;
@@ -64,83 +62,15 @@ ResultCode Process::ClearSignalState() {
64 return RESULT_SUCCESS; 62 return RESULT_SUCCESS;
65} 63}
66 64
67void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { 65ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
68 program_id = metadata.GetTitleID(); 66 program_id = metadata.GetTitleID();
69 ideal_processor = metadata.GetMainThreadCore(); 67 ideal_processor = metadata.GetMainThreadCore();
70 is_64bit_process = metadata.Is64BitProgram(); 68 is_64bit_process = metadata.Is64BitProgram();
71 vm_manager.Reset(metadata.GetAddressSpaceType());
72}
73
74void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) {
75 for (std::size_t i = 0; i < len; ++i) {
76 u32 descriptor = kernel_caps[i];
77 u32 type = descriptor >> 20;
78
79 if (descriptor == 0xFFFFFFFF) {
80 // Unused descriptor entry
81 continue;
82 } else if ((type & 0xF00) == 0xE00) { // 0x0FFF
83 // Allowed interrupts list
84 LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
85 } else if ((type & 0xF80) == 0xF00) { // 0x07FF
86 // Allowed syscalls mask
87 unsigned int index = ((descriptor >> 24) & 7) * 24;
88 u32 bits = descriptor & 0xFFFFFF;
89
90 while (bits && index < svc_access_mask.size()) {
91 svc_access_mask.set(index, bits & 1);
92 ++index;
93 bits >>= 1;
94 }
95 } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF
96 // Handle table size
97 handle_table_size = descriptor & 0x3FF;
98 } else if ((type & 0xFF8) == 0xFF0) { // 0x007F
99 // Misc. flags
100 flags.raw = descriptor & 0xFFFF;
101 } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
102 // Mapped memory range
103 if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) {
104 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
105 continue;
106 }
107 u32 end_desc = kernel_caps[i + 1];
108 ++i; // Skip over the second descriptor on the next iteration
109 69
110 AddressMapping mapping; 70 vm_manager.Reset(metadata.GetAddressSpaceType());
111 mapping.address = descriptor << 12;
112 VAddr end_address = end_desc << 12;
113
114 if (mapping.address < end_address) {
115 mapping.size = end_address - mapping.address;
116 } else {
117 mapping.size = 0;
118 }
119 71
120 mapping.read_only = (descriptor & (1 << 20)) != 0; 72 const auto& caps = metadata.GetKernelCapabilities();
121 mapping.unk_flag = (end_desc & (1 << 20)) != 0; 73 return capabilities.InitializeForUserProcess(caps.data(), caps.size(), vm_manager);
122
123 address_mappings.push_back(mapping);
124 } else if ((type & 0xFFF) == 0xFFE) { // 0x000F
125 // Mapped memory page
126 AddressMapping mapping;
127 mapping.address = descriptor << 12;
128 mapping.size = Memory::PAGE_SIZE;
129 mapping.read_only = false;
130 mapping.unk_flag = false;
131
132 address_mappings.push_back(mapping);
133 } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF
134 // Kernel version
135 kernel_version = descriptor & 0xFFFF;
136
137 int minor = kernel_version & 0xFF;
138 int major = (kernel_version >> 8) & 0xFF;
139 LOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor);
140 } else {
141 LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor);
142 }
143 }
144} 74}
145 75
146void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { 76void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {