core: hle: Address various feedback & code cleanup.
- Should be no functional changes.
This commit is contained in:
		
							parent
							
								
									92caa003a8
								
							
						
					
					
						commit
						8bbe74a8dc
					
				@ -13,13 +13,15 @@ namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
 | 
			
		||||
namespace DramMemoryMap {
 | 
			
		||||
constexpr u64 Base = 0x80000000ULL;
 | 
			
		||||
constexpr u64 Size = 0x100000000ULL;
 | 
			
		||||
constexpr u64 End = Base + Size;
 | 
			
		||||
constexpr u64 KernelReserveBase = Base + 0x60000;
 | 
			
		||||
constexpr u64 SlabHeapBase = KernelReserveBase + 0x85000;
 | 
			
		||||
constexpr u64 SlapHeapSize = 0xa21000;
 | 
			
		||||
constexpr u64 SlabHeapEnd = SlabHeapBase + SlapHeapSize;
 | 
			
		||||
enum : u64 {
 | 
			
		||||
    Base = 0x80000000ULL,
 | 
			
		||||
    Size = 0x100000000ULL,
 | 
			
		||||
    End = Base + Size,
 | 
			
		||||
    KernelReserveBase = Base + 0x60000,
 | 
			
		||||
    SlabHeapBase = KernelReserveBase + 0x85000,
 | 
			
		||||
    SlapHeapSize = 0xa21000,
 | 
			
		||||
    SlabHeapEnd = SlabHeapBase + SlapHeapSize,
 | 
			
		||||
};
 | 
			
		||||
}; // namespace DramMemoryMap
 | 
			
		||||
 | 
			
		||||
class DeviceMemory : NonCopyable {
 | 
			
		||||
 | 
			
		||||
@ -14,16 +14,18 @@ namespace Kernel::Memory {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
constexpr std::size_t Size_1_MB{0x100000};
 | 
			
		||||
constexpr std::size_t Size_2_MB{2 * Size_1_MB};
 | 
			
		||||
constexpr std::size_t Size_128_MB{128 * Size_1_MB};
 | 
			
		||||
constexpr std::size_t Size_1_GB{0x40000000};
 | 
			
		||||
constexpr std::size_t Size_2_GB{2 * Size_1_GB};
 | 
			
		||||
constexpr std::size_t Size_4_GB{4 * Size_1_GB};
 | 
			
		||||
constexpr std::size_t Size_6_GB{6 * Size_1_GB};
 | 
			
		||||
constexpr std::size_t Size_64_GB{64 * Size_1_GB};
 | 
			
		||||
constexpr std::size_t Size_512_GB{512 * Size_1_GB};
 | 
			
		||||
constexpr u64 Invalid{std::numeric_limits<u64>::max()};
 | 
			
		||||
enum : u64 {
 | 
			
		||||
    Size_1_MB = 0x100000,
 | 
			
		||||
    Size_2_MB = 2 * Size_1_MB,
 | 
			
		||||
    Size_128_MB = 128 * Size_1_MB,
 | 
			
		||||
    Size_1_GB = 0x40000000,
 | 
			
		||||
    Size_2_GB = 2 * Size_1_GB,
 | 
			
		||||
    Size_4_GB = 4 * Size_1_GB,
 | 
			
		||||
    Size_6_GB = 6 * Size_1_GB,
 | 
			
		||||
    Size_64_GB = 64 * Size_1_GB,
 | 
			
		||||
    Size_512_GB = 512 * Size_1_GB,
 | 
			
		||||
    Invalid = std::numeric_limits<u64>::max(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) {
 | 
			
		||||
    iterator node{memory_block_tree.begin()};
 | 
			
		||||
    auto node{memory_block_tree.begin()};
 | 
			
		||||
    while (node != end()) {
 | 
			
		||||
        const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()};
 | 
			
		||||
        if (node->GetAddress() <= addr && end_addr - 1 >= addr) {
 | 
			
		||||
@ -35,8 +35,8 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu
 | 
			
		||||
 | 
			
		||||
    const VAddr region_end{region_start + region_num_pages * PageSize};
 | 
			
		||||
    const VAddr region_last{region_end - 1};
 | 
			
		||||
    for (const_iterator it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) {
 | 
			
		||||
        const MemoryInfo info{it->GetMemoryInfo()};
 | 
			
		||||
    for (auto it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) {
 | 
			
		||||
        const auto info{it->GetMemoryInfo()};
 | 
			
		||||
        if (region_last < info.GetAddress()) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -15,15 +15,14 @@
 | 
			
		||||
namespace Kernel::Memory {
 | 
			
		||||
 | 
			
		||||
std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) {
 | 
			
		||||
    const std::size_t size{end_address - start_address};
 | 
			
		||||
    const auto size{end_address - start_address};
 | 
			
		||||
 | 
			
		||||
    // Calculate metadata sizes
 | 
			
		||||
    const std::size_t ref_count_size{(size / PageSize) * sizeof(u16)};
 | 
			
		||||
    const std::size_t optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) *
 | 
			
		||||
                                        sizeof(u64)};
 | 
			
		||||
    const std::size_t manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)};
 | 
			
		||||
    const std::size_t page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)};
 | 
			
		||||
    const std::size_t total_metadata_size{manager_size + page_heap_size};
 | 
			
		||||
    const auto ref_count_size{(size / PageSize) * sizeof(u16)};
 | 
			
		||||
    const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)};
 | 
			
		||||
    const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)};
 | 
			
		||||
    const auto page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)};
 | 
			
		||||
    const auto total_metadata_size{manager_size + page_heap_size};
 | 
			
		||||
    ASSERT(manager_size <= total_metadata_size);
 | 
			
		||||
    ASSERT(Common::IsAligned(total_metadata_size, PageSize));
 | 
			
		||||
 | 
			
		||||
@ -55,7 +54,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Lock the pool that we're allocating from
 | 
			
		||||
    const std::size_t pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    const auto pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    std::lock_guard lock{pool_locks[pool_index]};
 | 
			
		||||
 | 
			
		||||
    // Choose a heap based on our page size request
 | 
			
		||||
@ -72,7 +71,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we allocated more than we need, free some
 | 
			
		||||
    const std::size_t allocated_pages{PageHeap::GetBlockNumPages(heap_index)};
 | 
			
		||||
    const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)};
 | 
			
		||||
    if (allocated_pages > num_pages) {
 | 
			
		||||
        chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages);
 | 
			
		||||
    }
 | 
			
		||||
@ -90,7 +89,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Lock the pool that we're allocating from
 | 
			
		||||
    const std::size_t pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    const auto pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    std::lock_guard lock{pool_locks[pool_index]};
 | 
			
		||||
 | 
			
		||||
    // Choose a heap based on our page size request
 | 
			
		||||
@ -105,7 +104,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
 | 
			
		||||
    // Ensure that we don't leave anything un-freed
 | 
			
		||||
    auto group_guard = detail::ScopeExit([&] {
 | 
			
		||||
        for (const auto& it : page_list.Nodes()) {
 | 
			
		||||
            const std::size_t num_pages{std::min(
 | 
			
		||||
            const auto num_pages{std::min(
 | 
			
		||||
                it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
 | 
			
		||||
            chosen_manager.Free(it.GetAddress(), num_pages);
 | 
			
		||||
        }
 | 
			
		||||
@ -113,12 +112,12 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
 | 
			
		||||
 | 
			
		||||
    // Keep allocating until we've allocated all our pages
 | 
			
		||||
    for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) {
 | 
			
		||||
        const std::size_t pages_per_alloc{PageHeap::GetBlockNumPages(index)};
 | 
			
		||||
        const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)};
 | 
			
		||||
 | 
			
		||||
        while (num_pages >= pages_per_alloc) {
 | 
			
		||||
            // Allocate a block
 | 
			
		||||
            VAddr allocated_block{chosen_manager.AllocateBlock(index)};
 | 
			
		||||
            if (allocated_block == 0) {
 | 
			
		||||
            if (!allocated_block) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -158,7 +157,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Lock the pool that we're freeing from
 | 
			
		||||
    const std::size_t pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    const auto pool_index{static_cast<std::size_t>(pool)};
 | 
			
		||||
    std::lock_guard lock{pool_locks[pool_index]};
 | 
			
		||||
 | 
			
		||||
    // TODO (bunnei): Support multiple managers
 | 
			
		||||
@ -166,7 +165,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages,
 | 
			
		||||
 | 
			
		||||
    // Free all of the pages
 | 
			
		||||
    for (const auto& it : page_list.Nodes()) {
 | 
			
		||||
        const std::size_t num_pages{std::min(
 | 
			
		||||
        const auto num_pages{std::min(
 | 
			
		||||
            it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
 | 
			
		||||
        chosen_manager.Free(it.GetAddress(), num_pages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -22,9 +22,10 @@ namespace Kernel::Memory {
 | 
			
		||||
class PageHeap final : NonCopyable {
 | 
			
		||||
public:
 | 
			
		||||
    static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) {
 | 
			
		||||
        const std::size_t target_pages{std::max(num_pages, align_pages)};
 | 
			
		||||
        const auto target_pages{std::max(num_pages, align_pages)};
 | 
			
		||||
        for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) {
 | 
			
		||||
            if (target_pages <= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) {
 | 
			
		||||
            if (target_pages <=
 | 
			
		||||
                (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
 | 
			
		||||
                return static_cast<s32>(i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -33,7 +34,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    static constexpr s32 GetBlockIndex(std::size_t num_pages) {
 | 
			
		||||
        for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) {
 | 
			
		||||
            if (num_pages >= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) {
 | 
			
		||||
            if (num_pages >= (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) {
 | 
			
		||||
                return i;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -41,7 +42,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr std::size_t GetBlockSize(std::size_t index) {
 | 
			
		||||
        return std::size_t(1) << MemoryBlockPageShifts[index];
 | 
			
		||||
        return static_cast<std::size_t>(1) << MemoryBlockPageShifts[index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr std::size_t GetBlockNumPages(std::size_t index) {
 | 
			
		||||
@ -51,7 +52,8 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    static constexpr std::size_t NumMemoryBlockPageShifts{7};
 | 
			
		||||
    static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{
 | 
			
		||||
        0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E};
 | 
			
		||||
        0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class Block final : NonCopyable {
 | 
			
		||||
    private:
 | 
			
		||||
@ -122,13 +124,13 @@ private:
 | 
			
		||||
 | 
			
		||||
            constexpr bool ClearRange(std::size_t offset, std::size_t count) {
 | 
			
		||||
                const s32 depth{GetHighestDepthIndex()};
 | 
			
		||||
                const std::size_t bit_ind{offset / 64};
 | 
			
		||||
                const auto bit_ind{offset / 64};
 | 
			
		||||
                u64* bits{bit_storages[depth]};
 | 
			
		||||
                if (count < 64) {
 | 
			
		||||
                    const std::size_t shift{offset % 64};
 | 
			
		||||
                    const auto shift{offset % 64};
 | 
			
		||||
                    ASSERT(shift + count <= 64);
 | 
			
		||||
                    // Check that all the bits are set
 | 
			
		||||
                    const u64 mask{((u64(1) << count) - 1) << shift};
 | 
			
		||||
                    const u64 mask{((1ULL << count) - 1) << shift};
 | 
			
		||||
                    u64 v{bits[bit_ind]};
 | 
			
		||||
                    if ((v & mask) != mask) {
 | 
			
		||||
                        return false;
 | 
			
		||||
@ -171,9 +173,9 @@ private:
 | 
			
		||||
        private:
 | 
			
		||||
            constexpr void SetBit(s32 depth, std::size_t offset) {
 | 
			
		||||
                while (depth >= 0) {
 | 
			
		||||
                    const std::size_t ind{offset / 64};
 | 
			
		||||
                    const std::size_t which{offset % 64};
 | 
			
		||||
                    const u64 mask{u64(1) << which};
 | 
			
		||||
                    const auto ind{offset / 64};
 | 
			
		||||
                    const auto which{offset % 64};
 | 
			
		||||
                    const u64 mask{1ULL << which};
 | 
			
		||||
 | 
			
		||||
                    u64* bit{std::addressof(bit_storages[depth][ind])};
 | 
			
		||||
                    const u64 v{*bit};
 | 
			
		||||
@ -189,9 +191,9 @@ private:
 | 
			
		||||
 | 
			
		||||
            constexpr void ClearBit(s32 depth, std::size_t offset) {
 | 
			
		||||
                while (depth >= 0) {
 | 
			
		||||
                    const std::size_t ind{offset / 64};
 | 
			
		||||
                    const std::size_t which{offset % 64};
 | 
			
		||||
                    const u64 mask{u64(1) << which};
 | 
			
		||||
                    const auto ind{offset / 64};
 | 
			
		||||
                    const auto which{offset % 64};
 | 
			
		||||
                    const u64 mask{1ULL << which};
 | 
			
		||||
 | 
			
		||||
                    u64* bit{std::addressof(bit_storages[depth][ind])};
 | 
			
		||||
                    u64 v{*bit};
 | 
			
		||||
@ -246,7 +248,7 @@ private:
 | 
			
		||||
            return next_block_shift;
 | 
			
		||||
        }
 | 
			
		||||
        constexpr std::size_t GetSize() const {
 | 
			
		||||
            return std::size_t(1) << GetShift();
 | 
			
		||||
            return static_cast<std::size_t>(1) << GetShift();
 | 
			
		||||
        }
 | 
			
		||||
        constexpr std::size_t GetNumPages() const {
 | 
			
		||||
            return GetSize() / PageSize;
 | 
			
		||||
@ -266,13 +268,13 @@ private:
 | 
			
		||||
 | 
			
		||||
            // Align up the address
 | 
			
		||||
            VAddr end{addr + size};
 | 
			
		||||
            const std::size_t align{(next_block_shift != 0) ? (u64(1) << next_block_shift)
 | 
			
		||||
                                                            : (u64(1) << block_shift)};
 | 
			
		||||
            const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift)
 | 
			
		||||
                                                     : (1ULL << block_shift)};
 | 
			
		||||
            addr = Common::AlignDown((addr), align);
 | 
			
		||||
            end = Common::AlignUp((end), align);
 | 
			
		||||
 | 
			
		||||
            heap_address = addr;
 | 
			
		||||
            end_offset = (end - addr) / (u64(1) << block_shift);
 | 
			
		||||
            end_offset = (end - addr) / (1ULL << block_shift);
 | 
			
		||||
            return bitmap.Initialize(bit_storage, end_offset);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -283,7 +285,7 @@ private:
 | 
			
		||||
 | 
			
		||||
            // If we have a next shift, try to clear the blocks below and return the address
 | 
			
		||||
            if (GetNextShift()) {
 | 
			
		||||
                const std::size_t diff{u64(1) << (GetNextShift() - GetShift())};
 | 
			
		||||
                const auto diff{1ULL << (GetNextShift() - GetShift())};
 | 
			
		||||
                offset = Common::AlignDown(offset, diff);
 | 
			
		||||
                if (bitmap.ClearRange(offset, diff)) {
 | 
			
		||||
                    return heap_address + (offset << GetShift());
 | 
			
		||||
@ -300,7 +302,7 @@ private:
 | 
			
		||||
            if (soffset < 0) {
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            const std::size_t offset{static_cast<std::size_t>(soffset)};
 | 
			
		||||
            const auto offset{static_cast<std::size_t>(soffset)};
 | 
			
		||||
 | 
			
		||||
            // Update our tracking and return it
 | 
			
		||||
            bitmap.ClearBit(offset);
 | 
			
		||||
@ -311,9 +313,9 @@ private:
 | 
			
		||||
        static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size,
 | 
			
		||||
                                                                   std::size_t cur_block_shift,
 | 
			
		||||
                                                                   std::size_t next_block_shift) {
 | 
			
		||||
            const std::size_t cur_block_size{(u64(1) << cur_block_shift)};
 | 
			
		||||
            const std::size_t next_block_size{(u64(1) << next_block_shift)};
 | 
			
		||||
            const std::size_t align{(next_block_shift != 0) ? next_block_size : cur_block_size};
 | 
			
		||||
            const auto cur_block_size{(1ULL << cur_block_shift)};
 | 
			
		||||
            const auto next_block_size{(1ULL << next_block_shift)};
 | 
			
		||||
            const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size};
 | 
			
		||||
            return Bitmap::CalculateMetadataOverheadSize(
 | 
			
		||||
                (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -64,10 +64,10 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
 | 
			
		||||
                                           bool enable_aslr, VAddr code_addr, std::size_t code_size,
 | 
			
		||||
                                           Memory::MemoryManager::Pool pool) {
 | 
			
		||||
 | 
			
		||||
    const auto GetSpaceStart = [&](AddressSpaceInfo::Type type) {
 | 
			
		||||
    const auto GetSpaceStart = [this](AddressSpaceInfo::Type type) {
 | 
			
		||||
        return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type);
 | 
			
		||||
    };
 | 
			
		||||
    const auto GetSpaceSize = [&](AddressSpaceInfo::Type type) {
 | 
			
		||||
    const auto GetSpaceSize = [this](AddressSpaceInfo::Type type) {
 | 
			
		||||
        return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -286,17 +286,9 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PageLinkedList page_linked_list;
 | 
			
		||||
    if (const ResultCode result{
 | 
			
		||||
            system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{
 | 
			
		||||
            Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(
 | 
			
		||||
        system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool));
 | 
			
		||||
    CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, num_pages, state, perm);
 | 
			
		||||
 | 
			
		||||
@ -310,13 +302,10 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::
 | 
			
		||||
 | 
			
		||||
    MemoryState state{};
 | 
			
		||||
    MemoryPermission perm{};
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &state, &perm, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal,
 | 
			
		||||
            MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask,
 | 
			
		||||
            MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All,
 | 
			
		||||
                                  MemoryState::Normal, MemoryPermission::Mask,
 | 
			
		||||
                                  MemoryPermission::ReadAndWrite, MemoryAttribute::Mask,
 | 
			
		||||
                                  MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    if (IsRegionMapped(dst_addr, size)) {
 | 
			
		||||
        return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
@ -329,16 +318,9 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::
 | 
			
		||||
        auto block_guard = detail::ScopeExit(
 | 
			
		||||
            [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); });
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None,
 | 
			
		||||
                                            OperationType::ChangePermissions)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{MapPages(dst_addr, page_linked_list, MemoryPermission::None)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(
 | 
			
		||||
            Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions));
 | 
			
		||||
        CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None));
 | 
			
		||||
 | 
			
		||||
        block_guard.Cancel();
 | 
			
		||||
    }
 | 
			
		||||
@ -359,35 +341,20 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std
 | 
			
		||||
 | 
			
		||||
    const std::size_t num_pages{size / PageSize};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal,
 | 
			
		||||
            MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
            MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All,
 | 
			
		||||
                                  MemoryState::Normal, MemoryPermission::None,
 | 
			
		||||
                                  MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
                                  MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    MemoryState state{};
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias,
 | 
			
		||||
            MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
            MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(dst_addr, size, MemoryState::All, state,
 | 
			
		||||
                                                 MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
                                                 MemoryAttribute::Mask, MemoryAttribute::None)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{
 | 
			
		||||
            Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(
 | 
			
		||||
        &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias,
 | 
			
		||||
        MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
        MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None,
 | 
			
		||||
                                  MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
                                  MemoryAttribute::None));
 | 
			
		||||
    CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(dst_addr, num_pages, MemoryState::Free);
 | 
			
		||||
    block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite);
 | 
			
		||||
@ -459,11 +426,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
 | 
			
		||||
            process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{system.Kernel().MemoryManager().Allocate(
 | 
			
		||||
                page_linked_list, remaining_pages, memory_pool)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages,
 | 
			
		||||
                                                              memory_pool));
 | 
			
		||||
 | 
			
		||||
        block_guard.Cancel();
 | 
			
		||||
    }
 | 
			
		||||
@ -508,9 +472,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
 | 
			
		||||
        return RESULT_SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{UnmapMemory(addr, size)}; result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(UnmapMemory(addr, size));
 | 
			
		||||
 | 
			
		||||
    auto process{system.Kernel().CurrentProcess()};
 | 
			
		||||
    process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size);
 | 
			
		||||
@ -559,13 +521,10 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
 | 
			
		||||
    std::lock_guard lock{page_table_lock};
 | 
			
		||||
 | 
			
		||||
    MemoryState src_state{};
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias,
 | 
			
		||||
            MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite,
 | 
			
		||||
            MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(
 | 
			
		||||
        &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias,
 | 
			
		||||
        MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite,
 | 
			
		||||
        MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    if (IsRegionMapped(dst_addr, size)) {
 | 
			
		||||
        return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
@ -582,17 +541,9 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
 | 
			
		||||
                    OperationType::ChangePermissions);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None,
 | 
			
		||||
                                            OperationType::ChangePermissions)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(
 | 
			
		||||
            Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions));
 | 
			
		||||
        CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite));
 | 
			
		||||
 | 
			
		||||
        block_guard.Cancel();
 | 
			
		||||
    }
 | 
			
		||||
@ -608,22 +559,16 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
 | 
			
		||||
    std::lock_guard lock{page_table_lock};
 | 
			
		||||
 | 
			
		||||
    MemoryState src_state{};
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias,
 | 
			
		||||
            MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None,
 | 
			
		||||
            MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(
 | 
			
		||||
        &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias,
 | 
			
		||||
        MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None,
 | 
			
		||||
        MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    MemoryPermission dst_perm{};
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, MemoryState::Stack,
 | 
			
		||||
            MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
            MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All,
 | 
			
		||||
                                  MemoryState::Stack, MemoryPermission::None,
 | 
			
		||||
                                  MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
                                  MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    PageLinkedList src_pages;
 | 
			
		||||
    PageLinkedList dst_pages;
 | 
			
		||||
@ -639,17 +584,9 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
 | 
			
		||||
    {
 | 
			
		||||
        auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); });
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite,
 | 
			
		||||
                                            OperationType::ChangePermissions)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap));
 | 
			
		||||
        CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite,
 | 
			
		||||
                             OperationType::ChangePermissions));
 | 
			
		||||
 | 
			
		||||
        block_guard.Cancel();
 | 
			
		||||
    }
 | 
			
		||||
@ -665,7 +602,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis
 | 
			
		||||
    VAddr cur_addr{addr};
 | 
			
		||||
 | 
			
		||||
    for (const auto& node : page_linked_list.Nodes()) {
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
        if (const auto result{
 | 
			
		||||
                Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()};
 | 
			
		||||
@ -698,9 +635,7 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem
 | 
			
		||||
        return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{MapPages(addr, page_linked_list, perm)}; result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(MapPages(addr, page_linked_list, perm));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, num_pages, state, perm);
 | 
			
		||||
 | 
			
		||||
@ -714,13 +649,10 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
 | 
			
		||||
    MemoryState prev_state{};
 | 
			
		||||
    MemoryPermission prev_perm{};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode,
 | 
			
		||||
            MemoryState::FlagCode, MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
            MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(
 | 
			
		||||
        &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode,
 | 
			
		||||
        MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
        MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    MemoryState state{prev_state};
 | 
			
		||||
 | 
			
		||||
@ -745,9 +677,7 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
 | 
			
		||||
                                      ? OperationType::ChangePermissionsAndRefresh
 | 
			
		||||
                                      : OperationType::ChangePermissions};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{Operate(addr, num_pages, perm, operation)}; result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(Operate(addr, num_pages, perm, operation));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, num_pages, state, perm);
 | 
			
		||||
 | 
			
		||||
@ -775,15 +705,12 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory
 | 
			
		||||
    MemoryState state{};
 | 
			
		||||
    MemoryAttribute attribute{};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &state, nullptr, &attribute, addr, size,
 | 
			
		||||
            MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
            MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
            MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask,
 | 
			
		||||
            MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size,
 | 
			
		||||
                                  MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                                  MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                                  MemoryPermission::Mask, MemoryPermission::ReadAndWrite,
 | 
			
		||||
                                  MemoryAttribute::Mask, MemoryAttribute::None,
 | 
			
		||||
                                  MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked);
 | 
			
		||||
 | 
			
		||||
@ -795,15 +722,12 @@ ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) {
 | 
			
		||||
 | 
			
		||||
    MemoryState state{};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{
 | 
			
		||||
            CheckMemoryState(&state, nullptr, nullptr, addr, size,
 | 
			
		||||
                             MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                             MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                             MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask,
 | 
			
		||||
                             MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size,
 | 
			
		||||
                                  MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                                  MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted,
 | 
			
		||||
                                  MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
                                  MemoryAttribute::Mask, MemoryAttribute::Locked,
 | 
			
		||||
                                  MemoryAttribute::IpcAndDeviceMapped));
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite);
 | 
			
		||||
 | 
			
		||||
@ -818,14 +742,11 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt
 | 
			
		||||
    MemoryPermission perm{};
 | 
			
		||||
    MemoryAttribute attribute{};
 | 
			
		||||
 | 
			
		||||
    if (const ResultCode result{CheckMemoryState(
 | 
			
		||||
            &state, &perm, &attribute, addr, size, MemoryState::FlagCanChangeAttribute,
 | 
			
		||||
            MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None,
 | 
			
		||||
            MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None,
 | 
			
		||||
            MemoryAttribute::DeviceSharedAndUncached)};
 | 
			
		||||
        result.IsError()) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size,
 | 
			
		||||
                                  MemoryState::FlagCanChangeAttribute,
 | 
			
		||||
                                  MemoryState::FlagCanChangeAttribute, MemoryPermission::None,
 | 
			
		||||
                                  MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked,
 | 
			
		||||
                                  MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached));
 | 
			
		||||
 | 
			
		||||
    attribute = attribute & ~mask;
 | 
			
		||||
    attribute = attribute | (mask & value);
 | 
			
		||||
@ -866,21 +787,15 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
 | 
			
		||||
        PageLinkedList page_linked_list;
 | 
			
		||||
        const std::size_t num_pages{delta / PageSize};
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(
 | 
			
		||||
            system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool));
 | 
			
		||||
 | 
			
		||||
        if (IsRegionMapped(current_heap_addr, delta)) {
 | 
			
		||||
            return ERR_INVALID_ADDRESS_STATE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(
 | 
			
		||||
            Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup));
 | 
			
		||||
 | 
			
		||||
        block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal,
 | 
			
		||||
                              MemoryPermission::ReadAndWrite);
 | 
			
		||||
@ -912,23 +827,12 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (is_map_only) {
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
 | 
			
		||||
    } else {
 | 
			
		||||
        PageLinkedList page_group;
 | 
			
		||||
        if (const ResultCode result{system.Kernel().MemoryManager().Allocate(
 | 
			
		||||
                page_group, needed_num_pages, memory_pool)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(
 | 
			
		||||
            system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool));
 | 
			
		||||
        CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    block_manager->Update(addr, needed_num_pages, state, perm);
 | 
			
		||||
@ -1196,11 +1100,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission*
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Validate against the provided masks
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        CASCADE_CODE(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr));
 | 
			
		||||
 | 
			
		||||
        // Break once we're done
 | 
			
		||||
        if (last_addr <= info.GetLastAddress()) {
 | 
			
		||||
 | 
			
		||||
@ -11,9 +11,9 @@
 | 
			
		||||
namespace Kernel::Memory::SystemControl {
 | 
			
		||||
 | 
			
		||||
u64 GenerateRandomU64ForInit() {
 | 
			
		||||
    std::random_device device;
 | 
			
		||||
    std::mt19937 gen(device());
 | 
			
		||||
    std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
 | 
			
		||||
    static std::random_device device;
 | 
			
		||||
    static std::mt19937 gen(device());
 | 
			
		||||
    static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
 | 
			
		||||
    return distribution(gen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,14 +40,14 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t
 | 
			
		||||
    const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize};
 | 
			
		||||
 | 
			
		||||
    if (page_list.GetNumPages() != page_count) {
 | 
			
		||||
        UNIMPLEMENTED();
 | 
			
		||||
        UNIMPLEMENTED_MSG("Page count does not match");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Memory::MemoryPermission expected =
 | 
			
		||||
        &target_process == owner_process ? owner_permission : user_permission;
 | 
			
		||||
 | 
			
		||||
    if (permission != expected) {
 | 
			
		||||
        UNIMPLEMENTED();
 | 
			
		||||
        UNIMPLEMENTED_MSG("Permission does not match");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared,
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ public:
 | 
			
		||||
        KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
 | 
			
		||||
        Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission,
 | 
			
		||||
        Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size,
 | 
			
		||||
        std::string name = "Unknown");
 | 
			
		||||
        std::string name);
 | 
			
		||||
 | 
			
		||||
    std::string GetTypeName() const override {
 | 
			
		||||
        return "SharedMemory";
 | 
			
		||||
 | 
			
		||||
@ -1196,7 +1196,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& memory{system.Memory()};
 | 
			
		||||
    const Svc::MemoryInfo memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
 | 
			
		||||
    const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
 | 
			
		||||
 | 
			
		||||
    memory.Write64(memory_info_address + 0x00, memory_info.addr);
 | 
			
		||||
    memory.Write64(memory_info_address + 0x08, memory_info.size);
 | 
			
		||||
 | 
			
		||||
@ -298,9 +298,7 @@ public:
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (result.IsError()) {
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
            CASCADE_CODE(result);
 | 
			
		||||
 | 
			
		||||
            if (ValidateRegionForMap(page_table, addr, size)) {
 | 
			
		||||
                return MakeResult<VAddr>(addr);
 | 
			
		||||
@ -470,16 +468,15 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map memory for the NRO
 | 
			
		||||
        const ResultVal<VAddr> map_result{MapNro(system.CurrentProcess(), nro_address, nro_size,
 | 
			
		||||
                                                 bss_address, bss_size, nro_size + bss_size)};
 | 
			
		||||
        const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address,
 | 
			
		||||
                                     bss_size, nro_size + bss_size)};
 | 
			
		||||
        if (map_result.Failed()) {
 | 
			
		||||
            IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
            rb.Push(map_result.Code());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Load the NRO into the mapped memory
 | 
			
		||||
        if (const ResultCode result{
 | 
			
		||||
                LoadNro(system.CurrentProcess(), header, nro_address, *map_result)};
 | 
			
		||||
        if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)};
 | 
			
		||||
            result.IsError()) {
 | 
			
		||||
            IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
            rb.Push(map_result.Code());
 | 
			
		||||
@ -551,7 +548,7 @@ public:
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const ResultCode result{UnmapNro(iter->second)};
 | 
			
		||||
        const auto result{UnmapNro(iter->second)};
 | 
			
		||||
 | 
			
		||||
        system.InvalidateCpuInstructionCaches();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user