All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation
@ 2009-09-26 12:57 Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning Graeme Russ
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

This patch series implements full relocation of the i386 port. The series
itself needs a lot of tidying up. The "Fix-gcc-4.4.1-compiler-warning"
patch, for example, needs to be submitted as a stand-alone patch.

In the meantime, I would appreciate any comments on this series

Thanks

G

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 19:20   ` Mike Frysinger
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 2/8] Add low-level progress indications Graeme Russ
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 common/Makefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/common/Makefile b/common/Makefile
index 3781738..7ea6e93 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -178,6 +178,10 @@ $(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc
 		-DENV_CRC=$(shell $(obj)../tools/envcrc) \
 		-c -o $@ $(src)env_embedded.c
 
+$(obj)dlmalloc.o: $(src)dlmalloc.c $(obj)dlmalloc.o
+	$(CC) $(CFLAGS) -Wa,--no-warn -fno-strict-aliasing \
+		-c -o $@ $(src)dlmalloc.c
+
 $(obj)../tools/envcrc:
 	$(MAKE) -C ../tools
 
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 2/8] Add low-level progress indications
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 3/8] Fix i386 malloc initialisation Graeme Russ
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 board/eNET/eNET_start16.S   |   66 +++++++++++++++++++++++++++++++++++++++++-
 board/eNET/hardware.h       |   16 ++++++++++
 include/asm-i386/ic/sc520.h |    6 ++++
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/board/eNET/eNET_start16.S b/board/eNET/eNET_start16.S
index 48e4d83..2d7929b 100644
--- a/board/eNET/eNET_start16.S
+++ b/board/eNET/eNET_start16.S
@@ -27,8 +27,7 @@
  * that is used by U-boot to its final destination.
  */
 
-/* #include <asm/ic/sc520_defs.h> */
-
+#include <asm/ic/sc520.h>
 #include "hardware.h"
 
 .text
@@ -60,6 +59,69 @@ board_init16:
 	xorw    %ax, %ax
 	movb    %al, (%di)
 
+	/* Enable UART 1 */
+	movl    $SC520_ADDDECCTL, %edi
+	movb    $0x02, %al
+	movb    %al, (%di)
+
+	/* Configure UART 1 - 9600 Baud 8N1 */
+	movl    $SC520_UART1CTL, %edi
+	movb    $0x07, %al
+	movb    %al, (%di)
+
+	/* Set DLAB bit */
+	movw    $(UART0_BASE + UART_LCR), %dx
+	movb    $0x80, %al
+	outb    %al, %dx
+
+	/* Set baudrate divisor (LSB) */
+	movw    $(UART0_BASE + UART_DLL), %dx
+	movb    $0x0c, %al
+	outb    %al, %dx
+
+	/* Set baudrate divisor (MSB) */
+	movw    $(UART0_BASE + UART_DLM), %dx
+	movb    $0x00, %al
+	outb    %al, %dx
+
+	/* clear DLAB; set 8 bits, no parity */
+	movw    $(UART0_BASE + UART_LCR), %dx
+	movb    $0x03, %al
+	outb    %al, %dx
+
+	/* enable FIFO */
+	movw    $(UART0_BASE + UART_FCR), %dx
+	movb    $0x01, %al
+	outb    %al, %dx
+
+	/* Set DTR and RTS active */
+	movw    $(UART0_BASE + UART_MCR), %dx
+	movb    $0x0b, %al
+	outb    %al, %dx
+
+	/* clear line status */
+	movw    $(UART0_BASE + UART_LSR), %dx
+	inb     %dx, %al
+
+	/* read receive buffer */
+	movw    $(UART0_BASE + UART_RBR), %dx
+	inb     %dx, %al
+
+	/* set scratchpad */
+	movw    $(UART0_BASE + UART_SCR), %dx
+	movb    $0x00, %al
+	outb    %al, %dx
+
+	/* Disable Interrupts */
+	movw    $(UART0_BASE + UART_IER), %dx
+	movb    $0x00, %al
+	outb    %al, %dx
+
+	/* wait for the UART clock to settle */
+	movl    $0x10000,%ecx
+uartdelay:
+	loop    uartdelay
+
 	/* Disabe MMCR alias */
 	movw	$0xfffc, %dx
 	movl	$0x000000cb, %eax
diff --git a/board/eNET/hardware.h b/board/eNET/hardware.h
index 42474a6..d85fde0 100644
--- a/board/eNET/hardware.h
+++ b/board/eNET/hardware.h
@@ -32,4 +32,20 @@
 #define LED_TX_BITMASK		0x10
 #define LED_ERR_BITMASK		0x20
 
+/* Serial Port Definitions */
+#define UART0_BASE             0x3f8
+
+#define UART_RBR               0x00
+#define UART_THR               0x00
+#define UART_IER               0x01
+#define UART_IIR               0x02
+#define UART_FCR               0x02
+#define UART_LCR               0x03
+#define UART_MCR               0x04
+#define UART_LSR               0x05
+#define UART_MSR               0x06
+#define UART_SCR               0x07
+#define UART_DLL               0x00
+#define UART_DLM               0x01
+
 #endif /* HARDWARE_H_ */
diff --git a/include/asm-i386/ic/sc520.h b/include/asm-i386/ic/sc520.h
index 57c9904..72e5d5d 100644
--- a/include/asm-i386/ic/sc520.h
+++ b/include/asm-i386/ic/sc520.h
@@ -257,10 +257,16 @@ extern volatile sc520_mmcr_t *sc520_mmcr;
 
 /* MMCR Offsets (required for assembler code */
 #define SC520_DBCTL		0x0040	/* SDRAM Buffer Control Register */
+#define SC520_ADDDECCTL		0x0080
 #define SC520_PAR14		0x00c0	/* Programmable Address Region 14 Register */
 #define SC520_PAR15		0x00c4	/* Programmable Address Region 15 Register */
 #define SC520_SWTMRMILLI	0x0c60  /* Software Timer Millisecond Count */
 #define SC520_SWTMRMICRO	0x0c62  /* Software Timer Microsecond Count */
+#define SC520_UART1CTL		0x0cc0  /* UART 1 Control */
+
+ /* MMCR Register bits (not all of them :) ) */
+
+
 
 /* MMCR Register bits (not all of them :) ) */
 
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 3/8] Fix i386 malloc initialisation
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 2/8] Add low-level progress indications Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 4/8] Rearrange i386 Interupt Handling Graeme Russ
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 board/eNET/u-boot.lds         |    5 ++++-
 common/dlmalloc.c             |    6 ------
 include/configs/eNET.h        |    2 +-
 include/configs/sc520_cdp.h   |    2 +-
 include/configs/sc520_spunk.h |    2 +-
 lib_i386/board.c              |   15 +++++++--------
 6 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/board/eNET/u-boot.lds b/board/eNET/u-boot.lds
index 4ea424d..832d101 100644
--- a/board/eNET/u-boot.lds
+++ b/board/eNET/u-boot.lds
@@ -32,12 +32,15 @@ SECTIONS
 
 	. = ALIGN(4);
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+	
+	.eh_frame : { *(.eh_frame) }
 
 	_i386boot_text_size = SIZEOF(.text) + SIZEOF(.rodata);
 
 	. = 0x03FF0000;		/* Ram data segment to use */
 	_i386boot_romdata_dest = ABSOLUTE(.);
-	.data : AT ( LOADADDR(.rodata) + SIZEOF(.rodata) ) { *(.data) }
+	.data : AT ( LOADADDR(.eh_frame) + SIZEOF(.eh_frame) ) { *(.data) }
+/*	.data : { *(.data) } */
 	_i386boot_romdata_start = LOADADDR(.data);
 
 	. = ALIGN(4);
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 241db8c..f980430 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -1520,11 +1520,6 @@ void *sbrk(ptrdiff_t increment)
 	return (void *)old;
 }
 
-#ifndef CONFIG_X86
-/*
- * x86 boards use a slightly different init sequence thus they implement
- * their own version of mem_malloc_init()
- */
 void mem_malloc_init(ulong start, ulong size)
 {
 	mem_malloc_start = start;
@@ -1533,7 +1528,6 @@ void mem_malloc_init(ulong start, ulong size)
 
 	memset((void *)mem_malloc_start, 0, size);
 }
-#endif
 
 /* field-extraction macros */
 
diff --git a/include/configs/eNET.h b/include/configs/eNET.h
index 243a554..54c34fa 100644
--- a/include/configs/eNET.h
+++ b/include/configs/eNET.h
@@ -61,7 +61,7 @@
 /*
  * Size of malloc() pool
  */
-#define CONFIG_MALLOC_SIZE	(CONFIG_SYS_ENV_SIZE + 128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 128*1024)
 
 #define CONFIG_BAUDRATE		9600
 
diff --git a/include/configs/sc520_cdp.h b/include/configs/sc520_cdp.h
index 214a9af..2f1dae7 100644
--- a/include/configs/sc520_cdp.h
+++ b/include/configs/sc520_cdp.h
@@ -65,7 +65,7 @@
 /*
  * Size of malloc() pool
  */
-#define CONFIG_MALLOC_SIZE	(CONFIG_ENV_SIZE + 128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 128*1024)
 
 #define CONFIG_BAUDRATE		9600
 
diff --git a/include/configs/sc520_spunk.h b/include/configs/sc520_spunk.h
index f3fc960..cf5633c 100644
--- a/include/configs/sc520_spunk.h
+++ b/include/configs/sc520_spunk.h
@@ -63,7 +63,7 @@
 /*
  * Size of malloc() pool
  */
-#define CONFIG_MALLOC_SIZE	(CONFIG_ENV_SIZE + 128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 128*1024)
 
 
 #define CONFIG_BAUDRATE		9600
diff --git a/lib_i386/board.c b/lib_i386/board.c
index 0262b5e..39a3099 100644
--- a/lib_i386/board.c
+++ b/lib_i386/board.c
@@ -73,17 +73,16 @@ ulong i386boot_bios_size     = (ulong)&_i386boot_bios_size;     /* size of BIOS
 const char version_string[] =
 	U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")";
 
-static int mem_malloc_init(void)
+static int heap_init(void)
 {
 	/* start malloc area right after the stack */
-	mem_malloc_start = i386boot_bss_start +
-		i386boot_bss_size + CONFIG_SYS_STACK_SIZE;
-	mem_malloc_start = (mem_malloc_start+3)&~3;
+	ulong start = i386boot_bss_start + i386boot_bss_size +
+			CONFIG_SYS_STACK_SIZE;
 
-	/* Use all available RAM for malloc() */
-	mem_malloc_end = gd->ram_size;
+	/* 4-byte aligned */
+	start = (start+3)&~3;
 
-	mem_malloc_brk = mem_malloc_start;
+	mem_malloc_init(start, CONFIG_SYS_MALLOC_LEN);
 
 	return 0;
 }
@@ -180,7 +179,7 @@ init_fnc_t *init_sequence[] = {
 	cpu_init,		/* basic cpu dependent setup */
 	board_init,		/* basic board dependent setup */
 	dram_init,		/* configure available RAM banks */
-	mem_malloc_init,        /* dependant on dram_init */
+	heap_init,		/* dependant on dram_init */
 	interrupt_init,		/* set up exceptions */
 	timer_init,
 	serial_init,
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 4/8] Rearrange i386 Interupt Handling
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
                   ` (2 preceding siblings ...)
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 3/8] Fix i386 malloc initialisation Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 5/8] Fix race condition when using SC520 timers Graeme Russ
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

In preperation for full relocation
---
 cpu/i386/Makefile              |    2 +-
 cpu/i386/cpu.c                 |    1 -
 cpu/i386/exceptions.c          |  229 ---------------------
 cpu/i386/interrupts.c          |  428 ++++++++++++++++++++++++++++++++++++++--
 include/asm-i386/interrupt.h   |   27 ---
 include/asm-i386/u-boot-i386.h |    3 -
 lib_i386/interrupts.c          |    4 +-
 lib_i386/pcat_interrupts.c     |   33 ---
 8 files changed, 417 insertions(+), 310 deletions(-)
 delete mode 100644 cpu/i386/exceptions.c

diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index e98bd3d..c658c6e 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o start16.o resetvec.o
-COBJS	= serial.o interrupts.o exceptions.o cpu.o
+COBJS	= serial.o interrupts.o cpu.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/i386/cpu.c b/cpu/i386/cpu.c
index d91e33b..8baf37d 100644
--- a/cpu/i386/cpu.c
+++ b/cpu/i386/cpu.c
@@ -48,7 +48,6 @@ int cpu_init(void)
 
 	/* Initialize core interrupt and exception functionality of CPU */
 	cpu_init_interrupts ();
-	cpu_init_exceptions ();
 
 	return 0;
 }
diff --git a/cpu/i386/exceptions.c b/cpu/i386/exceptions.c
deleted file mode 100644
index bc3d434..0000000
--- a/cpu/i386/exceptions.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engstr?m, Omicron Ceti AB, daniel at omicron.se.
- *
- * 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 <common.h>
-#include <asm/interrupt.h>
-
-asm (".globl exp_return\n"
-     "exp_return:\n"
-     "     addl  $12, %esp\n"
-     "     pop   %esp\n"
-     "     popa\n"
-     "     iret\n");
-
-char exception_stack[4096];
-
-/*
- * For detailed description of each exception, refer to:
- * Intel? 64 and IA-32 Architectures Software Developer's Manual
- * Volume 1: Basic Architecture
- * Order Number: 253665-029US, November 2008
- * Table 6-1. Exceptions and Interrupts
- */
-DECLARE_EXCEPTION(0, divide_error_entry);
-DECLARE_EXCEPTION(1, debug_entry);
-DECLARE_EXCEPTION(2, nmi_interrupt_entry);
-DECLARE_EXCEPTION(3, breakpoint_entry);
-DECLARE_EXCEPTION(4, overflow_entry);
-DECLARE_EXCEPTION(5, bound_range_exceeded_entry);
-DECLARE_EXCEPTION(6, invalid_opcode_entry);
-DECLARE_EXCEPTION(7, device_not_available_entry);
-DECLARE_EXCEPTION(8, double_fault_entry);
-DECLARE_EXCEPTION(9, coprocessor_segment_overrun_entry);
-DECLARE_EXCEPTION(10, invalid_tss_entry);
-DECLARE_EXCEPTION(11, segment_not_present_entry);
-DECLARE_EXCEPTION(12, stack_segment_fault_entry);
-DECLARE_EXCEPTION(13, general_protection_entry);
-DECLARE_EXCEPTION(14, page_fault_entry);
-DECLARE_EXCEPTION(15, reserved_exception_entry);
-DECLARE_EXCEPTION(16, floating_point_error_entry);
-DECLARE_EXCEPTION(17, alignment_check_entry);
-DECLARE_EXCEPTION(18, machine_check_entry);
-DECLARE_EXCEPTION(19, simd_floating_point_exception_entry);
-DECLARE_EXCEPTION(20, reserved_exception_entry);
-DECLARE_EXCEPTION(21, reserved_exception_entry);
-DECLARE_EXCEPTION(22, reserved_exception_entry);
-DECLARE_EXCEPTION(23, reserved_exception_entry);
-DECLARE_EXCEPTION(24, reserved_exception_entry);
-DECLARE_EXCEPTION(25, reserved_exception_entry);
-DECLARE_EXCEPTION(26, reserved_exception_entry);
-DECLARE_EXCEPTION(27, reserved_exception_entry);
-DECLARE_EXCEPTION(28, reserved_exception_entry);
-DECLARE_EXCEPTION(29, reserved_exception_entry);
-DECLARE_EXCEPTION(30, reserved_exception_entry);
-DECLARE_EXCEPTION(31, reserved_exception_entry);
-
-__isr__ reserved_exception_entry(int cause, int ip, int seg)
-{
-	printf("Reserved Exception %d at %04x:%08x\n", cause, seg, ip);
-}
-
-__isr__ divide_error_entry(int cause, int ip, int seg)
-{
-	printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ debug_entry(int cause, int ip, int seg)
-{
-	printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ nmi_interrupt_entry(int cause, int ip, int seg)
-{
-	printf("NMI Interrupt at %04x:%08x\n", seg, ip);
-}
-
-__isr__ breakpoint_entry(int cause, int ip, int seg)
-{
-	printf("Breakpoint at %04x:%08x\n", seg, ip);
-}
-
-__isr__ overflow_entry(int cause, int ip, int seg)
-{
-	printf("Overflow at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ bound_range_exceeded_entry(int cause, int ip, int seg)
-{
-	printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ invalid_opcode_entry(int cause, int ip, int seg)
-{
-	printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ device_not_available_entry(int cause, int ip, int seg)
-{
-	printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ double_fault_entry(int cause, int ip, int seg)
-{
-	printf("Double fault at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ coprocessor_segment_overrun_entry(int cause, int ip, int seg)
-{
-	printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ invalid_tss_entry(int cause, int ip, int seg)
-{
-	printf("Invalid TSS at %04x:%08x\n", seg, ip);
-}
-
-__isr__ segment_not_present_entry(int cause, int ip, int seg)
-{
-	printf("Segment Not Present at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ stack_segment_fault_entry(int cause, int ip, int seg)
-{
-	printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ general_protection_entry(int cause, int ip, int seg)
-{
-	printf("General Protection at %04x:%08x\n", seg, ip);
-}
-
-__isr__ page_fault_entry(int cause, int ip, int seg)
-{
-	printf("Page fault at %04x:%08x\n", seg, ip);
-	while(1);
-}
-
-__isr__ floating_point_error_entry(int cause, int ip, int seg)
-{
-	printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ alignment_check_entry(int cause, int ip, int seg)
-{
-	printf("Alignment check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ machine_check_entry(int cause, int ip, int seg)
-{
-	printf("Machine Check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ simd_floating_point_exception_entry(int cause, int ip, int seg)
-{
-	printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
-}
-
-int cpu_init_exceptions(void)
-{
-	/* Just in case... */
-	disable_interrupts();
-
-	/* Setup exceptions */
-	set_vector(0x00, exp_0);
-	set_vector(0x01, exp_1);
-	set_vector(0x02, exp_2);
-	set_vector(0x03, exp_3);
-	set_vector(0x04, exp_4);
-	set_vector(0x05, exp_5);
-	set_vector(0x06, exp_6);
-	set_vector(0x07, exp_7);
-	set_vector(0x08, exp_8);
-	set_vector(0x09, exp_9);
-	set_vector(0x0a, exp_10);
-	set_vector(0x0b, exp_11);
-	set_vector(0x0c, exp_12);
-	set_vector(0x0d, exp_13);
-	set_vector(0x0e, exp_14);
-	set_vector(0x0f, exp_15);
-	set_vector(0x10, exp_16);
-	set_vector(0x11, exp_17);
-	set_vector(0x12, exp_18);
-	set_vector(0x13, exp_19);
-	set_vector(0x14, exp_20);
-	set_vector(0x15, exp_21);
-	set_vector(0x16, exp_22);
-	set_vector(0x17, exp_23);
-	set_vector(0x18, exp_24);
-	set_vector(0x19, exp_25);
-	set_vector(0x1a, exp_26);
-	set_vector(0x1b, exp_27);
-	set_vector(0x1c, exp_28);
-	set_vector(0x1d, exp_29);
-	set_vector(0x1e, exp_30);
-	set_vector(0x1f, exp_31);
-
-	/* It is now safe to enable interrupts */
-	enable_interrupts();
-
-	return 0;
-}
diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c
index 063ea42..f4a297f 100644
--- a/cpu/i386/interrupts.c
+++ b/cpu/i386/interrupts.c
@@ -24,6 +24,14 @@
 #include <common.h>
 #include <asm/interrupt.h>
 
+#define DECLARE_INTERRUPT(x) \
+	".globl irq_"#x"\n" \
+	"irq_"#x":\n" \
+	"pushl %ebp\n" \
+	"movl %esp,%ebp\n" \
+	"pusha\n" \
+	"pushl $"#x"\n" \
+	"jmp irq_common_entry\n" \
 
 struct idt_entry {
 	u16	base_low;
@@ -33,23 +41,20 @@ struct idt_entry {
 	u16	base_high;
 } __attribute__ ((packed));
 
+struct desc_ptr {
+	unsigned short size;
+	unsigned long address;
+	unsigned short segment;
+} __attribute__((packed));
 
 struct idt_entry idt[256];
 
+struct desc_ptr idt_ptr;
 
-asm (".globl irq_return\n"
-     "irq_return:\n"
-     "     addl  $4, %esp\n"
-     "     popa\n"
-     "     iret\n");
-
-void __attribute__ ((regparm(0))) default_isr(void);
-asm ("default_isr: iret\n");
-
-asm ("idt_ptr:\n"
-	".word	0x800\n" /* size of the table 8*256 bytes */
-	".long	idt\n"	 /* offset */
-	".word	0x18\n");/* data segment */
+static inline void load_idt(const struct desc_ptr *dtr)
+{
+	asm volatile("cs lidt %0"::"m" (*dtr));
+}
 
 void set_vector(u8 intnum, void *routine)
 {
@@ -57,11 +62,16 @@ void set_vector(u8 intnum, void *routine)
 	idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff);
 }
 
+void irq_0(void);
+void irq_1(void);
 
 int cpu_init_interrupts(void)
 {
 	int i;
 
+	int irq_entry_size = irq_1 - irq_0;
+	void *irq_entry = (void *)irq_0;
+
 	/* Just in case... */
 	disable_interrupts();
 
@@ -70,10 +80,15 @@ int cpu_init_interrupts(void)
 		idt[i].access = 0x8e;
 		idt[i].res = 0;
 		idt[i].selector = 0x10;
-		set_vector(i, default_isr);
+		set_vector(i, irq_entry);
+		irq_entry += irq_entry_size;
 	}
 
-	asm ("cs lidt idt_ptr\n");
+	idt_ptr.size = 256 * 8;
+	idt_ptr.address = (unsigned long) idt;
+	idt_ptr.segment = 0x18;
+
+	load_idt(&idt_ptr);
 
 	/* It is now safe to enable interrupts */
 	enable_interrupts();
@@ -81,6 +96,12 @@ int cpu_init_interrupts(void)
 	return 0;
 }
 
+void __do_irq(int irq)
+{
+	printf("Unhandled IRQ : %d\n", irq);
+}
+void do_irq(int irq) __attribute__((weak, alias("__do_irq")));
+
 void enable_interrupts(void)
 {
 	asm("sti\n");
@@ -94,3 +115,380 @@ int disable_interrupts(void)
 
 	return (flags&0x200); /* IE flags is bit 9 */
 }
+
+/* IRQ Low-Level Service Routine */
+__isr__ irq_llsr(int ip, int seg, int irq)
+{
+	/*
+	 * For detailed description of each exception, refer to:
+	 * Intel? 64 and IA-32 Architectures Software Developer's Manual
+	 * Volume 1: Basic Architecture
+	 * Order Number: 253665-029US, November 2008
+	 * Table 6-1. Exceptions and Interrupts
+	 */
+	switch (irq) {
+	case 0x00:
+		printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x01:
+		printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
+		break;
+	case 0x02:
+		printf("NMI Interrupt at %04x:%08x\n", seg, ip);
+		break;
+	case 0x03:
+		printf("Breakpoint at %04x:%08x\n", seg, ip);
+		break;
+	case 0x04:
+		printf("Overflow at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x05:
+		printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x06:
+		printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x07:
+		printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x08:
+		printf("Double fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x09:
+		printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0a:
+		printf("Invalid TSS at %04x:%08x\n", seg, ip);
+		break;
+	case 0x0b:
+		printf("Segment Not Present at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0c:
+		printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0d:
+		printf("General Protection at %04x:%08x\n", seg, ip);
+		break;
+	case 0x0e:
+		printf("Page fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0f:
+		printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
+		break;
+	case 0x10:
+		printf("Alignment check at %04x:%08x\n", seg, ip);
+		break;
+	case 0x11:
+		printf("Machine Check at %04x:%08x\n", seg, ip);
+		break;
+	case 0x12:
+		printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
+		break;
+	case 0x13:
+	case 0x14:
+	case 0x15:
+	case 0x16:
+	case 0x17:
+	case 0x18:
+	case 0x19:
+	case 0x1a:
+	case 0x1b:
+	case 0x1c:
+	case 0x1d:
+	case 0x1e:
+	case 0x1f:
+		printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip);
+		break;
+
+	default:
+		/* Hardware or User IRQ */
+		do_irq(irq);
+	}
+}
+
+/*
+ * OK - This looks really horrible, but it serves a purpose - It helps create
+ * fully relocatable code.
+ *  - The call to irq_llsr will be a relative jump
+ *  - The IRQ entries will be guaranteed to be in order
+ * It's a bit annoying that we need to waste 3 bytes per interrupt entry
+ * (total of 768 code bytes), but we MUST create a Stack Frame and this is
+ * the easiest way I could do it. Maybe it can be made better later.
+ */
+asm(".globl irq_common_entry\n" \
+	"irq_common_entry:\n" \
+	"pushl $0\n" \
+	"pushl $0\n" \
+	"call irq_llsr\n" \
+	"popl %eax\n" \
+	"popl %eax\n" \
+	"popl %eax\n" \
+	"popa\n" \
+	"leave\n"\
+	"iret\n" \
+	DECLARE_INTERRUPT(0) \
+	DECLARE_INTERRUPT(1) \
+	DECLARE_INTERRUPT(2) \
+	DECLARE_INTERRUPT(3) \
+	DECLARE_INTERRUPT(4) \
+	DECLARE_INTERRUPT(5) \
+	DECLARE_INTERRUPT(6) \
+	DECLARE_INTERRUPT(7) \
+	DECLARE_INTERRUPT(8) \
+	DECLARE_INTERRUPT(9) \
+	DECLARE_INTERRUPT(10) \
+	DECLARE_INTERRUPT(11) \
+	DECLARE_INTERRUPT(12) \
+	DECLARE_INTERRUPT(13) \
+	DECLARE_INTERRUPT(14) \
+	DECLARE_INTERRUPT(15) \
+	DECLARE_INTERRUPT(16) \
+	DECLARE_INTERRUPT(17) \
+	DECLARE_INTERRUPT(18) \
+	DECLARE_INTERRUPT(19) \
+	DECLARE_INTERRUPT(20) \
+	DECLARE_INTERRUPT(21) \
+	DECLARE_INTERRUPT(22) \
+	DECLARE_INTERRUPT(23) \
+	DECLARE_INTERRUPT(24) \
+	DECLARE_INTERRUPT(25) \
+	DECLARE_INTERRUPT(26) \
+	DECLARE_INTERRUPT(27) \
+	DECLARE_INTERRUPT(28) \
+	DECLARE_INTERRUPT(29) \
+	DECLARE_INTERRUPT(30) \
+	DECLARE_INTERRUPT(31) \
+	DECLARE_INTERRUPT(32) \
+	DECLARE_INTERRUPT(33) \
+	DECLARE_INTERRUPT(34) \
+	DECLARE_INTERRUPT(35) \
+	DECLARE_INTERRUPT(36) \
+	DECLARE_INTERRUPT(37) \
+	DECLARE_INTERRUPT(38) \
+	DECLARE_INTERRUPT(39) \
+	DECLARE_INTERRUPT(40) \
+	DECLARE_INTERRUPT(41) \
+	DECLARE_INTERRUPT(42) \
+	DECLARE_INTERRUPT(43) \
+	DECLARE_INTERRUPT(44) \
+	DECLARE_INTERRUPT(45) \
+	DECLARE_INTERRUPT(46) \
+	DECLARE_INTERRUPT(47) \
+	DECLARE_INTERRUPT(48) \
+	DECLARE_INTERRUPT(49) \
+	DECLARE_INTERRUPT(50) \
+	DECLARE_INTERRUPT(51) \
+	DECLARE_INTERRUPT(52) \
+	DECLARE_INTERRUPT(53) \
+	DECLARE_INTERRUPT(54) \
+	DECLARE_INTERRUPT(55) \
+	DECLARE_INTERRUPT(56) \
+	DECLARE_INTERRUPT(57) \
+	DECLARE_INTERRUPT(58) \
+	DECLARE_INTERRUPT(59) \
+	DECLARE_INTERRUPT(60) \
+	DECLARE_INTERRUPT(61) \
+	DECLARE_INTERRUPT(62) \
+	DECLARE_INTERRUPT(63) \
+	DECLARE_INTERRUPT(64) \
+	DECLARE_INTERRUPT(65) \
+	DECLARE_INTERRUPT(66) \
+	DECLARE_INTERRUPT(67) \
+	DECLARE_INTERRUPT(68) \
+	DECLARE_INTERRUPT(69) \
+	DECLARE_INTERRUPT(70) \
+	DECLARE_INTERRUPT(71) \
+	DECLARE_INTERRUPT(72) \
+	DECLARE_INTERRUPT(73) \
+	DECLARE_INTERRUPT(74) \
+	DECLARE_INTERRUPT(75) \
+	DECLARE_INTERRUPT(76) \
+	DECLARE_INTERRUPT(77) \
+	DECLARE_INTERRUPT(78) \
+	DECLARE_INTERRUPT(79) \
+	DECLARE_INTERRUPT(80) \
+	DECLARE_INTERRUPT(81) \
+	DECLARE_INTERRUPT(82) \
+	DECLARE_INTERRUPT(83) \
+	DECLARE_INTERRUPT(84) \
+	DECLARE_INTERRUPT(85) \
+	DECLARE_INTERRUPT(86) \
+	DECLARE_INTERRUPT(87) \
+	DECLARE_INTERRUPT(88) \
+	DECLARE_INTERRUPT(89) \
+	DECLARE_INTERRUPT(90) \
+	DECLARE_INTERRUPT(91) \
+	DECLARE_INTERRUPT(92) \
+	DECLARE_INTERRUPT(93) \
+	DECLARE_INTERRUPT(94) \
+	DECLARE_INTERRUPT(95) \
+	DECLARE_INTERRUPT(97) \
+	DECLARE_INTERRUPT(96) \
+	DECLARE_INTERRUPT(98) \
+	DECLARE_INTERRUPT(99) \
+	DECLARE_INTERRUPT(100) \
+	DECLARE_INTERRUPT(101) \
+	DECLARE_INTERRUPT(102) \
+	DECLARE_INTERRUPT(103) \
+	DECLARE_INTERRUPT(104) \
+	DECLARE_INTERRUPT(105) \
+	DECLARE_INTERRUPT(106) \
+	DECLARE_INTERRUPT(107) \
+	DECLARE_INTERRUPT(108) \
+	DECLARE_INTERRUPT(109) \
+	DECLARE_INTERRUPT(110) \
+	DECLARE_INTERRUPT(111) \
+	DECLARE_INTERRUPT(112) \
+	DECLARE_INTERRUPT(113) \
+	DECLARE_INTERRUPT(114) \
+	DECLARE_INTERRUPT(115) \
+	DECLARE_INTERRUPT(116) \
+	DECLARE_INTERRUPT(117) \
+	DECLARE_INTERRUPT(118) \
+	DECLARE_INTERRUPT(119) \
+	DECLARE_INTERRUPT(120) \
+	DECLARE_INTERRUPT(121) \
+	DECLARE_INTERRUPT(122) \
+	DECLARE_INTERRUPT(123) \
+	DECLARE_INTERRUPT(124) \
+	DECLARE_INTERRUPT(125) \
+	DECLARE_INTERRUPT(126) \
+	DECLARE_INTERRUPT(127) \
+	DECLARE_INTERRUPT(128) \
+	DECLARE_INTERRUPT(129) \
+	DECLARE_INTERRUPT(130) \
+	DECLARE_INTERRUPT(131) \
+	DECLARE_INTERRUPT(132) \
+	DECLARE_INTERRUPT(133) \
+	DECLARE_INTERRUPT(134) \
+	DECLARE_INTERRUPT(135) \
+	DECLARE_INTERRUPT(136) \
+	DECLARE_INTERRUPT(137) \
+	DECLARE_INTERRUPT(138) \
+	DECLARE_INTERRUPT(139) \
+	DECLARE_INTERRUPT(140) \
+	DECLARE_INTERRUPT(141) \
+	DECLARE_INTERRUPT(142) \
+	DECLARE_INTERRUPT(143) \
+	DECLARE_INTERRUPT(144) \
+	DECLARE_INTERRUPT(145) \
+	DECLARE_INTERRUPT(146) \
+	DECLARE_INTERRUPT(147) \
+	DECLARE_INTERRUPT(148) \
+	DECLARE_INTERRUPT(149) \
+	DECLARE_INTERRUPT(150) \
+	DECLARE_INTERRUPT(151) \
+	DECLARE_INTERRUPT(152) \
+	DECLARE_INTERRUPT(153) \
+	DECLARE_INTERRUPT(154) \
+	DECLARE_INTERRUPT(155) \
+	DECLARE_INTERRUPT(156) \
+	DECLARE_INTERRUPT(157) \
+	DECLARE_INTERRUPT(158) \
+	DECLARE_INTERRUPT(159) \
+	DECLARE_INTERRUPT(160) \
+	DECLARE_INTERRUPT(161) \
+	DECLARE_INTERRUPT(162) \
+	DECLARE_INTERRUPT(163) \
+	DECLARE_INTERRUPT(164) \
+	DECLARE_INTERRUPT(165) \
+	DECLARE_INTERRUPT(166) \
+	DECLARE_INTERRUPT(167) \
+	DECLARE_INTERRUPT(168) \
+	DECLARE_INTERRUPT(169) \
+	DECLARE_INTERRUPT(170) \
+	DECLARE_INTERRUPT(171) \
+	DECLARE_INTERRUPT(172) \
+	DECLARE_INTERRUPT(173) \
+	DECLARE_INTERRUPT(174) \
+	DECLARE_INTERRUPT(175) \
+	DECLARE_INTERRUPT(176) \
+	DECLARE_INTERRUPT(177) \
+	DECLARE_INTERRUPT(178) \
+	DECLARE_INTERRUPT(179) \
+	DECLARE_INTERRUPT(180) \
+	DECLARE_INTERRUPT(181) \
+	DECLARE_INTERRUPT(182) \
+	DECLARE_INTERRUPT(183) \
+	DECLARE_INTERRUPT(184) \
+	DECLARE_INTERRUPT(185) \
+	DECLARE_INTERRUPT(186) \
+	DECLARE_INTERRUPT(187) \
+	DECLARE_INTERRUPT(188) \
+	DECLARE_INTERRUPT(189) \
+	DECLARE_INTERRUPT(190) \
+	DECLARE_INTERRUPT(191) \
+	DECLARE_INTERRUPT(192) \
+	DECLARE_INTERRUPT(193) \
+	DECLARE_INTERRUPT(194) \
+	DECLARE_INTERRUPT(195) \
+	DECLARE_INTERRUPT(196) \
+	DECLARE_INTERRUPT(197) \
+	DECLARE_INTERRUPT(198) \
+	DECLARE_INTERRUPT(199) \
+	DECLARE_INTERRUPT(200) \
+	DECLARE_INTERRUPT(201) \
+	DECLARE_INTERRUPT(202) \
+	DECLARE_INTERRUPT(203) \
+	DECLARE_INTERRUPT(204) \
+	DECLARE_INTERRUPT(205) \
+	DECLARE_INTERRUPT(206) \
+	DECLARE_INTERRUPT(207) \
+	DECLARE_INTERRUPT(208) \
+	DECLARE_INTERRUPT(209) \
+	DECLARE_INTERRUPT(210) \
+	DECLARE_INTERRUPT(211) \
+	DECLARE_INTERRUPT(212) \
+	DECLARE_INTERRUPT(213) \
+	DECLARE_INTERRUPT(214) \
+	DECLARE_INTERRUPT(215) \
+	DECLARE_INTERRUPT(216) \
+	DECLARE_INTERRUPT(217) \
+	DECLARE_INTERRUPT(218) \
+	DECLARE_INTERRUPT(219) \
+	DECLARE_INTERRUPT(220) \
+	DECLARE_INTERRUPT(221) \
+	DECLARE_INTERRUPT(222) \
+	DECLARE_INTERRUPT(223) \
+	DECLARE_INTERRUPT(224) \
+	DECLARE_INTERRUPT(225) \
+	DECLARE_INTERRUPT(226) \
+	DECLARE_INTERRUPT(227) \
+	DECLARE_INTERRUPT(228) \
+	DECLARE_INTERRUPT(229) \
+	DECLARE_INTERRUPT(230) \
+	DECLARE_INTERRUPT(231) \
+	DECLARE_INTERRUPT(232) \
+	DECLARE_INTERRUPT(233) \
+	DECLARE_INTERRUPT(234) \
+	DECLARE_INTERRUPT(235) \
+	DECLARE_INTERRUPT(236) \
+	DECLARE_INTERRUPT(237) \
+	DECLARE_INTERRUPT(238) \
+	DECLARE_INTERRUPT(239) \
+	DECLARE_INTERRUPT(240) \
+	DECLARE_INTERRUPT(241) \
+	DECLARE_INTERRUPT(242) \
+	DECLARE_INTERRUPT(243) \
+	DECLARE_INTERRUPT(244) \
+	DECLARE_INTERRUPT(245) \
+	DECLARE_INTERRUPT(246) \
+	DECLARE_INTERRUPT(247) \
+	DECLARE_INTERRUPT(248) \
+	DECLARE_INTERRUPT(249) \
+	DECLARE_INTERRUPT(250) \
+	DECLARE_INTERRUPT(251) \
+	DECLARE_INTERRUPT(252) \
+	DECLARE_INTERRUPT(253) \
+	DECLARE_INTERRUPT(254) \
+	DECLARE_INTERRUPT(255));
diff --git a/include/asm-i386/interrupt.h b/include/asm-i386/interrupt.h
index 7f408cb..3e2674a 100644
--- a/include/asm-i386/interrupt.h
+++ b/include/asm-i386/interrupt.h
@@ -43,31 +43,4 @@ extern char exception_stack[];
 
 #define __isr__ void __attribute__ ((regparm(0)))
 
-#define DECLARE_INTERRUPT(x) \
-	asm(".globl irq_"#x"\n" \
-		    "irq_"#x":\n" \
-		    "pusha \n" \
-		    "pushl $"#x"\n" \
-		    "pushl $irq_return\n" \
-		    "jmp   do_irq\n"); \
-	__isr__ irq_##x(void)
-
-#define DECLARE_EXCEPTION(x, f) \
-	asm(".globl exp_"#x"\n" \
-		    "exp_"#x":\n" \
-		    "pusha \n" \
-		    "movl     %esp, %ebx\n" \
-		    "movl     $exception_stack, %eax\n" \
-		    "movl     %eax, %esp \n" \
-		    "pushl    %ebx\n" \
-		    "movl     32(%esp), %ebx\n" \
-		    "xorl     %edx, %edx\n" \
-		    "movw     36(%esp), %dx\n" \
-		    "pushl    %edx\n" \
-		    "pushl    %ebx\n" \
-		    "pushl    $"#x"\n" \
-		    "pushl    $exp_return\n" \
-		    "jmp      "#f"\n"); \
-	__isr__ exp_##x(void)
-
 #endif
diff --git a/include/asm-i386/u-boot-i386.h b/include/asm-i386/u-boot-i386.h
index 3921e01..dfec307 100644
--- a/include/asm-i386/u-boot-i386.h
+++ b/include/asm-i386/u-boot-i386.h
@@ -55,9 +55,6 @@ int timer_init(void);
 /* cpu/.../interrupts.c */
 int cpu_init_interrupts(void);
 
-/* cpu/.../exceptions.c */
-int cpu_init_exceptions(void);
-
 /* board/.../... */
 int board_init(void);
 int dram_init(void);
diff --git a/lib_i386/interrupts.c b/lib_i386/interrupts.c
index 3f3613a..efbad72 100644
--- a/lib_i386/interrupts.c
+++ b/lib_i386/interrupts.c
@@ -109,8 +109,10 @@ void irq_free_handler(int irq)
 	return;
 }
 
-__isr__ do_irq(int irq)
+void do_irq(int hw_irq)
 {
+	int irq = hw_irq - 0x20;
+
 	if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) {
 		printf("do_irq: bad irq number %d\n", irq);
 		return;
diff --git a/lib_i386/pcat_interrupts.c b/lib_i386/pcat_interrupts.c
index f01298e..67e6e97 100644
--- a/lib_i386/pcat_interrupts.c
+++ b/lib_i386/pcat_interrupts.c
@@ -40,45 +40,12 @@
 #error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined"
 #endif
 
-DECLARE_INTERRUPT(0);
-DECLARE_INTERRUPT(1);
-DECLARE_INTERRUPT(3);
-DECLARE_INTERRUPT(4);
-DECLARE_INTERRUPT(5);
-DECLARE_INTERRUPT(6);
-DECLARE_INTERRUPT(7);
-DECLARE_INTERRUPT(8);
-DECLARE_INTERRUPT(9);
-DECLARE_INTERRUPT(10);
-DECLARE_INTERRUPT(11);
-DECLARE_INTERRUPT(12);
-DECLARE_INTERRUPT(13);
-DECLARE_INTERRUPT(14);
-DECLARE_INTERRUPT(15);
-
 int interrupt_init(void)
 {
 	u8 i;
 
 	disable_interrupts();
 
-	/* Setup interrupts */
-	set_vector(0x20, irq_0);
-	set_vector(0x21, irq_1);
-	set_vector(0x23, irq_3);
-	set_vector(0x24, irq_4);
-	set_vector(0x25, irq_5);
-	set_vector(0x26, irq_6);
-	set_vector(0x27, irq_7);
-	set_vector(0x28, irq_8);
-	set_vector(0x29, irq_9);
-	set_vector(0x2a, irq_10);
-	set_vector(0x2b, irq_11);
-	set_vector(0x2c, irq_12);
-	set_vector(0x2d, irq_13);
-	set_vector(0x2e, irq_14);
-	set_vector(0x2f, irq_15);
-
 	/* Mask all interrupts */
 	outb(0xff, MASTER_PIC + IMR);
 	outb(0xff, SLAVE_PIC + IMR);
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 5/8] Fix race condition when using SC520 timers
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
                   ` (3 preceding siblings ...)
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 4/8] Rearrange i386 Interupt Handling Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 6/8] Reorder source objects in lib_i386 Makefile Graeme Russ
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 cpu/i386/sc520/sc520_timer.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/cpu/i386/sc520/sc520_timer.c b/cpu/i386/sc520/sc520_timer.c
index 23de14b..25c9a24 100644
--- a/cpu/i386/sc520/sc520_timer.c
+++ b/cpu/i386/sc520/sc520_timer.c
@@ -35,6 +35,12 @@ void sc520_timer_isr(void)
 
 int timer_init(void)
 {
+	/* Register the SC520 specific timer interrupt handler */
+	register_timer_isr (sc520_timer_isr);
+
+	/* Install interrupt handler for GP Timer 1 */
+	irq_install_handler (0, timer_isr, NULL);
+
 	/* Map GP Timer 1 to Master PIC IR0  */
 	sc520_mmcr->gp_tmr_int_map[1] = 0x01;
 
@@ -54,11 +60,6 @@ int timer_init(void)
 	sc520_mmcr->gptmr1maxcmpa = 100;
 	sc520_mmcr->gptmr1ctl = 0xe009;
 
-	/* Register the SC520 specific timer interrupt handler */
-	register_timer_isr (sc520_timer_isr);
-
-	/* Install interrupt handler for GP Timer 1 */
-	irq_install_handler (0, timer_isr, NULL);
 	unmask_irq (0);
 
 	/* Clear the GP Timer 1 status register to get the show rolling*/
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 6/8] Reorder source objects in lib_i386 Makefile
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
                   ` (4 preceding siblings ...)
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 5/8] Fix race condition when using SC520 timers Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 7/8] Fix global label in inline asm compile error Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 8/8] Final i386 Relocation Graeme Russ
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 lib_i386/Makefile |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib_i386/Makefile b/lib_i386/Makefile
index bb9b330..9838506 100644
--- a/lib_i386/Makefile
+++ b/lib_i386/Makefile
@@ -32,16 +32,16 @@ SOBJS-y	+= realmode_switch.o
 COBJS-y	+= bios_setup.o
 COBJS-y	+= board.o
 COBJS-y	+= bootm.o
+COBJS-y	+= interrupts.o
+COBJS-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
+COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
 COBJS-$(CONFIG_PCI) += pci.o
 COBJS-$(CONFIG_PCI) += pci_type1.o
 COBJS-y	+= realmode.o
+COBJS-y	+= timer.o
 COBJS-y	+= video_bios.o
 COBJS-y	+= video.o
 COBJS-y	+= zimage.o
-COBJS-y	+= interrupts.o
-COBJS-y	+= timer.o
-COBJS-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
-COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
 
 SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 7/8] Fix global label in inline asm compile error
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
                   ` (5 preceding siblings ...)
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 6/8] Reorder source objects in lib_i386 Makefile Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 8/8] Final i386 Relocation Graeme Russ
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 include/configs/eNET.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/configs/eNET.h b/include/configs/eNET.h
index 54c34fa..0a86550 100644
--- a/include/configs/eNET.h
+++ b/include/configs/eNET.h
@@ -234,8 +234,8 @@
 #ifndef __ASSEMBLER__
 extern unsigned long ip;
 
-#define PRINTIP				asm ("call next_line\n" \
-					    "next_line:\n" \
+#define PRINTIP				asm ("call 0\n" \
+					    "0:\n" \
 					    "pop %%eax\n" \
 					    "movl %%eax, %0\n" \
 					    :"=r"(ip) \
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 8/8] Final i386 Relocation
  2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
                   ` (6 preceding siblings ...)
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 7/8] Fix global label in inline asm compile error Graeme Russ
@ 2009-09-26 12:57 ` Graeme Russ
  7 siblings, 0 replies; 10+ messages in thread
From: Graeme Russ @ 2009-09-26 12:57 UTC (permalink / raw)
  To: u-boot

---
 board/eNET/config.mk           |    2 +
 board/eNET/eNET.c              |   17 ++++--
 board/eNET/u-boot.lds          |   49 +++++++++++----
 cpu/i386/cpu.c                 |   12 ++-
 cpu/i386/interrupts.c          |    4 +-
 cpu/i386/start.S               |  125 +++---------------------------------
 include/asm-i386/u-boot-i386.h |   10 +++-
 lib_i386/Makefile              |    1 +
 lib_i386/board.c               |  108 ++++++++++++++++---------------
 lib_i386/elf_reloc.c           |  139 ++++++++++++++++++++++++++++++++++++++++
 lib_i386/interrupts.c          |    4 +-
 lib_i386/realmode.c            |    4 +-
 lib_i386/timer.c               |    2 +-
 13 files changed, 279 insertions(+), 198 deletions(-)
 create mode 100644 lib_i386/elf_reloc.c

diff --git a/board/eNET/config.mk b/board/eNET/config.mk
index a763841..cbec0a8 100644
--- a/board/eNET/config.mk
+++ b/board/eNET/config.mk
@@ -22,3 +22,5 @@
 #
 
 TEXT_BASE = 0x38040000
+PLATFORM_RELFLAGS += -fpic
+PLATFORM_LDFLAGS += -pic
diff --git a/board/eNET/eNET.c b/board/eNET/eNET.c
index 29cf295..baf7c95 100644
--- a/board/eNET/eNET.c
+++ b/board/eNET/eNET.c
@@ -47,7 +47,6 @@ void init_sc520_enet (void)
 {
 	/* Set CPU Speed to 100MHz */
 	sc520_mmcr->cpuctl = 0x01;
-	gd->cpu_clk = 100000000;
 
 	/* wait at least one millisecond */
 	asm("movl	$0x2000,%%ecx\n"
@@ -67,7 +66,7 @@ void init_sc520_enet (void)
 /*
  * Miscellaneous platform dependent initializations
  */
-int board_init(void)
+int board_early_init_f(void)
 {
 	init_sc520_enet();
 
@@ -117,12 +116,20 @@ int board_init(void)
 	sc520_mmcr->sysarbctl = 0x06;
 	sc520_mmcr->sysarbmenb = 0x0003;
 
-	/* Crystal is 33.000MHz */
-	gd->bus_clk = 33000000;
-
 	return 0;
 }
 
+int board_early_init_r(void)
+{
+	/* CPU Speed to 100MHz */
+	gd->cpu_clk = 100000000;
+
+ 	/* Crystal is 33.000MHz */
+ 	gd->bus_clk = 33000000;
+
+ 	return 0;
+}
+
 int dram_init(void)
 {
 	init_sc520_dram();
diff --git a/board/eNET/u-boot.lds b/board/eNET/u-boot.lds
index 832d101..1cd6056 100644
--- a/board/eNET/u-boot.lds
+++ b/board/eNET/u-boot.lds
@@ -28,39 +28,64 @@ ENTRY(_start)
 SECTIONS
 {
 	. = 0x38040000;		/* Location of bootcode in flash */
+	_i386boot_rom_copy_start = .;
 	.text  : { *(.text); }
 
 	. = ALIGN(4);
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+	. = ALIGN(4);
 	
 	.eh_frame : { *(.eh_frame) }
+	. = ALIGN(4);
 
-	_i386boot_text_size = SIZEOF(.text) + SIZEOF(.rodata);
-
-	. = 0x03FF0000;		/* Ram data segment to use */
-	_i386boot_romdata_dest = ABSOLUTE(.);
-	.data : AT ( LOADADDR(.eh_frame) + SIZEOF(.eh_frame) ) { *(.data) }
-/*	.data : { *(.data) } */
-	_i386boot_romdata_start = LOADADDR(.data);
+ 	.data : { *(.data) }
+ 	. = ALIGN(4);
+ 
+	.got : { *(.got) }
+ 	. = ALIGN(4);
+	_i386boot_got_start = LOADADDR(.got);
+	_i386boot_got_end = LOADADDR(.got) + SIZEOF(.got) - 1;
 
+	.got.plt : { *(.got.plt) }
 	. = ALIGN(4);
-	.got : AT ( LOADADDR(.data) + SIZEOF(.data) ) { *(.got) }
-
+	_i386boot_got_plt_start = LOADADDR(.got.plt);
+	_i386boot_got_plt_end = LOADADDR(.got.plt) + SIZEOF(.got.plt) - 1;
+	
+	.rel.got : { *(.rel.got) }
 	. = ALIGN(4);
+	_i386boot_rel_got_start = LOADADDR(.rel.got);
+	_i386boot_rel_got_end = LOADADDR(.rel.got) + SIZEOF(.rel.got) - 1;
+
+	.rel.dyn : { *(.rel.dyn) }
+ 	. = ALIGN(4);
+	_i386boot_rel_dyn_start = LOADADDR(.rel.dyn);
+	_i386boot_rel_dyn_end = LOADADDR(.rel.dyn) + SIZEOF(.rel.dyn) - 1;
+
+	.dynsym : { *(.dynsym) }
+ 	. = ALIGN(4);
+	_i386boot_dynsym_start = LOADADDR(.dynsym);
+	_i386boot_dynsym_end = LOADADDR(.dynsym) + SIZEOF(.dynsym) - 1;
+
+	.dynamic : { *(.dynamic) }
+ 	. = ALIGN(4);
+	_i386boot_dynamic_start = LOADADDR(.dynamic);
+	_i386boot_dynamic_end = LOADADDR(.dynamic) + SIZEOF(.dynamic) - 1;
+ 	
 	__u_boot_cmd_start = .;
 	.u_boot_cmd : { *(.u_boot_cmd) }
 	__u_boot_cmd_end = .;
 	_i386boot_cmd_start = LOADADDR(.u_boot_cmd);
+	. = ALIGN(4);
 
-	_i386boot_romdata_size = SIZEOF(.data) + SIZEOF(.got) + SIZEOF(.u_boot_cmd);
+	_i386boot_rom_copy_end = .;
 
-	. = ALIGN(4);
 	_i386boot_bss_start = ABSOLUTE(.);
 	.bss (NOLOAD) : { *(.bss) }
+	. = ALIGN(4);
 	_i386boot_bss_size = SIZEOF(.bss);
 
 	/* 16bit realmode trampoline code */
-	.realmode 0x7c0 : AT ( LOADADDR(.got) + SIZEOF(.got) + SIZEOF(.u_boot_cmd)) { *(.realmode) }
+	.realmode 0x7c0 : AT ( LOADADDR(.u_boot_cmd) + SIZEOF(.u_boot_cmd) ) { *(.realmode) }
 
 	_i386boot_realmode = LOADADDR(.realmode);
 	_i386boot_realmode_size = SIZEOF(.realmode);
diff --git a/cpu/i386/cpu.c b/cpu/i386/cpu.c
index 8baf37d..685f6c1 100644
--- a/cpu/i386/cpu.c
+++ b/cpu/i386/cpu.c
@@ -37,7 +37,7 @@
 #include <command.h>
 #include <asm/interrupt.h>
 
-int cpu_init(void)
+int cpu_init_f(void)
 {
 	/* initialize FPU, reset EM, set MP and NE */
 	asm ("fninit\n" \
@@ -46,12 +46,16 @@ int cpu_init(void)
 	     "orl  $0x22, %eax\n" \
 	     "movl %eax, %cr0\n" );
 
-	/* Initialize core interrupt and exception functionality of CPU */
-	cpu_init_interrupts ();
-
 	return 0;
 }
 
+int cpu_init_r(void)
+{
+ 	/* Initialize core interrupt and exception functionality of CPU */
+ 	cpu_init_interrupts ();
+ 	return 0;
+}
+
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	printf ("resetting ...\n");
diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c
index f4a297f..47bbdde 100644
--- a/cpu/i386/interrupts.c
+++ b/cpu/i386/interrupts.c
@@ -58,8 +58,8 @@ static inline void load_idt(const struct desc_ptr *dtr)
 
 void set_vector(u8 intnum, void *routine)
 {
-	idt[intnum].base_high = (u16)((u32)(routine + gd->reloc_off) >> 16);
-	idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff);
+	idt[intnum].base_high = (u16)((u32)(routine) >> 16);
+	idt[intnum].base_low = (u16)((u32)(routine) & 0xffff);
 }
 
 void irq_0(void);
diff --git a/cpu/i386/start.S b/cpu/i386/start.S
index 59089ef..320a607 100644
--- a/cpu/i386/start.S
+++ b/cpu/i386/start.S
@@ -63,11 +63,8 @@ early_board_init_ret:
 	jmp     mem_init
 mem_init_ret:
 
-	/* check ammount of configured memory
-	 * (we need atleast bss start+bss size+stack size) */
-	movl	$_i386boot_bss_start, %ecx        /* BSS start */
-	addl	$_i386boot_bss_size, %ecx         /* BSS size */
-	addl	$CONFIG_SYS_STACK_SIZE, %ecx
+	/* Check we have enough memory for stack */
+	movl	$CONFIG_SYS_STACK_SIZE, %ecx
 	cmpl	%ecx, %eax
 	jae	mem_ok
 
@@ -78,6 +75,8 @@ mem_init_ret:
 .progress0a:
 	jmp	die
 mem_ok:
+	/* Keep a copy of the memory size (needed later) */
+	movl	%eax, %ecx
 
 	/* indicate progress */
 	movw	$0x02, %ax
@@ -85,12 +84,11 @@ mem_ok:
 	jmp	show_boot_progress_asm
 .progress1:
 
-	/* create a stack after the bss */
-	movl    $_i386boot_bss_start, %eax
-	addl	$_i386boot_bss_size, %eax
-	addl	$CONFIG_SYS_STACK_SIZE, %eax
+	/* Create the stack at upper memory limit*/
+	subl	$0x100, %eax
 	movl    %eax, %esp
 
+	/* Test the stack */
 	pushl	$0
 	popl	%eax
 	cmpl	$0, %eax
@@ -116,115 +114,10 @@ stack_ok:
 	jmp	show_boot_progress_asm
 .progress2:
 
-	/* copy data section to ram, size must be 4-byte aligned */
-	movl	$_i386boot_romdata_dest, %edi	  /* destination address */
-	movl	$_i386boot_romdata_start, %esi	  /* source address */
-	movl	$_i386boot_romdata_size, %ecx     /* number of bytes to copy */
-	movl	%ecx, %eax
-	andl	$3, %eax
-	jnz	data_fail
-
-	shrl	$2, %ecx	                  /* copy 4 byte each time */
-	cld
-	cmpl	$0, %ecx
-	je	data_ok
-data_segment:
-	movsl
-	loop	data_segment
-	jmp	data_ok
-data_fail:
-	/* indicate (lack of) progress */
-	movw	$0x83, %ax
-	movl	$.progress2a, %ebp
-	jmp	show_boot_progress_asm
-.progress2a:
-	jmp	die
-
-data_ok:
-
-	/* indicate progress */
-	movw	$0x04, %ax
-	movl	$.progress3, %ebp
-	jmp	show_boot_progress_asm
-.progress3:
-
-	/* clear bss section in ram, size must be 4-byte aligned  */
-	movl	$_i386boot_bss_start, %edi        /* MK_CHG BSS start */
-	movl	$_i386boot_bss_size, %ecx         /* BSS size */
-	movl	%ecx, %eax
-	andl	$3, %eax
-	jnz	bss_fail
-	shrl	$2, %ecx	                  /* clear 4 byte each time */
-	cld
-	cmpl	$0, %ecx
-	je	bss_ok
-bss:
-	movl	$0, (%edi)
-	add	$4, %edi
-	loop	bss
-	jmp	bss_ok
-
-bss_fail:
-	/* indicate (lack of) progress */
-	movw	$0x84, %ax
-	movl	$.progress3a, %ebp
-	jmp	show_boot_progress_asm
-.progress3a:
-	jmp	die
-
-bss_ok:
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-	/* indicate progress */
-	movw	$0x06, %ax
-	movl	$.progress6, %ebp
-	jmp	show_boot_progress_asm
-.progress6:
-
-	/* copy text section to ram, size must be 4-byte aligned */
-	movl	$CONFIG_SYS_BL_START_RAM, %edi		/* destination address */
-	movl	$TEXT_BASE, %esi		/* source address */
-	movl	$_i386boot_text_size, %ecx	/* number of bytes to copy */
-	movl	%ecx, %eax
-	andl	$3, %eax
-	jz	text_copy			/* Already 4-byte aligned */
-	subl    $4, %eax			/* Add extra bytes to size */
-	addl	%eax, %ecx
-text_copy:
-	shrl	$2, %ecx			/* copy 4 byte each time */
-	cld
-	cmpl	$0, %ecx
-	je	text_ok
-text_segment:
-	movsl
-	loop	text_segment
-	jmp	text_ok
-text_fail:
-	/* indicate (lack of) progress */
-	movw	$0x86, %ax
-	movl	$.progress5a, %ebp
-	jmp	show_boot_progress_asm
-.progress5a:
-	jmp	die
-
-text_ok:
-#endif
 	wbinvd
 
-
-	/* indicate progress */
-	movw	$0x05, %ax
-	movl	$.progress4, %ebp
-	jmp	show_boot_progress_asm
-.progress4:
-
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-	/* Jump to the RAM copy of start_i386boot */
-	movl	$start_i386boot, %ebp
-	addl	$(CONFIG_SYS_BL_START_RAM - TEXT_BASE), %ebp
-	call	*%ebp		/* Enter, U-boot! */
-#else
-	call	start_i386boot  /* Enter, U-boot! */
-#endif
+	pushl	%ecx		/* mem_size parameter */
+	call	board_init_f	/* Enter, U-boot! */
 
 	/* indicate (lack of) progress */
 	movw	$0x85, %ax
diff --git a/include/asm-i386/u-boot-i386.h b/include/asm-i386/u-boot-i386.h
index dfec307..823e5ce 100644
--- a/include/asm-i386/u-boot-i386.h
+++ b/include/asm-i386/u-boot-i386.h
@@ -24,6 +24,8 @@
 #ifndef _U_BOOT_I386_H_
 #define _U_BOOT_I386_H_	1
 
+#include <elf.h>
+
 /* for the following variables, see start.S */
 extern ulong i386boot_start;	    /* code start (in flash) */
 extern ulong i386boot_end;	    /* code end (in flash) */
@@ -42,7 +44,8 @@ extern ulong i386boot_bios_size;    /* size of BIOS emulation code */
 
 
 /* cpu/.../cpu.c */
-int cpu_init(void);
+int cpu_init_r(void);
+int cpu_init_f(void);
 
 /* cpu/.../timer.c */
 void timer_isr(void *);
@@ -65,6 +68,11 @@ u32 isa_map_rom(u32 bus_addr, int size);
 /* lib_i386/... */
 int video_bios_init(void);
 int video_init(void);
+void elf_relocate(ulong rel_offset);
+void reloc_fixup_elf32_dyn (Elf32_Dyn *start, Elf32_Dyn *end, ulong offset);
+void reloc_fixup_elf32_sym (Elf32_Sym *start, Elf32_Sym *end, ulong offset);
+void reloc_fixup_elf32_rel (Elf32_Rel *start, Elf32_Rel *end, ulong offset);
+void reloc_fixup_elf32_rela (Elf32_Rela *start, Elf32_Rela *end, ulong offset);
 
 
 #endif	/* _U_BOOT_I386_H_ */
diff --git a/lib_i386/Makefile b/lib_i386/Makefile
index 9838506..1532579 100644
--- a/lib_i386/Makefile
+++ b/lib_i386/Makefile
@@ -32,6 +32,7 @@ SOBJS-y	+= realmode_switch.o
 COBJS-y	+= bios_setup.o
 COBJS-y	+= board.o
 COBJS-y	+= bootm.o
+COBJS-y	+= elf_reloc.o
 COBJS-y	+= interrupts.o
 COBJS-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
 COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
diff --git a/lib_i386/board.c b/lib_i386/board.c
index 39a3099..4c77a9f 100644
--- a/lib_i386/board.c
+++ b/lib_i386/board.c
@@ -41,13 +41,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-extern long _i386boot_start;
 extern long _i386boot_end;
-extern long _i386boot_romdata_start;
-extern long _i386boot_romdata_dest;
-extern long _i386boot_romdata_size;
 extern long _i386boot_bss_start;
 extern long _i386boot_bss_size;
+extern long _i386boot_rom_copy_start;
+extern long _i386boot_rom_copy_end;
 
 extern long _i386boot_realmode;
 extern long _i386boot_realmode_size;
@@ -56,11 +54,7 @@ extern long _i386boot_bios_size;
 
 /* The symbols defined by the linker script becomes pointers
  * which is somewhat inconveient ... */
-ulong i386boot_start         = (ulong)&_i386boot_start;         /* code start (in flash) defined in start.S */
 ulong i386boot_end           = (ulong)&_i386boot_end;	        /* code end (in flash) */
-ulong i386boot_romdata_start = (ulong)&_i386boot_romdata_start; /* datasegment in flash (also code+rodata end) */
-ulong i386boot_romdata_dest  = (ulong)&_i386boot_romdata_dest;  /* data location segment in ram */
-ulong i386boot_romdata_size  = (ulong)&_i386boot_romdata_size;  /* size of data segment */
 ulong i386boot_bss_start     = (ulong)&_i386boot_bss_start;     /* bss start */
 ulong i386boot_bss_size      = (ulong)&_i386boot_bss_size;      /* bss size */
 
@@ -73,19 +67,7 @@ ulong i386boot_bios_size     = (ulong)&_i386boot_bios_size;     /* size of BIOS
 const char version_string[] =
 	U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")";
 
-static int heap_init(void)
-{
-	/* start malloc area right after the stack */
-	ulong start = i386boot_bss_start + i386boot_bss_size +
-			CONFIG_SYS_STACK_SIZE;
-
-	/* 4-byte aligned */
-	start = (start+3)&~3;
-
-	mem_malloc_init(start, CONFIG_SYS_MALLOC_LEN);
-
-	return 0;
-}
+void start_i386boot (ulong);
 
 /************************************************************************
  * Init Utilities							*
@@ -110,6 +92,7 @@ static int display_banner (void)
 {
 
 	printf ("\n\n%s\n\n", version_string);
+/*
 	printf ("U-Boot code: %08lX -> %08lX  data: %08lX -> %08lX\n"
 		"        BSS: %08lX -> %08lX stack: %08lX -> %08lX\n",
 		i386boot_start, i386boot_romdata_start-1,
@@ -117,7 +100,7 @@ static int display_banner (void)
 		i386boot_bss_start, i386boot_bss_start+i386boot_bss_size-1,
 		i386boot_bss_start+i386boot_bss_size,
 		i386boot_bss_start+i386boot_bss_size+CONFIG_SYS_STACK_SIZE-1);
-
+*/
 
 	return (0);
 }
@@ -160,6 +143,50 @@ static void display_flash_config (ulong size)
  * its main purpose is to initialize the RAM so that we
  * can relocate the monitor code to RAM.
  */
+void board_init_f (ulong mem_size)
+{
+	ulong i386boot_rom_copy_start = (ulong)&_i386boot_rom_copy_start;
+	ulong i386boot_rom_copy_end = (ulong)&_i386boot_rom_copy_end;
+	ulong i386boot_bss_start = (ulong)&_i386boot_bss_start;
+	ulong i386boot_bss_size = (ulong)&_i386boot_bss_size;
+
+	ulong uboot_rom_size = i386boot_rom_copy_end - i386boot_rom_copy_start;
+
+	ulong ram_start = mem_size -
+			(CONFIG_SYS_STACK_SIZE +
+					uboot_rom_size +
+					i386boot_bss_size);
+
+	ulong rel_offset  = CONFIG_SYS_MONITOR_BASE - ram_start;
+
+	void (*start_func)(ulong) = start_i386boot - rel_offset;
+
+	/* compiler optimization barrier needed for GCC >= 3.4 */
+	__asm__ __volatile__("": : :"memory");
+
+	/* First stage CPU initialization */
+	if (cpu_init_f() != 0)
+		hang();
+
+	/* First stage Board initialization */
+	if (board_early_init_f() != 0)
+		hang();
+
+	memcpy((void *)ram_start,
+		(void *)CONFIG_SYS_MONITOR_BASE,
+		uboot_rom_size);
+
+	memset ((void *) i386boot_bss_start - rel_offset,
+		0,
+		i386boot_bss_size);
+
+	elf_relocate(rel_offset);
+
+	start_func(ram_start);
+
+	/* NOTREACHED - relocate_code() does not return */
+	while(1);
+}
 
 /*
  * All attempts to come up with a "common" initialization sequence
@@ -176,10 +203,9 @@ static void display_flash_config (ulong size)
 typedef int (init_fnc_t) (void);
 
 init_fnc_t *init_sequence[] = {
-	cpu_init,		/* basic cpu dependent setup */
-	board_init,		/* basic board dependent setup */
+	cpu_init_r,		/* basic cpu dependent setup */
+	board_early_init_r,	/* basic board dependent setup */
 	dram_init,		/* configure available RAM banks */
-	heap_init,		/* dependant on dram_init */
 	interrupt_init,		/* set up exceptions */
 	timer_init,
 	serial_init,
@@ -194,7 +220,7 @@ init_fnc_t *init_sequence[] = {
 
 gd_t *gd;
 
-void start_i386boot (void)
+void start_i386boot (ulong ram_start)
 {
 	char *s;
 	int i;
@@ -203,9 +229,6 @@ void start_i386boot (void)
 	static bd_t bd_data;
 	init_fnc_t **init_fnc_ptr;
 
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-	cmd_tbl_t *p;
-#endif
 	show_boot_progress(0x21);
 
 	gd = &gd_data;
@@ -219,10 +242,9 @@ void start_i386boot (void)
 
 	gd->baudrate =  CONFIG_BAUDRATE;
 
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-	/* Need to set relocation offset here for interrupt initialization */
-	gd->reloc_off =  CONFIG_SYS_BL_START_RAM - TEXT_BASE;
-#endif
+	mem_malloc_init(((ram_start - CONFIG_SYS_MALLOC_LEN)+3)&~3,
+			CONFIG_SYS_MALLOC_LEN);
+
 	for (init_fnc_ptr = init_sequence, i=0; *init_fnc_ptr; ++init_fnc_ptr, i++) {
 		show_boot_progress(0xa130|i);
 
@@ -232,26 +254,6 @@ void start_i386boot (void)
 	}
 	show_boot_progress(0x23);
 
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-	for (p = &__u_boot_cmd_start; p != &__u_boot_cmd_end; p++) {
-		ulong addr;
-		addr = (ulong) (p->cmd) + gd->reloc_off;
-		p->cmd = (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
-		addr = (ulong)(p->name) + gd->reloc_off;
-		p->name = (char *)addr;
-
-		if (p->usage != NULL) {
-			addr = (ulong)(p->usage) + gd->reloc_off;
-			p->usage = (char *)addr;
-		}
-	#ifdef	CONFIG_SYS_LONGHELP
-		if (p->help != NULL) {
-			addr = (ulong)(p->help) + gd->reloc_off;
-			p->help = (char *)addr;
-		}
-	#endif
-	}
-#endif
 	/* configure available FLASH banks */
 	size = flash_init();
 	display_flash_config(size);
diff --git a/lib_i386/elf_reloc.c b/lib_i386/elf_reloc.c
new file mode 100644
index 0000000..ee5e589
--- /dev/null
+++ b/lib_i386/elf_reloc.c
@@ -0,0 +1,139 @@
+/*
+ * (C) Copyright 2009
+ * Graeme Russ, graeme.russ at gmail.com
+ *
+ * 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 <elf.h>
+#include <asm/u-boot-i386.h>
+
+extern long _i386boot_dynamic_start;
+extern long _i386boot_dynamic_end;
+extern long _i386boot_dynsym_start;
+extern long _i386boot_dynsym_end;
+extern long _i386boot_rel_dyn_start;
+extern long _i386boot_rel_dyn_end;
+extern long _i386boot_rel_got_start;
+extern long _i386boot_rel_got_end;
+extern long _i386boot_got_start;
+extern long _i386boot_got_end;
+extern long _i386boot_got_plt_start;
+extern long _i386boot_got_plt_end;
+
+void elf_relocate(ulong rel_offset)
+{
+	ulong *reloc_ptr;
+
+	/*
+	 * Need to process:
+	 *  .rel.got - Array of Elf32_Rel
+	 *  .got.plt - Array of Elf32_Rela
+	 *
+	 *  .dynsym - Array of Elf32_Sym
+	 *  .rel.dyn - Array of Elf32_Rel
+	 */
+	reloc_ptr = (ulong *)_i386boot_dynamic_start;
+
+	reloc_fixup_elf32_rel ((Elf32_Rel *)&_i386boot_rel_got_start,
+			(Elf32_Rel *)&_i386boot_rel_got_end,
+			rel_offset);
+
+	reloc_fixup_elf32_rela ((Elf32_Rela *)&_i386boot_got_plt_start,
+			(Elf32_Rela *)&_i386boot_got_plt_end,
+			rel_offset);
+
+	reloc_fixup_elf32_rel ((Elf32_Rel *)&_i386boot_rel_dyn_start,
+			(Elf32_Rel *)&_i386boot_rel_dyn_end,
+			rel_offset);
+
+	reloc_fixup_elf32_dyn ((Elf32_Dyn *)&_i386boot_dynamic_start,
+			(Elf32_Dyn *)&_i386boot_dynamic_end,
+			rel_offset);
+
+	reloc_fixup_elf32_sym ((Elf32_Sym *)&_i386boot_dynsym_start,
+			(Elf32_Sym *)&_i386boot_dynsym_end,
+			rel_offset);
+}
+
+void reloc_fixup_elf32_rel (Elf32_Rel *start, Elf32_Rel *end, ulong offset)
+{
+	Elf32_Rel *reloc_entry = (Elf32_Rel *)((ulong)start - offset);
+	Elf32_Rel *table_end   = (Elf32_Rel *)((ulong)end - offset);
+
+	while (reloc_entry <= table_end) {
+		if (reloc_entry->r_offset >= TEXT_BASE) {
+			ulong *ref;
+			reloc_entry->r_offset -= (Elf32_Addr)offset;
+
+			ref = (ulong *)reloc_entry->r_offset;
+
+			if (*ref >= TEXT_BASE)
+				*ref -= (Elf32_Addr)offset;
+		}
+
+		reloc_entry++;
+	}
+}
+
+void reloc_fixup_elf32_rela (Elf32_Rela *start, Elf32_Rela *end, ulong offset)
+{
+	Elf32_Rela *reloc_entry = (Elf32_Rela *)((ulong)start - offset);
+	Elf32_Rela *table_end   = (Elf32_Rela *)((ulong)end - offset);
+
+	while (reloc_entry <= table_end) {
+		if (reloc_entry->r_offset >= TEXT_BASE) {
+			ulong *ref;
+			reloc_entry->r_offset -= (Elf32_Addr)offset;
+
+			ref = (ulong *)reloc_entry->r_offset;
+
+			if (*ref >= TEXT_BASE)
+				*ref -= (Elf32_Addr)offset;
+		}
+
+		reloc_entry++;
+	}
+}
+
+void reloc_fixup_elf32_sym (Elf32_Sym *start, Elf32_Sym *end, ulong offset)
+{
+	Elf32_Sym *reloc_entry = (Elf32_Sym *)((ulong)start - offset);
+	Elf32_Sym *table_end   = (Elf32_Sym *)((ulong)end - offset);
+
+	while (reloc_entry <= table_end) {
+		if (reloc_entry->st_value >= TEXT_BASE)
+			reloc_entry->st_value -= (Elf32_Addr)offset;
+
+		reloc_entry++;
+	}
+}
+
+void reloc_fixup_elf32_dyn (Elf32_Dyn *start, Elf32_Dyn *end, ulong offset)
+{
+	Elf32_Dyn *reloc_entry = (Elf32_Dyn *)((ulong)start - offset);
+	Elf32_Dyn *table_end   = (Elf32_Dyn *)((ulong)end - offset);
+
+	while (reloc_entry <= table_end) {
+		if (reloc_entry->d_un.d_ptr >= TEXT_BASE)
+			reloc_entry->d_un.d_ptr -= (Elf32_Addr)offset;
+
+		reloc_entry++;
+	}
+}
+
diff --git a/lib_i386/interrupts.c b/lib_i386/interrupts.c
index efbad72..51def59 100644
--- a/lib_i386/interrupts.c
+++ b/lib_i386/interrupts.c
@@ -70,12 +70,12 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
 
 	if (irq_handlers[irq].handler != NULL)
 		printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
-		       (ulong) handler + gd->reloc_off,
+		       (ulong) handler,
 		       (ulong) irq_handlers[irq].handler);
 
 	status = disable_interrupts ();
 
-	irq_handlers[irq].handler = handler + gd->reloc_off;
+	irq_handlers[irq].handler = handler;
 	irq_handlers[irq].arg = arg;
 	irq_handlers[irq].count = 0;
 
diff --git a/lib_i386/realmode.c b/lib_i386/realmode.c
index 6cf2738..726d1d3 100644
--- a/lib_i386/realmode.c
+++ b/lib_i386/realmode.c
@@ -68,10 +68,10 @@ int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out)
 
 	memcpy(REALMODE_MAILBOX, in, sizeof(struct pt_regs));
 	asm("wbinvd\n");
-
+/* TODO
 	__asm__ volatile (
 		 "lcall $0x20,%0\n"  : :  "i" (&realmode_enter) );
-
+*/
 	asm("wbinvd\n");
 	memcpy(out, REALMODE_MAILBOX, sizeof(struct pt_regs));
 
diff --git a/lib_i386/timer.c b/lib_i386/timer.c
index 58a0212..5cb1f54 100644
--- a/lib_i386/timer.c
+++ b/lib_i386/timer.c
@@ -51,7 +51,7 @@ int register_timer_isr (timer_fnc_t *isr_func)
 	if (new_func == NULL)
 		return 1;
 
-	new_func->isr_func = isr_func + gd->reloc_off;
+	new_func->isr_func = isr_func;
 	new_func->next = NULL;
 
 	/*
-- 
1.6.4.1.174.g32f4c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning
  2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning Graeme Russ
@ 2009-09-26 19:20   ` Mike Frysinger
  0 siblings, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2009-09-26 19:20 UTC (permalink / raw)
  To: u-boot

On Saturday 26 September 2009 08:57:31 Graeme Russ wrote:
> ---
>  common/Makefile |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/common/Makefile b/common/Makefile
> index 3781738..7ea6e93 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -178,6 +178,10 @@ $(obj)env_embedded.o: $(src)env_embedded.c
>  $(obj)../tools/envcrc -DENV_CRC=$(shell $(obj)../tools/envcrc) \
>  		-c -o $@ $(src)env_embedded.c
> 
> +$(obj)dlmalloc.o: $(src)dlmalloc.c $(obj)dlmalloc.o
> +	$(CC) $(CFLAGS) -Wa,--no-warn -fno-strict-aliasing \
> +		-c -o $@ $(src)dlmalloc.c

there's already patches floating around to fix this at the source level

but if your only goal is to add custom compiler flags, please use the per-
object CFLAGS support.  this should work:
CFLAGS_dlmalloc.o += -Wa,--no-warn -fno-strict-aliasing
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20090926/7a9a67b3/attachment.pgp 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-09-26 19:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-26 12:57 [U-Boot] [RFC][PATCH 0/8] i386 Full Relocation Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 1/8] Fix gcc 4.4.1 compiler warning Graeme Russ
2009-09-26 19:20   ` Mike Frysinger
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 2/8] Add low-level progress indications Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 3/8] Fix i386 malloc initialisation Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 4/8] Rearrange i386 Interupt Handling Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 5/8] Fix race condition when using SC520 timers Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 6/8] Reorder source objects in lib_i386 Makefile Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 7/8] Fix global label in inline asm compile error Graeme Russ
2009-09-26 12:57 ` [U-Boot] [RFC][PATCH 8/8] Final i386 Relocation Graeme Russ

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.