#include "archconst.h"
#include "apic.h"
#include "sconst.h"
#include "apic_asm.h"
#include <machine/asm.h>

#define APIC_IRQ_HANDLER(irq)	\
	push	$irq						;\
	call	_C_LABEL(irq_handle)		/* intr_handle(irq) */	;\
	add	$4, %esp					;

/*===========================================================================*/
/*				interrupt handlers			     */
/*		interrupt handlers for 386 32-bit protected mode	     */
/*		APIC interrupt handlers for 386 32-bit protected mode	     */
/*===========================================================================*/
#define apic_hwint(irq)							\
ENTRY(apic_hwint##irq)							\
	TEST_INT_IN_KERNEL(4, 0f)					;\
									\
	SAVE_PROCESS_CTX(0, KTS_INT_HARD)				;\
	push	%ebp							;\
	call	_C_LABEL(context_stop)					;\
	add	$4, %esp						;\
	movl	$0, %ebp	/* for stack trace */			;\
	APIC_IRQ_HANDLER(irq)						;\
	jmp	_C_LABEL(switch_to_user)				;\
									\
0:									\
	pusha								;\
	call	_C_LABEL(context_stop_idle)				;\
	APIC_IRQ_HANDLER(irq)						;\
	CLEAR_IF(10*4(%esp))						;\
	popa								;\
	iret								;

#define LAPIC_INTR_HANDLER(func)	\
	movl	$func, %eax						;\
	call	*%eax           /* call the actual handler */		;\
	mov	_C_LABEL(lapic_eoi_addr), %eax	/* the end of handler*/	;\
	movl	$0, (%eax)						;

/*===========================================================================*/
/*			handler of the local APIC interrupts		     */
/*===========================================================================*/

#define lapic_intr(func) \
	TEST_INT_IN_KERNEL(4, 0f)					;\
									\
	SAVE_PROCESS_CTX(0, KTS_INT_HARD)				;\
	push	%ebp							;\
	call	_C_LABEL(context_stop)					;\
	add	$4, %esp						;\
	movl	$0, %ebp		/* for stack trace */		;\
	LAPIC_INTR_HANDLER(func)					;\
	jmp	_C_LABEL(switch_to_user)				;\
	\
0:	\
	pusha								;\
	call	_C_LABEL(context_stop_idle)				;\
	LAPIC_INTR_HANDLER(func)					;\
	CLEAR_IF(10*4(%esp))						;\
	popa								;\
	iret								;

/* apic timer tick handlers */
ENTRY(lapic_timer_int_handler)
	lapic_intr(_C_LABEL(timer_int_handler))

ENTRY(apic_spurios_intr)
	lapic_intr(_C_LABEL(apic_spurios_intr_handler))

ENTRY(apic_error_intr)
	lapic_intr(_C_LABEL(apic_error_intr_handler))

#ifdef CONFIG_SMP

ENTRY(apic_ipi_sched_intr)
	lapic_intr(_C_LABEL(smp_ipi_sched_handler))

ENTRY(apic_ipi_halt_intr)
	lapic_intr(_C_LABEL(smp_ipi_halt_handler))

#endif /* CONFIG_SMP */

#ifdef APIC_DEBUG

.data
lapic_intr_dummy_handler_msg:
.ascii "UNHANDLED APIC interrupt vector %d\n"

.text

#define lapic_intr_dummy_handler(vect)			\
	pushl	$vect;					\
	push	$lapic_intr_dummy_handler_msg;		\
	call	_C_LABEL(panic);			\
1:	jmp	1b; /* never return */

#define LAPIC_INTR_DUMMY_HANDLER(vect)			\
	.balign	LAPIC_INTR_DUMMY_HANDLER_SIZE;		\
	_lapic_intr_dummy_handler_##vect: lapic_intr_dummy_handler(vect)

apic_hwint(0)
apic_hwint(1)
apic_hwint(2)
apic_hwint(3)
apic_hwint(4)
apic_hwint(5)
apic_hwint(6)
apic_hwint(7)
apic_hwint(8)
apic_hwint(9)
apic_hwint(10)
apic_hwint(11)
apic_hwint(12)
apic_hwint(13)
apic_hwint(14)
apic_hwint(15)
apic_hwint(16)
apic_hwint(17)
apic_hwint(18)
apic_hwint(19)
apic_hwint(20)
apic_hwint(21)
apic_hwint(22)
apic_hwint(23)
apic_hwint(24)
apic_hwint(25)
apic_hwint(26)
apic_hwint(27)
apic_hwint(28)
apic_hwint(29)
apic_hwint(30)
apic_hwint(31)
apic_hwint(32)
apic_hwint(33)
apic_hwint(34)
apic_hwint(35)
apic_hwint(36)
apic_hwint(37)
apic_hwint(38)
apic_hwint(39)
apic_hwint(40)
apic_hwint(41)
apic_hwint(42)
apic_hwint(43)
apic_hwint(44)
apic_hwint(45)
apic_hwint(46)
apic_hwint(47)
apic_hwint(48)
apic_hwint(49)
apic_hwint(50)
apic_hwint(51)
apic_hwint(52)
apic_hwint(53)
apic_hwint(54)
apic_hwint(55)
apic_hwint(56)
apic_hwint(57)
apic_hwint(58)
apic_hwint(59)
apic_hwint(60)
apic_hwint(61)
apic_hwint(62)
apic_hwint(63)

LABEL(lapic_intr_dummy_handles_start)
	LAPIC_INTR_DUMMY_HANDLER(0)
	LAPIC_INTR_DUMMY_HANDLER(1)
	LAPIC_INTR_DUMMY_HANDLER(2)
	LAPIC_INTR_DUMMY_HANDLER(3)
	LAPIC_INTR_DUMMY_HANDLER(4)
	LAPIC_INTR_DUMMY_HANDLER(5)
	LAPIC_INTR_DUMMY_HANDLER(6)
	LAPIC_INTR_DUMMY_HANDLER(7)
	LAPIC_INTR_DUMMY_HANDLER(8)
	LAPIC_INTR_DUMMY_HANDLER(9)
	LAPIC_INTR_DUMMY_HANDLER(10)
	LAPIC_INTR_DUMMY_HANDLER(11)
	LAPIC_INTR_DUMMY_HANDLER(12)
	LAPIC_INTR_DUMMY_HANDLER(13)
	LAPIC_INTR_DUMMY_HANDLER(14)
	LAPIC_INTR_DUMMY_HANDLER(15)
	LAPIC_INTR_DUMMY_HANDLER(16)
	LAPIC_INTR_DUMMY_HANDLER(17)
	LAPIC_INTR_DUMMY_HANDLER(18)
	LAPIC_INTR_DUMMY_HANDLER(19)
	LAPIC_INTR_DUMMY_HANDLER(20)
	LAPIC_INTR_DUMMY_HANDLER(21)
	LAPIC_INTR_DUMMY_HANDLER(22)
	LAPIC_INTR_DUMMY_HANDLER(23)
	LAPIC_INTR_DUMMY_HANDLER(24)
	LAPIC_INTR_DUMMY_HANDLER(25)
	LAPIC_INTR_DUMMY_HANDLER(26)
	LAPIC_INTR_DUMMY_HANDLER(27)
	LAPIC_INTR_DUMMY_HANDLER(28)
	LAPIC_INTR_DUMMY_HANDLER(29)
	LAPIC_INTR_DUMMY_HANDLER(30)
	LAPIC_INTR_DUMMY_HANDLER(31)
	LAPIC_INTR_DUMMY_HANDLER(32)
	LAPIC_INTR_DUMMY_HANDLER(33)
	LAPIC_INTR_DUMMY_HANDLER(34)
	LAPIC_INTR_DUMMY_HANDLER(35)
	LAPIC_INTR_DUMMY_HANDLER(36)
	LAPIC_INTR_DUMMY_HANDLER(37)
	LAPIC_INTR_DUMMY_HANDLER(38)
	LAPIC_INTR_DUMMY_HANDLER(39)
	LAPIC_INTR_DUMMY_HANDLER(40)
	LAPIC_INTR_DUMMY_HANDLER(41)
	LAPIC_INTR_DUMMY_HANDLER(42)
	LAPIC_INTR_DUMMY_HANDLER(43)
	LAPIC_INTR_DUMMY_HANDLER(44)
	LAPIC_INTR_DUMMY_HANDLER(45)
	LAPIC_INTR_DUMMY_HANDLER(46)
	LAPIC_INTR_DUMMY_HANDLER(47)
	LAPIC_INTR_DUMMY_HANDLER(48)
	LAPIC_INTR_DUMMY_HANDLER(49)
	LAPIC_INTR_DUMMY_HANDLER(50)
	LAPIC_INTR_DUMMY_HANDLER(51)
	LAPIC_INTR_DUMMY_HANDLER(52)
	LAPIC_INTR_DUMMY_HANDLER(53)
	LAPIC_INTR_DUMMY_HANDLER(54)
	LAPIC_INTR_DUMMY_HANDLER(55)
	LAPIC_INTR_DUMMY_HANDLER(56)
	LAPIC_INTR_DUMMY_HANDLER(57)
	LAPIC_INTR_DUMMY_HANDLER(58)
	LAPIC_INTR_DUMMY_HANDLER(59)
	LAPIC_INTR_DUMMY_HANDLER(60)
	LAPIC_INTR_DUMMY_HANDLER(61)
	LAPIC_INTR_DUMMY_HANDLER(62)
	LAPIC_INTR_DUMMY_HANDLER(63)
	LAPIC_INTR_DUMMY_HANDLER(64)
	LAPIC_INTR_DUMMY_HANDLER(65)
	LAPIC_INTR_DUMMY_HANDLER(66)
	LAPIC_INTR_DUMMY_HANDLER(67)
	LAPIC_INTR_DUMMY_HANDLER(68)
	LAPIC_INTR_DUMMY_HANDLER(69)
	LAPIC_INTR_DUMMY_HANDLER(70)
	LAPIC_INTR_DUMMY_HANDLER(71)
	LAPIC_INTR_DUMMY_HANDLER(72)
	LAPIC_INTR_DUMMY_HANDLER(73)
	LAPIC_INTR_DUMMY_HANDLER(74)
	LAPIC_INTR_DUMMY_HANDLER(75)
	LAPIC_INTR_DUMMY_HANDLER(76)
	LAPIC_INTR_DUMMY_HANDLER(77)
	LAPIC_INTR_DUMMY_HANDLER(78)
	LAPIC_INTR_DUMMY_HANDLER(79)
	LAPIC_INTR_DUMMY_HANDLER(80)
	LAPIC_INTR_DUMMY_HANDLER(81)
	LAPIC_INTR_DUMMY_HANDLER(82)
	LAPIC_INTR_DUMMY_HANDLER(83)
	LAPIC_INTR_DUMMY_HANDLER(84)
	LAPIC_INTR_DUMMY_HANDLER(85)
	LAPIC_INTR_DUMMY_HANDLER(86)
	LAPIC_INTR_DUMMY_HANDLER(87)
	LAPIC_INTR_DUMMY_HANDLER(88)
	LAPIC_INTR_DUMMY_HANDLER(89)
	LAPIC_INTR_DUMMY_HANDLER(90)
	LAPIC_INTR_DUMMY_HANDLER(91)
	LAPIC_INTR_DUMMY_HANDLER(92)
	LAPIC_INTR_DUMMY_HANDLER(93)
	LAPIC_INTR_DUMMY_HANDLER(94)
	LAPIC_INTR_DUMMY_HANDLER(95)
	LAPIC_INTR_DUMMY_HANDLER(96)
	LAPIC_INTR_DUMMY_HANDLER(97)
	LAPIC_INTR_DUMMY_HANDLER(98)
	LAPIC_INTR_DUMMY_HANDLER(99)
	LAPIC_INTR_DUMMY_HANDLER(100)
	LAPIC_INTR_DUMMY_HANDLER(101)
	LAPIC_INTR_DUMMY_HANDLER(102)
	LAPIC_INTR_DUMMY_HANDLER(103)
	LAPIC_INTR_DUMMY_HANDLER(104)
	LAPIC_INTR_DUMMY_HANDLER(105)
	LAPIC_INTR_DUMMY_HANDLER(106)
	LAPIC_INTR_DUMMY_HANDLER(107)
	LAPIC_INTR_DUMMY_HANDLER(108)
	LAPIC_INTR_DUMMY_HANDLER(109)
	LAPIC_INTR_DUMMY_HANDLER(110)
	LAPIC_INTR_DUMMY_HANDLER(111)
	LAPIC_INTR_DUMMY_HANDLER(112)
	LAPIC_INTR_DUMMY_HANDLER(113)
	LAPIC_INTR_DUMMY_HANDLER(114)
	LAPIC_INTR_DUMMY_HANDLER(115)
	LAPIC_INTR_DUMMY_HANDLER(116)
	LAPIC_INTR_DUMMY_HANDLER(117)
	LAPIC_INTR_DUMMY_HANDLER(118)
	LAPIC_INTR_DUMMY_HANDLER(119)
	LAPIC_INTR_DUMMY_HANDLER(120)
	LAPIC_INTR_DUMMY_HANDLER(121)
	LAPIC_INTR_DUMMY_HANDLER(122)
	LAPIC_INTR_DUMMY_HANDLER(123)
	LAPIC_INTR_DUMMY_HANDLER(124)
	LAPIC_INTR_DUMMY_HANDLER(125)
	LAPIC_INTR_DUMMY_HANDLER(126)
	LAPIC_INTR_DUMMY_HANDLER(127)
	LAPIC_INTR_DUMMY_HANDLER(128)
	LAPIC_INTR_DUMMY_HANDLER(129)
	LAPIC_INTR_DUMMY_HANDLER(130)
	LAPIC_INTR_DUMMY_HANDLER(131)
	LAPIC_INTR_DUMMY_HANDLER(132)
	LAPIC_INTR_DUMMY_HANDLER(133)
	LAPIC_INTR_DUMMY_HANDLER(134)
	LAPIC_INTR_DUMMY_HANDLER(135)
	LAPIC_INTR_DUMMY_HANDLER(136)
	LAPIC_INTR_DUMMY_HANDLER(137)
	LAPIC_INTR_DUMMY_HANDLER(138)
	LAPIC_INTR_DUMMY_HANDLER(139)
	LAPIC_INTR_DUMMY_HANDLER(140)
	LAPIC_INTR_DUMMY_HANDLER(141)
	LAPIC_INTR_DUMMY_HANDLER(142)
	LAPIC_INTR_DUMMY_HANDLER(143)
	LAPIC_INTR_DUMMY_HANDLER(144)
	LAPIC_INTR_DUMMY_HANDLER(145)
	LAPIC_INTR_DUMMY_HANDLER(146)
	LAPIC_INTR_DUMMY_HANDLER(147)
	LAPIC_INTR_DUMMY_HANDLER(148)
	LAPIC_INTR_DUMMY_HANDLER(149)
	LAPIC_INTR_DUMMY_HANDLER(150)
	LAPIC_INTR_DUMMY_HANDLER(151)
	LAPIC_INTR_DUMMY_HANDLER(152)
	LAPIC_INTR_DUMMY_HANDLER(153)
	LAPIC_INTR_DUMMY_HANDLER(154)
	LAPIC_INTR_DUMMY_HANDLER(155)
	LAPIC_INTR_DUMMY_HANDLER(156)
	LAPIC_INTR_DUMMY_HANDLER(157)
	LAPIC_INTR_DUMMY_HANDLER(158)
	LAPIC_INTR_DUMMY_HANDLER(159)
	LAPIC_INTR_DUMMY_HANDLER(160)
	LAPIC_INTR_DUMMY_HANDLER(161)
	LAPIC_INTR_DUMMY_HANDLER(162)
	LAPIC_INTR_DUMMY_HANDLER(163)
	LAPIC_INTR_DUMMY_HANDLER(164)
	LAPIC_INTR_DUMMY_HANDLER(165)
	LAPIC_INTR_DUMMY_HANDLER(166)
	LAPIC_INTR_DUMMY_HANDLER(167)
	LAPIC_INTR_DUMMY_HANDLER(168)
	LAPIC_INTR_DUMMY_HANDLER(169)
	LAPIC_INTR_DUMMY_HANDLER(170)
	LAPIC_INTR_DUMMY_HANDLER(171)
	LAPIC_INTR_DUMMY_HANDLER(172)
	LAPIC_INTR_DUMMY_HANDLER(173)
	LAPIC_INTR_DUMMY_HANDLER(174)
	LAPIC_INTR_DUMMY_HANDLER(175)
	LAPIC_INTR_DUMMY_HANDLER(176)
	LAPIC_INTR_DUMMY_HANDLER(177)
	LAPIC_INTR_DUMMY_HANDLER(178)
	LAPIC_INTR_DUMMY_HANDLER(179)
	LAPIC_INTR_DUMMY_HANDLER(180)
	LAPIC_INTR_DUMMY_HANDLER(181)
	LAPIC_INTR_DUMMY_HANDLER(182)
	LAPIC_INTR_DUMMY_HANDLER(183)
	LAPIC_INTR_DUMMY_HANDLER(184)
	LAPIC_INTR_DUMMY_HANDLER(185)
	LAPIC_INTR_DUMMY_HANDLER(186)
	LAPIC_INTR_DUMMY_HANDLER(187)
	LAPIC_INTR_DUMMY_HANDLER(188)
	LAPIC_INTR_DUMMY_HANDLER(189)
	LAPIC_INTR_DUMMY_HANDLER(190)
	LAPIC_INTR_DUMMY_HANDLER(191)
	LAPIC_INTR_DUMMY_HANDLER(192)
	LAPIC_INTR_DUMMY_HANDLER(193)
	LAPIC_INTR_DUMMY_HANDLER(194)
	LAPIC_INTR_DUMMY_HANDLER(195)
	LAPIC_INTR_DUMMY_HANDLER(196)
	LAPIC_INTR_DUMMY_HANDLER(197)
	LAPIC_INTR_DUMMY_HANDLER(198)
	LAPIC_INTR_DUMMY_HANDLER(199)
	LAPIC_INTR_DUMMY_HANDLER(200)
	LAPIC_INTR_DUMMY_HANDLER(201)
	LAPIC_INTR_DUMMY_HANDLER(202)
	LAPIC_INTR_DUMMY_HANDLER(203)
	LAPIC_INTR_DUMMY_HANDLER(204)
	LAPIC_INTR_DUMMY_HANDLER(205)
	LAPIC_INTR_DUMMY_HANDLER(206)
	LAPIC_INTR_DUMMY_HANDLER(207)
	LAPIC_INTR_DUMMY_HANDLER(208)
	LAPIC_INTR_DUMMY_HANDLER(209)
	LAPIC_INTR_DUMMY_HANDLER(210)
	LAPIC_INTR_DUMMY_HANDLER(211)
	LAPIC_INTR_DUMMY_HANDLER(212)
	LAPIC_INTR_DUMMY_HANDLER(213)
	LAPIC_INTR_DUMMY_HANDLER(214)
	LAPIC_INTR_DUMMY_HANDLER(215)
	LAPIC_INTR_DUMMY_HANDLER(216)
	LAPIC_INTR_DUMMY_HANDLER(217)
	LAPIC_INTR_DUMMY_HANDLER(218)
	LAPIC_INTR_DUMMY_HANDLER(219)
	LAPIC_INTR_DUMMY_HANDLER(220)
	LAPIC_INTR_DUMMY_HANDLER(221)
	LAPIC_INTR_DUMMY_HANDLER(222)
	LAPIC_INTR_DUMMY_HANDLER(223)
	LAPIC_INTR_DUMMY_HANDLER(224)
	LAPIC_INTR_DUMMY_HANDLER(225)
	LAPIC_INTR_DUMMY_HANDLER(226)
	LAPIC_INTR_DUMMY_HANDLER(227)
	LAPIC_INTR_DUMMY_HANDLER(228)
	LAPIC_INTR_DUMMY_HANDLER(229)
	LAPIC_INTR_DUMMY_HANDLER(230)
	LAPIC_INTR_DUMMY_HANDLER(231)
	LAPIC_INTR_DUMMY_HANDLER(232)
	LAPIC_INTR_DUMMY_HANDLER(233)
	LAPIC_INTR_DUMMY_HANDLER(234)
	LAPIC_INTR_DUMMY_HANDLER(235)
	LAPIC_INTR_DUMMY_HANDLER(236)
	LAPIC_INTR_DUMMY_HANDLER(237)
	LAPIC_INTR_DUMMY_HANDLER(238)
	LAPIC_INTR_DUMMY_HANDLER(239)
	LAPIC_INTR_DUMMY_HANDLER(240)
	LAPIC_INTR_DUMMY_HANDLER(241)
	LAPIC_INTR_DUMMY_HANDLER(242)
	LAPIC_INTR_DUMMY_HANDLER(243)
	LAPIC_INTR_DUMMY_HANDLER(244)
	LAPIC_INTR_DUMMY_HANDLER(245)
	LAPIC_INTR_DUMMY_HANDLER(246)
	LAPIC_INTR_DUMMY_HANDLER(247)
	LAPIC_INTR_DUMMY_HANDLER(248)
	LAPIC_INTR_DUMMY_HANDLER(249)
	LAPIC_INTR_DUMMY_HANDLER(250)
	LAPIC_INTR_DUMMY_HANDLER(251)
	LAPIC_INTR_DUMMY_HANDLER(252)
	LAPIC_INTR_DUMMY_HANDLER(253)
	LAPIC_INTR_DUMMY_HANDLER(254)
	LAPIC_INTR_DUMMY_HANDLER(255)
LABEL(lapic_intr_dummy_handles_end)


#endif /* APIC_DEBUG */
