mb/starlabs/starbook/mtl: Correct USB Port Configuration
[coreboot2.git] / src / include / cpu / x86 / lapic.h
blob0e1384fe7ed82ecef81d8721e497838bc820d346
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #ifndef CPU_X86_LAPIC_H
4 #define CPU_X86_LAPIC_H
6 #include <arch/cpu.h>
7 #include <cpu/x86/lapic_def.h>
8 #include <cpu/x86/msr.h>
9 #include <device/mmio.h>
10 #include <halt.h>
11 #include <stdint.h>
13 static __always_inline uint32_t xapic_read(unsigned int reg)
15 return read32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg));
18 static __always_inline void xapic_write(unsigned int reg, uint32_t v)
20 write32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg), v);
23 static __always_inline void xapic_send_ipi(uint32_t icrlow, uint32_t icrhi)
25 xapic_write(LAPIC_ICR2, icrhi);
26 xapic_write(LAPIC_ICR, icrlow);
29 static __always_inline int xapic_busy(void)
31 return xapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
34 static __always_inline uint32_t x2apic_read(unsigned int reg)
36 uint32_t value, index;
37 msr_t msr;
39 index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
40 msr = rdmsr(index);
41 value = msr.lo;
42 return value;
45 static __always_inline void x2apic_write(unsigned int reg, uint32_t v)
47 uint32_t index;
48 msr_t msr;
50 index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
51 msr.hi = 0x0;
52 msr.lo = v;
53 wrmsr(index, msr);
56 static __always_inline void x2apic_send_ipi(uint32_t icrlow, uint32_t icrhi)
58 msr_t icr;
59 icr.hi = icrhi;
60 icr.lo = icrlow;
61 wrmsr(X2APIC_MSR_ICR_ADDRESS, icr);
64 static __always_inline bool is_x2apic_mode(void)
66 if (CONFIG(XAPIC_ONLY))
67 return false;
69 if (CONFIG(X2APIC_ONLY))
70 return true;
72 msr_t msr;
73 msr = rdmsr(LAPIC_BASE_MSR);
74 return ((msr.lo & LAPIC_BASE_X2APIC_ENABLED) == LAPIC_BASE_X2APIC_ENABLED);
77 static __always_inline uint32_t lapic_read(unsigned int reg)
79 if (is_x2apic_mode())
80 return x2apic_read(reg);
81 else
82 return xapic_read(reg);
85 static __always_inline void lapic_write(unsigned int reg, uint32_t v)
87 if (is_x2apic_mode())
88 x2apic_write(reg, v);
89 else
90 xapic_write(reg, v);
93 static __always_inline void lapic_update32(unsigned int reg, uint32_t mask, uint32_t or)
95 if (is_x2apic_mode()) {
96 uint32_t index;
97 msr_t msr;
98 index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
99 msr = rdmsr(index);
100 msr.lo &= mask;
101 msr.lo |= or;
102 wrmsr(index, msr);
103 } else {
104 uint32_t value;
105 value = xapic_read(reg);
106 value &= mask;
107 value |= or;
108 xapic_write(reg, value);
112 static __always_inline void lapic_send_ipi(uint32_t icrlow, uint32_t apicid)
114 if (is_x2apic_mode())
115 x2apic_send_ipi(icrlow, apicid);
116 else
117 xapic_send_ipi(icrlow, SET_LAPIC_DEST_FIELD(apicid));
120 static __always_inline int lapic_busy(void)
122 if (is_x2apic_mode())
123 return 0;
124 else
125 return xapic_busy();
128 static __always_inline unsigned int initial_lapicid(void)
130 uint32_t lapicid;
131 if (is_x2apic_mode() && cpuid_get_max_func() >= 0xb)
132 lapicid = cpuid_ext(0xb, 0).edx;
133 else
134 lapicid = cpuid_ebx(1) >> 24;
135 return lapicid;
138 static __always_inline unsigned int lapicid(void)
140 uint32_t lapicid = lapic_read(LAPIC_ID);
142 /* check x2apic mode and return accordingly */
143 if (!is_x2apic_mode())
144 lapicid >>= 24;
145 return lapicid;
148 static __always_inline void lapic_send_ipi_self(uint32_t icrlow)
150 int i = 1000;
152 /* LAPIC_DEST_SELF does not support all delivery mode -fields. */
153 lapic_send_ipi(icrlow, lapicid());
155 /* In case of X2APIC force a short delay, to prevent deadlock in a case
156 * the immediately following code acquires some lock, like with printk().
158 const bool x2apic = is_x2apic_mode();
160 while (x2apic && i--)
161 cpu_relax();
164 static __always_inline void lapic_send_ipi_others(uint32_t icrlow)
166 lapic_send_ipi(LAPIC_DEST_ALLBUT | icrlow, 0);
169 #if !CONFIG(AP_IN_SIPI_WAIT)
170 /* If we need to go back to sipi wait, we use the long non-inlined version of
171 * this function in lapic_cpu_stop.c
173 static __always_inline void stop_this_cpu(void)
175 /* Called by an AP when it is ready to halt and wait for a new task */
176 halt();
178 #else
179 void stop_this_cpu(void);
180 #endif
182 void enable_lapic(void);
183 void enable_lapic_mode(bool try_set_x2apic);
184 void setup_lapic_interrupts(void);
186 static inline unsigned int early_lapicid(void)
188 if (!CONFIG(SMP))
189 return 0;
191 if (!ENV_RAMSTAGE)
192 return 0;
194 enable_lapic();
195 return lapicid();
198 #endif /* CPU_X86_LAPIC_H */