summaryrefslogtreecommitdiff
path: root/core/minute-ia/task.c
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/task.c
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/task.c')
-rw-r--r--core/minute-ia/task.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/core/minute-ia/task.c b/core/minute-ia/task.c
index 8c3d9fd9f2..18c23f5515 100644
--- a/core/minute-ia/task.c
+++ b/core/minute-ia/task.c
@@ -261,11 +261,9 @@ uint32_t switch_handler(int desched, task_id_t resched)
void __schedule(int desched, int resched)
{
- __asm__ __volatile__ ("int %0"
- :
- : "i" (ISH_TS_VECTOR),
- "d" (desched), "c" (resched)
- );
+ __asm__ __volatile__("int %0"
+ :
+ : "i"(ISH_TS_VECTOR), "d"(desched), "c"(resched));
}
#ifdef CONFIG_TASK_PROFILING
@@ -276,15 +274,14 @@ void __keep task_start_irq_handler(void *data)
* pre-empted.
*/
uint32_t t = get_time().le.lo;
- uint32_t vector = (uint32_t)data;
- int irq = VEC_TO_IRQ(vector);
+ int irq = (uint32_t)data;
/*
* Track IRQ distribution. No need for atomic add, because an IRQ
* can't pre-empt itself. If less than 0, then the vector did not map
* to an IRQ but was for a synchronous exception instead (TS_VECTOR)
*/
- if (irq > 0 && irq < ARRAY_SIZE(irq_dist))
+ if (irq < CONFIG_IRQ_COUNT)
irq_dist[irq]++;
else
/* Track total number of service calls */
@@ -420,11 +417,20 @@ void task_clear_pending_irq(int irq)
void task_trigger_irq(int irq)
{
- /* Writing to Local APIC Interrupt Command Register (ICR) causes an
- * IPI (Inter-processor interrupt) on the APIC bus. Here we direct the
- * IPI to originating prccessor to generate self-interrupt
+ /* ISR should not be called before the first task is scheduled */
+ if (!task_start_called())
+ return;
+
+ /* we don't allow nested interrupt */
+ if (in_interrupt_context())
+ return;
+
+ /*
+ * "int" instruction accepts vector only as immediate value.
+ * so here, we use one vector(SOFTIRQ_VECTOR) and pass
+ * the address of ISR of irq in ecx register.
*/
- REG32(LAPIC_ICR_REG) = LAPIC_ICR_BITS | IRQ_TO_VEC(irq);
+ __asm__ __volatile__("int %0\n" : : "i"(SOFTIRQ_VECTOR), "c"(irq));
}
void mutex_lock(struct mutex *mtx)