From a6d51b5113380e58d57d94f8e3354fbf9bdd98c6 Mon Sep 17 00:00:00 2001
From: Andreas Eversberg <jolly@eversberg.eu>
Date: Sun, 6 Jan 2013 05:57:49 +0100
Subject: [PATCH] Generate Compal E99 binaries for loader and flash locations

Loader binaries start at 0x20000 of flash memory. This is where the Compal
loader jumps to. Flash binaries start at 0x30000 of flash memory.
---
 src/target/firmware/Makefile                    |    8 +-
 src/target/firmware/board/compal_e99/flash.lds  |  134 +++++++++++++++++++++
 src/target/firmware/board/compal_e99/loader.lds |  147 +++++++++++++++++++++++
 3 files changed, 288 insertions(+), 1 deletions(-)
 create mode 100644 src/target/firmware/board/compal_e99/flash.lds
 create mode 100644 src/target/firmware/board/compal_e99/loader.lds

diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile
index 28344e1..f551671 100644
--- a/src/target/firmware/Makefile
+++ b/src/target/firmware/Makefile
@@ -18,6 +18,12 @@ ENV_e88loader_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/e
 ENV_e88flash_LDS=board/compal_e88/flash.lds
 ENV_e88flash_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/exceptions_redirected.o board/compal/handlers.o
 
+ENV_e99loader_LDS=board/compal_e99/loader.lds
+ENV_e99loader_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/exceptions_redirect.o
+
+ENV_e99flash_LDS=board/compal_e99/flash.lds
+ENV_e99flash_OBJS=board/compal/start.rom.o board/compal/header.o board/compal/exceptions_redirected.o board/compal/handlers.o
+
 
 #
 # Boards
@@ -71,7 +77,7 @@ BOARD_compal_e86_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
 # Compal E99
 BOARD_compal_e99_OBJS=$(compal_COMMON_OBJS) board/compal_e99/init.o \
 	battery/dummy.o $(FB_e99_OBJS)
-BOARD_compal_e99_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
+BOARD_compal_e99_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS) e99loader e99flash
 
 # Sony Ericsson J100 (made by Compal)
 BOARD_se_j100_OBJS=$(compal_COMMON_OBJS) board/se_j100/init.o \
diff --git a/src/target/firmware/board/compal_e99/flash.lds b/src/target/firmware/board/compal_e99/flash.lds
new file mode 100644
index 0000000..1cf189f
--- /dev/null
+++ b/src/target/firmware/board/compal_e99/flash.lds
@@ -0,0 +1,134 @@
+/*
+ * Linker script for flashed applications on the Compal E99
+ *
+ * This script creates a binary that can be linked at 0x2FFFF, starting
+ * with the fourth flash page. This is what a phone application or
+ * pure layer1 device uses.
+ *
+ * XXX: interrupts?
+ *
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+MEMORY
+{
+	LOADR (rx) : ORIGIN = 0x00000000, LENGTH = 0x30000
+    /* 2 MBytes of external flash memory (minus loader) */
+    FLASH (rx) : ORIGIN = 0x00030000, LENGTH = 0x1F0000
+    /* 256 kBytes of internal zero-waitstate sram */
+    IRAM  (rw) : ORIGIN = 0x00800000, LENGTH = 0x040000
+    /* 256 kBytes of external slow sram */
+    ERAM  (rw) : ORIGIN = 0x01000000, LENGTH = 0x040000
+}
+SECTIONS
+{
+    /* entrypoint */
+    .text.start : {
+        PROVIDE(_start = .);
+        KEEP(*(.text.start))
+        *(.text.start)
+    } > FLASH
+
+    /* exception vectors from 0x80001c to 0x800034 */
+    .text.exceptions 0x80001c : {
+        KEEP(*(.text.exceptions))
+        * (.text.exceptions)
+        . = ALIGN(4);
+    } > IRAM AT> FLASH
+    PROVIDE(_exceptions = LOADADDR(.text.exceptions));
+
+    /* code */
+    .text : {
+        /* regular code */
+        *(.text*)
+        /* gcc voodoo */
+        *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+    } > FLASH
+    PROVIDE(_text_start = ADDR(.text));
+    PROVIDE(_text_end = ADDR(.text) + SIZEOF(.text));
+
+    /* constructor pointers */
+    .ctors : {
+        /* ctor count */
+        LONG(SIZEOF(.ctors) / 4 - 2)
+        /* ctor pointers */
+        KEEP(*(SORT(.ctors)))
+        /* end of list */
+        LONG(0)
+    } > FLASH
+    PROVIDE(_ctor_start = LOADADDR(.ctors));
+    PROVIDE(_ctor_end = LOADADDR(.ctors) + SIZEOF(.ctors));
+
+    /* destructor pointers */
+    .dtors : {
+        /* dtor count */
+        LONG(SIZEOF(.dtors) / 4 - 2)
+        /* dtor pointers */
+        KEEP(*(SORT(.dtors)))
+        /* end of list */
+        LONG(0)
+    } > FLASH
+    PROVIDE(_dtor_start = LOADADDR(.dtors));
+    PROVIDE(_dtor_end = LOADADDR(.dtors) + SIZEOF(.dtors));
+
+    /* read-only data */
+    .rodata : {
+        *(.rodata*)
+    } > FLASH
+    PROVIDE(_rodata_start = ADDR(.rodata));
+    PROVIDE(_rodata_end = ADDR(.rodata) + SIZEOF(.rodata));
+
+    /* pic offset tables */
+    .got : {
+        . = ALIGN(4);
+        *(.got)
+        *(.got.plt) *(.igot.plt) *(.got) *(.igot)
+        . = ALIGN(4);
+    } > FLASH
+    PROVIDE(_got_start = ADDR(.got));
+    PROVIDE(_got_end = ADDR(.got) + SIZEOF(.got));
+
+    /* reserved ram  */
+    .compal.reservedram 0x800000 (NOLOAD) : {
+        . = 0xff;
+    } > IRAM
+
+    /* initialized data */
+    .data : AT (LOADADDR(.got) + SIZEOF(.got)) {
+        . = ALIGN(4);
+        *(.data)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__data_start = LOADADDR(.data));
+    PROVIDE(__data_end = LOADADDR(.data) + SIZEOF(.data));
+    PROVIDE(_data_start = ADDR(.data));
+    PROVIDE(_data_end = ADDR(.data) + SIZEOF(.data));
+
+    /* ram code */
+    .ramtext : AT (LOADADDR(.data) + SIZEOF(.data)) {
+        . = ALIGN(4);
+        *(.ramtext)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__ramtext_start = LOADADDR(.ramtext));
+    PROVIDE(__ramtext_end = LOADADDR(.ramtext) + SIZEOF(.ramtext));
+    PROVIDE(_ramtext_start = ADDR(.ramtext));
+    PROVIDE(_ramtext_end = ADDR(.ramtext) + SIZEOF(.ramtext));
+
+    /* uninitialized data */
+    .bss (NOLOAD) : {
+        . = ALIGN(4);
+        *(.bss)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__bss_start = ADDR(.bss));
+    PROVIDE(__bss_end = ADDR(.bss) + SIZEOF(.bss));
+    PROVIDE(_bss_start = __bss_start);
+    PROVIDE(_bss_end = __bss_end);
+
+    /* end of image */
+    . = ALIGN(4);
+    _end = .;
+    PROVIDE(end = .);
+}
diff --git a/src/target/firmware/board/compal_e99/loader.lds b/src/target/firmware/board/compal_e99/loader.lds
new file mode 100644
index 0000000..33d8f12
--- /dev/null
+++ b/src/target/firmware/board/compal_e99/loader.lds
@@ -0,0 +1,147 @@
+/*
+ * Linker script for flashed loader on the Compal E99
+ *
+ * This script creates a binary that can replace a standard firmware
+ * located at 0x20000. It works in conjunction with the compal ramloader.
+ *
+ * The interrupt vectors and start address are at known, fixed offsets.
+ *
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+MEMORY
+{
+    /* 2 MBytes of external flash memory */
+    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x200000
+    /* 256 kBytes of internal zero-waitstate sram */
+    IRAM  (rw) : ORIGIN = 0x00800000, LENGTH = 0x040000
+    /* 256 kBytes of external slow sram */
+    ERAM  (rw) : ORIGIN = 0x01000000, LENGTH = 0x040000
+}
+SECTIONS
+{
+    /* Provide symbols for the compal loader */
+    .compal.loader 0x00000000 (NOLOAD) : {
+        _compal_loader_start = .;
+        . = 0x20000;
+        _compal_loader_end = .;
+    } > FLASH
+
+    /* Compal-style image header */
+    .compal.header 0x00020000 : {
+        _compal_header_start = .;
+        KEEP(*(.compal.header))
+        *(.compal.header)
+        . = 0xA0;
+        _compal_header_end = .;
+    } > FLASH
+
+    /* Compal-style vector table */
+    .compal.vectors 0x000200A0 : {
+        PROVIDE(_exceptions = .);
+        KEEP(*(.text.exceptions))
+        *(.text.exceptions)
+    } > FLASH
+
+    /* Compal-style entry point */
+    .text.start 0x000200F8 : {
+        PROVIDE(_start = .);
+        KEEP(*(.text.start))
+        *(.text.start)
+    } > FLASH
+
+    /* code */
+    .text : {
+        /* regular code */
+        *(.text*)
+        /* gcc voodoo */
+        *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+    } > FLASH
+    PROVIDE(_text_start = ADDR(.text));
+    PROVIDE(_text_end = ADDR(.text) + SIZEOF(.text));
+
+    /* constructor pointers */
+    .ctors : {
+        /* ctor count */
+        LONG(SIZEOF(.ctors) / 4 - 2)
+        /* ctor pointers */
+        KEEP(*(SORT(.ctors)))
+        /* end of list */
+        LONG(0)
+    } > FLASH
+    PROVIDE(_ctor_start = LOADADDR(.ctors));
+    PROVIDE(_ctor_end = LOADADDR(.ctors) + SIZEOF(.ctors));
+
+    /* destructor pointers */
+    .dtors : {
+        /* dtor count */
+        LONG(SIZEOF(.dtors) / 4 - 2)
+        /* dtor pointers */
+        KEEP(*(SORT(.dtors)))
+        /* end of list */
+        LONG(0)
+    } > FLASH
+    PROVIDE(_dtor_start = LOADADDR(.dtors));
+    PROVIDE(_dtor_end = LOADADDR(.dtors) + SIZEOF(.dtors));
+
+    /* read-only data */
+    .rodata : {
+        *(.rodata*)
+    } > FLASH
+    PROVIDE(_rodata_start = ADDR(.rodata));
+    PROVIDE(_rodata_end = ADDR(.rodata) + SIZEOF(.rodata));
+
+    /* pic offset tables */
+    .got : {
+        . = ALIGN(4);
+        *(.got)
+        *(.got.plt) *(.igot.plt) *(.got) *(.igot)
+        . = ALIGN(4);
+    } > FLASH
+    PROVIDE(_got_start = ADDR(.got));
+    PROVIDE(_got_end = ADDR(.got) + SIZEOF(.got));
+
+    /* reserved ram  */
+    .compal.reservedram 0x800000 (NOLOAD) : {
+        . = 0xff;
+    } > IRAM
+
+    /* initialized data */
+    .data : AT (LOADADDR(.got) + SIZEOF(.got)) {
+        . = ALIGN(4);
+        *(.data)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__data_start = LOADADDR(.data));
+    PROVIDE(__data_end = LOADADDR(.data) + SIZEOF(.data));
+    PROVIDE(_data_start = ADDR(.data));
+    PROVIDE(_data_end = ADDR(.data) + SIZEOF(.data));
+
+    /* ram code */
+    .ramtext : AT (LOADADDR(.data) + SIZEOF(.data)) {
+        . = ALIGN(4);
+        *(.ramtext)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__ramtext_start = LOADADDR(.ramtext));
+    PROVIDE(__ramtext_end = LOADADDR(.ramtext) + SIZEOF(.ramtext));
+    PROVIDE(_ramtext_start = ADDR(.ramtext));
+    PROVIDE(_ramtext_end = ADDR(.ramtext) + SIZEOF(.ramtext));
+
+    /* uninitialized data */
+    .bss (NOLOAD) : {
+        . = ALIGN(4);
+        *(.bss)
+        . = ALIGN(4);
+    } > IRAM
+    PROVIDE(__bss_start = ADDR(.bss));
+    PROVIDE(__bss_end = ADDR(.bss) + SIZEOF(.bss));
+    PROVIDE(_bss_start = __bss_start);
+    PROVIDE(_bss_end = __bss_end);
+
+    /* end of image */
+    . = ALIGN(4);
+    _end = .;
+    PROVIDE(end = .);
+}
-- 
1.7.3.4

