Author: hailfinger
Date: 2008-10-08 18:07:29 +0200 (Wed, 08 Oct 2008)
New Revision: 908
Added:
coreboot-v3/arch/x86/stage0_common.S
Modified:
coreboot-v3/arch/x86/amd/stage0.S
coreboot-v3/arch/x86/geodelx/stage0.S
coreboot-v3/arch/x86/i586/stage0.S
Log:
We have lots of bit-for-bit identical code in the various stage0
implementations. Factor out the 16 bit code with associated protected
mode activation.
I'm open to moving even more common code out, but this is a well-defined
start.
This cleanup has been prepared for by r902, r905 and r907.
Boot tested on qemu. Build tested on i586, geodelx, k8.
The diffstat is most enlightening:
amd/stage0.S | 145 ---------------------------------------------
geodelx/stage0.S | 145 ---------------------------------------------
i586/stage0.S | 145 ---------------------------------------------
stage0_common.S | 145 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 148 insertions(+), 432 deletions(-)
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006(a)gmx.net>
Acked-by: Ronald G. Minnich <rminnich(a)gmail.com>
Modified: coreboot-v3/arch/x86/amd/stage0.S
===================================================================
--- coreboot-v3/arch/x86/amd/stage0.S 2008-10-07 23:53:02 UTC (rev 907)
+++ coreboot-v3/arch/x86/amd/stage0.S 2008-10-08 16:07:29 UTC (rev 908)
@@ -38,112 +38,7 @@
#define CacheSizeAPStack 0x400 /* 1K */
#endif
- .code16
- .globl _stage0
-_stage0:
- cli
- /* Save the BIST result. */
- movl %eax, %ebp;
-
- /* thanks to kmliu(a)sis.com.tw for this TLB fix */
- /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
- * executing any further code. Even though paging is disabled we
- * could still get false address translations due to the TLB if we
- * didn't invalidate it.
- */
- xorl %eax, %eax
- movl %eax, %cr3 /* Invalidate TLB. */
-
- /* Switch to protected mode. */
-
- /* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
- * using BFD version 2.15.94.0.2.2 20041220 this works fine without all
- * the ld hackery and other things. So leave it as is with this comment.
- */
-
- data32 lgdt %cs:gdtptr
-
- movl %cr0, %eax
- andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
- orl $0x60000001, %eax /* CD, NW, PE = 1 */
- movl %eax, %cr0
-
- /* Restore BIST result. */
- movl %ebp, %eax
-
- // port80_post(0x23)
-
- /* Now we are in protected mode. Jump to a 32 bit code segment. */
- data32 ljmp $ROM_CODE_SEG, $protected_stage0
-
- /* I am leaving this weird jump in here in the event that future gas
- * bugs force it to be used.
- */
- /* .byte 0x66 */
- .code32
- /* ljmp $ROM_CODE_SEG, $protected_stage0 */
-
- /* .code16 */
- .align 4
- .globl gdt16
-gdt16 = . - _stage0
-gdt16x:
- .word gdt16xend - gdt16x -1 /* Compute the table limit. */
- .long gdt16x
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt16xend:
-
- /* From now on we are 32 bit. */
- .code32
-
- /* We have two gdts where we could have one. That is ok.
- *
- * Let's not worry about this -- optimizing gdt is pointless since
- * we're only in it for a little bit.
- *
- * Btw. note the trick below: The GDT points to ITSELF, and the first
- * good descriptor is at offset 8. So you word-align the table, and
- * then because you chose 8, you get a nice 64-bit aligned GDT entry,
- * which is good as this is the size of the entry.
- * Just in case you ever wonder why people do this.
- */
- .align 4
- .globl gdtptr
- .globl gdt_limit
-gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */
-
-gdt:
-gdtptr:
- .word gdt_end - gdt -1 /* Compute the table limit. */
- .long gdt /* We know the offset. */
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-
- /* selgdt 0x18, flat code segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x20, flat data segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt_end:
-
/* When we come here we are in protected mode. We expand the stack
* and copy the data segment from ROM to the memory.
*
@@ -468,42 +363,4 @@
.long 0xC001001A, 0xC001001D
.long 0x000 /* NULL, end of table */
-/* Reset vector. */
-
-/*
- * RVECTOR: Size of reset vector, default is 0x10.
- * RESRVED: Size of vpd code, default is 0xf0.
- * BOOTBLK: Size of bootblock code, default is 0x1f00 (8k-256b).
- */
-
-SEGMENT_SIZE = 0x10000
-RVECTOR = 0x00010
-
-/* Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
- * I think we should leave it this way forever, as the bugs come and
- * go -- and come again.
- *
- * .code16
- * .section ".rom.text"
- */
-.section ".reset", "ax"
- .globl _resetjump
-_resetjump:
- /* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
- /* jmp _stage0 */
- .byte 0xe9
- .int _stage0 - ( . + 2 )
-
- /* Note: The above jump is hand coded to work around bugs in binutils.
- * 5 bytes are used for a 3 byte instruction. This works because x86
- * is little endian and allows us to use supported 32 bit relocations
- * instead of the weird 16 bit relocations that binutils does not
- * handle consistenly between versions because they are used so rarely.
- */
-.byte 0
-
-/* Date? ID string? We might want to put something else in here. */
-.ascii DATE
-
-/* Checksum. */
-/* .word 0 */
+#include "../stage0_common.S"
Modified: coreboot-v3/arch/x86/geodelx/stage0.S
===================================================================
--- coreboot-v3/arch/x86/geodelx/stage0.S 2008-10-07 23:53:02 UTC (rev 907)
+++ coreboot-v3/arch/x86/geodelx/stage0.S 2008-10-08 16:07:29 UTC (rev 908)
@@ -28,112 +28,7 @@
#include <macros.h>
#include <amd_geodelx.h>
- .code16
- .globl _stage0
-_stage0:
- cli
- /* Save the BIST result. */
- movl %eax, %ebp;
-
- /* thanks to kmliu(a)sis.com.tw for this TLB fix */
- /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
- * executing any further code. Even though paging is disabled we
- * could still get false address translations due to the TLB if we
- * didn't invalidate it.
- */
- xorl %eax, %eax
- movl %eax, %cr3 /* Invalidate TLB. */
-
- /* Switch to protected mode. */
-
- /* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
- * using BFD version 2.15.94.0.2.2 20041220 this works fine without all
- * the ld hackery and other things. So leave it as is with this comment.
- */
-
- data32 lgdt %cs:gdtptr
-
- movl %cr0, %eax
- andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
- orl $0x60000001, %eax /* CD, NW, PE = 1 */
- movl %eax, %cr0
-
- /* Restore BIST result. */
- movl %ebp, %eax
-
- // port80_post(0x23)
-
- /* Now we are in protected mode. Jump to a 32 bit code segment. */
- data32 ljmp $ROM_CODE_SEG, $protected_stage0
-
- /* I am leaving this weird jump in here in the event that future gas
- * bugs force it to be used.
- */
- /* .byte 0x66 */
- .code32
- /* ljmp $ROM_CODE_SEG, $protected_stage0 */
-
- /* .code16 */
- .align 4
- .globl gdt16
-gdt16 = . - _stage0
-gdt16x:
- .word gdt16xend - gdt16x -1 /* Compute the table limit. */
- .long gdt16x
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt16xend:
-
- /* From now on we are 32 bit. */
- .code32
-
- /* We have two gdts where we could have one. That is ok.
- *
- * Let's not worry about this -- optimizing gdt is pointless since
- * we're only in it for a little bit.
- *
- * Btw. note the trick below: The GDT points to ITSELF, and the first
- * good descriptor is at offset 8. So you word-align the table, and
- * then because you chose 8, you get a nice 64-bit aligned GDT entry,
- * which is good as this is the size of the entry.
- * Just in case you ever wonder why people do this.
- */
- .align 4
- .globl gdtptr
- .globl gdt_limit
-gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */
-
-gdt:
-gdtptr:
- .word gdt_end - gdt -1 /* Compute the table limit. */
- .long gdt /* We know the offset. */
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-
- /* selgdt 0x18, flat code segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x20, flat data segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt_end:
-
/* When we come here we are in protected mode. We expand the stack
* and copy the data segment from ROM to the memory.
*
@@ -379,42 +274,4 @@
jmp stage1_main
/* We will not go back. */
-/* Reset vector. */
-
-/*
- * RVECTOR: Size of reset vector, default is 0x10.
- * RESRVED: Size of vpd code, default is 0xf0.
- * BOOTBLK: Size of bootblock code, default is 0x1f00 (8k-256b).
- */
-
-SEGMENT_SIZE = 0x10000
-RVECTOR = 0x00010
-
-/* Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
- * I think we should leave it this way forever, as the bugs come and
- * go -- and come again.
- *
- * .code16
- * .section ".rom.text"
- */
-.section ".reset", "ax"
- .globl _resetjump
-_resetjump:
- /* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
- /* jmp _stage0 */
- .byte 0xe9
- .int _stage0 - ( . + 2 )
-
- /* Note: The above jump is hand coded to work around bugs in binutils.
- * 5 bytes are used for a 3 byte instruction. This works because x86
- * is little endian and allows us to use supported 32 bit relocations
- * instead of the weird 16 bit relocations that binutils does not
- * handle consistenly between versions because they are used so rarely.
- */
-.byte 0
-
-/* Date? ID string? We might want to put something else in here. */
-.ascii DATE
-
-/* Checksum. */
-/* .word 0 */
+#include "../stage0_common.S"
Modified: coreboot-v3/arch/x86/i586/stage0.S
===================================================================
--- coreboot-v3/arch/x86/i586/stage0.S 2008-10-07 23:53:02 UTC (rev 907)
+++ coreboot-v3/arch/x86/i586/stage0.S 2008-10-08 16:07:29 UTC (rev 908)
@@ -32,112 +32,7 @@
#define CACHE_RAM_CODE_SEG 0x18
#define CACHE_RAM_DATA_SEG 0x20
- .code16
- .globl _stage0
-_stage0:
- cli
- /* Save the BIST result. */
- movl %eax, %ebp;
-
- /* thanks to kmliu(a)sis.com.tw for this TLB fix */
- /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
- * executing any further code. Even though paging is disabled we
- * could still get false address translations due to the TLB if we
- * didn't invalidate it.
- */
- xorl %eax, %eax
- movl %eax, %cr3 /* Invalidate TLB. */
-
- /* Switch to protected mode. */
-
- /* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
- * using BFD version 2.15.94.0.2.2 20041220 this works fine without all
- * the ld hackery and other things. So leave it as is with this comment.
- */
-
- data32 lgdt %cs:gdtptr
-
- movl %cr0, %eax
- andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
- orl $0x60000001, %eax /* CD, NW, PE = 1 */
- movl %eax, %cr0
-
- /* Restore BIST result. */
- movl %ebp, %eax
-
- // port80_post(0x23)
-
- /* Now we are in protected mode. Jump to a 32 bit code segment. */
- data32 ljmp $ROM_CODE_SEG, $protected_stage0
-
- /* I am leaving this weird jump in here in the event that future gas
- * bugs force it to be used.
- */
- /* .byte 0x66 */
- .code32
- /* ljmp $ROM_CODE_SEG, $protected_stage0 */
-
- /* .code16 */
- .align 4
- .globl gdt16
-gdt16 = . - _stage0
-gdt16x:
- .word gdt16xend - gdt16x -1 /* Compute the table limit. */
- .long gdt16x
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt16xend:
-
- /* From now on we are 32 bit. */
- .code32
-
- /* We have two gdts where we could have one. That is ok.
- *
- * Let's not worry about this -- optimizing gdt is pointless since
- * we're only in it for a little bit.
- *
- * Btw. note the trick below: The GDT points to ITSELF, and the first
- * good descriptor is at offset 8. So you word-align the table, and
- * then because you chose 8, you get a nice 64-bit aligned GDT entry,
- * which is good as this is the size of the entry.
- * Just in case you ever wonder why people do this.
- */
- .align 4
- .globl gdtptr
- .globl gdt_limit
-gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */
-
-gdt:
-gdtptr:
- .word gdt_end - gdt -1 /* Compute the table limit. */
- .long gdt /* We know the offset. */
- .word 0
-
- /* selgdt 0x08, flat code segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x10, flat data segment */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-
- /* selgdt 0x18, flat code segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x9b, 0xcf, 0x00
-
- /* selgdt 0x20, flat data segment for CAR */
- .word 0xffff, 0x0000
- .byte 0x00, 0x93, 0xcf, 0x00
-gdt_end:
-
/* When we come here we are in protected mode. We expand the stack
* and copy the data segment from ROM to the memory.
*
@@ -465,42 +360,4 @@
.long 0x20C, 0x20D, 0x20E, 0x20F
.long 0x000 /* NULL, end of table */
-/* Reset vector. */
-
-/*
- * RVECTOR: Size of reset vector, default is 0x10.
- * RESRVED: Size of vpd code, default is 0xf0.
- * BOOTBLK: Size of bootblock code, default is 0x1f00 (8k-256b).
- */
-
-SEGMENT_SIZE = 0x10000
-RVECTOR = 0x00010
-
-/* Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
- * I think we should leave it this way forever, as the bugs come and
- * go -- and come again.
- *
- * .code16
- * .section ".rom.text"
- */
-.section ".reset", "ax"
- .globl _resetjump
-_resetjump:
- /* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
- /* jmp _stage0 */
- .byte 0xe9
- .int _stage0 - ( . + 2 )
-
- /* Note: The above jump is hand coded to work around bugs in binutils.
- * 5 bytes are used for a 3 byte instruction. This works because x86
- * is little endian and allows us to use supported 32 bit relocations
- * instead of the weird 16 bit relocations that binutils does not
- * handle consistenly between versions because they are used so rarely.
- */
-.byte 0
-
-/* Date? ID string? We might want to put something else in here. */
-.ascii DATE
-
-/* Checksum. */
-/* .word 0 */
+#include "../stage0_common.S"
Added: coreboot-v3/arch/x86/stage0_common.S
===================================================================
--- coreboot-v3/arch/x86/stage0_common.S (rev 0)
+++ coreboot-v3/arch/x86/stage0_common.S 2008-10-08 16:07:29 UTC (rev 908)
@@ -0,0 +1,164 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 1999 Ronald G. Minnich
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ .code16
+ .globl _stage0
+_stage0:
+ cli
+
+ /* Save the BIST result. */
+ movl %eax, %ebp;
+
+ /* thanks to kmliu(a)sis.com.tw for this TLB fix */
+ /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
+ * executing any further code. Even though paging is disabled we
+ * could still get false address translations due to the TLB if we
+ * didn't invalidate it.
+ */
+ xorl %eax, %eax
+ movl %eax, %cr3 /* Invalidate TLB. */
+
+ /* Switch to protected mode. */
+
+ /* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
+ * using BFD version 2.15.94.0.2.2 20041220 this works fine without all
+ * the ld hackery and other things. So leave it as is with this comment.
+ */
+
+ data32 lgdt %cs:gdtptr
+
+ movl %cr0, %eax
+ andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
+ orl $0x60000001, %eax /* CD, NW, PE = 1 */
+ movl %eax, %cr0
+
+ /* Restore BIST result. */
+ movl %ebp, %eax
+
+ // port80_post(0x23)
+
+ /* Now we are in protected mode. Jump to a 32 bit code segment. */
+ data32 ljmp $ROM_CODE_SEG, $protected_stage0
+
+ /* I am leaving this weird jump in here in the event that future gas
+ * bugs force it to be used.
+ */
+ /* .byte 0x66 */
+ .code32
+ /* ljmp $ROM_CODE_SEG, $protected_stage0 */
+
+ /* .code16 */
+ .align 4
+ .globl gdt16
+gdt16 = . - _stage0
+gdt16x:
+ .word gdt16xend - gdt16x -1 /* Compute the table limit. */
+ .long gdt16x
+ .word 0
+
+ /* selgdt 0x08, flat code segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x9b, 0xcf, 0x00
+
+ /* selgdt 0x10, flat data segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x93, 0xcf, 0x00
+gdt16xend:
+
+ /* From now on we are 32 bit. */
+ .code32
+
+ /* We have two gdts where we could have one. That is ok.
+ *
+ * Let's not worry about this -- optimizing gdt is pointless since
+ * we're only in it for a little bit.
+ *
+ * Btw. note the trick below: The GDT points to ITSELF, and the first
+ * good descriptor is at offset 8. So you word-align the table, and
+ * then because you chose 8, you get a nice 64-bit aligned GDT entry,
+ * which is good as this is the size of the entry.
+ * Just in case you ever wonder why people do this.
+ */
+ .align 4
+ .globl gdtptr
+ .globl gdt_limit
+gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */
+
+gdt:
+gdtptr:
+ .word gdt_end - gdt -1 /* Compute the table limit. */
+ .long gdt /* We know the offset. */
+ .word 0
+
+ /* selgdt 0x08, flat code segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x9b, 0xcf, 0x00
+
+ /* selgdt 0x10, flat data segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x93, 0xcf, 0x00
+
+ /* selgdt 0x18, flat code segment for CAR */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x9b, 0xcf, 0x00
+
+ /* selgdt 0x20, flat data segment for CAR */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x93, 0xcf, 0x00
+gdt_end:
+
+/* Reset vector. */
+
+/*
+ * RVECTOR: Size of reset vector, default is 0x10.
+ * RESRVED: Size of vpd code, default is 0xf0.
+ * BOOTBLK: Size of bootblock code, default is 0x1f00 (8k-256b).
+ */
+
+SEGMENT_SIZE = 0x10000
+RVECTOR = 0x00010
+
+/* Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
+ * I think we should leave it this way forever, as the bugs come and
+ * go -- and come again.
+ *
+ * .code16
+ * .section ".rom.text"
+ */
+.section ".reset", "ax"
+ .globl _resetjump
+_resetjump:
+ /* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
+ /* jmp _stage0 */
+ .byte 0xe9
+ .int _stage0 - ( . + 2 )
+
+ /* Note: The above jump is hand coded to work around bugs in binutils.
+ * 5 bytes are used for a 3 byte instruction. This works because x86
+ * is little endian and allows us to use supported 32 bit relocations
+ * instead of the weird 16 bit relocations that binutils does not
+ * handle consistenly between versions because they are used so rarely.
+ */
+.byte 0
+
+/* Date? ID string? We might want to put something else in here. */
+.ascii DATE
+
+/* Checksum. */
+/* .word 0 */