coreboot-v3/arch/x86/secondary.S
<<
>>
Prefs
   1/*
   2 * This file is part of the coreboot project.
   3 *
   4 * Copyright (C) 2002 Linux Networx
   5 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
   6 * Copyright (C) 2004 Ollie Lo
   7 * Copyright (C) 2005 YingHai Lu
   8 * Copyright (C) Copyright (C) 2005-2007 Stefan Reinauer <stepan@openbios.org>
   9 * Copyright (C) 2009 Ronald G. Minnich <rminnich@gmail.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; version 2 of the License.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
  23 */
  24
  25/* POST_ZERO writes a POST_CODE at zero. Note that once we load %ds from %cs, "0" is at the start of this function!
  26 * This is debug only; you can't use it on systems with more than one core. It should be left off by default. 
  27 */
  28#define NO_POST_ZERO
  29
  30#ifdef NO_POST_ZERO
  31#define POST_ZERO(x)
  32#else
  33#define POST_ZERO(x) movw       x, 0
  34#endif
  35        .text
  36        .globl _secondary_start, _secondary_start_end
  37_secondary_start:
  381:
  39        .code16
  40        .balign 4096
  41        cli
  42        POST_ZERO($0xdead)
  43        xorl    %eax, %eax
  44        movl    %eax, %cr3    /* Invalidate TLB*/
  45        /* On hyper threaded cpus, invalidating the cache here is
  46         * very very bad.  Don't.
  47         */
  48        POST_ZERO($0)
  49        movl    $1b, %ebx
  50        POST_ZERO($1)
  51        POST_ZERO($2)
  52
  53        /* setup the data segment */
  54        movw    %cs, %ax
  55        movw    %ax, 2
  56        POST_ZERO($3)
  57        movw    %ax, %ds
  58        POST_ZERO($4)
  59        /* past this point, "0" means ds:0, i.e. cs:0, or the 
  60         * segment part of the address. 
  61         */
  62
  63        data32  lgdt    gdtaddr  - _secondary_start
  64//      data32 lgdt %cs:gdtptr
  65        POST_ZERO($5)
  66
  67        movl    %cr0, %eax
  68        POST_ZERO($6)
  69        andl    $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
  70        POST_ZERO($7)
  71        orl     $0x60000001, %eax /* CD, NW, PE = 1 */
  72        POST_ZERO($8)
  73        movl    %eax, %cr0
  74        POST_ZERO($9)
  75
  76        /* This jump pops us into 32-bit protected mode */
  77        data32 ljmp     $0x8, $secondary32
  78        POST_ZERO($0xa)
  791:      
  80        .code32
  81secondary32:
  82        POST_ZERO($0x11)
  83        movw    $0x10, %ax
  84        movw    %ax, %ds
  85        /* having a post here for testing is useful. 
  86         *If ds is bad for some reason, we'll reboot */
  87        POST_ZERO($0x13)
  88        movw    %ax, %es
  89        movw    %ax, %ss
  90        movw    %ax, %fs
  91        movw    %ax, %gs
  92        POST_ZERO($0x17)
  93
  94        /* Load the Interrupt descriptor table */
  95        lidt    idtarg
  96
  97        /* Set the stack pointer */
  98        movl    -4(%ebx),%esp
  99        movl    $0, -4(%ebx)
 100        /* tested to this point but not past it */
 101        /* AP sees the stack value set to 0 */
 102
 103        call    secondary_cpu_init
 1041:      hlt
 105        jmp     1b
 106        .align 4
 107
 108gdt_limit = gdt_end - gdt - 1           /* Compute the table limit. */
 109
 110gdt:
 111gdtptr:
 112        .word   gdt_end - gdt -1        /* Compute the table limit. */
 113        .long   gdt                     /* We know the offset. */
 114        .word   0
 115
 116        /* selgdt 0x08, flat code segment */
 117        .word   0xffff, 0x0000
 118        .byte   0x00, 0x9b, 0xcf, 0x00
 119
 120        /* selgdt 0x10, flat data segment */
 121        .word   0xffff, 0x0000
 122        .byte   0x00, 0x93, 0xcf, 0x00
 123gdt_end:
 124
 125
 126        gdtaddr:
 127        .word   gdt_limit       /* the table limit */
 128        .long   gdt             /* we know the offset */
 129idtarg:
 130        .word   _idt_end - _idt - 1     /* limit */
 131        .long   _idt
 132        .word   0       
 133_idt:
 134        .fill   20, 8, 0        # idt is unitiailzed
 135_idt_end:
 136
 137
 138_secondary_start_end:
 139.code32
 140
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.