From patchwork Mon Jan 2 04:09:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Graeme Russ X-Patchwork-Id: 133779 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 8D535B6FA2 for ; Mon, 2 Jan 2012 15:10:54 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 38953281F3; Mon, 2 Jan 2012 05:10:33 +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 PkqGRTA97eqN; Mon, 2 Jan 2012 05:10:32 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D856028219; Mon, 2 Jan 2012 05:10:18 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1F12C28220 for ; Mon, 2 Jan 2012 05:10:17 +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 NLE0dhPGHZSh for ; Mon, 2 Jan 2012 05:10:16 +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-yw0-f44.google.com (mail-yw0-f44.google.com [209.85.213.44]) by theia.denx.de (Postfix) with ESMTPS id 75546280F0 for ; Mon, 2 Jan 2012 05:10:00 +0100 (CET) Received: by yhjj72 with SMTP id j72so8340306yhj.3 for ; Sun, 01 Jan 2012 20:09:59 -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; bh=a0/lI9J0H+j0HqltfGTH5NiJJhZSJ820gwnYNFhWMiI=; b=Araf8ITtXW67ptHzKuuyhrEIibwO9GEh/CBM/XKUU4BVP51zwnNAK811I7GOzGFBfZ 1tJS+Um7HQejyPkkVPsQHO53rfD41Weeu1uFlPZOLtMl8yRnT97vp7SRsraKzTraSBww LSMMVUacojHV1A1fObkiHbHpMl4eBzEEoHp8M= Received: by 10.236.185.8 with SMTP id t8mr21562997yhm.30.1325477399232; Sun, 01 Jan 2012 20:09:59 -0800 (PST) Received: from localhost.localdomain (d58-106-85-147.sbr801.nsw.optusnet.com.au. [58.106.85.147]) by mx.google.com with ESMTPS id 9sm114431452any.3.2012.01.01.20.09.57 (version=SSLv3 cipher=OTHER); Sun, 01 Jan 2012 20:09:58 -0800 (PST) From: Graeme Russ To: u-boot@lists.denx.de Date: Mon, 2 Jan 2012 15:09:21 +1100 Message-Id: <1325477374-6417-5-git-send-email-graeme.russ@gmail.com> X-Mailer: git-send-email 1.7.5.2.317.g391b14 In-Reply-To: <1325477374-6417-1-git-send-email-graeme.russ@gmail.com> References: <1325477374-6417-1-git-send-email-graeme.russ@gmail.com> Subject: [U-Boot] [PATCH 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 Signed-off-by: Graeme Russ --- arch/x86/cpu/cpu.c | 82 +++++++++++++++++++++++++++++++++------------------ 1 files changed, 53 insertions(+), 29 deletions(-) diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 61d0b69..bf55c26 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 */ - [GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), - /* DS: data, read/write, 4 GB, base 0 */ - [GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), - /* 16-bit CS: code, read/execute, 64 kB, base 0 */ - [GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff), - /* 16-bit DS: data, read/write, 64 kB, base 0 */ - [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 * 8)); +} + +static void load_es(u32 segment) +{ + asm volatile("movl %0, %%es" : : "r" (segment * 8)); +} + +static void load_fs(u32 segment) +{ + asm volatile("movl %0, %%fs" : : "r" (segment * 8)); +} + +static void load_gs(u32 segment) +{ + asm volatile("movl %0, %%gs" : : "r" (segment * 8)); +} + +static void load_ss(u32 segment) +{ + asm volatile("movl %0, %%ss" : : "r" (segment * 8)); +} + +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 */ + [GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), + /* DS: data, read/write, 4 GB, base 0 */ + [GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), + /* 16-bit CS: code, read/execute, 64 kB, base 0 */ + [GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff), + /* 16-bit DS: data, read/write, 64 kB, base 0 */ + [GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff), + }; + + load_gdt(boot_gdt, GDT_NUM_ENTRIES); + load_ds(GDT_ENTRY_32BIT_DS); + load_es(GDT_ENTRY_32BIT_DS); + load_fs(GDT_ENTRY_32BIT_DS); + load_gs(GDT_ENTRY_32BIT_DS); + load_ss(GDT_ENTRY_32BIT_DS); /* Initialize core interrupt and exception functionality of CPU */ cpu_init_interrupts();