coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
lapic.h
Go to the documentation of this file.
1 #ifndef CPU_X86_LAPIC_H
2 #define CPU_X86_LAPIC_H
3 
4 #include <arch/mmio.h>
5 #include <arch/cpu.h>
6 #include <cpu/x86/lapic_def.h>
7 #include <cpu/x86/msr.h>
8 #include <halt.h>
9 #include <stdint.h>
10 
11 static __always_inline uint32_t xapic_read(unsigned int reg)
12 {
13  return read32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg));
14 }
15 
16 static __always_inline void xapic_write(unsigned int reg, uint32_t v)
17 {
18  write32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg), v);
19 }
20 
21 static __always_inline void xapic_send_ipi(uint32_t icrlow, uint32_t icrhi)
22 {
23  xapic_write(LAPIC_ICR2, icrhi);
24  xapic_write(LAPIC_ICR, icrlow);
25 }
26 
27 static __always_inline int xapic_busy(void)
28 {
30 }
31 
32 static __always_inline uint32_t x2apic_read(unsigned int reg)
33 {
34  uint32_t value, index;
35  msr_t msr;
36 
37  index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
38  msr = rdmsr(index);
39  value = msr.lo;
40  return value;
41 }
42 
43 static __always_inline void x2apic_write(unsigned int reg, uint32_t v)
44 {
45  uint32_t index;
46  msr_t msr;
47 
48  index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
49  msr.hi = 0x0;
50  msr.lo = v;
51  wrmsr(index, msr);
52 }
53 
55 {
56  msr_t icr;
57  icr.hi = icrhi;
58  icr.lo = icrlow;
60 }
61 
63 {
64  if (CONFIG(XAPIC_ONLY))
65  return false;
66 
67  if (CONFIG(X2APIC_ONLY))
68  return true;
69 
70  msr_t msr;
71  msr = rdmsr(LAPIC_BASE_MSR);
73 }
74 
75 static __always_inline uint32_t lapic_read(unsigned int reg)
76 {
77  if (is_x2apic_mode())
78  return x2apic_read(reg);
79  else
80  return xapic_read(reg);
81 }
82 
83 static __always_inline void lapic_write(unsigned int reg, uint32_t v)
84 {
85  if (is_x2apic_mode())
86  x2apic_write(reg, v);
87  else
88  xapic_write(reg, v);
89 }
90 
91 static __always_inline void lapic_update32(unsigned int reg, uint32_t mask, uint32_t or)
92 {
93  if (is_x2apic_mode()) {
94  uint32_t index;
95  msr_t msr;
96  index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
97  msr = rdmsr(index);
98  msr.lo &= mask;
99  msr.lo |= or;
100  wrmsr(index, msr);
101  } else {
102  uint32_t value;
103  value = xapic_read(reg);
104  value &= mask;
105  value |= or;
106  xapic_write(reg, value);
107  }
108 }
109 
110 static __always_inline void lapic_send_ipi(uint32_t icrlow, uint32_t apicid)
111 {
112  if (is_x2apic_mode())
113  x2apic_send_ipi(icrlow, apicid);
114  else
115  xapic_send_ipi(icrlow, SET_LAPIC_DEST_FIELD(apicid));
116 }
117 
118 static __always_inline int lapic_busy(void)
119 {
120  if (is_x2apic_mode())
121  return 0;
122  else
123  return xapic_busy();
124 }
125 
126 static __always_inline unsigned int initial_lapicid(void)
127 {
129  if (is_x2apic_mode() && cpuid_get_max_func() >= 0xb)
130  lapicid = cpuid_ext(0xb, 0).edx;
131  else
132  lapicid = cpuid_ebx(1) >> 24;
133  return lapicid;
134 }
135 
136 static __always_inline unsigned int lapicid(void)
137 {
139 
140  /* check x2apic mode and return accordingly */
141  if (!is_x2apic_mode())
142  lapicid >>= 24;
143  return lapicid;
144 }
145 
147 {
148  int i = 1000;
149 
150  /* LAPIC_DEST_SELF does not support all delivery mode -fields. */
151  lapic_send_ipi(icrlow, lapicid());
152 
153  /* In case of X2APIC force a short delay, to prevent deadlock in a case
154  * the immediately following code acquires some lock, like with printk().
155  */
156  while (CONFIG(X2APIC_ONLY) && i--)
157  cpu_relax();
158 }
159 
161 {
162  lapic_send_ipi(LAPIC_DEST_ALLBUT | icrlow, 0);
163 }
164 
165 #if !CONFIG(AP_IN_SIPI_WAIT)
166 /* If we need to go back to sipi wait, we use the long non-inlined version of
167  * this function in lapic_cpu_stop.c
168  */
170 {
171  /* Called by an AP when it is ready to halt and wait for a new task */
172  halt();
173 }
174 #else
175 void stop_this_cpu(void);
176 #endif
177 
178 void enable_lapic(void);
179 void disable_lapic(void);
180 void setup_lapic_interrupts(void);
181 
182 #endif /* CPU_X86_LAPIC_H */
pte_t value
Definition: mmu.c:91
static void cpu_relax(void)
Definition: cpu.h:6
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static unsigned int cpuid_get_max_func(void)
Definition: cpu.h:132
static unsigned int cpuid_ebx(unsigned int op)
Definition: cpu.h:92
static struct cpuid_result cpuid_ext(int op, unsigned int ecx)
Definition: cpu.h:59
#define __always_inline
Definition: compiler.h:35
#define LAPIC_ID
Definition: smihandler.c:52
@ CONFIG
Definition: dsi_common.h:201
void __noreturn halt(void)
halt the system reliably
Definition: halt.c:6
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
static __always_inline void wrmsr(unsigned int index, msr_t msr)
Definition: msr.h:157
static __always_inline void lapic_update32(unsigned int reg, uint32_t mask, uint32_t or)
Definition: lapic.h:91
static __always_inline void x2apic_write(unsigned int reg, uint32_t v)
Definition: lapic.h:43
static __always_inline void stop_this_cpu(void)
Definition: lapic.h:169
static __always_inline void x2apic_send_ipi(uint32_t icrlow, uint32_t icrhi)
Definition: lapic.h:54
static __always_inline void xapic_write(unsigned int reg, uint32_t v)
Definition: lapic.h:16
static __always_inline unsigned int lapicid(void)
Definition: lapic.h:136
static __always_inline void lapic_send_ipi_others(uint32_t icrlow)
Definition: lapic.h:160
static __always_inline int lapic_busy(void)
Definition: lapic.h:118
static __always_inline int xapic_busy(void)
Definition: lapic.h:27
static __always_inline void lapic_write(unsigned int reg, uint32_t v)
Definition: lapic.h:83
static __always_inline void xapic_send_ipi(uint32_t icrlow, uint32_t icrhi)
Definition: lapic.h:21
static __always_inline uint32_t xapic_read(unsigned int reg)
Definition: lapic.h:11
static __always_inline uint32_t x2apic_read(unsigned int reg)
Definition: lapic.h:32
static __always_inline bool is_x2apic_mode(void)
Definition: lapic.h:62
void setup_lapic_interrupts(void)
Definition: lapic.c:68
static __always_inline void lapic_send_ipi_self(uint32_t icrlow)
Definition: lapic.h:146
void enable_lapic(void)
Definition: lapic.c:12
void disable_lapic(void)
Definition: lapic.c:55
static __always_inline unsigned int initial_lapicid(void)
Definition: lapic.h:126
static __always_inline uint32_t lapic_read(unsigned int reg)
Definition: lapic.h:75
static __always_inline void lapic_send_ipi(uint32_t icrlow, uint32_t apicid)
Definition: lapic.h:110
#define LAPIC_ICR2
Definition: lapic_def.h:52
#define LAPIC_ICR
Definition: lapic_def.h:31
#define LAPIC_ICR_BUSY
Definition: lapic_def.h:41
#define LAPIC_BASE_X2APIC_ENABLED
Definition: lapic_def.h:8
#define LAPIC_DEST_ALLBUT
Definition: lapic_def.h:34
#define X2APIC_MSR_BASE_ADDRESS
Definition: lapic_def.h:95
#define LAPIC_BASE_MSR
Definition: lapic_def.h:4
#define SET_LAPIC_DEST_FIELD(x)
Definition: lapic_def.h:54
#define X2APIC_MSR_ICR_ADDRESS
Definition: lapic_def.h:97
#define LAPIC_DEFAULT_BASE
Definition: lapic_def.h:12
static const int mask[4]
Definition: gpio.c:308
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
uint32_t edx
Definition: cpu.h:33
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111