fxos/include/fxos/memory.h

114 lines
3.8 KiB
C++

//---------------------------------------------------------------------------//
// 1100101 |_ mov #0, r4 __ //
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
// |_ base# + offset |_| /_\_\___/__/ //
//---------------------------------------------------------------------------//
// fxos/memory: Standard memory areas and regions
//
// This file provides some basic information about memory layout.
//
// The MemoryArea structure is a finite type with exactly 6 instances
// describing the virtual memory areas outlined by the MMU for both the SH7705
// and the SH7305.
//
// The MemoryRegion structure is use to represent address ranges. The standard
// regions of the SH7305 are defined, including some different placements for
// RAM (which depend on the BSC configuration), but this does not restrict the
// ability of MemoryRegion to describe eg. SH7705 on-chip memory.
//
// MemoryRegion is frequently used in commands to request start/end address
// pairs even when no detailed information is needed.
//---
#ifndef FXOS_MEMORY_H
#define FXOS_MEMORY_H
#include <string>
#include <array>
#include <cstdint>
namespace FxOS {
struct MemoryArea
{
/* Userspace seen from user and privileged mode */
static MemoryArea U0, P0;
/* Second half of memory, only for privileged mode */
static MemoryArea P1, P2, P3, P4;
/* Start and end of area (both included) */
uint32_t start, end;
/* Size of area */
uint32_t size() const
{
return this->end - this->start + 1;
}
/* Name ("U0", "P0", "P1", "P2", "P3", or "P4") */
char const *name;
constexpr bool operator==(MemoryArea const &other) const
{
return this->start == other.start && this->end == other.end;
}
};
struct MemoryRegion
{
/* Address space regions that correspond to standard (ie. contiguous
multi-addressable) memory */
static MemoryRegion const ROM, ROM_P2;
static MemoryRegion const RAM, RAM_P2, RAM_8C, RAM_8C_P2;
static MemoryRegion const RS;
static MemoryRegion const ILRAM;
static MemoryRegion const XRAM;
static MemoryRegion const YRAM;
/* All standard regions */
static std::array<MemoryRegion const *, 10> const &all();
/* Determine if an address falls into one of the standard regions */
static MemoryRegion const *region_for(uint32_t address);
/* Determine if a region falls entirely into one of the standard regions */
static MemoryRegion const *region_for(MemoryRegion r);
/* Empty region at 0 */
MemoryRegion();
/* Short constructor which calls guess_flags() */
MemoryRegion(std::string name, uint32_t start, uint32_t end, bool writable);
/* Short constructor for standard regions only */
MemoryRegion(std::string standard_region_name);
/* Region name */
std::string name;
/* Start address and end address. Generally the end address has one
additional byte. This is okay since no region is supposed to extend
to the very end of the memory. */
uint32_t start, end;
/* The region is writable under normal conditions */
bool writable;
/* The cache is active in that region (if enabled) */
bool cacheable;
/* The MMU is active in that region (if enabled) */
bool mappable;
/* Returns the size of the region */
uint32_t size() const noexcept;
/* Returns the area associated with the region (assuming it is fully
contained in one, which should always be the case) */
MemoryArea area() const noexcept;
private:
static std::array<MemoryRegion const *, 10> const m_all;
/* Automatically guess the cacheable and mappable flags */
void guess_flags() noexcept;
};
} /* namespace FxOS */
#endif /* FXOS_MEMORY_H */