u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size) { assert(size); for (u32 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { bool is_good_addr = true; // check if address is already mapped for (u32 i = 0; i<m_mapped_memory.size(); ++i) { if ((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) { is_good_addr = false; addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; break; } } if (!is_good_addr) continue; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } return 0; }
bool VirtualMemoryBlock::Reserve(u32 size) { if(size + GetReservedAmount() > GetEndAddr() - GetStartAddr()) return false; m_reserve_size += size; return true; }
u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) { if(addr) { if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1))) return 0; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } else { for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { bool is_good_addr = true; // check if address is already mapped for(u32 i=0; i<m_mapped_memory.size(); ++i) { if((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || (m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size)) { is_good_addr = false; addr = m_mapped_memory[i].addr + m_mapped_memory[i].size; break; } } if(!is_good_addr) continue; m_mapped_memory.emplace_back(addr, realaddr, size); return addr; } return 0; } }
bool MemoryBlock::IsMyAddress(const u64 addr) { return mem && addr >= GetStartAddr() && addr < GetEndAddr(); }
bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size) { return addr >= GetStartAddr() && addr + size - 1 <= GetEndAddr() - GetReservedAmount(); }