/* See if I need to initialize the local apic */
#if CONFIG_SMP || CONFIG_IOAPIC
# define NEED_LAPIC 1
+#else
+# define NEED_LAPIC 0
#endif
-static inline unsigned long lapic_read(unsigned long reg)
+static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg)
{
return *((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg));
}
-static inline void lapic_write(unsigned long reg, unsigned long v)
+static inline __attribute__((always_inline)) void lapic_write(unsigned long reg, unsigned long v)
{
*((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg)) = v;
}
-static inline void lapic_wait_icr_idle(void)
+static inline __attribute__((always_inline)) void lapic_wait_icr_idle(void)
{
do { } while ( lapic_read( LAPIC_ICR ) & LAPIC_ICR_BUSY );
}
-
-
static inline void enable_lapic(void)
{
wrmsr(LAPIC_BASE_MSR, msr);
}
-static inline unsigned long lapicid(void)
+static inline __attribute__((always_inline)) unsigned long lapicid(void)
{
return lapic_read(LAPIC_ID) >> 24;
}
-static inline void stop_this_cpu(void)
+#ifndef __ROMCC__
+#if CONFIG_AP_IN_SIPI_WAIT != 1
+/* If we need to go back to sipi wait, we use the long non-inlined version of
+ * this function in lapic_cpu_init.c
+ */
+static inline __attribute__((always_inline)) void stop_this_cpu(void)
{
- unsigned apicid;
- apicid = lapicid();
-
- /* Send an APIC INIT to myself */
- lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
- lapic_write(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
- /* Wait for the ipi send to finish */
- lapic_wait_icr_idle();
-
- /* Deassert the APIC INIT */
- lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
- lapic_write(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
- /* Wait for the ipi send to finish */
- lapic_wait_icr_idle();
-
- /* If I haven't halted spin forever */
+ /* Called by an AP when it is ready to halt and wait for a new task */
for(;;) {
hlt();
}
}
+#else
+void stop_this_cpu(void);
+#endif
-#if ! defined (__ROMCC__)
+#if !defined(__PRE_RAM__)
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
return x;
}
-
-extern inline void lapic_write_atomic(unsigned long reg, unsigned long v)
+static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
{
- xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v);
+ (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v);
}
-#ifdef CONFIG_X86_GOOD_APIC
+#ifdef X86_GOOD_APIC
# define FORCE_READ_AROUND_WRITE 0
# define lapic_read_around(x) lapic_read(x)
# define lapic_write_around(x,y) lapic_write((x),(y))
void setup_lapic(void);
-
#if CONFIG_SMP == 1
struct device;
int start_cpu(struct device *cpu);
-
#endif /* CONFIG_SMP */
+#endif /* !__PRE_RAM__ */
-#endif /* !__ROMCC__ */
+int boot_cpu(void);
+#endif
#endif /* CPU_X86_LAPIC_H */