From patchwork Sun Jun 7 03:33:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 481696 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 B937414010F for ; Sun, 7 Jun 2015 13:34:29 +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=Y4MNyhfk; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 378F54B703; Sun, 7 Jun 2015 05:34:28 +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 goCSAfQTOF5S; Sun, 7 Jun 2015 05:34:27 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A36DB4B65D; Sun, 7 Jun 2015 05:34:27 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A669A4B703 for ; Sun, 7 Jun 2015 05:34:24 +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 fiYscYm_lSSY for ; Sun, 7 Jun 2015 05:34:24 +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-f182.google.com (mail-qk0-f182.google.com [209.85.220.182]) by theia.denx.de (Postfix) with ESMTPS id 47D624B6FC for ; Sun, 7 Jun 2015 05:34:19 +0200 (CEST) Received: by qkoo18 with SMTP id o18so61346410qko.1 for ; Sat, 06 Jun 2015 20:34:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:from:to:cc:subject:date:in-reply-to:references :mime-version:content-type; bh=cAP56FG1TXP0wlhoYUwE5YDJB2MxmktW5fNfDxhGvqM=; b=Y4MNyhfk+lO56fIHAslWfej/KURM6ADfEvgtUHpaCVClSJZBIFsRzuzSN7tnJaWRl6 C41ad+9vOytNMQ8pmg+EUsZ26NJkKzEx437vl3cbV4ps8TZDR6xIZ5q0S9yC2kEv8YYP sr/snk7gTlMsvXqhOJQpAxY0IftEMWXatHVXPXg7qTwIgZq7QyS+pLEgI2HTL+zTf5zI +eOiAMkE5BPczgAFgfmFA+JL5+tI8IRfBRc9YlvkP0k8N5NcpjP53u/tRpKEFbHBTn9S V4gsF5BCFeKXXLjSS6uz8cZiYd4+Mr38syfORAR7F25PsQHxEMh4xCVtnvzqj7rxi49z QaOw== X-Received: by 10.55.22.143 with SMTP id 15mr20512819qkw.85.1433648058802; Sat, 06 Jun 2015 20:34:18 -0700 (PDT) Received: from mail.hotmail.com (blu004-wss1s6.hotmail.com. [134.170.2.221]) by mx.google.com with ESMTPSA id p100sm6167027qkp.3.2015.06.06.20.34.18 (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 06 Jun 2015 20:34:18 -0700 (PDT) Received: from BLU436-SMTP208 ([134.170.2.215]) by BLU004-WSS1S6.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.22751); Sat, 6 Jun 2015 20:34:17 -0700 X-TMN: [kAuUhWO5TQjiXlgiM5Soz1DHuSasvpdt] Message-ID: From: Bin Meng To: Simon Glass , U-Boot Mailing List Date: Sun, 7 Jun 2015 11:33:13 +0800 X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1433647994-21704-1-git-send-email-bmeng.cn@gmail.com> References: <1433647994-21704-1-git-send-email-bmeng.cn@gmail.com> X-OriginalArrivalTime: 07 Jun 2015 03:34:17.0308 (UTC) FILETIME=[D521C1C0:01D0A0D2] MIME-Version: 1.0 Cc: Andrew Bradford Subject: [U-Boot] [PATCH v3 2/3] x86: fsp: Load GDT before calling FspInitEntry 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" Currently the FSP execution environment GDT is setup by U-Boot in arch/x86/cpu/start16.S, which works pretty well. But if we try to move the FspInitEntry call a little bit later to better fit into U-Boot's initialization sequence, FSP will fail to bring up the AP due to #GP fault as AP's GDT is duplicated from BSP whose GDT is now moved into CAR, and unfortunately FSP calls AP initialization after it disables the CAR. So basically the BSP's GDT still refers to the one in the CAR, whose content is no longer available, so when AP starts up and loads its segment register, it blows up. To resolve this, we load GDT before calling into FspInitEntry. The GDT is the same one used in arch/x86/cpu/start16.S, which is in the ROM and exists forever. Signed-off-by: Bin Meng Tested-by: Andrew Bradford Tested-by: Simon Glass Acked-by: Simon Glass --- Changes in v3: - Rename gdt in arch/x86/cpu/start16.S to gdt_rom - Change 'extern u32 gdt' to 'extern char gdt_rom[]' - Add comments to setup_fsp_gdt() Changes in v2: - Use CONFIG_RESET_SEG_START to avoid duplication arch/x86/cpu/cpu.c | 20 ++++++++++++++++++++ arch/x86/cpu/start16.S | 5 +++-- arch/x86/include/asm/u-boot-x86.h | 7 +++++++ arch/x86/lib/fsp/fsp_support.c | 3 +++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index bb4a110..b6c585a 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -164,6 +164,26 @@ void setup_gdt(gd_t *id, u64 *gdt_addr) load_fs(X86_GDT_ENTRY_32BIT_FS); } +#ifdef CONFIG_HAVE_FSP +/* + * Setup FSP execution environment GDT + * + * Per Intel FSP external architecture specification, before calling any FSP + * APIs, we need make sure the system is in flat 32-bit mode and both the code + * and data selectors should have full 4GB access range. Here we reuse the one + * we used in arch/x86/cpu/start16.S, and reload the segement registers. + */ +void setup_fsp_gdt(void) +{ + load_gdt((const u64 *)(gdt_rom + CONFIG_RESET_SEG_START), 4); + load_ds(X86_GDT_ENTRY_32BIT_DS); + load_ss(X86_GDT_ENTRY_32BIT_DS); + load_es(X86_GDT_ENTRY_32BIT_DS); + load_fs(X86_GDT_ENTRY_32BIT_DS); + load_gs(X86_GDT_ENTRY_32BIT_DS); +} +#endif + int __weak x86_cleanup_before_linux(void) { #ifdef CONFIG_BOOTSTAGE_STASH diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S index 826e2b4..5eb17f1 100644 --- a/arch/x86/cpu/start16.S +++ b/arch/x86/cpu/start16.S @@ -71,11 +71,12 @@ idt_ptr: */ gdt_ptr: .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ - .long BOOT_SEG + gdt /* base */ + .long BOOT_SEG + gdt_rom /* base */ /* Some CPUs are picky about GDT alignment... */ .align 16 -gdt: +.globl gdt_rom +gdt_rom: /* * The GDT table ... * diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index d1d21ed..3c6ee29 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -8,12 +8,19 @@ #ifndef _U_BOOT_I386_H_ #define _U_BOOT_I386_H_ 1 +extern char gdt_rom[]; + /* cpu/.../cpu.c */ int arch_cpu_init(void); int x86_cpu_init_f(void); int cpu_init_f(void); void init_gd(gd_t *id, u64 *gdt_addr); void setup_gdt(gd_t *id, u64 *gdt_addr); +/* + * Setup FSP execution environment GDT to use the one we used in + * arch/x86/cpu/start16.S and reload the segment registers. + */ +void setup_fsp_gdt(void); int init_cache(void); int cleanup_before_linux(void); diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 5809235..4585166 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -173,6 +173,9 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) post_code(POST_PRE_MRC); + /* Load GDT for FSP */ + setup_fsp_gdt(); + /* * Use ASM code to ensure the register value in EAX & ECX * will be passed into BlContinuationFunc