xref: /openbmc/qemu/pc-bios/optionrom/pvh.S (revision 3e29da9fd81002a0c03041aaa26dea6d9dd9bd65)
1*2785dc7bSStefano Garzarella/*
2*2785dc7bSStefano Garzarella * PVH Option ROM
3*2785dc7bSStefano Garzarella *
4*2785dc7bSStefano Garzarella * This program is free software; you can redistribute it and/or modify
5*2785dc7bSStefano Garzarella * it under the terms of the GNU General Public License as published by
6*2785dc7bSStefano Garzarella * the Free Software Foundation; either version 2 of the License, or
7*2785dc7bSStefano Garzarella * (at your option) any later version.
8*2785dc7bSStefano Garzarella *
9*2785dc7bSStefano Garzarella * This program is distributed in the hope that it will be useful,
10*2785dc7bSStefano Garzarella * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*2785dc7bSStefano Garzarella * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*2785dc7bSStefano Garzarella * GNU General Public License for more details.
13*2785dc7bSStefano Garzarella *
14*2785dc7bSStefano Garzarella * You should have received a copy of the GNU General Public License
15*2785dc7bSStefano Garzarella * along with this program; if not, see <http://www.gnu.org/licenses/>.
16*2785dc7bSStefano Garzarella *
17*2785dc7bSStefano Garzarella * Copyright Novell Inc, 2009
18*2785dc7bSStefano Garzarella *   Authors: Alexander Graf <agraf@suse.de>
19*2785dc7bSStefano Garzarella *
20*2785dc7bSStefano Garzarella * Copyright (c) 2019 Red Hat Inc.
21*2785dc7bSStefano Garzarella *   Authors: Stefano Garzarella <sgarzare@redhat.com>
22*2785dc7bSStefano Garzarella */
23*2785dc7bSStefano Garzarella
24*2785dc7bSStefano Garzarella#include "optionrom.h"
25*2785dc7bSStefano Garzarella
26*2785dc7bSStefano Garzarella#define BOOT_ROM_PRODUCT "PVH loader"
27*2785dc7bSStefano Garzarella
28*2785dc7bSStefano Garzarella#define GS_PROT_JUMP		0
29*2785dc7bSStefano Garzarella#define GS_GDT_DESC		6
30*2785dc7bSStefano Garzarella
31*2785dc7bSStefano Garzarella#ifdef OPTION_ROM_START
32*2785dc7bSStefano Garzarella#undef OPTION_ROM_START
33*2785dc7bSStefano Garzarella#endif
34*2785dc7bSStefano Garzarella#ifdef OPTION_ROM_END
35*2785dc7bSStefano Garzarella#undef OPTION_ROM_END
36*2785dc7bSStefano Garzarella#endif
37*2785dc7bSStefano Garzarella
38*2785dc7bSStefano Garzarella/*
39*2785dc7bSStefano Garzarella * Redefine OPTION_ROM_START and OPTION_ROM_END, because this rom is produced
40*2785dc7bSStefano Garzarella * linking multiple objects.
41*2785dc7bSStefano Garzarella * signrom.py will add padding.
42*2785dc7bSStefano Garzarella */
43*2785dc7bSStefano Garzarella#define OPTION_ROM_START                                \
44*2785dc7bSStefano Garzarella    .code16;						\
45*2785dc7bSStefano Garzarella    .text;						\
46*2785dc7bSStefano Garzarella	.global 	_start;				\
47*2785dc7bSStefano Garzarella    _start:;						\
48*2785dc7bSStefano Garzarella	.short		0xaa55;				\
49*2785dc7bSStefano Garzarella	.byte		3; /* desired size in 512 units */
50*2785dc7bSStefano Garzarella
51*2785dc7bSStefano Garzarella#define OPTION_ROM_END					\
52*2785dc7bSStefano Garzarella    _end:
53*2785dc7bSStefano Garzarella
54*2785dc7bSStefano GarzarellaBOOT_ROM_START
55*2785dc7bSStefano Garzarella
56*2785dc7bSStefano Garzarellarun_pvhboot:
57*2785dc7bSStefano Garzarella
58*2785dc7bSStefano Garzarella	cli
59*2785dc7bSStefano Garzarella	cld
60*2785dc7bSStefano Garzarella
61*2785dc7bSStefano Garzarella	mov		%cs, %eax
62*2785dc7bSStefano Garzarella	shl		$0x4, %eax
63*2785dc7bSStefano Garzarella
64*2785dc7bSStefano Garzarella	/* set up a long jump descriptor that is PC relative */
65*2785dc7bSStefano Garzarella
66*2785dc7bSStefano Garzarella	/* move stack memory to %gs */
67*2785dc7bSStefano Garzarella	mov		%ss, %ecx
68*2785dc7bSStefano Garzarella	shl		$0x4, %ecx
69*2785dc7bSStefano Garzarella	mov		%esp, %ebx
70*2785dc7bSStefano Garzarella	add		%ebx, %ecx
71*2785dc7bSStefano Garzarella	sub		$0x20, %ecx
72*2785dc7bSStefano Garzarella	sub		$0x30, %esp
73*2785dc7bSStefano Garzarella	shr		$0x4, %ecx
74*2785dc7bSStefano Garzarella	mov		%cx, %gs
75*2785dc7bSStefano Garzarella
76*2785dc7bSStefano Garzarella	/* now push the indirect jump descriptor there */
77*2785dc7bSStefano Garzarella	mov		(prot_jump), %ebx
78*2785dc7bSStefano Garzarella	add		%eax, %ebx
79*2785dc7bSStefano Garzarella	movl		%ebx, %gs:GS_PROT_JUMP
80*2785dc7bSStefano Garzarella	mov		$8, %bx
81*2785dc7bSStefano Garzarella	movw		%bx, %gs:GS_PROT_JUMP + 4
82*2785dc7bSStefano Garzarella
83*2785dc7bSStefano Garzarella	/* fix the gdt descriptor to be PC relative */
84*2785dc7bSStefano Garzarella	movw		(gdt_desc), %bx
85*2785dc7bSStefano Garzarella	movw		%bx, %gs:GS_GDT_DESC
86*2785dc7bSStefano Garzarella	movl		(gdt_desc+2), %ebx
87*2785dc7bSStefano Garzarella	add		%eax, %ebx
88*2785dc7bSStefano Garzarella	movl		%ebx, %gs:GS_GDT_DESC + 2
89*2785dc7bSStefano Garzarella
90*2785dc7bSStefano Garzarella	/* initialize HVM memmap table using int 0x15(e820) */
91*2785dc7bSStefano Garzarella
92*2785dc7bSStefano Garzarella	/* ES = pvh_e820 struct */
93*2785dc7bSStefano Garzarella	mov 		$pvh_e820, %eax
94*2785dc7bSStefano Garzarella	shr		$4, %eax
95*2785dc7bSStefano Garzarella	mov		%ax, %es
96*2785dc7bSStefano Garzarella
97*2785dc7bSStefano Garzarella	/* start storing memmap table at %es:8 (pvh_e820.table) */
98*2785dc7bSStefano Garzarella	mov 		$8,%edi
99*2785dc7bSStefano Garzarella	xor		%ebx, %ebx
100*2785dc7bSStefano Garzarella	jmp 		memmap_loop
101*2785dc7bSStefano Garzarella
102*2785dc7bSStefano Garzarellamemmap_loop_check:
103*2785dc7bSStefano Garzarella	/* pvh_e820 can contains up to 128 entries */
104*2785dc7bSStefano Garzarella	cmp 		$128, %ebx
105*2785dc7bSStefano Garzarella	je 		memmap_done
106*2785dc7bSStefano Garzarella
107*2785dc7bSStefano Garzarellamemmap_loop:
108*2785dc7bSStefano Garzarella	/* entry size (hvm_memmap_table_entry) & max buffer size (int15) */
109*2785dc7bSStefano Garzarella	movl		$24, %ecx
110*2785dc7bSStefano Garzarella	/* e820 */
111*2785dc7bSStefano Garzarella	movl		$0x0000e820, %eax
112*2785dc7bSStefano Garzarella	/* 'SMAP' magic */
113*2785dc7bSStefano Garzarella	movl		$0x534d4150, %edx
114*2785dc7bSStefano Garzarella	/* store counter value at %es:0 (pvh_e820.entries) */
115*2785dc7bSStefano Garzarella	movl 		%ebx, %es:0
116*2785dc7bSStefano Garzarella
117*2785dc7bSStefano Garzarella	int		$0x15
118*2785dc7bSStefano Garzarella	/* error or last entry already done? */
119*2785dc7bSStefano Garzarella	jb		memmap_err
120*2785dc7bSStefano Garzarella
121*2785dc7bSStefano Garzarella	/* %edi += entry size (hvm_memmap_table_entry) */
122*2785dc7bSStefano Garzarella	add		$24, %edi
123*2785dc7bSStefano Garzarella
124*2785dc7bSStefano Garzarella	/* continuation value 0 means last entry */
125*2785dc7bSStefano Garzarella	test		%ebx, %ebx
126*2785dc7bSStefano Garzarella	jnz		memmap_loop_check
127*2785dc7bSStefano Garzarella
128*2785dc7bSStefano Garzarella	/* increase pvh_e820.entries to save the last entry */
129*2785dc7bSStefano Garzarella	movl 		%es:0, %ebx
130*2785dc7bSStefano Garzarella	inc 		%ebx
131*2785dc7bSStefano Garzarella
132*2785dc7bSStefano Garzarellamemmap_done:
133*2785dc7bSStefano Garzarella	movl 		%ebx, %es:0
134*2785dc7bSStefano Garzarella
135*2785dc7bSStefano Garzarellamemmap_err:
136*2785dc7bSStefano Garzarella
137*2785dc7bSStefano Garzarella	/* load the GDT before going into protected mode */
138*2785dc7bSStefano Garzarellalgdt:
139*2785dc7bSStefano Garzarella	data32 lgdt	%gs:GS_GDT_DESC
140*2785dc7bSStefano Garzarella
141*2785dc7bSStefano Garzarella	/* get us to protected mode now */
142*2785dc7bSStefano Garzarella	movl		$1, %eax
143*2785dc7bSStefano Garzarella	movl		%eax, %cr0
144*2785dc7bSStefano Garzarella
145*2785dc7bSStefano Garzarella	/* the LJMP sets CS for us and gets us to 32-bit */
146*2785dc7bSStefano Garzarellaljmp:
147*2785dc7bSStefano Garzarella	data32 ljmp	*%gs:GS_PROT_JUMP
148*2785dc7bSStefano Garzarella
149*2785dc7bSStefano Garzarellaprot_mode:
150*2785dc7bSStefano Garzarella.code32
151*2785dc7bSStefano Garzarella
152*2785dc7bSStefano Garzarella	/* initialize all other segments */
153*2785dc7bSStefano Garzarella	movl		$0x10, %eax
154*2785dc7bSStefano Garzarella	movl		%eax, %ss
155*2785dc7bSStefano Garzarella	movl		%eax, %ds
156*2785dc7bSStefano Garzarella	movl		%eax, %es
157*2785dc7bSStefano Garzarella	movl		%eax, %fs
158*2785dc7bSStefano Garzarella	movl		%eax, %gs
159*2785dc7bSStefano Garzarella
160*2785dc7bSStefano Garzarella	jmp pvh_load_kernel
161*2785dc7bSStefano Garzarella
162*2785dc7bSStefano Garzarella/* Variables */
163*2785dc7bSStefano Garzarella.align 4, 0
164*2785dc7bSStefano Garzarellaprot_jump:	.long prot_mode
165*2785dc7bSStefano Garzarella		.short 8
166*2785dc7bSStefano Garzarella
167*2785dc7bSStefano Garzarella.align 4, 0
168*2785dc7bSStefano Garzarellagdt:
169*2785dc7bSStefano Garzarella	/* 0x00 */
170*2785dc7bSStefano Garzarella.byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
171*2785dc7bSStefano Garzarella
172*2785dc7bSStefano Garzarella	/*
173*2785dc7bSStefano Garzarella	 * 0x08: code segment
174*2785dc7bSStefano Garzarella	 * (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k)
175*2785dc7bSStefano Garzarella	 */
176*2785dc7bSStefano Garzarella.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
177*2785dc7bSStefano Garzarella
178*2785dc7bSStefano Garzarella	/*
179*2785dc7bSStefano Garzarella	 * 0x10: data segment
180*2785dc7bSStefano Garzarella	 * (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k)
181*2785dc7bSStefano Garzarella	 */
182*2785dc7bSStefano Garzarella.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
183*2785dc7bSStefano Garzarella
184*2785dc7bSStefano Garzarella	/*
185*2785dc7bSStefano Garzarella	 * 0x18: code segment
186*2785dc7bSStefano Garzarella	 * (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b)
187*2785dc7bSStefano Garzarella	 */
188*2785dc7bSStefano Garzarella.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
189*2785dc7bSStefano Garzarella
190*2785dc7bSStefano Garzarella	/*
191*2785dc7bSStefano Garzarella	 * 0x20: data segment
192*2785dc7bSStefano Garzarella	 * (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b)
193*2785dc7bSStefano Garzarella	 */
194*2785dc7bSStefano Garzarella.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
195*2785dc7bSStefano Garzarella
196*2785dc7bSStefano Garzarellagdt_desc:
197*2785dc7bSStefano Garzarella.short	(5 * 8) - 1
198*2785dc7bSStefano Garzarella.long	gdt
199*2785dc7bSStefano Garzarella
200*2785dc7bSStefano GarzarellaBOOT_ROM_END
201