xref: /qemu/pc-bios/optionrom/optionrom.h (revision 727385c4)
1 /*
2  * Common Option ROM Functions
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 
21 
22 #define FW_CFG_KERNEL_ADDR      0x07
23 #define FW_CFG_KERNEL_SIZE      0x08
24 #define FW_CFG_KERNEL_CMDLINE   0x09
25 #define FW_CFG_INITRD_ADDR      0x0a
26 #define FW_CFG_INITRD_SIZE      0x0b
27 #define FW_CFG_KERNEL_ENTRY     0x10
28 #define FW_CFG_KERNEL_DATA      0x11
29 #define FW_CFG_INITRD_DATA      0x12
30 #define FW_CFG_CMDLINE_ADDR     0x13
31 #define FW_CFG_CMDLINE_SIZE     0x14
32 #define FW_CFG_CMDLINE_DATA     0x15
33 #define FW_CFG_SETUP_ADDR       0x16
34 #define FW_CFG_SETUP_SIZE       0x17
35 #define FW_CFG_SETUP_DATA       0x18
36 
37 #define BIOS_CFG_IOPORT_CFG	0x510
38 #define BIOS_CFG_IOPORT_DATA	0x511
39 
40 #define FW_CFG_DMA_CTL_ERROR   0x01
41 #define FW_CFG_DMA_CTL_READ    0x02
42 #define FW_CFG_DMA_CTL_SKIP    0x04
43 #define FW_CFG_DMA_CTL_SELECT  0x08
44 #define FW_CFG_DMA_CTL_WRITE   0x10
45 
46 #define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
47 
48 #define BIOS_CFG_DMA_ADDR_HIGH  0x514
49 #define BIOS_CFG_DMA_ADDR_LOW   0x518
50 
51 /* Break the translation block flow so -d cpu shows us values */
52 #define DEBUG_HERE \
53 	jmp		1f;				\
54 	1:
55 
56 /*
57  * Read a variable from the fw_cfg device.
58  * Clobbers:	%edx
59  * Out:		%eax
60  */
61 .macro read_fw VAR
62 	mov		$\VAR, %ax
63 	mov		$BIOS_CFG_IOPORT_CFG, %dx
64 	outw		%ax, (%dx)
65 	mov		$BIOS_CFG_IOPORT_DATA, %dx
66 	inb		(%dx), %al
67 	shl		$8, %eax
68 	inb		(%dx), %al
69 	shl		$8, %eax
70 	inb		(%dx), %al
71 	shl		$8, %eax
72 	inb		(%dx), %al
73 	bswap		%eax
74 .endm
75 
76 
77 /*
78  * Read data from the fw_cfg device using DMA.
79  * Clobbers:	%edx, %eax, ADDR, SIZE, memory[%esp-16] to memory[%esp]
80  */
81 .macro read_fw_dma VAR, SIZE, ADDR
82         /* Address */
83 	bswapl		\ADDR
84 	pushl		\ADDR
85 
86 	/* We only support 32 bit target addresses */
87 	xorl		%eax, %eax
88 	pushl		%eax
89 	mov		$BIOS_CFG_DMA_ADDR_HIGH, %dx
90 	outl		%eax, (%dx)
91 
92 	/* Size */
93 	bswapl		\SIZE
94 	pushl		\SIZE
95 
96         /* Control */
97 	movl		$(\VAR << 16) | (FW_CFG_DMA_CTL_READ | FW_CFG_DMA_CTL_SELECT), %eax
98 	bswapl		%eax
99 	pushl		%eax
100 
101 	movl		%esp, %eax /* Address of the struct we generated */
102 	bswapl		%eax
103 	mov		$BIOS_CFG_DMA_ADDR_LOW, %dx
104 	outl		%eax, (%dx) /* Initiate DMA */
105 
106 1:  mov		(%esp), %eax /* Wait for completion */
107 	bswapl		%eax
108 	testl		$~FW_CFG_DMA_CTL_ERROR, %eax
109 	jnz		1b
110        addl            $16, %esp
111 .endm
112 
113 
114 /*
115  * Read a blob from the fw_cfg device using DMA
116  * Requires _ADDR, _SIZE and _DATA values for the parameter.
117  *
118  * Clobbers:	%eax, %edx, %es, %ecx, %edi and adresses %esp-20 to %esp
119  */
120 #ifdef USE_FW_CFG_DMA
121 #define read_fw_blob_dma(var) \
122 	read_fw		var ## _SIZE; \
123 	mov		%eax, %ecx; \
124 	read_fw		var ## _ADDR; \
125 	mov		%eax, %edi ;\
126 	read_fw_dma	var ## _DATA, %ecx, %edi
127 #else
128 #define read_fw_blob_dma(var) read_fw_blob(var)
129 #endif
130 
131 #define read_fw_blob_pre(var)				\
132 	read_fw		var ## _SIZE;			\
133 	mov		%eax, %ecx;			\
134 	mov		$var ## _DATA, %ax;		\
135 	mov		$BIOS_CFG_IOPORT_CFG, %edx;	\
136 	outw		%ax, (%dx);			\
137 	mov		$BIOS_CFG_IOPORT_DATA, %dx;	\
138 	cld
139 
140 /*
141  * Read a blob from the fw_cfg device.
142  * Requires _ADDR, _SIZE and _DATA values for the parameter.
143  *
144  * Clobbers:	%eax, %edx, %es, %ecx, %edi
145  */
146 #define read_fw_blob(var)				\
147 	read_fw		var ## _ADDR;			\
148 	mov		%eax, %edi;			\
149 	read_fw_blob_pre(var);				\
150 	/* old as(1) doesn't like this insn so emit the bytes instead: \
151 	rep insb	(%dx), %es:(%edi);		\
152 	*/						\
153 	.dc.b		0xf3,0x6c
154 
155 /*
156  * Read a blob from the fw_cfg device in forced addr32 mode.
157  * Requires _ADDR, _SIZE and _DATA values for the parameter.
158  *
159  * Clobbers:	%eax, %edx, %es, %ecx, %edi
160  */
161 #define read_fw_blob_addr32(var)			\
162 	read_fw		var ## _ADDR;			\
163 	mov		%eax, %edi;			\
164 	read_fw_blob_pre(var);				\
165 	/* old as(1) doesn't like this insn so emit the bytes instead: \
166 	addr32 rep insb	(%dx), %es:(%edi);		\
167 	*/						\
168 	.dc.b		0x67,0xf3,0x6c
169 
170 /*
171  * Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
172  * Requires _SIZE and _DATA values for the parameter.
173  *
174  * Clobbers:	%eax, %edx, %edi, %es, %ecx
175  */
176 #define read_fw_blob_addr32_edi(var)			\
177 	read_fw_blob_pre(var);				\
178 	/* old as(1) doesn't like this insn so emit the bytes instead: \
179 	addr32 rep insb	(%dx), %es:(%edi);		\
180 	*/						\
181 	.dc.b		0x67,0xf3,0x6c
182 
183 #define OPTION_ROM_START					\
184     .code16;						\
185     .text;						\
186 	.global 	_start;				\
187     _start:;						\
188 	.short		0xaa55;				\
189 	.byte		(_end - _start) / 512;
190 
191 #define BOOT_ROM_START					\
192 	OPTION_ROM_START				\
193 	lret;						\
194 	.org 		0x18;				\
195 	.short		0;				\
196 	.short		_pnph;				\
197     _pnph:						\
198 	.ascii		"$PnP";				\
199 	.byte		0x01;				\
200 	.byte		( _pnph_len / 16 );		\
201 	.short		0x0000;				\
202 	.byte		0x00;				\
203 	.byte		0x00;				\
204 	.long		0x00000000;			\
205 	.short		_manufacturer;			\
206 	.short		_product;			\
207 	.long		0x00000000;			\
208 	.short		0x0000;				\
209 	.short		0x0000;				\
210 	.short		_bev;				\
211 	.short		0x0000;				\
212 	.short		0x0000;				\
213 	.equ		_pnph_len, . - _pnph;		\
214     _bev:;						\
215 	/* DS = CS */					\
216 	movw		%cs, %ax;			\
217 	movw		%ax, %ds;
218 
219 #define OPTION_ROM_END					\
220 	.byte		0;				\
221 	.align		512, 0;				\
222     _end:
223 
224 #define BOOT_ROM_END					\
225     _manufacturer:;					\
226 	.asciz "QEMU";					\
227     _product:;						\
228 	.asciz BOOT_ROM_PRODUCT;			\
229 	OPTION_ROM_END
230 
231