Xen Test Framework
apic.c
Go to the documentation of this file.
1 
6 #include <xtf/lib.h>
7 
8 #include <arch/apic.h>
9 #include <arch/cpuid.h>
10 #include <arch/lib.h>
11 #include <arch/page.h>
12 
14 
15 static enum apic_mode apicbase_to_mode(uint64_t apicbase)
16 {
17  switch ( apicbase & (APICBASE_EXTD | APICBASE_ENABLE) )
18  {
19  case 0:
20  return APIC_MODE_DISABLED;
21 
22  case APICBASE_ENABLE:
23  return APIC_MODE_XAPIC;
24 
26  return APIC_MODE_X2APIC;
27 
28  default:
29  return APIC_MODE_NONE;
30  }
31 }
32 
34 {
35  uint64_t msrval;
36 
37  ASSERT(mode > APIC_MODE_NONE);
38 
39  /*
40  * First pass through this function. Try to calculate what is available
41  * (if anything).
42  */
44  {
45  if ( rdmsr_safe(MSR_APICBASE, &msrval) )
47  else
48  {
50 
51  /* Set the MMIO base back to default if necessary. */
52  if ( (msrval & PAGE_MASK) != APIC_DEFAULT_BASE )
53  {
54  msrval &= ~PAGE_MASK;
55  msrval |= APIC_DEFAULT_BASE;
56 
57  wrmsr(MSR_APICBASE, msrval);
58  }
59  }
60  }
61 
62  /*
63  * Bail if there is no APIC, or X2APIC was requested and hardware doesn't
64  * support it.
65  */
66  if ( (cur_apic_mode == APIC_MODE_NONE) ||
67  (mode == APIC_MODE_X2APIC && !cpu_has_x2apic) )
68  return -ENODEV;
69 
70  /*
71  * Attempt to switch to the requested mode. For simplicity, this always
72  * starts by disabling, then cycling through XAPIC and X2APIC if
73  * applicable.
74  */
75  if ( mode != cur_apic_mode )
76  {
77  msrval = rdmsr(MSR_APICBASE) &
79 
80  wrmsr(MSR_APICBASE, msrval);
81 
82  if ( mode == APIC_MODE_XAPIC || mode == APIC_MODE_X2APIC )
84 
85  if ( mode == APIC_MODE_X2APIC )
87 
89  }
90 
91  /*
92  * Enable the APIC. Use 0xff for the spurious vector, not that we expect
93  * to see any.
94  */
96 
97  return 0;
98 }
99 
100 /*
101  * Local variables:
102  * mode: C
103  * c-file-style: "BSD"
104  * c-basic-offset: 4
105  * tab-width: 4
106  * indent-tabs-mode: nil
107  * End:
108  */
static void wrmsr(uint32_t idx, uint64_t val)
Thin wrapper around an wrmsr instruction.
Definition: msr.h:55
static uint64_t rdmsr(uint32_t idx)
Thin wrapper around an rdmsr instruction.
Definition: msr.h:19
#define cpu_has_x2apic
Definition: cpuid.h:80
int apic_init(enum apic_mode mode)
Discover and initialise the local APIC to the requested mode.
Definition: apic.c:33
mode
Definition: main.c:102
#define PAGE_MASK
Definition: page.h:12
#define APICBASE_EXTD
Definition: msr-index.h:13
static void apic_write(unsigned int reg, uint32_t val)
Definition: apic.h:99
#define APICBASE_ENABLE
Definition: msr-index.h:14
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
apic_mode
Definition: apic.h:35
#define ENODEV
Definition: errno.h:32
enum apic_mode cur_apic_mode
Definition: apic.c:13
#define MSR_APICBASE
Definition: msr-index.h:11
static bool rdmsr_safe(uint32_t idx, uint64_t *val)
Wrapper around rdmsr which safely catches #GP[0].
Definition: msr.h:35
#define APIC_SPIV_APIC_ENABLED
Definition: apic.h:22
#define APIC_DEFAULT_BASE
Definition: apic.h:31
x86 Local APIC register definitions and utility functions.
static enum apic_mode apicbase_to_mode(uint64_t apicbase)
Definition: apic.c:15
#define ASSERT(cond)
Definition: lib.h:14
#define APIC_SPIV
Definition: apic.h:21