Compare commits
No commits in common. "0b47e3b7fcc4a8b5c87e5454e762cf299eb1ee42" and "92d8a02291740e02e3528b57a68d0f6d1f4ae2fc" have entirely different histories.
0b47e3b7fc
...
92d8a02291
|
@ -16,23 +16,6 @@ class LinkedList {
|
||||||
bool empty() const { return size_ == 0; }
|
bool empty() const { return size_ == 0; }
|
||||||
uint64_t size() const { return size_; }
|
uint64_t size() const { return size_; }
|
||||||
|
|
||||||
void PushFront(const T& item) {
|
|
||||||
ListItem* new_item = new ListItem{
|
|
||||||
.item = item,
|
|
||||||
.next = front_,
|
|
||||||
};
|
|
||||||
front_ = new_item;
|
|
||||||
size_++;
|
|
||||||
}
|
|
||||||
void PushFront(T&& item) {
|
|
||||||
ListItem* new_item = new ListItem{
|
|
||||||
.item = glcr::Move(item),
|
|
||||||
.next = front_,
|
|
||||||
};
|
|
||||||
front_ = new_item;
|
|
||||||
size_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushBack(const T& item) {
|
void PushBack(const T& item) {
|
||||||
ListItem* new_item = new ListItem{
|
ListItem* new_item = new ListItem{
|
||||||
.item = item,
|
.item = item,
|
||||||
|
@ -59,8 +42,7 @@ class LinkedList {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& PeekFront() { return front_->item; }
|
T& PeekFront() const { return front_->item; }
|
||||||
const T& PeekFront() const { return front_->item; }
|
|
||||||
|
|
||||||
struct ListItem {
|
struct ListItem {
|
||||||
T item;
|
T item;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "interrupt/apic.h"
|
#include "interrupt/apic.h"
|
||||||
#include "interrupt/apic_timer.h"
|
#include "interrupt/apic_timer.h"
|
||||||
#include "memory/kernel_heap.h"
|
#include "memory/kernel_heap.h"
|
||||||
#include "memory/physical_memory.h"
|
|
||||||
#include "scheduler/scheduler.h"
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
#define IDT_INTERRUPT_GATE 0x8E
|
#define IDT_INTERRUPT_GATE 0x8E
|
||||||
|
@ -143,7 +142,6 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) {
|
||||||
if (cnt % 20 == 0) {
|
if (cnt % 20 == 0) {
|
||||||
if (cnt == 20) {
|
if (cnt == 20) {
|
||||||
KernelHeap::DumpDebugData();
|
KernelHeap::DumpDebugData();
|
||||||
phys_mem::DumpPhysicalMemoryUsage();
|
|
||||||
}
|
}
|
||||||
dbgln("timer: {}s", cnt * 50 / 1000);
|
dbgln("timer: {}s", cnt * 50 / 1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "memory/physical_memory.h"
|
#include "memory/physical_memory.h"
|
||||||
|
|
||||||
#include <glacier/container/linked_list.h>
|
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
#include "boot/boot_info.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
|
|
||||||
|
@ -55,89 +53,78 @@ class PhysicalMemoryManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AllocatePage() {
|
uint64_t AllocatePage() {
|
||||||
if (memory_blocks.size() == 0) {
|
if (front_ == nullptr) {
|
||||||
panic("No available memory regions.");
|
panic("No available memory regions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (memory_blocks.PeekFront().num_pages == 0) {
|
if (front_->num_pages == 0) {
|
||||||
memory_blocks.PopFront();
|
panic("Bad state, empty memory block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MemBlock& block = memory_blocks.PeekFront();
|
uint64_t page = front_->base;
|
||||||
uint64_t page = block.base;
|
front_->base += 0x1000;
|
||||||
block.base += 0x1000;
|
front_->num_pages--;
|
||||||
block.num_pages--;
|
if (front_->num_pages == 0) {
|
||||||
if (block.num_pages == 0) {
|
MemBlock* temp = front_;
|
||||||
memory_blocks.PopFront();
|
front_ = front_->next;
|
||||||
|
delete temp;
|
||||||
}
|
}
|
||||||
#if K_PHYS_DEBUG
|
#if K_PHYS_DEBUG
|
||||||
dbgln("Single {x}", page);
|
dbgln("Single {x}", page);
|
||||||
#endif
|
#endif
|
||||||
allocated_pages_ += 1;
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
uint64_t AllocateContinuous(uint64_t num_pages) {
|
uint64_t AllocateContinuous(uint64_t num_pages) {
|
||||||
if (memory_blocks.size() == 0) {
|
if (front_ == nullptr) {
|
||||||
panic("No available memory regions.");
|
panic("No available memory regions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MemBlock& block = memory_blocks.PeekFront();
|
if (front_->num_pages == 0) {
|
||||||
if (block.num_pages == 0) {
|
|
||||||
panic("Bad state, empty memory block.");
|
panic("Bad state, empty memory block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iter = memory_blocks.begin();
|
MemBlock* block = front_;
|
||||||
while (iter != memory_blocks.end() && iter->num_pages < num_pages) {
|
while (block != nullptr && block->num_pages < num_pages) {
|
||||||
dbgln("Skipping block of size {} seeking {}", iter->num_pages, num_pages);
|
dbgln("Skipping block of size {} seeking {}", block->num_pages,
|
||||||
iter = iter.next();
|
num_pages);
|
||||||
|
block = block->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter == memory_blocks.end()) {
|
if (block == nullptr) {
|
||||||
panic("No memory regions to allocate");
|
panic("No memory regions to allocate");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t page = iter->base;
|
uint64_t page = front_->base;
|
||||||
iter->base += num_pages * 0x1000;
|
front_->base += num_pages * 0x1000;
|
||||||
iter->num_pages -= num_pages;
|
front_->num_pages -= num_pages;
|
||||||
|
if (front_->num_pages == 0) {
|
||||||
|
MemBlock* temp = front_;
|
||||||
|
front_ = front_->next;
|
||||||
|
delete temp;
|
||||||
|
}
|
||||||
#if K_PHYS_DEBUG
|
#if K_PHYS_DEBUG
|
||||||
dbgln("Continuous {x}:{}", page, num_pages);
|
dbgln("Continuous {x}:{}", page, num_pages);
|
||||||
#endif
|
#endif
|
||||||
allocated_pages_ += num_pages;
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
void FreePage(uint64_t page) {
|
void FreePage(uint64_t page) { AddMemoryRegion(page, 0x1000); }
|
||||||
AddMemoryRegion(page, 0x1000);
|
|
||||||
allocated_pages_--;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t AllocatedPages() { return allocated_pages_; }
|
|
||||||
|
|
||||||
uint64_t AvailablePages() {
|
|
||||||
uint64_t available = 0;
|
|
||||||
for (auto iter = memory_blocks.begin(); iter != memory_blocks.end();
|
|
||||||
iter = iter.next()) {
|
|
||||||
available += iter->num_pages;
|
|
||||||
}
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void AddMemoryRegion(uint64_t base, uint64_t size) {
|
||||||
|
MemBlock* block = new MemBlock{
|
||||||
|
.next = front_,
|
||||||
|
.base = base,
|
||||||
|
.num_pages = size >> 12,
|
||||||
|
};
|
||||||
|
front_ = block;
|
||||||
|
}
|
||||||
struct MemBlock {
|
struct MemBlock {
|
||||||
|
MemBlock* next = nullptr;
|
||||||
uint64_t base = 0;
|
uint64_t base = 0;
|
||||||
uint64_t num_pages = 0;
|
uint64_t num_pages = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
glcr::LinkedList<MemBlock> memory_blocks;
|
MemBlock* front_ = nullptr;
|
||||||
|
|
||||||
uint64_t allocated_pages_ = 0;
|
|
||||||
|
|
||||||
void AddMemoryRegion(uint64_t base, uint64_t size) {
|
|
||||||
MemBlock block{
|
|
||||||
.base = base,
|
|
||||||
.num_pages = size >> 12,
|
|
||||||
};
|
|
||||||
memory_blocks.PushFront(block);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PhysicalMemoryManager* gPmm = nullptr;
|
static PhysicalMemoryManager* gPmm = nullptr;
|
||||||
|
@ -233,9 +220,4 @@ uint64_t AllocateContinuous(uint64_t num_continuous) {
|
||||||
return gPmm->AllocateContinuous(num_continuous);
|
return gPmm->AllocateContinuous(num_continuous);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpPhysicalMemoryUsage() {
|
|
||||||
dbgln("Pages used: {} MiB, avail: {} MiB", gPmm->AllocatedPages() / 256,
|
|
||||||
gPmm->AvailablePages() / 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace phys_mem
|
} // namespace phys_mem
|
||||||
|
|
|
@ -21,6 +21,4 @@ uint64_t AllocateAndZeroPage();
|
||||||
uint64_t AllocateContinuous(uint64_t num_pages);
|
uint64_t AllocateContinuous(uint64_t num_pages);
|
||||||
void FreePage(uint64_t page);
|
void FreePage(uint64_t page);
|
||||||
|
|
||||||
void DumpPhysicalMemoryUsage();
|
|
||||||
|
|
||||||
} // namespace phys_mem
|
} // namespace phys_mem
|
||||||
|
|
Loading…
Reference in New Issue