1#ifndef KERNEL_X64_VIRTUALADDRESSSPACE_INTERNAL_H
2#define KERNEL_X64_VIRTUALADDRESSSPACE_INTERNAL_H
3#include "pedigree/kernel/Spinlock.h"
4#include "pedigree/kernel/panic.h"
5#include "pedigree/kernel/processor/Processor.h"
12#define PAGE_PRESENT 0x01
13#define PAGE_WRITE 0x02
15#define PAGE_WRITE_COMBINE 0x08
16#define PAGE_CACHE_DISABLE 0x10
17#define PAGE_ACCESSED 0x20
18#define PAGE_DIRTY 0x40
21#define PAGE_GLOBAL 0x100
22#define PAGE_SWAPPED 0x200
23#define PAGE_COPY_ON_WRITE 0x400
24#define PAGE_SHARED 0x800
26#define PAGE_RUNTIME (1ULL << 55)
27#define PAGE_BORROWED (1ULL << 56)
28#define PAGE_NO_ACCESS (1ULL << 57)
29#define PAGE_WRITE_PROTECTED (1ULL << 58)
30#define PAGE_NX 0x8000000000000000
31#define PAGE_WRITE_THROUGH (PAGE_PAT | PAGE_WRITE_COMBINE)
36#define PML4_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 39) & 0x1FF)
37#define PAGE_DIRECTORY_POINTER_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 30) & 0x1FF)
38#define PAGE_DIRECTORY_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 21) & 0x1FF)
39#define PAGE_TABLE_INDEX(x) ((reinterpret_cast<uintptr_t>(x) >> 12) & 0x1FF)
41#define TABLE_ENTRY(table, index) (&physicalAddress(reinterpret_cast<uint64_t*>(table))[index])
43#define PAGE_GET_FLAGS(x) (*x & 0x8780000000000FFFULL)
44#define PAGE_SET_FLAGS(x, f) *x = (*x & ~0x8780000000000FFFULL) | f
45#define PAGE_GET_PHYSICAL_ADDRESS(x) (*x & ~0x8780000000000FFFULL)
49 case TlbInvalidationResult::Success:
51 case TlbInvalidationResult::InvalidContext:
52 panic(
"Mapping mutation started from an invalid TLB-shootdown context");
53 case TlbInvalidationResult::UnsupportedTopology:
54 panic(
"Mapping mutation has no safe all-processor TLB route");
55 case TlbInvalidationResult::SerialisationTimedOut:
62 panic(
"Mapping mutation admission timed out");
63 case TlbInvalidationResult::SubmissionFailed:
64 case TlbInvalidationResult::AcknowledgementTimedOut:
65 case TlbInvalidationResult::DrainTimedOut:
66 panic(
"Mapping mutation admission returned an invalid phase result");
68 panic(
"Mapping mutation admission returned an unknown result");
73 case TlbInvalidationResult::InvalidContext:
74 return "Mapping changed from an invalid TLB-shootdown context";
75 case TlbInvalidationResult::UnsupportedTopology:
76 return "Mapping has no safe all-processor TLB route";
77 case TlbInvalidationResult::SerialisationTimedOut:
78 return "Cross-processor TLB shootdown serialisation timed out";
79 case TlbInvalidationResult::SubmissionFailed:
80 return "Cross-processor TLB shootdown IPI submission failed";
81 case TlbInvalidationResult::AcknowledgementTimedOut:
82 return "Cross-processor TLB shootdown acknowledgement timed out";
83 case TlbInvalidationResult::DrainTimedOut:
84 return "Cross-processor TLB shootdown service drain timed out";
85 case TlbInvalidationResult::Success:
88 return "Cross-processor TLB shootdown returned an unknown result";
103 m_Result(TlbInvalidationResult::Success),
104 m_Coordinator(
false),
106 beginMappingInvalidation(m_Invalidation);
115 m_Locks[m_LockCount].lock = &lock;
116 m_Locks[m_LockCount].owned =
true;
121 for (
size_t i = m_LockCount; i > 0; --i) {
123 if (state.lock == &lock && state.owned) {
129 panicWithoutRestoringInterrupts(
"Mapping mutation released an unowned VAS lock");
133 for (
size_t i = 0; i < m_LockCount; ++i) {
135 if (state.lock == &lock && !state.owned) {
141 panicWithoutRestoringInterrupts(
"Mapping mutation reacquired an unknown VAS lock");
144 bool invalidate(
void* virtualAddress) {
146 if (m_Result == TlbInvalidationResult::Success) {
154 bool failed()
const {
155 return m_Result != TlbInvalidationResult::Success;
158 void panicInvalidationFailure()
NORETURN {
160 const bool coordinator = m_Coordinator;
168 panic(mappingInvalidationFailureMessage(result));
182 void finish(
bool restoreInterrupts) {
188 for (
size_t i = m_LockCount; i > 0; --i) {
189 LockState& state = m_Locks[i - 1];
198 if (restoreInterrupts && m_RestoreInterrupts) {
204 bool m_RestoreInterrupts;
205 LockState m_Locks[2];
static bool getInterrupts()
static MUST_USE_RESULT TlbInvalidationResult invalidateAll(void *pAddress)
static bool tlbInvalidationFailureActive()
static void setInterrupts(bool bEnable)
static MUST_USE_RESULT TlbInvalidationResult beginTlbInvalidation(TlbInvalidationGuard &guard)
bool acquire(bool recurse=false, bool safe=true)
void exit(uintptr_t ra=0)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
MUST_USE_RESULT bool closeAdmissionForTerminalFailure(TlbInvalidationResult result)