summaryrefslogtreecommitdiff
path: root/core/minute-ia/irq_handler.h
blob: deb8048e123b432a1297d57a6ef115c87b2d9ac7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* Copyright 2016 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Helper to declare IRQ handling routines */

#ifndef __CROS_EC_IRQ_HANDLER_H
#define __CROS_EC_IRQ_HANDLER_H

#include "registers.h"
#include "task.h"
#include "task_defs.h"

asm(".include \"core/minute-ia/irq_handler_common.S\"");

/* Helper macros to build the IRQ handler and priority struct names */
#define IRQ_HANDLER(irqname) CONCAT3(_irq_, irqname, _handler)
#define IRQ_PRIORITY(irqname) CONCAT2(prio_, irqname)
/*
 * Macro to connect the interrupt handler "routine" to the irq number "irq" and
 * ensure it is enabled in the interrupt controller with the right priority.
 *
 * Note: No 'naked' function support for x86, so function is implemented within
 * __asm__
 * Note: currently we don't allow nested irq handling
 */
#define DECLARE_IRQ(irq, routine) DECLARE_IRQ_(irq, routine, irq + 32 + 10)
/*
 * Each irq has a irq_data structure placed in .rodata.irqs section,
 * to be used for dynamically setting up interrupt gates
 */
#define DECLARE_IRQ_(irq_, routine_, vector)                                                    \
	static void __keep routine_(void);                                                      \
	void IRQ_HANDLER(irq_)(void);                                                           \
	__asm__(".section .rodata.irqs\n");                                                     \
	const struct irq_def __keep CONCAT4(__irq_, irq_, _, routine_)                          \
		__attribute__((section(                                                         \
			".rodata.irqs"))) = { .irq = irq_,                                      \
					      .routine = routine_,                              \
					      .handler = IRQ_HANDLER(irq_) };                   \
	__asm__(".section .text._irq_" #irq_ "_handler\n"                                       \
		"_irq_" #irq_ "_handler:\n"                                                     \
		"pusha\n" ASM_LOCK_PREFIX "addl  $1, __in_isr\n"                                \
		"irq_handler_common $0 $0 $" #irq_ "\n"                                         \
		"movl $" #vector ", " STRINGIFY(                                                \
			IOAPIC_EOI_REG_ADDR) "\n"                                               \
					     "movl $0x00, " STRINGIFY(                          \
						     LAPIC_EOI_REG_ADDR) "\n" ASM_LOCK_PREFIX   \
									 "subl  $1, __in_isr\n" \
									 "popa\n"               \
									 "iret\n")
#endif /* __CROS_EC_IRQ_HANDLER_H */