From patchwork Wed Jan 4 19:59:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Graeme Russ X-Patchwork-Id: 134340 X-Patchwork-Delegate: graeme.russ@gmail.com 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 36EADB6FA8 for ; Thu, 5 Jan 2012 07:00:54 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C50CD283E6; Wed, 4 Jan 2012 21:00:31 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de 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 qYv2pNiL7cJ9; Wed, 4 Jan 2012 21:00:31 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5FFBD283F5; Wed, 4 Jan 2012 21:00:20 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9D076283F0 for ; Wed, 4 Jan 2012 21:00:18 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de 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 zEtlCetpY37a for ; Wed, 4 Jan 2012 21:00:18 +0100 (CET) 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-vx0-f172.google.com (mail-vx0-f172.google.com [209.85.220.172]) by theia.denx.de (Postfix) with ESMTPS id 6820B283D0 for ; Wed, 4 Jan 2012 21:00:11 +0100 (CET) Received: by mail-vx0-f172.google.com with SMTP id fk13so13532083vcb.3 for ; Wed, 04 Jan 2012 12:00:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to; bh=0OtoYEbzVqzi4pfehNHAIxBQxm27jVIhx2nankRWnv8=; b=G7HLZuTW2/SEDGLBWEXvqadRTuVAp7T0QMxpc76uEhUt/Pcj0LAdYLezMcLa9OX7Gv 0epAxZga1EjlPzV4QJuyL12Ez2bnU7imFPcmpWgoN8h991m58IUFAHnio/srXRSYCvSC 9CTGENkD4ubI2htGChK6IYOinaNZHjmaIysRU= Received: by 10.220.149.135 with SMTP id t7mr22465848vcv.34.1325707211161; Wed, 04 Jan 2012 12:00:11 -0800 (PST) Received: from localhost.localdomain (d110-32-162-141.sbr801.nsw.optusnet.com.au. [110.32.162.141]) by mx.google.com with ESMTPS id eb3sm33049296vdc.5.2012.01.04.12.00.08 (version=SSLv3 cipher=OTHER); Wed, 04 Jan 2012 12:00:10 -0800 (PST) From: Graeme Russ To: u-boot@lists.denx.de Date: Thu, 5 Jan 2012 06:59:42 +1100 Message-Id: <1325707195-3218-4-git-send-email-graeme.russ@gmail.com> X-Mailer: git-send-email 1.7.5.2.317.g391b14 In-Reply-To: <1325707195-3218-1-git-send-email-graeme.russ@gmail.com> References: <1325707195-3218-1-git-send-email-graeme.russ@gmail.com> In-Reply-To: <1325477374-6417-5-git-send-email-graeme.russ@gmail.com> Subject: [U-Boot] [PATCH v2 04/17] x86: Rework Global Descriptor Table loading X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de The inline assembler is ugly and uses hard coded magic numbers. Make it more elegant to allow cleaner implementation of future GDT related patches. The compiler seems smart enough to generate the same code anyway Signed-off-by: Graeme Russ Acked-by: Simon Glass --- Changes for v2: - Rebased against revised patch #3 - Use GDT size define instead of magic number - Added commit message arch/x86/cpu/cpu.c | 82 +++++++++++++++++++++++++++++++++------------------ 1 files changed, 53 insertions(+), 29 deletions(-) -- 1.7.5.2.317.g391b14 diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 209ff29..8102fb9 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -55,35 +55,39 @@ struct gdt_ptr { u32 ptr; } __packed; -static void reload_gdt(void) +static void load_ds(u32 segment) { - /* - * There are machines which are known to not boot with the GDT - * being 8-byte unaligned. Intel recommends 16 byte alignment - */ - static const u64 boot_gdt[] __attribute__((aligned(16))) = { - /* CS: code, read/execute, 4 GB, base 0 */ - [X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), - /* DS: data, read/write, 4 GB, base 0 */ - [X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), - /* 16-bit CS: code, read/execute, 64 kB, base 0 */ - [X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff), - /* 16-bit DS: data, read/write, 64 kB, base 0 */ - [X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff), - }; - static struct gdt_ptr gdt; - - gdt.len = sizeof(boot_gdt)-1; - gdt.ptr = (u32)&boot_gdt; - - asm volatile("lgdtl %0\n" \ - "movl $((2+1)*8), %%ecx\n" \ - "movl %%ecx, %%ds\n" \ - "movl %%ecx, %%es\n" \ - "movl %%ecx, %%fs\n" \ - "movl %%ecx, %%gs\n" \ - "movl %%ecx, %%ss" \ - : : "m" (gdt) : "ecx"); + asm volatile("movl %0, %%ds" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_es(u32 segment) +{ + asm volatile("movl %0, %%es" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_fs(u32 segment) +{ + asm volatile("movl %0, %%fs" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_gs(u32 segment) +{ + asm volatile("movl %0, %%gs" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_ss(u32 segment) +{ + asm volatile("movl %0, %%ss" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_gdt(const u64 *boot_gdt, u16 num_entries) +{ + struct gdt_ptr gdt; + + gdt.len = (num_entries * 8) - 1; + gdt.ptr = (u32)boot_gdt; + + asm volatile("lgdtl %0\n" : : "m" (gdt)); } int x86_cpu_init_f(void) @@ -113,7 +117,27 @@ int x86_cpu_init_r(void) "movl %%eax, %%cr0\n" "wbinvd\n" : : "i" (nw_cd_rst) : "eax"); - reload_gdt(); + /* + * There are machines which are known to not boot with the GDT + * being 8-byte unaligned. Intel recommends 16 byte alignment + */ + static const u64 boot_gdt[] __aligned(16) = { + /* CS: code, read/execute, 4 GB, base 0 */ + [X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), + /* DS: data, read/write, 4 GB, base 0 */ + [X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), + /* 16-bit CS: code, read/execute, 64 kB, base 0 */ + [X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff), + /* 16-bit DS: data, read/write, 64 kB, base 0 */ + [X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff), + }; + + load_gdt(boot_gdt, X86_GDT_NUM_ENTRIES); + load_ds(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); + load_ss(X86_GDT_ENTRY_32BIT_DS); /* Initialize core interrupt and exception functionality of CPU */ cpu_init_interrupts();