cpu/x86/lapic: Support x86_64 and clean up code

Most LAPIC registers are 32bit, and thus the use of long is valid on
x86_32, however it doesn't work on x86_64.

* Don't use long as it is 64bit on x86_64, which breaks interrupts
  in QEMU and thus SeaBIOS wouldn't time out the boot menu
* Get rid of unused defines
* Get rid of unused atomic xchg code

Tested on QEMU Q35 with x86_64 enabled: Interrupts work again.
Tested on QEMU Q35 with x86_32 enabled: Interrupts are still working.
Tested on Lenovo T410 with x86_64 enabled.

Change-Id: Iaed1ad956d090625c7bb5cd9cf55cbae16dd82bd
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36777
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h
index f8081b5..28978f2 100644
--- a/src/include/cpu/x86/lapic.h
+++ b/src/include/cpu/x86/lapic.h
@@ -1,18 +1,20 @@
 #ifndef CPU_X86_LAPIC_H
 #define CPU_X86_LAPIC_H
 
+#include <arch/mmio.h>
 #include <cpu/x86/lapic_def.h>
 #include <cpu/x86/msr.h>
 #include <halt.h>
+#include <stdint.h>
 
-static __always_inline unsigned long lapic_read(unsigned long reg)
+static __always_inline uint32_t lapic_read(unsigned int reg)
 {
-	return *((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg));
+	return read32((volatile void *)(LAPIC_DEFAULT_BASE + reg));
 }
 
-static __always_inline void lapic_write(unsigned long reg, unsigned long v)
+static __always_inline void lapic_write(unsigned int reg, uint32_t v)
 {
-	*((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg)) = v;
+	write32((volatile void *)(LAPIC_DEFAULT_BASE + reg), v);
 }
 
 static __always_inline void lapic_wait_icr_idle(void)
@@ -39,7 +41,7 @@
 	wrmsr(LAPIC_BASE_MSR, msr);
 }
 
-static __always_inline unsigned long lapicid(void)
+static __always_inline unsigned int lapicid(void)
 {
 	return lapic_read(LAPIC_ID) >> 24;
 }
@@ -57,58 +59,19 @@
 void stop_this_cpu(void);
 #endif
 
-#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \
-	sizeof(*(ptr))))
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((struct __xchg_dummy *)(x))
-
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- *	  but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
-	int size)
+static inline void lapic_write_atomic(unsigned long reg, uint32_t v)
 {
-	switch (size) {
-	case 1:
-		__asm__ __volatile__("xchgb %b0,%1"
-			: "=q" (x)
-			: "m" (*__xg(ptr)), "0" (x)
-			: "memory");
-		break;
-	case 2:
-		__asm__ __volatile__("xchgw %w0,%1"
-			: "=r" (x)
-			: "m" (*__xg(ptr)), "0" (x)
-			: "memory");
-		break;
-	case 4:
-		__asm__ __volatile__("xchgl %0,%1"
-			: "=r" (x)
-			: "m" (*__xg(ptr)), "0" (x)
-			: "memory");
-		break;
-	}
-	return x;
+	volatile uint32_t *ptr;
+
+	ptr = (volatile uint32_t *)(LAPIC_DEFAULT_BASE + reg);
+
+	asm volatile ("xchgl %0, %1\n"
+		      : "+r" (v), "+m" (*(ptr))
+		      : : "memory", "cc");
 }
 
-static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
-{
-	(void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v);
-}
-
-
-#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))
-#else
-# define FORCE_READ_AROUND_WRITE 1
 # define lapic_read_around(x) lapic_read(x)
 # define lapic_write_around(x, y) lapic_write_atomic((x), (y))
-#endif
 
 void do_lapic_init(void);