[CLT2012]
[reactos.git] / hal / halx86 / apic / apic.h
1
2 #ifdef _M_AMD64
3 #define IOAPIC_BASE 0xFFFFFFFFFFFE1000ULL // checkme
4 #define ZERO_VECTOR 0x00 // IRQL 00
5 #define APC_VECTOR 0x3D // IRQL 01
6 #define APIC_SPURIOUS_VECTOR 0x3f
7 #define DISPATCH_VECTOR 0x41 // IRQL 02
8 #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27
9 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28
10 #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28
11 #define APIC_IPI_VECTOR 0xE1 // IRQL 29
12 #define APIC_ERROR_VECTOR 0xE3
13 #define POWERFAIL_VECTOR 0xEF // IRQL 30
14 #define APIC_PROFILE_VECTOR 0xFD // IRQL 31
15 #define APIC_NMI_VECTOR 0xFF
16 #define IrqlToTpr(Irql) (Irql << 4)
17 #define TprToIrql(Tpr) ((KIRQL)(Tpr >> 4))
18 #define CLOCK2_LEVEL CLOCK_LEVEL
19 #else
20 #define IOAPIC_BASE 0xFFFE1000 // checkme
21 #define ZERO_VECTOR 0x00 // IRQL 00
22 #define APIC_SPURIOUS_VECTOR 0x1f
23 #define APC_VECTOR 0x3D // IRQL 01
24 #define DISPATCH_VECTOR 0x41 // IRQL 02
25 #define APIC_GENERIC_VECTOR 0xC1 // IRQL 27
26 #define APIC_CLOCK_VECTOR 0xD1 // IRQL 28
27 #define APIC_SYNCH_VECTOR 0xD1 // IRQL 28
28 #define APIC_IPI_VECTOR 0xE1 // IRQL 29
29 #define APIC_ERROR_VECTOR 0xE3
30 #define POWERFAIL_VECTOR 0xEF // IRQL 30
31 #define APIC_PROFILE_VECTOR 0xFD // IRQL 31
32 #define APIC_NMI_VECTOR 0xFF
33 #define IrqlToTpr(Irql) (HalpIRQLtoTPR[Irql])
34 #define TprToIrql(Tpr) (HalVectorToIRQL[Tpr >> 4])
35 #endif
36
37 #define MSR_APIC_BASE 0x0000001B
38 #define IOAPIC_PHYS_BASE 0xFEC00000
39 #define APIC_CLOCK_INDEX 8
40
41 #define ApicLogicalId(Cpu) ((UCHAR)(1<< Cpu))
42
43 /* APIC Register Address Map */
44 #define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
45 #define APIC_VER 0x0030 /* Local APIC Version Register (R) */
46 #define APIC_TPR 0x0080 /* Task Priority Register (R/W) */
47 #define APIC_APR 0x0090 /* Arbitration Priority Register (R) */
48 #define APIC_PPR 0x00A0 /* Processor Priority Register (R) */
49 #define APIC_EOI 0x00B0 /* EOI Register (W) */
50 #define APIC_RRR 0x00C0 /* Remote Read Register () */
51 #define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */
52 #define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
53 #define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
54 #define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */
55 #define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */
56 #define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */
57 #define APIC_ESR 0x0280 /* Error Status Register (R) */
58 #define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */
59 #define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */
60 #define APIC_TMRLVTR 0x0320 /* Timer Local Vector Table (R/W) */
61 #define APIC_THRMLVTR 0x0330 /* Thermal Local Vector Table */
62 #define APIC_PCLVTR 0x0340 /* Performance Counter Local Vector Table (R/W) */
63 #define APIC_LINT0 0x0350 /* LINT0 Local Vector Table (R/W) */
64 #define APIC_LINT1 0x0360 /* LINT1 Local Vector Table (R/W) */
65 #define APIC_ERRLVTR 0x0370 /* Error Local Vector Table (R/W) */
66 #define APIC_TICR 0x0380 /* Initial Count Register for Timer (R/W) */
67 #define APIC_TCCR 0x0390 /* Current Count Register for Timer (R) */
68 #define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
69 #define APIC_EAFR 0x0400 /* extended APIC Feature register (R/W) */
70 #define APIC_EACR 0x0410 /* Extended APIC Control Register (R/W) */
71 #define APIC_SEOI 0x0420 /* Specific End Of Interrupt Register (W) */
72 #define APIC_EXT0LVTR 0x0500 /* Extended Interrupt 0 Local Vector Table */
73 #define APIC_EXT1LVTR 0x0510 /* Extended Interrupt 1 Local Vector Table */
74 #define APIC_EXT2LVTR 0x0520 /* Extended Interrupt 2 Local Vector Table */
75 #define APIC_EXT3LVTR 0x0530 /* Extended Interrupt 3 Local Vector Table */
76
77 enum
78 {
79 APIC_MT_Fixed = 0,
80 APIC_MT_LowestPriority = 1,
81 APIC_MT_SMI = 2,
82 APIC_MT_RemoteRead = 3,
83 APIC_MT_NMI = 4,
84 APIC_MT_INIT = 5,
85 APIC_MT_Startup = 6,
86 APIC_MT_ExtInt = 7,
87 };
88
89 enum
90 {
91 APIC_TGM_Edge,
92 APIC_TGM_Level
93 };
94
95 enum
96 {
97 APIC_DM_Physical,
98 APIC_DM_Logical
99 };
100
101 enum
102 {
103 APIC_DSH_Destination,
104 APIC_DSH_Self,
105 APIC_DSH_AllIncludingSelf,
106 APIC_DSH_AllExclusingSelf
107 };
108
109 enum
110 {
111 APIC_DF_Flat = 0xFFFFFFFF,
112 APIC_DF_Cluster = 0x0FFFFFFF
113 };
114
115 enum
116 {
117 TIMER_DV_DivideBy2 = 0,
118 TIMER_DV_DivideBy4 = 1,
119 TIMER_DV_DivideBy8 = 2,
120 TIMER_DV_DivideBy16 = 3,
121 TIMER_DV_DivideBy32 = 8,
122 TIMER_DV_DivideBy64 = 9,
123 TIMER_DV_DivideBy128 = 10,
124 TIMER_DV_DivideBy1 = 11,
125 };
126
127
128 typedef union _APIC_BASE_ADRESS_REGISTER
129 {
130 ULONG64 Long;
131 struct
132 {
133 ULONG64 Reserved1:8;
134 ULONG64 BootStrapCPUCore:1;
135 ULONG64 Reserved2:2;
136 ULONG64 Enable:1;
137 ULONG64 BaseAddress:40;
138 ULONG64 ReservedMBZ:12;
139 };
140 } APIC_BASE_ADRESS_REGISTER;
141
142 typedef union _APIC_SPURIOUS_INERRUPT_REGISTER
143 {
144 ULONG Long;
145 struct
146 {
147 ULONG Vector:8;
148 ULONG SoftwareEnable:1;
149 ULONG FocusCPUCoreChecking:1;
150 ULONG ReservedMBZ:22;
151 };
152 } APIC_SPURIOUS_INERRUPT_REGISTER;
153
154 typedef union
155 {
156 ULONG Long;
157 struct
158 {
159 ULONG Version:8;
160 ULONG ReservedMBZ:8;
161 ULONG MaxLVT:8;
162 ULONG ReservedMBZ1:7;
163 ULONG ExtRegSpacePresent:1;
164 };
165 } APIC_VERSION_REGISTER;
166
167 typedef union
168 {
169 ULONG Long;
170 struct
171 {
172 ULONG Version:1;
173 ULONG SEOIEnable:1;
174 ULONG ExtApicIdEnable:1;
175 ULONG ReservedMBZ:29;
176 };
177 } APIC_EXTENDED_CONTROL_REGISTER;
178
179 typedef union _APIC_COMMAND_REGISTER
180 {
181 ULONGLONG LongLong;
182 struct
183 {
184 ULONG Long0;
185 ULONG Long1;
186 };
187 struct
188 {
189 ULONGLONG Vector:8;
190 ULONGLONG MessageType:3;
191 ULONGLONG DestinationMode:1;
192 ULONGLONG DeliveryStatus:1;
193 ULONGLONG ReservedMBZ:1;
194 ULONGLONG Level:1;
195 ULONGLONG TriggerMode:1;
196 ULONGLONG RemoteReadStatus:2;
197 ULONGLONG DestinationShortHand:2;
198 ULONGLONG Reserved2MBZ:36;
199 ULONGLONG Destination:8;
200 };
201 } APIC_COMMAND_REGISTER;
202
203 typedef union
204 {
205 ULONG Long;
206 struct
207 {
208 ULONG Vector:8;
209 ULONG MessageType:3;
210 ULONG ReservedMBZ:1;
211 ULONG DeliveryStatus:1;
212 ULONG Reserved1MBZ:1;
213 ULONG RemoteIRR:1;
214 ULONG TriggerMode:1;
215 ULONG Mask:1;
216 ULONG TimerMode:1;
217 ULONG Reserved2MBZ:13;
218 };
219 } LVT_REGISTER;
220
221
222 enum
223 {
224 IOAPIC_IOREGSEL = 0x00,
225 IOAPIC_IOWIN = 0x10
226 };
227
228 enum
229 {
230 IOAPIC_ID = 0x00,
231 IOAPIC_VER = 0x01,
232 IOAPIC_ARB = 0x02,
233 IOAPIC_REDTBL = 0x10
234 };
235
236 typedef union _IOAPIC_REDIRECTION_REGISTER
237 {
238 ULONGLONG LongLong;
239 struct
240 {
241 ULONG Long0;
242 ULONG Long1;
243 };
244 struct
245 {
246 ULONGLONG Vector:8;
247 ULONGLONG DeliveryMode:3;
248 ULONGLONG DestinationMode:1;
249 ULONGLONG DeliveryStatus:1;
250 ULONGLONG Polarity:1;
251 ULONGLONG RemoteIRR:1;
252 ULONGLONG TriggerMode:1;
253 ULONGLONG Mask:1;
254 ULONGLONG Reserved:39;
255 ULONGLONG Destination:8;
256 };
257 } IOAPIC_REDIRECTION_REGISTER;
258
259 ULONG
260 FORCEINLINE
261 ApicRead(ULONG Offset)
262 {
263 return *(volatile ULONG *)(APIC_BASE + Offset);
264 }
265
266 VOID
267 FORCEINLINE
268 ApicWrite(ULONG Offset, ULONG Value)
269 {
270 *(volatile ULONG *)(APIC_BASE + Offset) = Value;
271 }
272
273 VOID
274 NTAPI
275 ApicInitializeTimer(ULONG Cpu);
276
277 VOID ApicSpuriousService(VOID);
278