From patchwork Fri Dec 23 12:25:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Graeme Russ X-Patchwork-Id: 133029 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 7C9D3B7138 for ; Fri, 23 Dec 2011 23:28:32 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3832C28288; Fri, 23 Dec 2011 13:27:58 +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 oGE45SlUnczv; Fri, 23 Dec 2011 13:27:57 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E019E28290; Fri, 23 Dec 2011 13:27:19 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9C5AC2823D for ; Fri, 23 Dec 2011 13:27:09 +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 Y25L6P8UnyzA for ; Fri, 23 Dec 2011 13:27:09 +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 342DB2825F for ; Fri, 23 Dec 2011 13:26:50 +0100 (CET) Received: by mail-yw0-f44.google.com with SMTP id j72so6037299yhj.3 for ; Fri, 23 Dec 2011 04:26:49 -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 :mime-version:content-type:content-transfer-encoding; bh=jdlWcDTpXJ7EVMPy3EPBn0Fd5K+eIW2pF2b1wOzruqU=; b=XkF7TlYaDmGrlVQ1JuJbOrJLNqx2V8aU+5cBlqVo+T8jwJkk1SFk9JCYhGKTeK7CTo hYxrs+f3HjKWsz9zGRLP+fKGnFP+NL0LeG5vcmYOUrR9HjJfX+G7iiq/NyROIfuKR31n y/M7+QGV5KoDPVWt6dk7q1EC1dXClbahFGE6w= Received: by 10.236.161.193 with SMTP id w41mr20444529yhk.93.1324643209901; Fri, 23 Dec 2011 04:26:49 -0800 (PST) Received: from localhost.localdomain (d58-106-90-149.sbr801.nsw.optusnet.com.au. [58.106.90.149]) by mx.google.com with ESMTPS id y17sm32624370anc.2.2011.12.23.04.26.47 (version=SSLv3 cipher=OTHER); Fri, 23 Dec 2011 04:26:49 -0800 (PST) From: Graeme Russ To: u-boot@lists.denx.de Date: Fri, 23 Dec 2011 23:25:49 +1100 Message-Id: <1324643151-23642-13-git-send-email-graeme.russ@gmail.com> X-Mailer: git-send-email 1.7.5.2.317.g391b14 In-Reply-To: <1324643151-23642-1-git-send-email-graeme.russ@gmail.com> References: <1324643151-23642-1-git-send-email-graeme.russ@gmail.com> MIME-Version: 1.0 Subject: [U-Boot] =?utf-8?q?=5BRFC_12/14=5D_x86=3A_Move_relocation_code_ou?= =?utf-8?q?t_of_board=2Ec?= 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: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de --- arch/x86/lib/Makefile | 1 + arch/x86/lib/board.c | 113 ----------------------------------- arch/x86/lib/relocate.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 113 deletions(-) create mode 100644 arch/x86/lib/relocate.c diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 7820895..57b6896 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -40,6 +40,7 @@ COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o COBJS-$(CONFIG_PCI) += pci.o COBJS-$(CONFIG_PCI) += pci_type1.o COBJS-$(CONFIG_SYS_X86_REALMODE) += realmode.o +COBJS-y += relocate.o COBJS-y += string.o COBJS-$(CONFIG_SYS_X86_ISR_TIMER) += timer.o COBJS-$(CONFIG_VIDEO) += video_bios.o diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index e8274bf..a6596ef 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -41,7 +41,6 @@ #include #include #include -#include #ifdef CONFIG_BITBANGMII #include @@ -124,11 +123,6 @@ static void display_flash_config(ulong size) */ typedef int (init_fnc_t) (void); -static int calculate_relocation_address(gd_t *); -static int copy_uboot_to_ram(gd_t *); -static int clear_bss(gd_t *); -static int do_elf_reloc_fixups(gd_t *); - init_fnc_t *init_sequence_f[] = { cpu_init_f, board_early_init_f, @@ -155,85 +149,6 @@ init_fnc_t *init_sequence_r[] = { gd_t *gd; -static int calculate_relocation_address(gd_t *id) -{ - ulong text_start = (ulong)&__text_start; - ulong bss_end = (ulong)&__bss_end; - ulong dest_addr; - ulong rel_offset; - - /* Calculate destination RAM Address and relocation offset */ - dest_addr = (ulong)id; - dest_addr -= CONFIG_SYS_STACK_SIZE; - dest_addr -= (bss_end - text_start); - - /* - * Round destination address down to 16-byte boundary to keep - * IDT and GDT 16-byte aligned - */ - dest_addr &= ~15; - - rel_offset = dest_addr - text_start; - - id->relocaddr = dest_addr; - id->reloc_off = rel_offset; - - return 0; -} - -static int copy_uboot_to_ram(gd_t *id) -{ - size_t len = (size_t)&__data_end - (size_t)&__text_start; - - memcpy((void *)id->relocaddr, (void *)&__text_start, len); - - return 0; -} - -static int clear_bss(gd_t *id) -{ - ulong dst_addr = (ulong)&__bss_start + id->reloc_off; - size_t len = (size_t)&__bss_end - (size_t)&__bss_start; - - memset((void *)dst_addr, 0x00, len); - - return 0; -} - -static int do_elf_reloc_fixups(gd_t *id) -{ - Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start); - Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end); - - Elf32_Addr *offset_ptr_rom; - Elf32_Addr *offset_ptr_ram; - - /* The size of the region of u-boot that runs out of RAM. */ - uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start; - - do { - /* Get the location from the relocation entry */ - offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; - - /* Check that the location of the relocation is in .text */ - if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE) { - - /* Switch to the in-RAM version */ - offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + - id->reloc_off); - - /* Check that the target points into .text */ - if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE && - *offset_ptr_ram < - (CONFIG_SYS_TEXT_BASE + size)) { - *offset_ptr_ram += id->reloc_off; - } - } - } while (re_src++ < re_end); - - return 0; -} - /* Load U-Boot into RAM, initialize BSS, perform relocation adjustments */ void board_init_f(ulong boot_flags) { @@ -254,34 +169,6 @@ void board_init_f(ulong boot_flags) ; } -typedef void (board_init_r_t) (gd_t *, ulong); - -void relocate_code(ulong stack_ptr, gd_t *id, ulong reloc_addr) -{ - board_init_r_t *board_init_r_func; - - /* We are running from flash, but the stack is now in SDRAM */ - - /* gd is still in CAR - Copy it into SDRAM */ - memcpy(id, gd, sizeof(gd_t)); - - if (init_cache() != 0) - hang(); - - calculate_relocation_address(id); - copy_uboot_to_ram(id); - clear_bss(id); - do_elf_reloc_fixups(id); - - board_init_r_func = board_init_r; - board_init_r_func += id->reloc_off; - board_init_r_func(id, id->relocaddr); - - /* NOTREACHED - relocate_code() does not return */ - while (1) - ; -} - void board_init_r(gd_t *id, ulong dest_addr) { #if defined(CONFIG_CMD_NET) diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c new file mode 100644 index 0000000..f8c0b3f --- /dev/null +++ b/arch/x86/lib/relocate.c @@ -0,0 +1,150 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, + * + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +static int calculate_relocation_address(gd_t *); +static int copy_uboot_to_ram(gd_t *); +static int clear_bss(gd_t *); +static int do_elf_reloc_fixups(gd_t *); + +static int calculate_relocation_address(gd_t *id) +{ + ulong text_start = (ulong)&__text_start; + ulong bss_end = (ulong)&__bss_end; + ulong dest_addr; + ulong rel_offset; + + /* Calculate destination RAM Address and relocation offset */ + dest_addr = (ulong)id; + dest_addr -= CONFIG_SYS_STACK_SIZE; + dest_addr -= (bss_end - text_start); + + /* + * Round destination address down to 16-byte boundary to keep + * IDT and GDT 16-byte aligned + */ + dest_addr &= ~15; + + rel_offset = dest_addr - text_start; + + id->relocaddr = dest_addr; + id->reloc_off = rel_offset; + + return 0; +} + +static int copy_uboot_to_ram(gd_t *id) +{ + size_t len = (size_t)&__data_end - (size_t)&__text_start; + + memcpy((void *)id->relocaddr, (void *)&__text_start, len); + + return 0; +} + +static int clear_bss(gd_t *id) +{ + ulong dst_addr = (ulong)&__bss_start + id->reloc_off; + size_t len = (size_t)&__bss_end - (size_t)&__bss_start; + + memset((void *)dst_addr, 0x00, len); + + return 0; +} + +static int do_elf_reloc_fixups(gd_t *id) +{ + Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start); + Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end); + + Elf32_Addr *offset_ptr_rom; + Elf32_Addr *offset_ptr_ram; + + /* The size of the region of u-boot that runs out of RAM. */ + uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start; + + do { + /* Get the location from the relocation entry */ + offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; + + /* Check that the location of the relocation is in .text */ + if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE) { + + /* Switch to the in-RAM version */ + offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + + id->reloc_off); + + /* Check that the target points into .text */ + if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE && + *offset_ptr_ram < + (CONFIG_SYS_TEXT_BASE + size)) { + *offset_ptr_ram += id->reloc_off; + } + } + } while (re_src++ < re_end); + + return 0; +} + +typedef void (board_init_r_t) (gd_t *, ulong); + +__attribute__ ((__noreturn__)) +void relocate_code(ulong dummy_1, gd_t *id, ulong dummy_2) +{ + board_init_r_t *board_init_r_func; + + /* We are running from flash, but the stack is now in SDRAM */ + + /* gd is still in CAR - Copy it into SDRAM */ + memcpy(id, gd, sizeof(gd_t)); + + if (init_cache() != 0) + hang(); + + calculate_relocation_address(id); + copy_uboot_to_ram(id); + clear_bss(id); + do_elf_reloc_fixups(id); + + board_init_r_func = board_init_r; + board_init_r_func += id->reloc_off; + board_init_r_func(id, id->relocaddr); + + /* NOTREACHED - relocate_code() does not return */ + while (1) + ; +}