| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | #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 data_len {    const char *data;    size_t len;};struct abc_mem_init {    int addr;    uint32_t flags;    enum sysvar_enum enable;    struct data_len dl;};#define RD ABCMEMMAP_RD#define WR ABCMEMMAP_WR#define K 1024#define DD(x)	{ (x), sizeof(x) }#define END { -1, 0, sysvar_null, { NULL, 0 } }/* ---- ABC80 memory configurations ---- *//* Not really NV, but matches NVRAM in some expansions */static char __dram_bss __aligned(512) abc80_nvram[2][2*K];/* 16K external memory to expand to 512K */static char __dram_bss __aligned(512) 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,  DD(abc80_nvram[0]) },    { 22*K, RD|WR, config_abc_mem_abc80_nvram_22k,  DD(abc80_nvram[1]) },    { 16*K, RD,    config_abc_mem_abc80_smartaid3,  DD(rom_abc80_smartaid3) },    { 16*K, RD,    config_abc_mem_abc80_superbasic, DD(rom_abc80_superbasic16k) },    { 20*K, RD,    config_abc_mem_abc80_abc80l,     DD(rom_abc80_abc80l) },    { 28*K, RD,    config_abc_mem_abc80_superbasic, DD(rom_abc80_superbasic28k) },    { 32*K, RD|WR, config_abc_mem_abc80_ram,        DD(abc80_extmem) },    END};static const struct abc_mem_init mem_init_abc80_nvram_20k[] = {    { 24*K, RD,    config_abc_mem_abc80_ufddos,	    DD(rom_abc80_nvram_20k_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  DD(rom_abc80_nvram_20k_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  DD(rom_abc80_nvram_20k_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  DD(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,	    DD(rom_abc80_nvram_22k_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  DD(rom_abc80_nvram_22k_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  DD(rom_abc80_nvram_22k_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  DD(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,	    DD(rom_abc80_no_nvram_ufddos80) },    { 28*K, RD,    config_abc_mem_abc80_pun80_28k,  DD(rom_abc80_no_nvram_print80_28) },    { 29*K, RD,    config_abc_mem_abc80_pun80_29k,  DD(rom_abc80_no_nvram_print80_29) },    { 30*K, RD,    config_abc_mem_abc80_pun80_30k,  DD(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,    DD(rom_abc800_ufddos) },    END};#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)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->dl.data;	size_t len = mem->dl.len;	if (!len)	    continue;		/* Empty range, skip */	uint32_t addr = mem->addr;	bool bad = ((addr | len) & ~ABC_PAGE_MASK) ||	    len > 0x10000 - addr ||	    (size_t)data & (ABC_PAGE_SIZE-1);	con_printf("abcmem: %s memory range @ 0x%04x len 0x%04x\n",		   bad ? "invalid" : !enabled ? "ignoring" :		   data ? "mapping" : "unmapping",		   addr, len);	if (enabled) {	    uint32_t *pg = &memmap[addr >> ABC_PAGE_SHIFT];	    uint32_t flags = mem->flags;	    if (!data) {		/* Mapped range */		for (uint32_t bytes = 0; bytes < len; bytes += ABC_PAGE_SIZE)		    *pg++ = ((size_t)(data + bytes) & SDRAM_MASK) | flags;	    } else {		/* Unmapped range - set to 0 for clarity */		memset(pg, 0, len >> (ABC_PAGE_SHIFT-2));	    }	}	mem++;    }}void __cold abc_init_memmap(void){    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;    }    if (is_abc800()) {	abc_map_list(memmap, mem_init_abc800);    } else {	/* 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, mem_init_abc80_nvram_22k);	else if (getvar_bool(config_abc_mem_abc80_nvram_20k))	    abc_map_list(memmap, mem_init_abc80_nvram_20k);	else	    abc_map_list(memmap, mem_init_abc80_no_nvram);	abc_map_list(memmap, mem_init_abc80);    }    /* Install memory map into hardware registers */    memcpy((void *)&ABCMEMMAP_PAGE(0), memmap,	   ABC_PAGE_COUNT*sizeof(uint32_t));    free(memmap);}
 |