#include "memory/MemoryMap.h" #include #include extern const BOOTBOOT bootboot; MemoryMapEntry::MemoryMapEntry(u64 address, usize size, bool is_free) : m_address(address), m_size(size), m_is_free(is_free) { } MemoryMapEntry& MemoryMapEntry::operator=(const MemoryMapEntry& other) { if (&other == this) return *this; m_address = other.address(); m_size = other.size(); m_is_free = other.is_free(); return *this; } static MemoryMapEntry memory_map_entry_from_mmapent(const MMapEnt* ent) { return { MMapEnt_Ptr(ent), MMapEnt_Size(ent), MMapEnt_IsFree(ent) }; } MemoryMapIterator::MemoryMapIterator() : m_mmap_entries((bootboot.size - 128) / 16), m_base_ent(&bootboot.mmap) { rewind(); } void MemoryMapIterator::rewind() { m_cur_ent = 0; } Option MemoryMapIterator::at(usize index) const { if (index >= m_mmap_entries) return {}; return memory_map_entry_from_mmapent(m_base_ent + index); } Option MemoryMapIterator::next() { const auto entry = TRY(at(m_cur_ent++)); #ifdef ARCH_X86_64 // Workaround for https://gitlab.com/qemu-project/qemu/-/commit/8504f129450b909c88e199ca44facd35d38ba4de // This invalid 12GiB reserved entry is made up by QEMU (doesn't appear on any real hardware), so we can simply // ignore it and move on to the next entry. if (entry.address() == 0x000000fd00000000 && entry.size() == (0x000000ffffffffff - 0x000000fd00000000) + 1) return at(m_cur_ent++); #endif return entry; } MemoryMapEntry MemoryMapIterator::largest_free() { usize largest_size = 0; usize largest_index = 0; rewind(); MemoryMapEntry entry; while (next().try_set_value(entry)) { if (entry.is_free() && entry.size() > largest_size) { largest_size = entry.size(); largest_index = m_cur_ent - 1; } } return at(largest_index).value(); } MemoryMapEntry MemoryMapIterator::highest() { usize highest_address = 0; usize highest_index = 0; rewind(); MemoryMapEntry entry; while (next().try_set_value(entry)) { if (entry.address() > highest_address) { highest_address = entry.address(); highest_index = m_cur_ent - 1; } } return at(highest_index).value(); }