mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
e5abe03b89
This commit introduces a large architectural change. Unlike previous models of the fx-9860G series, the G-III models have a new user RAM address different from 8801c000. The purpose of this change is to dynamically load GMAPPED functions to this address by querying the TLB, and call them through a function pointer whose address is determined when loading. Because of the overhead of using a function pointer in both assembly and C code, changes have been made to avoid GMAPPED functions altogether. Current, only cpu_setVBR() and gint_inth_callback() are left, the second being used specifically to enable TLB misses when needed. * Add a .gint.mappedrel section for the function pointers holding addresses to GMAPPED functions; add function pointers for cpu_setVBR() and gint_inth_callback() * Move rram to address 0 instead of the hardcoded 0x8801c000 * Load GMAPPED functions at their linked address + the physical address user RAM is mapped, to and compute their function pointers * Remove the GMAPPED macro since no user function needs it anymore * Add section flags "ax" (code) or "aw" (data) to every custom .section in assembler code, as they default to unpredictable values that can cause the section to be marked NOLOAD by the linker * Update the main kernel, TMU, ETMU and RTC interrupt handlers to use the new indirect calling method This is made possible by new MMU functions giving direct access to the physical area behind any virtualized page. * Add an mmu_translate() function to query the TLB * Add an mmu_uram() function to access user RAM from P1 The exception catching mechanism has been modified to avoid the use of GMAPPED functions altogether. * Set SR.BL=0 and SR.IMASK=15 before calling exception catchers * Move gint_exc_skip() to normal text ROM * Also fix registers not being popped off the stack before a panic The timer drivers have also been modified to avoid GMAPPED functions. * Invoke timer_stop() through gint_inth_callback() and move it to ROM * Move and expand the ETMU driver to span 3 blocks at 0xd00 (ETMU4) * Remove the timer_clear() function by inlining it into the ETMU handler (TCR is provided within the storage block of each timer) * Also split src/timer/inth.s into src/timer/inth-{tmu,etmu}.s Additionally, VBR addresses are now determined at runtime to further reduce hardcoded memory layout addresses in the linker script. * Determine fx-9860G VBR addresses dynamically from mmu_uram() * Determine fx-CG 50 VBR addresses dynamically from mmu_uram() * Remove linker symbols for VBR addresses Comments and documentation have been updated throughout the code to reflect the changes.
206 lines
4.6 KiB
Text
206 lines
4.6 KiB
Text
/*
|
|
Linker script for fxcg50 add-ins. Most symbols are used in the startup
|
|
routine in core/start.c; some others in core/setup.c.
|
|
*/
|
|
|
|
/* All fxcg50 have SH4 processors (finally rid of compatibility issues) */
|
|
OUTPUT_ARCH(sh4)
|
|
/* ELF offers a lot of symbol/section/relocation insights */
|
|
OUTPUT_FORMAT(elf32-sh)
|
|
/* Located in core/start.c */
|
|
ENTRY(_start)
|
|
|
|
MEMORY
|
|
{
|
|
/* Userspace mapping of the add-in (without G3A header) */
|
|
rom (rx): o = 0x00300000, l = 2M
|
|
/* Static RAM; stack grows down from the end of this region.
|
|
The first 5k (0x1400 bytes) are reserved by gint for the VBR space,
|
|
which is loaded dynamically and accessed through P1 */
|
|
ram (rw): o = 0x08101400, l = 507k
|
|
/* On-chip IL memory */
|
|
ilram (rwx): o = 0xe5200000, l = 4k
|
|
/* On-chip X and Y memory */
|
|
xram (rwx): o = 0xe5007000, l = 8k
|
|
yram (rwx): o = 0xe5017000, l = 8k
|
|
}
|
|
|
|
SECTIONS
|
|
{
|
|
/*
|
|
** ROM sections
|
|
*/
|
|
|
|
/* First address to be mapped to ROM */
|
|
_brom = 0x00300000;
|
|
/* Size of ROM mappings */
|
|
_srom = SIZEOF(.text) + SIZEOF(.rodata)
|
|
+ SIZEOF(.gint.drivers) + SIZEOF(.gint.blocks);
|
|
|
|
/* Machine code going to ROM:
|
|
- Entry function (.text.entry)
|
|
- Compiler-provided constructors (.ctors) and destructors (.dtors)
|
|
- All text from .text and .text.* (including user code) */
|
|
.text : {
|
|
*(.text.entry)
|
|
|
|
_bctors = . ;
|
|
*(.ctors .ctors.*)
|
|
_ectors = . ;
|
|
|
|
_bdtors = . ;
|
|
*(.dtors .dtors.*)
|
|
_edtors = . ;
|
|
|
|
_gint_exch_start = . ;
|
|
*(.gint.exch)
|
|
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
|
|
|
|
_gint_tlbh_start = . ;
|
|
*(.gint.tlbh)
|
|
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
|
|
|
|
*(.text .text.*)
|
|
} > rom
|
|
|
|
/* gint's interrupt handler blocks (.gint.blocks)
|
|
Although gint's blocks end up in VBR space, they are relocated at
|
|
startup by the library/drivers, so we store them here for now */
|
|
.gint.blocks : {
|
|
KEEP(*(.gint.blocks));
|
|
} > rom
|
|
|
|
/* Exposed driver interfaces (.gint.drivers)
|
|
The driver information is required to start and configure the
|
|
driver, even if the symbols are not referenced */
|
|
.gint.drivers : {
|
|
_bdrv = . ;
|
|
KEEP(*(.gint.drivers.0));
|
|
KEEP(*(.gint.drivers.1));
|
|
KEEP(*(.gint.drivers.2));
|
|
KEEP(*(.gint.drivers.3));
|
|
KEEP(*(.gint.drivers.4));
|
|
KEEP(*(.gint.drivers.5));
|
|
KEEP(*(.gint.drivers.6));
|
|
_edrv = . ;
|
|
} > rom
|
|
|
|
/* Read-only data going to ROM:
|
|
- Resources or assets from fxconv or similar converters
|
|
- Data marked read-only by the compiler (.rodata and .rodata.*) */
|
|
.rodata : SUBALIGN(4) {
|
|
/* Put these first, they need to be 4-aligned */
|
|
*(.rodata.4)
|
|
|
|
*(.rodata .rodata.*)
|
|
} > rom
|
|
|
|
|
|
|
|
/*
|
|
** RAM sections
|
|
*/
|
|
|
|
. = ORIGIN(ram);
|
|
|
|
/* BSS data going to RAM. The BSS section is to be stripped from the
|
|
ELF file later, and wiped at startup */
|
|
.bss (NOLOAD) : {
|
|
_rbss = . ;
|
|
|
|
*(.bss.vram)
|
|
*(.bss COMMON)
|
|
|
|
. = ALIGN(16);
|
|
} > ram :NONE
|
|
|
|
_sbss = SIZEOF(.bss);
|
|
|
|
/* Read-write data sections going to RAM (.data and .data.*) */
|
|
.data ALIGN(4) : ALIGN(4) {
|
|
_ldata = LOADADDR(.data);
|
|
_rdata = . ;
|
|
|
|
*(.data .data.*)
|
|
/* References to mapped code - no relocation needed */
|
|
*(.gint.mappedrel)
|
|
|
|
. = ALIGN(16);
|
|
} > ram AT> rom
|
|
|
|
/* Read-write data sub-aligned to 4 bytes (mainly from fxconv) */
|
|
.data.4 : SUBALIGN(4) {
|
|
*(.data.4)
|
|
. = ALIGN(16);
|
|
} > ram AT> rom
|
|
|
|
_sdata = SIZEOF(.data) + SIZEOF(.data.4);
|
|
|
|
/* On-chip memory sections: IL, X and Y memory */
|
|
|
|
. = ORIGIN(ilram);
|
|
.ilram ALIGN(4) : ALIGN(4) {
|
|
_lilram = LOADADDR(.ilram);
|
|
_rilram = . ;
|
|
|
|
*(.ilram)
|
|
/* Code that must remain mapped is placed here */
|
|
*(.gint.mapped)
|
|
|
|
. = ALIGN(16);
|
|
} > ilram AT> rom
|
|
|
|
. = ORIGIN(xram);
|
|
.xram ALIGN(4) : ALIGN(4) {
|
|
_lxram = LOADADDR(.xram);
|
|
_rxram = . ;
|
|
|
|
*(.xram)
|
|
|
|
. = ALIGN(16);
|
|
} > xram AT> rom
|
|
|
|
. = ORIGIN(yram);
|
|
.yram ALIGN(4) : ALIGN(4) {
|
|
_lyram = LOADADDR(.yram);
|
|
_ryram = . ;
|
|
|
|
*(.yram)
|
|
|
|
. = ALIGN(16);
|
|
} > yram AT> rom
|
|
|
|
_silram = SIZEOF(.ilram);
|
|
_sxram = SIZEOF(.xram);
|
|
_syram = SIZEOF(.yram);
|
|
|
|
/* gint's uninitialized BSS section, going to static RAM. All the large
|
|
data arrays will be located here */
|
|
.gint.bss (NOLOAD) : {
|
|
*(.gint.bss)
|
|
. = ALIGN(16);
|
|
} > ram :NONE
|
|
|
|
_sgbss = SIZEOF(.gint.bss);
|
|
|
|
|
|
|
|
/*
|
|
** Unused sections
|
|
*/
|
|
|
|
/DISCARD/ : {
|
|
/* SH3-only data sections */
|
|
*(.gint.data.sh3 .gint.bss.sh3)
|
|
/* Debug sections (often from libgcc) */
|
|
*(.debug_info .debug_abbrev .debug_loc .debug_aranges
|
|
.debug_ranges .debug_line .debug_str)
|
|
/* Java class registration (why are they even here?!) */
|
|
*(.jcr)
|
|
/* Asynchronous unwind tables: no C++ exception handling */
|
|
*(.eh_frame_hdr)
|
|
*(.eh_frame)
|
|
/* Comments or anything the compiler might generate */
|
|
*(.comment)
|
|
}
|
|
}
|