summaryrefslogtreecommitdiff
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/cpu/start.S36
-rw-r--r--arch/i386/cpu/start16.S8
2 files changed, 38 insertions, 6 deletions
diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S
index 1980f1a7b7..3cea04b4ce 100644
--- a/arch/i386/cpu/start.S
+++ b/arch/i386/cpu/start.S
@@ -33,7 +33,27 @@
.type _start, @function
.globl _i386boot_start
_i386boot_start:
+ /*
+ * This is the fail safe 32-bit bootstrap entry point. The
+ * following code is not executed from a cold-reset (actually, a
+ * lot of it is, but from real-mode after cold reset. It is
+ * repeated here to put the board into a state as close to cold
+ * reset as necessary)
+ */
+ cli
+ cld
+
+ /* Turn of cache (this might require a 486-class CPU) */
+ movl %cr0, %eax
+ orl $0x60000000,%eax
+ movl %eax, %cr0
+ wbinvd
+
+ /* Tell 32-bit code it is being entered from an in-RAM copy */
+ movw $0x0000, %bx
_start:
+ /* This is the 32-bit cold-reset entry point */
+
movl $0x18,%eax /* Load our segement registes, the
* gdt have already been loaded by start16.S */
movw %ax,%fs
@@ -42,6 +62,18 @@ _start:
movw %ax,%es
movw %ax,%ss
+ /* Clear the interupt vectors */
+ lidt blank_idt_ptr
+
+ /*
+ * Skip low-level board and memory initialization if not starting
+ * from cold-reset. This allows us to do a fail safe boot-strap
+ * into a new build of U-Boot from a known-good boot flash
+ */
+ movw $0x0001, %ax
+ cmpw %ax, %bx
+ jne mem_init_ret
+
/* We call a few functions in the board support package
* since we have no stack yet we'll have to use %ebp
* to store the return address */
@@ -138,3 +170,7 @@ stack_ok:
die: hlt
jmp die
hlt
+
+blank_idt_ptr:
+ .word 0 /* limit */
+ .long 0 /* base */
diff --git a/arch/i386/cpu/start16.S b/arch/i386/cpu/start16.S
index 1ebb6bc8b6..5e33aa1069 100644
--- a/arch/i386/cpu/start16.S
+++ b/arch/i386/cpu/start16.S
@@ -45,10 +45,8 @@ board_init16_ret:
wbinvd
/* load the descriptor tables */
-o32 cs lidt idt_ptr
o32 cs lgdt gdt_ptr
-
/* Now, we enter protected mode */
movl %cr0, %eax
orl $1,%eax
@@ -57,6 +55,8 @@ o32 cs lgdt gdt_ptr
/* Flush the prefetch queue */
jmp ff
ff:
+ /* Tell 32-bit code it is being entered from hard-reset */
+ movw $0x0001, %bx
/* Finally jump to the 32bit initialization code */
movw $code32start, %ax
@@ -68,10 +68,6 @@ code32start:
.long _start /* offset */
.word 0x10 /* segment */
-idt_ptr:
- .word 0 /* limit */
- .long 0 /* base */
-
gdt_ptr:
.word 0x30 /* limit (48 bytes = 6 GDT entries) */
.long BOOT_SEG + gdt /* base */