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
Signed by: Lephenixnoir
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
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`
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

4
TODO
View File

@ -1,9 +1,8 @@
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
* stdio: support %f in printf
* project: add license 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
* dma: fx9860g support (need to switch it on and update the Makefile)
* 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: run destructors when a task-switch results in leaving the app
* core rtc: use qdiv10 to massively improve division performance
* topti: let the font specify letter and word spacing
Future directions.
* A complete file system abstraction

View File

@ -16,12 +16,15 @@ MEMORY
/* Userspace mapping of the add-in (G1A header takes 0x200 bytes) */
rom (rx): o = 0x00300200, l = 500k
/* User RAM is mapped at 0x08100000 through MMU; 8k on SH3, 32k on SH4.
Currently gint provides access to 8k, with three blocks:
/* User RAM is mapped at 0x08100000 through MMU; usually 8k on SH3, 32k
on SH4. This script exposes only 6k to the user, reserving:
* 0x200 bytes for text accessed without the TLB when SR.BL=1, linked
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
/* This region represents the first block of user RAM. Linker arranges
@ -172,6 +175,9 @@ SECTIONS
*(.gint.bss .gint.bss.sh3)
. = ALIGN(16);
/* End of user RAM */
_euram = . ;
} > ram :NONE
_sgbss = SIZEOF(.gint.bss);

View File

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

View File

@ -24,6 +24,9 @@
extern uint32_t (*cpu_setVBR)(uint32_t vbr, void (*conf_intc)(int arg),
int arg);
/* cpu_getVBR(): Query the current VBR address */
uint32_t cpu_getVBR(void);
/* cpu_setCPUOPM(): Change the CPU Operation Mode register
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
*/
.global _cpu_setVBR
.global _cpu_getVBR
.global _cpu_setVBR
.global _cpu_setCPUOPM
.global _cpu_getCPUOPM
.global _cpu_getSR
@ -52,6 +53,12 @@ _cpu_setVBR:
.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:
/* Set CPUOPM as requested */

View File

@ -127,9 +127,17 @@ static void kinit_cpu(void)
void kinit(void)
{
#ifdef FX9860G
/* VBR is loaded 0x600 bytes before end of the user RAM (0x100 bytes at
the start of the VBR space are unused) */
gint_ctx.VBR = (uint32_t)mmu_uram() + 0x1a00 - 0x100;
/* VBR is loaded at the end of the user RAM. */
uint32_t uram_end = (uint32_t)mmu_uram() + mmu_uram_size();
/* 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
#ifdef FXCG50
@ -191,6 +199,12 @@ void *gint_inthandler(int event_code, const void *handler, size_t size)
if(event_code < 0x400) return NULL;
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
above to avoid gaps */
if(isSH3())