[Zion] Make the base MemoryObject pure abstract.

This commit is contained in:
Drew Galbraith 2023-11-19 23:17:12 -08:00
parent 126482f3e8
commit a8ad225cf1
4 changed files with 72 additions and 64 deletions

View file

@ -6,30 +6,8 @@
#define K_MEM_DEBUG 0
MemoryObject::MemoryObject(uint64_t size) : size_(size) {
if ((size & 0xFFF) != 0) {
size_ = (size & ~0xFFF) + 0x1000;
#if K_MEM_DEBUG
dbgln("MemoryObject: aligned {x} to {x}", size, size_);
#endif
}
// FIXME: Do this lazily.
uint64_t num_pages = size_ / 0x1000;
for (uint64_t i = 0; i < num_pages; i++) {
phys_page_list_.PushBack(0);
}
}
MemoryObject::~MemoryObject() {
for (uint64_t page : phys_page_list_) {
if (page != 0) {
phys_mem::FreePage(page);
}
}
}
uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) {
if (offset > size_) {
if (offset > size()) {
panic("Invalid offset");
}
uint64_t page_num = offset / 0x1000;
@ -37,8 +15,8 @@ uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) {
}
void MemoryObject::CopyBytesToObject(uint64_t source, uint64_t length) {
if (length > size_) {
panic("Copy overruns memory object: {x} too large for {x}", length, size_);
if (length > size()) {
panic("Copy overruns memory object: {x} too large for {x}", length, size());
}
uint64_t hhdm = boot::GetHigherHalfDirectMap();
uint64_t page_number = 0;
@ -59,21 +37,38 @@ void MemoryObject::CopyBytesToObject(uint64_t source, uint64_t length) {
}
}
uint64_t MemoryObject::PageNumberToPhysAddr(uint64_t page_num) {
auto iter = phys_page_list_.begin();
uint64_t index = 0;
while (index < page_num) {
++iter;
index++;
VariableMemoryObject::VariableMemoryObject(uint64_t size) : size_(size) {
if ((size & 0xFFF) != 0) {
size_ = (size & ~0xFFF) + 0x1000;
#if K_MEM_DEBUG
dbgln("MemoryObject: aligned {x} to {x}", size, size_);
#endif
}
// FIXME: Do this lazily.
uint64_t num_pages = size_ / 0x1000;
phys_page_list_ = glcr::Array<uint64_t>(num_pages);
for (uint64_t i = 0; i < phys_page_list_.size(); i++) {
phys_page_list_[i] = 0;
}
}
if (*iter == 0) {
VariableMemoryObject::~VariableMemoryObject() {
for (uint64_t p = 0; p < phys_page_list_.size(); p++) {
if (phys_page_list_[p] != 0) {
// TODO: We may be able to do some sort of coalescing here.
phys_mem::FreePage(phys_page_list_[p]);
}
}
}
uint64_t VariableMemoryObject::PageNumberToPhysAddr(uint64_t page_num) {
if (phys_page_list_[page_num] == 0) {
#if K_MEM_DEBUG
dbgln("Allocating page num {} for mem object", page_num);
#endif
*iter = phys_mem::AllocatePage();
phys_page_list_[page_num] = phys_mem::AllocatePage();
}
return *iter;
return phys_page_list_[page_num];
}
FixedMemoryObject::~FixedMemoryObject() {

View file

@ -1,10 +1,11 @@
#pragma once
#include <glacier/container/linked_list.h>
#include <glacier/container/array.h>
#include <glacier/memory/ref_ptr.h>
#include <glacier/status/error_or.h>
#include "include/ztypes.h"
#include "memory/constants.h"
#include "object/kernel_object.h"
class MemoryObject;
@ -27,32 +28,41 @@ class MemoryObject : public KernelObject {
kZionPerm_Transmit;
}
explicit MemoryObject(uint64_t size);
~MemoryObject();
MemoryObject() = default;
virtual ~MemoryObject() = default;
uint64_t size() { return size_; }
uint64_t num_pages() { return ((size_ - 1) / 0x1000) + 1; }
virtual uint64_t size() = 0;
uint64_t num_pages() { return ((size() - 1) / kPageSize) + 1; }
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(
uint64_t offset, uint64_t length) = 0;
uint64_t PhysicalPageAtOffset(uint64_t offset);
void CopyBytesToObject(uint64_t source, uint64_t length);
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(uint64_t offset,
uint64_t length) {
protected:
virtual uint64_t PageNumberToPhysAddr(uint64_t page_num) = 0;
};
class VariableMemoryObject : public MemoryObject {
public:
explicit VariableMemoryObject(uint64_t size);
~VariableMemoryObject() override;
uint64_t size() override { return size_; }
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(
uint64_t offset, uint64_t length) override {
return glcr::UNIMPLEMENTED;
}
protected:
// Hacky to avoid linked_list creation.
MemoryObject(uint64_t size, bool) : size_(size) {}
virtual uint64_t PageNumberToPhysAddr(uint64_t page_num) override;
private:
// Always stores the full page-aligned size.
uint64_t size_;
virtual uint64_t PageNumberToPhysAddr(uint64_t page_num);
glcr::LinkedList<uint64_t> phys_page_list_;
glcr::Array<uint64_t> phys_page_list_;
};
class FixedMemoryObject : public MemoryObject {
@ -60,20 +70,21 @@ class FixedMemoryObject : public MemoryObject {
// FIXME: Validate that this is 4k aligned.
// Create a new class object for should free.
FixedMemoryObject(uint64_t physical_addr, uint64_t size, bool should_free)
: MemoryObject(size, true),
physical_addr_(physical_addr),
should_free_(should_free) {}
: size_(size), physical_addr_(physical_addr), should_free_(should_free) {}
~FixedMemoryObject();
~FixedMemoryObject() override;
virtual uint64_t size() override { return size_; }
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(
uint64_t offset, uint64_t length) override;
protected:
uint64_t PageNumberToPhysAddr(uint64_t page_num) override {
return physical_addr_ + (kPageSize * page_num);
}
private:
uint64_t size_;
uint64_t physical_addr_;
bool should_free_;
uint64_t PageNumberToPhysAddr(uint64_t page_num) override {
return physical_addr_ + (0x1000 * page_num);
}
};