* [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 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
* [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