#include "common.h" #include "io.h" #include "abcio.h" #include "sys.h" #include "console.h" #include "config.h" /* Configure ABC memory map */ struct abc_mem_init { unsigned int addr; uint16_t len; uint8_t flags; enum sysvar_enum enable; const char *data; /* May not be const, but... */ }; #define RD (ABCMEMMAP_RD >> 24) #define WR (ABCMEMMAP_WR >> 24) extern const char rom_ufddos80[]; extern const char rom_ufddos800[]; extern const char rom_print80_29[]; /* Not really NV, but matches NVRAM in some expansions */ 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 } }; 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 } }; 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; } void __cold abc_init_memmap(void) { volatile uint32_t *pg = &ABCMEMMAP_PAGE(0); const struct abc_mem_init *next; next = is_abc800() ? mem_init_abc800 : mem_init_abc80; for (unsigned int addr = 0; addr < 0x10000; addr += 512) { next = get_next(next, addr); if (addr < next->addr) { *pg++ = 0; } else { *pg++ = ((size_t)(next->data + (addr - next->addr)) & SDRAM_MASK) | (next->flags << 24); } } }