svc: Implement svcSetMemoryAttribute
With all the basic backing functionality implemented, we can now unstub svcSetMemoryAttribute.
This commit is contained in:
		
							parent
							
								
									622242e345
								
							
						
					
					
						commit
						caab838bdb
					
				@ -254,11 +254,52 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
 | 
			
		||||
    return vm_manager.ReprotectRange(addr, size, converted_permissions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
 | 
			
		||||
    LOG_WARNING(Kernel_SVC,
 | 
			
		||||
                "(STUBBED) called, addr=0x{:X}, size=0x{:X}, state0=0x{:X}, state1=0x{:X}", addr,
 | 
			
		||||
                size, state0, state1);
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attribute) {
 | 
			
		||||
    LOG_DEBUG(Kernel_SVC,
 | 
			
		||||
              "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
 | 
			
		||||
              size, mask, attribute);
 | 
			
		||||
 | 
			
		||||
    if (!Common::Is4KBAligned(address)) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "Address not page aligned (0x{:016X})", address);
 | 
			
		||||
        return ERR_INVALID_ADDRESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (size == 0 || !Common::Is4KBAligned(size)) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "Invalid size (0x{:X}). Size must be non-zero and page aligned.",
 | 
			
		||||
                  size);
 | 
			
		||||
        return ERR_INVALID_ADDRESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!IsValidAddressRange(address, size)) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "Address range overflowed (Address: 0x{:016X}, Size: 0x{:016X})",
 | 
			
		||||
                  address, size);
 | 
			
		||||
        return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto mem_attribute = static_cast<MemoryAttribute>(attribute);
 | 
			
		||||
    const auto mem_mask = static_cast<MemoryAttribute>(mask);
 | 
			
		||||
    const auto attribute_with_mask = mem_attribute | mem_mask;
 | 
			
		||||
 | 
			
		||||
    if (attribute_with_mask != mem_mask) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC,
 | 
			
		||||
                  "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}",
 | 
			
		||||
                  attribute, mask);
 | 
			
		||||
        return ERR_INVALID_COMBINATION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((attribute_with_mask | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC, "Specified attribute isn't equal to MemoryAttributeUncached (8).");
 | 
			
		||||
        return ERR_INVALID_COMBINATION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& vm_manager = Core::CurrentProcess()->VMManager();
 | 
			
		||||
    if (!IsInsideAddressSpace(vm_manager, address, size)) {
 | 
			
		||||
        LOG_ERROR(Kernel_SVC,
 | 
			
		||||
                  "Given address (0x{:016X}) is outside the bounds of the address space.", address);
 | 
			
		||||
        return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return vm_manager.SetMemoryAttribute(address, size, mem_mask, mem_attribute);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Maps a memory range into a different range.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user