From: Suresh Siddha <suresh.b.siddha@intel.com>
To: mingo@elte.hu, hpa@zytor.com, tglx@linutronix.de,
akpm@linux-foundation.org, arjan@linux.intel.com,
andi@firstfloor.org, ebiederm@xmission.com,
jbarnes@virtuousgeek.org, steiner@sgi.com
Cc: linux-kernel@vger.kernel.org, Suresh Siddha <suresh.b.siddha@intel.com>
Subject: [patch 15/26] x64, x2apic/intr-remap: basic apic ops support
Date: Thu, 10 Jul 2008 11:16:49 -0700 [thread overview]
Message-ID: <20080710182238.058684000@linux-os.sc.intel.com> (raw)
In-Reply-To: 20080710181634.764954000@linux-os.sc.intel.com
[-- Attachment #1: apic_ops.patch --]
[-- Type: text/plain, Size: 11951 bytes --]
Introduce basic apic operations which handle the apic programming. This
will be used later to introduce another specific operations for x2apic.
For the perfomance critial accesses like IPI's, EOI etc, we use the
native operations as they are already referenced by different
indirections like genapic, irq_chip etc.
64bit Paravirt ops can also define their apic operations accordingly.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
Index: tree-x86/arch/x86/kernel/apic_64.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/apic_64.c 2008-07-10 09:52:12.000000000 -0700
+++ tree-x86/arch/x86/kernel/apic_64.c 2008-07-10 09:52:14.000000000 -0700
@@ -119,13 +119,13 @@
return lapic_get_version() >= 0x14;
}
-void apic_wait_icr_idle(void)
+void xapic_wait_icr_idle(void)
{
while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
cpu_relax();
}
-u32 safe_apic_wait_icr_idle(void)
+u32 safe_xapic_wait_icr_idle(void)
{
u32 send_status;
int timeout;
@@ -141,6 +141,36 @@
return send_status;
}
+void xapic_icr_write(u32 low, u32 id)
+{
+ apic_write(APIC_ICR2, id << 24);
+ apic_write(APIC_ICR, low);
+}
+
+u64 xapic_icr_read(void)
+{
+ u32 icr1, icr2;
+
+ icr2 = apic_read(APIC_ICR2);
+ icr1 = apic_read(APIC_ICR);
+
+ return (icr1 | ((u64)icr2 << 32));
+}
+
+static struct apic_ops xapic_ops = {
+ .read = native_apic_mem_read,
+ .write = native_apic_mem_write,
+ .write_atomic = native_apic_mem_write_atomic,
+ .icr_read = xapic_icr_read,
+ .icr_write = xapic_icr_write,
+ .wait_icr_idle = xapic_wait_icr_idle,
+ .safe_wait_icr_idle = safe_xapic_wait_icr_idle,
+};
+
+struct apic_ops __read_mostly *apic_ops = &xapic_ops;
+
+EXPORT_SYMBOL_GPL(apic_ops);
+
/**
* enable_NMI_through_LVT0 - enable NMI through local vector table 0
*/
Index: tree-x86/arch/x86/kernel/paravirt.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/paravirt.c 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/arch/x86/kernel/paravirt.c 2008-07-10 09:52:14.000000000 -0700
@@ -373,9 +373,11 @@
struct pv_apic_ops pv_apic_ops = {
#ifdef CONFIG_X86_LOCAL_APIC
- .apic_write = native_apic_write,
- .apic_write_atomic = native_apic_write_atomic,
- .apic_read = native_apic_read,
+#ifnded CONFIG_X86_64
+ .apic_write = native_apic_mem_write,
+ .apic_write_atomic = native_apic_mem_write_atomic,
+ .apic_read = native_apic_mem_read,
+#endif
.setup_boot_clock = setup_boot_APIC_clock,
.setup_secondary_clock = setup_secondary_APIC_clock,
.startup_ipi_hook = paravirt_nop,
Index: tree-x86/include/asm-x86/apic.h
===================================================================
--- tree-x86.orig/include/asm-x86/apic.h 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/include/asm-x86/apic.h 2008-07-10 09:52:14.000000000 -0700
@@ -47,32 +47,59 @@
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
-#define apic_write native_apic_write
-#define apic_write_atomic native_apic_write_atomic
-#define apic_read native_apic_read
+#ifndef CONFIG_X86_64
+#define apic_write native_apic_mem_write
+#define apic_write_atomic native_apic_mem_write_atomic
+#define apic_read native_apic_mem_read
+#endif
#define setup_boot_clock setup_boot_APIC_clock
#define setup_secondary_clock setup_secondary_APIC_clock
#endif
extern int is_vsmp_box(void);
-static inline void native_apic_write(unsigned long reg, u32 v)
+static inline void native_apic_mem_write(u32 reg, u32 v)
{
*((volatile u32 *)(APIC_BASE + reg)) = v;
}
-static inline void native_apic_write_atomic(unsigned long reg, u32 v)
+static inline void native_apic_mem_write_atomic(u32 reg, u32 v)
{
(void)xchg((u32 *)(APIC_BASE + reg), v);
}
-static inline u32 native_apic_read(unsigned long reg)
+static inline u32 native_apic_mem_read(u32 reg)
{
return *((volatile u32 *)(APIC_BASE + reg));
}
+#ifdef CONFIG_X86_32
extern void apic_wait_icr_idle(void);
extern u32 safe_apic_wait_icr_idle(void);
+extern void apic_icr_write(u32 low, u32 id);
+#else
+
+struct apic_ops {
+ u32 (*read)(u32 reg);
+ void (*write)(u32 reg, u32 v);
+ void (*write_atomic)(u32 reg, u32 v);
+ u64 (*icr_read)(void);
+ void (*icr_write)(u32 low, u32 high);
+ void (*wait_icr_idle)(void);
+ u32 (*safe_wait_icr_idle)(void);
+};
+
+extern struct apic_ops *apic_ops;
+
+#define apic_read (apic_ops->read)
+#define apic_write (apic_ops->write)
+#define apic_write_atomic (apic_ops->write_atomic)
+#define apic_icr_read (apic_ops->icr_read)
+#define apic_icr_write (apic_ops->icr_write)
+#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
+#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle)
+#endif
+
extern int get_physical_broadcast(void);
#ifdef CONFIG_X86_GOOD_APIC
@@ -95,7 +122,11 @@
*/
/* Docs say use 0 for future compatibility */
+#ifdef CONFIG_X86_32
apic_write_around(APIC_EOI, 0);
+#else
+ native_apic_mem_write(APIC_EOI, 0);
+#endif
}
extern int lapic_get_maxlvt(void);
Index: tree-x86/include/asm-x86/paravirt.h
===================================================================
--- tree-x86.orig/include/asm-x86/paravirt.h 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/include/asm-x86/paravirt.h 2008-07-10 09:52:14.000000000 -0700
@@ -902,6 +902,7 @@
/*
* Basic functions accessing APICs.
*/
+#ifndef CONFIG_X86_64
static inline void apic_write(unsigned long reg, u32 v)
{
PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);
@@ -916,6 +917,7 @@
{
return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);
}
+#endif
static inline void setup_boot_clock(void)
{
Index: tree-x86/include/asm-x86/ipi.h
===================================================================
--- tree-x86.orig/include/asm-x86/ipi.h 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/include/asm-x86/ipi.h 2008-07-10 09:52:14.000000000 -0700
@@ -49,6 +49,12 @@
return SET_APIC_DEST_FIELD(mask);
}
+static inline void __xapic_wait_icr_idle(void)
+{
+ while (native_apic_mem_read(APIC_ICR) & APIC_ICR_BUSY)
+ cpu_relax();
+}
+
static inline void __send_IPI_shortcut(unsigned int shortcut, int vector,
unsigned int dest)
{
@@ -64,7 +70,7 @@
/*
* Wait for idle.
*/
- apic_wait_icr_idle();
+ __xapic_wait_icr_idle();
/*
* No need to touch the target chip field
@@ -74,7 +80,7 @@
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write(APIC_ICR, cfg);
+ native_apic_mem_write(APIC_ICR, cfg);
}
/*
@@ -92,13 +98,13 @@
if (unlikely(vector == NMI_VECTOR))
safe_apic_wait_icr_idle();
else
- apic_wait_icr_idle();
+ __xapic_wait_icr_idle();
/*
* prepare target chip field
*/
cfg = __prepare_ICR2(mask);
- apic_write(APIC_ICR2, cfg);
+ native_apic_mem_write(APIC_ICR2, cfg);
/*
* program the ICR
@@ -108,7 +114,7 @@
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write(APIC_ICR, cfg);
+ native_apic_mem_write(APIC_ICR, cfg);
}
static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
Index: tree-x86/arch/x86/kernel/apic_32.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/apic_32.c 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/arch/x86/kernel/apic_32.c 2008-07-10 09:52:14.000000000 -0700
@@ -145,6 +145,12 @@
return lapic_get_version() >= 0x14;
}
+void apic_icr_write(u32 low, u32 id)
+{
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(id));
+ apic_write_around(APIC_ICR, low);
+}
+
void apic_wait_icr_idle(void)
{
while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
Index: tree-x86/arch/x86/kernel/smpboot.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/smpboot.c 2008-07-10 09:51:45.000000000 -0700
+++ tree-x86/arch/x86/kernel/smpboot.c 2008-07-10 09:52:14.000000000 -0700
@@ -123,7 +123,6 @@
static atomic_t init_deasserted;
-static int boot_cpu_logical_apicid;
/* representing cpus for which sibling maps can be computed */
static cpumask_t cpu_sibling_setup_map;
@@ -165,6 +164,8 @@
#endif
#ifdef CONFIG_X86_32
+static int boot_cpu_logical_apicid;
+
u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = BAD_APICID };
@@ -546,8 +547,7 @@
printk(KERN_CONT
"a previous APIC delivery may have failed\n");
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
- apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
+ apic_icr_write(APIC_DM_REMRD | regs[i], apicid);
timeout = 0;
do {
@@ -579,11 +579,9 @@
int maxlvt;
/* Target chip */
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
-
/* Boot on the stack */
/* Kick the second */
- apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL);
+ apic_icr_write(APIC_DM_NMI | APIC_DEST_LOGICAL, logical_apicid);
Dprintk("Waiting for send to finish...\n");
send_status = safe_apic_wait_icr_idle();
@@ -639,13 +637,11 @@
/*
* Turn INIT on target chip
*/
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
-
/*
* Send IPI
*/
- apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
- | APIC_DM_INIT);
+ apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
+ phys_apicid);
Dprintk("Waiting for send to finish...\n");
send_status = safe_apic_wait_icr_idle();
@@ -655,10 +651,8 @@
Dprintk("Deasserting INIT.\n");
/* Target chip */
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
-
/* Send IPI */
- apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+ apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
Dprintk("Waiting for send to finish...\n");
send_status = safe_apic_wait_icr_idle();
@@ -703,12 +697,10 @@
*/
/* Target chip */
- apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
-
/* Boot on the stack */
/* Kick the second */
- apic_write_around(APIC_ICR, APIC_DM_STARTUP
- | (start_eip >> 12));
+ apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
+ phys_apicid);
/*
* Give the other CPU some time to accept the IPI.
@@ -1147,7 +1139,9 @@
* Setup boot CPU information
*/
smp_store_cpu_info(0); /* Final full version of the data */
+#ifdef CONFIG_X86_32
boot_cpu_logical_apicid = logical_smp_processor_id();
+#endif
current_thread_info()->cpu = 0; /* needed? */
set_cpu_sibling_map(0);
Index: tree-x86/arch/x86/kernel/io_apic_64.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/io_apic_64.c 2008-07-10 09:52:11.000000000 -0700
+++ tree-x86/arch/x86/kernel/io_apic_64.c 2008-07-10 09:52:14.000000000 -0700
@@ -1157,6 +1157,7 @@
void __apicdebuginit print_local_APIC(void * dummy)
{
unsigned int v, ver, maxlvt;
+ unsigned long icr;
if (apic_verbosity == APIC_QUIET)
return;
@@ -1200,10 +1201,9 @@
v = apic_read(APIC_ESR);
printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
- v = apic_read(APIC_ICR);
- printk(KERN_DEBUG "... APIC ICR: %08x\n", v);
- v = apic_read(APIC_ICR2);
- printk(KERN_DEBUG "... APIC ICR2: %08x\n", v);
+ icr = apic_icr_read();
+ printk(KERN_DEBUG "... APIC ICR: %08x\n", icr);
+ printk(KERN_DEBUG "... APIC ICR2: %08x\n", icr >> 32);
v = apic_read(APIC_LVTT);
printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
Index: tree-x86/include/asm-x86/smp.h
===================================================================
--- tree-x86.orig/include/asm-x86/smp.h 2008-07-10 09:52:12.000000000 -0700
+++ tree-x86/include/asm-x86/smp.h 2008-07-10 09:52:14.000000000 -0700
@@ -165,13 +165,13 @@
#ifdef CONFIG_X86_LOCAL_APIC
+#ifndef CONFIG_X86_64
static inline int logical_smp_processor_id(void)
{
/* we don't want to mark this access volatile - bad code generation */
return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR));
}
-#ifndef CONFIG_X86_64
static inline unsigned int read_apic_id(void)
{
return *(u32 *)(APIC_BASE + APIC_ID);
--
next prev parent reply other threads:[~2008-07-10 18:44 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-10 18:16 [patch 00/26] x64, x2apic/intr-remap: Interrupt-remapping and x2apic support Suresh Siddha
2008-07-10 18:16 ` [patch 01/26] x64, x2apic/intr-remap: Intel vt-d, IOMMU code reorganization Suresh Siddha
2008-07-10 18:16 ` [patch 02/26] x64, x2apic/intr-remap: fix the need for sequential array allocation of iommus Suresh Siddha
2008-07-10 18:16 ` [patch 03/26] x64, x2apic/intr-remap: code re-structuring, to be used by both DMA and Interrupt remapping Suresh Siddha
2008-07-10 18:16 ` [patch 04/26] x64, x2apic/intr-remap: use CONFIG_DMAR for DMA-remapping specific code Suresh Siddha
2008-07-10 18:16 ` [patch 05/26] x64, x2apic/intr-remap: Fix the need for RMRR in the DMA-remapping detection Suresh Siddha
2008-07-10 18:16 ` [patch 06/26] x64, x2apic/intr-remap: parse ioapic scope under vt-d structures Suresh Siddha
2008-07-10 18:16 ` [patch 07/26] x64, x2apic/intr-remap: move IOMMU_WAIT_OP() macro to intel-iommu.h Suresh Siddha
2008-07-10 18:16 ` [patch 08/26] x64, x2apic/intr-remap: Queued invalidation infrastructure (part of VT-d) Suresh Siddha
2008-07-10 18:16 ` [patch 09/26] x64, x2apic/intr-remap: Interrupt remapping infrastructure Suresh Siddha
2008-07-10 18:16 ` [patch 10/26] x64, x2apic/intr-remap: routines managing Interrupt remapping table entries Suresh Siddha
2008-07-10 18:16 ` [patch 11/26] x64, x2apic/intr-remap: generic irq migration support from process context Suresh Siddha
2008-07-10 23:08 ` Eric W. Biederman
2008-07-11 5:41 ` Suresh Siddha
2008-07-11 9:19 ` Eric W. Biederman
2008-07-10 18:16 ` [patch 12/26] x64, x2apic/intr-remap: 8259 specific mask/unmask routines Suresh Siddha
2008-07-10 18:16 ` [patch 13/26] x64, x2apic/intr-remap: ioapic routines which deal with initial io-apic RTE setup Suresh Siddha
2008-07-10 18:16 ` [patch 14/26] x64, x2apic/intr-remap: introduce read_apic_id() to genapic routines Suresh Siddha
2008-07-10 18:16 ` Suresh Siddha [this message]
2008-07-10 18:16 ` [patch 16/26] x64, x2apic/intr-remap: cpuid bits for x2apic feature Suresh Siddha
2008-07-10 18:16 ` [patch 17/26] x64, x2apic/intr-remap: disable DMA-remapping if Interrupt-remapping is detected (temporary quirk) Suresh Siddha
2008-07-10 18:16 ` [patch 18/26] x64, x2apic/intr-remap: x2apic ops for x2apic mode support Suresh Siddha
2008-07-10 18:16 ` [patch 19/26] x64, x2apic/intr-remap: introcude self IPI to genapic routines Suresh Siddha
2008-07-10 23:34 ` Eric W. Biederman
2008-07-11 2:29 ` Mike Travis
2008-07-11 3:50 ` Eric W. Biederman
2008-07-11 13:55 ` Mike Travis
2008-07-10 18:16 ` [patch 20/26] x64, x2apic/intr-remap: x2apic cluster mode support Suresh Siddha
2008-07-10 18:16 ` [patch 21/26] x64, x2apic/intr-remap: setup init_apic_ldr for UV Suresh Siddha
2008-07-11 0:14 ` Andrew Morton
2008-07-11 1:56 ` Suresh Siddha
2008-07-10 18:16 ` [patch 22/26] x64, x2apic/intr-remap: IO-APIC support for interrupt-remapping Suresh Siddha
2008-07-10 18:16 ` [patch 23/26] x64, x2apic/intr-remap: MSI and MSI-X support for interrupt remapping infrastructure Suresh Siddha
2008-07-11 1:22 ` Eric W. Biederman
2008-07-11 6:07 ` Suresh Siddha
2008-07-11 8:59 ` Eric W. Biederman
2008-07-11 23:07 ` Suresh Siddha
2008-07-11 23:50 ` Eric W. Biederman
2008-07-10 18:16 ` [patch 24/26] x64, x2apic/intr-remap: add x2apic support, including enabling interrupt-remapping Suresh Siddha
2008-07-10 18:16 ` [patch 25/26] x64, x2apic/intr-remap: support for x2apic physical mode support Suresh Siddha
2008-07-10 18:17 ` [patch 26/26] x64, x2apic/intr-remap: introduce CONFIG_INTR_REMAP Suresh Siddha
2008-07-10 23:29 ` Eric W. Biederman
2008-07-10 23:37 ` Yong Wang
2008-07-11 1:50 ` Suresh Siddha
2008-07-11 1:53 ` Eric W. Biederman
2008-07-10 19:53 ` [patch 00/26] x64, x2apic/intr-remap: Interrupt-remapping and x2apic support Ingo Molnar
2008-07-10 20:22 ` Suresh Siddha
2008-07-10 21:56 ` Suresh Siddha
2008-07-11 10:28 ` Ingo Molnar
2008-07-11 20:09 ` Ingo Molnar
2008-07-11 20:31 ` Suresh Siddha
2008-07-11 20:42 ` Yinghai Lu
2008-07-11 20:45 ` Ingo Molnar
2008-07-11 21:24 ` Suresh Siddha
2008-07-11 22:02 ` Yinghai Lu
2008-07-12 3:16 ` Yinghai Lu
2008-07-12 3:52 ` Eric W. Biederman
2008-07-12 6:17 ` Yinghai Lu
2008-07-12 7:02 ` Eric W. Biederman
2008-07-12 7:49 ` Yinghai Lu
2008-07-12 8:11 ` Eric W. Biederman
2008-07-12 8:37 ` Yinghai Lu
2008-07-12 9:46 ` Eric W. Biederman
2008-07-13 1:02 ` Suresh Siddha
2008-07-13 1:01 ` Suresh Siddha
2008-07-13 1:32 ` Suresh Siddha
2008-07-13 1:00 ` Suresh Siddha
2008-07-13 0:55 ` Suresh Siddha
2008-07-12 5:37 ` Ingo Molnar
2008-07-12 6:06 ` Yinghai Lu
2008-07-12 6:45 ` Ingo Molnar
2008-07-11 20:49 ` Ingo Molnar
2008-07-16 14:37 ` Yong Wang
2008-07-16 14:53 ` Ingo Molnar
2008-07-22 20:49 ` Andrew Morton
2008-07-22 21:00 ` Mike Travis
2008-07-22 21:14 ` Andrew Morton
2008-07-24 5:03 ` Ingo Molnar
2008-07-10 20:05 ` Eric W. Biederman
2008-07-10 20:18 ` Ingo Molnar
2008-07-10 21:07 ` Eric W. Biederman
2008-07-10 21:15 ` Suresh Siddha
2008-07-10 22:52 ` Eric W. Biederman
2008-07-11 2:35 ` Suresh Siddha
2008-07-11 3:15 ` Eric W. Biederman
2008-07-10 22:09 ` Arjan van de Ven
2008-07-10 22:54 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080710182238.058684000@linux-os.sc.intel.com \
--to=suresh.b.siddha@intel.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=arjan@linux.intel.com \
--cc=ebiederm@xmission.com \
--cc=hpa@zytor.com \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=steiner@sgi.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox