summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/hle/source.cpp2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_cmdlists.cpp4
-rw-r--r--src/citra_qt/debugger/graphics/graphics_surface.cpp3
-rw-r--r--src/common/string_util.cpp2
-rw-r--r--src/common/string_util.h2
-rw-r--r--src/common/vector_math.h12
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/gdbstub/gdbstub.cpp4
-rw-r--r--src/core/hle/ipc.h8
-rw-r--r--src/core/hle/ipc_helpers.h12
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp2
-rw-r--r--src/core/hle/kernel/mutex.cpp2
-rw-r--r--src/core/hle/kernel/process.cpp2
-rw-r--r--src/core/hle/kernel/resource_limit.cpp2
-rw-r--r--src/core/hle/kernel/resource_limit.h2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp3
-rw-r--r--src/core/hle/kernel/shared_memory.h2
-rw-r--r--src/core/hle/kernel/thread.cpp33
-rw-r--r--src/core/hle/kernel/thread.h27
-rw-r--r--src/core/hle/kernel/wait_object.cpp2
-rw-r--r--src/core/hle/service/apt/apt.cpp4
-rw-r--r--src/core/hle/service/cam/cam.cpp2
-rw-r--r--src/core/hle/service/cfg/cfg.cpp2
-rw-r--r--src/core/hle/service/fs/archive.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/ldr_ro/cro_helper.h6
-rw-r--r--src/core/hle/service/nwm/nwm_uds.cpp10
-rw-r--r--src/core/hle/service/nwm/uds_beacon.cpp4
-rw-r--r--src/core/hle/service/nwm/uds_data.cpp8
-rw-r--r--src/core/hle/svc.cpp13
-rw-r--r--src/core/loader/3dsx.cpp15
-rw-r--r--src/core/loader/3dsx.h2
-rw-r--r--src/core/loader/elf.cpp15
-rw-r--r--src/core/loader/elf.h2
-rw-r--r--src/core/loader/loader.h13
-rw-r--r--src/core/loader/ncch.cpp19
-rw-r--r--src/core/loader/ncch.h5
-rw-r--r--src/core/memory.cpp61
-rw-r--r--src/core/memory.h7
-rw-r--r--src/network/packet.cpp2
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/core/arm/arm_test_common.cpp22
-rw-r--r--src/tests/core/memory/memory.cpp56
-rw-r--r--src/video_core/geometry_pipeline.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp4
45 files changed, 252 insertions, 159 deletions
diff --git a/src/audio_core/hle/source.cpp b/src/audio_core/hle/source.cpp
index de4e88cae..c12287700 100644
--- a/src/audio_core/hle/source.cpp
+++ b/src/audio_core/hle/source.cpp
@@ -264,7 +264,7 @@ void Source::GenerateFrame() {
264 break; 264 break;
265 } 265 }
266 } 266 }
267 state.next_sample_number += frame_position; 267 state.next_sample_number += static_cast<u32>(frame_position);
268 268
269 state.filters.ProcessFrame(current_frame); 269 state.filters.ProcessFrame(current_frame);
270} 270}
diff --git a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
index 7d06ec28a..ce2b9fa50 100644
--- a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
@@ -26,8 +26,8 @@
26namespace { 26namespace {
27QImage LoadTexture(const u8* src, const Pica::Texture::TextureInfo& info) { 27QImage LoadTexture(const u8* src, const Pica::Texture::TextureInfo& info) {
28 QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); 28 QImage decoded_image(info.width, info.height, QImage::Format_ARGB32);
29 for (int y = 0; y < info.height; ++y) { 29 for (u32 y = 0; y < info.height; ++y) {
30 for (int x = 0; x < info.width; ++x) { 30 for (u32 x = 0; x < info.width; ++x) {
31 Math::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true); 31 Math::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true);
32 decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); 32 decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
33 } 33 }
diff --git a/src/citra_qt/debugger/graphics/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp
index 47d9924e1..c974545ef 100644
--- a/src/citra_qt/debugger/graphics/graphics_surface.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp
@@ -273,7 +273,8 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
273 surface_picker_x_control->setValue(x); 273 surface_picker_x_control->setValue(x);
274 surface_picker_y_control->setValue(y); 274 surface_picker_y_control->setValue(y);
275 275
276 if (x < 0 || x >= surface_width || y < 0 || y >= surface_height) { 276 if (x < 0 || x >= static_cast<int>(surface_width) || y < 0 ||
277 y >= static_cast<int>(surface_height)) {
277 surface_info_label->setText(tr("Pixel out of bounds")); 278 surface_info_label->setText(tr("Pixel out of bounds"));
278 surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 279 surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
279 return; 280 return;
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index bad311793..6959915fa 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -117,7 +117,7 @@ std::string StringFromFormat(const char* format, ...) {
117} 117}
118 118
119// For Debugging. Read out an u8 array. 119// For Debugging. Read out an u8 array.
120std::string ArrayToString(const u8* data, u32 size, int line_len, bool spaces) { 120std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces) {
121 std::ostringstream oss; 121 std::ostringstream oss;
122 oss << std::setfill('0') << std::hex; 122 oss << std::setfill('0') << std::hex;
123 123
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 075bf4ecb..259360aec 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -33,7 +33,7 @@ inline void CharArrayFromFormat(char (&out)[Count], const char* format, ...) {
33} 33}
34 34
35// Good 35// Good
36std::string ArrayToString(const u8* data, u32 size, int line_len = 20, bool spaces = true); 36std::string ArrayToString(const u8* data, size_t size, int line_len = 20, bool spaces = true);
37 37
38std::string StripSpaces(const std::string& s); 38std::string StripSpaces(const std::string& s);
39std::string StripQuotes(const std::string& s); 39std::string StripQuotes(const std::string& s);
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index 2b05f66ee..3f0057d9e 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -104,8 +104,7 @@ public:
104 } 104 }
105 template <typename V> 105 template <typename V>
106 void operator*=(const V& f) { 106 void operator*=(const V& f) {
107 x *= f; 107 *this = *this * f;
108 y *= f;
109 } 108 }
110 template <typename V> 109 template <typename V>
111 Vec2<decltype(T{} / V{})> operator/(const V& f) const { 110 Vec2<decltype(T{} / V{})> operator/(const V& f) const {
@@ -262,9 +261,7 @@ public:
262 } 261 }
263 template <typename V> 262 template <typename V>
264 void operator*=(const V& f) { 263 void operator*=(const V& f) {
265 x *= f; 264 *this = *this * f;
266 y *= f;
267 z *= f;
268 } 265 }
269 template <typename V> 266 template <typename V>
270 Vec3<decltype(T{} / V{})> operator/(const V& f) const { 267 Vec3<decltype(T{} / V{})> operator/(const V& f) const {
@@ -478,10 +475,7 @@ public:
478 } 475 }
479 template <typename V> 476 template <typename V>
480 void operator*=(const V& f) { 477 void operator*=(const V& f) {
481 x *= f; 478 *this = *this * f;
482 y *= f;
483 z *= f;
484 w *= f;
485 } 479 }
486 template <typename V> 480 template <typename V>
487 Vec4<decltype(T{} / V{})> operator/(const V& f) const { 481 Vec4<decltype(T{} / V{})> operator/(const V& f) const {
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 59b8768e7..0c7a72987 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -13,6 +13,7 @@
13#include "core/core_timing.h" 13#include "core/core_timing.h"
14#include "core/gdbstub/gdbstub.h" 14#include "core/gdbstub/gdbstub.h"
15#include "core/hle/kernel/kernel.h" 15#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/process.h"
16#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
17#include "core/hle/service/service.h" 18#include "core/hle/service/service.h"
18#include "core/hw/hw.h" 19#include "core/hw/hw.h"
@@ -100,7 +101,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
100 return init_result; 101 return init_result;
101 } 102 }
102 103
103 const Loader::ResultStatus load_result{app_loader->Load()}; 104 const Loader::ResultStatus load_result{app_loader->Load(Kernel::g_current_process)};
104 if (Loader::ResultStatus::Success != load_result) { 105 if (Loader::ResultStatus::Success != load_result) {
105 LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result); 106 LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
106 System::Shutdown(); 107 System::Shutdown();
@@ -114,6 +115,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
114 return ResultStatus::ErrorLoader; 115 return ResultStatus::ErrorLoader;
115 } 116 }
116 } 117 }
118 Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
117 status = ResultStatus::Success; 119 status = ResultStatus::Success;
118 return status; 120 return status;
119} 121}
@@ -196,4 +198,4 @@ void System::Shutdown() {
196 LOG_DEBUG(Core, "Shutdown OK"); 198 LOG_DEBUG(Core, "Shutdown OK");
197} 199}
198 200
199} // namespace 201} // namespace Core
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 123fe7cd4..be2b2e25f 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -946,7 +946,7 @@ static void Init(u16 port) {
946 WSAStartup(MAKEWORD(2, 2), &InitData); 946 WSAStartup(MAKEWORD(2, 2), &InitData);
947#endif 947#endif
948 948
949 int tmpsock = socket(PF_INET, SOCK_STREAM, 0); 949 int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
950 if (tmpsock == -1) { 950 if (tmpsock == -1) {
951 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); 951 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
952 } 952 }
@@ -973,7 +973,7 @@ static void Init(u16 port) {
973 sockaddr_in saddr_client; 973 sockaddr_in saddr_client;
974 sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client); 974 sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
975 socklen_t client_addrlen = sizeof(saddr_client); 975 socklen_t client_addrlen = sizeof(saddr_client);
976 gdbserver_socket = accept(tmpsock, client_addr, &client_addrlen); 976 gdbserver_socket = static_cast<int>(accept(tmpsock, client_addr, &client_addrlen));
977 if (gdbserver_socket < 0) { 977 if (gdbserver_socket < 0) {
978 // In the case that we couldn't start the server for whatever reason, just start CPU 978 // In the case that we couldn't start the server for whatever reason, just start CPU
979 // execution like normal. 979 // execution like normal.
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index f7f96125a..87ed85df6 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -122,11 +122,11 @@ union StaticBufferDescInfo {
122 BitField<14, 18, u32> size; 122 BitField<14, 18, u32> size;
123}; 123};
124 124
125inline u32 StaticBufferDesc(u32 size, u8 buffer_id) { 125inline u32 StaticBufferDesc(size_t size, u8 buffer_id) {
126 StaticBufferDescInfo info{}; 126 StaticBufferDescInfo info{};
127 info.descriptor_type.Assign(StaticBuffer); 127 info.descriptor_type.Assign(StaticBuffer);
128 info.buffer_id.Assign(buffer_id); 128 info.buffer_id.Assign(buffer_id);
129 info.size.Assign(size); 129 info.size.Assign(static_cast<u32>(size));
130 return info.raw; 130 return info.raw;
131} 131}
132 132
@@ -160,11 +160,11 @@ union MappedBufferDescInfo {
160 BitField<4, 28, u32> size; 160 BitField<4, 28, u32> size;
161}; 161};
162 162
163inline u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { 163inline u32 MappedBufferDesc(size_t size, MappedBufferPermissions perms) {
164 MappedBufferDescInfo info{}; 164 MappedBufferDescInfo info{};
165 info.flags.Assign(MappedBuffer); 165 info.flags.Assign(MappedBuffer);
166 info.perms.Assign(perms); 166 info.perms.Assign(perms);
167 info.size.Assign(size); 167 info.size.Assign(static_cast<u32>(size));
168 return info.raw; 168 return info.raw;
169} 169}
170 170
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index f0d89cffe..7cb95cbac 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -117,9 +117,9 @@ public:
117 117
118 void PushCurrentPIDHandle(); 118 void PushCurrentPIDHandle();
119 119
120 void PushStaticBuffer(VAddr buffer_vaddr, u32 size, u8 buffer_id); 120 void PushStaticBuffer(VAddr buffer_vaddr, size_t size, u8 buffer_id);
121 121
122 void PushMappedBuffer(VAddr buffer_vaddr, u32 size, MappedBufferPermissions perms); 122 void PushMappedBuffer(VAddr buffer_vaddr, size_t size, MappedBufferPermissions perms);
123}; 123};
124 124
125/// Push /// 125/// Push ///
@@ -190,12 +190,12 @@ inline void RequestBuilder::PushCurrentPIDHandle() {
190 Push(u32(0)); 190 Push(u32(0));
191} 191}
192 192
193inline void RequestBuilder::PushStaticBuffer(VAddr buffer_vaddr, u32 size, u8 buffer_id) { 193inline void RequestBuilder::PushStaticBuffer(VAddr buffer_vaddr, size_t size, u8 buffer_id) {
194 Push(StaticBufferDesc(size, buffer_id)); 194 Push(StaticBufferDesc(size, buffer_id));
195 Push(buffer_vaddr); 195 Push(buffer_vaddr);
196} 196}
197 197
198inline void RequestBuilder::PushMappedBuffer(VAddr buffer_vaddr, u32 size, 198inline void RequestBuilder::PushMappedBuffer(VAddr buffer_vaddr, size_t size,
199 MappedBufferPermissions perms) { 199 MappedBufferPermissions perms) {
200 Push(MappedBufferDesc(size, perms)); 200 Push(MappedBufferDesc(size, perms));
201 Push(buffer_vaddr); 201 Push(buffer_vaddr);
@@ -227,8 +227,8 @@ public:
227 bool validateHeader = true) { 227 bool validateHeader = true) {
228 if (validateHeader) 228 if (validateHeader)
229 ValidateHeader(); 229 ValidateHeader();
230 Header builderHeader{ 230 Header builderHeader{MakeHeader(static_cast<u16>(header.command_id), normal_params_size,
231 MakeHeader(header.command_id, normal_params_size, translate_params_size)}; 231 translate_params_size)};
232 if (context != nullptr) 232 if (context != nullptr)
233 return {*context, builderHeader}; 233 return {*context, builderHeader};
234 else 234 else
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 5ebe2eca4..6020e9764 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -37,7 +37,7 @@ SharedPtr<Object> HLERequestContext::GetIncomingHandle(u32 id_from_cmdbuf) const
37 37
38u32 HLERequestContext::AddOutgoingHandle(SharedPtr<Object> object) { 38u32 HLERequestContext::AddOutgoingHandle(SharedPtr<Object> object) {
39 request_handles.push_back(std::move(object)); 39 request_handles.push_back(std::move(object));
40 return request_handles.size() - 1; 40 return static_cast<u32>(request_handles.size() - 1);
41} 41}
42 42
43void HLERequestContext::ClearIncomingObjects() { 43void HLERequestContext::ClearIncomingObjects() {
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index cef961289..2cbca5e5b 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -90,7 +90,7 @@ void Mutex::UpdatePriority() {
90 if (!holding_thread) 90 if (!holding_thread)
91 return; 91 return;
92 92
93 s32 best_priority = THREADPRIO_LOWEST; 93 u32 best_priority = THREADPRIO_LOWEST;
94 for (auto& waiter : GetWaitingThreads()) { 94 for (auto& waiter : GetWaitingThreads()) {
95 if (waiter->current_priority < best_priority) 95 if (waiter->current_priority < best_priority)
96 best_priority = waiter->current_priority; 96 best_priority = waiter->current_priority;
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 522ad2333..cf3163e0f 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -147,7 +147,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
147 } 147 }
148 148
149 vm_manager.LogLayout(Log::Level::Debug); 149 vm_manager.LogLayout(Log::Level::Debug);
150 Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); 150 Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this);
151} 151}
152 152
153VAddr Process::GetLinearHeapAreaAddress() const { 153VAddr Process::GetLinearHeapAreaAddress() const {
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index a8f10a3ee..517dc47a8 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -61,7 +61,7 @@ s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const {
61 } 61 }
62} 62}
63 63
64s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { 64u32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
65 switch (resource) { 65 switch (resource) {
66 case PRIORITY: 66 case PRIORITY:
67 return max_priority; 67 return max_priority;
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 6cdfbcf8d..42874eb8d 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -67,7 +67,7 @@ public:
67 * @param resource Requested resource type 67 * @param resource Requested resource type
68 * @returns The max value of the resource type 68 * @returns The max value of the resource type
69 */ 69 */
70 s32 GetMaxResourceValue(u32 resource) const; 70 u32 GetMaxResourceValue(u32 resource) const;
71 71
72 /// Name of resource limit object. 72 /// Name of resource limit object.
73 std::string name; 73 std::string name;
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index a7b66142f..02d5a7a36 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -42,7 +42,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
42 memory_region->used += size; 42 memory_region->used += size;
43 43
44 shared_memory->linear_heap_phys_address = 44 shared_memory->linear_heap_phys_address =
45 Memory::FCRAM_PADDR + memory_region->base + shared_memory->backing_block_offset; 45 Memory::FCRAM_PADDR + memory_region->base +
46 static_cast<PAddr>(shared_memory->backing_block_offset);
46 47
47 // Increase the amount of used linear heap memory for the owner process. 48 // Increase the amount of used linear heap memory for the owner process.
48 if (shared_memory->owner_process != nullptr) { 49 if (shared_memory->owner_process != nullptr) {
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 94b335ed1..93a6f2182 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -114,7 +114,7 @@ public:
114 /// Backing memory for this shared memory block. 114 /// Backing memory for this shared memory block.
115 std::shared_ptr<std::vector<u8>> backing_block; 115 std::shared_ptr<std::vector<u8>> backing_block;
116 /// Offset into the backing block for this shared memory. 116 /// Offset into the backing block for this shared memory.
117 u32 backing_block_offset; 117 size_t backing_block_offset;
118 /// Size of the memory block. Page-aligned. 118 /// Size of the memory block. Page-aligned.
119 u32 size; 119 u32 size;
120 /// Permission restrictions applied to the process which created the block. 120 /// Permission restrictions applied to the process which created the block.
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 690cb20b3..2614a260c 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -111,7 +111,7 @@ void Thread::Stop() {
111 111
112Thread* ArbitrateHighestPriorityThread(u32 address) { 112Thread* ArbitrateHighestPriorityThread(u32 address) {
113 Thread* highest_priority_thread = nullptr; 113 Thread* highest_priority_thread = nullptr;
114 s32 priority = THREADPRIO_LOWEST; 114 u32 priority = THREADPRIO_LOWEST;
115 115
116 // Iterate through threads, find highest priority thread that is waiting to be arbitrated... 116 // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
117 for (auto& thread : thread_list) { 117 for (auto& thread : thread_list) {
@@ -319,7 +319,7 @@ static void DebugThreadQueue() {
319 } 319 }
320 320
321 for (auto& t : thread_list) { 321 for (auto& t : thread_list) {
322 s32 priority = ready_queue.contains(t.get()); 322 u32 priority = ready_queue.contains(t.get());
323 if (priority != -1) { 323 if (priority != -1) {
324 LOG_DEBUG(Kernel, "0x%02X %u", priority, t->GetObjectId()); 324 LOG_DEBUG(Kernel, "0x%02X %u", priority, t->GetObjectId());
325 } 325 }
@@ -369,7 +369,8 @@ static void ResetThreadContext(ARM_Interface::ThreadContext& context, u32 stack_
369} 369}
370 370
371ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority, 371ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority,
372 u32 arg, s32 processor_id, VAddr stack_top) { 372 u32 arg, s32 processor_id, VAddr stack_top,
373 SharedPtr<Process> owner_process) {
373 // Check if priority is in ranged. Lowest priority -> highest priority id. 374 // Check if priority is in ranged. Lowest priority -> highest priority id.
374 if (priority > THREADPRIO_LOWEST) { 375 if (priority > THREADPRIO_LOWEST) {
375 LOG_ERROR(Kernel_SVC, "Invalid thread priority: %d", priority); 376 LOG_ERROR(Kernel_SVC, "Invalid thread priority: %d", priority);
@@ -383,7 +384,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
383 384
384 // TODO(yuriks): Other checks, returning 0xD9001BEA 385 // TODO(yuriks): Other checks, returning 0xD9001BEA
385 386
386 if (!Memory::IsValidVirtualAddress(entry_point)) { 387 if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
387 LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); 388 LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point);
388 // TODO: Verify error 389 // TODO: Verify error
389 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, 390 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
@@ -406,10 +407,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
406 thread->wait_address = 0; 407 thread->wait_address = 0;
407 thread->name = std::move(name); 408 thread->name = std::move(name);
408 thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); 409 thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap();
409 thread->owner_process = g_current_process; 410 thread->owner_process = owner_process;
410 411
411 // Find the next available TLS index, and mark it as used 412 // Find the next available TLS index, and mark it as used
412 auto& tls_slots = Kernel::g_current_process->tls_slots; 413 auto& tls_slots = owner_process->tls_slots;
413 bool needs_allocation = true; 414 bool needs_allocation = true;
414 u32 available_page; // Which allocated page has free space 415 u32 available_page; // Which allocated page has free space
415 u32 available_slot; // Which slot within the page is free 416 u32 available_slot; // Which slot within the page is free
@@ -428,18 +429,18 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
428 return ERR_OUT_OF_MEMORY; 429 return ERR_OUT_OF_MEMORY;
429 } 430 }
430 431
431 u32 offset = linheap_memory->size(); 432 size_t offset = linheap_memory->size();
432 433
433 // Allocate some memory from the end of the linear heap for this region. 434 // Allocate some memory from the end of the linear heap for this region.
434 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0); 435 linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
435 memory_region->used += Memory::PAGE_SIZE; 436 memory_region->used += Memory::PAGE_SIZE;
436 Kernel::g_current_process->linear_heap_used += Memory::PAGE_SIZE; 437 owner_process->linear_heap_used += Memory::PAGE_SIZE;
437 438
438 tls_slots.emplace_back(0); // The page is completely available at the start 439 tls_slots.emplace_back(0); // The page is completely available at the start
439 available_page = tls_slots.size() - 1; 440 available_page = static_cast<u32>(tls_slots.size() - 1);
440 available_slot = 0; // Use the first slot in the new page 441 available_slot = 0; // Use the first slot in the new page
441 442
442 auto& vm_manager = Kernel::g_current_process->vm_manager; 443 auto& vm_manager = owner_process->vm_manager;
443 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 444 vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
444 445
445 // Map the page to the current process' address space. 446 // Map the page to the current process' address space.
@@ -463,7 +464,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
463 return MakeResult<SharedPtr<Thread>>(std::move(thread)); 464 return MakeResult<SharedPtr<Thread>>(std::move(thread));
464} 465}
465 466
466void Thread::SetPriority(s32 priority) { 467void Thread::SetPriority(u32 priority) {
467 ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, 468 ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST,
468 "Invalid priority value."); 469 "Invalid priority value.");
469 // If thread was ready, adjust queues 470 // If thread was ready, adjust queues
@@ -476,7 +477,7 @@ void Thread::SetPriority(s32 priority) {
476} 477}
477 478
478void Thread::UpdatePriority() { 479void Thread::UpdatePriority() {
479 s32 best_priority = nominal_priority; 480 u32 best_priority = nominal_priority;
480 for (auto& mutex : held_mutexes) { 481 for (auto& mutex : held_mutexes) {
481 if (mutex->priority < best_priority) 482 if (mutex->priority < best_priority)
482 best_priority = mutex->priority; 483 best_priority = mutex->priority;
@@ -484,7 +485,7 @@ void Thread::UpdatePriority() {
484 BoostPriority(best_priority); 485 BoostPriority(best_priority);
485} 486}
486 487
487void Thread::BoostPriority(s32 priority) { 488void Thread::BoostPriority(u32 priority) {
488 // If thread was ready, adjust queues 489 // If thread was ready, adjust queues
489 if (status == THREADSTATUS_READY) 490 if (status == THREADSTATUS_READY)
490 ready_queue.move(this, current_priority, priority); 491 ready_queue.move(this, current_priority, priority);
@@ -493,10 +494,10 @@ void Thread::BoostPriority(s32 priority) {
493 current_priority = priority; 494 current_priority = priority;
494} 495}
495 496
496SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { 497SharedPtr<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process) {
497 // Initialize new "main" thread 498 // Initialize new "main" thread
498 auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, 499 auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
499 Memory::HEAP_VADDR_END); 500 Memory::HEAP_VADDR_END, owner_process);
500 501
501 SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); 502 SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
502 503
@@ -537,7 +538,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
537s32 Thread::GetWaitObjectIndex(WaitObject* object) const { 538s32 Thread::GetWaitObjectIndex(WaitObject* object) const {
538 ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything"); 539 ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
539 auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); 540 auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
540 return std::distance(match, wait_objects.rend()) - 1; 541 return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
541} 542}
542 543
543//////////////////////////////////////////////////////////////////////////////////////////////////// 544////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 328f1a86a..4679c2022 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -15,7 +15,7 @@
15#include "core/hle/kernel/wait_object.h" 15#include "core/hle/kernel/wait_object.h"
16#include "core/hle/result.h" 16#include "core/hle/result.h"
17 17
18enum ThreadPriority : s32 { 18enum ThreadPriority : u32 {
19 THREADPRIO_HIGHEST = 0, ///< Highest thread priority 19 THREADPRIO_HIGHEST = 0, ///< Highest thread priority
20 THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps 20 THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps
21 THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps 21 THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps
@@ -61,10 +61,12 @@ public:
61 * @param arg User data to pass to the thread 61 * @param arg User data to pass to the thread
62 * @param processor_id The ID(s) of the processors on which the thread is desired to be run 62 * @param processor_id The ID(s) of the processors on which the thread is desired to be run
63 * @param stack_top The address of the thread's stack top 63 * @param stack_top The address of the thread's stack top
64 * @param owner_process The parent process for the thread
64 * @return A shared pointer to the newly created thread 65 * @return A shared pointer to the newly created thread
65 */ 66 */
66 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, u32 priority, 67 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, u32 priority,
67 u32 arg, s32 processor_id, VAddr stack_top); 68 u32 arg, s32 processor_id, VAddr stack_top,
69 SharedPtr<Process> owner_process);
68 70
69 std::string GetName() const override { 71 std::string GetName() const override {
70 return name; 72 return name;
@@ -85,7 +87,7 @@ public:
85 * Gets the thread's current priority 87 * Gets the thread's current priority
86 * @return The current thread's priority 88 * @return The current thread's priority
87 */ 89 */
88 s32 GetPriority() const { 90 u32 GetPriority() const {
89 return current_priority; 91 return current_priority;
90 } 92 }
91 93
@@ -93,7 +95,7 @@ public:
93 * Sets the thread's current priority 95 * Sets the thread's current priority
94 * @param priority The new priority 96 * @param priority The new priority
95 */ 97 */
96 void SetPriority(s32 priority); 98 void SetPriority(u32 priority);
97 99
98 /** 100 /**
99 * Boost's a thread's priority to the best priority among the thread's held mutexes. 101 * Boost's a thread's priority to the best priority among the thread's held mutexes.
@@ -105,7 +107,7 @@ public:
105 * Temporarily boosts the thread's priority until the next time it is scheduled 107 * Temporarily boosts the thread's priority until the next time it is scheduled
106 * @param priority The new priority 108 * @param priority The new priority
107 */ 109 */
108 void BoostPriority(s32 priority); 110 void BoostPriority(u32 priority);
109 111
110 /** 112 /**
111 * Gets the thread's thread ID 113 * Gets the thread's thread ID
@@ -121,9 +123,9 @@ public:
121 void ResumeFromWait(); 123 void ResumeFromWait();
122 124
123 /** 125 /**
124 * Schedules an event to wake up the specified thread after the specified delay 126 * Schedules an event to wake up the specified thread after the specified delay
125 * @param nanoseconds The time this thread will be allowed to sleep for 127 * @param nanoseconds The time this thread will be allowed to sleep for
126 */ 128 */
127 void WakeAfterDelay(s64 nanoseconds); 129 void WakeAfterDelay(s64 nanoseconds);
128 130
129 /** 131 /**
@@ -179,8 +181,8 @@ public:
179 u32 entry_point; 181 u32 entry_point;
180 u32 stack_top; 182 u32 stack_top;
181 183
182 s32 nominal_priority; ///< Nominal thread priority, as set by the emulated application 184 u32 nominal_priority; ///< Nominal thread priority, as set by the emulated application
183 s32 current_priority; ///< Current thread priority, can be temporarily changed 185 u32 current_priority; ///< Current thread priority, can be temporarily changed
184 186
185 u64 last_running_ticks; ///< CPU tick when thread was last running 187 u64 last_running_ticks; ///< CPU tick when thread was last running
186 188
@@ -223,9 +225,10 @@ private:
223 * Sets up the primary application thread 225 * Sets up the primary application thread
224 * @param entry_point The address at which the thread should start execution 226 * @param entry_point The address at which the thread should start execution
225 * @param priority The priority to give the main thread 227 * @param priority The priority to give the main thread
228 * @param owner_process The parent process for the main thread
226 * @return A shared pointer to the main thread 229 * @return A shared pointer to the main thread
227 */ 230 */
228SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority); 231SharedPtr<Thread> SetupMainThread(u32 entry_point, u32 priority, SharedPtr<Process> owner_process);
229 232
230/** 233/**
231 * Returns whether there are any threads that are ready to run. 234 * Returns whether there are any threads that are ready to run.
@@ -285,4 +288,4 @@ void ThreadingShutdown();
285 */ 288 */
286const std::vector<SharedPtr<Thread>>& GetThreadList(); 289const std::vector<SharedPtr<Thread>>& GetThreadList();
287 290
288} // namespace 291} // namespace Kernel
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 1ced26905..469554908 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -34,7 +34,7 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
34 34
35SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { 35SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
36 Thread* candidate = nullptr; 36 Thread* candidate = nullptr;
37 s32 candidate_priority = THREADPRIO_LOWEST + 1; 37 u32 candidate_priority = THREADPRIO_LOWEST + 1;
38 38
39 for (const auto& thread : waiting_threads) { 39 for (const auto& thread : waiting_threads) {
40 // The list of waiting threads must not contain threads that are not waiting to be awakened. 40 // The list of waiting threads must not contain threads that are not waiting to be awakened.
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 8c0ba73f2..4c6156345 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -561,7 +561,7 @@ void ReceiveParameter(Service::Interface* self) {
561 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() 561 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
562 : 0); 562 : 0);
563 563
564 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); 564 rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0);
565 565
566 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); 566 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
567 567
@@ -609,7 +609,7 @@ void GlanceParameter(Service::Interface* self) {
609 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() 609 ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap()
610 : 0); 610 : 0);
611 611
612 rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); 612 rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0);
613 613
614 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); 614 Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size());
615 615
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp
index c9f9e9d95..8172edae8 100644
--- a/src/core/hle/service/cam/cam.cpp
+++ b/src/core/hle/service/cam/cam.cpp
@@ -177,7 +177,7 @@ void CompletionEventCallBack(u64 port_id, int) {
177 LOG_ERROR(Service_CAM, "The destination size (%u) doesn't match the source (%zu)!", 177 LOG_ERROR(Service_CAM, "The destination size (%u) doesn't match the source (%zu)!",
178 port.dest_size, buffer_size); 178 port.dest_size, buffer_size);
179 } 179 }
180 Memory::WriteBlock(port.dest, buffer.data(), std::min<u32>(port.dest_size, buffer_size)); 180 Memory::WriteBlock(port.dest, buffer.data(), std::min<size_t>(port.dest_size, buffer_size));
181 } 181 }
182 182
183 port.is_receiving = false; 183 port.is_receiving = false;
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index f26a1f65f..f78c25fb2 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -141,7 +141,7 @@ void GetCountryCodeString(Service::Interface* self) {
141 141
142void GetCountryCodeID(Service::Interface* self) { 142void GetCountryCodeID(Service::Interface* self) {
143 u32* cmd_buff = Kernel::GetCommandBuffer(); 143 u32* cmd_buff = Kernel::GetCommandBuffer();
144 u16 country_code = cmd_buff[1]; 144 u16 country_code = static_cast<u16>(cmd_buff[1]);
145 u16 country_code_id = 0; 145 u16 country_code_id = 0;
146 146
147 // The following algorithm will fail if the first country code isn't 0. 147 // The following algorithm will fail if the first country code isn't 0.
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 4ccb3cd32..4ee7df73c 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -217,7 +217,7 @@ void Directory::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> serve
217 LOG_TRACE(Service_FS, "Read %s: count=%d", GetName().c_str(), count); 217 LOG_TRACE(Service_FS, "Read %s: count=%d", GetName().c_str(), count);
218 218
219 // Number of entries actually read 219 // Number of entries actually read
220 u32 read = backend->Read(entries.size(), entries.data()); 220 u32 read = backend->Read(static_cast<u32>(entries.size()), entries.data());
221 cmd_buff[2] = read; 221 cmd_buff[2] = read;
222 Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry)); 222 Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry));
223 break; 223 break;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index aa5d821f9..379fbd71c 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -251,7 +251,7 @@ static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) {
251 Math::Vec3<float> gyro; 251 Math::Vec3<float> gyro;
252 std::tie(std::ignore, gyro) = motion_device->GetStatus(); 252 std::tie(std::ignore, gyro) = motion_device->GetStatus();
253 double stretch = Core::System::GetInstance().perf_stats.GetLastFrameTimeScale(); 253 double stretch = Core::System::GetInstance().perf_stats.GetLastFrameTimeScale();
254 gyro *= gyroscope_coef * stretch; 254 gyro *= gyroscope_coef * static_cast<float>(stretch);
255 gyroscope_entry.x = static_cast<s16>(gyro.x); 255 gyroscope_entry.x = static_cast<s16>(gyro.x);
256 gyroscope_entry.y = static_cast<s16>(gyro.y); 256 gyroscope_entry.y = static_cast<s16>(gyro.y);
257 gyroscope_entry.z = static_cast<s16>(gyro.z); 257 gyroscope_entry.z = static_cast<s16>(gyro.z);
diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h
index 3bc10dbdc..57b4fb6df 100644
--- a/src/core/hle/service/ldr_ro/cro_helper.h
+++ b/src/core/hle/service/ldr_ro/cro_helper.h
@@ -413,7 +413,8 @@ private:
413 */ 413 */
414 template <typename T> 414 template <typename T>
415 void GetEntry(std::size_t index, T& data) const { 415 void GetEntry(std::size_t index, T& data) const {
416 Memory::ReadBlock(GetField(T::TABLE_OFFSET_FIELD) + index * sizeof(T), &data, sizeof(T)); 416 Memory::ReadBlock(GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
417 &data, sizeof(T));
417 } 418 }
418 419
419 /** 420 /**
@@ -425,7 +426,8 @@ private:
425 */ 426 */
426 template <typename T> 427 template <typename T>
427 void SetEntry(std::size_t index, const T& data) { 428 void SetEntry(std::size_t index, const T& data) {
428 Memory::WriteBlock(GetField(T::TABLE_OFFSET_FIELD) + index * sizeof(T), &data, sizeof(T)); 429 Memory::WriteBlock(GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
430 &data, sizeof(T));
429 } 431 }
430 432
431 /** 433 /**
diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp
index 4e2af9ae6..8ef0cda09 100644
--- a/src/core/hle/service/nwm/nwm_uds.cpp
+++ b/src/core/hle/service/nwm/nwm_uds.cpp
@@ -316,7 +316,7 @@ static void RecvBeaconBroadcastData(Interface* self) {
316 auto beacons = GetReceivedBeacons(mac_address); 316 auto beacons = GetReceivedBeacons(mac_address);
317 317
318 BeaconDataReplyHeader data_reply_header{}; 318 BeaconDataReplyHeader data_reply_header{};
319 data_reply_header.total_entries = beacons.size(); 319 data_reply_header.total_entries = static_cast<u32>(beacons.size());
320 data_reply_header.max_output_size = out_buffer_size; 320 data_reply_header.max_output_size = out_buffer_size;
321 321
322 Memory::WriteBlock(current_buffer_pos, &data_reply_header, sizeof(BeaconDataReplyHeader)); 322 Memory::WriteBlock(current_buffer_pos, &data_reply_header, sizeof(BeaconDataReplyHeader));
@@ -326,8 +326,8 @@ static void RecvBeaconBroadcastData(Interface* self) {
326 for (const auto& beacon : beacons) { 326 for (const auto& beacon : beacons) {
327 BeaconEntryHeader entry{}; 327 BeaconEntryHeader entry{};
328 // TODO(Subv): Figure out what this size is used for. 328 // TODO(Subv): Figure out what this size is used for.
329 entry.unk_size = sizeof(BeaconEntryHeader) + beacon.data.size(); 329 entry.unk_size = static_cast<u32>(sizeof(BeaconEntryHeader) + beacon.data.size());
330 entry.total_size = sizeof(BeaconEntryHeader) + beacon.data.size(); 330 entry.total_size = static_cast<u32>(sizeof(BeaconEntryHeader) + beacon.data.size());
331 entry.wifi_channel = beacon.channel; 331 entry.wifi_channel = beacon.channel;
332 entry.header_size = sizeof(BeaconEntryHeader); 332 entry.header_size = sizeof(BeaconEntryHeader);
333 entry.mac_address = beacon.transmitter_address; 333 entry.mac_address = beacon.transmitter_address;
@@ -338,9 +338,9 @@ static void RecvBeaconBroadcastData(Interface* self) {
338 current_buffer_pos += sizeof(BeaconEntryHeader); 338 current_buffer_pos += sizeof(BeaconEntryHeader);
339 339
340 Memory::WriteBlock(current_buffer_pos, beacon.data.data(), beacon.data.size()); 340 Memory::WriteBlock(current_buffer_pos, beacon.data.data(), beacon.data.size());
341 current_buffer_pos += beacon.data.size(); 341 current_buffer_pos += static_cast<VAddr>(beacon.data.size());
342 342
343 total_size += sizeof(BeaconEntryHeader) + beacon.data.size(); 343 total_size += static_cast<u32>(sizeof(BeaconEntryHeader) + beacon.data.size());
344 } 344 }
345 345
346 // Update the total size in the structure and write it to the buffer again. 346 // Update the total size in the structure and write it to the buffer again.
diff --git a/src/core/hle/service/nwm/uds_beacon.cpp b/src/core/hle/service/nwm/uds_beacon.cpp
index 552eaf65e..73a80d940 100644
--- a/src/core/hle/service/nwm/uds_beacon.cpp
+++ b/src/core/hle/service/nwm/uds_beacon.cpp
@@ -243,7 +243,7 @@ std::vector<u8> GenerateNintendoFirstEncryptedDataTag(const NetworkInfo& network
243 243
244 EncryptedDataTag tag{}; 244 EncryptedDataTag tag{};
245 tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific); 245 tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
246 tag.header.length = sizeof(tag) - sizeof(TagHeader) + payload_size; 246 tag.header.length = static_cast<u8>(sizeof(tag) - sizeof(TagHeader) + payload_size);
247 tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData0); 247 tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData0);
248 tag.oui = NintendoOUI; 248 tag.oui = NintendoOUI;
249 249
@@ -279,7 +279,7 @@ std::vector<u8> GenerateNintendoSecondEncryptedDataTag(const NetworkInfo& networ
279 279
280 EncryptedDataTag tag{}; 280 EncryptedDataTag tag{};
281 tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific); 281 tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
282 tag.header.length = tag_length; 282 tag.header.length = static_cast<u8>(tag_length);
283 tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData1); 283 tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData1);
284 tag.oui = NintendoOUI; 284 tag.oui = NintendoOUI;
285 285
diff --git a/src/core/hle/service/nwm/uds_data.cpp b/src/core/hle/service/nwm/uds_data.cpp
index 0fd9b8b8c..3ef2a84b6 100644
--- a/src/core/hle/service/nwm/uds_data.cpp
+++ b/src/core/hle/service/nwm/uds_data.cpp
@@ -197,7 +197,7 @@ static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload
197 df.ChannelMessageEnd(CryptoPP::DEFAULT_CHANNEL); 197 df.ChannelMessageEnd(CryptoPP::DEFAULT_CHANNEL);
198 df.SetRetrievalChannel(CryptoPP::DEFAULT_CHANNEL); 198 df.SetRetrievalChannel(CryptoPP::DEFAULT_CHANNEL);
199 199
200 int size = df.MaxRetrievable(); 200 size_t size = df.MaxRetrievable();
201 201
202 std::vector<u8> pdata(size); 202 std::vector<u8> pdata(size);
203 df.Get(pdata.data(), size); 203 df.Get(pdata.data(), size);
@@ -251,7 +251,7 @@ static std::vector<u8> EncryptDataFrame(const std::vector<u8>& payload,
251 251
252 df.SetRetrievalChannel(CryptoPP::DEFAULT_CHANNEL); 252 df.SetRetrievalChannel(CryptoPP::DEFAULT_CHANNEL);
253 253
254 int size = df.MaxRetrievable(); 254 size_t size = df.MaxRetrievable();
255 255
256 std::vector<u8> cipher(size); 256 std::vector<u8> cipher(size);
257 df.Get(cipher.data(), size); 257 df.Get(cipher.data(), size);
@@ -266,8 +266,8 @@ static std::vector<u8> EncryptDataFrame(const std::vector<u8>& payload,
266std::vector<u8> GenerateDataPayload(const std::vector<u8>& data, u8 channel, u16 dest_node, 266std::vector<u8> GenerateDataPayload(const std::vector<u8>& data, u8 channel, u16 dest_node,
267 u16 src_node, u16 sequence_number) { 267 u16 src_node, u16 sequence_number) {
268 std::vector<u8> buffer = GenerateLLCHeader(EtherType::SecureData); 268 std::vector<u8> buffer = GenerateLLCHeader(EtherType::SecureData);
269 std::vector<u8> securedata_header = 269 std::vector<u8> securedata_header = GenerateSecureDataHeader(
270 GenerateSecureDataHeader(data.size(), channel, dest_node, src_node, sequence_number); 270 static_cast<u16>(data.size()), channel, dest_node, src_node, sequence_number);
271 271
272 buffer.insert(buffer.end(), securedata_header.begin(), securedata_header.end()); 272 buffer.insert(buffer.end(), securedata_header.begin(), securedata_header.end());
273 buffer.insert(buffer.end(), data.begin(), data.end()); 273 buffer.insert(buffer.end(), data.begin(), data.end());
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 41e62cf62..fefd50805 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -396,7 +396,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
396 // We found a ready object, acquire it and set the result value 396 // We found a ready object, acquire it and set the result value
397 Kernel::WaitObject* object = itr->get(); 397 Kernel::WaitObject* object = itr->get();
398 object->Acquire(thread); 398 object->Acquire(thread);
399 *out = std::distance(objects.begin(), itr); 399 *out = static_cast<s32>(std::distance(objects.begin(), itr));
400 return RESULT_SUCCESS; 400 return RESULT_SUCCESS;
401 } 401 }
402 402
@@ -520,7 +520,7 @@ static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handl
520 // We found a ready object, acquire it and set the result value 520 // We found a ready object, acquire it and set the result value
521 Kernel::WaitObject* object = itr->get(); 521 Kernel::WaitObject* object = itr->get();
522 object->Acquire(thread); 522 object->Acquire(thread);
523 *index = std::distance(objects.begin(), itr); 523 *index = static_cast<s32>(std::distance(objects.begin(), itr));
524 524
525 if (object->GetHandleType() == Kernel::HandleType::ServerSession) { 525 if (object->GetHandleType() == Kernel::HandleType::ServerSession) {
526 auto server_session = static_cast<Kernel::ServerSession*>(object); 526 auto server_session = static_cast<Kernel::ServerSession*>(object);
@@ -717,8 +717,9 @@ static ResultCode CreateThread(Kernel::Handle* out_handle, u32 priority, u32 ent
717 "Newly created thread must run in the SysCore (Core1), unimplemented."); 717 "Newly created thread must run in the SysCore (Core1), unimplemented.");
718 } 718 }
719 719
720 CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create(name, entry_point, priority, 720 CASCADE_RESULT(SharedPtr<Thread> thread,
721 arg, processor_id, stack_top)); 721 Kernel::Thread::Create(name, entry_point, priority, arg, processor_id, stack_top,
722 Kernel::g_current_process));
722 723
723 thread->context.fpscr = 724 thread->context.fpscr =
724 FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000 725 FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000
@@ -743,7 +744,7 @@ static void ExitThread() {
743} 744}
744 745
745/// Gets the priority for the specified thread 746/// Gets the priority for the specified thread
746static ResultCode GetThreadPriority(s32* priority, Kernel::Handle handle) { 747static ResultCode GetThreadPriority(u32* priority, Kernel::Handle handle) {
747 const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); 748 const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
748 if (thread == nullptr) 749 if (thread == nullptr)
749 return ERR_INVALID_HANDLE; 750 return ERR_INVALID_HANDLE;
@@ -753,7 +754,7 @@ static ResultCode GetThreadPriority(s32* priority, Kernel::Handle handle) {
753} 754}
754 755
755/// Sets the priority for the specified thread 756/// Sets the priority for the specified thread
756static ResultCode SetThreadPriority(Kernel::Handle handle, s32 priority) { 757static ResultCode SetThreadPriority(Kernel::Handle handle, u32 priority) {
757 if (priority > THREADPRIO_LOWEST) { 758 if (priority > THREADPRIO_LOWEST) {
758 return Kernel::ERR_OUT_OF_RANGE; 759 return Kernel::ERR_OUT_OF_RANGE;
759 } 760 }
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index 5ad5c5287..918038f1e 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -91,8 +91,8 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo* loadinfo, u32* offsets)
91 return loadinfo->seg_addrs[2] + addr - offsets[1]; 91 return loadinfo->seg_addrs[2] + addr - offsets[1];
92} 92}
93 93
94using Kernel::SharedPtr;
95using Kernel::CodeSet; 94using Kernel::CodeSet;
95using Kernel::SharedPtr;
96 96
97static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, 97static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr,
98 SharedPtr<CodeSet>* out_codeset) { 98 SharedPtr<CodeSet>* out_codeset) {
@@ -255,7 +255,7 @@ FileType AppLoader_THREEDSX::IdentifyType(FileUtil::IOFile& file) {
255 return FileType::Error; 255 return FileType::Error;
256} 256}
257 257
258ResultStatus AppLoader_THREEDSX::Load() { 258ResultStatus AppLoader_THREEDSX::Load(Kernel::SharedPtr<Kernel::Process>& process) {
259 if (is_loaded) 259 if (is_loaded)
260 return ResultStatus::ErrorAlreadyLoaded; 260 return ResultStatus::ErrorAlreadyLoaded;
261 261
@@ -267,16 +267,15 @@ ResultStatus AppLoader_THREEDSX::Load() {
267 return ResultStatus::Error; 267 return ResultStatus::Error;
268 codeset->name = filename; 268 codeset->name = filename;
269 269
270 Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); 270 process = Kernel::Process::Create(std::move(codeset));
271 Kernel::g_current_process->svc_access_mask.set(); 271 process->svc_access_mask.set();
272 Kernel::g_current_process->address_mappings = default_address_mappings; 272 process->address_mappings = default_address_mappings;
273 Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
274 273
275 // Attach the default resource limit (APPLICATION) to the process 274 // Attach the default resource limit (APPLICATION) to the process
276 Kernel::g_current_process->resource_limit = 275 process->resource_limit =
277 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 276 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
278 277
279 Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); 278 process->Run(48, Kernel::DEFAULT_STACK_SIZE);
280 279
281 Service::FS::RegisterSelfNCCH(*this); 280 Service::FS::RegisterSelfNCCH(*this);
282 281
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h
index 3f376778a..1e59bbb9d 100644
--- a/src/core/loader/3dsx.h
+++ b/src/core/loader/3dsx.h
@@ -31,7 +31,7 @@ public:
31 return IdentifyType(file); 31 return IdentifyType(file);
32 } 32 }
33 33
34 ResultStatus Load() override; 34 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
35 35
36 ResultStatus ReadIcon(std::vector<u8>& buffer) override; 36 ResultStatus ReadIcon(std::vector<u8>& buffer) override;
37 37
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 2de1f4e81..e36e42120 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -13,8 +13,8 @@
13#include "core/loader/elf.h" 13#include "core/loader/elf.h"
14#include "core/memory.h" 14#include "core/memory.h"
15 15
16using Kernel::SharedPtr;
17using Kernel::CodeSet; 16using Kernel::CodeSet;
17using Kernel::SharedPtr;
18 18
19//////////////////////////////////////////////////////////////////////////////////////////////////// 19////////////////////////////////////////////////////////////////////////////////////////////////////
20// ELF Header Constants 20// ELF Header Constants
@@ -375,7 +375,7 @@ FileType AppLoader_ELF::IdentifyType(FileUtil::IOFile& file) {
375 return FileType::Error; 375 return FileType::Error;
376} 376}
377 377
378ResultStatus AppLoader_ELF::Load() { 378ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
379 if (is_loaded) 379 if (is_loaded)
380 return ResultStatus::ErrorAlreadyLoaded; 380 return ResultStatus::ErrorAlreadyLoaded;
381 381
@@ -394,16 +394,15 @@ ResultStatus AppLoader_ELF::Load() {
394 SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); 394 SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
395 codeset->name = filename; 395 codeset->name = filename;
396 396
397 Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); 397 process = Kernel::Process::Create(std::move(codeset));
398 Kernel::g_current_process->svc_access_mask.set(); 398 process->svc_access_mask.set();
399 Kernel::g_current_process->address_mappings = default_address_mappings; 399 process->address_mappings = default_address_mappings;
400 Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
401 400
402 // Attach the default resource limit (APPLICATION) to the process 401 // Attach the default resource limit (APPLICATION) to the process
403 Kernel::g_current_process->resource_limit = 402 process->resource_limit =
404 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 403 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
405 404
406 Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); 405 process->Run(48, Kernel::DEFAULT_STACK_SIZE);
407 406
408 is_loaded = true; 407 is_loaded = true;
409 return ResultStatus::Success; 408 return ResultStatus::Success;
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h
index 862aa90d8..113da5917 100644
--- a/src/core/loader/elf.h
+++ b/src/core/loader/elf.h
@@ -30,7 +30,7 @@ public:
30 return IdentifyType(file); 30 return IdentifyType(file);
31 } 31 }
32 32
33 ResultStatus Load() override; 33 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
34 34
35private: 35private:
36 std::string filename; 36 std::string filename;
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 3160fd2fd..82b2be6a3 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -13,10 +13,12 @@
13#include <boost/optional.hpp> 13#include <boost/optional.hpp>
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/file_util.h" 15#include "common/file_util.h"
16#include "core/hle/kernel/kernel.h"
16 17
17namespace Kernel { 18namespace Kernel {
18struct AddressMapping; 19struct AddressMapping;
19} 20class Process;
21} // namespace Kernel
20 22
21//////////////////////////////////////////////////////////////////////////////////////////////////// 23////////////////////////////////////////////////////////////////////////////////////////////////////
22// Loader namespace 24// Loader namespace
@@ -92,10 +94,11 @@ public:
92 virtual FileType GetFileType() = 0; 94 virtual FileType GetFileType() = 0;
93 95
94 /** 96 /**
95 * Load the application 97 * Load the application and return the created Process instance
96 * @return ResultStatus result of function 98 * @param process The newly created process.
99 * @return The status result of the operation.
97 */ 100 */
98 virtual ResultStatus Load() = 0; 101 virtual ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) = 0;
99 102
100 /** 103 /**
101 * Loads the system mode that this application needs. 104 * Loads the system mode that this application needs.
@@ -206,4 +209,4 @@ extern const std::initializer_list<Kernel::AddressMapping> default_address_mappi
206 */ 209 */
207std::unique_ptr<AppLoader> GetLoader(const std::string& filename); 210std::unique_ptr<AppLoader> GetLoader(const std::string& filename);
208 211
209} // namespace 212} // namespace Loader
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 5107135f9..66bc5823d 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -67,9 +67,9 @@ std::pair<boost::optional<u32>, ResultStatus> AppLoader_NCCH::LoadKernelSystemMo
67 ResultStatus::Success); 67 ResultStatus::Success);
68} 68}
69 69
70ResultStatus AppLoader_NCCH::LoadExec() { 70ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& process) {
71 using Kernel::SharedPtr;
72 using Kernel::CodeSet; 71 using Kernel::CodeSet;
72 using Kernel::SharedPtr;
73 73
74 if (!is_loaded) 74 if (!is_loaded)
75 return ResultStatus::ErrorNotLoaded; 75 return ResultStatus::ErrorNotLoaded;
@@ -107,16 +107,15 @@ ResultStatus AppLoader_NCCH::LoadExec() {
107 codeset->entrypoint = codeset->code.addr; 107 codeset->entrypoint = codeset->code.addr;
108 codeset->memory = std::make_shared<std::vector<u8>>(std::move(code)); 108 codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
109 109
110 Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); 110 process = Kernel::Process::Create(std::move(codeset));
111 Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
112 111
113 // Attach a resource limit to the process based on the resource limit category 112 // Attach a resource limit to the process based on the resource limit category
114 Kernel::g_current_process->resource_limit = 113 process->resource_limit =
115 Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>( 114 Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>(
116 overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category)); 115 overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category));
117 116
118 // Set the default CPU core for this process 117 // Set the default CPU core for this process
119 Kernel::g_current_process->ideal_processor = 118 process->ideal_processor =
120 overlay_ncch->exheader_header.arm11_system_local_caps.ideal_processor; 119 overlay_ncch->exheader_header.arm11_system_local_caps.ideal_processor;
121 120
122 // Copy data while converting endianness 121 // Copy data while converting endianness
@@ -124,11 +123,11 @@ ResultStatus AppLoader_NCCH::LoadExec() {
124 kernel_caps; 123 kernel_caps;
125 std::copy_n(overlay_ncch->exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), 124 std::copy_n(overlay_ncch->exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(),
126 begin(kernel_caps)); 125 begin(kernel_caps));
127 Kernel::g_current_process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size()); 126 process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size());
128 127
129 s32 priority = overlay_ncch->exheader_header.arm11_system_local_caps.priority; 128 s32 priority = overlay_ncch->exheader_header.arm11_system_local_caps.priority;
130 u32 stack_size = overlay_ncch->exheader_header.codeset_info.stack_size; 129 u32 stack_size = overlay_ncch->exheader_header.codeset_info.stack_size;
131 Kernel::g_current_process->Run(priority, stack_size); 130 process->Run(priority, stack_size);
132 return ResultStatus::Success; 131 return ResultStatus::Success;
133 } 132 }
134 return ResultStatus::Error; 133 return ResultStatus::Error;
@@ -151,7 +150,7 @@ void AppLoader_NCCH::ParseRegionLockoutInfo() {
151 } 150 }
152} 151}
153 152
154ResultStatus AppLoader_NCCH::Load() { 153ResultStatus AppLoader_NCCH::Load(Kernel::SharedPtr<Kernel::Process>& process) {
155 u64_le ncch_program_id; 154 u64_le ncch_program_id;
156 155
157 if (is_loaded) 156 if (is_loaded)
@@ -183,7 +182,7 @@ ResultStatus AppLoader_NCCH::Load() {
183 182
184 is_loaded = true; // Set state to loaded 183 is_loaded = true; // Set state to loaded
185 184
186 result = LoadExec(); // Load the executable into memory for booting 185 result = LoadExec(process); // Load the executable into memory for booting
187 if (ResultStatus::Success != result) 186 if (ResultStatus::Success != result)
188 return result; 187 return result;
189 188
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h
index 9b56465cb..09230ae33 100644
--- a/src/core/loader/ncch.h
+++ b/src/core/loader/ncch.h
@@ -33,7 +33,7 @@ public:
33 return IdentifyType(file); 33 return IdentifyType(file);
34 } 34 }
35 35
36 ResultStatus Load() override; 36 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
37 37
38 /** 38 /**
39 * Loads the Exheader and returns the system mode for this application. 39 * Loads the Exheader and returns the system mode for this application.
@@ -62,9 +62,10 @@ public:
62private: 62private:
63 /** 63 /**
64 * Loads .code section into memory for booting 64 * Loads .code section into memory for booting
65 * @param process The newly created process
65 * @return ResultStatus result of function 66 * @return ResultStatus result of function
66 */ 67 */
67 ResultStatus LoadExec(); 68 ResultStatus LoadExec(Kernel::SharedPtr<Kernel::Process>& process);
68 69
69 /// Reads the region lockout info in the SMDH and send it to CFG service 70 /// Reads the region lockout info in the SMDH and send it to CFG service
70 void ParseRegionLockoutInfo(); 71 void ParseRegionLockoutInfo();
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 9b394f84b..847e69710 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -110,8 +110,8 @@ static u8* GetPointerFromVMA(VAddr vaddr) {
110/** 110/**
111 * This function should only be called for virtual addreses with attribute `PageType::Special`. 111 * This function should only be called for virtual addreses with attribute `PageType::Special`.
112 */ 112 */
113static MMIORegionPointer GetMMIOHandler(VAddr vaddr) { 113static MMIORegionPointer GetMMIOHandler(const PageTable& page_table, VAddr vaddr) {
114 for (const auto& region : current_page_table->special_regions) { 114 for (const auto& region : page_table.special_regions) {
115 if (vaddr >= region.base && vaddr < (region.base + region.size)) { 115 if (vaddr >= region.base && vaddr < (region.base + region.size)) {
116 return region.handler; 116 return region.handler;
117 } 117 }
@@ -120,6 +120,11 @@ static MMIORegionPointer GetMMIOHandler(VAddr vaddr) {
120 return nullptr; // Should never happen 120 return nullptr; // Should never happen
121} 121}
122 122
123static MMIORegionPointer GetMMIOHandler(VAddr vaddr) {
124 const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table;
125 return GetMMIOHandler(page_table, vaddr);
126}
127
123template <typename T> 128template <typename T>
124T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr); 129T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr);
125 130
@@ -204,18 +209,20 @@ void Write(const VAddr vaddr, const T data) {
204 } 209 }
205} 210}
206 211
207bool IsValidVirtualAddress(const VAddr vaddr) { 212bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
208 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 213 auto& page_table = process.vm_manager.page_table;
214
215 const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
209 if (page_pointer) 216 if (page_pointer)
210 return true; 217 return true;
211 218
212 if (current_page_table->attributes[vaddr >> PAGE_BITS] == PageType::RasterizerCachedMemory) 219 if (page_table.attributes[vaddr >> PAGE_BITS] == PageType::RasterizerCachedMemory)
213 return true; 220 return true;
214 221
215 if (current_page_table->attributes[vaddr >> PAGE_BITS] != PageType::Special) 222 if (page_table.attributes[vaddr >> PAGE_BITS] != PageType::Special)
216 return false; 223 return false;
217 224
218 MMIORegionPointer mmio_region = GetMMIOHandler(vaddr); 225 MMIORegionPointer mmio_region = GetMMIOHandler(page_table, vaddr);
219 if (mmio_region) { 226 if (mmio_region) {
220 return mmio_region->IsValidAddress(vaddr); 227 return mmio_region->IsValidAddress(vaddr);
221 } 228 }
@@ -223,6 +230,10 @@ bool IsValidVirtualAddress(const VAddr vaddr) {
223 return false; 230 return false;
224} 231}
225 232
233bool IsValidVirtualAddress(const VAddr vaddr) {
234 return IsValidVirtualAddress(*Kernel::g_current_process, vaddr);
235}
236
226bool IsValidPhysicalAddress(const PAddr paddr) { 237bool IsValidPhysicalAddress(const PAddr paddr) {
227 return GetPhysicalPointer(paddr) != nullptr; 238 return GetPhysicalPointer(paddr) != nullptr;
228} 239}
@@ -466,7 +477,7 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
466 477
467 while (remaining_size > 0) { 478 while (remaining_size > 0) {
468 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 479 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
469 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; 480 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
470 481
471 switch (current_page_table->attributes[page_index]) { 482 switch (current_page_table->attributes[page_index]) {
472 case PageType::Unmapped: { 483 case PageType::Unmapped: {
@@ -489,13 +500,15 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
489 break; 500 break;
490 } 501 }
491 case PageType::RasterizerCachedMemory: { 502 case PageType::RasterizerCachedMemory: {
492 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); 503 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
504 FlushMode::Flush);
493 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); 505 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
494 break; 506 break;
495 } 507 }
496 case PageType::RasterizerCachedSpecial: { 508 case PageType::RasterizerCachedSpecial: {
497 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 509 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
498 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); 510 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
511 FlushMode::Flush);
499 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); 512 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
500 break; 513 break;
501 } 514 }
@@ -533,7 +546,7 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
533 546
534 while (remaining_size > 0) { 547 while (remaining_size > 0) {
535 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 548 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
536 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; 549 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
537 550
538 switch (current_page_table->attributes[page_index]) { 551 switch (current_page_table->attributes[page_index]) {
539 case PageType::Unmapped: { 552 case PageType::Unmapped: {
@@ -556,13 +569,15 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
556 break; 569 break;
557 } 570 }
558 case PageType::RasterizerCachedMemory: { 571 case PageType::RasterizerCachedMemory: {
559 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); 572 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
573 FlushMode::FlushAndInvalidate);
560 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); 574 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
561 break; 575 break;
562 } 576 }
563 case PageType::RasterizerCachedSpecial: { 577 case PageType::RasterizerCachedSpecial: {
564 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 578 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
565 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); 579 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
580 FlushMode::FlushAndInvalidate);
566 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); 581 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
567 break; 582 break;
568 } 583 }
@@ -586,7 +601,7 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
586 601
587 while (remaining_size > 0) { 602 while (remaining_size > 0) {
588 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 603 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
589 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; 604 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
590 605
591 switch (current_page_table->attributes[page_index]) { 606 switch (current_page_table->attributes[page_index]) {
592 case PageType::Unmapped: { 607 case PageType::Unmapped: {
@@ -608,13 +623,15 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
608 break; 623 break;
609 } 624 }
610 case PageType::RasterizerCachedMemory: { 625 case PageType::RasterizerCachedMemory: {
611 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); 626 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
627 FlushMode::FlushAndInvalidate);
612 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); 628 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
613 break; 629 break;
614 } 630 }
615 case PageType::RasterizerCachedSpecial: { 631 case PageType::RasterizerCachedSpecial: {
616 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 632 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
617 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); 633 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
634 FlushMode::FlushAndInvalidate);
618 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); 635 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
619 break; 636 break;
620 } 637 }
@@ -635,7 +652,7 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
635 652
636 while (remaining_size > 0) { 653 while (remaining_size > 0) {
637 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 654 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
638 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; 655 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
639 656
640 switch (current_page_table->attributes[page_index]) { 657 switch (current_page_table->attributes[page_index]) {
641 case PageType::Unmapped: { 658 case PageType::Unmapped: {
@@ -659,13 +676,15 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
659 break; 676 break;
660 } 677 }
661 case PageType::RasterizerCachedMemory: { 678 case PageType::RasterizerCachedMemory: {
662 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); 679 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
680 FlushMode::Flush);
663 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); 681 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
664 break; 682 break;
665 } 683 }
666 case PageType::RasterizerCachedSpecial: { 684 case PageType::RasterizerCachedSpecial: {
667 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 685 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
668 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); 686 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
687 FlushMode::Flush);
669 688
670 std::vector<u8> buffer(copy_amount); 689 std::vector<u8> buffer(copy_amount);
671 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); 690 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());
@@ -678,8 +697,8 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
678 697
679 page_index++; 698 page_index++;
680 page_offset = 0; 699 page_offset = 0;
681 dest_addr += copy_amount; 700 dest_addr += static_cast<VAddr>(copy_amount);
682 src_addr += copy_amount; 701 src_addr += static_cast<VAddr>(copy_amount);
683 remaining_size -= copy_amount; 702 remaining_size -= copy_amount;
684 } 703 }
685} 704}
diff --git a/src/core/memory.h b/src/core/memory.h
index 1865bfea0..347c08c78 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -12,6 +12,10 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/mmio.h" 13#include "core/mmio.h"
14 14
15namespace Kernel {
16class Process;
17}
18
15namespace Memory { 19namespace Memory {
16 20
17/** 21/**
@@ -185,7 +189,10 @@ enum : VAddr {
185void SetCurrentPageTable(PageTable* page_table); 189void SetCurrentPageTable(PageTable* page_table);
186PageTable* GetCurrentPageTable(); 190PageTable* GetCurrentPageTable();
187 191
192/// Determines if the given VAddr is valid for the specified process.
193bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr);
188bool IsValidVirtualAddress(const VAddr addr); 194bool IsValidVirtualAddress(const VAddr addr);
195
189bool IsValidPhysicalAddress(const PAddr addr); 196bool IsValidPhysicalAddress(const PAddr addr);
190 197
191u8 Read8(VAddr addr); 198u8 Read8(VAddr addr);
diff --git a/src/network/packet.cpp b/src/network/packet.cpp
index cc60f2fbc..7e1a812f3 100644
--- a/src/network/packet.cpp
+++ b/src/network/packet.cpp
@@ -233,7 +233,7 @@ Packet& Packet::operator<<(double in_data) {
233 233
234Packet& Packet::operator<<(const char* in_data) { 234Packet& Packet::operator<<(const char* in_data) {
235 // First insert string length 235 // First insert string length
236 u32 length = std::strlen(in_data); 236 u32 length = static_cast<u32>(std::strlen(in_data));
237 *this << length; 237 *this << length;
238 238
239 // Then insert characters 239 // Then insert characters
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 5e9c4c2bf..1aac0daa2 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -4,6 +4,7 @@ set(SRCS
4 core/arm/dyncom/arm_dyncom_vfp_tests.cpp 4 core/arm/dyncom/arm_dyncom_vfp_tests.cpp
5 core/file_sys/path_parser.cpp 5 core/file_sys/path_parser.cpp
6 core/hle/kernel/hle_ipc.cpp 6 core/hle/kernel/hle_ipc.cpp
7 core/memory/memory.cpp
7 glad.cpp 8 glad.cpp
8 tests.cpp 9 tests.cpp
9 ) 10 )
diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp
index cfe0d503a..484713a92 100644
--- a/src/tests/core/arm/arm_test_common.cpp
+++ b/src/tests/core/arm/arm_test_common.cpp
@@ -3,30 +3,34 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/process.h"
6#include "core/memory.h" 7#include "core/memory.h"
7#include "core/memory_setup.h" 8#include "core/memory_setup.h"
8#include "tests/core/arm/arm_test_common.h" 9#include "tests/core/arm/arm_test_common.h"
9 10
10namespace ArmTests { 11namespace ArmTests {
11 12
12static Memory::PageTable page_table; 13static Memory::PageTable* page_table = nullptr;
13 14
14TestEnvironment::TestEnvironment(bool mutable_memory_) 15TestEnvironment::TestEnvironment(bool mutable_memory_)
15 : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { 16 : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
16 17
17 page_table.pointers.fill(nullptr); 18 Kernel::g_current_process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
18 page_table.attributes.fill(Memory::PageType::Unmapped); 19 page_table = &Kernel::g_current_process->vm_manager.page_table;
19 page_table.cached_res_count.fill(0);
20 20
21 Memory::MapIoRegion(page_table, 0x00000000, 0x80000000, test_memory); 21 page_table->pointers.fill(nullptr);
22 Memory::MapIoRegion(page_table, 0x80000000, 0x80000000, test_memory); 22 page_table->attributes.fill(Memory::PageType::Unmapped);
23 page_table->cached_res_count.fill(0);
23 24
24 Memory::SetCurrentPageTable(&page_table); 25 Memory::MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory);
26 Memory::MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory);
27
28 Memory::SetCurrentPageTable(page_table);
25} 29}
26 30
27TestEnvironment::~TestEnvironment() { 31TestEnvironment::~TestEnvironment() {
28 Memory::UnmapRegion(page_table, 0x80000000, 0x80000000); 32 Memory::UnmapRegion(*page_table, 0x80000000, 0x80000000);
29 Memory::UnmapRegion(page_table, 0x00000000, 0x80000000); 33 Memory::UnmapRegion(*page_table, 0x00000000, 0x80000000);
30} 34}
31 35
32void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) { 36void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) {
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp
new file mode 100644
index 000000000..a01b896f7
--- /dev/null
+++ b/src/tests/core/memory/memory.cpp
@@ -0,0 +1,56 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <catch.hpp>
6#include "core/hle/kernel/memory.h"
7#include "core/hle/kernel/process.h"
8#include "core/memory.h"
9
10TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
11 SECTION("these regions should not be mapped on an empty process") {
12 auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
13 CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);
14 CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false);
15 CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false);
16 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false);
17 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
18 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false);
19 CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false);
20 }
21
22 SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") {
23 auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
24 Kernel::MapSharedPages(process->vm_manager);
25 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true);
26 CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true);
27 }
28
29 SECTION("special regions should be valid after mapping them") {
30 auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
31 SECTION("VRAM") {
32 Kernel::HandleSpecialMapping(process->vm_manager,
33 {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false});
34 CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true);
35 }
36
37 SECTION("IO (Not yet implemented)") {
38 Kernel::HandleSpecialMapping(
39 process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false});
40 CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true);
41 }
42
43 SECTION("DSP") {
44 Kernel::HandleSpecialMapping(
45 process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false});
46 CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true);
47 }
48 }
49
50 SECTION("Unmapping a VAddr should make it invalid") {
51 auto process = Kernel::Process::Create(Kernel::CodeSet::Create("", 0));
52 Kernel::MapSharedPages(process->vm_manager);
53 process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE);
54 CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false);
55 }
56}
diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp
index b146e2ecb..98ff2ccd3 100644
--- a/src/video_core/geometry_pipeline.cpp
+++ b/src/video_core/geometry_pipeline.cpp
@@ -105,7 +105,7 @@ public:
105 DEBUG_ASSERT(need_index); 105 DEBUG_ASSERT(need_index);
106 106
107 // The number of vertex input is put to the uniform register 107 // The number of vertex input is put to the uniform register
108 float24 vertex_num = float24::FromFloat32(val); 108 float24 vertex_num = float24::FromFloat32(static_cast<float>(val));
109 setup.uniforms.f[0] = Math::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num); 109 setup.uniforms.f[0] = Math::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num);
110 110
111 // The second uniform register and so on are used for receiving input vertices 111 // The second uniform register and so on are used for receiving input vertices
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 06a905766..5770ae08f 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -267,9 +267,9 @@ void OpenGLState::Apply() const {
267 for (size_t i = 0; i < clip_distance.size(); ++i) { 267 for (size_t i = 0; i < clip_distance.size(); ++i) {
268 if (clip_distance[i] != cur_state.clip_distance[i]) { 268 if (clip_distance[i] != cur_state.clip_distance[i]) {
269 if (clip_distance[i]) { 269 if (clip_distance[i]) {
270 glEnable(GL_CLIP_DISTANCE0 + i); 270 glEnable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i));
271 } else { 271 } else {
272 glDisable(GL_CLIP_DISTANCE0 + i); 272 glDisable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i));
273 } 273 }
274 } 274 }
275 } 275 }