diff options
author | John Snow | 2015-02-05 18:41:19 +0100 |
---|---|---|
committer | Stefan Hajnoczi | 2015-02-16 16:07:17 +0100 |
commit | d1ef883894f0661f9994bc937ba09077a32a8bee (patch) | |
tree | 0d5f6b2b8b837aa745263617fd29297c99b31907 /tests/libqos/ahci.c | |
parent | libqos/ahci: Add port_check_nonbusy helper (diff) | |
download | qemu-d1ef883894f0661f9994bc937ba09077a32a8bee.tar.gz qemu-d1ef883894f0661f9994bc937ba09077a32a8bee.tar.xz qemu-d1ef883894f0661f9994bc937ba09077a32a8bee.zip |
libqos/ahci: Add cmd response sanity check helpers
This patch adds a few helpers to help sanity-check the response of the
AHCI device after a command.
ahci_d2h_check_sanity inspects the D2H Register FIS,
ahci_pio_check_sanity inspects the PIO Setup FIS, and
ahci_cmd_check_sanity inspects the command header.
To support the PIO sanity check, a new structure is added for the
PIO Setup FIS type. Existing FIS types (H2D and D2H) have had their
members renamed slightly to condense reserved members into fewer
fields; and LBA fields are now represented by arrays of 8 byte chunks
instead of independent variables.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1423158090-25580-9-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'tests/libqos/ahci.c')
-rw-r--r-- | tests/libqos/ahci.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c index 7ed6494805..8ecfdd30d8 100644 --- a/tests/libqos/ahci.c +++ b/tests/libqos/ahci.c @@ -365,6 +365,53 @@ void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot) ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_DRQ); } +void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot) +{ + RegD2HFIS *d2h = g_malloc0(0x20); + uint32_t reg; + + memread(ahci->port[port].fb + 0x40, d2h, 0x20); + g_assert_cmphex(d2h->fis_type, ==, 0x34); + + reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD); + g_assert_cmphex((reg & AHCI_PX_TFD_ERR) >> 8, ==, d2h->error); + g_assert_cmphex((reg & AHCI_PX_TFD_STS), ==, d2h->status); + + g_free(d2h); +} + +void ahci_port_check_pio_sanity(AHCIQState *ahci, uint8_t port, + uint8_t slot, size_t buffsize) +{ + PIOSetupFIS *pio = g_malloc0(0x20); + + /* We cannot check the Status or E_Status registers, becuase + * the status may have again changed between the PIO Setup FIS + * and the conclusion of the command with the D2H Register FIS. */ + memread(ahci->port[port].fb + 0x20, pio, 0x20); + g_assert_cmphex(pio->fis_type, ==, 0x5f); + + /* BUG: PIO Setup FIS as utilized by QEMU tries to fit the entire + * transfer size in a uint16_t field. The maximum transfer size can + * eclipse this; the field is meant to convey the size of data per + * each Data FIS, not the entire operation as a whole. For now, + * we will sanity check the broken case where applicable. */ + if (buffsize <= UINT16_MAX) { + g_assert_cmphex(le16_to_cpu(pio->tx_count), ==, buffsize); + } + + g_free(pio); +} + +void ahci_port_check_cmd_sanity(AHCIQState *ahci, uint8_t port, + uint8_t slot, size_t buffsize) +{ + AHCICommandHeader cmd; + + ahci_get_command_header(ahci, port, slot, &cmd); + g_assert_cmphex(buffsize, ==, cmd.prdbc); +} + /* Get the command in #slot of port #port. */ void ahci_get_command_header(AHCIQState *ahci, uint8_t port, uint8_t slot, AHCICommandHeader *cmd) |