mirror of https://github.com/xemu-project/xemu.git
usb: canokey fixes.
ui: better tab labels, cocoa fix, docs: convert fw_cfg to rst. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmLCndwACgkQTLbY7tPo cTjNHA/+MT56crVXnjMTdgBRLOuq0cxYnIUptN0JPKx9DTJzdlXEyT+zYD7iIzUt W0xbOrTLVzU9hfJVh9/5V2HuFmc1eAhfl0BDTzd1TT0kdH6LyUkz5RWgotzo3nvH 7tnl/sBy48a7diSyQn6K2s8r35ubrX1GNJiJcCLWdVEqvzKKWDEqebs02PxbN/OJ 9UG9xtkM/QQ1+h74jq5BGKXf08xOhOZIjO274Sn5zievBC9JU6RVkCOlUXiBdk51 +vNTfKt3c864cstryXSTknYWyVv7zKzCqr7xR7c+fgbt3cN/HmLkM9LGytDMEDl/ IC0CtKiRN316GgVHHMDT8v8X2dVHNH9ZEEoXRKIbc5jD/tetJw7IIEO7blJphdpV WE4/bRpJwYVW9UHzig9rPRxsHLs3NSZbNCQEbGUvAbZzS2kq9hnDa/BBtFSYaf+X RIwR7rY7WhENfSrus1jR5rfWRU7n+q+fcNIFZetUakH1V6Idb0xQir3eM/yM6sBC nzQSzzLsd3Mwh2ahbnLZ1HkyybZV692usVylKsFLVwcUhCvk+VHccOF31QfrxO/j ogVzTYYtfrGM5kaknueIMg7XAhjQ04Av70+0b886kZawB3ZE5Ccare2TztHq1jcG dMdEm7DLaDRm2RXa9NtcbxsIrS0DT2EuFcBnQ1mHMCGql4MidzE= =Bhbw -----END PGP SIGNATURE----- Merge tag 'kraxel-20220704-pull-request' of https://gitlab.com/kraxel/qemu into staging usb: canokey fixes. ui: better tab labels, cocoa fix, docs: convert fw_cfg to rst. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmLCndwACgkQTLbY7tPo # cTjNHA/+MT56crVXnjMTdgBRLOuq0cxYnIUptN0JPKx9DTJzdlXEyT+zYD7iIzUt # W0xbOrTLVzU9hfJVh9/5V2HuFmc1eAhfl0BDTzd1TT0kdH6LyUkz5RWgotzo3nvH # 7tnl/sBy48a7diSyQn6K2s8r35ubrX1GNJiJcCLWdVEqvzKKWDEqebs02PxbN/OJ # 9UG9xtkM/QQ1+h74jq5BGKXf08xOhOZIjO274Sn5zievBC9JU6RVkCOlUXiBdk51 # +vNTfKt3c864cstryXSTknYWyVv7zKzCqr7xR7c+fgbt3cN/HmLkM9LGytDMEDl/ # IC0CtKiRN316GgVHHMDT8v8X2dVHNH9ZEEoXRKIbc5jD/tetJw7IIEO7blJphdpV # WE4/bRpJwYVW9UHzig9rPRxsHLs3NSZbNCQEbGUvAbZzS2kq9hnDa/BBtFSYaf+X # RIwR7rY7WhENfSrus1jR5rfWRU7n+q+fcNIFZetUakH1V6Idb0xQir3eM/yM6sBC # nzQSzzLsd3Mwh2ahbnLZ1HkyybZV692usVylKsFLVwcUhCvk+VHccOF31QfrxO/j # ogVzTYYtfrGM5kaknueIMg7XAhjQ04Av70+0b886kZawB3ZE5Ccare2TztHq1jcG # dMdEm7DLaDRm2RXa9NtcbxsIrS0DT2EuFcBnQ1mHMCGql4MidzE= # =Bhbw # -----END PGP SIGNATURE----- # gpg: Signature made Mon 04 Jul 2022 01:29:24 PM +0530 # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [undefined] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [undefined] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * tag 'kraxel-20220704-pull-request' of https://gitlab.com/kraxel/qemu: hw: canokey: Remove HS support as not compliant to the spec docs/system/devices/usb/canokey: remove limitations on qemu-xhci hw/usb/canokey: fix compatibility of qemu-xhci hw/usb/canokey: Fix CCID ZLP ui/cocoa: Fix clipboard text release ui/console: allow display device to be labeled with given id Convert fw_cfg.rst to reStructuredText syntax Rename docs/specs/fw_cfg.txt to .rst Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
dfe2382f06
|
@ -1,7 +1,9 @@
|
||||||
|
===========================================
|
||||||
QEMU Firmware Configuration (fw_cfg) Device
|
QEMU Firmware Configuration (fw_cfg) Device
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
= Guest-side Hardware Interface =
|
Guest-side Hardware Interface
|
||||||
|
=============================
|
||||||
|
|
||||||
This hardware interface allows the guest to retrieve various data items
|
This hardware interface allows the guest to retrieve various data items
|
||||||
(blobs) that can influence how the firmware configures itself, or may
|
(blobs) that can influence how the firmware configures itself, or may
|
||||||
|
@ -9,7 +11,8 @@ contain tables to be installed for the guest OS. Examples include device
|
||||||
boot order, ACPI and SMBIOS tables, virtual machine UUID, SMP and NUMA
|
boot order, ACPI and SMBIOS tables, virtual machine UUID, SMP and NUMA
|
||||||
information, kernel/initrd images for direct (Linux) kernel booting, etc.
|
information, kernel/initrd images for direct (Linux) kernel booting, etc.
|
||||||
|
|
||||||
== Selector (Control) Register ==
|
Selector (Control) Register
|
||||||
|
---------------------------
|
||||||
|
|
||||||
* Write only
|
* Write only
|
||||||
* Location: platform dependent (IOport or MMIO)
|
* Location: platform dependent (IOport or MMIO)
|
||||||
|
@ -30,10 +33,12 @@ 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
|
register. In other words, configuration write mode is enabled when
|
||||||
the selector value is between 0x4000-0x7fff or 0xc000-0xffff.
|
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
|
.. 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)!
|
longer supported, and will be ignored (treated as no-ops)!
|
||||||
|
|
||||||
NOTE: As of QEMU v2.9, writes are reinstated, but only through the DMA
|
.. NOTE::
|
||||||
|
As of QEMU v2.9, writes are reinstated, but only through the DMA
|
||||||
interface (see below). Furthermore, writeability of any specific item is
|
interface (see below). Furthermore, writeability of any specific item is
|
||||||
governed independently of Bit14 in the selector key value.
|
governed independently of Bit14 in the selector key value.
|
||||||
|
|
||||||
|
@ -45,17 +50,19 @@ items are accessed with a selector value between 0x0000-0x7fff, and
|
||||||
architecture specific configuration items are accessed with a selector
|
architecture specific configuration items are accessed with a selector
|
||||||
value between 0x8000-0xffff.
|
value between 0x8000-0xffff.
|
||||||
|
|
||||||
== Data Register ==
|
Data Register
|
||||||
|
-------------
|
||||||
|
|
||||||
* Read/Write (writes ignored as of QEMU v2.4, but see the DMA interface)
|
* Read/Write (writes ignored as of QEMU v2.4, but see the DMA interface)
|
||||||
* Location: platform dependent (IOport [*] or MMIO)
|
* Location: platform dependent (IOport [#]_ or MMIO)
|
||||||
* Width: 8-bit (if IOport), 8/16/32/64-bit (if MMIO)
|
* Width: 8-bit (if IOport), 8/16/32/64-bit (if MMIO)
|
||||||
* Endianness: string-preserving
|
* 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
|
On platforms where the data register is exposed as an IOport, its
|
||||||
selector register. In other words, the two ports overlap, and can not
|
port number will always be one greater than the port number of the
|
||||||
be mapped separately.
|
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
|
The data register allows access to an array of bytes for each firmware
|
||||||
configuration data item. The specific item is selected by writing to
|
configuration data item. The specific item is selected by writing to
|
||||||
|
@ -74,91 +81,103 @@ 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
|
N bytes of the selected firmware configuration item, as a substring, in
|
||||||
increasing address order, similar to memcpy().
|
increasing address order, similar to memcpy().
|
||||||
|
|
||||||
== Register Locations ==
|
Register Locations
|
||||||
|
------------------
|
||||||
|
|
||||||
=== x86, x86_64 Register Locations ===
|
x86, x86_64
|
||||||
|
* Selector Register IOport: 0x510
|
||||||
|
* Data Register IOport: 0x511
|
||||||
|
* DMA Address IOport: 0x514
|
||||||
|
|
||||||
Selector Register IOport: 0x510
|
Arm
|
||||||
Data Register IOport: 0x511
|
* Selector Register address: Base + 8 (2 bytes)
|
||||||
DMA Address IOport: 0x514
|
* Data Register address: Base + 0 (8 bytes)
|
||||||
|
* DMA Address address: Base + 16 (8 bytes)
|
||||||
|
|
||||||
=== Arm Register Locations ===
|
ACPI Interface
|
||||||
|
--------------
|
||||||
|
|
||||||
Selector Register address: Base + 8 (2 bytes)
|
The fw_cfg device is defined with ACPI ID ``QEMU0002``. Since we expect
|
||||||
Data Register address: Base + 0 (8 bytes)
|
|
||||||
DMA Address address: Base + 16 (8 bytes)
|
|
||||||
|
|
||||||
== ACPI Interface ==
|
|
||||||
|
|
||||||
The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
|
|
||||||
ACPI tables to be passed into the guest through the fw_cfg device itself,
|
ACPI tables to be passed into the guest through the fw_cfg device itself,
|
||||||
the guest-side firmware can not use ACPI to find fw_cfg. However, once the
|
the guest-side firmware can not use ACPI to find fw_cfg. However, once the
|
||||||
firmware is finished setting up ACPI tables and hands control over to the
|
firmware is finished setting up ACPI tables and hands control over to the
|
||||||
guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
|
guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
|
||||||
inventory of in-use IOport or MMIO regions.
|
inventory of in-use IOport or MMIO regions.
|
||||||
|
|
||||||
== Firmware Configuration Items ==
|
Firmware Configuration Items
|
||||||
|
----------------------------
|
||||||
|
|
||||||
=== Signature (Key 0x0000, FW_CFG_SIGNATURE) ===
|
Signature (Key 0x0000, ``FW_CFG_SIGNATURE``)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The presence of the fw_cfg selector and data registers can be verified
|
The presence of the fw_cfg selector and data registers can be verified
|
||||||
by selecting the "signature" item using key 0x0000 (FW_CFG_SIGNATURE),
|
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
|
and reading four bytes from the data register. If the fw_cfg device is
|
||||||
present, the four bytes read will contain the characters "QEMU".
|
present, the four bytes read will contain the characters ``QEMU``.
|
||||||
|
|
||||||
If the DMA interface is available, then reading the DMA Address
|
If the DMA interface is available, then reading the DMA Address
|
||||||
Register returns 0x51454d5520434647 ("QEMU CFG" in big-endian format).
|
Register returns 0x51454d5520434647 (``QEMU CFG`` in big-endian format).
|
||||||
|
|
||||||
=== Revision / feature bitmap (Key 0x0001, FW_CFG_ID) ===
|
Revision / feature bitmap (Key 0x0001, ``FW_CFG_ID``)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A 32-bit little-endian unsigned int, this item is used to check for enabled
|
A 32-bit little-endian unsigned int, this item is used to check for enabled
|
||||||
features.
|
features.
|
||||||
- Bit 0: traditional interface. Always set.
|
|
||||||
- Bit 1: DMA interface.
|
|
||||||
|
|
||||||
=== File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===
|
- Bit 0: traditional interface. Always set.
|
||||||
|
- Bit 1: DMA interface.
|
||||||
|
|
||||||
|
File Directory (Key 0x0019, ``FW_CFG_FILE_DIR``)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. highlight:: c
|
||||||
|
|
||||||
Firmware configuration items stored at selector keys 0x0020 or higher
|
Firmware configuration items stored at selector keys 0x0020 or higher
|
||||||
(FW_CFG_FILE_FIRST or higher) have an associated entry in a directory
|
(``FW_CFG_FILE_FIRST`` or higher) have an associated entry in a directory
|
||||||
structure, which makes it easier for guest-side firmware to identify
|
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
|
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:
|
the QEMU source tree) is shown here, slightly annotated for clarity::
|
||||||
|
|
||||||
struct FWCfgFiles { /* the entire file directory fw_cfg item */
|
struct FWCfgFiles { /* the entire file directory fw_cfg item */
|
||||||
uint32_t count; /* number of entries, in big-endian format */
|
uint32_t count; /* number of entries, in big-endian format */
|
||||||
struct FWCfgFile f[]; /* array of file entries, see below */
|
struct FWCfgFile f[]; /* array of file entries, see below */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FWCfgFile { /* an individual file entry, 64 bytes total */
|
struct FWCfgFile { /* an individual file entry, 64 bytes total */
|
||||||
uint32_t size; /* size of referenced fw_cfg item, big-endian */
|
uint32_t size; /* size of referenced fw_cfg item, big-endian */
|
||||||
uint16_t select; /* selector key of fw_cfg item, big-endian */
|
uint16_t select; /* selector key of fw_cfg item, big-endian */
|
||||||
uint16_t reserved;
|
uint16_t reserved;
|
||||||
char name[56]; /* fw_cfg item name, NUL-terminated ascii */
|
char name[56]; /* fw_cfg item name, NUL-terminated ascii */
|
||||||
};
|
};
|
||||||
|
|
||||||
=== All Other Data Items ===
|
All Other Data Items
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Please consult the QEMU source for the most up-to-date and authoritative list
|
Please consult the QEMU source for the most up-to-date and authoritative list
|
||||||
of selector keys and their respective items' purpose, format and writeability.
|
of selector keys and their respective items' purpose, format and writeability.
|
||||||
|
|
||||||
=== Ranges ===
|
Ranges
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
Theoretically, there may be up to 0x4000 generic firmware configuration
|
Theoretically, there may be up to 0x4000 generic firmware configuration
|
||||||
items, and up to 0x4000 architecturally specific ones.
|
items, and up to 0x4000 architecturally specific ones.
|
||||||
|
|
||||||
|
=============== ===========
|
||||||
Selector Reg. Range Usage
|
Selector Reg. Range Usage
|
||||||
--------------- -----------
|
=============== ===========
|
||||||
0x0000 - 0x3fff Generic (0x0000 - 0x3fff, generally RO, possibly RW through
|
0x0000 - 0x3fff Generic (0x0000 - 0x3fff, generally RO, possibly RW through
|
||||||
the DMA interface in QEMU v2.9+)
|
the DMA interface in QEMU v2.9+)
|
||||||
0x4000 - 0x7fff Generic (0x0000 - 0x3fff, RW, ignored in QEMU v2.4+)
|
0x4000 - 0x7fff Generic (0x0000 - 0x3fff, RW, ignored in QEMU v2.4+)
|
||||||
0x8000 - 0xbfff Arch. Specific (0x0000 - 0x3fff, generally RO, possibly RW
|
0x8000 - 0xbfff Arch. Specific (0x0000 - 0x3fff, generally RO, possibly RW
|
||||||
through the DMA interface in QEMU v2.9+)
|
through the DMA interface in QEMU v2.9+)
|
||||||
0xc000 - 0xffff Arch. Specific (0x0000 - 0x3fff, RW, ignored in v2.4+)
|
0xc000 - 0xffff Arch. Specific (0x0000 - 0x3fff, RW, ignored in v2.4+)
|
||||||
|
=============== ===========
|
||||||
|
|
||||||
In practice, the number of allowed firmware configuration items depends on the
|
In practice, the number of allowed firmware configuration items depends on the
|
||||||
machine type/version.
|
machine type/version.
|
||||||
|
|
||||||
= Guest-side DMA Interface =
|
Guest-side DMA Interface
|
||||||
|
========================
|
||||||
|
|
||||||
If bit 1 of the feature bitmap is set, the DMA interface is present. This does
|
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
|
not replace the existing fw_cfg interface, it is an add-on. This interface
|
||||||
|
@ -171,68 +190,74 @@ 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,
|
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).
|
starting with the most significant half (at offset 0).
|
||||||
|
|
||||||
In this register, the physical address of a FWCfgDmaAccess structure in RAM
|
In this register, the physical address of a ``FWCfgDmaAccess`` structure in RAM
|
||||||
should be written. This is the format of the FWCfgDmaAccess structure:
|
should be written. This is the format of the ``FWCfgDmaAccess`` structure::
|
||||||
|
|
||||||
typedef struct FWCfgDmaAccess {
|
typedef struct FWCfgDmaAccess {
|
||||||
uint32_t control;
|
uint32_t control;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
} FWCfgDmaAccess;
|
} FWCfgDmaAccess;
|
||||||
|
|
||||||
The fields of the structure are in big endian mode, and the field at the lowest
|
The fields of the structure are in big endian mode, and the field at the lowest
|
||||||
address is the "control" field.
|
address is the ``control`` field.
|
||||||
|
|
||||||
The "control" field has the following bits:
|
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.
|
|
||||||
- Bit 4: Write
|
|
||||||
|
|
||||||
When an operation is triggered, if the "control" field has bit 3 set, the
|
- Bit 0: Error
|
||||||
|
- Bit 1: Read
|
||||||
|
- Bit 2: Skip
|
||||||
|
- Bit 3: Select. The upper 16 bits are the selected index.
|
||||||
|
- Bit 4: Write
|
||||||
|
|
||||||
|
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.
|
upper 16 bits are interpreted as an index of a firmware configuration item.
|
||||||
This has the same effect as writing the selector register.
|
This has the same effect as writing the selector register.
|
||||||
|
|
||||||
If the "control" field has bit 1 set, a read operation will be performed.
|
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
|
``length`` bytes for the current selector and offset will be copied into the
|
||||||
physical RAM address specified by the "address" field.
|
physical RAM address specified by the ``address`` field.
|
||||||
|
|
||||||
If the "control" field has bit 4 set (and not bit 1), a write operation will be
|
If the ``control`` field has bit 4 set (and not bit 1), a write operation will be
|
||||||
performed. "length" bytes will be copied from the physical RAM address
|
performed. ``length`` bytes will be copied from the physical RAM address
|
||||||
specified by the "address" field to the current selector and offset. QEMU
|
specified by the ``address`` field to the current selector and offset. QEMU
|
||||||
prevents starting or finishing the write beyond the end of the item associated
|
prevents starting or finishing the write beyond the end of the item associated
|
||||||
with the current selector (i.e., the item cannot be resized). Truncated writes
|
with the current selector (i.e., the item cannot be resized). Truncated writes
|
||||||
are dropped entirely. Writes to read-only items are also rejected. All of these
|
are dropped entirely. Writes to read-only items are also rejected. All of these
|
||||||
write errors set bit 0 (the error bit) in the "control" field.
|
write errors set bit 0 (the error bit) in the ``control`` field.
|
||||||
|
|
||||||
If the "control" field has bit 2 set (and neither bit 1 nor bit 4), a skip
|
If the ``control`` field has bit 2 set (and neither bit 1 nor bit 4), a skip
|
||||||
operation will be performed. The offset for the current selector will be
|
operation will be performed. The offset for the current selector will be
|
||||||
advanced "length" bytes.
|
advanced ``length`` bytes.
|
||||||
|
|
||||||
To check the result, read the "control" field:
|
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).
|
|
||||||
|
|
||||||
= Externally Provided Items =
|
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).
|
||||||
|
|
||||||
|
Externally Provided Items
|
||||||
|
=========================
|
||||||
|
|
||||||
Since v2.4, "file" fw_cfg items (i.e., items with selector keys above
|
Since 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
|
``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
|
directory structure) may be inserted via the QEMU command line, using
|
||||||
the following syntax:
|
the following syntax::
|
||||||
|
|
||||||
-fw_cfg [name=]<item_name>,file=<path>
|
-fw_cfg [name=]<item_name>,file=<path>
|
||||||
|
|
||||||
Or
|
Or::
|
||||||
|
|
||||||
-fw_cfg [name=]<item_name>,string=<string>
|
-fw_cfg [name=]<item_name>,string=<string>
|
||||||
|
|
||||||
Since v5.1, QEMU allows some objects to generate fw_cfg-specific content,
|
Since v5.1, QEMU allows some objects to generate fw_cfg-specific content,
|
||||||
the content is then associated with a "file" item using the 'gen_id' option
|
the content is then associated with a "file" item using the 'gen_id' option
|
||||||
in the command line, using the following syntax:
|
in the command line, using the following syntax::
|
||||||
|
|
||||||
-object <generator-type>,id=<generated_id>,[generator-specific-options] \
|
-object <generator-type>,id=<generated_id>,[generator-specific-options] \
|
||||||
-fw_cfg [name=]<item_name>,gen_id=<generated_id>
|
-fw_cfg [name=]<item_name>,gen_id=<generated_id>
|
||||||
|
@ -241,24 +266,24 @@ See QEMU man page for more documentation.
|
||||||
|
|
||||||
Using item_name with plain ASCII characters only is recommended.
|
Using item_name with plain ASCII characters only is recommended.
|
||||||
|
|
||||||
Item names beginning with "opt/" are reserved for users. QEMU will
|
Item names beginning with ``opt/`` are reserved for users. QEMU will
|
||||||
never create entries with such names unless explicitly ordered by the
|
never create entries with such names unless explicitly ordered by the
|
||||||
user.
|
user.
|
||||||
|
|
||||||
To avoid clashes among different users, it is strongly recommended
|
To avoid clashes among different users, it is strongly recommended
|
||||||
that you use names beginning with opt/RFQDN/, where RFQDN is a reverse
|
that you use names beginning with ``opt/RFQDN/``, where RFQDN is a reverse
|
||||||
fully qualified domain name you control. For instance, if SeaBIOS
|
fully qualified domain name you control. For instance, if SeaBIOS
|
||||||
wanted to define additional names, the prefix "opt/org.seabios/" would
|
wanted to define additional names, the prefix ``opt/org.seabios/`` would
|
||||||
be appropriate.
|
be appropriate.
|
||||||
|
|
||||||
For historical reasons, "opt/ovmf/" is reserved for OVMF firmware.
|
For historical reasons, ``opt/ovmf/`` is reserved for OVMF firmware.
|
||||||
|
|
||||||
Prefix "opt/org.qemu/" is reserved for QEMU itself.
|
Prefix ``opt/org.qemu/`` is reserved for QEMU itself.
|
||||||
|
|
||||||
Use of names not beginning with "opt/" is potentially dangerous and
|
Use of names not beginning with ``opt/`` is potentially dangerous and
|
||||||
entirely unsupported. QEMU will warn if you try.
|
entirely unsupported. QEMU will warn if you try.
|
||||||
|
|
||||||
Use of names not beginning with "opt/" is tolerated with 'gen_id' (that
|
Use of names not beginning with ``opt/`` is tolerated with 'gen_id' (that
|
||||||
is, the warning is suppressed), but you must know exactly what you're
|
is, the warning is suppressed), but you must know exactly what you're
|
||||||
doing.
|
doing.
|
||||||
|
|
|
@ -20,3 +20,4 @@ guest hardware that is specific to QEMU.
|
||||||
acpi_nvdimm
|
acpi_nvdimm
|
||||||
acpi_erst
|
acpi_erst
|
||||||
sev-guest-firmware
|
sev-guest-firmware
|
||||||
|
fw_cfg
|
||||||
|
|
|
@ -146,16 +146,6 @@ multiple CanoKey QEMU running, namely you can not
|
||||||
Also, there is no lock on canokey-file, thus two CanoKey QEMU instance
|
Also, there is no lock on canokey-file, thus two CanoKey QEMU instance
|
||||||
can not read one canokey-file at the same time.
|
can not read one canokey-file at the same time.
|
||||||
|
|
||||||
Another limitation is that this device is not compatible with ``qemu-xhci``,
|
|
||||||
in that this device would hang when there are FIDO2 packets (traffic on
|
|
||||||
interrupt endpoints). If you do not use FIDO2 then it works as intended,
|
|
||||||
but for full functionality you should use old uhci/ehci bus and attach canokey
|
|
||||||
to it, for example
|
|
||||||
|
|
||||||
.. parsed-literal::
|
|
||||||
|
|
||||||
|qemu_system| -device piix3-usb-uhci,id=uhci -device canokey,bus=uhci.0
|
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,6 @@ static const USBDesc desc_canokey = {
|
||||||
.iSerialNumber = STR_SERIALNUMBER,
|
.iSerialNumber = STR_SERIALNUMBER,
|
||||||
},
|
},
|
||||||
.full = &desc_device_canokey,
|
.full = &desc_device_canokey,
|
||||||
.high = &desc_device_canokey,
|
|
||||||
.str = desc_strings,
|
.str = desc_strings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,17 +102,23 @@ int canokey_emu_transmit(
|
||||||
pbuf, size);
|
pbuf, size);
|
||||||
key->ep_in_size[ep_in] += size;
|
key->ep_in_size[ep_in] += size;
|
||||||
key->ep_in_state[ep_in] = CANOKEY_EP_IN_READY;
|
key->ep_in_state[ep_in] = CANOKEY_EP_IN_READY;
|
||||||
|
/*
|
||||||
|
* wake up controller if we NAKed IN token before
|
||||||
|
* Note: this is a quirk for CanoKey CTAPHID
|
||||||
|
*/
|
||||||
|
if (ep_in == CANOKEY_EMU_EP_CTAPHID) {
|
||||||
|
usb_wakeup(usb_ep_get(&key->dev, USB_TOKEN_IN, ep_in), 0);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* ready for more data in device loop
|
* ready for more data in device loop
|
||||||
*
|
*
|
||||||
* Note: this is a quirk for CanoKey CTAPHID
|
* Note: this is a quirk for CanoKey CTAPHID
|
||||||
* because it calls multiple emu_transmit in one device_loop
|
* because it calls multiple emu_transmit in one device_loop
|
||||||
* but w/o data_in it would stuck in device_loop
|
* but w/o data_in it would stuck in device_loop
|
||||||
* This has no side effect for CCID as it is strictly
|
* This has side effect for CCID since CCID can send ZLP
|
||||||
* OUT then IN transfer
|
* This also has side effect for Control transfer
|
||||||
* However it has side effect for Control transfer
|
|
||||||
*/
|
*/
|
||||||
if (ep_in != 0) {
|
if (ep_in == CANOKEY_EMU_EP_CTAPHID) {
|
||||||
canokey_emu_data_in(ep_in);
|
canokey_emu_data_in(ep_in);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -209,6 +214,22 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p)
|
||||||
key->ep_out_size[ep_out] = out_len;
|
key->ep_out_size[ep_out] = out_len;
|
||||||
canokey_emu_data_out(ep_out, NULL);
|
canokey_emu_data_out(ep_out, NULL);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Note: this is a quirk for CanoKey CTAPHID
|
||||||
|
*
|
||||||
|
* There is one code path that uses this device loop
|
||||||
|
* INTR IN -> useful data_in and useless device_loop -> NAKed
|
||||||
|
* INTR OUT -> useful device loop -> transmit -> wakeup
|
||||||
|
* (useful thanks to both data_in and data_out having been called)
|
||||||
|
* the next INTR IN -> actual data to guest
|
||||||
|
*
|
||||||
|
* if there is no such device loop, there would be no further
|
||||||
|
* INTR IN, no device loop, no transmit hence no usb_wakeup
|
||||||
|
* then qemu would hang
|
||||||
|
*/
|
||||||
|
if (ep_in == CANOKEY_EMU_EP_CTAPHID) {
|
||||||
|
canokey_emu_device_loop(); /* may call transmit multiple times */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case USB_TOKEN_IN:
|
case USB_TOKEN_IN:
|
||||||
if (key->ep_in_pos[ep_in] == 0) { /* first time IN */
|
if (key->ep_in_pos[ep_in] == 0) { /* first time IN */
|
||||||
|
|
|
@ -463,6 +463,7 @@ bool qemu_console_is_visible(QemuConsole *con);
|
||||||
bool qemu_console_is_graphic(QemuConsole *con);
|
bool qemu_console_is_graphic(QemuConsole *con);
|
||||||
bool qemu_console_is_fixedsize(QemuConsole *con);
|
bool qemu_console_is_fixedsize(QemuConsole *con);
|
||||||
bool qemu_console_is_gl_blocked(QemuConsole *con);
|
bool qemu_console_is_gl_blocked(QemuConsole *con);
|
||||||
|
bool qemu_console_is_multihead(DeviceState *dev);
|
||||||
char *qemu_console_get_label(QemuConsole *con);
|
char *qemu_console_get_label(QemuConsole *con);
|
||||||
int qemu_console_get_index(QemuConsole *con);
|
int qemu_console_get_index(QemuConsole *con);
|
||||||
uint32_t qemu_console_get_head(QemuConsole *con);
|
uint32_t qemu_console_get_head(QemuConsole *con);
|
||||||
|
|
|
@ -1894,16 +1894,18 @@ static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
||||||
static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
||||||
QemuClipboardType type)
|
QemuClipboardType type)
|
||||||
{
|
{
|
||||||
|
NSAutoreleasePool *pool;
|
||||||
NSData *text;
|
NSData *text;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QEMU_CLIPBOARD_TYPE_TEXT:
|
case QEMU_CLIPBOARD_TYPE_TEXT:
|
||||||
|
pool = [[NSAutoreleasePool alloc] init];
|
||||||
text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
|
text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
|
||||||
if (text) {
|
if (text) {
|
||||||
qemu_clipboard_set_data(&cbpeer, info, type,
|
qemu_clipboard_set_data(&cbpeer, info, type,
|
||||||
[text length], [text bytes], true);
|
[text length], [text bytes], true);
|
||||||
[text release];
|
|
||||||
}
|
}
|
||||||
|
[pool release];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
41
ui/console.c
41
ui/console.c
|
@ -2313,11 +2313,50 @@ bool qemu_console_is_gl_blocked(QemuConsole *con)
|
||||||
return con->gl_block;
|
return con->gl_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qemu_console_is_multihead(DeviceState *dev)
|
||||||
|
{
|
||||||
|
QemuConsole *con;
|
||||||
|
Object *obj;
|
||||||
|
uint32_t f = 0xffffffff;
|
||||||
|
uint32_t h;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
|
obj = object_property_get_link(OBJECT(con),
|
||||||
|
"device", &error_abort);
|
||||||
|
if (DEVICE(obj) != dev) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = object_property_get_uint(OBJECT(con),
|
||||||
|
"head", &error_abort);
|
||||||
|
if (f == 0xffffffff) {
|
||||||
|
f = h;
|
||||||
|
} else if (h != f) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char *qemu_console_get_label(QemuConsole *con)
|
char *qemu_console_get_label(QemuConsole *con)
|
||||||
{
|
{
|
||||||
if (con->console_type == GRAPHIC_CONSOLE) {
|
if (con->console_type == GRAPHIC_CONSOLE) {
|
||||||
if (con->device) {
|
if (con->device) {
|
||||||
return g_strdup(object_get_typename(con->device));
|
DeviceState *dev;
|
||||||
|
bool multihead;
|
||||||
|
|
||||||
|
dev = DEVICE(con->device);
|
||||||
|
multihead = qemu_console_is_multihead(dev);
|
||||||
|
if (multihead) {
|
||||||
|
return g_strdup_printf("%s.%d", dev->id ?
|
||||||
|
dev->id :
|
||||||
|
object_get_typename(con->device),
|
||||||
|
con->head);
|
||||||
|
} else {
|
||||||
|
return g_strdup_printf("%s", dev->id ?
|
||||||
|
dev->id :
|
||||||
|
object_get_typename(con->device));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return g_strdup("VGA");
|
return g_strdup("VGA");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue