1/* 2 * This file is part of the coreboot project. 3 * 4 * Copyright (C) 1999 Ronald G. Minnich 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 .code16 21 .globl _stage0 22_stage0: 23 cli 24 25 /* Save the BIST result. */ 26 movl %eax, %ebp; 27 28 /* thanks to kmliu@sis.com.tw for this TLB fix */ 29 /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before 30 * executing any further code. Even though paging is disabled we 31 * could still get false address translations due to the TLB if we 32 * didn't invalidate it. 33 */ 34 xorl %eax, %eax 35 movl %eax, %cr3 /* Invalidate TLB. */ 36 37 /* Switch to protected mode. */ 38 39 /* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux) 40 * using BFD version 2.15.94.0.2.2 20041220 this works fine without all 41 * the ld hackery and other things. So leave it as is with this comment. 42 */ 43 44 data32 lgdt %cs:gdtptr 45 46 movl %cr0, %eax 47 andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */ 48 orl $0x60000001, %eax /* CD, NW, PE = 1 */ 49 movl %eax, %cr0 50 51 /* Restore BIST result. */ 52 movl %ebp, %eax 53 54 // port80_post(0x23) 55 56 /* Now we are in protected mode. Jump to a 32 bit code segment. */ 57 data32 ljmp $ROM_CODE_SEG, $protected_stage0 58 59 /* I am leaving this weird jump in here in the event that future gas 60 * bugs force it to be used. 61 */ 62 /* .byte 0x66 */ 63 .code32 64 /* ljmp $ROM_CODE_SEG, $protected_stage0 */ 65 66 /* .code16 */ 67 .align 4 68 .globl gdt16 69gdt16 = . - _stage0 70gdt16x: 71 .word gdt16xend - gdt16x -1 /* Compute the table limit. */ 72 .long gdt16x 73 .word 0 74 75 /* selgdt 0x08, flat code segment */ 76 .word 0xffff, 0x0000 77 .byte 0x00, 0x9b, 0xcf, 0x00 78 79 /* selgdt 0x10, flat data segment */ 80 .word 0xffff, 0x0000 81 .byte 0x00, 0x93, 0xcf, 0x00 82gdt16xend: 83 84 /* From now on we are 32 bit. */ 85 .code32 86 87 /* We have two gdts where we could have one. That is ok. 88 * 89 * Let's not worry about this -- optimizing gdt is pointless since 90 * we're only in it for a little bit. 91 * 92 * Btw. note the trick below: The GDT points to ITSELF, and the first 93 * good descriptor is at offset 8. So you word-align the table, and 94 * then because you chose 8, you get a nice 64-bit aligned GDT entry, 95 * which is good as this is the size of the entry. 96 * Just in case you ever wonder why people do this. 97 */ 98 .align 4 99 .globl gdtptr 100 .globl gdt_limit 101gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */ 102 103gdt: 104gdtptr: 105 .word gdt_end - gdt -1 /* Compute the table limit. */ 106 .long gdt /* We know the offset. */ 107 .word 0 108 109 /* selgdt 0x08, flat code segment */ 110 .word 0xffff, 0x0000 111 .byte 0x00, 0x9b, 0xcf, 0x00 112 113 /* selgdt 0x10, flat data segment */ 114 .word 0xffff, 0x0000 115 .byte 0x00, 0x93, 0xcf, 0x00 116 117 /* selgdt 0x18, flat code segment for CAR */ 118 .word 0xffff, 0x0000 119 .byte 0x00, 0x9b, 0xcf, 0x00 120 121 /* selgdt 0x20, flat data segment for CAR */ 122 .word 0xffff, 0x0000 123 .byte 0x00, 0x93, 0xcf, 0x00 124gdt_end: 125 126/* Reset vector. */ 127 128/* 129 * RVECTOR: Size of reset vector, default is 0x10. 130 * RESRVED: Size of vpd code, default is 0xf0. 131 * BOOTBLK: Size of bootblock code, default is 0x1f00 (8k-256b). 132 */ 133 134SEGMENT_SIZE = 0x10000 135RVECTOR = 0x00010 136 137/* Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here. 138 * I think we should leave it this way forever, as the bugs come and 139 * go -- and come again. 140 * 141 * .code16 142 * .section ".rom.text" 143 */ 144.section ".reset", "ax" 145 .globl _resetjump 146_resetjump: 147 /* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */ 148 /* jmp _stage0 */ 149 .byte 0xe9 150 .int _stage0 - ( . + 2 ) 151 152#warning Everything below this line and two bytes above this line is being clobbered by LAR. For the discussion about this, see the thread at www.coreboot.org/pipermail/coreboot/2008-December/042771.html 153 /* Note: The above jump is hand coded to work around bugs in binutils. 154 * 5 bytes are used for a 3 byte instruction. This works because x86 155 * is little endian and allows us to use supported 32 bit relocations 156 * instead of the weird 16 bit relocations that binutils does not 157 * handle consistenly between versions because they are used so rarely. 158 */ 159.byte 0 160 161/* Date? ID string? We might want to put something else in here. */ 162.ascii DATE 163 164/* Checksum. */ 165/* .word 0 */ 166

