2022-12-04 14:45:13 +00:00
|
|
|
#include "memory/MemoryMap.h"
|
2022-12-07 10:40:02 +00:00
|
|
|
#include <luna/Result.h>
|
|
|
|
#include <luna/SystemError.h>
|
2022-12-04 14:45:13 +00:00
|
|
|
|
2022-12-05 12:04:01 +00:00
|
|
|
extern const BOOTBOOT bootboot;
|
2022-12-04 14:45:13 +00:00
|
|
|
|
2022-12-07 09:55:47 +00:00
|
|
|
MemoryMapEntry::MemoryMapEntry(u64 address, usize size, bool is_free)
|
2022-12-05 12:23:01 +00:00
|
|
|
: 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;
|
|
|
|
}
|
|
|
|
|
2022-12-05 12:04:01 +00:00
|
|
|
static MemoryMapEntry memory_map_entry_from_mmapent(const MMapEnt* ent)
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
2022-12-21 19:22:44 +00:00
|
|
|
return { MMapEnt_Ptr(ent), MMapEnt_Size(ent), MMapEnt_IsFree(ent) };
|
2022-12-04 14:45:13 +00:00
|
|
|
}
|
|
|
|
|
2022-12-05 12:23:01 +00:00
|
|
|
MemoryMapIterator::MemoryMapIterator() : m_mmap_entries((bootboot.size - 128) / 16), m_base_ent(&bootboot.mmap)
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
|
|
|
rewind();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemoryMapIterator::rewind()
|
|
|
|
{
|
|
|
|
m_cur_ent = 0;
|
|
|
|
}
|
|
|
|
|
2022-12-16 18:47:20 +00:00
|
|
|
Option<MemoryMapEntry> MemoryMapIterator::at(usize index) const
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
2022-12-16 18:47:20 +00:00
|
|
|
if (index >= m_mmap_entries) return {};
|
2022-12-04 14:45:13 +00:00
|
|
|
return memory_map_entry_from_mmapent(m_base_ent + index);
|
|
|
|
}
|
|
|
|
|
2022-12-16 18:47:20 +00:00
|
|
|
Option<MemoryMapEntry> MemoryMapIterator::next()
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
2023-01-07 19:58:12 +00:00
|
|
|
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;
|
2022-12-04 14:45:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MemoryMapEntry MemoryMapIterator::largest_free()
|
|
|
|
{
|
|
|
|
usize largest_size = 0;
|
|
|
|
usize largest_index = 0;
|
|
|
|
|
|
|
|
rewind();
|
|
|
|
|
|
|
|
MemoryMapEntry entry;
|
|
|
|
while (next().try_set_value(entry))
|
|
|
|
{
|
2022-12-05 12:23:01 +00:00
|
|
|
if (entry.is_free() && entry.size() > largest_size)
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
2022-12-05 12:23:01 +00:00
|
|
|
largest_size = entry.size();
|
2022-12-04 14:45:13 +00:00
|
|
|
largest_index = m_cur_ent - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-16 18:44:33 +00:00
|
|
|
return at(largest_index).value();
|
2022-12-04 14:45:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MemoryMapEntry MemoryMapIterator::highest()
|
|
|
|
{
|
2022-12-05 12:23:01 +00:00
|
|
|
usize highest_address = 0;
|
2022-12-04 14:45:13 +00:00
|
|
|
usize highest_index = 0;
|
|
|
|
|
|
|
|
rewind();
|
|
|
|
|
|
|
|
MemoryMapEntry entry;
|
|
|
|
while (next().try_set_value(entry))
|
|
|
|
{
|
2022-12-05 12:23:01 +00:00
|
|
|
if (entry.address() > highest_address)
|
2022-12-04 14:45:13 +00:00
|
|
|
{
|
2022-12-05 12:23:01 +00:00
|
|
|
highest_address = entry.address();
|
2022-12-04 14:45:13 +00:00
|
|
|
highest_index = m_cur_ent - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-16 18:44:33 +00:00
|
|
|
return at(highest_index).value();
|
2023-01-02 12:07:29 +00:00
|
|
|
}
|