From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: famz@redhat.com, mst@redhat.com, armbru@redhat.com,
stefanha@redhat.com, pbonzini@redhat.com,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH 15/19] libqos/ahci: add ahci_io
Date: Fri, 30 Jan 2015 13:42:09 -0500 [thread overview]
Message-ID: <1422643333-27926-16-git-send-email-jsnow@redhat.com> (raw)
In-Reply-To: <1422643333-27926-1-git-send-email-jsnow@redhat.com>
ahci_io is a wrapper around ahci_guest_io that takes a pointer to host
memory instead, and will create a guest memory buffer and copy the data
to/from as needed and as appropriate for a read/write command, such that
after a read, the guest data will be in a host buffer, and for a write,
the data will be transmitted to guest memory prior to the block operation.
Now that we have all the syntactic sugar functions in place for AHCI,
we can convert the identify test to be very, very short.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ahci-test.c | 63 +++++++++++++++++++++--------------------------------
tests/libqos/ahci.c | 25 +++++++++++++++++++++
tests/libqos/ahci.h | 2 ++
3 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 6e7b765..47491fe 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -657,56 +657,43 @@ static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port)
*/
static void ahci_test_identify(AHCIQState *ahci)
{
- uint32_t data_ptr;
uint16_t buff[256];
- unsigned i;
+ unsigned px;
int rc;
- AHCICommand *cmd;
+ const size_t buffsize = 512;
g_assert(ahci != NULL);
- /* We need to:
- * (1) Create a data buffer for the IDENTIFY response to be sent to,
- * (2) Create a Command Table Buffer
+ /**
+ * This serves as a bit of a tutorial on AHCI device programming:
+ *
+ * (1) Create a data buffer for the IDENTIFY response to be sent to
+ * (2) Create a Command Table buffer, where we will store the
+ * command and PRDT (Physical Region Descriptor Table)
* (3) Construct an FIS host-to-device command structure, and write it to
- * the top of the command table buffer.
- * (4) Create a Physical Region Descriptor that points to the data buffer,
- * and write it to the bottom (offset 0x80) of the command table.
- * (5) Obtain a Command List slot, and update this header to point to
- * the Command Table we built above.
- * (6) Now, PxCLB points to the command list, command 0 points to
- * our table, and our table contains an FIS instruction and a
- * PRD that points to our rx buffer.
- * (7) We inform the HBA via PxCI that there is a command ready in slot #0.
+ * the top of the Command Table buffer.
+ * (4) Create one or more Physical Region Descriptors (PRDs) that describe
+ * a location in memory where data may be stored/retrieved.
+ * (5) Write these PRDTs to the bottom (offset 0x80) of the Command Table.
+ * (6) Each AHCI port has up to 32 command slots. Each slot contains a
+ * header that points to a Command Table buffer. Pick an unused slot
+ * and update it to point to the Command Table we have built.
+ * (7) Now: Command #n points to our Command Table, and our Command Table
+ * contains the FIS (that describes our command) and the PRDTL, which
+ * describes our buffer.
+ * (8) We inform the HBA via PxCI (Command Issue) that the command in slot
+ * #n is ready for processing.
*/
/* Pick the first implemented and running port */
- i = ahci_port_select(ahci);
- g_test_message("Selected port %u for test", i);
+ px = ahci_port_select(ahci);
+ g_test_message("Selected port %u for test", px);
/* Clear out the FIS Receive area and any pending interrupts. */
- ahci_port_clear(ahci, i);
+ ahci_port_clear(ahci, px);
- /* Create a data buffer where we will dump the IDENTIFY data to. */
- data_ptr = ahci_alloc(ahci, 512);
- g_assert(data_ptr);
-
- /* Construct the Command Table (FIS and PRDT) and Command Header */
- cmd = ahci_command_create(CMD_IDENTIFY);
- ahci_command_set_buffer(cmd, data_ptr);
- /* Write the command header and PRDT to guest memory */
- ahci_command_commit(ahci, cmd, i);
-
- /* Everything is in place, but we haven't given the go-ahead yet,
- * so we should find that there are no pending interrupts yet. */
- g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_IS), ==, 0);
-
- /* Issue command and sanity check response. */
- ahci_command_issue(ahci, cmd);
- ahci_command_verify(ahci, cmd);
-
- /* Last, but not least: Investigate the IDENTIFY response data. */
- memread(data_ptr, &buff, 512);
+ /* "Read" 512 bytes using CMD_IDENTIFY into the host buffer. */
+ ahci_io(ahci, px, CMD_IDENTIFY, &buff, buffsize);
/* Check serial number/version in the buffer */
/* NB: IDENTIFY strings are packed in 16bit little endian chunks.
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index d55dab8..e73205b 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -580,6 +580,31 @@ static AHCICommandProp *ahci_command_find(uint8_t command_name)
}
}
+/* Given a HOST buffer, create a buffer address and perform an IO operation. */
+void ahci_io(AHCIQState *ahci, uint8_t px, uint8_t ide_cmd,
+ void *buffer, size_t bufsize)
+{
+ uint64_t ptr;
+ AHCICommandProp *props;
+
+ props = ahci_command_find(ide_cmd);
+ g_assert(props);
+ ptr = ahci_alloc(ahci, bufsize);
+ g_assert(ptr);
+
+ if (props->write) {
+ memwrite(ptr, buffer, bufsize);
+ }
+
+ ahci_guest_io(ahci, px, ide_cmd, ptr, bufsize);
+
+ if (props->read) {
+ memread(ptr, buffer, bufsize);
+ }
+
+ ahci_free(ahci, ptr);
+}
+
/**
* Initializes a basic command header in memory.
* We assume that this is for an ATA command using RegH2DFIS.
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index cbde141..3c4f478 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -522,6 +522,8 @@ unsigned ahci_pick_cmd(AHCIQState *ahci, uint8_t px);
unsigned size_to_prdtl(unsigned bytes, unsigned bytes_per_prd);
void ahci_guest_io(AHCIQState *ahci, uint8_t px, uint8_t ide_cmd,
uint64_t gbuffer, size_t size);
+void ahci_io(AHCIQState *ahci, uint8_t px, uint8_t ide_cmd,
+ void *buffer, size_t bufsize);
/* Command Lifecycle */
AHCICommand *ahci_command_create(uint8_t command_name);
--
1.9.3
next prev parent reply other threads:[~2015-01-30 18:42 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-30 18:41 [Qemu-devel] [PATCH 00/19] qtest/ahci: add dma test John Snow
2015-01-30 18:41 ` [Qemu-devel] [PATCH 01/19] libqos/ahci: Add ahci_port_select helper John Snow
2015-01-30 18:41 ` [Qemu-devel] [PATCH 02/19] libqos/ahci: Add ahci_port_clear helper John Snow
2015-01-30 18:41 ` [Qemu-devel] [PATCH 03/19] qtest/ahci: rename 'Command' to 'CommandHeader' John Snow
2015-02-02 10:25 ` Paolo Bonzini
2015-01-30 18:41 ` [Qemu-devel] [PATCH 04/19] libqos/ahci: Add command header helpers John Snow
2015-02-02 10:25 ` Paolo Bonzini
2015-02-02 20:33 ` John Snow
2015-02-02 10:27 ` Paolo Bonzini
2015-02-02 20:38 ` John Snow
2015-01-30 18:41 ` [Qemu-devel] [PATCH 05/19] libqos/ahci: Add ahci_port_check_error helper John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 06/19] libqos/ahci: Add ahci_port_check_interrupts helper John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 07/19] libqos/ahci: Add port_check_nonbusy helper John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 08/19] libqos/ahci: Add cmd response sanity check helpers John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 09/19] qtest/ahci: Demagic ahci tests John Snow
2015-02-02 10:33 ` Paolo Bonzini
2015-01-30 18:42 ` [Qemu-devel] [PATCH 10/19] libqos/ahci: Add ide cmd properties John Snow
2015-02-02 10:34 ` Paolo Bonzini
2015-01-30 18:42 ` [Qemu-devel] [PATCH 11/19] libqos/ahci: add ahci command functions John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 12/19] libqos/ahci: add ahci command verify John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 13/19] libqos/ahci: add ahci command size setters John Snow
2015-02-02 10:35 ` Paolo Bonzini
2015-02-02 21:09 ` John Snow
2015-02-03 8:52 ` Paolo Bonzini
2015-01-30 18:42 ` [Qemu-devel] [PATCH 14/19] libqos/ahci: Add ahci_guest_io John Snow
2015-01-30 18:42 ` John Snow [this message]
2015-01-30 18:42 ` [Qemu-devel] [PATCH 16/19] libqos/ahci: Add ahci_clean_mem John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 17/19] qtest/ahci: Add a macro bootup routine John Snow
2015-02-02 10:37 ` Paolo Bonzini
2015-02-02 21:12 ` John Snow
2015-02-03 8:53 ` Paolo Bonzini
2015-01-30 18:42 ` [Qemu-devel] [PATCH 18/19] qtest/ahci: Assert sector size in identify test John Snow
2015-01-30 18:42 ` [Qemu-devel] [PATCH 19/19] qtest/ahci: Adding simple dma read-write test John Snow
2015-02-02 10:38 ` Paolo Bonzini
2015-02-02 10:38 ` [Qemu-devel] [PATCH 00/19] qtest/ahci: add dma test Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1422643333-27926-16-git-send-email-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=famz@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).