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
|
/*
* vmxloader.c: ROM/VMXAssist image loader.
*
* A quicky so that we can boot rom images as if they were a Linux kernel.
* This code will copy the rom images (ROMBIOS/VGABIOS/VM86) into their
* respective spaces and transfer control to VM86 to execute the BIOSes.
*
* 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 "machine.h"
#include "roms.h"
#ifdef _ACPI_
#include "acpi.h"
#include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS
#endif
/*
* C runtime start off
*/
asm(" \n\
.text \n\
.globl _start \n\
_start: \n\
cli \n\
movl $stack_top, %esp \n\
movl %esp, %ebp \n\
call main \n\
jmp halt \n\
\n\
.globl halt \n\
halt: \n\
sti \n\
jmp . \n\
\n\
.bss \n\
.align 8 \n\
.globl stack, stack_top \n\
stack: \n\
.skip 0x4000 \n\
stack_top: \n\
");
void *
memcpy(void *dest, const void *src, unsigned n)
{
int t0, t1, t2;
__asm__ __volatile__(
"cld\n"
"rep; movsl\n"
"testb $2,%b4\n"
"je 1f\n"
"movsw\n"
"1: testb $1,%b4\n"
"je 2f\n"
"movsb\n"
"2:"
: "=&c" (t0), "=&D" (t1), "=&S" (t2)
: "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
: "memory"
);
return dest;
}
int
puts(const char *s)
{
while (*s)
outb(0xE9, *s++);
return 0;
}
int
cirrus_check(void)
{
outw(0x3C4, 0x9206);
return inb(0x3C5) == 0x12;
}
int
main()
{
puts("VMXAssist Loader\n");
puts("Loading ROMBIOS ...\n");
memcpy((void *)0xF0000, rombios, sizeof(rombios));
if (cirrus_check()) {
puts("Loading Cirrus VGABIOS ...\n");
memcpy((void *)0xC0000,
vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
} else {
puts("Loading Standard VGABIOS ...\n");
memcpy((void *)0xC0000,
vgabios_stdvga, sizeof(vgabios_stdvga));
}
#ifdef _ACPI_
puts("Loading ACPI ...\n");
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000 ){
/* make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
*/
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
}
#endif
puts("Loading VMXAssist ...\n");
memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
puts("Go ...\n");
((void (*)())TEXTADDR)();
}
|