1/*
2 * Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
3 * Copyright 2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 *
6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
8 */
9#ifndef _KERNEL_ARCH_x86_APIC_H
10#define _KERNEL_ARCH_x86_APIC_H
11
12#include <boot/kernel_args.h>
13#include <SupportDefs.h>
14
15#define APIC_ENABLE				0x100
16#define APIC_FOCUS				(~(1 << 9))
17#define APIC_SIV				(0xff)
18
19// offsets to APIC register
20#define APIC_ID							0x020
21#define APIC_VERSION					0x030
22#define APIC_TASK_PRIORITY				0x080
23#define APIC_ARBITRATION_PRIORITY		0x090
24#define APIC_PROCESSOR_PRIORITY			0x0a0
25#define APIC_EOI						0x0b0
26#define APIC_LOGICAL_DEST				0x0d0
27#define APIC_DEST_FORMAT				0x0e0
28#define APIC_SPURIOUS_INTR_VECTOR		0x0f0
29#define APIC_ERROR_STATUS				0x280
30#define APIC_INTR_COMMAND_1				0x300	// bits 0-31
31#define APIC_INTR_COMMAND_2				0x310	// bits 32-63
32#define APIC_LVT_TIMER					0x320
33#define APIC_LVT_THERMAL_SENSOR			0x330
34#define APIC_LVT_PERFMON_COUNTERS		0x340
35#define APIC_LVT_LINT0					0x350
36#define APIC_LVT_LINT1					0x360
37#define APIC_LVT_ERROR					0x370
38#define APIC_INITIAL_TIMER_COUNT		0x380
39#define APIC_CURRENT_TIMER_COUNT		0x390
40#define APIC_TIMER_DIVIDE_CONFIG		0x3e0
41
42/* standard APIC interrupt defines */
43#define APIC_DELIVERY_MODE_FIXED				0
44#define APIC_DELIVERY_MODE_LOWESTPRI			(1 << 8)	// ICR1 only
45#define APIC_DELIVERY_MODE_SMI					(2 << 8)
46#define APIC_DELIVERY_MODE_NMI					(4 << 8)
47#define APIC_DELIVERY_MODE_INIT					(5 << 8)
48#define APIC_DELIVERY_MODE_STARTUP				(6 << 8)	// ICR1 only
49#define APIC_DELIVERY_MODE_ExtINT				(7 << 8)	// LINT0/1 only
50
51#define APIC_DELIVERY_STATUS					(1 << 12)
52#define APIC_TRIGGER_MODE_LEVEL					(1 << 15)
53
54/* Interrupt Command defines */
55#define APIC_INTR_COMMAND_1_MASK				0xfff32000
56#define APIC_INTR_COMMAND_2_MASK				0x00ffffff
57
58#define APIC_INTR_COMMAND_1_DEST_MODE_PHYSICAL	0
59#define APIC_INTR_COMMAND_1_DEST_MODE_LOGICAL	(1 << 11)
60
61#define APIC_INTR_COMMAND_1_ASSERT				(1 << 14)
62
63#define APIC_INTR_COMMAND_1_DEST_FIELD			0
64#define APIC_INTR_COMMAND_1_DEST_SELF			(1 << 18)
65#define APIC_INTR_COMMAND_1_DEST_ALL			(2 << 18)
66#define APIC_INTR_COMMAND_1_DEST_ALL_BUT_SELF	(3 << 18)
67
68/* Local Vector Table defines */
69#define APIC_LVT_MASKED							(1 << 16)
70
71// timer defines
72#define APIC_LVT_TIMER_MASK						0xfffcef00
73
74// LINT0/1 defines
75#define APIC_LVT_LINT_MASK						0xfffe0800
76#define APIC_LVT_LINT_INPUT_POLARITY			(1 << 13)
77
78// Timer Divide Config Divisors
79#define APIC_TIMER_DIVIDE_CONFIG_1				0x0b
80#define APIC_TIMER_DIVIDE_CONFIG_2				0x00
81#define APIC_TIMER_DIVIDE_CONFIG_4				0x01
82#define APIC_TIMER_DIVIDE_CONFIG_8				0x02
83#define APIC_TIMER_DIVIDE_CONFIG_16				0x03
84#define APIC_TIMER_DIVIDE_CONFIG_32				0x08
85#define APIC_TIMER_DIVIDE_CONFIG_64				0x09
86#define APIC_TIMER_DIVIDE_CONFIG_128			0x0a
87
88/*
89#define APIC_LVT_DM				0x00000700
90#define APIC_LVT_DM_ExtINT		0x00000700
91#define APIC_LVT_DM_NMI			0x00000400
92#define APIC_LVT_IIPP			0x00002000
93#define APIC_LVT_TM				0x00008000
94#define APIC_LVT_M				0x00010000
95#define APIC_LVT_OS				0x00020000
96
97#define APIC_TPR_PRIO			0x000000ff
98#define APIC_TPR_INT			0x000000f0
99#define APIC_TPR_SUB			0x0000000f
100
101#define APIC_SVR_SWEN			0x00000100
102#define APIC_SVR_FOCUS			0x00000200
103
104#define IOAPIC_ID				0x0
105#define IOAPIC_VERSION			0x1
106#define IOAPIC_ARB				0x2
107#define IOAPIC_REDIR_TABLE		0x10
108*/
109
110#if !_BOOT_MODE
111
112bool		apic_available();
113bool		x2apic_available();
114uint32		apic_read(uint32 offset);
115void		apic_write(uint32 offset, uint32 data);
116uint32		apic_local_id();
117uint32		apic_local_version();
118uint32		apic_task_priority();
119void		apic_set_task_priority(uint32 config);
120void		apic_end_of_interrupt();
121
122void		apic_disable_local_ints();
123
124uint32		apic_spurious_intr_vector();
125void		apic_set_spurious_intr_vector(uint32 config);
126
127void		apic_set_interrupt_command(uint32 destination, uint32 mode);
128bool		apic_interrupt_delivered(void);
129
130uint32		apic_lvt_timer();
131void		apic_set_lvt_timer(uint32 config);
132uint32		apic_lvt_error();
133void		apic_set_lvt_error(uint32 config);
134uint32		apic_lvt_initial_timer_count();
135void		apic_set_lvt_initial_timer_count(uint32 config);
136uint32		apic_lvt_timer_divide_config();
137void		apic_set_lvt_timer_divide_config(uint32 config);
138
139status_t	apic_init(kernel_args *args);
140status_t	apic_per_cpu_init(kernel_args *args, int32 cpu);
141
142#endif // !_BOOT_MODE
143
144#endif	/* _KERNEL_ARCH_x86_APIC_H */
145