/*
	Linker script for the fx9860g platform. Most of the symbols defined
	here are used in the initialization routine in core/start.c; others are
	used in core/setup.c.
*/

/* fx9860g may mean SH3 or SH4 and we want full compatibility */
OUTPUT_ARCH(sh3)
/* 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 (G1A header takes 0x200 bytes) */
	rom   (rx):   o = 0x00300200, l = 500k
	/* This is mapped to RAM; 8k on SH3, 32k on SH4. Since gint uses the
	   last 2k for its VBR and mapped code, 6k are left */
	ram   (rw):   o = 0x08100200, l = 6k
	/* This is the VBR space. The [ram] region is mapped to 8801c000. This
	   region is used at load time and mentioned here for completeness */
	vbr   (rwx):  o = 0x8801da00, l = 1536
	/* These first bits of RAM are used for gint's perma-mapped code */
	rram  (rwx):  o = 0x8801c000, l = 512
	/* 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 (including G1A header) */
	_brom = 0x00300000;
	/* Size of ROM mappings */
	_srom = 0x200
	      + 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)
	   - Code sections from fxlib, named "C" and "P" */

	.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.*)
		*(C P)
	} > rom

	/* Interrupt handlers going to ROM:
	   - gint's interrupt handler blocks (.gint.blocks)

	   Although gint's blocks end up in VBR space, they are selected and
	   installed on-the-fly by the library and the drivers, so we can't
	   just put them in the vbr region and wait for the copy */
	.gint.blocks : {
		KEEP(*(.gint.blocks));
	} > rom

	/* Driver data going to 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 stuff going to RAM:
	   - Data marked BSS by the compiler
	   - BSS sections from fxlib, namely "B" and "R"
	   The BSS section is to be stripped from the ELF file later, and wiped
	   at startup. */
	.bss (NOLOAD) : {
		_rbss = . ;

		*(.bss COMMON)
		*(B R)

		. = ALIGN(16);
	} > ram :NONE

	_sbss = SIZEOF(.bss);

	/* Read-write data going to RAM:
	   - Data sections generated by the compiler (.data and .data.*)
	   - Data sections from fxlib, "D"
	   - The SH3-only data section (.gint.data.sh3) */
	.data ALIGN(4) : ALIGN(4) {
		_ldata = LOADADDR(.data);
		_rdata = . ;

		*(.data .data.*)
		*(D)
		*(.gint.data.sh3)

		. = 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);

	/* gint's uninitialized BSS section */
	.gint.bss (NOLOAD) : {
		/* Since it's uninitialized, the location doesn't matter */
		*(.gint.bss .gint.bss.sh3)

		. = ALIGN(16);
	} > ram :NONE

	_sgbss = SIZEOF(.gint.bss);

	/* On-chip memory sections: IL, X and Y memory */

	. = ORIGIN(ilram);
	.ilram ALIGN(4) : ALIGN(4) {
		_lilram = LOADADDR(.ilram);
		_rilram = . ;

		*(.ilram)

		. = 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);



	/*
	**  RRAM sections
	*/

	/* VBR address: let's just start at the beginning of the RRAM area.
	   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_fx9860g = ORIGIN(vbr) - 0x100;

	. = ORIGIN(rram);

	/* Code that must remain permanently mapped (.gint.mapped) */
	.gint.mapped ALIGN(4) : ALIGN(4) {
		_lgmapped = LOADADDR(.gint.mapped);
		_rgmapped = . ;

		*(.gint.mapped)

		. = ALIGN(16);
	} > rram AT> rom

	_sgmapped = SIZEOF(.gint.mapped);



	/*
	**  Other sections
	*/

	/* Unwanted sections going to meet Dave Null:
	   - Debug sections, often come out of libgcc
	   - Java classes registration (why is there any of this here?)
	   - Asynchronous unwind tables: no C++ exception handling for now ^^
	   - Comments or anything the compiler might put in its assembler
	   - A stack section sometimes generated for build/version.o */
	/DISCARD/ : {
		*(.debug_info .debug_abbrev .debug_loc .debug_aranges
		  .debug_ranges .debug_line .debug_str)
		*(.jcr)
		*(.eh_frame_hdr)
		*(.eh_frame)
		*(.comment)
	}
}