1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
47
48#define BIOS_CFG_DMA_ADDR_HIGH 0x514
49#define BIOS_CFG_DMA_ADDR_LOW 0x518
50
51
52#define DEBUG_HERE \
53 jmp 1f; \
54 1:
55
56
57
58
59
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
79
80
81.macro read_fw_dma VAR, SIZE, ADDR
82
83 bswapl \ADDR
84 pushl \ADDR
85
86
87 xorl %eax, %eax
88 pushl %eax
89 mov $BIOS_CFG_DMA_ADDR_HIGH, %dx
90 outl %eax, (%dx)
91
92
93 bswapl \SIZE
94 pushl \SIZE
95
96
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
102 bswapl %eax
103 mov $BIOS_CFG_DMA_ADDR_LOW, %dx
104 outl %eax, (%dx)
105
1061: mov (%esp), %eax
107 bswapl %eax
108 testl $~FW_CFG_DMA_CTL_ERROR, %eax
109 jnz 1b
110 addl $16, %esp
111.endm
112
113
114
115
116
117
118
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
142
143
144
145
146#define read_fw_blob(var) \
147 read_fw var ## _ADDR; \
148 mov %eax, %edi; \
149 read_fw_blob_pre(var); \
150
151
152 \
153 .dc.b 0xf3,0x6c
154
155
156
157
158
159
160
161#define read_fw_blob_addr32(var) \
162 read_fw var ## _ADDR; \
163 mov %eax, %edi; \
164 read_fw_blob_pre(var); \
165
166
167 \
168 .dc.b 0x67,0xf3,0x6c
169
170
171
172
173
174
175
176#define read_fw_blob_addr32_edi(var) \
177 read_fw_blob_pre(var); \
178
179
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 \
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