qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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

  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).