VirtualBox

source: vbox/trunk/src/VBox/VMM/include/APICInternal.h@ 60464

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

VMM/APIC: more logging

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
1/* $Id: APICInternal.h 60464 2016-04-12 16:56:07Z vboxsync $ */
2/** @file
3 * APIC - Advanced Programmable Interrupt Controller.
4 */
5
6/*
7 * Copyright (C) 2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___APICInternal_h
19#define ___APICInternal_h
20
21#include <VBox/sup.h>
22#include <VBox/types.h>
23#include <VBox/vmm/apic.h>
24
25/** @defgroup grp_apic_int Internal
26 * @ingroup grp_apic
27 * @internal
28 * @{
29 */
30
31#define VMCPU_TO_XAPICPAGE(a_pVCpu) ((PXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
32#define VMCPU_TO_CXAPICPAGE(a_pVCpu) ((PCXAPICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
33
34#define VMCPU_TO_X2APICPAGE(a_pVCpu) ((PX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
35#define VMCPU_TO_CX2APICPAGE(a_pVCpu) ((PCX2APICPAGE)(CTX_SUFF((a_pVCpu)->apic.s.pvApicPage)))
36
37#define VMCPU_TO_APICCPU(a_pVCpu) (&(a_pVCpu)->apic.s)
38#define VM_TO_APIC(a_pVM) (&(a_pVM)->apic.s)
39#define VM_TO_APICDEV(a_pVM) CTX_SUFF(VM_TO_APIC(a_pVM)->pApicDev)
40
41#define APICCPU_TO_XAPICPAGE(a_ApicCpu) ((PXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
42#define APICCPU_TO_CXAPICPAGE(a_ApicCpu) ((PCXAPICPAGE)(CTX_SUFF((a_ApicCpu)->pvApicPage)))
43
44
45/** Whether the APIC is in X2APIC mode or not. */
46#define XAPIC_IN_X2APIC_MODE(a_pVCpu) RT_BOOL((((a_pVCpu)->apic.s.uApicBaseMsr) & (MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT)) \
47 == (MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT))
48/** Get an xAPIC page offset for an x2APIC MSR value. */
49#define X2APIC_GET_XAPIC_OFF(a_uMsr) ((((a_uMsr) - MSR_IA32_X2APIC_START) << 4) & UINT32_C(0xff0))
50/** Get an x2APIC MSR for an xAPIC page offset. */
51#define XAPIC_GET_X2APIC_MSR(a_offReg) ((((a_offReg) & UINT32_C(0xff0)) >> 4) | MSR_IA32_X2APIC_START)
52
53/** Illegal APIC vector value start. */
54#define XAPIC_ILLEGAL_VECTOR_START UINT8_C(0)
55/** Illegal APIC vector value end (inclusive). */
56#define XAPIC_ILLEGAL_VECTOR_END UINT8_C(15)
57/** Reserved APIC vector value start. */
58#define XAPIC_RSVD_VECTOR_START UINT8_C(16)
59/** Reserved APIC vector value end (inclusive). */
60#define XAPIC_RSVD_VECTOR_END UINT8_C(31)
61
62/** Vector offset in an APIC 256-bit sparse register. */
63#define XAPIC_REG256_VECTOR_OFF(a_Vector) (((a_Vector) & UINT32_C(0xe0)) >> 1)
64/** Bit position at offset in an APIC 256-bit sparse register. */
65#define XAPIC_REG256_VECTOR_BIT(a_Vector) ((a_Vector) & UINT32_C(0x1f))
66
67/** Maximum number of LVT entries for Pentium 4. */
68#define XAPIC_MAX_LVT_ENTRIES_P4 UINT8_C(6)
69/** Size of the APIC ID bits for Pentium 4. */
70#define XAPIC_APIC_ID_BIT_COUNT_P4 UINT8_C(8)
71/** The APIC hardware version number for Pentium 4. */
72#define XAPIC_HARDWARE_VERSION_P4 UINT8_C(0x14)
73
74/** Maximum number of LVT entries for Pentium 6. */
75#define XAPIC_MAX_LVT_ENTRIES_P6 UINT8_C(4)
76/** Size of the APIC ID bits for Pentium 6. */
77#define XAPIC_APIC_ID_BIT_COUNT_P6 UINT8_C(4)
78/** The APIC hardware version number for Pentium 6. */
79#define XAPIC_HARDWARE_VERSION_P6 UINT8_C(0x10)
80
81/** Maximum valid offset for a register (16-byte aligned, 4 byte wide access). */
82#define XAPIC_OFF_MAX_VALID (sizeof(XAPICPAGE) - 4 * sizeof(uint32_t))
83
84#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P6
85/** ESR - Send checksum error. */
86# define XAPIC_ESR_SEND_CHKSUM_ERROR RT_BIT(0)
87/** ESR - Send accept error. */
88# define XAPIC_ESR_RECV_CHKSUM_ERROR RT_BIT(1)
89/** ESR - Send accept error. */
90# define XAPIC_ESR_SEND_ACCEPT_ERROR RT_BIT(2)
91/** ESR - Receive accept error. */
92# define XAPIC_ESR_RECV_ACCEPT_ERROR RT_BIT(3)
93#endif
94/** ESR - Redirectable IPI. */
95#define XAPIC_ESR_REDIRECTABLE_IPI RT_BIT(4)
96/** ESR - Send accept error. */
97#define XAPIC_ESR_SEND_ILLEGAL_VECTOR RT_BIT(5)
98/** ESR - Send accept error. */
99#define XAPIC_ESR_RECV_ILLEGAL_VECTOR RT_BIT(6)
100/** ESR - Send accept error. */
101#define XAPIC_ESR_ILLEGAL_REG_ADDRESS RT_BIT(7)
102/** ESR - Valid write-only bits. */
103#define XAPIC_ESR_WO UINT32_C(0x0)
104
105/** TPR - Valid bits. */
106#define XAPIC_TPR UINT32_C(0xff)
107/** TPR - Task-priority class. */
108#define XAPIC_TPR_TP UINT32_C(0xf0)
109/** TPR - Task-priority subclass. */
110#define XAPIC_TPR_TP_SUBCLASS UINT32_C(0x0f)
111/** TPR - Get the task-priority class. */
112#define XAPIC_TPR_GET_TP(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP)
113/** TPR - Get the task-priority subclass. */
114#define XAPIC_TPR_GET_TP_SUBCLASS(a_Tpr) ((a_Tpr) & XAPIC_TPR_TP_SUBCLASS)
115
116/** PPR - Valid bits. */
117#define XAPIC_PPR UINT32_C(0xff)
118/** PPR - Processor-priority class. */
119#define XAPIC_PPR_PP UINT32_C(0xf0)
120/** PPR - Processor-priority subclass. */
121#define XAPIC_PPR_PP_SUBCLASS UINT32_C(0x0f)
122/** PPR - Get the processor-priority class. */
123#define XAPIC_PPR_GET_PP(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP)
124/** PPR - Get the processor-priority subclass. */
125#define XAPIC_PPR_GET_PP_SUBCLASS(a_Ppr) ((a_Ppr) & XAPIC_PPR_PP_SUBCLASS)
126
127/** Timer mode - One-shot. */
128#define XAPIC_TIMER_MODE_ONESHOT UINT32_C(0)
129/** Timer mode - Periodic. */
130#define XAPIC_TIMER_MODE_PERIODIC UINT32_C(1)
131/** Timer mode - TSC deadline. */
132#define XAPIC_TIMER_MODE_TSC_DEADLINE UINT32_C(2)
133
134/** LVT - The vector. */
135#define XAPIC_LVT_VECTOR UINT32_C(0xff)
136/** LVT - Gets the vector from an LVT entry. */
137#define XAPIC_LVT_GET_VECTOR(a_Lvt) ((a_Lvt) & XAPIC_LVT_VECTOR)
138/** LVT - The mask. */
139#define XAPIC_LVT_MASK RT_BIT(16)
140/** LVT - Is the LVT masked? */
141#define XAPIC_LVT_IS_MASKED(a_Lvt) RT_BOOL((a_Lvt) & XAPIC_LVT_MASK)
142/** LVT - Timer mode. */
143#define XAPIC_LVT_TIMER_MODE RT_BIT(17)
144/** LVT - Timer TSC-deadline timer mode. */
145#define XAPIC_LVT_TIMER_TSCDEADLINE RT_BIT(18)
146/** LVT - Gets the timer mode. */
147#define XAPIC_LVT_GET_TIMER_MODE(a_Lvt) (XAPICTIMERMODE)(((a_Lvt) >> 17) & UINT32_C(3))
148/** LVT - Delivery mode. */
149#define XAPIC_LVT_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
150/** LVT - Gets the delivery mode. */
151#define XAPIC_LVT_GET_DELIVERY_MODE(a_Lvt) (XAPICDELIVERYMODE)(((a_Lvt) >> 8) & UINT32_C(7))
152/** LVT - Delivery status. */
153#define XAPIC_LVT_DELIVERY_STATUS RT_BIT(12)
154/** LVT - Trigger mode. */
155#define XAPIC_LVT_TRIGGER_MODE RT_BIT(15)
156/** LVT - Gets the trigger mode. */
157#define XAPIC_LVT_GET_TRIGGER_MODE(a_Lvt) (XAPICTRIGGERMODE)(((a_Lvt) >> 15) & UINT32_C(1))
158/** LVT - Remote IRR. */
159#define XAPIC_LVT_REMOTE_IRR RT_BIT(14)
160/** LVT - Interrupt Input Pin Polarity. */
161#define XAPIC_LVT_INTR_INPUT_PIN_POLARITY RT_BIT(13)
162/** LVT - Valid bits common to all LVTs. */
163#define XAPIC_LVT_COMMON (XAPIC_LVT_VECTOR | XAPIC_LVT_DELIVERY_STATUS | XAPIC_LVT_MASK)
164/** LVT CMCI - Valid bits. */
165#define XAPIC_LVT_CMCI_VALID (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
166/** LVT Timer - Valid bits. */
167#define XAPIC_LVT_TIMER (XAPIC_LVT_COMMON | XAPIC_LVT_TIMER_MODE | XAPIC_LVT_TIMER_TSCDEADLINE)
168/** LVT Thermal - Valid bits. */
169#define XAPIC_LVT_THERMAL (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
170/** LVT Perf - Valid bits. */
171#define XAPIC_LVT_PERF (XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE)
172/** LVT LINT0 - Valid bits. */
173#define XAPIC_LVT_LINT0 ( XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE | XAPIC_LVT_DELIVERY_STATUS \
174 | XAPIC_LVT_INTR_INPUT_PIN_POLARITY | XAPIC_LVT_REMOTE_IRR)
175/** LVT LINT1 - Valid bits. */
176#define XAPIC_LVT_LINT1 ( XAPIC_LVT_COMMON | XAPIC_LVT_DELIVERY_MODE | XAPIC_LVT_DELIVERY_STATUS \
177 | XAPIC_LVT_INTR_INPUT_PIN_POLARITY | XAPIC_LVT_REMOTE_IRR)
178/** LVT Error - Valid bits. */
179#define XAPIC_LVT_ERROR (XAPIC_LVT_COMMON)
180
181/** SVR - The vector. */
182#define XAPIC_SVR_VECTOR UINT32_C(0xff)
183/** SVR - APIC Software enable. */
184#define XAPIC_SVR_SOFTWARE_ENABLE RT_BIT(8)
185/** SVR - Supress EOI broadcast. */
186#define XAPIC_SVR_SUPRESS_EOI_BROADCAST RT_BIT(12)
187#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
188/** SVR - Valid bits. */
189# define XAPIC_SVR (XAPIC_SVR_VECTOR | XAPIC_SVR_SOFTWARE_ENABLE)
190#else
191# error "Implement Pentium and P6 family APIC architectures"
192#endif
193
194/** DFR - Valid bits. */
195#define XAPIC_DFR UINT32_C(0xf0000000)
196/** DFR - The model. */
197#define XAPIC_DFR_MODEL UINT32_C(0xf)
198/** DFR - Gets the destination model. */
199#define XAPIC_DFR_GET_MODEL(a_uReg) (((a_uReg) >> 28) & XAPIC_DFR_MODEL)
200
201/** LDR - Valid bits. */
202#define XAPIC_LDR UINT32_C(0xff000000)
203/** LDR - Cluster ID mask (x2APIC). */
204#define X2APIC_LDR_CLUSTER_ID UINT32_C(0xffff0000)
205/** LDR - Mask of the LDR cluster ID (x2APIC). */
206#define X2APIC_LDR_GET_CLUSTER_ID(a_uReg) ((a_uReg) & X2APIC_LDR_CLUSTER_ID)
207/** LDR - Mask of the LDR logical ID (x2APIC). */
208#define X2APIC_LDR_LOGICAL_ID UINT32_C(0x0000ffff)
209
210/** LDR - Flat mode logical ID mask. */
211#define XAPIC_LDR_FLAT_LOGICAL_ID UINT32_C(0xff)
212/** LDR - Clustered mode cluster ID mask. */
213#define XAPIC_LDR_CLUSTERED_CLUSTER_ID UINT32_C(0xf0)
214/** LDR - Clustered mode logical ID mask. */
215#define XAPIC_LDR_CLUSTERED_LOGICAL_ID UINT32_C(0x0f)
216/** LDR - Gets the clustered mode cluster ID. */
217#define XAPIC_LDR_CLUSTERED_GET_CLUSTER_ID(a_uReg) ((a_uReg) & XAPIC_LDR_CLUSTERED_CLUSTER_ID)
218
219
220/** EOI - Valid write-only bits. */
221#define XAPIC_EOI_WO UINT32_C(0x0)
222/** Timer ICR - Valid bits. */
223#define XAPIC_TIMER_ICR UINT32_C(0xffffffff)
224/** Timer DCR - Valid bits. */
225#define XAPIC_TIMER_DCR (RT_BIT(0) | RT_BIT(1) | RT_BIT(3))
226
227/** Self IPI - Valid bits. */
228#define XAPIC_SELF_IPI UINT32_C(0xff)
229/** Self IPI - The vector. */
230#define XAPIC_SELF_IPI_VECTOR UINT32_C(0xff)
231/** Self IPI - Gets the vector. */
232#define XAPIC_SELF_IPI_GET_VECTOR(a_uReg) ((a_uReg) & XAPIC_SELF_IPI_VECTOR)
233
234/** ICR Low - The Vector. */
235#define XAPIC_ICR_LO_VECTOR UINT32_C(0xff)
236/** ICR Low - Gets the vector. */
237#define XAPIC_ICR_LO_GET_VECTOR(a_uIcr) ((a_uIcr) & XAPIC_ICR_LO_VECTOR)
238/** ICR Low - The delivery mode. */
239#define XAPIC_ICR_LO_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
240/** ICR Low - The destination mode. */
241#define XAPIC_ICR_LO_DEST_MODE RT_BIT(11)
242/** ICR Low - The delivery status. */
243#define XAPIC_ICR_LO_DELIVERY_STATUS RT_BIT(12)
244/** ICR Low - The level. */
245#define XAPIC_ICR_LO_LEVEL RT_BIT(14)
246/** ICR Low - The trigger mode. */
247#define XAPIC_ICR_TRIGGER_MODE RT_BIT(15)
248/** ICR Low - The destination shorthand. */
249#define XAPIC_ICR_LO_DEST_SHORTHAND (RT_BIT(18) | RT_BIT(19))
250/** ICR Low - Valid write bits. */
251#define XAPIC_ICR_LO_WR ( XAPIC_ICR_LO_VECTOR | XAPIC_ICR_LO_DELIVERY_MODE | XAPIC_ICR_LO_DEST_MODE \
252 | XAPIC_ICR_LO_LEVEL | XAPIC_ICR_TRIGGER_MODE | XAPIC_ICR_LO_DEST_SHORTHAND)
253
254/** ICR High - The destination field. */
255#define XAPIC_ICR_HI_DEST UINT32_C(0xff000000)
256/** ICR High - Get the destination field. */
257#define XAPIC_ICR_HI_GET_DEST(a_u32IcrHi) (((a_u32IcrHi) >> 24) & XAPIC_ICR_HI_DEST)
258/** ICR High - Valid write bits in xAPIC mode. */
259#define XAPIC_ICR_HI_WR XAPIC_ICR_HI_DEST
260
261/** APIC ID broadcast mask - x2APIC mode. */
262#define X2APIC_ID_BROADCAST_MASK UINT32_C(0xffffffff)
263#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
264/** APIC ID broadcast mask - xAPIC mode. */
265# define XAPIC_ID_BROADCAST_MASK UINT32_C(0xff)
266#else
267# error "Implement Pentium and P6 family APIC architectures"
268#endif
269
270/**
271 * APIC MSR access error.
272 * @note The values must match the array indices in apicMsrAccessError().
273 */
274typedef enum APICMSRACCESS
275{
276 /* MSR read while not in x2APIC. */
277 APICMSRACCESS_INVALID_READ_MODE = 0,
278 /* MSR write while not in x2APIC. */
279 APICMSRACCESS_INVALID_WRITE_MODE,
280 /* MSR read for a reserved/unknown/invalid MSR. */
281 APICMSRACCESS_READ_RSVD_OR_UNKNOWN,
282 /* MSR write for a reserved/unknown/invalid MSR. */
283 APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN,
284 /* MSR read for a write-only MSR. */
285 APICMSRACCESS_READ_WRITE_ONLY,
286 /* MSR write for a read-only MSR. */
287 APICMSRACCESS_WRITE_READ_ONLY,
288 /* MSR read to reserved bits. */
289 APICMSRACCESS_READ_RSVD_BITS,
290 /* MSR write to reserved bits. */
291 APICMSRACCESS_WRITE_RSVD_BITS,
292 /* MSR write with invalid value. */
293 APICMSRACCESS_WRITE_INVALID,
294 /* Count of enum members (don't use). */
295 APICMSRACCESS_COUNT
296} APICMSRACCESS;
297
298/** @name xAPIC Destination Format Register bits.
299 * See Intel spec. 10.6.2.2 "Logical Destination Mode".
300 * @{ */
301typedef enum XAPICDESTFORMAT
302{
303 XAPICDESTFORMAT_FLAT = 0xf,
304 XAPICDESTFORMAT_CLUSTER = 0
305} XAPICDESTFORMAT;
306/** @} */
307
308/** @name xAPIC Timer Mode bits.
309 * See Intel spec. 10.5.1 "Local Vector Table".
310 * @{ */
311typedef enum XAPICTIMERMODE
312{
313 XAPICTIMERMODE_ONESHOT = XAPIC_TIMER_MODE_ONESHOT,
314 XAPICTIMERMODE_PERIODIC = XAPIC_TIMER_MODE_PERIODIC,
315 XAPICTIMERMODE_TSC_DEADLINE = XAPIC_TIMER_MODE_TSC_DEADLINE
316} XAPICTIMERMODE;
317/** @} */
318
319/** @name xAPIC Interrupt Command Register bits.
320 * See Intel spec. 10.6.1 "Interrupt Command Register (ICR)".
321 * See Intel spec. 10.5.1 "Local Vector Table".
322 * @{ */
323/**
324 * xAPIC trigger mode.
325 */
326typedef enum XAPICTRIGGERMODE
327{
328 XAPICTRIGGERMODE_EDGE = 0,
329 XAPICTRIGGERMODE_LEVEL
330} XAPICTRIGGERMODE;
331
332/**
333 * xAPIC destination shorthand.
334 */
335typedef enum XAPICDESTSHORTHAND
336{
337 XAPICDESTSHORTHAND_NONE = 0,
338 XAPICDESTSHORTHAND_SELF,
339 XAPIDDESTSHORTHAND_ALL_INCL_SELF,
340 XAPICDESTSHORTHAND_ALL_EXCL_SELF
341} XAPICDESTSHORTHAND;
342
343/**
344 * xAPIC INIT level de-assert delivery mode.
345 */
346typedef enum XAPICINITLEVEL
347{
348 XAPICINITLEVEL_DEASSERT = 0,
349 XAPICINITLEVEL_ASSERT
350} XAPICLEVEL;
351
352/**
353 * xAPIC destination mode.
354 */
355typedef enum XAPICDESTMODE
356{
357 XAPICDESTMODE_PHYSICAL = 0,
358 XAPICDESTMODE_LOGICAL
359} XAPICDESTMODE;
360
361/**
362 * xAPIC delivery mode type.
363 */
364typedef enum XAPICDELIVERYMODE
365{
366 XAPICDELIVERYMODE_FIXED = 0,
367 XAPICDELIVERYMODE_LOWEST_PRIO = 1,
368 XAPICDELIVERYMODE_SMI = 2,
369 XAPICDELIVERYMODE_NMI = 4,
370 XAPICDELIVERYMODE_INIT = 5,
371 XAPICDELIVERYMODE_INIT_LEVEL_DEASSERT = 5, /* Yes, also 5. */
372 XAPICDELIVERYMODE_STARTUP = 6,
373 XAPICDELIVERYMODE_EXTINT = 7
374} XAPICDELIVERYMODE;
375/** @} */
376
377/**
378 * APIC operating modes.
379 *
380 * The values match hardware states.
381 * See Intel spec. 10.12.1 "Detecting and Enabling x2APIC Mode".
382 */
383typedef enum APICMODE
384{
385 APICMODE_DISABLED = 0,
386 APICMODE_INVALID,
387 APICMODE_XAPIC,
388 APICMODE_X2APIC
389} APICMODE;
390
391/**
392 * APIC PDM instance data (per-VM).
393 */
394typedef struct APICDEV
395{
396 /** The device instance - R3 Ptr. */
397 PPDMDEVINSR3 pDevInsR3;
398 /** The APIC helpers - R3 Ptr. */
399 PCPDMAPICHLPR3 pApicHlpR3;
400 /** The PDM critical section - R3 Ptr. */
401 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
402
403 /** The device instance - R0 Ptr. */
404 PPDMDEVINSR0 pDevInsR0;
405 /** The APIC helpers - R0 Ptr. */
406 PCPDMAPICHLPR0 pApicHlpR0;
407 /** The PDM critical section - R0 Ptr. */
408 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;
409
410 /** The device instance - RC Ptr. */
411 PPDMDEVINSRC pDevInsRC;
412 /** The APIC helpers - RC Ptr. */
413 PCPDMAPICHLPRC pApicHlpRC;
414 /** The PDM critical section - RC Ptr. */
415 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;
416 /** Alignment padding. */
417 RCPTRTYPE(void *) pvAlignment0;
418} APICDEV;
419/** Pointer to an APIC device. */
420typedef APICDEV *PAPICDEV;
421/** Pointer to a const APIC device. */
422typedef APICDEV const *PCAPICDEV;
423
424/**
425 * APIC VM Instance data.
426 */
427typedef struct APIC
428{
429 /** @name The APIC PDM device instance.
430 * @{ */
431 /** The APIC device - R0 ptr. */
432 R0PTRTYPE(PAPICDEV) pApicDevR0;
433 /** The APIC device - R3 ptr. */
434 R3PTRTYPE(PAPICDEV) pApicDevR3;
435 /** The APIC device - RC ptr. */
436 RCPTRTYPE(PAPICDEV) pApicDevRC;
437 /** Alignment padding. */
438 RTRCPTR RCPtrAlignment0;
439 /** @} */
440
441 /** @name The APIC pending interrupt bitmap (PIB).
442 * @{ */
443 /** The host-context physical address of the PIB. */
444 RTHCPHYS HCPhysApicPib;
445 /** The ring-0 memory object of the PIB. */
446 RTR0MEMOBJ hMemObjApicPibR0;
447 /** The ring-3 mapping of the memory object of the PIB. */
448 RTR0MEMOBJ hMapObjApicPibR0;
449 /** The APIC PIB virtual address - R0 ptr. */
450 R0PTRTYPE(volatile void *) pvApicPibR0;
451 /** The APIC PIB virtual address - R3 ptr. */
452 R3PTRTYPE(volatile void *) pvApicPibR3;
453 /** The APIC PIB virtual address - RC ptr. */
454 RCPTRTYPE(volatile void *) pvApicPibRC;
455 /** Alignment padding. */
456 RTRCPTR RCPtrAlignment1;
457 /** The size of the page in bytes. */
458 uint32_t cbApicPib;
459 /** Alignment padding. */
460 uint32_t u32Aligment0;
461 /** @} */
462
463 /** @name Other miscellaneous data.
464 * @{ */
465 /** Whether full APIC register virtualization is enabled. */
466 bool fVirtApicRegsEnabled;
467 /** Whether posted-interrupt processing is enabled. */
468 bool fPostedIntrsEnabled;
469 /** Whether TSC-deadline timer mode is supported for the guest. */
470 bool fSupportsTscDeadline;
471 /** Whether this VM has an IO-APIC. */
472 bool fIoApicPresent;
473 /** Whether RZ is enabled or not (required for MSR handling as well). */
474 bool fRZEnabled;
475 /** Alignment padding. */
476 bool afAlignment0[7];
477 /** The original APIC mode from CFGM. */
478 APICMODE enmOriginalMode;
479 /** @} */
480} APIC;
481/** Pointer to APIC VM instance data. */
482typedef APIC *PAPIC;
483/** Pointer to const APIC VM instance data. */
484typedef APIC const *PCAPIC;
485
486/**
487 * APIC VMCPU Instance data.
488 */
489typedef struct APICCPU
490{
491 /** @name The APIC page.
492 * @{ */
493 /** The host-context physical address of the page. */
494 RTHCPHYS HCPhysApicPage;
495 /** The ring-0 memory object of the page. */
496 RTR0MEMOBJ hMemObjApicPageR0;
497 /** The ring-3 mapping of the memory object of the page. */
498 RTR0MEMOBJ hMapObjApicPageR0;
499 /** The APIC page virtual address - R0 ptr. */
500 R0PTRTYPE(volatile void *) pvApicPageR0;
501 /** The APIC page virtual address - R3 ptr. */
502 R3PTRTYPE(volatile void *) pvApicPageR3;
503 /** The APIC page virtual address - RC ptr. */
504 RCPTRTYPE(volatile void *) pvApicPageRC;
505 /** Alignment padding. */
506 RTRCPTR RCPtrAlignment0;
507 /** The size of the page in bytes. */
508 uint32_t cbApicPage;
509 /** @} */
510
511 /** @name Auxiliary state.
512 * @{ */
513 /** The error status register's internal state. */
514 uint32_t volatile uEsrInternal;
515 /** The APIC base MSR.*/
516 uint64_t volatile uApicBaseMsr;
517 /** @} */
518
519 /** @name The pending interrupt bitmaps (PIB).
520 * @{ */
521 /** The host-context physical address of the page. */
522 RTHCPHYS HCPhysApicPib;
523 /** The APIC PIB virtual address - R0 ptr. */
524 R0PTRTYPE(volatile void *) pvApicPibR0;
525 /** The APIC PIB virtual address - R3 ptr. */
526 R3PTRTYPE(volatile void *) pvApicPibR3;
527 /** The APIC PIB virtual address - RC ptr. */
528 RCPTRTYPE(volatile void *) pvApicPibRC;
529 /** Alignment padding. */
530 RTRCPTR RCPtrAlignment1;
531 /** The APIC PIB for level-sensitive interrupts. */
532 volatile APICPIB ApicPibLevel;
533 /** @} */
534
535 /** @name The APIC timer.
536 * @{ */
537 /** The timer - R0 ptr. */
538 PTMTIMERR0 pTimerR0;
539 /** The timer - R3 ptr. */
540 PTMTIMERR3 pTimerR3;
541 /** The timer - RC ptr. */
542 PTMTIMERRC pTimerRC;
543 /** Alignment padding. */
544 RTRCPTR RCPtrAlignment2;
545 /** The timer critical sect protecting @a u64TimerInitial */
546 PDMCRITSECT TimerCritSect;
547 /** The time stamp when the timer was initialized. */
548 uint64_t u64TimerInitial;
549 /** Cache of timer initial count of the frequency hint to TM. */
550 uint32_t uHintedTimerInitialCount;
551 /** Cache of timer shift of the frequency hint to TM. */
552 uint32_t uHintedTimerShift;
553 /** The timer description. */
554 char szTimerDesc[32];
555 /** @} */
556
557#ifdef VBOX_WITH_STATISTICS
558 /** @name APIC statistics.
559 * @{ */
560 /** Number of MMIO reads in R0. */
561 STAMCOUNTER StatMmioReadR0;
562 /** Number of MMIO reads in R3. */
563 STAMCOUNTER StatMmioReadR3;
564 /** Number of MMIO reads in RC. */
565 STAMCOUNTER StatMmioReadRC;
566
567 /** Number of MMIO writes in R0. */
568 STAMCOUNTER StatMmioWriteR0;
569 /** Number of MMIO writes in R3. */
570 STAMCOUNTER StatMmioWriteR3;
571 /** Number of MMIO writes in RC. */
572 STAMCOUNTER StatMmioWriteRC;
573
574 /** Number of MSR reads in R0. */
575 STAMCOUNTER StatMsrReadR0;
576 /** Number of MSR reads in R3. */
577 STAMCOUNTER StatMsrReadR3;
578 /** Number of MSR reads in RC. */
579 STAMCOUNTER StatMsrReadRC;
580
581 /** Number of MSR writes in R0. */
582 STAMCOUNTER StatMsrWriteR0;
583 /** Number of MSR writes in R3. */
584 STAMCOUNTER StatMsrWriteR3;
585 /** Number of MSR writes in RC. */
586 STAMCOUNTER StatMsrWriteRC;
587 /** @} */
588#endif
589} APICCPU;
590/** Pointer to APIC VMCPU instance data. */
591typedef APICCPU *PAPICCPU;
592/** Pointer to a const APIC VMCPU instance data. */
593typedef APICCPU const *PCAPICCPU;
594AssertCompileMemberAlignment(APICCPU, uApicBaseMsr, 8);
595
596/**
597 * Gets the timer shift value.
598 *
599 * @returns The timer shift value.
600 * @param pXApicPage The xAPIC page.
601 */
602DECLINLINE(uint8_t) apicGetTimerShift(PCXAPICPAGE pXApicPage)
603{
604 /* See Intel spec. 10.5.4 "APIC Timer". */
605 uint32_t uShift = pXApicPage->timer_dcr.u.u2DivideValue0 | (pXApicPage->timer_dcr.u.u1DivideValue1 << 2);
606 return (uShift + 1) & 7;
607}
608
609RT_C_DECLS_BEGIN
610
611VMMDECL(uint64_t) APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
612VMMDECL(VBOXSTRICTRC) APICSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t uBase);
613VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
614VMMDECL(void) APICSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr);
615VMMDECL(uint64_t) APICGetTimerFreq(PPDMDEVINS pDevIns);
616VMMDECL(int) APICReadMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
617VMMDECL(int) APICWriteMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
618VMMDECL(VBOXSTRICTRC) APICReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Val);
619VMMDECL(VBOXSTRICTRC) APICWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Val);
620VMMDECL(bool) APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq);
621VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc);
622VMMDECL(void) APICSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
623VMMDECL(void) APICClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
624VMMDECL(VBOXSTRICTRC) APICLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ);
625VMMDECL(int) APICBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode,
626 uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc);
627
628VMM_INT_DECL(void) APICPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode);
629VMM_INT_DECL(void) APICStartTimer(PAPICCPU pApicCpu, uint32_t uInitialCount);
630VMM_INT_DECL(void) APICStopTimer(PAPICCPU pApicCpu);
631VMM_INT_DECL(void) APICUpdateCpuIdForMode(PVM pVM, APICMODE enmMode);
632
633RT_C_DECLS_END
634
635/** @} */
636
637#endif
638
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