coreboot-v3/arch/x86/stage0_common.S
<<
>>
Prefs
   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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.