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