#include "objects/vm_area.h" #include "vm_mapper.h" #include "vm_space.h" vm_mapper_single::vm_mapper_single(vm_area &area, vm_space &space) : m_area(area), m_space(space) {} vm_mapper_single::~vm_mapper_single() { m_space.clear(m_area, 0, memory::page_count(m_area.size()), true); } bool vm_mapper_single::can_resize(size_t size) const { return m_space.can_resize(m_area, size); } void vm_mapper_single::map(uintptr_t offset, size_t count, uintptr_t phys) { m_space.page_in(m_area, offset, phys, count); } void vm_mapper_single::unmap(uintptr_t offset, size_t count) { m_space.clear(m_area, offset, count, true); } void vm_mapper_single::remove(vm_space *space) { size_t count = memory::page_count(m_area.size()); bool keep = m_area.flags() && vm_flags::mmio; m_space.clear(m_area, 0, count, !keep); } vm_mapper_multi::vm_mapper_multi(vm_area &area) : m_area(area) { } vm_mapper_multi::~vm_mapper_multi() { if (!m_spaces.count()) return; size_t count = memory::page_count(m_area.size()); for (int i = 1; i < m_spaces.count(); ++i) m_spaces[i]->clear(m_area, 0, count); m_spaces[0]->clear(m_area, 0, count, true); } bool vm_mapper_multi::can_resize(size_t size) const { for (auto &it : m_spaces) if (!it->can_resize(m_area, size)) return false; return true; } void vm_mapper_multi::map(uintptr_t offset, size_t count, uintptr_t phys) { for (auto &it : m_spaces) it->page_in(m_area, offset, phys, count); } void vm_mapper_multi::unmap(uintptr_t offset, size_t count) { for (auto &it : m_spaces) it->clear(m_area, offset, count); } void vm_mapper_multi::add(vm_space *space) { if (m_spaces.count()) { vm_space *source = m_spaces[0]; space->copy_from(*source, m_area); } m_spaces.append(space); } void vm_mapper_multi::remove(vm_space *space) { size_t count = memory::page_count(m_area.size()); bool keep = m_area.flags() && vm_flags::mmio; for (int i = 0; i < m_spaces.count(); ++i) { if (m_spaces[i] == space) { m_spaces.remove_swap_at(i); keep &= m_spaces.count() > 0; space->clear(m_area, 0, count, !keep); } } }