fw_cfg: Define a static signature to be returned on DMA port reads

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>
This commit is contained in:
Kevin O'Connor 2015-10-08 17:02:58 +02:00 committed by Gerd Hoffmann
parent c886fc4c20
commit 2cc06a8843
2 changed files with 15 additions and 2 deletions

View File

@ -93,6 +93,9 @@ 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

View File

@ -53,6 +53,8 @@
#define FW_CFG_DMA_CTL_SKIP 0x04
#define FW_CFG_DMA_CTL_SELECT 0x08
#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
typedef struct FWCfgEntry {
uint32_t len;
uint8_t *data;
@ -397,6 +399,13 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
trace_fw_cfg_read(s, 0);
}
static uint64_t fw_cfg_dma_mem_read(void *opaque, hwaddr addr,
unsigned size)
{
/* Return a signature value (and handle various read sizes) */
return extract64(FW_CFG_DMA_SIGNATURE, (8 - addr - size) * 8, size * 8);
}
static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
@ -420,8 +429,8 @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
unsigned size, bool is_write)
{
return is_write && ((size == 4 && (addr == 0 || addr == 4)) ||
(size == 8 && addr == 0));
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
(size == 8 && addr == 0));
}
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
@ -492,6 +501,7 @@ static const MemoryRegionOps fw_cfg_comb_mem_ops = {
};
static const MemoryRegionOps fw_cfg_dma_mem_ops = {
.read = fw_cfg_dma_mem_read,
.write = fw_cfg_dma_mem_write,
.endianness = DEVICE_BIG_ENDIAN,
.valid.accepts = fw_cfg_dma_mem_valid,