diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2024-09-27 06:02:49 -0400 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2024-09-27 06:02:49 -0400 |
commit | d43d7caf15a01dd9c2ef1d9e975df3ef7c4e9204 (patch) | |
tree | aaf1f0f3a18b6f7b3fc25022e06941a9fb4fa612 /memory.cpp |
wip: initial commit
Diffstat (limited to 'memory.cpp')
-rw-r--r-- | memory.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/memory.cpp b/memory.cpp new file mode 100644 index 0000000..2cc15be --- /dev/null +++ b/memory.cpp @@ -0,0 +1,87 @@ +#include "textoutput.hpp" + +#include <array> +#include <cstdint> + +struct PageDirectory +{ + static constexpr std::uint32_t NotPresent = 0x2; + + PageDirectory(): value(NotPresent) {} + PageDirectory(void *addr): value(reinterpret_cast<std::uint32_t>(addr) | 3) {} + + std::uint32_t value; +}; +static_assert(sizeof(PageDirectory) == sizeof(std::uint32_t)); + +extern std::uint32_t lowerMem; +extern std::uint32_t upperMem; +extern TextOutput& term; + +static std::uintptr_t lowerFree = 0x400; +static std::uintptr_t upperFree = 0x100000; + +alignas(4096) +static std::array<PageDirectory, 1024> pageDirectory; + +alignas(4096) +static std::array<std::uint32_t, 1024> pageTable; + +void memory_initialize() +{ + lowerMem -= 1024; + + const auto totalKb = (lowerMem + upperMem) / 1024u; + + term.write("Claiming "); + term.write(totalKb); + term.write(" kB for allocations...\n"); + + std::uint32_t addr = 0; + for (auto& p : pageTable) { + p = addr | 3; // supervisor, r/w, present + addr += 0x1000; + } + + pageDirectory[0] = PageDirectory(pageTable.data()); + + asm volatile(R"( + mov %%eax, %%cr3 + mov %%cr0, %%eax + or $0x80000000, %%eax + mov %%eax, %%cr0 + )" :: "a"(pageDirectory.data())); + + term.write("Paging enabled.\n"); +} + +static void *memory_alloc(std::size_t size) +{ + void *ret = nullptr; + + if (lowerMem > size) { + ret = reinterpret_cast<void *>(lowerFree); + lowerFree += size; + lowerMem -= size; + } else if (upperMem > size) { + ret = reinterpret_cast<void *>(upperFree); + upperFree += size; + upperMem -= size; + } else { + // Uh oh! + term.write("!!! Kernel allocation failed !!!"); + } + + return ret; +} + +void *operator new(std::size_t size) +{ + return memory_alloc(size); +} + +void *operator new[](std::size_t size) +{ + return memory_alloc(size); +} + |