|
@@ -7,11 +7,11 @@
|
|
|
|
|
|
/* Configure ABC memory map */
|
|
|
struct abc_mem_init {
|
|
|
- unsigned int addr;
|
|
|
+ int addr;
|
|
|
uint16_t len;
|
|
|
uint8_t flags;
|
|
|
enum sysvar_enum enable;
|
|
|
- const char *data; /* May not be const, but... */
|
|
|
+ const char *data; /* May not actually be const, but... */
|
|
|
};
|
|
|
#define RD (ABCMEMMAP_RD >> 24)
|
|
|
#define WR (ABCMEMMAP_WR >> 24)
|
|
@@ -26,43 +26,64 @@ static char __dram_bss __aligned(512) abc80_nvram[2 << 10];
|
|
|
/* 16K external memory to expand to 512K */
|
|
|
static char __dram_bss __aligned(512) abc80_extmem[16 << 10];
|
|
|
|
|
|
-/* These MUST be sorted! */
|
|
|
static const struct abc_mem_init mem_init_abc80[] = {
|
|
|
{ 0x5000, 2 << 10, RD|WR, config_abc_mem_abc80_nvram, abc80_nvram },
|
|
|
{ 0x6000, 4 << 10, RD, config_abc_mem_abc80_ufddos, rom_ufddos80 },
|
|
|
{ 0x7400, 1 << 10, RD, config_abc_mem_abc80_pun80, rom_print80_29 },
|
|
|
{ 0x8000, 16 << 10, RD|WR, config_abc_mem_abc80_ram, abc80_extmem },
|
|
|
- { -1U, 0, 0, sysvar_null, NULL }
|
|
|
+ { -1, 0, 0, sysvar_null, NULL }
|
|
|
};
|
|
|
static const struct abc_mem_init mem_init_abc800[] = {
|
|
|
{ 0x6000, 4 << 10, RD, config_abc_mem_abc800_ufddos, rom_ufddos800 },
|
|
|
- { -1U, 0, 0, sysvar_null, NULL }
|
|
|
+ { -1, 0, 0, sysvar_null, NULL }
|
|
|
};
|
|
|
|
|
|
-static const struct abc_mem_init *
|
|
|
-get_next(const struct abc_mem_init *curr, unsigned int addr)
|
|
|
-{
|
|
|
- while (addr >= curr->addr + curr->len ||
|
|
|
- !(!curr->enable || getvar_bool(curr->enable)))
|
|
|
- curr++;
|
|
|
- return curr;
|
|
|
-}
|
|
|
+#define ABC_PAGE_SHIFT 9
|
|
|
+#define ABC_PAGE_SIZE (1U << ABC_PAGE_SHIFT)
|
|
|
+#define ABC_PAGE_MASK (0xffff & ~(ABC_PAGE_SIZE-1))
|
|
|
+#define ABC_PAGE_COUNT (0x10000 >> ABC_PAGE_SHIFT)
|
|
|
|
|
|
void __cold abc_init_memmap(void)
|
|
|
{
|
|
|
- volatile uint32_t *pg = &ABCMEMMAP_PAGE(0);
|
|
|
- const struct abc_mem_init *next;
|
|
|
+ uint32_t *memmap = calloc(sizeof(uint32_t), ABC_PAGE_COUNT);
|
|
|
+ const struct abc_mem_init *mem;
|
|
|
+
|
|
|
+ if (!memmap) {
|
|
|
+ con_printf("abcmem: memory map initialization failure\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- next = is_abc800() ? mem_init_abc800 : mem_init_abc80;
|
|
|
+ mem = is_abc800() ? mem_init_abc800 : mem_init_abc80;
|
|
|
|
|
|
- for (unsigned int addr = 0; addr < 0x10000; addr += 512) {
|
|
|
- next = get_next(next, addr);
|
|
|
+ while (mem->addr >= 0) {
|
|
|
+ if (!mem->len)
|
|
|
+ continue;
|
|
|
|
|
|
- if (addr < next->addr) {
|
|
|
- *pg++ = 0;
|
|
|
- } else {
|
|
|
- *pg++ = ((size_t)(next->data + (addr - next->addr))
|
|
|
- & SDRAM_MASK) | (next->flags << 24);
|
|
|
+ bool bad = ((mem->addr|mem->len) & ~ABC_PAGE_MASK) || (mem->addr+mem->len > 0x10000);
|
|
|
+ bool enabled = !bad && (!mem->enable || getvar_bool(mem->enable));
|
|
|
+
|
|
|
+ con_printf("abcmem: %s memory range @ 0x%04x len 0x%04x\n",
|
|
|
+ bad ? "invalid" : !enabled ? "ignoring" :
|
|
|
+ mem->data ? "mapping" : "unmapping",
|
|
|
+ mem->addr, mem->len);
|
|
|
+
|
|
|
+ if (enabled) {
|
|
|
+ uint32_t *pg = &memmap[mem->addr >> ABC_PAGE_SHIFT];
|
|
|
+ uint32_t flags = mem->flags << 24;
|
|
|
+ if (mem->data) {
|
|
|
+ /* Mapped range */
|
|
|
+ for (unsigned int bytes = 0; bytes < mem->len;
|
|
|
+ bytes += ABC_PAGE_SIZE) {
|
|
|
+ *pg++ = ((size_t)(mem->data + bytes) & SDRAM_MASK) | flags;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* Unmapped range */
|
|
|
+ memset(pg, 0, mem->len >> (ABC_PAGE_SHIFT-2));
|
|
|
+ }
|
|
|
}
|
|
|
+ mem++;
|
|
|
}
|
|
|
+
|
|
|
+ memcpy((void *)&ABCMEMMAP_PAGE(0), memmap, ABC_PAGE_COUNT*sizeof(uint32_t));
|
|
|
+ free(memmap);
|
|
|
}
|