/* GCC memory file for the STR91XF - for use with the uTasker project                   */


/* Memory sizes available - these must match the MEMORY setting below since they may not use variables */
RAM_START   = 0x04000000;
RAM_SIZE    = 64*1024;
FLASH_START = 0x0000000;
FLASH_SIZE  = 0x80000;
HEAP_SIZE   = 0;                                                         /* non uMalloc heap, if used */

VIC0_BASE   = 0xFFFFF030;
VIC1_BASE   = 0xFC000030;

MEMORY
{
    SRAM (wx)  : ORIGIN = 0x04000000, LENGTH = 0x00010000
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
}


SECTIONS
{
    __SRAM_segment_start__  = RAM_START;
    __SRAM_segment_end__    = RAM_START + RAM_SIZE;
    __FLASH_segment_start__ = FLASH_START;
    __FLASH_segment_end__   = FLASH_START + FLASH_SIZE;

    __STACKSIZE__           = 0;
    __STACKSIZE_IRQ__       = 512;
    __STACKSIZE_FIQ__       = 0;
    __STACKSIZE_SVC__       = 0;
    __STACKSIZE_ABT__       = 0;
    __STACKSIZE_UND__       = 0;
    __HEAPSIZE__            = HEAP_SIZE;

    STACK_SIZE              = (__STACKSIZE__ + __STACKSIZE_IRQ__ + __STACKSIZE_FIQ__ + __STACKSIZE_SVC__ + __STACKSIZE_ABT__ + __STACKSIZE_UND__);


    __vectors_ram_load_start__ = __SRAM_segment_start__;
    .vectors_ram                 __SRAM_segment_start__ (NOLOAD) : {     /* vectors can be placed in SRAM if required */
        __vectors_ram_start__  = .;
        *(.vectors_ram)
        . = MAX(__vectors_ram_start__ + 0x3C , .);
    }
    __vectors_ram_end__        = __vectors_ram_start__ + SIZEOF(.vectors_ram);


    __vectors_load_start__     = __FLASH_segment_start__;
    .vectors                     __FLASH_segment_start__ : {             /* Vectors at the start of FLASH             */
        __vectors_start__      = .;
        *(.vectors .vectors.*)
    }
    __vectors_end__            = __vectors_start__ + SIZEOF(.vectors);


    __init_load_start__        = ALIGN(__vectors_end__ , 4);
    .init                        ALIGN(__vectors_end__ , 4) : {          /* Reset code in FLASH                       */
         __init_start__        = .;
        *(.init .init.*)
    }
    __init_end__               = __init_start__ + SIZEOF(.init);


    __text_load_start__        = ALIGN(__init_end__ , 4);
    .text                        ALIGN(__init_end__ , 4) : {             /* Program code in FLASH                     */
        __text_start__         = .;
        *(.text .text.* .glue_7t .glue_7 .gnu.linkonce.t.*)
    }
    __text_end__               = __text_start__ + SIZEOF(.text);

    __rodata_load_start__      = ALIGN(__text_end__ , 4);
    .rodata                      ALIGN(__text_end__ , 4) : {             /* Constants in FLASH                        */
        __rodata_start__       = .;
        *(.rodata .rodata.* .gnu.linkonce.r.*)
    }
    __rodata_end__             = __rodata_start__ + SIZEOF(.rodata);


    __fast_load_start__        = ALIGN(__rodata_end__ , 4);              /* fast code in FLASH to be copied to RAM    */
    .fast                        __vectors_ram_end__ : AT(ALIGN(__rodata_end__ , 4)) {
        __fast_start__         = .;
        *(.fast .fast.*)
    }
    __fast_end__               = __fast_start__ + SIZEOF(.fast);
    __fast_load_end__          = __fast_load_start__ + SIZEOF(.fast);


    .fast_run                    ALIGN(__vectors_ram_end__ , 4) (NOLOAD) : { /* fast code execution in RAM            */
        __fast_run_start__     = .;
        . = MAX(__fast_run_start__ + SIZEOF(.fast), .);
    }
    __fast_run_end__           = __fast_run_start__ + SIZEOF(.fast_run);


    __data_load_start__        = ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4); /* Initialised variables in FLASH to be copied to RAM    */
    .data                        __fast_run_end__ : AT(ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4)) {
        __data_start__         = .;
        *(.data .data.* .gnu.linkonce.d.*)
    }
    __data_end__               = __data_start__ + SIZEOF(.data);
    __data_load_end__          = __data_load_start__ + SIZEOF(.data);
    __FLASH_segment_used_end__ = ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4) + SIZEOF(.data);
    . = ASSERT(__FLASH_segment_used_end__ >= __FLASH_segment_start__ && __FLASH_segment_used_end__ <= __FLASH_segment_end__ , "ERROR: CODE size is too large to fit in FLASH!!");



    .data_run                    ALIGN(__fast_run_end__ , 4) (NOLOAD) : { /* Initialised variables location in RAM    */
        __data_run_start__     = .;
        . = MAX(__data_run_start__ + SIZEOF(.data), .);
    }
    __data_run_end__           = __data_run_start__ + SIZEOF(.data_run);


    __bss_load_start__         = ALIGN(__data_run_end__ , 4);
    .bss                         ALIGN(__data_run_end__ , 4) (NOLOAD) : { /* Zeroes variables RAM locations           */
        __bss_start__          = .;
        *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)
    }
    __bss_end__                = __bss_start__ + SIZEOF(.bss);


    __non_init_load_start__    = ALIGN(__bss_end__ , 4);
    .non_init                    ALIGN(__bss_end__ , 4) (NOLOAD) : {     /* Non-initialised variables RAm locations   */
        __non_init_start__     = .;
        *(.non_init .non_init.*)
    }
    __non_init_end__           = __non_init_start__ + SIZEOF(.non_init);


    __heap_load_start__        = ALIGN(__non_init_end__ , 4);
    .heap                        ALIGN(__non_init_end__ , 4) (NOLOAD) : { /* heap location in RAM - if used           */
        __heap_start__         = .;
        *(.heap)
        . = MAX(__heap_start__ + __HEAPSIZE__ , .);
    }
    __heap_end__               = __heap_start__ + SIZEOF(.heap);
    . = ASSERT(__heap_end__ >= __SRAM_segment_start__ && __heap_end__ <= (__SRAM_segment_end__ - STACK_SIZE) , "ERROR: RAM size is too large to fit in SRAM!!");


	__stack_und_end__ = __SRAM_segment_end__;                             /* stack limits for use by the start up assembler code */
	__stack_abt_end__ = __stack_und_end__ - __STACKSIZE_UND__;
	__stack_irq_end__ = __stack_abt_end__ - __STACKSIZE_ABT__;
	__stack_fiq_end__ = __stack_irq_end__ - __STACKSIZE_IRQ__;
	__stack_svc_end__ = __stack_fiq_end__ - __STACKSIZE_FIQ__;
	__stack_end__     = __stack_svc_end__ - __STACKSIZE_SVC__;
}

