xref: /openbmc/qemu/pc-bios/optionrom/optionrom.h (revision 4921d0a7)
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