mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
606 lines
16 KiB
C++
606 lines
16 KiB
C++
/*
|
|
This file is part of Fennix Kernel.
|
|
|
|
Fennix Kernel is free software: you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
Fennix Kernel is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef __FENNIX_KERNEL_MEMORY_TABLE_H__
|
|
#define __FENNIX_KERNEL_MEMORY_TABLE_H__
|
|
|
|
#include <types.h>
|
|
|
|
namespace Memory
|
|
{
|
|
/**
|
|
* @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png
|
|
* @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png
|
|
*/
|
|
enum PTFlag
|
|
{
|
|
/** @brief Present */
|
|
P = 1 << 0,
|
|
|
|
/** @brief Read/Write */
|
|
RW = 1 << 1,
|
|
|
|
/** @brief User/Supervisor */
|
|
US = 1 << 2,
|
|
|
|
/** @brief Write-Through */
|
|
PWT = 1 << 3,
|
|
|
|
/** @brief Cache Disable */
|
|
PCD = 1 << 4,
|
|
|
|
/** @brief Accessed */
|
|
A = 1 << 5,
|
|
|
|
/** @brief Dirty */
|
|
D = 1 << 6,
|
|
|
|
/** @brief Page Size */
|
|
PS = 1 << 7,
|
|
|
|
/** @brief Global */
|
|
G = 1 << 8,
|
|
|
|
/** @brief Available 0 */
|
|
CoW = 1 << 9,
|
|
|
|
/** @brief Available 1 */
|
|
KRsv = 1 << 10,
|
|
|
|
/** @brief Available 2 */
|
|
AVL2 = 1 << 11,
|
|
|
|
/** @brief Page Attribute Table */
|
|
PAT = 1 << 12,
|
|
|
|
/** @brief Available 3 */
|
|
AVL3 = (uint64_t)1 << 52,
|
|
|
|
/** @brief Available 4 */
|
|
AVL4 = (uint64_t)1 << 53,
|
|
|
|
/** @brief Available 5 */
|
|
AVL5 = (uint64_t)1 << 54,
|
|
|
|
/** @brief Available 6 */
|
|
AVL6 = (uint64_t)1 << 55,
|
|
|
|
/** @brief Available 7 */
|
|
AVL7 = (uint64_t)1 << 56,
|
|
|
|
/** @brief Available 8 */
|
|
AVL8 = (uint64_t)1 << 57,
|
|
|
|
/** @brief Available 9 */
|
|
AVL9 = (uint64_t)1 << 58,
|
|
|
|
/** @brief Protection Key 0 */
|
|
PK0 = (uint64_t)1 << 59,
|
|
|
|
/** @brief Protection Key 1 */
|
|
PK1 = (uint64_t)1 << 60,
|
|
|
|
/** @brief Protection Key 2 */
|
|
PK2 = (uint64_t)1 << 61,
|
|
|
|
/** @brief Protection Key 3 */
|
|
PK3 = (uint64_t)1 << 62,
|
|
|
|
/** @brief Execute Disable */
|
|
XD = (uint64_t)1 << 63
|
|
};
|
|
|
|
union __packed PageTableEntry
|
|
{
|
|
struct
|
|
{
|
|
#if defined(__amd64__)
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Dirty : 1; // 6
|
|
uintptr_t PageAttributeTable : 1; // 7
|
|
uintptr_t Global : 1; // 8
|
|
uintptr_t CopyOnWrite : 1; // 9
|
|
uintptr_t KernelReserve : 1; // 10
|
|
uintptr_t Available2 : 1; // 11
|
|
uintptr_t Address : 40; // 12-51
|
|
uintptr_t Available3 : 1; // 52
|
|
uintptr_t Available4 : 1; // 53
|
|
uintptr_t Available5 : 1; // 54
|
|
uintptr_t Available6 : 1; // 55
|
|
uintptr_t Available7 : 1; // 56
|
|
uintptr_t Available8 : 1; // 57
|
|
uintptr_t Available9 : 1; // 58
|
|
uintptr_t ProtectionKey : 4; // 59-62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
#elif defined(__i386__)
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Dirty : 1; // 6
|
|
uintptr_t PageAttributeTable : 1; // 7
|
|
uintptr_t Global : 1; // 8
|
|
uintptr_t CopyOnWrite : 1; // 9
|
|
uintptr_t KernelReserve : 1; // 10
|
|
uintptr_t Available2 : 1; // 11
|
|
uintptr_t Address : 20; // 12-31
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
};
|
|
uintptr_t raw = 0;
|
|
|
|
/** @brief Set Address */
|
|
void SetAddress(uintptr_t _Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__i386__)
|
|
_Address &= 0x000FFFFF;
|
|
this->raw &= 0xFFC00003;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__aarch64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#endif
|
|
}
|
|
|
|
/** @brief Get Address */
|
|
uintptr_t GetAddress()
|
|
{
|
|
#if defined(__amd64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#elif defined(__i386__)
|
|
return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12);
|
|
#elif defined(__aarch64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
struct __packed PageTableEntryPtr
|
|
{
|
|
#if defined(__amd64__)
|
|
PageTableEntry Entries[512];
|
|
#elif defined(__i386__)
|
|
PageTableEntry Entries[1024];
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
};
|
|
|
|
union __packed PageDirectoryEntry
|
|
{
|
|
#if defined(__amd64__)
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t CopyOnWrite : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t KernelReserve : 1; // 8
|
|
uintptr_t Available2 : 1; // 9
|
|
uintptr_t Available3 : 1; // 10
|
|
uintptr_t Available4 : 1; // 11
|
|
uintptr_t Address : 40; // 12-51
|
|
uintptr_t Available5 : 1; // 52
|
|
uintptr_t Available6 : 1; // 53
|
|
uintptr_t Available7 : 1; // 54
|
|
uintptr_t Available8 : 1; // 55
|
|
uintptr_t Available9 : 1; // 56
|
|
uintptr_t Available10 : 1; // 57
|
|
uintptr_t Available11 : 1; // 58
|
|
uintptr_t Available12 : 1; // 59
|
|
uintptr_t Available13 : 1; // 60
|
|
uintptr_t Available14 : 1; // 61
|
|
uintptr_t Available15 : 1; // 62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
};
|
|
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Dirty : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t Global : 1; // 8
|
|
uintptr_t CopyOnWrite : 1; // 9
|
|
uintptr_t KernelReserve : 1; // 10
|
|
uintptr_t Available2 : 1; // 11
|
|
uintptr_t PageAttributeTable : 1; // 12
|
|
uintptr_t Reserved0 : 8; // 13-20
|
|
uintptr_t Address : 31; // 21-51
|
|
uintptr_t Available3 : 1; // 52
|
|
uintptr_t Available4 : 1; // 53
|
|
uintptr_t Available5 : 1; // 54
|
|
uintptr_t Available6 : 1; // 55
|
|
uintptr_t Available7 : 1; // 56
|
|
uintptr_t Available8 : 1; // 57
|
|
uintptr_t Available9 : 1; // 58
|
|
uintptr_t ProtectionKey : 4; // 59-62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
} TwoMiB;
|
|
#elif defined(__i386__)
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t CopyOnWrite : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t KernelReserve : 1; // 8
|
|
uintptr_t Available2 : 1; // 9
|
|
uintptr_t Available3 : 1; // 10
|
|
uintptr_t Available4 : 1; // 11
|
|
uintptr_t Address : 20; // 12-31
|
|
};
|
|
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Dirty : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t Global : 1; // 8
|
|
uintptr_t CopyOnWrite : 1; // 9
|
|
uintptr_t KernelReserve : 1; // 10
|
|
uintptr_t Available2 : 1; // 11
|
|
uintptr_t PageAttributeTable : 1; // 12
|
|
uintptr_t Address0 : 8; // 13-20
|
|
uintptr_t Reserved0 : 1; // 21
|
|
uintptr_t Address1 : 10; // 22-31
|
|
} FourMiB;
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
uintptr_t raw = 0;
|
|
|
|
/** @brief Set PageTableEntryPtr address */
|
|
void SetAddress(uintptr_t _Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__i386__)
|
|
_Address &= 0x000FFFFF;
|
|
this->raw &= 0xFFC00003;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__aarch64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#endif
|
|
}
|
|
|
|
/** @brief Get PageTableEntryPtr address */
|
|
uintptr_t GetAddress()
|
|
{
|
|
#if defined(__amd64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#elif defined(__i386__)
|
|
return ((uintptr_t)(this->raw & 0x003FFFFF000) >> 12);
|
|
#elif defined(__aarch64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
struct __packed PageDirectoryEntryPtr
|
|
{
|
|
PageDirectoryEntry Entries[512];
|
|
};
|
|
|
|
union __packed PageDirectoryPointerTableEntry
|
|
{
|
|
#if defined(__amd64__)
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t CopyOnWrite : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t KernelReserve : 1; // 8
|
|
uintptr_t Available2 : 1; // 9
|
|
uintptr_t Available3 : 1; // 10
|
|
uintptr_t Available4 : 1; // 11
|
|
uintptr_t Address : 40; // 12-51
|
|
uintptr_t Available5 : 1; // 52
|
|
uintptr_t Available6 : 1; // 53
|
|
uintptr_t Available7 : 1; // 54
|
|
uintptr_t Available8 : 1; // 55
|
|
uintptr_t Available9 : 1; // 56
|
|
uintptr_t Available10 : 1; // 57
|
|
uintptr_t Available11 : 1; // 58
|
|
uintptr_t Available12 : 1; // 59
|
|
uintptr_t Available13 : 1; // 60
|
|
uintptr_t Available14 : 1; // 61
|
|
uintptr_t Available15 : 1; // 62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
};
|
|
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Dirty : 1; // 6
|
|
uintptr_t PageSize : 1; // 7
|
|
uintptr_t Global : 1; // 8
|
|
uintptr_t CopyOnWrite : 1; // 9
|
|
uintptr_t KernelReserve : 1; // 10
|
|
uintptr_t Available2 : 1; // 11
|
|
uintptr_t PageAttributeTable : 1; // 12
|
|
uintptr_t Reserved0 : 17; // 13-29
|
|
uintptr_t Address : 22; // 30-51
|
|
uintptr_t Available3 : 1; // 52
|
|
uintptr_t Available4 : 1; // 53
|
|
uintptr_t Available5 : 1; // 54
|
|
uintptr_t Available6 : 1; // 55
|
|
uintptr_t Available7 : 1; // 56
|
|
uintptr_t Available8 : 1; // 57
|
|
uintptr_t Available9 : 1; // 58
|
|
uintptr_t ProtectionKey : 4; // 59-62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
} OneGiB;
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
uintptr_t raw = 0;
|
|
|
|
/** @brief Set PageDirectoryEntryPtr address */
|
|
void SetAddress(uintptr_t _Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__aarch64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#endif
|
|
}
|
|
|
|
/** @brief Get PageDirectoryEntryPtr address */
|
|
uintptr_t GetAddress()
|
|
{
|
|
#if defined(__amd64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#elif defined(__i386__)
|
|
return 0;
|
|
#elif defined(__aarch64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
struct __packed PageDirectoryPointerTableEntryPtr
|
|
{
|
|
PageDirectoryPointerTableEntry Entries[512];
|
|
};
|
|
|
|
union __packed PageMapLevel4
|
|
{
|
|
#if defined(__amd64__)
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t CopyOnWrite : 1; // 6
|
|
uintptr_t Reserved0 : 1; // 7
|
|
uintptr_t KernelReserve : 1; // 8
|
|
uintptr_t Available2 : 1; // 9
|
|
uintptr_t Available3 : 1; // 10
|
|
uintptr_t Available4 : 1; // 11
|
|
uintptr_t Address : 40; // 12-51
|
|
uintptr_t Available5 : 1; // 52
|
|
uintptr_t Available6 : 1; // 53
|
|
uintptr_t Available7 : 1; // 54
|
|
uintptr_t Available8 : 1; // 55
|
|
uintptr_t Available9 : 1; // 56
|
|
uintptr_t Available10 : 1; // 57
|
|
uintptr_t Available11 : 1; // 58
|
|
uintptr_t Available12 : 1; // 59
|
|
uintptr_t Available13 : 1; // 60
|
|
uintptr_t Available14 : 1; // 61
|
|
uintptr_t Available15 : 1; // 62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
};
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
uintptr_t raw = 0;
|
|
|
|
/** @brief Set PageDirectoryPointerTableEntryPtr address */
|
|
void SetAddress(uintptr_t _Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__aarch64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#endif
|
|
}
|
|
|
|
/** @brief Get PageDirectoryPointerTableEntryPtr address */
|
|
uintptr_t GetAddress()
|
|
{
|
|
#if defined(__amd64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#elif defined(__i386__)
|
|
return 0;
|
|
#elif defined(__aarch64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
struct __packed PageMapLevel4Ptr
|
|
{
|
|
PageMapLevel4 Entries[512];
|
|
};
|
|
|
|
union __packed PageMapLevel5
|
|
{
|
|
#if defined(__amd64__)
|
|
struct
|
|
{
|
|
uintptr_t Present : 1; // 0
|
|
uintptr_t ReadWrite : 1; // 1
|
|
uintptr_t UserSupervisor : 1; // 2
|
|
uintptr_t WriteThrough : 1; // 3
|
|
uintptr_t CacheDisable : 1; // 4
|
|
uintptr_t Accessed : 1; // 5
|
|
uintptr_t Available0 : 1; // 6
|
|
uintptr_t Reserved0 : 1; // 7
|
|
uintptr_t KernelReserve : 1; // 8
|
|
uintptr_t Available1 : 1; // 9
|
|
uintptr_t Available2 : 1; // 10
|
|
uintptr_t Available3 : 1; // 11
|
|
uintptr_t Address : 40; // 12-51
|
|
uintptr_t Available4 : 1; // 52
|
|
uintptr_t Available5 : 1; // 53
|
|
uintptr_t Available6 : 1; // 54
|
|
uintptr_t Available7 : 1; // 55
|
|
uintptr_t Available8 : 1; // 56
|
|
uintptr_t Available9 : 1; // 57
|
|
uintptr_t Available10 : 1; // 58
|
|
uintptr_t Available11 : 1; // 59
|
|
uintptr_t Available12 : 1; // 60
|
|
uintptr_t Available13 : 1; // 61
|
|
uintptr_t Available14 : 1; // 62
|
|
uintptr_t ExecuteDisable : 1; // 63
|
|
};
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
uintptr_t raw = 0;
|
|
|
|
/** @brief Set PageMapLevel4Ptr address */
|
|
void SetAddress(uintptr_t _Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#elif defined(__aarch64__)
|
|
_Address &= 0x000000FFFFFFFFFF;
|
|
this->raw &= 0xFFF0000000000FFF;
|
|
this->raw |= (_Address << 12);
|
|
#endif
|
|
}
|
|
|
|
/** @brief Get PageMapLevel4Ptr address */
|
|
uintptr_t GetAddress()
|
|
{
|
|
#if defined(__amd64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#elif defined(__i386__)
|
|
return 0;
|
|
#elif defined(__aarch64__)
|
|
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
class PageTable
|
|
{
|
|
public:
|
|
#if defined(__amd64__)
|
|
PageMapLevel4 Entries[512];
|
|
#elif defined(__i386__)
|
|
PageDirectoryEntry Entries[1024];
|
|
#elif defined(__aarch64__)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Update CR3 with this PageTable
|
|
*/
|
|
void Update();
|
|
|
|
/**
|
|
* @brief Fork this PageTable
|
|
*
|
|
* @return A new PageTable with the same content
|
|
*/
|
|
PageTable *Fork();
|
|
|
|
void *__getPhysical(void *Address);
|
|
|
|
/**
|
|
* @brief Get the Physical Address of a virtual address
|
|
*
|
|
* This function will return the physical address
|
|
* of a virtual address and not the virtual address
|
|
* of the current page table. This is intentional because
|
|
* the kernel page table has 1:1 mapping for the free
|
|
* memory.
|
|
*
|
|
* @tparam T
|
|
* @param Address The virtual address
|
|
* @return The physical address
|
|
*/
|
|
template <typename T>
|
|
T Get(T Address)
|
|
{
|
|
void *PhysAddr = __getPhysical((void *)Address);
|
|
if (PhysAddr == nullptr)
|
|
return {};
|
|
uintptr_t Diff = uintptr_t(Address);
|
|
Diff &= 0xFFF;
|
|
Diff = uintptr_t(PhysAddr) + Diff;
|
|
return (T)Diff;
|
|
}
|
|
} __aligned(0x1000);
|
|
}
|
|
|
|
#endif // !__FENNIX_KERNEL_MEMORY_TABLE_H__
|