summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/svc.cpp51
1 files changed, 46 insertions, 5 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 348a22904..c826dfd96 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -254,11 +254,52 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
254 return vm_manager.ReprotectRange(addr, size, converted_permissions); 254 return vm_manager.ReprotectRange(addr, size, converted_permissions);
255} 255}
256 256
257static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { 257static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attribute) {
258 LOG_WARNING(Kernel_SVC, 258 LOG_DEBUG(Kernel_SVC,
259 "(STUBBED) called, addr=0x{:X}, size=0x{:X}, state0=0x{:X}, state1=0x{:X}", addr, 259 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
260 size, state0, state1); 260 size, mask, attribute);
261 return RESULT_SUCCESS; 261
262 if (!Common::Is4KBAligned(address)) {
263 LOG_ERROR(Kernel_SVC, "Address not page aligned (0x{:016X})", address);
264 return ERR_INVALID_ADDRESS;
265 }
266
267 if (size == 0 || !Common::Is4KBAligned(size)) {
268 LOG_ERROR(Kernel_SVC, "Invalid size (0x{:X}). Size must be non-zero and page aligned.",
269 size);
270 return ERR_INVALID_ADDRESS;
271 }
272
273 if (!IsValidAddressRange(address, size)) {
274 LOG_ERROR(Kernel_SVC, "Address range overflowed (Address: 0x{:016X}, Size: 0x{:016X})",
275 address, size);
276 return ERR_INVALID_ADDRESS_STATE;
277 }
278
279 const auto mem_attribute = static_cast<MemoryAttribute>(attribute);
280 const auto mem_mask = static_cast<MemoryAttribute>(mask);
281 const auto attribute_with_mask = mem_attribute | mem_mask;
282
283 if (attribute_with_mask != mem_mask) {
284 LOG_ERROR(Kernel_SVC,
285 "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}",
286 attribute, mask);
287 return ERR_INVALID_COMBINATION;
288 }
289
290 if ((attribute_with_mask | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) {
291 LOG_ERROR(Kernel_SVC, "Specified attribute isn't equal to MemoryAttributeUncached (8).");
292 return ERR_INVALID_COMBINATION;
293 }
294
295 auto& vm_manager = Core::CurrentProcess()->VMManager();
296 if (!IsInsideAddressSpace(vm_manager, address, size)) {
297 LOG_ERROR(Kernel_SVC,
298 "Given address (0x{:016X}) is outside the bounds of the address space.", address);
299 return ERR_INVALID_ADDRESS_STATE;
300 }
301
302 return vm_manager.SetMemoryAttribute(address, size, mem_mask, mem_attribute);
262} 303}
263 304
264/// Maps a memory range into a different range. 305/// Maps a memory range into a different range.