diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-05-20 19:47:34 -0700 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-05-25 16:11:41 +0000 |
commit | c7fcad29242e8576add5b9a3640149bb1d22dd34 (patch) | |
tree | 1ad7eb4488b576cad515cee9fa7d1a8852e1c703 /core | |
parent | 61902efd16095af85764bd4b2df51415df49ea55 (diff) | |
download | chrome-ec-c7fcad29242e8576add5b9a3640149bb1d22dd34.tar.gz |
Init task contexts/stacks at runtime
Instead of storing task contexts in .data and wasting several kB of
flash with mostly 0s, move them to .bss and fill the initial context at EC
startup. The runtime overhead is small enough.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:9839
TEST=run on Link and check verified boot and chromeOS startup are OK.
Change-Id: Iaef23d46a4e3e80e49886dfbf7ab1f537c587362
Diffstat (limited to 'core')
-rw-r--r-- | core/cortex-m/ec.lds.S | 29 | ||||
-rw-r--r-- | core/cortex-m/task.c | 42 |
2 files changed, 42 insertions, 29 deletions
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index 18d8fe6dc8..4eee36f763 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -96,11 +96,21 @@ SECTIONS #endif #ifdef COMPILE_FOR_RAM } > IRAM - __ro_end = . ; - .data : { #else } > FLASH +#endif __ro_end = . ; + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss.tasks) + *(.bss) + . = ALIGN(4); + __bss_end = .; + } > IRAM +#ifdef COMPILE_FOR_RAM + .data : { +#else .data : AT(ADDR(.rodata) + SIZEOF(.rodata)) { #endif . = ALIGN(4); @@ -111,6 +121,10 @@ SECTIONS *(.iram.text) . = ALIGN(4); __data_end = .; + + /* Shared memory buffer must be at the end of preallocated RAM, so it + * can expand to use all the remaining RAM. */ + __shared_mem_buf = .; } > IRAM /* The linker won't notice if the .data section is too big to fit, * apparently because we're sending it into IRAM, not FLASH. The following @@ -127,17 +141,6 @@ SECTIONS *(.google) } #endif - .bss : { - . = ALIGN(4); - __bss_start = .; - *(.bss) - . = ALIGN(4); - __bss_end = .; - - /* Shared memory buffer must be at the end of preallocated RAM, so it - * can expand to use all the remaining RAM. */ - __shared_mem_buf = .; - } > IRAM /DISCARD/ : { *(.ARM.*) } } diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 3041f431c8..4bd194bd78 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -33,9 +33,6 @@ typedef union { uint32_t context[TASK_SIZE/4]; } task_; -#define CONTEXT_SP (__builtin_offsetof(task_, sp) / sizeof(uint32_t)) -#define CONTEXT_GUARD (__builtin_offsetof(task_, guard) / sizeof(uint32_t)) - /* declare task routine prototypes */ #define TASK(n, r, d) int r(void *); #include TASK_LIST @@ -94,24 +91,23 @@ static void task_exit_trap(void) #define GUARD_VALUE 0x12345678 -/* Declare and fill the contexts for all tasks. Note that while it would be - * more readable to use the struct fields (.sp, .guard) where applicable, gcc - * can't mix initializing some fields on one side of the union and some fields - * on the other, so we have to use .context for all initialization. */ -#define TASK(n, r, d) { \ - .context[CONTEXT_SP] = (uint32_t)(tasks + TASK_ID_##n + 1) - 64,\ - .context[CONTEXT_GUARD] = GUARD_VALUE, \ - .context[TASK_SIZE/4 - 8/*r0*/] = (uint32_t)d, \ - .context[TASK_SIZE/4 - 3/*lr*/] = (uint32_t)task_exit_trap, \ - .context[TASK_SIZE/4 - 2/*pc*/] = (uint32_t)r, \ - .context[TASK_SIZE/4 - 1/*psr*/] = 0x01000000 }, +/* Startup parameters for all tasks. */ +#define TASK(n, r, d) { \ + .r0 = (uint32_t)d, \ + .pc = (uint32_t)r, \ +}, #include TASK_LIST -static task_ tasks[] __attribute__((section(".data.tasks"))) - __attribute__((aligned(TASK_SIZE))) = { +static const struct { + uint32_t r0; + uint32_t pc; +} const tasks_init[] = { TASK(IDLE, __idle, 0) CONFIG_TASK_LIST }; #undef TASK +/* Contexts and stacks for all tasks. */ +static task_ tasks[TASK_ID_COUNT] __attribute__((section(".bss.tasks"))) + __attribute__((aligned(TASK_SIZE))); /* Reserve space to discard context on first context switch. */ uint32_t scratchpad[17] __attribute__((section(".data.tasks"))); @@ -561,6 +557,20 @@ DECLARE_CONSOLE_COMMAND(taskready, command_task_ready); int task_pre_init(void) { + int i; + + /* fill the task memory with initial values */ + for (i = 0; i < TASK_ID_COUNT; i++) { + tasks[i].sp = (uint32_t)(tasks + i + 1) - 64; + tasks[i].guard = GUARD_VALUE; + /* initial context on stack */ + tasks[i].context[TASK_SIZE/4 - 8/*r0*/] = tasks_init[i].r0; + tasks[i].context[TASK_SIZE/4 - 3/*lr*/] = + (uint32_t)task_exit_trap; + tasks[i].context[TASK_SIZE/4 - 2/*pc*/] = tasks_init[i].pc; + tasks[i].context[TASK_SIZE/4 - 1/*psr*/] = 0x01000000; + } + /* Fill in guard value in scratchpad to prevent stack overflow * detection failure on the first context switch. */ ((task_ *)scratchpad)->guard = GUARD_VALUE; |