| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | #include "common.h"#include "io.h"#include "abcio.h"#include "sys.h"#include "console.h"#include "config.h"#include "roms.h"/* Configure ABC memory map */struct rom {    const char *data;    size_t len;    const char *name;};struct abc_mem_init {    int addr;    uint32_t flags;    enum sysvar_enum enable;    struct rom r;};/* Convenience aliases */#define MAPS		ABCMEMMAP_MAPS#define PAGE_SHIFT	ABCMEMMAP_PAGE_SHIFT#define PAGE_SIZE	ABCMEMMAP_PAGE_SIZE#define PAGE_MASK	ABCMEMMAP_PAGE_MASK#define PAGE_COUNT	ABCMEMMAP_PAGE_COUNT#define PERMAP		(PAGE_COUNT / MAPS)#define RD		ABCMEMMAP_RD#define WR		ABCMEMMAP_WR#define XM		ABCMEMMAP_XM#define K 1024#define R(x)	{ (x), sizeof(x), #x }#define END { -1, 0, sysvar_null, { NULL, 0, NULL } }/* ---- ABC80 memory configurations ---- *//* Not really NV, but matches NVRAM in some expansions */static char __dram_bss __aligned(PAGE_SIZE) abc80_nvram[2][2*K];/* ABC800MAC RAM */static char __dram_bss __aligned(PAGE_SIZE) abc800mac_ram[64*K];/* 16K external memory to expand to 512K */static char __dram_bss __aligned(PAGE_SIZE) abc80_extmem[16*K];static const struct abc_mem_init mem_init_abc80[] = {    /* Put these here in case someone wants to enable both */    { 20*K, RD|WR, config_abc_mem_abc80_nvram_20k,  R(abc80_nvram[0]) },    { 22*K, RD|WR, config_abc_mem_abc80_nvram_22k,  R(abc80_nvram[1]) },    { 16*K, RD,    config_abc_mem_abc80_smartaid3,  R(rom_abc80_smartaid3) },    { 16*K, RD,    config_abc_mem_abc80_superbasic, R(rom_abc80_superbasic16k) },    { 20*K, RD,    config_abc_mem_abc80_abc80l,     R(rom_abc80_abc80l) },    { 28*K, RD,    config_abc_mem_abc80_superbasic, R(rom_abc80_superbasic28k) },    { 32*K, RD|WR, config_abc_mem_abc80_ram,        R(abc80_extmem) },    END};static const struct abc_mem_init mem_init_abc80_nvram_20k[] = {    { 24*K, RD,    config_abc_mem_abc80_ufddos,	    R(rom_abc80_nvram_20k_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  R(rom_abc80_nvram_20k_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  R(rom_abc80_nvram_20k_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  R(rom_abc80_nvram_20k_print80_30) },    END};static const struct abc_mem_init mem_init_abc80_nvram_22k[] = {    { 24*K, RD,    config_abc_mem_abc80_ufddos,	    R(rom_abc80_nvram_22k_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  R(rom_abc80_nvram_22k_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  R(rom_abc80_nvram_22k_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  R(rom_abc80_nvram_22k_print80_30) },    END};static const struct abc_mem_init mem_init_abc80_no_nvram[] = {    { 24*K, RD,    config_abc_mem_abc80_ufddos,	    R(rom_abc80_no_nvram_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  R(rom_abc80_no_nvram_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  R(rom_abc80_no_nvram_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  R(rom_abc80_no_nvram_print80_30) },    END};/* ---- ABC800 memory configurations ---- */static const struct abc_mem_init mem_init_abc800[] = {    { 24*K, RD,    config_abc_mem_abc800_ufddos,    R(rom_abc800_ufddos) },    END};static const struct abc_mem_init mem_init_abc800mac[] = {    { 0,    RD|WR, 0,                               R(abc800mac_ram) },    END};static void abc_map_list(uint32_t *memmap, const struct abc_mem_init *mem){    while (mem->addr >= 0) {	bool enabled = !mem->enable || getvar_bool(mem->enable);	const void *data = mem->r.data;	size_t len = mem->r.len;	if (!len)	    continue;		/* Empty range, skip */	uint32_t addr = mem->addr;	bool bad = ((addr | len) & ~PAGE_MASK) ||	    (len > 0x10000 - addr) ||	    ((size_t)data & (PAGE_SIZE-1));	con_printf("abcmem: %s %s @ 0x%04x len 0x%04x\n",		   mem->r.name ? mem->r.name : "(none)",		   bad ? "invalid" :		   !enabled ? "disabled" :		   data ? "mapping" : "unmapping",		   addr, len);	if (enabled) {	    uint32_t *pg = &memmap[addr >> PAGE_SHIFT];	    uint32_t flags = mem->flags;	    if (data) {		/* Mapped range */		size_t pgv = (size_t)data | flags;		for (uint32_t bytes = 0; bytes < len; bytes += PAGE_SIZE)		    *pg++ = pgv + bytes;	    } else {		/* Unmapped range - set to 0 for clarity */		memset(pg, 0, len >> (PAGE_SHIFT-2));	    }	}	mem++;    }}static void abc_init_memmap800(uint32_t memmap[MAPS][PERMAP]){    abc_map_list(memmap[0], mem_init_abc800);    abc_map_list(memmap[1], mem_init_abc800mac);    /* XXX: enable abc800mac if desired */    ABC_MAP_CFG = 0;}static void abc_init_memmap80(uint32_t memmap[MAPS][PERMAP]){    /* Put 22K first so UFD-DOS/PUN80 memory always is put at the end */    if (getvar_bool(config_abc_mem_abc80_nvram_22k))	abc_map_list(memmap[0], mem_init_abc80_nvram_22k);    else if (getvar_bool(config_abc_mem_abc80_nvram_20k))	abc_map_list(memmap[0], mem_init_abc80_nvram_20k);    else	abc_map_list(memmap[0], mem_init_abc80_no_nvram);    abc_map_list(memmap[0], mem_init_abc80);    /* XXX: Until such time as SAM is supported... */    ABC_MAP_CFG = 0;}void __cold abc_init_memmap(void){    static uint32_t memmap[MAPS][PERMAP]; /* Too big to fit on stack */    memset(memmap, 0, sizeof memmap);    /*     * Currently the only map that gets populated is map 0; the     * remaining map(s) get cleared by the memset() above.     */    if (is_abc800())	abc_init_memmap800(memmap);    else	abc_init_memmap80(memmap);    /* Install memory map into hardware registers */    memcpy((void *)&ABCMEMMAP_PAGE(0), memmap, sizeof memmap);}
 |