diff options
author | Hyungwoo Yang <hyungwoo.yang@intel.com> | 2019-01-30 12:30:47 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-02-26 05:09:12 -0800 |
commit | decc9452e981a7c8ce5c6b8983061a054057c615 (patch) | |
tree | eaea7bba6491f96bc06a77e2af2fd43d4b210894 /core/minute-ia | |
parent | 0a3f44e4f508d0c6a96519e6db97b2f2fd4bfb23 (diff) | |
download | chrome-ec-decc9452e981a7c8ce5c6b8983061a054057c615.tar.gz |
ish: save/restore FPU context only for the task uses FPU
Currently we save/retore FPU H/W context for every task on
every contxt switch. This hurts overall performance of ISH.
This patch allows save and restore FPU H/W context only for
a task that declares it uses FPU.
BRANCH=none
BUG=none
TEST=verified in Atlas platform
Change-Id: Ic2f0bbf59f655661e2dd788c688edc4e83068c1c
Signed-off-by: Hyungwoo Yang <hyungwoo.yang@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/1448818
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Hyungwoo Yang <hyungwoo.yang@intel.corp-partner.google.com>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'core/minute-ia')
-rw-r--r-- | core/minute-ia/config_core.h | 5 | ||||
-rw-r--r-- | core/minute-ia/irq_handler.h | 14 | ||||
-rw-r--r-- | core/minute-ia/switch.S | 17 | ||||
-rw-r--r-- | core/minute-ia/task.c | 33 | ||||
-rw-r--r-- | core/minute-ia/task_defs.h | 18 |
5 files changed, 73 insertions, 14 deletions
diff --git a/core/minute-ia/config_core.h b/core/minute-ia/config_core.h index 20f4404d38..47121642a4 100644 --- a/core/minute-ia/config_core.h +++ b/core/minute-ia/config_core.h @@ -26,4 +26,9 @@ #define ASM_LOCK_PREFIX #endif +/* + * Flag indicates the task uses FPU H/W + */ +#define MIA_TASK_FLAG_USE_FPU 0x00000001 + #endif /* __CROS_EC_CONFIG_CORE_H */ diff --git a/core/minute-ia/irq_handler.h b/core/minute-ia/irq_handler.h index c561ee472b..4df2b14da6 100644 --- a/core/minute-ia/irq_handler.h +++ b/core/minute-ia/irq_handler.h @@ -9,10 +9,20 @@ #define __CROS_EC_IRQ_HANDLER_H #include "registers.h" +#include "task_defs.h" #ifdef CONFIG_FPU -#define save_fpu_ctx "fnsave 20(%eax)\n" -#define rstr_fpu_ctx "frstor 20(%eax)\n" +#define save_fpu_ctx "movl "USE_FPU_OFFSET_STR"(%eax), %ebx\n" \ + "test %ebx, %ebx\n" \ + "jz 9f\n" \ + "fnsave "FPU_CTX_OFFSET_STR"(%eax)\n" \ + "9:\n" + +#define rstr_fpu_ctx "movl "USE_FPU_OFFSET_STR"(%eax), %ebx\n" \ + "test %ebx, %ebx\n" \ + "jz 9f\n" \ + "frstor "FPU_CTX_OFFSET_STR"(%eax)\n" \ + "9:\n" #else #define save_fpu_ctx #define rstr_fpu_ctx diff --git a/core/minute-ia/switch.S b/core/minute-ia/switch.S index eed2f7929f..27aba1a7cc 100644 --- a/core/minute-ia/switch.S +++ b/core/minute-ia/switch.S @@ -33,7 +33,11 @@ __task_start: movl current_task, %eax movl (%eax), %esp #ifdef CONFIG_FPU - frstor 20(%eax) + movl USE_FPU_OFFSET(%eax), %ebx + test %ebx, %ebx + jz 1f + frstor FPU_CTX_OFFSET(%eax) + 1: #endif movl $0x1, (%ebx) # first task is ready. set start_called = 1 popa @@ -112,7 +116,11 @@ __switchto: movl current_task, %eax #ifdef CONFIG_FPU - fnsave 20(%eax) # Save current FPU context at current->fp_ctx + movl USE_FPU_OFFSET(%eax), %ebx + test %ebx, %ebx + jz 2f + fnsave FPU_CTX_OFFSET(%eax) # Save current FPU context(current->fp_ctx) + 2: #endif # Save SP of current task and switch to new task @@ -122,7 +130,10 @@ __switchto: movl (%eax), %esp #ifdef CONFIG_FPU - frstor 20(%eax) # Restore next FPU context + movl USE_FPU_OFFSET(%eax), %ebx + test %ebx, %ebx + jz 1f + frstor FPU_CTX_OFFSET(%eax) # Restore next FPU context #endif 1: diff --git a/core/minute-ia/task.c b/core/minute-ia/task.c index 2836d40975..9975cc62d7 100644 --- a/core/minute-ia/task.c +++ b/core/minute-ia/task.c @@ -26,7 +26,7 @@ #define STACK_UNUSED_VALUE 0xdeadd00d /* declare task routine prototypes */ -#define TASK(n, r, d, s) void r(void *); +#define TASK(n, r, d, s, f) void r(void *); void __idle(void); CONFIG_TASK_LIST CONFIG_TEST_TASK_LIST @@ -36,7 +36,7 @@ CONFIG_TEST_TASK_LIST extern volatile uint32_t __in_isr; /* Task names for easier debugging */ -#define TASK(n, r, d, s) #n, +#define TASK(n, r, d, s, f) #n, static const char * const task_names[] = { "<< idle >>", CONFIG_TASK_LIST @@ -90,17 +90,19 @@ static void task_exit_trap(void) } /* Startup parameters for all tasks. */ -#define TASK(n, r, d, s) { \ +#define TASK(n, r, d, s, f) { \ .r0 = (uint32_t)d, \ .pc = (uint32_t)r, \ .stack_size = s, \ + .flags = f, \ }, static const struct { uint32_t r0; uint32_t pc; uint16_t stack_size; + uint32_t flags; } tasks_init[] = { - TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE) + TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE, 0) CONFIG_TASK_LIST CONFIG_TEST_TASK_LIST }; @@ -115,9 +117,9 @@ BUILD_ASSERT(TASK_ID_COUNT < (1 << (sizeof(task_id_t) * 8))); /* Stacks for all tasks */ -#define TASK(n, r, d, s) + s +#define TASK(n, r, d, s, f) + s uint8_t task_stacks[0 - TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE) + TASK(IDLE, __idle, 0, IDLE_TASK_STACK_SIZE, 0) CONFIG_TASK_LIST CONFIG_TEST_TASK_LIST ] __aligned(8); @@ -474,10 +476,18 @@ void task_print_list(void) { int i; +#ifdef CONFIG_FPU + ccputs("Task Ready Name Events Time (s) " + " StkUsed UseFPU\n"); +#else ccputs("Task Ready Name Events Time (s) StkUsed\n"); +#endif for (i = 0; i < TASK_ID_COUNT; i++) { char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; +#ifdef CONFIG_FPU + char use_fpu = tasks[i].use_fpu ? 'Y' : 'N'; +#endif uint32_t *sp; int stackused = tasks_init[i].stack_size; @@ -487,9 +497,16 @@ void task_print_list(void) sp++) stackused -= sizeof(uint32_t); +#ifdef CONFIG_FPU + ccprintf("%4d %c %-16s %08x %11.6ld %3d/%3d %c\n", i, is_ready, + task_names[i], tasks[i].events, tasks[i].runtime, + stackused, tasks_init[i].stack_size, use_fpu); +#else ccprintf("%4d %c %-16s %08x %11.6ld %3d/%3d\n", i, is_ready, task_names[i], tasks[i].events, tasks[i].runtime, stackused, tasks_init[i].stack_size); +#endif + cflush(); } } @@ -606,6 +623,9 @@ void task_pre_init(void) /* Copy default x86 FPU state for each task */ memcpy(tasks[i].fp_ctx, default_fp_ctx, sizeof(default_fp_ctx)); + + if (tasks_init[i].flags & MIA_TASK_FLAG_USE_FPU) + tasks[i].use_fpu = 1; #endif /* Fill unused stack; also used to detect stack overflow. */ for (sp = stack_next; sp < (uint32_t *)tasks[i].sp; sp++) @@ -618,7 +638,6 @@ void task_pre_init(void) /* Initialize IRQs */ init_interrupts(); - } void task_clear_fp_used(void) diff --git a/core/minute-ia/task_defs.h b/core/minute-ia/task_defs.h index 2ec33e5c98..15aca6b8b5 100644 --- a/core/minute-ia/task_defs.h +++ b/core/minute-ia/task_defs.h @@ -6,8 +6,21 @@ #ifndef __CROS_EC_TASK_DEFS_H #define __CROS_EC_TASK_DEFS_H -#define FPU_CTX_SZ 108 /* 28 bytes header + 80 bytes registers */ -#define FPU_CTX_OFFSET 20 /* offsetof(task_, fp_ctx) */ +#ifdef CONFIG_FPU +#define FPU_CTX_SZ 108 /* 28 bytes header + 80 bytes registers */ +#define USE_FPU_OFFSET 20 /* offsetof(task_, use_fpu */ +#define FPU_CTX_OFFSET 24 /* offsetof(task_, fp_ctx) */ + +/* + * defines for inline asm + */ +#ifndef __ASSEMBLER__ +#include "common.h" + +#define USE_FPU_OFFSET_STR STRINGIFY(USE_FPU_OFFSET) /* "20" */ +#define FPU_CTX_OFFSET_STR STRINGIFY(FPU_CTX_OFFSET) /* "24" */ +#endif +#endif /* CONFIG_FPU */ #ifndef __ASSEMBLER__ typedef union { @@ -21,6 +34,7 @@ typedef union { uint64_t runtime; /* Time spent in task */ uint32_t *stack; /* Start of stack */ #ifdef CONFIG_FPU + uint32_t use_fpu; /* set if task uses FPU */ uint8_t fp_ctx[FPU_CTX_SZ]; /* x87 FPU context */ #endif }; |