54 lines
1.5 KiB
C
54 lines
1.5 KiB
C
#pragma once
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
|
|
// 0x1F000000 - 0x1FFFFFFF
|
|
// 0xFF000000 - 0xFFFFFFFF
|
|
|
|
struct memory_access {
|
|
uint8_t (* read_memory8 )(void * mem, uint32_t address);
|
|
uint16_t (* read_memory16 )(void * mem, uint32_t address);
|
|
uint32_t (* read_memory32 )(void * mem, uint32_t address);
|
|
void (* write_memory8 )(void * mem, uint32_t address, uint8_t value);
|
|
void (* write_memory16)(void * mem, uint32_t address, uint16_t value);
|
|
void (* write_memory32)(void * mem, uint32_t address, uint32_t value);
|
|
};
|
|
|
|
struct memory_map_entry {
|
|
uint32_t start;
|
|
uint32_t size;
|
|
void * mem;
|
|
struct memory_access access;
|
|
};
|
|
|
|
#define memory_map_max_length 16
|
|
|
|
struct memory_map {
|
|
uint32_t length;
|
|
struct memory_map_entry entry[memory_map_max_length];
|
|
};
|
|
|
|
static inline uint32_t physical_address(uint32_t address)
|
|
{
|
|
if (address < 0xe0000000)
|
|
return address & (~(0b111 << 29)); // P0 P1 P2 P3 region
|
|
else
|
|
return address; // P4 region
|
|
}
|
|
|
|
static inline struct memory_map_entry * find_entry(struct memory_map * map, uint32_t address)
|
|
{
|
|
uint32_t physical = physical_address(address);
|
|
assert(map->length <= memory_map_max_length);
|
|
for (int i = 0; i < map->length; i++) {
|
|
uint32_t entry_start = map->entry[i].start;
|
|
uint32_t entry_end = map->entry[i].start + map->entry[i].size;
|
|
if (physical >= entry_start && physical < entry_end)
|
|
return &map->entry[i];
|
|
}
|
|
return (struct memory_map_entry *)0;
|
|
}
|
|
|
|
#undef memory_map_max_length
|