VirtualBox

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

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

VMM/APIC: Add stat. counter for timer callbacks, fix busted logging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/* $Id: APICInternal.h 60632 2016-04-21 15:48:52Z 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 - Reserved bits that must always remain set. */
197#define XAPIC_DFR_RSVD_MB1 UINT32_C(0x0fffffff)
198/** DFR - The model. */
199#define XAPIC_DFR_MODEL UINT32_C(0xf)
200/** DFR - Gets the destination model. */
201#define XAPIC_DFR_GET_MODEL(a_uReg) (((a_uReg) >> 28) & XAPIC_DFR_MODEL)
202
203/** LDR - Valid bits. */
204#define XAPIC_LDR UINT32_C(0xff000000)
205/** LDR - Cluster ID mask (x2APIC). */
206#define X2APIC_LDR_CLUSTER_ID UINT32_C(0xffff0000)
207/** LDR - Mask of the LDR cluster ID (x2APIC). */
208#define X2APIC_LDR_GET_CLUSTER_ID(a_uReg) ((a_uReg) & X2APIC_LDR_CLUSTER_ID)
209/** LDR - Mask of the LDR logical ID (x2APIC). */
210#define X2APIC_LDR_LOGICAL_ID UINT32_C(0x0000ffff)
211
212/** LDR - Flat mode logical ID mask. */
213#define XAPIC_LDR_FLAT_LOGICAL_ID UINT32_C(0xff)
214/** LDR - Clustered mode cluster ID mask. */
215#define XAPIC_LDR_CLUSTERED_CLUSTER_ID UINT32_C(0xf0)
216/** LDR - Clustered mode logical ID mask. */
217#define XAPIC_LDR_CLUSTERED_LOGICAL_ID UINT32_C(0x0f)
218/** LDR - Gets the clustered mode cluster ID. */
219#define XAPIC_LDR_CLUSTERED_GET_CLUSTER_ID(a_uReg) ((a_uReg) & XAPIC_LDR_CLUSTERED_CLUSTER_ID)
220
221
222/** EOI - Valid write-only bits. */
223#define XAPIC_EOI_WO UINT32_C(0x0)
224/** Timer ICR - Valid bits. */
225#define XAPIC_TIMER_ICR UINT32_C(0xffffffff)
226/** Timer DCR - Valid bits. */
227#define XAPIC_TIMER_DCR (RT_BIT(0) | RT_BIT(1) | RT_BIT(3))
228
229/** Self IPI - Valid bits. */
230#define XAPIC_SELF_IPI UINT32_C(0xff)
231/** Self IPI - The vector. */
232#define XAPIC_SELF_IPI_VECTOR UINT32_C(0xff)
233/** Self IPI - Gets the vector. */
234#define XAPIC_SELF_IPI_GET_VECTOR(a_uReg) ((a_uReg) & XAPIC_SELF_IPI_VECTOR)
235
236/** ICR Low - The Vector. */
237#define XAPIC_ICR_LO_VECTOR UINT32_C(0xff)
238/** ICR Low - Gets the vector. */
239#define XAPIC_ICR_LO_GET_VECTOR(a_uIcr) ((a_uIcr) & XAPIC_ICR_LO_VECTOR)
240/** ICR Low - The delivery mode. */
241#define XAPIC_ICR_LO_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
242/** ICR Low - The destination mode. */
243#define XAPIC_ICR_LO_DEST_MODE RT_BIT(11)
244/** ICR Low - The delivery status. */
245#define XAPIC_ICR_LO_DELIVERY_STATUS RT_BIT(12)
246/** ICR Low - The level. */
247#define XAPIC_ICR_LO_LEVEL RT_BIT(14)
248/** ICR Low - The trigger mode. */
249#define XAPIC_ICR_TRIGGER_MODE RT_BIT(15)
250/** ICR Low - The destination shorthand. */
251#define XAPIC_ICR_LO_DEST_SHORTHAND (RT_BIT(18) | RT_BIT(19))
252/** ICR Low - Valid write bits. */
253#define XAPIC_ICR_LO_WR ( XAPIC_ICR_LO_VECTOR | XAPIC_ICR_LO_DELIVERY_MODE | XAPIC_ICR_LO_DEST_MODE \
254 | XAPIC_ICR_LO_LEVEL | XAPIC_ICR_TRIGGER_MODE | XAPIC_ICR_LO_DEST_SHORTHAND)
255
256/** ICR High - The destination field. */
257#define XAPIC_ICR_HI_DEST UINT32_C(0xff000000)
258/** ICR High - Get the destination field. */
259#define XAPIC_ICR_HI_GET_DEST(a_u32IcrHi) (((a_u32IcrHi) >> 24) & XAPIC_ICR_HI_DEST)
260/** ICR High - Valid write bits in xAPIC mode. */
261#define XAPIC_ICR_HI_WR XAPIC_ICR_HI_DEST
262
263/** APIC ID broadcast mask - x2APIC mode. */
264#define X2APIC_ID_BROADCAST_MASK UINT32_C(0xffffffff)
265#if XAPIC_HARDWARE_VERSION == XAPIC_HARDWARE_VERSION_P4
266/** APIC ID broadcast mask - xAPIC mode. */
267# define XAPIC_ID_BROADCAST_MASK UINT32_C(0xff)
268#else
269# error "Implement Pentium and P6 family APIC architectures"
270#endif
271
272/**
273 * APIC MSR access error.
274 * @note The values must match the array indices in apicMsrAccessError().
275 */
276typedef enum APICMSRACCESS
277{
278 /* MSR read while not in x2APIC. */
279 APICMSRACCESS_INVALID_READ_MODE = 0,
280 /* MSR write while not in x2APIC. */
281 APICMSRACCESS_INVALID_WRITE_MODE,
282 /* MSR read for a reserved/unknown/invalid MSR. */
283 APICMSRACCESS_READ_RSVD_OR_UNKNOWN,
284 /* MSR write for a reserved/unknown/invalid MSR. */
285 APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN,
286 /* MSR read for a write-only MSR. */
287 APICMSRACCESS_READ_WRITE_ONLY,
288 /* MSR write for a read-only MSR. */
289 APICMSRACCESS_WRITE_READ_ONLY,
290 /* MSR read to reserved bits. */
291 APICMSRACCESS_READ_RSVD_BITS,
292 /* MSR write to reserved bits. */
293 APICMSRACCESS_WRITE_RSVD_BITS,
294 /* MSR write with invalid value. */
295 APICMSRACCESS_WRITE_INVALID,
296 /* Count of enum members (don't use). */
297 APICMSRACCESS_COUNT
298} APICMSRACCESS;
299
300/** @name xAPIC Destination Format Register bits.
301 * See Intel spec. 10.6.2.2 "Logical Destination Mode".
302 * @{ */
303typedef enum XAPICDESTFORMAT
304{
305 XAPICDESTFORMAT_FLAT = 0xf,
306 XAPICDESTFORMAT_CLUSTER = 0
307} XAPICDESTFORMAT;
308/** @} */
309
310/** @name xAPIC Timer Mode bits.
311 * See Intel spec. 10.5.1 "Local Vector Table".
312 * @{ */
313typedef enum XAPICTIMERMODE
314{
315 XAPICTIMERMODE_ONESHOT = XAPIC_TIMER_MODE_ONESHOT,
316 XAPICTIMERMODE_PERIODIC = XAPIC_TIMER_MODE_PERIODIC,
317 XAPICTIMERMODE_TSC_DEADLINE = XAPIC_TIMER_MODE_TSC_DEADLINE
318} XAPICTIMERMODE;
319/** @} */
320
321/** @name xAPIC Interrupt Command Register bits.
322 * See Intel spec. 10.6.1 "Interrupt Command Register (ICR)".
323 * See Intel spec. 10.5.1 "Local Vector Table".
324 * @{ */
325/**
326 * xAPIC trigger mode.
327 */
328typedef enum XAPICTRIGGERMODE
329{
330 XAPICTRIGGERMODE_EDGE = 0,
331 XAPICTRIGGERMODE_LEVEL
332} XAPICTRIGGERMODE;
333
334/**
335 * xAPIC destination shorthand.
336 */
337typedef enum XAPICDESTSHORTHAND
338{
339 XAPICDESTSHORTHAND_NONE = 0,
340 XAPICDESTSHORTHAND_SELF,
341 XAPIDDESTSHORTHAND_ALL_INCL_SELF,
342 XAPICDESTSHORTHAND_ALL_EXCL_SELF
343} XAPICDESTSHORTHAND;
344
345/**
346 * xAPIC INIT level de-assert delivery mode.
347 */
348typedef enum XAPICINITLEVEL
349{
350 XAPICINITLEVEL_DEASSERT = 0,
351 XAPICINITLEVEL_ASSERT
352} XAPICLEVEL;
353
354/**
355 * xAPIC destination mode.
356 */
357typedef enum XAPICDESTMODE
358{
359 XAPICDESTMODE_PHYSICAL = 0,
360 XAPICDESTMODE_LOGICAL
361} XAPICDESTMODE;
362
363/**
364 * xAPIC delivery mode type.
365 */
366typedef enum XAPICDELIVERYMODE
367{
368 XAPICDELIVERYMODE_FIXED = 0,
369 XAPICDELIVERYMODE_LOWEST_PRIO = 1,
370 XAPICDELIVERYMODE_SMI = 2,
371 XAPICDELIVERYMODE_NMI = 4,
372 XAPICDELIVERYMODE_INIT = 5,
373 XAPICDELIVERYMODE_INIT_LEVEL_DEASSERT = 5, /* Yes, also 5. */
374 XAPICDELIVERYMODE_STARTUP = 6,
375 XAPICDELIVERYMODE_EXTINT = 7
376} XAPICDELIVERYMODE;
377/** @} */
378
379/**
380 * APIC operating modes.
381 *
382 * The values match hardware states.
383 * See Intel spec. 10.12.1 "Detecting and Enabling x2APIC Mode".
384 */
385typedef enum APICMODE
386{
387 APICMODE_DISABLED = 0,
388 APICMODE_INVALID,
389 APICMODE_XAPIC,
390 APICMODE_X2APIC
391} APICMODE;
392
393/**
394 * APIC PDM instance data (per-VM).
395 */
396typedef struct APICDEV
397{
398 /** The device instance - R3 Ptr. */
399 PPDMDEVINSR3 pDevInsR3;
400 /** The APIC helpers - R3 Ptr. */
401 PCPDMAPICHLPR3 pApicHlpR3;
402 /** The PDM critical section - R3 Ptr. */
403 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
404
405 /** The device instance - R0 Ptr. */
406 PPDMDEVINSR0 pDevInsR0;
407 /** The APIC helpers - R0 Ptr. */
408 PCPDMAPICHLPR0 pApicHlpR0;
409 /** The PDM critical section - R0 Ptr. */
410 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;
411
412 /** The device instance - RC Ptr. */
413 PPDMDEVINSRC pDevInsRC;
414 /** The APIC helpers - RC Ptr. */
415 PCPDMAPICHLPRC pApicHlpRC;
416 /** The PDM critical section - RC Ptr. */
417 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;
418 /** Alignment padding. */
419 RCPTRTYPE(void *) pvAlignment0;
420} APICDEV;
421/** Pointer to an APIC device. */
422typedef APICDEV *PAPICDEV;
423/** Pointer to a const APIC device. */
424typedef APICDEV const *PCAPICDEV;
425
426/**
427 * APIC VM Instance data.
428 */
429typedef struct APIC
430{
431 /** @name The APIC PDM device instance.
432 * @{ */
433 /** The APIC device - R0 ptr. */
434 R0PTRTYPE(PAPICDEV) pApicDevR0;
435 /** The APIC device - R3 ptr. */
436 R3PTRTYPE(PAPICDEV) pApicDevR3;
437 /** The APIC device - RC ptr. */
438 RCPTRTYPE(PAPICDEV) pApicDevRC;
439 /** Alignment padding. */
440 RTRCPTR RCPtrAlignment0;
441 /** @} */
442
443 /** @name The APIC pending-interrupt bitmap (PIB).
444 * @{ */
445 /** The host-context physical address of the PIB. */
446 RTHCPHYS HCPhysApicPib;
447 /** The ring-0 memory object of the PIB. */
448 RTR0MEMOBJ hMemObjApicPibR0;
449 /** The ring-3 mapping of the memory object of the PIB. */
450 RTR0MEMOBJ hMapObjApicPibR0;
451 /** The APIC PIB virtual address - R0 ptr. */
452 R0PTRTYPE(volatile void *) pvApicPibR0;
453 /** The APIC PIB virtual address - R3 ptr. */
454 R3PTRTYPE(volatile void *) pvApicPibR3;
455 /** The APIC PIB virtual address - RC ptr. */
456 RCPTRTYPE(volatile void *) pvApicPibRC;
457 /** Alignment padding. */
458 RTRCPTR RCPtrAlignment1;
459 /** The size of the page in bytes. */
460 uint32_t cbApicPib;
461 /** Alignment padding. */
462 uint32_t u32Aligment0;
463 /** @} */
464
465 /** @name Other miscellaneous data.
466 * @{ */
467 /** Whether full APIC register virtualization is enabled. */
468 bool fVirtApicRegsEnabled;
469 /** Whether posted-interrupt processing is enabled. */
470 bool fPostedIntrsEnabled;
471 /** Whether TSC-deadline timer mode is supported for the guest. */
472 bool fSupportsTscDeadline;
473 /** Whether this VM has an IO-APIC. */
474 bool fIoApicPresent;
475 /** Whether RZ is enabled or not (applies to MSR handling as well). */
476 bool fRZEnabled;
477 /** Alignment padding. */
478 bool afAlignment0[7];
479 /** The original APIC mode from CFGM. */
480 APICMODE enmOriginalMode;
481 /** @} */
482} APIC;
483/** Pointer to APIC VM instance data. */
484typedef APIC *PAPIC;
485/** Pointer to const APIC VM instance data. */
486typedef APIC const *PCAPIC;
487
488/**
489 * APIC VMCPU Instance data.
490 */
491typedef struct APICCPU
492{
493 /** @name The APIC page.
494 * @{ */
495 /** The host-context physical address of the page. */
496 RTHCPHYS HCPhysApicPage;
497 /** The ring-0 memory object of the page. */
498 RTR0MEMOBJ hMemObjApicPageR0;
499 /** The ring-3 mapping of the memory object of the page. */
500 RTR0MEMOBJ hMapObjApicPageR0;
501 /** The APIC page virtual address - R0 ptr. */
502 R0PTRTYPE(volatile void *) pvApicPageR0;
503 /** The APIC page virtual address - R3 ptr. */
504 R3PTRTYPE(volatile void *) pvApicPageR3;
505 /** The APIC page virtual address - RC ptr. */
506 RCPTRTYPE(volatile void *) pvApicPageRC;
507 /** Alignment padding. */
508 RTRCPTR RCPtrAlignment0;
509 /** The size of the page in bytes. */
510 uint32_t cbApicPage;
511 /** @} */
512
513 /** @name Auxiliary state.
514 * @{ */
515 /** The error status register's internal state. */
516 uint32_t uEsrInternal;
517 /** The APIC base MSR.*/
518 uint64_t volatile uApicBaseMsr;
519 /** @} */
520
521 /** @name The pending-interrupt bitmaps (PIB).
522 * @{ */
523 /** The host-context physical address of the page. */
524 RTHCPHYS HCPhysApicPib;
525 /** The APIC PIB virtual address - R0 ptr. */
526 R0PTRTYPE(volatile void *) pvApicPibR0;
527 /** The APIC PIB virtual address - R3 ptr. */
528 R3PTRTYPE(volatile void *) pvApicPibR3;
529 /** The APIC PIB virtual address - RC ptr. */
530 RCPTRTYPE(volatile void *) pvApicPibRC;
531 /** Alignment padding. */
532 RTRCPTR RCPtrAlignment1;
533 /** The APIC PIB for level-sensitive interrupts. */
534 volatile APICPIB ApicPibLevel;
535 /** @} */
536
537 /** @name The APIC timer.
538 * @{ */
539 /** The timer - R0 ptr. */
540 PTMTIMERR0 pTimerR0;
541 /** The timer - R3 ptr. */
542 PTMTIMERR3 pTimerR3;
543 /** The timer - RC ptr. */
544 PTMTIMERRC pTimerRC;
545 /** Alignment padding. */
546 RTRCPTR RCPtrAlignment2;
547 /** The timer critical sect protecting @a u64TimerInitial */
548 PDMCRITSECT TimerCritSect;
549 /** The time stamp when the timer was initialized. */
550 uint64_t u64TimerInitial;
551 /** Cache of timer initial count of the frequency hint to TM. */
552 uint32_t uHintedTimerInitialCount;
553 /** Cache of timer shift of the frequency hint to TM. */
554 uint32_t uHintedTimerShift;
555 /** The timer description. */
556 char szTimerDesc[32];
557 /** @} */
558
559#ifdef VBOX_WITH_STATISTICS
560 /** @name APIC statistics.
561 * @{ */
562 /** Number of MMIO reads in R0. */
563 STAMCOUNTER StatMmioReadR0;
564 /** Number of MMIO reads in R3. */
565 STAMCOUNTER StatMmioReadR3;
566 /** Number of MMIO reads in RC. */
567 STAMCOUNTER StatMmioReadRC;
568
569 /** Number of MMIO writes in R0. */
570 STAMCOUNTER StatMmioWriteR0;
571 /** Number of MMIO writes in R3. */
572 STAMCOUNTER StatMmioWriteR3;
573 /** Number of MMIO writes in RC. */
574 STAMCOUNTER StatMmioWriteRC;
575
576 /** Number of MSR reads in R0. */
577 STAMCOUNTER StatMsrReadR0;
578 /** Number of MSR reads in R3. */
579 STAMCOUNTER StatMsrReadR3;
580 /** Number of MSR reads in RC. */
581 STAMCOUNTER StatMsrReadRC;
582
583 /** Number of MSR writes in R0. */
584 STAMCOUNTER StatMsrWriteR0;
585 /** Number of MSR writes in R3. */
586 STAMCOUNTER StatMsrWriteR3;
587 /** Number of MSR writes in RC. */
588 STAMCOUNTER StatMsrWriteRC;
589
590 /** Profiling of APICUpdatePendingInterrupts(). */
591 STAMPROFILE StatUpdatePendingIntrs;
592 /** Profiling of APICPostInterrupt(). */
593 STAMPROFILE StatPostIntr;
594 /** Number of times an interrupt is already pending in
595 * APICPostInterrupts().*/
596 STAMCOUNTER StatPostIntrAlreadyPending;
597 /** Number of times the timer callback is invoked. */
598 STAMCOUNTER StatTimerCallback;
599 /** @} */
600#endif
601} APICCPU;
602/** Pointer to APIC VMCPU instance data. */
603typedef APICCPU *PAPICCPU;
604/** Pointer to a const APIC VMCPU instance data. */
605typedef APICCPU const *PCAPICCPU;
606AssertCompileMemberAlignment(APICCPU, uApicBaseMsr, 8);
607
608/**
609 * Gets the timer shift value.
610 *
611 * @returns The timer shift value.
612 * @param pXApicPage The xAPIC page.
613 */
614DECLINLINE(uint8_t) apicGetTimerShift(PCXAPICPAGE pXApicPage)
615{
616 /* See Intel spec. 10.5.4 "APIC Timer". */
617 uint32_t uShift = pXApicPage->timer_dcr.u.u2DivideValue0 | (pXApicPage->timer_dcr.u.u1DivideValue1 << 2);
618 return (uShift + 1) & 7;
619}
620
621RT_C_DECLS_BEGIN
622
623const char *apicGetModeName(APICMODE enmMode);
624const char *apicGetDestFormatName(XAPICDESTFORMAT enmDestFormat);
625const char *apicGetDeliveryModeName(XAPICDELIVERYMODE enmDeliveryMode);
626const char *apicGetDestModeName(XAPICDESTMODE enmDestMode);
627const char *apicGetTriggerModeName(XAPICTRIGGERMODE enmTriggerMode);
628const char *apicGetDestShorthandName(XAPICDESTSHORTHAND enmDestShorthand);
629const char *apicGetTimerModeName(XAPICTIMERMODE enmTimerMode);
630void apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift);
631
632VMMDECL(uint64_t) APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
633VMMDECL(VBOXSTRICTRC) APICSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t uBase);
634VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
635VMMDECL(void) APICSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr);
636VMMDECL(uint64_t) APICGetTimerFreq(PPDMDEVINS pDevIns);
637VMMDECL(int) APICReadMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
638VMMDECL(int) APICWriteMmio(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
639VMMDECL(VBOXSTRICTRC) APICReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Val);
640VMMDECL(VBOXSTRICTRC) APICWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Val);
641VMMDECL(bool) APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq);
642VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc);
643VMMDECL(void) APICSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
644VMMDECL(void) APICClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType);
645VMMDECL(VBOXSTRICTRC) APICLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ);
646VMMDECL(int) APICBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode,
647 uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc);
648
649VMM_INT_DECL(void) APICPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode);
650VMM_INT_DECL(void) APICStartTimer(PAPICCPU pApicCpu, uint32_t uInitialCount);
651VMM_INT_DECL(void) APICStopTimer(PAPICCPU pApicCpu);
652VMM_INT_DECL(void) APICUpdateCpuIdForMode(PVM pVM, APICMODE enmMode);
653
654RT_C_DECLS_END
655
656/** @} */
657
658#endif
659
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