 2cc06a8843
			
		
	
	
		2cc06a8843
		
	
	
	
	
		
			
			Return a static signature ("QEMU CFG") if the guest does a read to the
DMA address io register.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
		
	
			
		
			
				
	
	
		
			313 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 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().
 |