#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_M5484LITE */

/* make bas_rom access flags rx if compiling to RAM */
#ifdef COMPILE_RAM
#define ROMFLAGS	WX
#else
#define ROMFLAGS	RX
#endif /* COMPILE_RAM */

MEMORY
{
   bas_rom (ROMFLAGS) : ORIGIN = TARGET_ADDRESS, LENGTH = 0x00100000
   /*
	* target to copy BaS data segment to. 1M should be enough for now
	*/
   bas_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00200000, LENGTH = 0x00100000
   /*
	* driver_ram is an uncached, reserved memory area for drivers (e.g. USB) that need this type of memory
	*/
   driver_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00100000, LENGTH = 0x00100000
}

SECTIONS
{
	/* BaS in ROM */
	.text :
	{
		OBJDIR/startcf.o(.text) /* this one is the entry point so it must be the first */

		OBJDIR/sysinit.o(.text)
		OBJDIR/fault_vectors.o(.text)
#ifdef MACHINE_FIREBEE
		OBJDIR/init_fpga.o(.text)
#endif /* MACHINE_FIREBEE */
		OBJDIR/wait.o(.text)
		OBJDIR/exceptions.o(.text)
		OBJDIR/driver_vec.o(.text)
		OBJDIR/interrupts.o(.text)
		OBJDIR/mmu.o(.text)

		OBJDIR/BaS.o(.text)
		OBJDIR/pci.o(.text)
		OBJDIR/pci_wrappers.o(.text)
		OBJDIR/usb.o(.text)
		OBJDIR/driver_mem.o(.text)
		OBJDIR/usb_hub.o(.text)
		OBJDIR/usb_mouse.o(.text)
		OBJDIR/ohci-hcd.o(.text)
		OBJDIR/ehci-hcd.o(.text)
		OBJDIR/wait.o(.text)

		OBJDIR/nbuf.o(.text)
		OBJDIR/net_timer.o(.text)
		OBJDIR/queue.o(.text)
		OBJDIR/nif.o(.text)
		OBJDIR/fecbd.o(.text)
		OBJDIR/fec.o(.text)
		OBJDIR/am79c874.o(.text)
		OBJDIR/bcm5222.o(.text)
		OBJDIR/ip.o(.text)
		OBJDIR/udp.o(text)
		OBJDIR/bootp.o(text)
		OBJDIR/tftp.o(text)
		OBJDIR/arp.o(text)

		OBJDIR/unicode.o(.text)
		OBJDIR/mmc.o(.text)
		OBJDIR/ff.o(.text)
		OBJDIR/sd_card.o(.text)
		OBJDIR/s19reader.o(.text)
		OBJDIR/bas_printf.o(.text)
		OBJDIR/bas_string.o(.text)
		OBJDIR/printf_helper.o(.text)
		OBJDIR/cache.o(.text)
		OBJDIR/dma.o(.text)
		OBJDIR/MCD_dmaApi.o(.text)
		OBJDIR/MCD_tasks.o(.text)
		OBJDIR/MCD_tasksInit.o(.text)

		OBJDIR/video.o(.text)
		OBJDIR/videl.o(.text)
		OBJDIR/fbmem.o(.text)
		OBJDIR/fbmon.o(.text)
		OBJDIR/fbmodedb.o(.text)
		OBJDIR/offscreen.o(.text)

		OBJDIR/x86decode.o(.text)
		OBJDIR/x86ops.o(.text)
		OBJDIR/x86ops2.o(.text)
		OBJDIR/x86fpu.o(.text)
		OBJDIR/x86sys.o(.text)
		OBJDIR/x86biosemu.o(.text)
		OBJDIR/x86debug.o(.text)
		OBJDIR/x86prim_ops.o(.text)
		OBJDIR/x86pcibios.o(.text)

		OBJDIR/radeon_base.o(.text)
		OBJDIR/radeon_accel.o(.text)
		OBJDIR/radeon_cursor.o(.text)
		OBJDIR/radeon_monitor.o(.text)

		OBJDIR/xhdi_sd.o(.text)
		OBJDIR/xhdi_interface.o(.text)
		OBJDIR/xhdi_vec.o(.text)

#ifdef COMPILE_RAM
		/*
		 * if we compile to RAM anyway, there is no need to copy anything
		 */
		. = ALIGN(4);
		__BAS_DATA_START = .;
		*(.data)
		__BAS_DATA_END = .;
		__BAS_BSS_START = .;
		*(.bss)
		__BAS_BSS_END = .;
#endif /* COMPILE_RAM */

#if (FORMAT_ELF == 1)
		*(.rodata)
		*(.rodata.*)
#endif
	} > bas_rom

#if (TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS)
	/*
	 * put BaS .data and .bss segments to flash, but relocate it to RAM after initialize_hardware() ran
	 */
	.bas :
	AT (ALIGN(ADDR(.text) + SIZEOF(.text), 4))
	{
		. = ALIGN(4);		/* same alignment than AT() statement! */
		__BAS_DATA_START = .;
		*(.data)
		__BAS_DATA_END = .;
		__BAS_BSS_START = .;
		*(.bss)
		__BAS_BSS_END = .;

		. = ALIGN(16);
	} > bas_ram
#endif

	.driver_memory :
	{
		. = ALIGN(4);
		_driver_mem_buffer = .;
		//. = . + DRIVER_MEM_BUFFER_SIZE;
	} > driver_ram

	/*
	 * Global memory map
	 */

	/* SDRAM Initialization */
	___SDRAM                = SDRAM_START;
	___SDRAM_SIZE           = SDRAM_SIZE;
	_SDRAM_VECTOR_TABLE		= ___SDRAM;

	/* ST-RAM */
	__STRAM                 = ___SDRAM;
	__STRAM_END             = __TOS;

	/* TOS */
	__TOS                   = 0x00e00000;

	/* FastRAM */
	__FASTRAM               = 0x10000000;
	__TARGET_ADDRESS		= TARGET_ADDRESS;

#if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS
	__FASTRAM_END           = __BAS_IN_RAM;
#else
	__FASTRAM_END			= TARGET_ADDRESS;
#endif
	__FASTRAM_SIZE			= __FASTRAM_END - __FASTRAM;

	/* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */
	___BOOT_FLASH           = BOOTFLASH_BASE_ADDRESS;
	___BOOT_FLASH_SIZE      = BOOTFLASH_SIZE;

#if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS
	/* BaS */
	__BAS_LMA               = LOADADDR(.bas);
	__BAS_IN_RAM            = ADDR(.bas);
	__BAS_SIZE              = SIZEOF(.bas);
#else
	/* BaS is already in RAM - no need to copy anything */
	__BAS_IN_RAM			= __FASTRAM_END;
	__BAS_SIZE				= 0;
	__BAS_LMA				= __BAS_IN_RAM;
#endif

	/* Other flash components */
	__FIRETOS               = 0xe0400000;
	__EMUTOS                = EMUTOS_BASE_ADDRESS;
	__EMUTOS_SIZE           = 0x00100000;

	/* where FPGA data lives in flash */
	__FPGA_CONFIG 		= 0xe0700000;
	__FPGA_CONFIG_SIZE 	= 0x100000;

	/* VIDEO RAM BASIS */
	__VRAM                  = 0x60000000;

	/* Memory mapped registers */
	__MBAR                  = 0xFF000000;

	/* 32KB on-chip System SRAM */
	__SYS_SRAM              = __MBAR + 0x10000;
	__SYS_SRAM_SIZE         = 0x00008000;

	/* MMU memory mapped registers */
	__MMUBAR                = 0xFF040000;

	/*
	 * 4KB on-chip Core SRAM0: -> exception table
	 */
	__RAMBAR0               = 0xFF100000;
	__RAMBAR0_SIZE          = 0x00001000;

	/* 4KB on-chip Core SRAM1 */
	__RAMBAR1               = 0xFF101000;
	__RAMBAR1_SIZE          = 0x00001000;
	__SUP_SP                = __RAMBAR1 + __RAMBAR1_SIZE - 4;

	/*
	 * this flag (if 1) indicates that FPGA configuration has been loaded through JTAG
	 * and shouldn't be overwritten on boot
	 */
	__FPGA_JTAG_LOADED		= __RAMBAR1;
	__FPGA_JTAG_VALID		= __RAMBAR1 + 4;
	/* system variables */

	/* RAMBAR0 0 to 0x7FF -> exception vectors */
	_rt_mod    = __RAMBAR0 + 0x800;
	_rt_ssp    = __RAMBAR0 + 0x804;
	_rt_usp    = __RAMBAR0 + 0x808;
	_rt_vbr    = __RAMBAR0 + 0x80C;  	/* (8)01 */
	_rt_cacr   = __RAMBAR0 + 0x810;   	/* 002 */
	_rt_asid   = __RAMBAR0 + 0x814;   	/* 003 */
	_rt_acr0   = __RAMBAR0 + 0x818;   	/* 004 */
	_rt_acr1   = __RAMBAR0 + 0x81c;   	/* 005 */
	_rt_acr2   = __RAMBAR0 + 0x820;   	/* 006 */
	_rt_acr3   = __RAMBAR0 + 0x824;   	/* 007 */
	_rt_mmubar = __RAMBAR0 + 0x828;		/* 008 */
	_rt_sr     = __RAMBAR0 + 0x82c;
	_d0_save   = __RAMBAR0 + 0x830;
	_a7_save   = __RAMBAR0 + 0x834;
	_video_tlb = __RAMBAR0 + 0x838;
	_video_sbt = __RAMBAR0 + 0x83C;
	_rt_mbar   = __RAMBAR0 + 0x844;   	/* (c)0f */

}
