acadia/zion/object/memory_object.cpp
Drew Galbraith 53ff49b265 Add preprocessor directives to supress logs per file.
Makes the output much cleaner by default but allows for getting more
infor if debugging in the future.
2023-06-07 13:51:13 -07:00

69 lines
1.7 KiB
C++

#include "object/memory_object.h"
#include "boot/boot_info.h"
#include "debug/debug.h"
#include "memory/physical_memory.h"
#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);
}
}
uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) {
if (offset > size_) {
panic("Invalid offset");
}
uint64_t page_num = offset / 0x1000;
return PageNumberToPhysAddr(page_num);
}
void MemoryObject::CopyBytesToObject(uint64_t source, uint64_t length) {
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;
while (length > 0) {
uint64_t physical = hhdm + PageNumberToPhysAddr(page_number);
uint64_t bytes_to_copy = length >= 0x1000 ? 0x1000 : length;
uint8_t* srcptr = reinterpret_cast<uint8_t*>(source);
uint8_t* destptr = reinterpret_cast<uint8_t*>(physical);
for (uint64_t i = 0; i < bytes_to_copy; i++) {
destptr[i] = srcptr[i];
}
length -= bytes_to_copy;
source += 0x1000;
page_number++;
}
}
uint64_t MemoryObject::PageNumberToPhysAddr(uint64_t page_num) {
auto iter = phys_page_list_.begin();
uint64_t index = 0;
while (index < page_num) {
++iter;
index++;
}
if (*iter == 0) {
#if K_MEM_DEBUG
dbgln("Allocating page num %u for mem object", page_num);
#endif
*iter = phys_mem::AllocatePage();
}
return *iter;
}