From patchwork Thu Jun 18 08:17:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 486136 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 9D7B414016A for ; Thu, 18 Jun 2015 18:19:54 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=u00uMC9F; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7FC384B672; Thu, 18 Jun 2015 10:19:10 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ag9LHPS1ttnW; Thu, 18 Jun 2015 10:19:10 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2A5414B700; Thu, 18 Jun 2015 10:19:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DBC374B61D for ; Thu, 18 Jun 2015 10:18:53 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0dlJuHVlGk-J for ; Thu, 18 Jun 2015 10:18:53 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-qk0-f176.google.com (mail-qk0-f176.google.com [209.85.220.176]) by theia.denx.de (Postfix) with ESMTPS id 058AD4B670 for ; Thu, 18 Jun 2015 10:18:45 +0200 (CEST) Received: by qkfe185 with SMTP id e185so40180789qkf.3 for ; Thu, 18 Jun 2015 01:18:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:from:to:subject:date:in-reply-to:references:mime-version :content-type; bh=Xu7mvgTE6oV+yVZQqvxUKcKwynU7OM0SKenMbQKkZuo=; b=u00uMC9FoCyVytnkqHbKfs7tkoy5l3x6WV2GTcTi1uhFvxjYhMqpA5ldgjM8HX7Ka+ 43T6ZT6ucPVD8dtPm6UxDFfAVqdjS7pLeDoa3h/Cez3Bx+mCHYcXutAunVms0KG1Gmal Nytonei7vu09RAra7iQkH25FUf1JGVDAoeiJXzlNgjSm5c4tZelikN3oiVnvHw57doeT JNlO4URQEEyzZP8fWB4qyWSZV4bbxkcKOts7MdF12feTsNMgNJt686TiFFpCPJHqclQO h+xWCYJOhtZTUlV6/YVWApvEyDanLo/29GCwxH2gVBKX1fEEmgU2Gkg7Mn3O5l0JcPfH bFNw== X-Received: by 10.140.133.9 with SMTP id 9mr13567493qhf.5.1434615524008; Thu, 18 Jun 2015 01:18:44 -0700 (PDT) Received: from mail.hotmail.com (blu004-wss1s3.hotmail.com. [134.170.2.218]) by mx.google.com with ESMTPSA id b191sm3506362qka.14.2015.06.18.01.18.43 (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Jun 2015 01:18:43 -0700 (PDT) Received: from BLU436-SMTP221 ([134.170.2.215]) by BLU004-WSS1S3.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.22751); Thu, 18 Jun 2015 01:18:42 -0700 X-TMN: [qZgHfnLAZOFPT9QH/KsFXr4v2+lJNc3p] Message-ID: From: Bin Meng To: Simon Glass , U-Boot Mailing List Date: Thu, 18 Jun 2015 16:17:42 +0800 X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1434615467-28855-1-git-send-email-bmeng.cn@gmail.com> References: <1434615467-28855-1-git-send-email-bmeng.cn@gmail.com> X-OriginalArrivalTime: 18 Jun 2015 08:18:42.0179 (UTC) FILETIME=[6321AD30:01D0A99F] MIME-Version: 1.0 Subject: [U-Boot] [PATCH v2 10/15] x86: Remove inline for lapic access routines X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Remove inline for lapic access routines and expose lapic_read() & lapic_write() as APIs to read/write lapic registers. Also move stop_this_cpu() to mp_init.c as it has nothing to do with lapic. Signed-off-by: Bin Meng --- Changes in v2: - New patch to remove inline for lapic access routines arch/x86/cpu/lapic.c | 143 +++++++++++++++++++++++++++++++++++++------ arch/x86/cpu/mp_init.c | 27 +++++--- arch/x86/include/asm/lapic.h | 134 +++------------------------------------- 3 files changed, 153 insertions(+), 151 deletions(-) diff --git a/arch/x86/cpu/lapic.c b/arch/x86/cpu/lapic.c index 6769ae5..30d2313 100644 --- a/arch/x86/cpu/lapic.c +++ b/arch/x86/cpu/lapic.c @@ -8,9 +8,116 @@ */ #include +#include #include +#include +#include #include +unsigned long lapic_read(unsigned long reg) +{ + return readl(LAPIC_DEFAULT_BASE + reg); +} + +#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. + */ +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + 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; +} + +void lapic_write(unsigned long reg, unsigned long v) +{ + (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v); +} + +void enable_lapic(void) +{ + msr_t msr; + + msr = msr_read(MSR_IA32_APICBASE); + msr.hi &= 0xffffff00; + msr.lo |= MSR_IA32_APICBASE_ENABLE; + msr.lo &= ~MSR_IA32_APICBASE_BASE; + msr.lo |= LAPIC_DEFAULT_BASE; + msr_write(MSR_IA32_APICBASE, msr); +} + +void disable_lapic(void) +{ + msr_t msr; + + msr = msr_read(MSR_IA32_APICBASE); + msr.lo &= ~MSR_IA32_APICBASE_ENABLE; + msr_write(MSR_IA32_APICBASE, msr); +} + +unsigned long lapicid(void) +{ + return lapic_read(LAPIC_ID) >> 24; +} + +static void lapic_wait_icr_idle(void) +{ + do { } while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY); +} + +int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) +{ + int timeout; + unsigned long status; + int result; + + lapic_wait_icr_idle(); + lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid)); + lapic_write(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4)); + + timeout = 0; + do { + status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK; + } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000); + + result = -1; + if (status == LAPIC_ICR_RR_VALID) { + *pvalue = lapic_read(LAPIC_RRR); + result = 0; + } + + return result; +} + void lapic_setup(void) { #ifdef CONFIG_SMP @@ -21,26 +128,26 @@ void lapic_setup(void) enable_lapic(); /* Set Task Priority to 'accept all' */ - lapic_write_around(LAPIC_TASKPRI, - lapic_read_around(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK); + lapic_write(LAPIC_TASKPRI, + lapic_read(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK); /* Put the local apic in virtual wire mode */ - lapic_write_around(LAPIC_SPIV, (lapic_read_around(LAPIC_SPIV) & - ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE); - lapic_write_around(LAPIC_LVT0, (lapic_read_around(LAPIC_LVT0) & - ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | - LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | - LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | - LAPIC_DELIVERY_MODE_MASK)) | - (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | - LAPIC_DELIVERY_MODE_EXTINT)); - lapic_write_around(LAPIC_LVT1, (lapic_read_around(LAPIC_LVT1) & - ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | - LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | - LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | - LAPIC_DELIVERY_MODE_MASK)) | - (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | - LAPIC_DELIVERY_MODE_NMI)); + lapic_write(LAPIC_SPIV, (lapic_read(LAPIC_SPIV) & + ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE); + lapic_write(LAPIC_LVT0, (lapic_read(LAPIC_LVT0) & + ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | + LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | + LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | + LAPIC_DELIVERY_MODE_MASK)) | + (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | + LAPIC_DELIVERY_MODE_EXTINT)); + lapic_write(LAPIC_LVT1, (lapic_read(LAPIC_LVT1) & + ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER | + LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY | + LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 | + LAPIC_DELIVERY_MODE_MASK)) | + (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING | + LAPIC_DELIVERY_MODE_NMI)); debug("apic_id: 0x%02lx, ", lapicid()); #else /* !CONFIG_SMP */ diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index e8bc9b6..e686b28 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -59,6 +61,13 @@ static inline void release_barrier(atomic_t *b) atomic_set(b, 1); } +static inline void stop_this_cpu(void) +{ + /* Called by an AP when it is ready to halt and wait for a new task */ + for (;;) + cpu_hlt(); +} + /* Returns 1 if timeout waiting for APs. 0 if target APs found */ static int wait_for_aps(atomic_t *val, int target, int total_delay, int delay_step) @@ -317,9 +326,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } /* Send INIT IPI to all but self */ - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_INIT); + lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); + lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | + LAPIC_DM_INIT); debug("Waiting for 10ms after sending INIT.\n"); mdelay(10); @@ -334,9 +343,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } } - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_STARTUP | sipi_vector); + lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); + lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | + LAPIC_DM_STARTUP | sipi_vector); debug("Waiting for 1st SIPI to complete..."); if (apic_wait_timeout(10000, 50)) { debug("timed out.\n"); @@ -359,9 +368,9 @@ static int start_aps(int ap_count, atomic_t *num_aps) } } - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); - lapic_write_around(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | - LAPIC_DM_STARTUP | sipi_vector); + lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); + lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | + LAPIC_DM_STARTUP | sipi_vector); debug("Waiting for 2nd SIPI to complete..."); if (apic_wait_timeout(10000, 50)) { debug("timed out.\n"); diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h index f60974a..bc2b2d1 100644 --- a/arch/x86/include/asm/lapic.h +++ b/arch/x86/include/asm/lapic.h @@ -9,11 +9,6 @@ #ifndef _ARCH_ASM_LAPIC_H #define _ARCH_ASM_LAPIC_H -#include -#include -#include -#include - #define LAPIC_DEFAULT_BASE 0xfee00000 #define LAPIC_ID 0x020 @@ -66,126 +61,17 @@ #define LAPIC_DELIVERY_MODE_NMI (4 << 8) #define LAPIC_DELIVERY_MODE_EXTINT (7 << 8) -static inline __attribute__((always_inline)) - unsigned long lapic_read(unsigned long reg) -{ - return readl(LAPIC_DEFAULT_BASE + reg); -} - -static inline __attribute__((always_inline)) - void lapic_write(unsigned long reg, unsigned long val) -{ - writel(val, LAPIC_DEFAULT_BASE + reg); -} - -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) -{ - msr_t msr; - - msr = msr_read(MSR_IA32_APICBASE); - msr.hi &= 0xffffff00; - msr.lo |= MSR_IA32_APICBASE_ENABLE; - msr.lo &= ~MSR_IA32_APICBASE_BASE; - msr.lo |= LAPIC_DEFAULT_BASE; - msr_write(MSR_IA32_APICBASE, msr); -} - -static inline void disable_lapic(void) -{ - msr_t msr; - - msr = msr_read(MSR_IA32_APICBASE); - msr.lo &= ~MSR_IA32_APICBASE_ENABLE; - msr_write(MSR_IA32_APICBASE, msr); -} - -static inline __attribute__((always_inline)) unsigned long lapicid(void) -{ - return lapic_read(LAPIC_ID) >> 24; -} - -static inline __attribute__((always_inline)) void stop_this_cpu(void) -{ - /* Called by an AP when it is ready to halt and wait for a new task */ - for (;;) - cpu_hlt(); -} - -#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)) +unsigned long lapic_read(unsigned long reg); -/* - * 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. - */ -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, - int size) -{ - 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; -} - -static inline void lapic_write_atomic(unsigned long reg, unsigned long v) -{ - (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v); -} - -#define lapic_read_around(x) lapic_read(x) -#define lapic_write_around(x, y) lapic_write_atomic((x), (y)) - -static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) -{ - int timeout; - unsigned long status; - int result; - - lapic_wait_icr_idle(); - lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid)); - lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4)); - - timeout = 0; - do { - status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK; - } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000); - - result = -1; - if (status == LAPIC_ICR_RR_VALID) { - *pvalue = lapic_read(LAPIC_RRR); - result = 0; - } - - return result; -} +void lapic_write(unsigned long reg, unsigned long v); + +void enable_lapic(void); + +void disable_lapic(void); + +unsigned long lapicid(void); + +int lapic_remote_read(int apicid, int reg, unsigned long *pvalue); void lapic_setup(void);