1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2002 Linux Networx
* (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
* Copyright (C) 2004 Ollie Lo
* Copyright (C) 2005 YingHai Lu
* Copyright (C) Copyright (C) 2005-2007 Stefan Reinauer <stepan@openbios.org>
* Copyright (C) 2009 Ronald G. Minnich <rminnich@gmail.com>
*
* 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
*/
.text
.globl _secondary_start, _secondary_start_end
_secondary_start:
1:
.code16
.balign 4096
cli
movw $0xdead, 0
movw $0xbeef, 2
xorl %eax, %eax
movl %eax, %cr3 /* Invalidate TLB*/
/* On hyper threaded cpus, invalidating the cache here is
* very very bad. Don't.
*/
movw $0, 0
movl $1b, %ebx
movw $1, 0
movw $2, 0
/* setup the data segment */
movw %cs, %ax
movw %ax, 2
movw $3, 0
movw %ax, %ds
movw $4, 0
/* past this point, "0" means ds:0, i.e. cs:0, or the
* segment part of the address.
*/
data32 lgdt gdtaddr - _secondary_start
// data32 lgdt %cs:gdtptr
movw $5, 0
movl %cr0, %eax
movw $6, 0
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
movw $7, 0
orl $0x60000001, %eax /* CD, NW, PE = 1 */
movw $8, 0
movl %eax, %cr0
movw $9, 0
hlt
/* tested to this point but not past it */
/* I am pretty sure this just jumps back into
* ROM; it's an abs jump
*/
data32 ljmp $0x10, $secondary32
movw $0xa, 0
1:
.code32
secondary32:
hlt
movw $0x18, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
/* Load the Interrupt descriptor table */
lidt idtarg
/* Set the stack pointer */
movl -4(%ebx),%esp
movl $0, -4(%ebx)
call secondary_cpu_init
1: hlt
jmp 1b
.align 4
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:
gdtaddr:
.word gdt_limit /* the table limit */
.long gdt /* we know the offset */
idtarg:
.word _idt_end - _idt - 1 /* limit */
.long _idt
.word 0
_idt:
.fill 20, 8, 0 # idt is unitiailzed
_idt_end:
_secondary_start_end:
.code32
|