3#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
4#include "pedigree/kernel/utilities/assert.h"
5#include "pedigree/kernel/utilities/new"
6#include "pedigree/kernel/utilities/utility.h"
10 size_t references = 0;
11 uint32_t generation = 0;
12 } slots[MaximumPages];
14 alignas(16)
unsigned char buffer[PagingChannel::PageBytes];
23bool SwapStore::prepareAtBoot() {
24#if (X64 || HOSTED) && THREADS
27 return m_State !=
nullptr;
32SwapStatus SwapStore::activate(uint32_t endpoint) {
33#if !(X64 || HOSTED) || !THREADS
34 return SwapStatus::Unsupported;
37 return SwapStatus::NoMemory;
39 return SwapStatus::Busy;
40 switch (DiskEndpoints::prepare(endpoint, m_State->channel)) {
41 case PagingStatus::Success:
43 case PagingStatus::Busy:
44 return SwapStatus::Busy;
45 case PagingStatus::NoMemory:
46 return SwapStatus::NoMemory;
47 case PagingStatus::Unsupported:
48 return SwapStatus::Unsupported;
49 case PagingStatus::Invalid:
50 case PagingStatus::Closed:
51 return SwapStatus::Invalid;
53 return SwapStatus::IoError;
55 SwapStatus result = SwapStatus::IoError;
56 if (m_State->channel.readPage(0, m_State->buffer) == PagingStatus::Success)
57 result = validateHeader(m_State->buffer, m_State->channel.size(), m_State->pages);
58 if (result != SwapStatus::Success) {
60 m_State->channel.reset();
64SwapStatus SwapStore::finishDeactivate(uint32_t endpoint) {
65 if (!m_State || !m_State->channel || endpoint != m_State->channel.endpointId())
66 return SwapStatus::NotActive;
68 return SwapStatus::Busy;
69 if (m_State->channel.flush() != PagingStatus::Success)
70 return SwapStatus::IoError;
71 m_State->channel.reset();
73 return SwapStatus::Success;
75SwapStatus SwapStore::writePage(physical_uintptr_t physical,
SwapReference& result) {
77 return SwapStatus::Invalid;
78 if (!m_State || !m_State->channel || !m_State->pages)
79 return SwapStatus::NotActive;
81 for (; index < m_State->pages; ++index)
82 if (!m_State->slots[index].references && m_State->slots[index].generation != ~uint32_t(0))
84 if (index == m_State->pages)
85 return SwapStatus::NoMemory;
87 m_State->channel.writePage((index + 1) * PagingChannel::PageBytes, m_State->buffer) !=
88 PagingStatus::Success ||
89 m_State->channel.flush() != PagingStatus::Success)
90 return SwapStatus::IoError;
91 auto& slot = m_State->slots[index];
95 result.value = (uint64_t(slot.generation) << 32) | (index + 1);
96 return SwapStatus::Success;
98SwapStatus SwapStore::readPage(
SwapReference reference, physical_uintptr_t physical) {
99 const size_t index = uint32_t(reference.value) - size_t(1);
100 if (!m_State || index >= m_State->pages || !m_State->slots[index].references ||
101 m_State->slots[index].generation != uint32_t(reference.value >> 32))
102 return SwapStatus::Invalid;
103 if (m_State->channel.readPage((index + 1) * PagingChannel::PageBytes, m_State->buffer) !=
104 PagingStatus::Success ||
106 return SwapStatus::IoError;
107 return SwapStatus::Success;
110 const size_t index = uint32_t(reference.value) - size_t(1);
111 if (!m_State || index >= m_State->pages || !m_State->slots[index].references ||
112 m_State->slots[index].references == ~
size_t(0) ||
113 m_State->slots[index].generation != uint32_t(reference.value >> 32))
115 ++m_State->slots[index].references;
121 const size_t index = uint32_t(reference.value) - size_t(1);
122 assert(m_State && index < m_State->pages && m_State->slots[index].references &&
123 m_State->slots[index].generation == uint32_t(reference.value >> 32));
124 if (!--m_State->slots[index].references)
129 if (!m_State || !m_State->channel)
131 return {m_State->pages, m_State->used,
true};
133uint32_t SwapStore::endpointId()
const {
134 return m_State ? m_State->channel.endpointId() : 0;
137bool SwapStore::zeroPage(physical_uintptr_t physical) {
140 ByteSet(m_State->buffer, 0, PagingChannel::PageBytes);
static PhysicalMemoryManager & instance()