aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware/vmxassist/head.S
blob: a4cb614c68bcd9f92032fb1a672b04967d8a82b2 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * head.S: VMXAssist runtime start off.
 *
 * Leendert van Doorn, leendert@watson.ibm.com
 * Copyright (c) 2005, International Business Machines Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 */
#include "vm86.h"
#include "machine.h"

/*
 * When a partition tries to mask off the CR0_PE bit a world
 * switch happens to the environment below. The magic indicates
 * that this is a valid context.
 */
#ifdef TEST
	.byte 0x55, 0xaa
	.byte 0x80
	.code16
	jmp	_start16
#else
	jmp	_start
#endif

	.align	8
	.long	VMXASSIST_MAGIC
	.long	newctx			/* new context */
	.long	oldctx			/* old context */

#ifdef TEST
/*
 * We are running in 16-bit. Get into the protected mode as soon as
 * possible. We use our own (minimal) GDT to get started.
 *
 * ROM is a misnomer as this code isn't really rommable (although it
 * only requires a few changes) but it does live in a BIOS ROM segment.
 * This code allows me to debug vmxassists under (a modified version of)
 * Bochs and load it as a "optromimage1".
 */
	.code16
	.globl	_start16
_start16:
        cli

        /* load our own global descriptor table */
        data32 addr32 lgdt %cs:(rom_gdtr - TEXTADDR)

        /* go to protected mode */
        movl    %cr0, %eax
        orl     $(CR0_PE), %eax
        movl    %eax, %cr0
        data32  ljmp $0x08, $1f

        .align  32
        .globl  rom_gdt
rom_gdt:
        .word   0, 0            /* 0x00: reserved */
        .byte   0, 0, 0, 0

        .word   0xFFFF, 0       /* 0x08: CS 32-bit */
        .byte   0, 0x9A, 0xCF, 0

        .word   0xFFFF, 0       /* 0x10: CS 32-bit */
        .byte   0, 0x92, 0xCF, 0
rom_gdt_end:

        .align  4
        .globl  rom_gdtr
rom_gdtr:
        .word   rom_gdt_end - rom_gdt - 1
        .long   rom_gdt

        .code32
1:
        /* welcome to the 32-bit world */
        movw    $0x10, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %ss
        movw    %ax, %fs
        movw    %ax, %gs

        /* enable Bochs debug facilities */
        movw    $0x8A00, %dx
        movw    $0x8A00, %ax
        outw    %ax, (%dx)

	jmp	_start
#endif /* TEST */

/*
 * This is the real start. Control was transfered to this point
 * with CR0_PE set and executing in some 32-bit segment. We call
 * main and setup our own environment.
 */
	.globl	_start
	.code32
_start:
	cli

	/* save register parameters to C land */
#ifdef TEST
	xorl	%edx, %edx
#endif

	/* clear bss */
	cld
	xorb	%al, %al
	movl	$_bbss, %edi
	movl	$_ebss, %ecx
	subl	%edi, %ecx
	rep	stosb

	movl	%edx, booting_cpu
	movl	%ebx, booting_vector

	/* make sure we are in a sane world */
	clts

	/* setup my own stack */
	movl	$stack_top - 4*4, %esp
	movl	%esp, %ebp

	/* go ... */
	call    main
	jmp	halt

/*
 * Something bad happened, print invoking %eip and loop forever
 */
	.align	4
	.globl	halt
halt:
	push	$halt_msg
	call	printf
#ifdef TEST
        movw    $0x8A00, %dx
        movw    $0x8AE0, %ax
        outw    %ax, (%dx)
#endif
	cli
	jmp	.

	.data
halt_msg:
	.asciz	"Halt called from %%eip 0x%x\n"


/*
 * Our stack
 */
	.bss
	.align	8
	.globl	stack, stack_top
stack:
	.skip	STACK_SIZE
stack_top: