OUTPUT_ARCH(mips)

/**** Start point ****/
ENTRY(__reset_vector)

PROVIDE(__boot_stack_size = 0x200);
PROVIDE(__ebase_size = 0x200);
PROVIDE(__isr_vec_space = 32);
PROVIDE(__isr_vec_count = 64);
PROVIDE(__boot_mem_reserved = 0x1000);

__mergebin_offset       = 0x9000;

/* ROM data and text*/
__rom_start             = 0xBFC00000 + __mergebin_offset;
__rom_size              = 0x40000;
__rom_end               = __rom_start + __rom_size;
_text_lma               = 0xBFC27000;
/* 64K IRAM */
__ram_start             = 0x90000000;
__ram_size              = 0x10000 - 0x1000;
__ram_end               = __ram_start + __ram_size;

/* 8M DDR */
__ddr_size              = 0x00800000;
__cached_ddr_start      = 0x80000000;
__cached_ddr_end        = __cached_ddr_start + __ddr_size;

_risc_code_end          = 0x01000000;
__uncached_ddr_size     = 0x00800000;
__uncached_ddr_start    = 0x70000000 + _risc_code_end;
__uncached_ddr_end      = __uncached_ddr_start + __uncached_ddr_size;

__ddr_start             = __cached_ddr_start;

EXTERN(__exception_entry)
EXTERN(__isr_vec)

MEMORY
{
    ROM          : ORIGIN = __rom_start,          LENGTH = __rom_size
    RAM          : ORIGIN = __ram_start,          LENGTH = __ram_size
    DDR          : ORIGIN = __ddr_start,          LENGTH = __ddr_size
    UNCACHED_DDR : ORIGIN = __uncached_ddr_start, LENGTH = __uncached_ddr_size
}

REGION_ALIAS("REGION_ROM_TEXT",     ROM);

/*
REGION_ALIAS("REGION_BOOT_TEXT",    ISPRAM);
REGION_ALIAS("REGION_BOOT_RODATA",  DSPRAM);
REGION_ALIAS("REGION_BOOT_DATA",    DSPRAM);
REGION_ALIAS("REGION_BOOT_BSS",     DSPRAM);
*/

REGION_ALIAS("REGION_BOOT_TEXT",    RAM);
REGION_ALIAS("REGION_BOOT_RODATA",  RAM);
REGION_ALIAS("REGION_BOOT_DATA",    RAM);
REGION_ALIAS("REGION_BOOT_BSS",     RAM);

/*
PROVIDE(__heap_size = 0x1200);
REGION_ALIAS("REGION_TEXT",         RAM);
REGION_ALIAS("REGION_RODATA",       RAM);
REGION_ALIAS("REGION_DATA",         RAM);
REGION_ALIAS("REGION_BSS",          RAM);
*/

PROVIDE(__heap_size = 0x200000);
REGION_ALIAS("REGION_TEXT",         DDR);
REGION_ALIAS("REGION_RODATA",       DDR);
REGION_ALIAS("REGION_DATA",         DDR);
REGION_ALIAS("REGION_BSS",          DDR);

REGION_ALIAS("REGION_UNCACHED_DATA",  UNCACHED_DDR);


SECTIONS
{

    .boot_rom_text : {
        __boot_rom_text_start = ABSOLUTE(.) ;   /* Start of init code. */
        start.*(.text)          /* Reset entry point            */
        set_gpr_boot_values.*(.text)
        init_gpr.*(.text)
        init_cp0.*(.text)
        init_tlb.*(.text)
        init_caches.*(.text)
        copy_c2_ram.*(.text)
        init_itc.*(.text)
        init_vpe1.*(.text)

        start.*(.text.*)          /* Reset entry point          */
        set_gpr_boot_values.*(.text.*)
        init_gpr.*(.text.*)
        init_cp0.*(.text.*)
        init_tlb.*(.text.*)
        init_caches.*(.text.*)
        copy_c2_ram.*(.text.*)
        init_itc.*(.text.*)
        init_vpe1.*(.text.*)
        . = ALIGN(8);
        __boot_rom_text_end = ABSOLUTE(.);  /* End of init code. */

    } > REGION_ROM_TEXT

    _boot_text_lma = __boot_rom_text_end - __boot_rom_text_start + __rom_start;
    .boot_text : AT(_boot_text_lma)
    {
        __boot_text_start = ABSOLUTE(.);
        /* entry point */

        hv_boot_Main.*(.text)
        hv_boot_Common.*(.text)
        hv_boot_DDRInit.*(.text)
        hv_boot_DDRTest.*(.text)
        hv_boot_Lzss.*(.text)
        risc_clean_cache.*(.text)
        risc_excpt_entry.*(.text)
        risc_excpt_handler.*(.text)
        risc_excpt_register.*(.text)
        risc_flush_cache.*(.text)
        risc_fp.*(.text)
        risc_isr_handler.*(.text)
        risc_l2size.*(.text)
        risc_lock_cache.*(.text)
        risc_size_cache.*(.text)
        risc_sync_cache.*(.text)
        risc_tlb.*(.text)
        set_gpr_boot_values.*(.text)

        hv_boot_Main.*(.text.*)
        copy_c2_ram.*(.text.*)
        hv_boot_Common.*(.text.*)
        hv_boot_DDRInit.*(.text.*)
        hv_boot_DDRTest.*(.text.*)
        hv_boot_Lzss.*(.text.*)
        risc_clean_cache.*(.text.*)
        risc_excpt_entry.*(.text.__exception_save)
        risc_excpt_entry.*(.text.__exception_restore)
        risc_excpt_handler.*(.text.*)
        risc_excpt_register.*(.text.*)
        risc_flush_cache.*(.text.*)
        risc_fp.*(.text.*)
        risc_isr_handler.*(.text.*)
        risc_l2size.*(.text.*)
        risc_lock_cache.*(.text.*)
        risc_size_cache.*(.text.*)
        risc_sync_cache.*(.text.*)
        risc_tlb.*(.text.*)
        set_gpr_boot_values.*(.text.*)
        . = ALIGN(16);
        __boot_text_end = ABSOLUTE(.);
    } > REGION_BOOT_TEXT

    _boot_rodata_lma = __boot_text_end - __boot_text_start + _boot_text_lma ;
    .boot_rodata : AT(_boot_rodata_lma)
    {
        __boot_rodata_start = ABSOLUTE(.);
        start.*(.rodata)
        hv_boot_Main.*(.rodata)
        copy_c2_ram.*(.rodata)
        hv_boot_Common.*(.rodata)
        hv_boot_DDRInit.*(.rodata)
        hv_boot_DDRTest.*(.rodata)
        hv_boot_Lzss.*(.rodata)
        excpt_isr.*(.rodata)
        init_caches.*(.rodata)
        init_cp0.*(.rodata)
        init_gpr.*(.rodata)
        init_itc.*(.rodata)
        init_tlb.*(.rodata)
        init_vpe1.*(.rodata)
        risc_clean_cache.*(.rodata)
        risc_excpt_entry.*(.rodata)
        risc_excpt_handler.*(.rodata)
        risc_excpt_register.*(.rodata)
        risc_flush_cache.*(.rodata)
        risc_fp.*(.rodata)
        risc_isr_handler.*(.rodata)
        risc_l2size.*(.rodata)
        risc_lock_cache.*(.rodata)
        risc_size_cache.*(.rodata)
        risc_sync_cache.*(.rodata)
        risc_tlb.*(.rodata)
        set_gpr_boot_values.*(.rodata)

        start.*(.rodata.*)
        hv_boot_Main.*(.rodata.*)
        copy_c2_ram.*(.rodata.*)
        hv_boot_Common.*(.rodata.*)
        hv_boot_DDRInit.*(.rodata.*)
        hv_boot_DDRTest.*(.rodata.*)
        hv_boot_Lzss.*(.rodata.*)
        excpt_isr.*(.rodata.*)
        init_caches.*(.rodata.*)
        init_cp0.*(.rodata.*)
        init_gpr.*(.rodata.*)
        init_itc.*(.rodata.*)
        init_tlb.*(.rodata.*)
        init_vpe1.*(.rodata.*)
        risc_clean_cache.*(.rodata.*)
        risc_excpt_entry.*(.rodata.*)
        risc_excpt_handler.*(.rodata.*)
        risc_excpt_register.*(.rodata.*)
        risc_flush_cache.*(.rodata.*)
        risc_fp.*(.rodata.*)
        risc_isr_handler.*(.rodata.*)
        risc_l2size.*(.rodata.*)
        risc_lock_cache.*(.rodata.*)
        risc_size_cache.*(.rodata.*)
        risc_sync_cache.*(.rodata.*)
        risc_tlb.*(.rodata.*)
        set_gpr_boot_values.*(.rodata.*)
        . = ALIGN(16);
        __boot_rodata_end = ABSOLUTE(.);
    } > REGION_BOOT_RODATA

    _boot_data_lma = __boot_rodata_end - __boot_rodata_start + _boot_rodata_lma ;
    .boot_data : AT(_boot_data_lma)
    {
        __boot_data_start = ABSOLUTE(.);
        start.*(.data)
        hv_boot_Main.*(.data)
        copy_c2_ram.*(.data)
        hv_boot_Common.*(.data)
        hv_boot_DDRInit.*(.data)
        hv_boot_DDRTest.*(.data)
        hv_boot_Lzss.*(.data)
        excpt_isr.*(.data)
        init_caches.*(.data)
        init_cp0.*(.data)
        init_gpr.*(.data)
        init_itc.*(.data)
        init_tlb.*(.data)
        init_vpe1.*(.data)
        risc_clean_cache.*(.data)
        risc_excpt_entry.*(.data)
        risc_excpt_handler.*(.data)
        risc_excpt_register.*(.data)
        risc_flush_cache.*(.data)
        risc_fp.*(.data)
        risc_isr_handler.*(.data)
        risc_l2size.*(.data)
        risc_lock_cache.*(.data)
        risc_size_cache.*(.data)
        risc_sync_cache.*(.data)
        risc_tlb.*(.data)
        set_gpr_boot_values.*(.data)

        start.*(.data.*)
        hv_boot_Main.*(.data.*)
        copy_c2_ram.*(.data.*)
        hv_boot_Common.*(.data.*)
        hv_boot_DDRInit.*(.data.*)
        hv_boot_DDRTest.*(.data.*)
        hv_boot_Lzss.*(.data.*)
        excpt_isr.*(.data.*)
        init_caches.*(.data.*)
        init_cp0.*(.data.*)
        init_gpr.*(.data.*)
        init_itc.*(.data.*)
        init_tlb.*(.data.*)
        init_vpe1.*(.data.*)
        risc_clean_cache.*(.data.*)
        risc_excpt_entry.*(.data.*)
        risc_excpt_handler.*(.data.*)
        risc_excpt_register.*(.data.*)
        risc_flush_cache.*(.data.*)
        risc_fp.*(.data.*)
        risc_isr_handler.*(.data.*)
        risc_l2size.*(.data.*)
        risc_lock_cache.*(.data.*)
        risc_size_cache.*(.data.*)
        risc_sync_cache.*(.data.*)
        risc_tlb.*(.data.*)
        set_gpr_boot_values.*(.data.*)
        . = ALIGN(0x1000);
        __boot_data_end = ABSOLUTE(.);
    } > REGION_BOOT_DATA

    _boot_vector_lma = __boot_data_end - __boot_data_start + _boot_data_lma ;
    .boot_vector : AT(_boot_vector_lma)
    {
        boot_vector_start = ABSOLUTE(.);
        _ebase_ram = ABSOLUTE(.);
        _base = .;
        KEEP(*(.text.__exception_entry))
        . = _base + __ebase_size;
        KEEP(* (SORT(.text.__isr_vec*)))
        /* Leave space for all the vector entries */
        . = _base + __ebase_size + (__isr_vec_space * __isr_vec_count);
        . = ALIGN(16);
        boot_vector_end = ABSOLUTE(.);
    } > REGION_BOOT_DATA

    .boot_bss (NOLOAD): {
        __boot_bss_start = ABSOLUTE(.);
        LONG(0x55AA55AD);
        start.*(.bss)
        hv_boot_Main.*(.bss)
        copy_c2_ram.*(.bss)
        hv_boot_Common.*(.bss)
        hv_boot_DDRInit.*(.bss)
        hv_boot_DDRTest.*(.bss)
        hv_boot_Lzss.*(.bss)
        excpt_isr.*(.bss)
        init_caches.*(.bss)
        init_cp0.*(.bss)
        init_gpr.*(.bss)
        init_itc.*(.bss)
        init_tlb.*(.bss)
        init_vpe1.*(.bss)
        ddrmc_tmg_cfg.*(.bss)
        risc_clean_cache.*(.bss)
        risc_excpt_entry.*(.bss)
        risc_excpt_handler.*(.bss)
        risc_excpt_register.*(.bss)
        risc_flush_cache.*(.bss)
        risc_fp.*(.bss)
        risc_isr_handler.*(.bss)
        risc_l2size.*(.bss)
        risc_lock_cache.*(.bss)
        risc_size_cache.*(.bss)
        risc_sync_cache.*(.bss)
        risc_tlb.*(.bss)
        set_gpr_boot_values.*(.bss)

        start.*(.bss.*)
        hv_boot_Main.*(.bss.*)
        copy_c2_ram.*(.bss.*)
        hv_boot_Common.*(.bss.*)
        hv_boot_DDRInit.*(.bss.*)
        hv_boot_DDRTest.*(.bss.*)
        hv_boot_Lzss.*(.bss.*)
        excpt_isr.*(.bss.*)
        init_caches.*(.bss.*)
        init_cp0.*(.bss.*)
        init_gpr.*(.bss.*)
        init_itc.*(.bss.*)
        init_tlb.*(.bss.*)
        init_vpe1.*(.bss.*)
        ddrmc_tmg_cfg.*(.bss.*)
        risc_clean_cache.*(.bss.*)
        risc_excpt_entry.*(.bss.*)
        risc_excpt_handler.*(.bss.*)
        risc_excpt_register.*(.bss.*)
        risc_flush_cache.*(.bss.*)
        risc_fp.*(.bss.*)
        risc_isr_handler.*(.bss.*)
        risc_l2size.*(.bss.*)
        risc_lock_cache.*(.bss.*)
        risc_size_cache.*(.bss.*)
        risc_sync_cache.*(.bss.*)
        risc_tlb.*(.bss.*)
        set_gpr_boot_values.*(.bss.*)
        __boot_bss_end = ABSOLUTE(.);
        . += __boot_stack_size;
        __boot_stack = ABSOLUTE(.);
    } > REGION_BOOT_BSS

    .uncached_ddr (NOLOAD) :{
        *(.uncached_data)
    } > REGION_UNCACHED_DATA

    /*_text_lma = boot_vector_end - boot_vector_start + _boot_vector_lma ;*/
    .text : AT(_text_lma)
    {
        __text_start = ABSOLUTE(.);
        *(.text)
        *(.text.*)
        . = ALIGN(512);
        __text_end = ABSOLUTE(.);
    } > REGION_TEXT

    _rodata_lma = __text_end - __text_start + _text_lma ;
    .rodata : AT(_rodata_lma)
    {
        __rodata_start = ABSOLUTE(.);
        _shell_command_start = ABSOLUTE(.);
        KEEP(*(shellCommand))
        _shell_command_end = ABSOLUTE(.);
        *(.rodata)
        *(.rodata.*)
        . = ALIGN(16);
        __rodata_end = ABSOLUTE(.);
    } > REGION_RODATA

    _data_lma = __rodata_end - __rodata_start + _rodata_lma ;
    .data : AT(_data_lma)
    {
        __data_start = ABSOLUTE(.);
        *(.data)
        *(.data.*)
        _gp = ABSOLUTE(. + 0x7ff0); /* Base of small data           */
        *(.lit8)
        *(.lit8.*)
        *(.lit4)
        *(.lit4.*)
        *(.sdata)
        *(.sdata.*)
        . = ALIGN(16);
        __data_end = ABSOLUTE(.);
    } > REGION_DATA


    .bss(NOLOAD) : {
        __bss_start = ABSOLUTE(.);
        *(.sbss)
        *(.sbss.*)
        *(.scommon)
        *(.bss)
        *(.bss.*)
        *(COMMON)
        . = ALIGN(16);
        __bss_end = ABSOLUTE(.);
    } > REGION_BSS

    .heap (NOLOAD) : {
        _heap_start = ABSOLUTE(.);
        . += __heap_size;
        . = ALIGN(16);
        _heap_end = ABSOLUTE(.);
    } > REGION_BSS

    .stack (NOLOAD) :{
        __stack_top = ABSOLUTE(.);
        __stack_size = ORIGIN(REGION_BSS) + LENGTH(REGION_BSS) - ABSOLUTE(.) - 4;
        . += __stack_size;
        . = ALIGN(16);
        __stack = ABSOLUTE(.);
    } > REGION_BSS


    .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
    .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }


    /DISCARD/ :
    {
        *(.reginfo)
        *(.MIPS.abiflags)
    }
    _freemem = .;
}


