kernel: move VBR at the end of the user RAM area on fx-9860G

This leaves more space available for the heap.
This commit is contained in:
Lephe 2021-02-15 09:39:14 +01:00
parent 2c9ff901d1
commit 3885f10ee1
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
7 changed files with 43 additions and 12 deletions

View file

@ -21,7 +21,7 @@ Currently, this includes:
* A stripped-down version of the [Grisu2b floating-point representation * A stripped-down version of the [Grisu2b floating-point representation
algorithm](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf) algorithm](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf)
with α=-59 and γ=-56, by Florian Loitsch. See `src/3rdparty/grisu2b_59_56/README` with α=-59 and γ=-56, by Florian Loitsch. See `src/3rdparty/grisu2b_59_56/README`
for details [the original code here](https://drive.google.com/open?id=0BwvYOx00EwKmejFIMjRORTFLcTA). for details, and [the original code here](https://drive.google.com/open?id=0BwvYOx00EwKmejFIMjRORTFLcTA).
## Programming interface ## Programming interface

4
TODO
View file

@ -1,9 +1,8 @@
Extensions on existing code: Extensions on existing code:
* kernel: better restore to userspace before panic (ensure BL=0 IMASK=0)
* kernel: check if cpu_setVBR() really needs to be perma-mapped * kernel: check if cpu_setVBR() really needs to be perma-mapped
* stdio: support %f in printf
* project: add license file * project: add license file
* kernel: group linker script symbols in a single header file * kernel: group linker script symbols in a single header file
* kernel: be consistent about *tlb_mapped_memory() in hw_detect()
* bopti: try to display fullscreen images with TLB access + DMA on fxcg50 * bopti: try to display fullscreen images with TLB access + DMA on fxcg50
* dma: fx9860g support (need to switch it on and update the Makefile) * dma: fx9860g support (need to switch it on and update the Makefile)
* core: try to leave add-in without reset in case of panic * core: try to leave add-in without reset in case of panic
@ -12,7 +11,6 @@ Extensions on existing code:
* core: review forgotten globals and MPU addresses not in <gint/mpu/*.h> * core: review forgotten globals and MPU addresses not in <gint/mpu/*.h>
* core: run destructors when a task-switch results in leaving the app * core: run destructors when a task-switch results in leaving the app
* core rtc: use qdiv10 to massively improve division performance * core rtc: use qdiv10 to massively improve division performance
* topti: let the font specify letter and word spacing
Future directions. Future directions.
* A complete file system abstraction * A complete file system abstraction

View file

@ -16,12 +16,15 @@ MEMORY
/* Userspace mapping of the add-in (G1A header takes 0x200 bytes) */ /* Userspace mapping of the add-in (G1A header takes 0x200 bytes) */
rom (rx): o = 0x00300200, l = 500k rom (rx): o = 0x00300200, l = 500k
/* User RAM is mapped at 0x08100000 through MMU; 8k on SH3, 32k on SH4. /* User RAM is mapped at 0x08100000 through MMU; usually 8k on SH3, 32k
Currently gint provides access to 8k, with three blocks: on SH4. This script exposes only 6k to the user, reserving:
* 0x200 bytes for text accessed without the TLB when SR.BL=1, linked * 0x200 bytes for text accessed without the TLB when SR.BL=1, linked
into the rram region below, then loaded dynamically into the rram region below, then loaded dynamically
* 6k for user content * 0x600 bytes for the VBR space, also without MMU
* 0x600 bytes for the VBR space, also without MMU */ On SH3, the VBR space consumes these 0x600 bytes. On SH4, it spans
0x1100 bytes near the end of the user RAM, which is larger; the 6k
left for the user are honored in both cases. Unused memory from the
exposed 6k and non-exposed memory is available through malloc(). */
ram (rw): o = 0x08100200, l = 6k ram (rw): o = 0x08100200, l = 6k
/* This region represents the first block of user RAM. Linker arranges /* This region represents the first block of user RAM. Linker arranges
@ -172,6 +175,9 @@ SECTIONS
*(.gint.bss .gint.bss.sh3) *(.gint.bss .gint.bss.sh3)
. = ALIGN(16); . = ALIGN(16);
/* End of user RAM */
_euram = . ;
} > ram :NONE } > ram :NONE
_sgbss = SIZEOF(.gint.bss); _sgbss = SIZEOF(.gint.bss);

View file

@ -179,6 +179,9 @@ SECTIONS
.gint.bss (NOLOAD) : { .gint.bss (NOLOAD) : {
*(.gint.bss) *(.gint.bss)
. = ALIGN(16); . = ALIGN(16);
/* End of user RAM */
_euram = . ;
} > ram :NONE } > ram :NONE
_sgbss = SIZEOF(.gint.bss); _sgbss = SIZEOF(.gint.bss);

View file

@ -24,6 +24,9 @@
extern uint32_t (*cpu_setVBR)(uint32_t vbr, void (*conf_intc)(int arg), extern uint32_t (*cpu_setVBR)(uint32_t vbr, void (*conf_intc)(int arg),
int arg); int arg);
/* cpu_getVBR(): Query the current VBR address */
uint32_t cpu_getVBR(void);
/* cpu_setCPUOPM(): Change the CPU Operation Mode register /* cpu_setCPUOPM(): Change the CPU Operation Mode register
Updates the CPU Operation Mode with the specified settings, then performs a Updates the CPU Operation Mode with the specified settings, then performs a

View file

@ -2,7 +2,8 @@
** gint:core:vbr - Assembler-level VBR management ** gint:core:vbr - Assembler-level VBR management
*/ */
.global _cpu_setVBR .global _cpu_getVBR
.global _cpu_setVBR
.global _cpu_setCPUOPM .global _cpu_setCPUOPM
.global _cpu_getCPUOPM .global _cpu_getCPUOPM
.global _cpu_getSR .global _cpu_getSR
@ -52,6 +53,12 @@ _cpu_setVBR:
.text .text
/* cpu_getVBR(): Query the current VBR address */
_cpu_getVBR:
stc vbr, r0
rts
nop
/* cpu_setCPUOPM(): Change the CPU Operation Mode register */ /* cpu_setCPUOPM(): Change the CPU Operation Mode register */
_cpu_setCPUOPM: _cpu_setCPUOPM:
/* Set CPUOPM as requested */ /* Set CPUOPM as requested */

View file

@ -127,9 +127,17 @@ static void kinit_cpu(void)
void kinit(void) void kinit(void)
{ {
#ifdef FX9860G #ifdef FX9860G
/* VBR is loaded 0x600 bytes before end of the user RAM (0x100 bytes at /* VBR is loaded at the end of the user RAM. */
the start of the VBR space are unused) */ uint32_t uram_end = (uint32_t)mmu_uram() + mmu_uram_size();
gint_ctx.VBR = (uint32_t)mmu_uram() + 0x1a00 - 0x100; /* On SH4, stack is at the end of the region, leave 8k */
if(isSH4()) uram_end -= 0x2000;
/* VBR size differs with models. On SH3, only 0x600 bytes are used due
to the compact scheme. On SH4, 0x1100 bytes are needed to cover the
expanded region. */
uram_end -= (isSH3() ? 0x600 : 0x1100);
/* There are 0x100 unused bytes at the start of the VBR area */
gint_ctx.VBR = uram_end - 0x100;
#endif #endif
#ifdef FXCG50 #ifdef FXCG50
@ -191,6 +199,12 @@ void *gint_inthandler(int event_code, const void *handler, size_t size)
if(event_code < 0x400) return NULL; if(event_code < 0x400) return NULL;
event_code &= ~0x1f; event_code &= ~0x1f;
/* Prevent writing beyond the end of the VBR space on SH4. Using code
0xfc0 into the interrupt handler space (which starts 0x540 bytes
into VBR-reserved memory) would reach byte 0x540 + 0xfc0 - 0x400 =
0x1100, which is out of gint's reserved VBR area. */
if(isSH4() && event_code + size > 0xfc0) return NULL;
/* On SH3, make VBR compact. Use this offset specified in the VBR map /* On SH3, make VBR compact. Use this offset specified in the VBR map
above to avoid gaps */ above to avoid gaps */
if(isSH3()) if(isSH3())