From 4a3c396284a4d56e77503c2fcf848c3555443e93 Mon Sep 17 00:00:00 2001 From: Lephe Date: Thu, 18 Jun 2020 09:59:31 +0200 Subject: [PATCH] fxcg50: remove rram region and fxcg20-friendly VBR address This change removes the RRAM region which was inherited from the fx9860g memory layout but no longer relevant on fxcg50. This removed one occurrence of a hardcoded user stack address in the linker script, the other being the VBR address. But since the VBR only contains position-independent code that is manually "relocated" at startup, the linker script needs not actually use its value, so this is not a true dependency. gint should now more or less be able to boot up on an fxcg20, except for the hardcoded VRAM addresses which need to be moved to the fxcg20 system stack. --- fx9860g.ld | 2 +- fxcg50.ld | 21 ++++++++++++--------- src/core/gint.c | 4 ++-- src/core/setup.c | 24 ++++++++++++++++++++---- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/fx9860g.ld b/fx9860g.ld index 883fe4f..e0b9f37 100644 --- a/fx9860g.ld +++ b/fx9860g.ld @@ -201,7 +201,7 @@ SECTIONS There's an unused 0x100-byte gap at the start of the VBR space. The VBR space is already a large block (> 2 kiB), so I'm cutting off the gap to spare some memory */ - _gint_vbr = 0x8800df00; + _gint_vbr_fx9860g = 0x8800df00; . = ORIGIN(rram); diff --git a/fxcg50.ld b/fxcg50.ld index d7a4f1a..704261a 100644 --- a/fxcg50.ld +++ b/fxcg50.ld @@ -16,11 +16,13 @@ MEMORY rom (rx): o = 0x00300000, l = 2M /* Static RAM; stack grows down from the end of this region. The first 0x2000 bytes are reserved by gint, see below */ - ram (rw): o = 0x08102000, l = 504k - /* gint's VBR space, at the start of the user stack */ - vbr (rwx): o = 0x8c160000, l = 5k - /* gint's data resides in these few kilobytes before the user area */ - rram (rwx): o = 0x8c161400, l = 3k + ram (rw): o = 0x08101400, l = 507k + /* gint's VBR space at the start of the user stack on fx-CG 50 and on + fx-CG 20. This address needs not be determined now because VBR code + is position-independent and stored in ROM so the linker doesn't even + need to know the value */ + vbr50 (rwx): o = 0x8c160000, l = 5k + vbr20 (rwx): o = 0x88160000, l = 5k /* On-chip IL memory */ ilram (rwx): o = 0xe5200000, l = 4k /* On-chip X and Y memory */ @@ -189,9 +191,10 @@ SECTIONS There's an unused 0x100-byte gap at the start of the VBR space. The VBR space is already a large block (> 2 kiB), so I'm cutting off the gap to spare some memory */ - _gint_vbr = ORIGIN(vbr) - 0x100; + _gint_vbr_fxcg50 = ORIGIN(vbr50) - 0x100; + _gint_vbr_fxcg20 = ORIGIN(vbr20) - 0x100; - . = ORIGIN(rram); + . = ORIGIN(ram) + _sbss + _sdata; /* gint's data section, going to static RAM. This section contains many small objects from the library (static/global variables, etc) */ @@ -202,7 +205,7 @@ SECTIONS *(.gint.data .gint.data.*) . = ALIGN(16); - } > rram AT> rom + } > ram AT> rom _sgdata = SIZEOF(.gint.data); @@ -213,7 +216,7 @@ SECTIONS *(.gint.bss .gint.bss.*) . = ALIGN(16); - } > rram :NONE + } > ram :NONE _sgbss = SIZEOF(.gint.bss); diff --git a/src/core/gint.c b/src/core/gint.c index 802748c..86dc9a0 100644 --- a/src/core/gint.c +++ b/src/core/gint.c @@ -49,7 +49,7 @@ int gint_intlevel(int intid, int level) /* gint_inthandler() - configure interrupt handlers */ void *gint_inthandler(int event_code, const void *handler, size_t size) { - extern char gint_vbr; + extern uint32_t gint_vbr; /* Normalize the event code */ event_code -= 0x400; @@ -58,6 +58,6 @@ void *gint_inthandler(int event_code, const void *handler, size_t size) /* Prevent overriding the entry gate */ if(event_code < 0) return NULL; - void *dest = (void *)&gint_vbr + event_code + 0x640; + void *dest = (void *)gint_vbr + event_code + 0x640; return memcpy(dest, handler, size); } diff --git a/src/core/setup.c b/src/core/setup.c index 649f21f..e1d4f17 100644 --- a/src/core/setup.c +++ b/src/core/setup.c @@ -12,8 +12,16 @@ #include /* VBR address, from the linker script */ -extern char gint_vbr[]; -/* System's VBR address */ +#ifdef FX9860G +extern char gint_vbr_fx9860g[]; +#endif +#ifdef FXCG50 +extern char gint_vbr_fxcg50[]; +extern char gint_vbr_fxcg20[]; +#endif + +/* VBR addresses for gint and the system */ +GBSS uint32_t gint_vbr; GBSS static uint32_t system_vbr; /* Size of exception and TLB handler */ extern char gint_exch_size; @@ -98,7 +106,14 @@ GMAPPED static void lock(void) void gint_install(void) { /* VBR address, provided by the linker script */ - void *vbr = (void *)&gint_vbr; + #ifdef FX9860G + gint_vbr = (uint32_t)&gint_vbr_fx9860g; + #endif + #ifdef FXCG50 + gint_vbr = (gint[HWCALC] == HWCALC_FXCG50) + ? (uint32_t)&gint_vbr_fxcg50 + : (uint32_t)&gint_vbr_fxcg20; + #endif /* Event handler entry points */ void *inth_entry = isSH3() ? gint_inth_7705 : gint_inth_7305; @@ -113,12 +128,13 @@ void gint_install(void) gint_ctx_save(&sys_ctx); /* Load the event handler entry points into memory */ + void *vbr = (void *)gint_vbr; memcpy(vbr + 0x100, gint_exch, exch_size); memcpy(vbr + 0x400, gint_tlbh, tlbh_size); memcpy(vbr + 0x600, inth_entry, 64); /* Time to switch VBR and roll! */ - system_vbr = gint_setvbr((uint32_t)vbr, lock); + system_vbr = gint_setvbr(gint_vbr, lock); } /* unlock() - unlock interrupts, restoring system settings */