Explorar el Código

abcmem: don't try to be smart about memmmap generation

Replace the attemting-to-be-smart memory map generation with a
"dumb" algorithm which simply computes the memory map in plain
memory and then copies it into the device registers.

This should make it more reliable and also allows one configuration
variable to override previous entries from another configuration
variable.
H. Peter Anvin hace 1 año
padre
commit
6a9308c435

BIN
esp32/output/max80.ino.bin


+ 3 - 3
fpga/max80.qpf

@@ -19,15 +19,15 @@
 #
 # Quartus Prime
 # Version 22.1std.0 Build 915 10/25/2022 SC Lite Edition
-# Date created = 22:13:31  September 05, 2023
+# Date created = 14:37:29  September 17, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "22:13:31  September 05, 2023"
+DATE = "14:37:29  September 17, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"
 PROJECT_REVISION = "bypass"

BIN
fpga/output/bypass.jic


BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 44 - 23
rv32/abcmem.c

@@ -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);
 }

+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0xb1adae41
+#define SDRAM_SUM 0x36da7735
 #endif