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

