2019-12-14 22:33:57 +01:00
|
|
|
#include <fxos/memory.h>
|
2020-06-13 09:59:01 +02:00
|
|
|
#include <stdexcept>
|
2019-12-14 22:33:57 +01:00
|
|
|
#include <array>
|
|
|
|
|
|
|
|
namespace FxOS {
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Overview of the memory areas
|
|
|
|
//---
|
|
|
|
|
|
|
|
uint32_t MemoryArea::start() const noexcept
|
|
|
|
{
|
|
|
|
switch(m_name)
|
|
|
|
{
|
|
|
|
case U0: return 0x00000000;
|
|
|
|
case P0: return 0x00000000;
|
|
|
|
case P1: return 0x80000000;
|
|
|
|
case P2: return 0xa0000000;
|
|
|
|
case P3: return 0xc0000000;
|
|
|
|
case P4: return 0xe0000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t MemoryArea::end() const noexcept
|
|
|
|
{
|
|
|
|
switch(m_name)
|
|
|
|
{
|
|
|
|
case U0: return 0x7fffffff;
|
|
|
|
case P0: return 0x7fffffff;
|
|
|
|
case P1: return 0x9fffffff;
|
|
|
|
case P2: return 0xbfffffff;
|
|
|
|
case P3: return 0xdfffffff;
|
|
|
|
case P4: return 0xffffffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t MemoryArea::size() const noexcept
|
|
|
|
{
|
|
|
|
return this->end() - this->start() + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Fine memory region management
|
|
|
|
//---
|
|
|
|
|
2019-12-28 17:18:13 +01:00
|
|
|
MemoryRegion::MemoryRegion():
|
|
|
|
name {"null"}, start {0x00000000}, end {0x00000000}, writable {false}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-12-14 22:33:57 +01:00
|
|
|
MemoryRegion::MemoryRegion(std::string name, uint32_t start, uint32_t end,
|
|
|
|
bool writable):
|
2019-12-28 17:18:13 +01:00
|
|
|
name {name}, start {start}, end {end}, writable {writable}
|
2019-12-14 22:33:57 +01:00
|
|
|
{
|
|
|
|
this->guess_flags();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t MemoryRegion::size() const noexcept
|
|
|
|
{
|
|
|
|
return end - start;
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryArea MemoryRegion::area() const noexcept
|
|
|
|
{
|
|
|
|
using Area = MemoryArea;
|
2021-03-16 13:19:41 +01:00
|
|
|
static Area areas[5]={ Area::P4, Area::P3, Area::P2, Area::P1, Area::P0 };
|
2019-12-14 22:33:57 +01:00
|
|
|
|
|
|
|
for(int i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
if(start >= areas[i].start()) return areas[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return Area::P0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemoryRegion::guess_flags() noexcept
|
|
|
|
{
|
|
|
|
switch(this->area())
|
|
|
|
{
|
|
|
|
case MemoryArea::U0:
|
|
|
|
case MemoryArea::P0:
|
|
|
|
case MemoryArea::P3:
|
|
|
|
cacheable = true;
|
|
|
|
mappable = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MemoryArea::P1:
|
|
|
|
cacheable = true;
|
|
|
|
mappable = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MemoryArea::P2:
|
|
|
|
case MemoryArea::P4:
|
|
|
|
cacheable = false;
|
|
|
|
mappable = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 13:19:41 +01:00
|
|
|
using R = MemoryRegion;
|
2019-12-14 22:33:57 +01:00
|
|
|
|
|
|
|
/* Basic memory regions */
|
2021-03-16 13:19:41 +01:00
|
|
|
R const R::ROM = MemoryRegion("ROM", 0x80000000, 0x81ffffff, false);
|
|
|
|
R const R::RAM = MemoryRegion("RAM", 0x88000000, 0x88040000, true);
|
|
|
|
R const R::ROM_P2 = MemoryRegion("ROM_P2", 0xa0000000, 0xa07fffff, false);
|
|
|
|
R const R::RAM_P2 = MemoryRegion("RAM_P2", 0xa8000000, 0xa8040000, true);
|
|
|
|
R const R::RS = MemoryRegion("RS", 0xfd800000, 0xfd8007ff, true);
|
|
|
|
R const R::ILRAM = MemoryRegion("ILRAM", 0xe5200000, 0xe5203fff, true);
|
|
|
|
R const R::XRAM = MemoryRegion("XRAM", 0xe5007000, 0xe5008fff, true);
|
|
|
|
R const R::YRAM = MemoryRegion("YRAM", 0xe5017000, 0xe5018fff, true);
|
|
|
|
|
|
|
|
std::array<MemoryRegion const *, 8> const MemoryRegion::m_all = {
|
|
|
|
&R::ROM, &R::RAM, &R::ROM_P2, &R::RAM_P2,
|
|
|
|
&R::RS, &R::ILRAM, &R::XRAM, &R::YRAM,
|
|
|
|
};
|
|
|
|
|
|
|
|
std::array<MemoryRegion const *, 8> const MemoryRegion::all()
|
|
|
|
{
|
|
|
|
return m_all;
|
|
|
|
}
|
2019-12-14 22:33:57 +01:00
|
|
|
|
|
|
|
MemoryRegion const *MemoryRegion::region_for(uint32_t address)
|
|
|
|
{
|
2021-03-16 13:19:41 +01:00
|
|
|
for(auto r: MemoryRegion::all()) {
|
|
|
|
if(r->start <= address && address < r->end) return r;
|
2019-12-14 22:33:57 +01:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-12-28 17:18:13 +01:00
|
|
|
MemoryRegion::MemoryRegion(std::string name)
|
|
|
|
{
|
2021-03-16 13:19:41 +01:00
|
|
|
for(auto r: MemoryRegion::all()) {
|
|
|
|
if(r->name == name) {
|
|
|
|
*this = *r;
|
2019-12-28 17:18:13 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw std::runtime_error("No standard region named '" + name + "'");
|
|
|
|
}
|
|
|
|
|
2019-12-14 22:33:57 +01:00
|
|
|
} /* namespace FxOS */
|