VirtualBox

source: vbox/trunk/include/VBox/vmm/apic.h@ 60398

Last change on this file since 60398 was 60398, checked in by vboxsync, 9 years ago

VMM/APIC: Get rid of specialized R0 code and clean up ordering issues.
It's still not nice that CPUMR3Reset() momentarily gets an un-initialized APIC base MSR until
it's re-cached again using CPUMR3InitCompleted() but I hope to eventually get rid of this
caching business entirely once the old APIC infrastructure can be kicked out.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.2 KB
Line 
1/** @file
2 * APIC - Advanced Programmable Interrupt Controller.
3 */
4
5/*
6 * Copyright (C) 2006-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vmm_apic_h
27#define ___VBox_vmm_apic_h
28
29#include <VBox/vmm/pdmins.h>
30#include <VBox/vmm/pdmdev.h>
31
32/** @defgroup grp_apic The local APIC VMM API
33 * @ingroup grp_vmm
34 * @{
35 */
36
37/** The APIC hardware version we are emulating. */
38#define XAPIC_HARDWARE_VERSION XAPIC_HARDWARE_VERSION_P4
39
40/** Gets the APIC base physical address. */
41#define MSR_APICBASE_GET_PHYSADDR(a) ((a) & PAGE_BASE_GC_MASK)
42/** Gets the APIC mode. */
43#define MSR_APICBASE_GET_MODE(a) (((a) >> 10) & UINT64_C(3))
44/** The APIC global enable bit. */
45#define MSR_APICBASE_XAPIC_ENABLE_BIT RT_BIT_64(11)
46/** The x2APIC global enable bit. */
47#define MSR_APICBASE_X2APIC_ENABLE_BIT RT_BIT_64(10)
48/** The APIC bootstrap processor bit. */
49#define MSR_APICBASE_BOOTSTRAP_CPU_BIT RT_BIT_64(8)
50/** The default APIC base address. */
51#define XAPIC_APICBASE_PHYSADDR (UINT64_C(0xfee00000) << PAGE_SHIFT)
52/** The APIC base MSR - Is the APIC enabled? */
53#define MSR_APICBASE_IS_ENABLED(a_Msr) RT_BOOL((a_Msr) & MSR_APICBASE_XAPIC_ENABLE_BIT)
54
55/** Offset of APIC ID Register. */
56#define XAPIC_OFF_ID 0x020
57/** Offset of APIC Version Register. */
58#define XAPIC_OFF_VERSION 0x030
59/** Offset of Task Priority Register. */
60#define XAPIC_OFF_TPR 0x080
61/** Offset of Arbitrartion Priority register. */
62#define XAPIC_OFF_APR 0x090
63/** Offset of Processor Priority register. */
64#define XAPIC_OFF_PPR 0x0A0
65/** Offset of End Of Interrupt register. */
66#define XAPIC_OFF_EOI 0x0B0
67/** Offset of Remote Read Register. */
68#define XAPIC_OFF_RRD 0x0C0
69/** Offset of Logical Destination Register. */
70#define XAPIC_OFF_LDR 0x0D0
71/** Offset of Destination Format Register. */
72#define XAPIC_OFF_DFR 0x0E0
73/** Offset of Spurious Interrupt Vector Register. */
74#define XAPIC_OFF_SVR 0x0F0
75/** Offset of In-service Register (bits 31:0). */
76#define XAPIC_OFF_ISR0 0x100
77/** Offset of In-service Register (bits 63:32). */
78#define XAPIC_OFF_ISR1 0x110
79/** Offset of In-service Register (bits 95:64). */
80#define XAPIC_OFF_ISR2 0x120
81/** Offset of In-service Register (bits 127:96). */
82#define XAPIC_OFF_ISR3 0x130
83/** Offset of In-service Register (bits 159:128). */
84#define XAPIC_OFF_ISR4 0x140
85/** Offset of In-service Register (bits 191:160). */
86#define XAPIC_OFF_ISR5 0x150
87/** Offset of In-service Register (bits 223:192). */
88#define XAPIC_OFF_ISR6 0x160
89/** Offset of In-service Register (bits 255:224). */
90#define XAPIC_OFF_ISR7 0x170
91/** Offset of Trigger Mode Register (bits 31:0). */
92#define XAPIC_OFF_TMR0 0x180
93/** Offset of Trigger Mode Register (bits 63:32). */
94#define XAPIC_OFF_TMR1 0x190
95/** Offset of Trigger Mode Register (bits 95:64). */
96#define XAPIC_OFF_TMR2 0x1A0
97/** Offset of Trigger Mode Register (bits 127:96). */
98#define XAPIC_OFF_TMR3 0x1B0
99/** Offset of Trigger Mode Register (bits 159:128). */
100#define XAPIC_OFF_TMR4 0x1C0
101/** Offset of Trigger Mode Register (bits 191:160). */
102#define XAPIC_OFF_TMR5 0x1D0
103/** Offset of Trigger Mode Register (bits 223:192). */
104#define XAPIC_OFF_TMR6 0x1E0
105/** Offset of Trigger Mode Register (bits 255:224). */
106#define XAPIC_OFF_TMR7 0x1F0
107/** Offset of Interrupt Request Register (bits 31:0). */
108#define XAPIC_OFF_IRR0 0x200
109/** Offset of Interrupt Request Register (bits 63:32). */
110#define XAPIC_OFF_IRR1 0x210
111/** Offset of Interrupt Request Register (bits 95:64). */
112#define XAPIC_OFF_IRR2 0x220
113/** Offset of Interrupt Request Register (bits 127:96). */
114#define XAPIC_OFF_IRR3 0x230
115/** Offset of Interrupt Request Register (bits 159:128). */
116#define XAPIC_OFF_IRR4 0x240
117/** Offset of Interrupt Request Register (bits 191:160). */
118#define XAPIC_OFF_IRR5 0x250
119/** Offset of Interrupt Request Register (bits 223:192). */
120#define XAPIC_OFF_IRR6 0x260
121/** Offset of Interrupt Request Register (bits 255:224). */
122#define XAPIC_OFF_IRR7 0x270
123/** Offset of Error Status Register. */
124#define XAPIC_OFF_ESR 0x280
125/** Offset of LVT CMCI Register. */
126#define XAPIC_OFF_LVT_CMCI 0x2F0
127/** Offset of Interrupt Command Register - Lo. */
128#define XAPIC_OFF_ICR_LO 0x300
129/** Offset of Interrupt Command Register - Hi. */
130#define XAPIC_OFF_ICR_HI 0x310
131/** Offset of LVT Timer Register. */
132#define XAPIC_OFF_LVT_TIMER 0x320
133/** Offset of LVT Thermal Sensor Register. */
134#define XAPIC_OFF_LVT_THERMAL 0x330
135/** Offset of LVT Performance Counter Register. */
136#define XAPIC_OFF_LVT_PERF 0x340
137/** Offset of LVT LINT0 Register. */
138#define XAPIC_OFF_LVT_LINT0 0x350
139/** Offset of LVT LINT1 Register. */
140#define XAPIC_OFF_LVT_LINT1 0x360
141/** Offset of LVT Error Register . */
142#define XAPIC_OFF_LVT_ERROR 0x370
143/** Offset of Timer Initial Count Register. */
144#define XAPIC_OFF_TIMER_ICR 0x380
145/** Offset of Timer Current Count Register. */
146#define XAPIC_OFF_TIMER_CCR 0x390
147/** Offset of Timer Divide Configuration Register. */
148#define XAPIC_OFF_TIMER_DCR 0x3E0
149/** Offset of Self-IPI Register (x2APIC only). */
150#define X2APIC_OFF_SELF_IPI 0x3F0
151
152/** Offset of LVT range start. */
153#define XAPIC_OFF_LVT_START XAPIC_OFF_LVT_TIMER
154/** Offset of LVT range end (inclusive). */
155#define XAPIC_OFF_LVT_END XAPIC_OFF_LVT_ERROR
156/** Offset of LVT extended range start. */
157#define XAPIC_OFF_LVT_EXT_START XAPIC_OFF_LVT_CMCI
158/** Offset of LVT extended range end (inclusive). */
159#define XAPIC_OFF_LVT_EXT_END XAPIC_OFF_LVT_CMCI
160
161
162/**
163 * The xAPIC sparse 256-bit register.
164 */
165typedef union XAPIC256BITREG
166{
167 /** The sparse-bitmap view. */
168 struct
169 {
170 uint32_t u32Reg;
171 uint32_t uReserved0[3];
172 } u[8];
173 /** The 32-bit view. */
174 uint32_t au32[32];
175} XAPIC256BITREG;
176/** Pointer to an xAPIC sparse bitmap register. */
177typedef XAPIC256BITREG *PXAPIC256BITREG;
178/** Pointer to a const xAPIC sparse bitmap register. */
179typedef XAPIC256BITREG const *PCXAPIC256BITREG;
180AssertCompileSize(XAPIC256BITREG, 128);
181
182/**
183 * The xAPIC memory layout as per Intel/AMD specs.
184 */
185typedef struct XAPICPAGE
186{
187 /* 0x00 - Reserved. */
188 uint32_t uReserved0[8];
189 /* 0x20 - APIC ID. */
190 struct
191 {
192 uint8_t u8Reserved0[3];
193 uint8_t u8ApicId;
194 uint32_t u32Reserved0[3];
195 } id;
196 /* 0x30 - APIC version register. */
197 union
198 {
199 struct
200 {
201#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
202 uint8_t u8Version;
203#else
204# error "Implement Pentium and P6 family APIC architectures"
205#endif
206 uint8_t uReserved0;
207 uint8_t u8MaxLvtEntry;
208 uint8_t fEoiBroadcastSupression : 1;
209 uint8_t u7Reserved1 : 7;
210 uint32_t u32Reserved0[3];
211 } u;
212 struct
213 {
214 uint32_t u32Version;
215 uint32_t u32Reserved0[3];
216 } all;
217 } version;
218 /* 0x40 - Reserved. */
219 uint32_t uReserved1[16];
220 /* 0x80 - Task Priority Register (TPR). */
221 struct
222 {
223 uint8_t u8Tpr;
224 uint8_t u8Reserved0[3];
225 uint32_t u32Reserved0[3];
226 } tpr;
227 /* 0x90 - Arbitration Priority Register (APR). */
228 struct
229 {
230 uint8_t u8Apr;
231 uint8_t u8Reserved0[3];
232 uint32_t u32Reserved0[3];
233 } apr;
234 /* 0xA0 - Processor Priority Register (PPR). */
235 struct
236 {
237 uint8_t u8Ppr;
238 uint8_t u8Reserved0[3];
239 uint32_t u32Reserved0[3];
240 } ppr;
241 /* 0xB0 - End Of Interrupt Register (EOI). */
242 struct
243 {
244 uint32_t u32Eoi;
245 uint32_t u32Reserved0[3];
246 } eoi;
247 /* 0xC0 - Remote Read Register (RRD). */
248 struct
249 {
250 uint32_t u32Rrd;
251 uint32_t u32Reserved0[3];
252 } rrd;
253 /* 0xD0 - Logical Destination Register (LDR). */
254 union
255 {
256 struct
257 {
258 uint32_t u24Reserved0 : 24;
259 uint32_t u8LogicalApicId : 8;
260 uint32_t u32Reserved0[3];
261 } u;
262 struct
263 {
264 uint32_t u32Ldr;
265 uint32_t u32Reserved0[3];
266 } all;
267 } ldr;
268 /* 0xE0 - Destination Format Register (DFR). */
269 union
270 {
271 struct
272 {
273 uint32_t u28ReservedMb1 : 28; /* MB1 */
274 uint32_t u4Model : 4;
275 uint32_t u32Reserved0[3];
276 } u;
277 struct
278 {
279 uint32_t u32Dfr;
280 uint32_t u32Reserved0[3];
281 } all;
282 } dfr;
283 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
284 union
285 {
286 struct
287 {
288 uint32_t u8SpuriousVector : 8;
289 uint32_t fApicSoftwareEnable : 1;
290 uint32_t u3Reserved0 : 3;
291 uint32_t fSupressEoiBroadcast : 1;
292 uint32_t u19Reserved1 : 19;
293 uint32_t u32Reserved0[3];
294 } u;
295 struct
296 {
297 uint32_t u32Svr;
298 uint32_t u32Reserved0[3];
299 } all;
300 } svr;
301 /* 0x100 - In-service Register (ISR). */
302 XAPIC256BITREG isr;
303 /* 0x180 - Trigger Mode Register (TMR). */
304 XAPIC256BITREG tmr;
305 /* 0x200 - Interrupt Request Register (IRR). */
306 XAPIC256BITREG irr;
307 /* 0x280 - Error Status Register (ESR). */
308 union
309 {
310 struct
311 {
312#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
313 uint32_t u4Reserved0 : 4;
314#else
315# error "Implement Pentium and P6 family APIC architectures"
316#endif
317 uint32_t fRedirectableIpi : 1;
318 uint32_t fSendIllegalVector : 1;
319 uint32_t fRcvdIllegalVector : 1;
320 uint32_t fIllegalRegAddr : 1;
321 uint32_t u24Reserved1 : 24;
322 uint32_t u32Reserved0[3];
323 } u;
324 struct
325 {
326 uint32_t u32Errors;
327 uint32_t u32Reserved0[3];
328 } all;
329 } esr;
330 /* 0x290 - Reserved. */
331 uint32_t uReserved2[28];
332 /* 0x300 - Interrupt Command Register (ICR) - Low. */
333 union
334 {
335 struct
336 {
337 uint32_t u8Vector : 8;
338 uint32_t u3DeliveryMode : 3;
339 uint32_t u1DestMode : 1;
340 uint32_t u1DeliveryStatus : 1;
341 uint32_t fReserved0 : 1;
342 uint32_t u1Level : 1;
343 uint32_t u1TriggerMode : 1;
344 uint32_t u2Reserved1 : 2;
345 uint32_t u2DestShorthand : 2;
346 uint32_t u12Reserved2 : 12;
347 uint32_t u32Reserved0[3];
348 } u;
349 struct
350 {
351 uint32_t u32IcrLo;
352 uint32_t u32Reserved0[3];
353 } all;
354 } icr_lo;
355 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
356 union
357 {
358 struct
359 {
360 uint32_t u24Reserved0 : 24;
361 uint32_t u8Dest : 8;
362 uint32_t u32Reserved0[3];
363 } u;
364 struct
365 {
366 uint32_t u32IcrHi;
367 uint32_t u32Reserved0[3];
368 } all;
369 } icr_hi;
370 /* 0x320 - Local Vector Table (LVT) Timer Register. */
371 union
372 {
373 struct
374 {
375 uint32_t u8Vector : 8;
376 uint32_t u4Reserved0 : 4;
377 uint32_t u1DeliveryStatus : 1;
378 uint32_t u3Reserved1 : 3;
379 uint32_t u1Mask : 1;
380 uint32_t u2TimerMode : 2;
381 uint32_t u13Reserved2 : 13;
382 uint32_t u32Reserved0[3];
383 } u;
384 struct
385 {
386 uint32_t u32LvtTimer;
387 uint32_t u32Reserved0[3];
388 } all;
389 } lvt_timer;
390 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
391#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
392 union
393 {
394 struct
395 {
396 uint32_t u8Vector : 8;
397 uint32_t u3DeliveryMode : 3;
398 uint32_t u1Reserved0 : 1;
399 uint32_t u1DeliveryStatus : 1;
400 uint32_t u3Reserved1 : 3;
401 uint32_t u1Mask : 1;
402 uint32_t u15Reserved2 : 15;
403 uint32_t u32Reserved0[3];
404 } u;
405 struct
406 {
407 uint32_t u32LvtThermal;
408 uint32_t u32Reserved0[3];
409 } all;
410 } lvt_thermal;
411#else
412# error "Implement Pentium and P6 family APIC architectures"
413#endif
414 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
415 union
416 {
417 struct
418 {
419 uint32_t u8Vector : 8;
420 uint32_t u3DeliveryMode : 3;
421 uint32_t u1Reserved0 : 1;
422 uint32_t u1DeliveryStatus : 1;
423 uint32_t u3Reserved1 : 3;
424 uint32_t u1Mask : 1;
425 uint32_t u15Reserved2 : 15;
426 uint32_t u32Reserved0[3];
427 } u;
428 struct
429 {
430 uint32_t u32LvtPerf;
431 uint32_t u32Reserved0[3];
432 } all;
433 } lvt_perf;
434 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
435 union
436 {
437 struct
438 {
439 uint32_t u8Vector : 8;
440 uint32_t u3DeliveryMode : 3;
441 uint32_t u1Reserved0 : 1;
442 uint32_t u1DeliveryStatus : 1;
443 uint32_t u1IntrPolarity : 1;
444 uint32_t u1RemoteIrr : 1;
445 uint32_t u1TriggerMode : 1;
446 uint32_t u1Mask : 1;
447 uint32_t u15Reserved2 : 15;
448 uint32_t u32Reserved0[3];
449 } u;
450 struct
451 {
452 uint32_t u32LvtLint0;
453 uint32_t u32Reserved0[3];
454 } all;
455 } lvt_lint0;
456 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
457 union
458 {
459 struct
460 {
461 uint32_t u8Vector : 8;
462 uint32_t u3DeliveryMode : 3;
463 uint32_t u1Reserved0 : 1;
464 uint32_t u1DeliveryStatus : 1;
465 uint32_t u1IntrPolarity : 1;
466 uint32_t u1RemoteIrr : 1;
467 uint32_t u1TriggerMode : 1;
468 uint32_t u1Mask : 1;
469 uint32_t u15Reserved2 : 15;
470 uint32_t u32Reserved0[3];
471 } u;
472 struct
473 {
474 uint32_t u32LvtLint1;
475 uint32_t u32Reserved0[3];
476 } all;
477 } lvt_lint1;
478 /* 0x370 - Local Vector Table (LVT) Error Register. */
479 union
480 {
481 struct
482 {
483 uint32_t u8Vector : 8;
484 uint32_t u4Reserved0 : 4;
485 uint32_t u1DeliveryStatus : 1;
486 uint32_t u3Reserved1 : 3;
487 uint32_t u1Mask : 1;
488 uint32_t u15Reserved2 : 15;
489 uint32_t u32Reserved0[3];
490 } u;
491 struct
492 {
493 uint32_t u32LvtError;
494 uint32_t u32Reserved0[3];
495 } all;
496 } lvt_error;
497 /* 0x380 - Timer Initial Counter Register. */
498 struct
499 {
500 uint32_t u32InitialCount;
501 uint32_t u32Reserved0[3];
502 } timer_icr;
503 /* 0x390 - Timer Current Counter Register. */
504 struct
505 {
506 uint32_t u32CurrentCount;
507 uint32_t u32Reserved0[3];
508 } timer_ccr;
509 /* 0x3A0 - Reserved. */
510 uint32_t u32Reserved3[16];
511 /* 0x3E0 - Timer Divide Configuration Register. */
512 union
513 {
514 struct
515 {
516 uint32_t u2DivideValue0 : 2;
517 uint32_t u1Reserved0 : 1;
518 uint32_t u1DivideValue1 : 1;
519 uint32_t u28Reserved1 : 28;
520 uint32_t u32Reserved0[3];
521 } u;
522 struct
523 {
524 uint32_t u32DivideValue;
525 uint32_t u32Reserved0[3];
526 } all;
527 } timer_dcr;
528 /* 0x3F0 - Reserved. */
529 uint8_t u8Reserved0[3088];
530} XAPICPAGE;
531/** Pointer to a XAPICPAGE struct. */
532typedef volatile XAPICPAGE *PXAPICPAGE;
533/** Pointer to a const XAPICPAGE struct. */
534typedef const volatile XAPICPAGE *PCXAPICPAGE;
535AssertCompileSize(XAPICPAGE, 4096);
536AssertCompileMemberOffset(XAPICPAGE, id, XAPIC_OFF_ID);
537AssertCompileMemberOffset(XAPICPAGE, version, XAPIC_OFF_VERSION);
538AssertCompileMemberOffset(XAPICPAGE, tpr, XAPIC_OFF_TPR);
539AssertCompileMemberOffset(XAPICPAGE, apr, XAPIC_OFF_APR);
540AssertCompileMemberOffset(XAPICPAGE, ppr, XAPIC_OFF_PPR);
541AssertCompileMemberOffset(XAPICPAGE, eoi, XAPIC_OFF_EOI);
542AssertCompileMemberOffset(XAPICPAGE, rrd, XAPIC_OFF_RRD);
543AssertCompileMemberOffset(XAPICPAGE, ldr, XAPIC_OFF_LDR);
544AssertCompileMemberOffset(XAPICPAGE, dfr, XAPIC_OFF_DFR);
545AssertCompileMemberOffset(XAPICPAGE, svr, XAPIC_OFF_SVR);
546AssertCompileMemberOffset(XAPICPAGE, isr, XAPIC_OFF_ISR0);
547AssertCompileMemberOffset(XAPICPAGE, tmr, XAPIC_OFF_TMR0);
548AssertCompileMemberOffset(XAPICPAGE, irr, XAPIC_OFF_IRR0);
549AssertCompileMemberOffset(XAPICPAGE, esr, XAPIC_OFF_ESR);
550AssertCompileMemberOffset(XAPICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
551AssertCompileMemberOffset(XAPICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
552AssertCompileMemberOffset(XAPICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
553AssertCompileMemberOffset(XAPICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
554AssertCompileMemberOffset(XAPICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
555AssertCompileMemberOffset(XAPICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
556AssertCompileMemberOffset(XAPICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
557AssertCompileMemberOffset(XAPICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
558AssertCompileMemberOffset(XAPICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
559AssertCompileMemberOffset(XAPICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
560AssertCompileMemberOffset(XAPICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
561
562/**
563 * The x2APIC memory layout as per Intel/AMD specs.
564 */
565typedef struct X2APICPAGE
566{
567 /* 0x00 - Reserved. */
568 uint32_t uReserved0[8];
569 /* 0x20 - APIC ID. */
570 struct
571 {
572 uint32_t u32ApicId;
573 uint32_t u32Reserved0[3];
574 } id;
575 /* 0x30 - APIC version register. */
576 union
577 {
578 struct
579 {
580 uint8_t u8Version;
581 uint8_t u8Reserved0;
582 uint8_t u8MaxLvtEntry;
583 uint8_t fEoiBroadcastSupression : 1;
584 uint8_t u7Reserved1 : 7;
585 uint32_t u32Reserved0[3];
586 } u;
587 struct
588 {
589 uint32_t u32Version;
590 uint32_t u32Reserved2[3];
591 } all;
592 } version;
593 /* 0x40 - Reserved. */
594 uint32_t uReserved1[16];
595 /* 0x80 - Task Priority Register (TPR). */
596 struct
597 {
598 uint8_t u8Tpr;
599 uint8_t u8Reserved0[3];
600 uint32_t u32Reserved0[3];
601 } tpr;
602 /* 0x90 - Reserved. */
603 uint32_t uReserved2[4];
604 /* 0xA0 - Processor Priority Register (PPR). */
605 struct
606 {
607 uint8_t u8Ppr;
608 uint8_t u8Reserved0[3];
609 uint32_t u32Reserved0[3];
610 } ppr;
611 /* 0xB0 - End Of Interrupt Register (EOI). */
612 struct
613 {
614 uint32_t u32Eoi;
615 uint32_t u32Reserved0[3];
616 } eoi;
617 /* 0xC0 - Remote Read Register (RRD). */
618 struct
619 {
620 uint32_t u32Rrd;
621 uint32_t u32Reserved0[3];
622 } rrd;
623 /* 0xD0 - Logical Destination Register (LDR). */
624 struct
625 {
626 uint32_t u32LogicalApicId;
627 uint32_t u32Reserved1[3];
628 } ldr;
629 /* 0xE0 - Reserved. */
630 uint32_t uReserved3[4];
631 /* 0xF0 - Spurious-Interrupt Vector Register (SVR). */
632 union
633 {
634 struct
635 {
636 uint32_t u8SpuriousVector : 8;
637 uint32_t fApicSoftwareEnable : 1;
638 uint32_t u3Reserved0 : 3;
639 uint32_t fSupressEoiBroadcast : 1;
640 uint32_t u19Reserved1 : 19;
641 uint32_t u32Reserved0[3];
642 } u;
643 struct
644 {
645 uint32_t u32Svr;
646 uint32_t uReserved0[3];
647 } all;
648 } svr;
649 /* 0x100 - In-service Register (ISR). */
650 XAPIC256BITREG isr;
651 /* 0x180 - Trigger Mode Register (TMR). */
652 XAPIC256BITREG tmr;
653 /* 0x200 - Interrupt Request Register (IRR). */
654 XAPIC256BITREG irr;
655 /* 0x280 - Error Status Register (ESR). */
656 union
657 {
658 struct
659 {
660#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
661 uint32_t u4Reserved0 : 4;
662#else
663# error "Implement Pentium and P6 family APIC architectures"
664#endif
665 uint32_t fRedirectableIpi : 1;
666 uint32_t fSendIllegalVector : 1;
667 uint32_t fRcvdIllegalVector : 1;
668 uint32_t fIllegalRegAddr : 1;
669 uint32_t u24Reserved1 : 24;
670 uint32_t uReserved0[3];
671 } u;
672 struct
673 {
674 uint32_t u32Errors;
675 uint32_t u32Reserved0[3];
676 } all;
677 } esr;
678 /* 0x290 - Reserved. */
679 uint32_t uReserved4[28];
680 /* 0x300 - Interrupt Command Register (ICR) - Low. */
681 union
682 {
683 struct
684 {
685 uint32_t u8Vector : 8;
686 uint32_t u3DeliveryMode : 3;
687 uint32_t u1DestMode : 1;
688 uint32_t u2Reserved0 : 2;
689 uint32_t u1Level : 1;
690 uint32_t u1TriggerMode : 1;
691 uint32_t u2Reserved1 : 2;
692 uint32_t u2DestShorthand : 2;
693 uint32_t u12Reserved2 : 12;
694 uint32_t u32Reserved0[3];
695 } u;
696 struct
697 {
698 uint32_t u32IcrLo;
699 uint32_t u32Reserved3[3];
700 } all;
701 } icr_lo;
702 /* 0x310 - Interrupt Comannd Register (ICR) - High. */
703 struct
704 {
705 uint32_t u32IcrHi;
706 uint32_t uReserved1[3];
707 } icr_hi;
708 /* 0x320 - Local Vector Table (LVT) Timer Register. */
709 union
710 {
711 struct
712 {
713 uint32_t u8Vector : 8;
714 uint32_t u4Reserved0 : 4;
715 uint32_t u1DeliveryStatus : 1;
716 uint32_t u3Reserved1 : 3;
717 uint32_t u1Mask : 1;
718 uint32_t u2TimerMode : 2;
719 uint32_t u13Reserved2 : 13;
720 uint32_t u32Reserved0[3];
721 } u;
722 struct
723 {
724 uint32_t u32LvtTimer;
725 uint32_t u32Reserved0[3];
726 } all;
727 } lvt_timer;
728 /* 0x330 - Local Vector Table (LVT) Thermal Sensor Register. */
729 union
730 {
731 struct
732 {
733 uint32_t u8Vector : 8;
734 uint32_t u3DeliveryMode : 3;
735 uint32_t u1Reserved0 : 1;
736 uint32_t u1DeliveryStatus : 1;
737 uint32_t u3Reserved1 : 3;
738 uint32_t u1Mask : 1;
739 uint32_t u15Reserved2 : 15;
740 uint32_t u32Reserved0[3];
741 } u;
742 struct
743 {
744 uint32_t u32LvtThermal;
745 uint32_t uReserved0[3];
746 } all;
747 } lvt_thermal;
748 /* 0x340 - Local Vector Table (LVT) Performance Monitor Counter (PMC) Register. */
749 union
750 {
751 struct
752 {
753 uint32_t u8Vector : 8;
754 uint32_t u3DeliveryMode : 3;
755 uint32_t u1Reserved0 : 1;
756 uint32_t u1DeliveryStatus : 1;
757 uint32_t u3Reserved1 : 3;
758 uint32_t u1Mask : 1;
759 uint32_t u15Reserved2 : 15;
760 uint32_t u32Reserved0[3];
761 } u;
762 struct
763 {
764 uint32_t u32LvtPerf;
765 uint32_t u32Reserved0[3];
766 } all;
767 } lvt_perf;
768 /* 0x350 - Local Vector Table (LVT) LINT0 Register. */
769 union
770 {
771 struct
772 {
773 uint32_t u8Vector : 8;
774 uint32_t u3DeliveryMode : 3;
775 uint32_t u1Reserved0 : 1;
776 uint32_t u1DeliveryStatus : 1;
777 uint32_t u1IntrPolarity : 1;
778 uint32_t u1RemoteIrr : 1;
779 uint32_t u1TriggerMode : 1;
780 uint32_t u1Mask : 1;
781 uint32_t u15Reserved2 : 15;
782 uint32_t u32Reserved0[3];
783 } u;
784 struct
785 {
786 uint32_t u32LvtLint0;
787 uint32_t u32Reserved0[3];
788 } all;
789 } lvt_lint0;
790 /* 0x360 - Local Vector Table (LVT) LINT1 Register. */
791 union
792 {
793 struct
794 {
795 uint32_t u8Vector : 8;
796 uint32_t u3DeliveryMode : 3;
797 uint32_t u1Reserved0 : 1;
798 uint32_t u1DeliveryStatus : 1;
799 uint32_t u1IntrPolarity : 1;
800 uint32_t u1RemoteIrr : 1;
801 uint32_t u1TriggerMode : 1;
802 uint32_t u1Mask : 1;
803 uint32_t u15Reserved2 : 15;
804 uint32_t u32Reserved0[3];
805 } u;
806 struct
807 {
808 uint32_t u32LvtLint1;
809 uint32_t u32Reserved0[3];
810 } all;
811 } lvt_lint1;
812 /* 0x370 - Local Vector Table (LVT) Error Register. */
813 union
814 {
815 struct
816 {
817 uint32_t u8Vector : 8;
818 uint32_t u4Reserved0 : 4;
819 uint32_t u1DeliveryStatus : 1;
820 uint32_t u3Reserved1 : 3;
821 uint32_t u1Mask : 1;
822 uint32_t u15Reserved2 : 15;
823 uint32_t u32Reserved0[3];
824 } u;
825 struct
826 {
827 uint32_t u32LvtError;
828 uint32_t u32Reserved0[3];
829 } all;
830 } lvt_error;
831 /* 0x380 - Timer Initial Counter Register. */
832 struct
833 {
834 uint32_t u32InitialCount;
835 uint32_t u32Reserved0[3];
836 } timer_icr;
837 /* 0x390 - Timer Current Counter Register. */
838 struct
839 {
840 uint32_t u32CurrentCount;
841 uint32_t u32Reserved0[3];
842 } timer_ccr;
843 /* 0x3A0 - Reserved. */
844 uint32_t uReserved5[16];
845 /* 0x3E0 - Timer Divide Configuration Register. */
846 union
847 {
848 struct
849 {
850 uint32_t u2DivideValue0 : 2;
851 uint32_t u1Reserved0 : 1;
852 uint32_t u1DivideValue1 : 1;
853 uint32_t u28Reserved1 : 28;
854 uint32_t u32Reserved0[3];
855 } u;
856 struct
857 {
858 uint32_t u32DivideValue;
859 uint32_t u32Reserved0[3];
860 } all;
861 } timer_dcr;
862 /* 0x3F0 - Self IPI Register. */
863 struct
864 {
865 uint32_t u8Vector : 8;
866 uint32_t u24Reserved0 : 24;
867 uint32_t u32Reserved0[3];
868 } self_ipi;
869 /* 0x400 - Reserved. */
870 uint8_t u8Reserved0[3072];
871} X2APICPAGE;
872/** Pointer to a X2APICPAGE struct. */
873typedef volatile X2APICPAGE *PX2APICPAGE;
874/** Pointer to a const X2APICPAGE struct. */
875typedef const volatile X2APICPAGE *PCX2APICPAGE;
876//AssertCompileSize(X2APICPAGE, 4096);
877AssertCompileMemberOffset(X2APICPAGE, id, XAPIC_OFF_ID);
878AssertCompileMemberOffset(X2APICPAGE, version, XAPIC_OFF_VERSION);
879AssertCompileMemberOffset(X2APICPAGE, tpr, XAPIC_OFF_TPR);
880AssertCompileMemberOffset(X2APICPAGE, ppr, XAPIC_OFF_PPR);
881AssertCompileMemberOffset(X2APICPAGE, eoi, XAPIC_OFF_EOI);
882AssertCompileMemberOffset(X2APICPAGE, rrd, XAPIC_OFF_RRD);
883AssertCompileMemberOffset(X2APICPAGE, ldr, XAPIC_OFF_LDR);
884AssertCompileMemberOffset(X2APICPAGE, svr, XAPIC_OFF_SVR);
885AssertCompileMemberOffset(X2APICPAGE, isr, XAPIC_OFF_ISR0);
886AssertCompileMemberOffset(X2APICPAGE, tmr, XAPIC_OFF_TMR0);
887AssertCompileMemberOffset(X2APICPAGE, irr, XAPIC_OFF_IRR0);
888AssertCompileMemberOffset(X2APICPAGE, esr, XAPIC_OFF_ESR);
889AssertCompileMemberOffset(X2APICPAGE, icr_lo, XAPIC_OFF_ICR_LO);
890AssertCompileMemberOffset(X2APICPAGE, icr_hi, XAPIC_OFF_ICR_HI);
891AssertCompileMemberOffset(X2APICPAGE, lvt_timer, XAPIC_OFF_LVT_TIMER);
892AssertCompileMemberOffset(X2APICPAGE, lvt_thermal, XAPIC_OFF_LVT_THERMAL);
893AssertCompileMemberOffset(X2APICPAGE, lvt_perf, XAPIC_OFF_LVT_PERF);
894AssertCompileMemberOffset(X2APICPAGE, lvt_lint0, XAPIC_OFF_LVT_LINT0);
895AssertCompileMemberOffset(X2APICPAGE, lvt_lint1, XAPIC_OFF_LVT_LINT1);
896AssertCompileMemberOffset(X2APICPAGE, lvt_error, XAPIC_OFF_LVT_ERROR);
897AssertCompileMemberOffset(X2APICPAGE, timer_icr, XAPIC_OFF_TIMER_ICR);
898AssertCompileMemberOffset(X2APICPAGE, timer_ccr, XAPIC_OFF_TIMER_CCR);
899AssertCompileMemberOffset(X2APICPAGE, timer_dcr, XAPIC_OFF_TIMER_DCR);
900AssertCompileMemberOffset(X2APICPAGE, self_ipi, X2APIC_OFF_SELF_IPI);
901
902/** The offset (in bits) of the posted-interrupt bitmap's outstanding
903 * notification bit. */
904#define XAPIC_PIB_NOTIFICATION_BIT UINT32_C(256)
905
906/**
907 * APIC Pending Interrupt Bitmap (PIB).
908 * The layout is critical as it mimics VT-x's Posted Interrupt Bitmap!
909 */
910typedef struct APICPIB
911{
912 uint32_t volatile aVectorBitmap[8];
913 uint32_t volatile fOutstandingNotification;
914 uint8_t au8Reserved[28];
915} APICPIB;
916AssertCompileMemberOffset(APICPIB, fOutstandingNotification, XAPIC_PIB_NOTIFICATION_BIT / 8);
917AssertCompileSize(APICPIB, 64);
918/** Pointer to a pending interrupt bitmap. */
919typedef APICPIB *PAPICPIB;
920/** Pointer to a const pending interrupt bitmap. */
921typedef const APICPIB *PCAPICPIB;
922
923RT_C_DECLS_BEGIN
924
925#ifdef IN_RING3
926/** @defgroup grp_apic_r3 The APIC Host Context Ring-3 API
927 * @{
928 */
929VMMR3_INT_DECL(void) APICR3InitIpi(PVMCPU pVCpu);
930VMMR3_INT_DECL(void) APICR3Reset(PVMCPU pVCpu);
931/** @} */
932#endif /* IN_RING3 */
933
934#ifdef IN_RING0
935/** @defgroup grp_apic_r0 The APIC Host Context Ring-0 API
936 * @{
937 */
938VMMR0_INT_DECL(int) APICR0InitVM(PVM pVM);
939VMMR0_INT_DECL(int) APICR0TermVM(PVM pVM);
940/** @} */
941#endif /* IN_RING0 */
942
943VMMDECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr);
944VMMDECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr);
945VMMDECL(void) APICUpdatePendingInterrupts(PVMCPU pVCpu);
946VMMDECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr);
947
948RT_C_DECLS_END
949
950extern const PDMDEVREG g_DeviceAPIC;
951/** @} */
952
953#endif
954
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette