From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, mst@redhat.com, armbru@redhat.com,
stefanha@redhat.com, pbonzini@redhat.com,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH 06/15] qtest/ahci: Add link_cmd_slot helper
Date: Thu, 18 Sep 2014 19:43:30 -0400 [thread overview]
Message-ID: <1411083819-9284-7-git-send-email-jsnow@redhat.com> (raw)
In-Reply-To: <1411083819-9284-1-git-send-email-jsnow@redhat.com>
link_cmd_slot creates the command header, by
setting a pointer to the command table as well as
adjusting other metadata, like DMA direction and
PRDT length.
It effectively links a command, via its table,
to the indicated command slot.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ahci-test.c | 72 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 57 insertions(+), 15 deletions(-)
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index f07495f..3e65435 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -252,11 +252,26 @@
#define AHCI_VERSION_1_2 (0x00010200)
#define AHCI_VERSION_1_3 (0x00010300)
+/* AHCI COMMAND HEADER FLAGS */
+
+#define CMDH_CFL (0x1F)
+#define CMDH_ATAPI (0x20)
+#define CMDH_READ (0x00) /* Fake. */
+#define CMDH_WRITE (0x40)
+#define CMDH_PREFETCH (0x80)
+#define CMDH_RESET (0x100)
+#define CMDH_BIST (0x200)
+#define CMDH_CLR_BSY (0x400)
+#define CMDH_RES (0x800)
+#define CMDH_PMP (0xF000)
+
/*** Structures ***/
typedef struct AHCIPortState {
uint64_t fb;
uint64_t clb;
+ uint64_t _ctba;
+ uint16_t _prdtl;
uint64_t ctba[32];
uint16_t prdtl[32];
uint8_t next; /** Next Command Slot to Use **/
@@ -341,8 +356,7 @@ typedef struct RegH2DFIS {
* The command list contains between 1-32 of these structures.
*/
typedef struct AHCICommand {
- uint8_t b1;
- uint8_t b2;
+ uint16_t flags; /* Cmd-Fis-Len, PMP#, and flags. */
uint16_t prdtl; /* Phys Region Desc. Table Length */
uint32_t prdbc; /* Phys Region Desc. Byte Count */
uint64_t ctba; /* Command Table Descriptor Base Address */
@@ -1286,6 +1300,7 @@ static void get_command_header(AHCIState *ahci, uint8_t px,
ba += cx * sizeof(AHCICommand);
memread(ba, cmd, sizeof(AHCICommand));
+ cmd->flags = le16_to_cpu(cmd->flags);
cmd->prdtl = le16_to_cpu(cmd->prdtl);
cmd->prdbc = le32_to_cpu(cmd->prdbc);
cmd->ctba = le64_to_cpu(cmd->ctba);
@@ -1298,6 +1313,7 @@ static void set_command_header(AHCIState *ahci, uint8_t px,
uint64_t ba = ahci->port[px].clb;
ba += cx * sizeof(AHCICommand);
+ cmd->flags = cpu_to_le16(cmd->flags);
cmd->prdtl = cpu_to_le16(cmd->prdtl);
cmd->prdbc = cpu_to_le32(cmd->prdbc);
cmd->ctba = cpu_to_le64(cmd->ctba);
@@ -1408,10 +1424,47 @@ static uint64_t build_cmd_table(AHCIState *ahci, uint8_t px, size_t sz,
/* Commit the Command FIS to the Command Table */
memwrite(table_ptr, &fis, sizeof(fis));
+ /* Bookmark these values. */
+ ahci->port[px]._prdtl = prdtl;
+ ahci->port[px]._ctba = table_ptr;
+
return table_ptr;
}
/**
+ * Given a pointer to a Command Table, create a Command Header for it and write
+ * it to a free slot in the Command List buffer.
+ * @return The command slot number we picked.
+ */
+static unsigned link_cmd_slot(AHCIState *ahci, uint8_t px, uint64_t table_ptr,
+ uint8_t cmdh_flags)
+{
+ AHCICommand cmd = { .flags = 0 };
+ uint8_t cx;
+
+ cx = pick_cmd(ahci, px);
+
+ /* Construct our Command Header */
+ cmd.flags = 5;
+ cmd.flags |= CMDH_CLR_BSY;
+ cmd.flags |= cmdh_flags;
+ cmd.prdtl = (table_ptr == ahci->port[px]._ctba) ? ahci->port[px]._prdtl : 1;
+ cmd.prdbc = 0;
+ cmd.ctba = table_ptr;
+
+ /* Commit Command #cx, pointing to the Table, to the Command List Buffer. */
+ set_command_header(ahci, px, cx, &cmd);
+
+ /* For convenience only. */
+ ahci->port[px].ctba[cx] = table_ptr;
+ ahci->port[px].prdtl[cx] = cmd.prdtl;
+ ahci->port[px]._ctba = 0;
+ ahci->port[px]._prdtl = 0;
+
+ return cx;
+}
+
+/**
* Utilizing an initialized AHCI HBA, issue an IDENTIFY command to the first
* device we see, then read and check the response.
*/
@@ -1458,19 +1511,8 @@ static void ahci_test_identify(AHCIState *ahci)
/* Construct the Command Table (FIS and PRDT) */
table_ptr = build_cmd_table(ahci, i, 512, 0xEC, data_ptr);
- /* pick a command slot (should be 0!) */
- cx = pick_cmd(ahci, i);
-
- /* Construct our Command Header (set_command_header handles endianness.) */
- memset(&cmd, 0x00, sizeof(cmd));
- cmd.b1 = 5; /* reg_h2d_fis is 5 double-words long */
- cmd.b2 = 0x04; /* clear PxTFD.STS.BSY when done */
- cmd.prdtl = 1; /* One PRD table entry. */
- cmd.prdbc = 0;
- cmd.ctba = table_ptr;
-
- /* Commit Command #cx, pointing to the Table, to the Command List Buffer. */
- set_command_header(ahci, i, cx, &cmd);
+ /* Pick a command slot and link it to the command table we've built */
+ cx = link_cmd_slot(ahci, i, table_ptr, CMDH_READ);
/* Everything is in place, but we haven't given the go-ahead yet,
* so we should find that there are no pending interrupts yet. */
--
1.9.3
next prev parent reply other threads:[~2014-09-18 23:44 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-18 23:43 [Qemu-devel] [PATCH 00/15] AHCI test helper refactors John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 01/15] qtest/ahci: Add AHCIState structure John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 02/15] qtest/ahci: Add port_select helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 03/15] qtest/ahci: Add port_clear helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 04/15] qtest/ahci: Add command header helpers John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 05/15] qtest/ahci: Add build cmd table helper John Snow
2014-09-18 23:43 ` John Snow [this message]
2014-09-18 23:43 ` [Qemu-devel] [PATCH 07/15] qtest/ahci: Add port_check_error helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 08/15] qtest/ahci: Add issue_command helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 09/15] qtest/ahci: Add port_check_interrupts helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 10/15] qtest/ahci: Add port_check_nonbusy helper John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 11/15] qtest/ahci: Add cmd response sanity check helpers John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 12/15] qtest/ahci: Enforce zero-leaks for guest mem usage John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 13/15] qtest/ahci: Add a macro bootup routine John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 14/15] qtest/ahci: Add human-readable command names John Snow
2014-09-18 23:43 ` [Qemu-devel] [PATCH 15/15] qtest/ahci: Don't use a magic constant for buffer size John Snow
2014-09-19 10:53 ` [Qemu-devel] [PATCH 00/15] AHCI test helper refactors Markus Armbruster
2014-09-19 12:57 ` Stefan Hajnoczi
2014-09-19 15:28 ` John Snow
2014-11-03 18:41 ` John Snow
2015-01-08 16:25 ` John Snow
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=1411083819-9284-7-git-send-email-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=kwolf@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).