abcmem.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "common.h"
  2. #include "io.h"
  3. #include "abcio.h"
  4. #include "sys.h"
  5. #include "console.h"
  6. #include "config.h"
  7. /* Configure ABC memory map */
  8. struct abc_mem_init {
  9. int addr;
  10. uint16_t len;
  11. uint8_t flags;
  12. enum sysvar_enum enable;
  13. const char *data; /* May not actually be const, but... */
  14. };
  15. #define RD (ABCMEMMAP_RD >> 24)
  16. #define WR (ABCMEMMAP_WR >> 24)
  17. extern const char rom_ufddos80[];
  18. extern const char rom_ufddos800[];
  19. extern const char rom_print80_29[];
  20. /* Not really NV, but matches NVRAM in some expansions */
  21. static char __dram_bss __aligned(512) abc80_nvram[2 << 10];
  22. /* 16K external memory to expand to 512K */
  23. static char __dram_bss __aligned(512) abc80_extmem[16 << 10];
  24. static const struct abc_mem_init mem_init_abc80[] = {
  25. { 0x5000, 2 << 10, RD|WR, config_abc_mem_abc80_nvram, abc80_nvram },
  26. { 0x6000, 4 << 10, RD, config_abc_mem_abc80_ufddos, rom_ufddos80 },
  27. { 0x7400, 1 << 10, RD, config_abc_mem_abc80_pun80, rom_print80_29 },
  28. { 0x8000, 16 << 10, RD|WR, config_abc_mem_abc80_ram, abc80_extmem },
  29. { -1, 0, 0, sysvar_null, NULL }
  30. };
  31. static const struct abc_mem_init mem_init_abc800[] = {
  32. { 0x6000, 4 << 10, RD, config_abc_mem_abc800_ufddos, rom_ufddos800 },
  33. { -1, 0, 0, sysvar_null, NULL }
  34. };
  35. #define ABC_PAGE_SHIFT 9
  36. #define ABC_PAGE_SIZE (1U << ABC_PAGE_SHIFT)
  37. #define ABC_PAGE_MASK (0xffff & ~(ABC_PAGE_SIZE-1))
  38. #define ABC_PAGE_COUNT (0x10000 >> ABC_PAGE_SHIFT)
  39. void __cold abc_init_memmap(void)
  40. {
  41. uint32_t *memmap = calloc(sizeof(uint32_t), ABC_PAGE_COUNT);
  42. const struct abc_mem_init *mem;
  43. if (!memmap) {
  44. con_printf("abcmem: memory map initialization failure\n");
  45. return;
  46. }
  47. mem = is_abc800() ? mem_init_abc800 : mem_init_abc80;
  48. while (mem->addr >= 0) {
  49. if (!mem->len)
  50. continue;
  51. bool bad = ((mem->addr|mem->len) & ~ABC_PAGE_MASK) || (mem->addr+mem->len > 0x10000);
  52. bool enabled = !bad && (!mem->enable || getvar_bool(mem->enable));
  53. con_printf("abcmem: %s memory range @ 0x%04x len 0x%04x\n",
  54. bad ? "invalid" : !enabled ? "ignoring" :
  55. mem->data ? "mapping" : "unmapping",
  56. mem->addr, mem->len);
  57. if (enabled) {
  58. uint32_t *pg = &memmap[mem->addr >> ABC_PAGE_SHIFT];
  59. uint32_t flags = mem->flags << 24;
  60. if (mem->data) {
  61. /* Mapped range */
  62. for (unsigned int bytes = 0; bytes < mem->len;
  63. bytes += ABC_PAGE_SIZE) {
  64. *pg++ = ((size_t)(mem->data + bytes) & SDRAM_MASK) | flags;
  65. }
  66. } else {
  67. /* Unmapped range */
  68. memset(pg, 0, mem->len >> (ABC_PAGE_SHIFT-2));
  69. }
  70. }
  71. mem++;
  72. }
  73. memcpy((void *)&ABCMEMMAP_PAGE(0), memmap, ABC_PAGE_COUNT*sizeof(uint32_t));
  74. free(memmap);
  75. }