aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware/vmxassist/vmxloader.c
blob: 85ea0640568359bd155acbb8a33defa1f55e2cce (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
/*
 * 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)();
}