Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13c88fb5 authored by Suresh Siddha's avatar Suresh Siddha Committed by Ingo Molnar
Browse files

x64, x2apic/intr-remap: x2apic ops for x2apic mode support



x2apic ops for x2apic mode support. This uses MSR interface and differs
slightly from the xapic register layout.

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Cc: akpm@linux-foundation.org
Cc: arjan@linux.intel.com
Cc: andi@firstfloor.org
Cc: ebiederm@xmission.com
Cc: jbarnes@virtuousgeek.org
Cc: steiner@sgi.com
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 1cb11583
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -171,6 +171,41 @@ struct apic_ops __read_mostly *apic_ops = &xapic_ops;

EXPORT_SYMBOL_GPL(apic_ops);

static void x2apic_wait_icr_idle(void)
{
	/* no need to wait for icr idle in x2apic */
	return;
}

static u32 safe_x2apic_wait_icr_idle(void)
{
	/* no need to wait for icr idle in x2apic */
	return 0;
}

void x2apic_icr_write(u32 low, u32 id)
{
	wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
}

u64 x2apic_icr_read(void)
{
	unsigned long val;

	rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
	return val;
}

static struct apic_ops x2apic_ops = {
	.read = native_apic_msr_read,
	.write = native_apic_msr_write,
	.write_atomic = native_apic_msr_write,
	.icr_read = x2apic_icr_read,
	.icr_write = x2apic_icr_write,
	.wait_icr_idle = x2apic_wait_icr_idle,
	.safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
};

/**
 * enable_NMI_through_LVT0 - enable NMI through local vector table 0
 */
+22 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#include <asm/apicdef.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/cpufeature.h>
#include <asm/msr.h>

#define ARCH_APICTIMER_STOPS_ON_C3	1

@@ -73,6 +75,26 @@ static inline u32 native_apic_mem_read(u32 reg)
	return *((volatile u32 *)(APIC_BASE + reg));
}

static inline void native_apic_msr_write(u32 reg, u32 v)
{
	if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
	    reg == APIC_LVR)
		return;

	wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
}

static inline u32 native_apic_msr_read(u32 reg)
{
	u32 low, high;

	if (reg == APIC_DFR)
		return -1;

	rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
	return low;
}

#ifdef CONFIG_X86_32
extern void apic_wait_icr_idle(void);
extern u32 safe_apic_wait_icr_idle(void);
+3 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@
#define	APIC_TMICT	0x380
#define	APIC_TMCCT	0x390
#define	APIC_TDCR	0x3E0
#define APIC_SELF_IPI	0x3F0
#define		APIC_TDR_DIV_TMBASE	(1 << 2)
#define		APIC_TDR_DIV_1		0xB
#define		APIC_TDR_DIV_2		0x0
@@ -128,6 +129,8 @@
#define	APIC_EILVT3     0x530

#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#define APIC_BASE_MSR	0x800
#define X2APIC_ENABLE	(1UL << 10)

#ifdef CONFIG_X86_32
# define MAX_IO_APICS 64