summaryrefslogtreecommitdiffstats
path: root/docs/specs/fw_cfg.txt
blob: b8c794f54665be9cfa4f0bbd5fb854220b1a2059 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
QEMU Firmware Configuration (fw_cfg) Device
===========================================

= Guest-side Hardware Interface =

This hardware interface allows the guest to retrieve various data items
(blobs) that can influence how the firmware configures itself, or may
contain tables to be installed for the guest OS. Examples include device
boot order, ACPI and SMBIOS tables, virtual machine UUID, SMP and NUMA
information, kernel/initrd images for direct (Linux) kernel booting, etc.

== Selector (Control) Register ==

* Write only
* Location: platform dependent (IOport or MMIO)
* Width: 16-bit
* Endianness: little-endian (if IOport), or big-endian (if MMIO)

A write to this register sets the index of a firmware configuration
item which can subsequently be accessed via the data register.

Setting the selector register will cause the data offset to be set
to zero. The data offset impacts which data is accessed via the data
register, and is explained below.

Bit14 of the selector register indicates whether the configuration
setting is being written. A value of 0 means the item is only being
read, and all write access to the data port will be ignored. A value
of 1 means the item's data can be overwritten by writes to the data
register. In other words, configuration write mode is enabled when
the selector value is between 0x4000-0x7fff or 0xc000-0xffff.

NOTE: As of QEMU v2.4, writes to the fw_cfg data register are no
      longer supported, and will be ignored (treated as no-ops)!

Bit15 of the selector register indicates whether the configuration
setting is architecture specific. A value of 0 means the item is a
generic configuration item. A value of 1 means the item is specific
to a particular architecture. In other words, generic configuration
items are accessed with a selector value between 0x0000-0x7fff, and
architecture specific configuration items are accessed with a selector
value between 0x8000-0xffff.

== Data Register ==

* Read/Write (writes ignored as of QEMU v2.4)
* Location: platform dependent (IOport [*] or MMIO)
* Width: 8-bit (if IOport), 8/16/32/64-bit (if MMIO)
* Endianness: string-preserving

[*] On platforms where the data register is exposed as an IOport, its
port number will always be one greater than the port number of the
selector register. In other words, the two ports overlap, and can not
be mapped separately.

The data register allows access to an array of bytes for each firmware
configuration data item. The specific item is selected by writing to
the selector register, as described above.

Initially following a write to the selector register, the data offset
will be set to zero. Each successful access to the data register will
increment the data offset by the appropriate access width.

Each firmware configuration item has a maximum length of data
associated with the item. After the data offset has passed the
end of this maximum data length, then any reads will return a data
value of 0x00, and all writes will be ignored.

An N-byte wide read of the data register will return the next available
N bytes of the selected firmware configuration item, as a substring, in
increasing address order, similar to memcpy().

== Register Locations ==

=== x86, x86_64 Register Locations ===

Selector Register IOport: 0x510
Data Register IOport:     0x511
DMA Address IOport:       0x514

=== ARM Register Locations ===

Selector Register address: Base + 8 (2 bytes)
Data Register address:     Base + 0 (8 bytes)
DMA Address address:       Base + 16 (8 bytes)

== Firmware Configuration Items ==

=== Signature (Key 0x0000, FW_CFG_SIGNATURE) ===

The presence of the fw_cfg selector and data registers can be verified
by selecting the "signature" item using key 0x0000 (FW_CFG_SIGNATURE),
and reading four bytes from the data register. If the fw_cfg device is
present, the four bytes read will contain the characters "QEMU".

If the DMA interface is available, then reading the DMA Address
Register returns 0x51454d5520434647 ("QEMU CFG" in big-endian format).

=== Revision / feature bitmap (Key 0x0001, FW_CFG_ID) ===

A 32-bit little-endian unsigned int, this item is used to check for enabled
features.
 - Bit 0: traditional interface. Always set.
 - Bit 1: DMA interface.

=== File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===

Firmware configuration items stored at selector keys 0x0020 or higher
(FW_CFG_FILE_FIRST or higher) have an associated entry in a directory
structure, which makes it easier for guest-side firmware to identify
and retrieve them. The format of this file directory (from fw_cfg.h in
the QEMU source tree) is shown here, slightly annotated for clarity:

struct FWCfgFiles {		/* the entire file directory fw_cfg item */
    uint32_t count;		/* number of entries, in big-endian format */
    struct FWCfgFile f[];	/* array of file entries, see below */
};

struct FWCfgFile {		/* an individual file entry, 64 bytes total */
    uint32_t size;		/* size of referenced fw_cfg item, big-endian */
    uint16_t select;		/* selector key of fw_cfg item, big-endian */
    uint16_t reserved;
    char name[56];		/* fw_cfg item name, NUL-terminated ascii */
};

=== All Other Data Items ===

Please consult the QEMU source for the most up-to-date and authoritative
list of selector keys and their respective items' purpose and format.

=== Ranges ===

Theoretically, there may be up to 0x4000 generic firmware configuration
items, and up to 0x4000 architecturally specific ones.

Selector Reg.    Range Usage
---------------  -----------
0x0000 - 0x3fff  Generic (0x0000 - 0x3fff, RO)
0x4000 - 0x7fff  Generic (0x0000 - 0x3fff, RW, ignored in QEMU v2.4+)
0x8000 - 0xbfff  Arch. Specific (0x0000 - 0x3fff, RO)
0xc000 - 0xffff  Arch. Specific (0x0000 - 0x3fff, RW, ignored in v2.4+)

In practice, the number of allowed firmware configuration items is given
by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).

= Guest-side DMA Interface =

If bit 1 of the feature bitmap is set, the DMA interface is present. This does
not replace the existing fw_cfg interface, it is an add-on. This interface
can be used through the 64-bit wide address register.

The address register is in big-endian format. The value for the register is 0
at startup and after an operation. A write to the least significant half (at
offset 4) triggers an operation. This means that operations with 32-bit
addresses can be triggered with just one write, whereas operations with
64-bit addresses can be triggered with one 64-bit write or two 32-bit writes,
starting with the most significant half (at offset 0).

In this register, the physical address of a FWCfgDmaAccess structure in RAM
should be written. This is the format of the FWCfgDmaAccess structure:

typedef struct FWCfgDmaAccess {
    uint32_t control;
    uint32_t length;
    uint64_t address;
} FWCfgDmaAccess;

The fields of the structure are in big endian mode, and the field at the lowest
address is the "control" field.

The "control" field has the following bits:
 - Bit 0: Error
 - Bit 1: Read
 - Bit 2: Skip
 - Bit 3: Select. The upper 16 bits are the selected index.

When an operation is triggered, if the "control" field has bit 3 set, the
upper 16 bits are interpreted as an index of a firmware configuration item.
This has the same effect as writing the selector register.

If the "control" field has bit 1 set, a read operation will be performed.
"length" bytes for the current selector and offset will be copied into the
physical RAM address specified by the "address" field.

If the "control" field has bit 2 set (and not bit 1), a skip operation will be
performed. The offset for the current selector will be advanced "length" bytes.

To check the result, read the "control" field:
   error bit set        ->  something went wrong.
   all bits cleared     ->  transfer finished successfully.
   otherwise            ->  transfer still in progress (doesn't happen
                            today due to implementation not being async,
                            but may in the future).

= Host-side API =

The following functions are available to the QEMU programmer for adding
data to a fw_cfg device during guest initialization (see fw_cfg.h for
each function's complete prototype):

== fw_cfg_add_bytes() ==

Given a selector key value, starting pointer, and size, create an item
as a raw "blob" of the given size, available by selecting the given key.
The data referenced by the starting pointer is only linked, NOT copied,
into the data structure of the fw_cfg device.

== fw_cfg_add_string() ==

Instead of a starting pointer and size, this function accepts a pointer
to a NUL-terminated ascii string, and inserts a newly allocated copy of
the string (including the NUL terminator) into the fw_cfg device data
structure.

== fw_cfg_add_iXX() ==

Insert an XX-bit item, where XX may be 16, 32, or 64. These functions
will convert a 16-, 32-, or 64-bit integer to little-endian, then add
a dynamically allocated copy of the appropriately sized item to fw_cfg
under the given selector key value.

== fw_cfg_modify_iXX() ==

Modify the value of an XX-bit item (where XX may be 16, 32, or 64).
Similarly to the corresponding fw_cfg_add_iXX() function set, convert
a 16-, 32-, or 64-bit integer to little endian, create a dynamically
allocated copy of the required size, and replace the existing item at
the given selector key value with the newly allocated one. The previous
item, assumed to have been allocated during an earlier call to
fw_cfg_add_iXX() or fw_cfg_modify_iXX() (of the same width XX), is freed
before the function returns.

== fw_cfg_add_file() ==

Given a filename (i.e., fw_cfg item name), starting pointer, and size,
create an item as a raw "blob" of the given size. Unlike fw_cfg_add_bytes()
above, the next available selector key (above 0x0020, FW_CFG_FILE_FIRST)
will be used, and a new entry will be added to the file directory structure
(at key 0x0019), containing the item name, blob size, and automatically
assigned selector key value. The data referenced by the starting pointer
is only linked, NOT copied, into the fw_cfg data structure.

== fw_cfg_add_file_callback() ==

Like fw_cfg_add_file(), but additionally sets pointers to a callback
function (and opaque argument), which will be executed host-side by
QEMU each time a byte is read by the guest from this particular item.

NOTE: The callback function is given the opaque argument set by
fw_cfg_add_file_callback(), but also the current data offset,
allowing it the option of only acting upon specific offset values
(e.g., 0, before the first data byte of the selected item is
returned to the guest).

== fw_cfg_modify_file() ==

Given a filename (i.e., fw_cfg item name), starting pointer, and size,
completely replace the configuration item referenced by the given item
name with the new given blob. If an existing blob is found, its
callback information is removed, and a pointer to the old data is
returned to allow the caller to free it, helping avoid memory leaks.
If a configuration item does not already exist under the given item
name, a new item will be created as with fw_cfg_add_file(), and NULL
is returned to the caller. In any case, the data referenced by the
starting pointer is only linked, NOT copied, into the fw_cfg data
structure.

== fw_cfg_add_callback() ==

Like fw_cfg_add_bytes(), but additionally sets pointers to a callback
function (and opaque argument), which will be executed host-side by
QEMU each time a guest-side write operation to this particular item
completes fully overwriting the item's data.

NOTE: This function is deprecated, and will be completely removed
starting with QEMU v2.4.

== Externally Provided Items ==

As of v2.4, "file" fw_cfg items (i.e., items with selector keys above
FW_CFG_FILE_FIRST, and with a corresponding entry in the fw_cfg file
directory structure) may be inserted via the QEMU command line, using
the following syntax:

    -fw_cfg [name=]<item_name>,file=<path>

where <item_name> is the fw_cfg item name, and <path> is the location
on the host file system of a file containing the data to be inserted.

Small enough items may be provided directly as strings on the command
line, using the syntax:

    -fw_cfg [name=]<item_name>,string=<string>

The terminating NUL character of the content <string> will NOT be
included as part of the fw_cfg item data, which is consistent with
the absence of a NUL terminator for items inserted via the file option.

Both <item_name> and, if applicable, the content <string> are passed
through by QEMU without any interpretation, expansion, or further
processing. Any such processing (potentially performed e.g., by the shell)
is outside of QEMU's responsibility; as such, using plain ASCII characters
is recommended.

NOTE: Users *SHOULD* choose item names beginning with the prefix "opt/"
when using the "-fw_cfg" command line option, to avoid conflicting with
item names used internally by QEMU. For instance:

    -fw_cfg name=opt/my_item_name,file=./my_blob.bin

Similarly, QEMU developers *SHOULD NOT* use item names prefixed with
"opt/" when inserting items programmatically, e.g. via fw_cfg_add_file().
OpenPOWER on IntegriCloud