summaryrefslogtreecommitdiff
path: root/core/minute-ia/irq_handler_common.S
diff options
context:
space:
mode:
authorHyungwoo Yang <hyungwoo.yang@intel.com>2019-04-15 22:17:11 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-04-26 04:19:18 -0700
commitf730c0c1ab2cadb820676ef09ebb57888d48cb96 (patch)
tree8953f42e6776f828c0f55cc2c01d44c087a43511 /core/minute-ia/irq_handler_common.S
parent6549da39d519b4d07e8bca7bef0393549765412b (diff)
downloadchrome-ec-f730c0c1ab2cadb820676ef09ebb57888d48cb96.tar.gz
ish: fix s/w generated interrupt request
Current s/w generated IRQ uses LAPIC's ICR but it causes pending interrupts for other IRQs in IOAPIC and leads LVT error with illegal vector. So instead of using ICR, we use "int" instruction. BRANCH=none BUG=b:129937881,b:124128140 TEST=Tested on Arcada platform Change-Id: I49c4120e7355f9a98d20d5ed259c4fdf6bad5196 Signed-off-by: Hyungwoo Yang <hyungwoo.yang@intel.com> Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1568786 Commit-Ready: Jack Rosenthal <jrosenth@chromium.org> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Diffstat (limited to 'core/minute-ia/irq_handler_common.S')
-rw-r--r--core/minute-ia/irq_handler_common.S68
1 files changed, 68 insertions, 0 deletions
diff --git a/core/minute-ia/irq_handler_common.S b/core/minute-ia/irq_handler_common.S
new file mode 100644
index 0000000000..e07cf26ce1
--- /dev/null
+++ b/core/minute-ia/irq_handler_common.S
@@ -0,0 +1,68 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * x86 task swtching and interrupt handling
+ */
+
+#include "config.h"
+#include "registers.h"
+#include "task_defs.h"
+
+# desched resched irq are all inputs and should be set to registers or immediate
+# values
+.macro irq_handler_common desched resched irq
+ # __schedule() copies 'resched' to %ecx and 'desched' to %edx before
+ movl %esp, %eax
+ movl $stack_end, %esp # use system stack
+ push %eax # push sp of preempted context
+
+ # Push resched and desched on stack to pass them as function parameters
+ # to switch_handler(desched, resched). After call, we clean up stack
+ # pointer. Note, we do this now before call_irq_service_routine has a
+ # chance to clobber these caller-saved registers.
+ push \resched
+ push \desched
+
+ push \irq
+#ifdef CONFIG_TASK_PROFILING
+ call task_start_irq_handler
+#endif
+ # Leave IRQ on stack for handler
+ call call_irq_service_routine
+ addl $0x04, %esp
+
+ # Call switch_handler(desched, resched).
+ call switch_handler # switch task if needed
+ addl $0x08, %esp
+
+ pop %esp # restore sp of preempted context
+
+ test %eax, %eax # Check if task switch required
+ jz 1f
+
+ movl current_task, %eax
+
+#ifdef CONFIG_FPU
+ movl USE_FPU_OFFSET(%eax), %ecx
+ test %ecx, %ecx
+ 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
+ movl %esp, (%eax)
+ movl next_task, %eax
+ movl %eax, current_task
+ movl (%eax), %esp
+
+#ifdef CONFIG_FPU
+ movl USE_FPU_OFFSET(%eax), %ecx
+ test %ecx, %ecx
+ jz 1f
+ frstor FPU_CTX_OFFSET(%eax) # Restore next FPU context
+#endif
+
+ 1:
+.endm