qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pvh.S (4326B)


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