}
}
-os::paging::page one_past_end_page_for_page_allocator;
-os::paging::page_allocator page_allocator(os::phys_ptr<os::paging::page>(reinterpret_cast<uintptr_t>(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000));
-
-
os::idt<32> idt;
extern "C" void handler_impl_code(std::uint32_t err_code) {
os::println("Interrupt !");
remove_some_mem(
s, e, info_start, info_end,
[] (auto s, auto e) {
- page_allocator.deallocate({.ptr = s, .size = std::uint64_t(e - s)});
+ os::paging::page_allocator.deallocate({.ptr = s, .size = std::uint64_t(e - s)});
}
);
}
// Deallocate multiboot info structure: not usable anymore.
if (info_pages_wholly_usable) {
- page_allocator.deallocate({.ptr = info_start, .size = std::uint64_t(info_end - info_start)});
+ os::paging::page_allocator.deallocate({.ptr = info_start, .size = std::uint64_t(info_end - info_start)});
} else if (info_start + 1 < info_end - 1) {
// Ignore the first and last blocks: ensures all the RAM is truly usable.
- page_allocator.deallocate({.ptr = info_start + 1, .size = std::uint64_t(info_end - info_start - 2)});
+ os::paging::page_allocator.deallocate({.ptr = info_start + 1, .size = std::uint64_t(info_end - info_start - 2)});
}
os::print("RAM:\n");
- page_allocator.print_all();
+ os::paging::page_allocator.print_all();
{
os::isr_info isr_info[32];
#include "paging.hpp"
-os::paging::page_allocator::page_allocator(phys_ptr<paging::page> one_past_end): begin_(one_past_end.get_phys_addr()), end_(begin_) {
+os::paging::page one_past_end_page_for_page_allocator;
+os::paging::page_allocator_t os::paging::page_allocator(os::phys_ptr<os::paging::page>(reinterpret_cast<uintptr_t>(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000));
+
+os::paging::page_allocator_t::page_allocator_t(phys_ptr<paging::page> one_past_end): begin_(one_past_end.get_phys_addr()), end_(begin_) {
end_->prev = nullptr;
end_->next = nullptr;
end_->size = 1;
}
-void os::paging::page_allocator::print_all() const {
+void os::paging::page_allocator_t::print_all() const {
if (is_empty()) {
os::println("No RAM left.");
} else for (auto it = begin(); it != end(); it = it->next) {
}
}
-os::paging::page_allocator::block os::paging::page_allocator::allocate(std::uint64_t count) {
+os::paging::page_allocator_t::block os::paging::page_allocator_t::allocate(std::uint64_t count) {
for (auto it = begin(); it != end(); it = it->next) {
if (count == it->size) {
erase(it);
}
return { .ptr = nullptr, .size = count };
}
-void os::paging::page_allocator::deallocate(block b) {
+void os::paging::page_allocator_t::deallocate(block b) {
if (b.ptr == nullptr) { return; }
if (b.size == 0) { return; }
const phys_ptr<page> b_it{b.ptr.get_phys_addr()};
try_merge_next(try_merge_prev(insert(it, b)));
}
-bool os::paging::page_allocator::is_empty() const { return begin() == end(); }
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::begin() { return begin_; }
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::end() { return end_; }
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::begin() const { return begin_; }
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::end() const { return end_; }
+bool os::paging::page_allocator_t::is_empty() const { return begin() == end(); }
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::begin() { return begin_; }
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::end() { return end_; }
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::begin() const { return begin_; }
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::end() const { return end_; }
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::insert(phys_ptr<page> it, block b) {
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::insert(phys_ptr<page> it, block b) {
const phys_ptr<page> b_it{b.ptr.get_phys_addr()};
if (it->prev == nullptr) {
begin_ = b_it;
b_it->size = b.size;
return b_it;
}
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::try_merge_prev(phys_ptr<page> it) {
- os::assert(it != end(), "end() passed to page_allocator::try_merge_prev(phys_ptr<page>).");
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::try_merge_prev(phys_ptr<page> it) {
+ os::assert(it != end(), "end() passed to page_allocator_t::try_merge_prev(phys_ptr<page>).");
if (it->prev == nullptr) { return it; }
if (it->prev + it->prev->size != it) { return it; }
it->prev->size += it->size;
return erase(it)->prev;
}
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::try_merge_next(phys_ptr<page> it) {
- os::assert(it != end(), "end() passed to page_allocator::try_merge_next(phys_ptr<page>).");
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::try_merge_next(phys_ptr<page> it) {
+ os::assert(it != end(), "end() passed to page_allocator_t::try_merge_next(phys_ptr<page>).");
if (it->next == end()) return it;
try_merge_prev(it->next);
return it;
}
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::erase(phys_ptr<page> it) {
- os::assert(it != end(), "end() passed to page_allocator::remove(phys_ptr<page>).");
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::erase(phys_ptr<page> it) {
+ os::assert(it != end(), "end() passed to page_allocator_t::remove(phys_ptr<page>).");
if (it->prev == nullptr) {
begin_ = it->next;
} else {
it->next->prev = it->prev;
return it->next;
}
-os::phys_ptr<os::paging::page_allocator::page> os::paging::page_allocator::split_at_offset(phys_ptr<page> it, std::size_t offset) {
- os::assert(it != end(), "end() passed to page_allocator::split_at_offset(phys_ptr<page>, std::size_t).");
- os::assert(offset < it->size, "offset passed to page_allocator::split_at_offset(phys_ptr<page>, std::size_t) was too big.");
- os::assert(offset != 0, "offset 0 passed to page_allocator::split_at_offset(phys_ptr<page>, std::size_t).");
+os::phys_ptr<os::paging::page_allocator_t::page> os::paging::page_allocator_t::split_at_offset(phys_ptr<page> it, std::size_t offset) {
+ os::assert(it != end(), "end() passed to page_allocator_t::split_at_offset(phys_ptr<page>, std::size_t).");
+ os::assert(offset < it->size, "offset passed to page_allocator_t::split_at_offset(phys_ptr<page>, std::size_t) was too big.");
+ os::assert(offset != 0, "offset 0 passed to page_allocator_t::split_at_offset(phys_ptr<page>, std::size_t).");
phys_ptr<page> after_split = it + offset;
insert(it->next, block{ .ptr = phys_ptr<paging::page>{after_split.get_phys_addr()}, .size = it->size - offset });
it->size = offset;
static_assert(order >= 0, "Paging table of negative order.");
paging_entry<order> contents[512];
};
+static_assert(sizeof(paging_table<0>) == 0x1000);
+static_assert(alignof(paging_table<0>) == 0x1000);
template<>
-struct paging_table<-1> {
- std::uint8_t contents[0x1000] = {0};
+struct __attribute__((aligned(0x1000))) paging_table<-1> {
};
+static_assert(sizeof(paging_table<-1>) == 0x1000);
+static_assert(alignof(paging_table<-1>) == 0x1000);
using PML4T = paging_table<3>;
using PML4E = paging_entry<3>;
using PE = paging_entry<0>;
using page = paging_table<-1>;
-class page_allocator {
+class page_allocator_t;
+extern page_allocator_t page_allocator;
+
+class page_allocator_t {
public:
struct block {
phys_ptr<paging::page> ptr = nullptr;
std::uint64_t size;
};
- page_allocator(phys_ptr<paging::page> one_past_end_page);
+ page_allocator_t(phys_ptr<paging::page> one_past_end_page);
void print_all() const;
block allocate(std::uint64_t page_count);