* [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests
@ 2015-09-10 23:09 John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere John Snow
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: John Snow @ 2015-09-10 23:09 UTC (permalink / raw)
To: qemu-block
Cc: kwolf, qemu-devel, armbru, zuban32s, stefanha, pbonzini,
John Snow
We don't have any CDROM tests yet.
So, add some for the PCI/BMDMA HBA.
===
v2:
===
- Some readability feedback from Markus
- Added an IRQ poll for the DRQ read loop
________________________________________________________________________________
For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch ide-atapi-test
https://github.com/jnsnow/qemu/tree/ide-atapi-test
This version is tagged ide-atapi-test-v2:
https://github.com/jnsnow/qemu/releases/tag/ide-atapi-test-v2
John Snow (4):
qtest/ahci: use generate_pattern everywhere
qtest/ahci: export generate_pattern
ide-test: add cdrom pio test
ide-test: add cdrom dma test
tests/ahci-test.c | 43 +--------
tests/ide-test.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++----
tests/libqos/libqos.c | 26 ++++++
tests/libqos/libqos.h | 1 +
4 files changed, 258 insertions(+), 57 deletions(-)
--
2.4.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
@ 2015-09-10 23:09 ` John Snow
2015-09-10 23:47 ` [Qemu-devel] [Qemu-block] " Eric Blake
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 2/4] qtest/ahci: export generate_pattern John Snow
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: John Snow @ 2015-09-10 23:09 UTC (permalink / raw)
To: qemu-block
Cc: kwolf, qemu-devel, armbru, zuban32s, stefanha, pbonzini,
John Snow
Fix the pattern generation to actually be interesting,
and make sure all buffers in the ahci-test actually use it.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ahci-test.c | 23 ++++++-----------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 87d7691..b1a785c 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -80,9 +80,9 @@ static void generate_pattern(void *buffer, size_t len, size_t cycle_len)
/* Write an indicative pattern that varies and is unique per-cycle */
p = rand() % 256;
- for (i = j = 0; i < len; i++, j++) {
- tx[i] = p;
- if (j % cycle_len == 0) {
+ for (i = 0; i < len; i++) {
+ tx[i] = p++ % 256;
+ if (i % cycle_len == 0) {
p = rand() % 256;
}
}
@@ -1155,7 +1155,6 @@ static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write)
size_t bufsize = 4096;
unsigned char *tx = g_malloc(bufsize);
unsigned char *rx = g_malloc0(bufsize);
- unsigned i;
const char *uri = "tcp:127.0.0.1:1234";
src = ahci_boot_and_enable("-m 1024 -M q35 "
@@ -1171,9 +1170,7 @@ static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write)
ahci_port_clear(src, px);
/* create pattern */
- for (i = 0; i < bufsize; i++) {
- tx[i] = (bufsize - i);
- }
+ generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
/* Write, migrate, then read. */
ahci_io(src, px, cmd_write, tx, bufsize, 0);
@@ -1213,7 +1210,6 @@ static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write)
size_t bufsize = 4096;
unsigned char *tx = g_malloc(bufsize);
unsigned char *rx = g_malloc0(bufsize);
- unsigned i;
uint64_t ptr;
AHCICommand *cmd;
@@ -1231,11 +1227,8 @@ static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write)
port = ahci_port_select(ahci);
ahci_port_clear(ahci, port);
- for (i = 0; i < bufsize; i++) {
- tx[i] = (bufsize - i);
- }
-
/* create DMA source buffer and write pattern */
+ generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
ptr = ahci_alloc(ahci, bufsize);
g_assert(ptr);
memwrite(ptr, tx, bufsize);
@@ -1282,7 +1275,6 @@ static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write)
size_t bufsize = 4096;
unsigned char *tx = g_malloc(bufsize);
unsigned char *rx = g_malloc0(bufsize);
- unsigned i;
uint64_t ptr;
AHCICommand *cmd;
const char *uri = "tcp:127.0.0.1:1234";
@@ -1310,10 +1302,7 @@ static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write)
/* Initialize and prepare */
port = ahci_port_select(src);
ahci_port_clear(src, port);
-
- for (i = 0; i < bufsize; i++) {
- tx[i] = (bufsize - i);
- }
+ generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
/* create DMA source buffer and write pattern */
ptr = ahci_alloc(src, bufsize);
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] qtest/ahci: export generate_pattern
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere John Snow
@ 2015-09-10 23:09 ` John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 3/4] ide-test: add cdrom pio test John Snow
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: John Snow @ 2015-09-10 23:09 UTC (permalink / raw)
To: qemu-block
Cc: kwolf, qemu-devel, armbru, zuban32s, stefanha, pbonzini,
John Snow
Share the pattern function for ide and ahci test.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ahci-test.c | 26 --------------------------
tests/libqos/libqos.c | 26 ++++++++++++++++++++++++++
tests/libqos/libqos.h | 1 +
3 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index b1a785c..59d387c 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -71,32 +71,6 @@ static void string_bswap16(uint16_t *s, size_t bytes)
}
}
-static void generate_pattern(void *buffer, size_t len, size_t cycle_len)
-{
- int i, j;
- unsigned char *tx = (unsigned char *)buffer;
- unsigned char p;
- size_t *sx;
-
- /* Write an indicative pattern that varies and is unique per-cycle */
- p = rand() % 256;
- for (i = 0; i < len; i++) {
- tx[i] = p++ % 256;
- if (i % cycle_len == 0) {
- p = rand() % 256;
- }
- }
-
- /* force uniqueness by writing an id per-cycle */
- for (i = 0; i < len / cycle_len; i++) {
- j = i * cycle_len;
- if (j + sizeof(*sx) <= len) {
- sx = (size_t *)&tx[j];
- *sx = i;
- }
- }
-}
-
/**
* Verify that the transfer did not corrupt our state at all.
*/
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index fce625b..8d7c5a9 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -212,3 +212,29 @@ void prepare_blkdebug_script(const char *debug_fn, const char *event)
ret = fclose(debug_file);
g_assert(ret == 0);
}
+
+void generate_pattern(void *buffer, size_t len, size_t cycle_len)
+{
+ int i, j;
+ unsigned char *tx = (unsigned char *)buffer;
+ unsigned char p;
+ size_t *sx;
+
+ /* Write an indicative pattern that varies and is unique per-cycle */
+ p = rand() % 256;
+ for (i = 0; i < len; i++) {
+ tx[i] = p++ % 256;
+ if (i % cycle_len == 0) {
+ p = rand() % 256;
+ }
+ }
+
+ /* force uniqueness by writing an id per-cycle */
+ for (i = 0; i < len / cycle_len; i++) {
+ j = i * cycle_len;
+ if (j + sizeof(*sx) <= len) {
+ sx = (size_t *)&tx[j];
+ *sx = i;
+ }
+ }
+}
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index e1f14ea..492a651 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -24,6 +24,7 @@ void mkqcow2(const char *file, unsigned size_mb);
void set_context(QOSState *s);
void migrate(QOSState *from, QOSState *to, const char *uri);
void prepare_blkdebug_script(const char *debug_fn, const char *event);
+void generate_pattern(void *buffer, size_t len, size_t cycle_len);
static inline uint64_t qmalloc(QOSState *q, size_t bytes)
{
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] ide-test: add cdrom pio test
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 2/4] qtest/ahci: export generate_pattern John Snow
@ 2015-09-10 23:09 ` John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 4/4] ide-test: add cdrom dma test John Snow
2015-09-14 18:09 ` [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
4 siblings, 0 replies; 7+ messages in thread
From: John Snow @ 2015-09-10 23:09 UTC (permalink / raw)
To: qemu-block
Cc: kwolf, qemu-devel, armbru, zuban32s, stefanha, pbonzini,
John Snow
Add a simple read test for ATAPI devices,
using the PIO mechanism.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ide-test.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 157 insertions(+)
diff --git a/tests/ide-test.c b/tests/ide-test.c
index 4a07e3a..b3ddcf4 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -45,6 +45,12 @@
#define IDE_BASE 0x1f0
#define IDE_PRIMARY_IRQ 14
+#define ATAPI_BLOCK_SIZE 2048
+
+/* How many bytes to receive via ATAPI PIO at one time.
+ * Must be less than 0xFFFF. */
+#define BYTE_COUNT_LIMIT 5120
+
enum {
reg_data = 0x0,
reg_nsectors = 0x2,
@@ -80,6 +86,7 @@ enum {
CMD_WRITE_DMA = 0xca,
CMD_FLUSH_CACHE = 0xe7,
CMD_IDENTIFY = 0xec,
+ CMD_PACKET = 0xa0,
CMDF_ABORT = 0x100,
CMDF_NO_BM = 0x200,
@@ -585,6 +592,153 @@ static void test_isa_retry_flush(const char *machine)
test_retry_flush("isapc");
}
+typedef struct Read10CDB {
+ uint8_t opcode;
+ uint8_t flags;
+ uint32_t lba;
+ uint8_t reserved;
+ uint16_t nblocks;
+ uint8_t control;
+ uint16_t padding;
+} __attribute__((__packed__)) Read10CDB;
+
+static void send_scsi_cdb_read10(uint32_t lba, uint16_t nblocks)
+{
+ Read10CDB pkt = { .padding = 0 };
+ int i;
+
+ /* Construct SCSI CDB packet */
+ pkt.opcode = 0x28;
+ pkt.lba = cpu_to_be32(lba);
+ pkt.nblocks = cpu_to_be16(nblocks);
+
+ /* Send Packet */
+ for (i = 0; i < sizeof(Read10CDB)/2; i++) {
+ outw(IDE_BASE + reg_data, ((uint16_t *)&pkt)[i]);
+ }
+}
+
+static void nsleep(int64_t nsecs)
+{
+ const struct timespec val = { .tv_nsec = nsecs };
+ nanosleep(&val, NULL);
+ clock_set(nsecs);
+}
+
+static uint8_t ide_wait_clear(uint8_t flag)
+{
+ int i;
+ uint8_t data;
+
+ /* Wait with a 5 second timeout */
+ for (i = 0; i <= 12500000; i++) {
+ data = inb(IDE_BASE + reg_status);
+ if (!(data & flag)) {
+ return data;
+ }
+ nsleep(400);
+ }
+ g_assert_not_reached();
+}
+
+static void ide_wait_intr(int irq)
+{
+ int i;
+ bool intr;
+
+ for (i = 0; i <= 12500000; i++) {
+ intr = get_irq(irq);
+ if (intr) {
+ return;
+ }
+ nsleep(400);
+ }
+
+ g_assert_not_reached();
+}
+
+static void cdrom_pio_impl(int nblocks)
+{
+ FILE *fh;
+ int patt_blocks = MAX(16, nblocks);
+ size_t patt_len = ATAPI_BLOCK_SIZE * patt_blocks;
+ char *pattern = g_malloc(patt_len);
+ size_t rxsize = ATAPI_BLOCK_SIZE * nblocks;
+ uint16_t *rx = g_malloc0(rxsize);
+ int i, j;
+ uint8_t data;
+ uint16_t limit;
+
+ /* Prepopulate the CDROM with an interesting pattern */
+ generate_pattern(pattern, patt_len, ATAPI_BLOCK_SIZE);
+ fh = fopen(tmp_path, "w+");
+ fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh);
+ fclose(fh);
+
+ ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
+ "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
+ qtest_irq_intercept_in(global_qtest, "ioapic");
+
+ /* PACKET command on device 0 */
+ outb(IDE_BASE + reg_device, 0);
+ outb(IDE_BASE + reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
+ outb(IDE_BASE + reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
+ outb(IDE_BASE + reg_command, CMD_PACKET);
+ /* HPD0: Check_Status_A State */
+ nsleep(400);
+ data = ide_wait_clear(BSY);
+ /* HPD1: Send_Packet State */
+ assert_bit_set(data, DRQ | DRDY);
+ assert_bit_clear(data, ERR | DF | BSY);
+
+ /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
+ send_scsi_cdb_read10(0, nblocks);
+
+ /* HPD3: INTRQ_Wait */
+ ide_wait_intr(IDE_PRIMARY_IRQ);
+
+ /* HPD2: Check_Status_B */
+ data = ide_wait_clear(BSY);
+ assert_bit_set(data, DRQ | DRDY);
+ assert_bit_clear(data, ERR | DF | BSY);
+
+ /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
+ * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
+ * We allow an odd limit only when the remaining transfer size is
+ * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
+ * request n blocks, so our request size is always even.
+ * For this reason, we assume there is never a hanging byte to fetch. */
+ g_assert(!(rxsize & 1));
+ limit = BYTE_COUNT_LIMIT & ~1;
+ for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
+ size_t offset = i * (limit / 2);
+ size_t rem = (rxsize / 2) - offset;
+ for (j = 0; j < MIN((limit / 2), rem); j++) {
+ rx[offset + j] = inw(IDE_BASE + reg_data);
+ }
+ ide_wait_intr(IDE_PRIMARY_IRQ);
+ }
+ data = ide_wait_clear(DRQ);
+ assert_bit_set(data, DRDY);
+ assert_bit_clear(data, DRQ | ERR | DF | BSY);
+
+ g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
+ g_free(pattern);
+ g_free(rx);
+ test_bmdma_teardown();
+}
+
+static void test_cdrom_pio(void)
+{
+ cdrom_pio_impl(1);
+}
+
+static void test_cdrom_pio_large(void)
+{
+ /* Test a few loops of the PIO DRQ mechanism. */
+ cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
+}
+
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
@@ -628,6 +782,9 @@ int main(int argc, char **argv)
qtest_add_func("/ide/flush/retry_pci", test_pci_retry_flush);
qtest_add_func("/ide/flush/retry_isa", test_isa_retry_flush);
+ qtest_add_func("/ide/cdrom/pio", test_cdrom_pio);
+ qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large);
+
ret = g_test_run();
/* Cleanup */
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] ide-test: add cdrom dma test
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
` (2 preceding siblings ...)
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 3/4] ide-test: add cdrom pio test John Snow
@ 2015-09-10 23:09 ` John Snow
2015-09-14 18:09 ` [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
4 siblings, 0 replies; 7+ messages in thread
From: John Snow @ 2015-09-10 23:09 UTC (permalink / raw)
To: qemu-block
Cc: kwolf, qemu-devel, armbru, zuban32s, stefanha, pbonzini,
John Snow
Now, test the DMA functionality of the ATAPI drive.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/ide-test.c | 90 ++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 72 insertions(+), 18 deletions(-)
diff --git a/tests/ide-test.c b/tests/ide-test.c
index b3ddcf4..5594738 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -53,6 +53,7 @@
enum {
reg_data = 0x0,
+ reg_feature = 0x1,
reg_nsectors = 0x2,
reg_lba_low = 0x3,
reg_lba_middle = 0x4,
@@ -179,7 +180,8 @@ typedef struct PrdtEntry {
#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
- PrdtEntry *prdt, int prdt_entries)
+ PrdtEntry *prdt, int prdt_entries,
+ void(*post_exec)(uint64_t sector, int nb_sectors))
{
QPCIDevice *dev;
uint16_t bmdma_base;
@@ -196,6 +198,9 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
switch (cmd) {
case CMD_READ_DMA:
+ case CMD_PACKET:
+ /* Assuming we only test data reads w/ ATAPI, otherwise we need to know
+ * the SCSI command being sent in the packet, too. */
from_dev = true;
break;
case CMD_WRITE_DMA:
@@ -224,14 +229,22 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
outl(bmdma_base + bmreg_prdt, guest_prdt);
/* ATA DMA command */
- outb(IDE_BASE + reg_nsectors, nb_sectors);
-
- outb(IDE_BASE + reg_lba_low, sector & 0xff);
- outb(IDE_BASE + reg_lba_middle, (sector >> 8) & 0xff);
- outb(IDE_BASE + reg_lba_high, (sector >> 16) & 0xff);
+ if (cmd == CMD_PACKET) {
+ /* Enables ATAPI DMA; otherwise PIO is attempted */
+ outb(IDE_BASE + reg_feature, 0x01);
+ } else {
+ outb(IDE_BASE + reg_nsectors, nb_sectors);
+ outb(IDE_BASE + reg_lba_low, sector & 0xff);
+ outb(IDE_BASE + reg_lba_middle, (sector >> 8) & 0xff);
+ outb(IDE_BASE + reg_lba_high, (sector >> 16) & 0xff);
+ }
outb(IDE_BASE + reg_command, cmd);
+ if (post_exec) {
+ post_exec(sector, nb_sectors);
+ }
+
/* Start DMA transfer */
outb(bmdma_base + bmreg_cmd, BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
@@ -285,7 +298,8 @@ static void test_bmdma_simple_rw(void)
memset(buf, 0x55, len);
memwrite(guest_buf, buf, len);
- status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt, ARRAY_SIZE(prdt));
+ status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt,
+ ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
@@ -293,14 +307,15 @@ static void test_bmdma_simple_rw(void)
memset(buf, 0xaa, len);
memwrite(guest_buf, buf, len);
- status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt, ARRAY_SIZE(prdt));
+ status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
+ ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
/* Read and verify 0x55 pattern in sector 0 */
memset(cmpbuf, 0x55, len);
- status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt));
+ status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
@@ -310,7 +325,7 @@ static void test_bmdma_simple_rw(void)
/* Read and verify 0xaa pattern in sector 1 */
memset(cmpbuf, 0xaa, len);
- status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt));
+ status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
@@ -335,13 +350,13 @@ static void test_bmdma_short_prdt(void)
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
}
@@ -360,13 +375,13 @@ static void test_bmdma_one_sector_short_prdt(void)
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 2,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
}
@@ -384,13 +399,13 @@ static void test_bmdma_long_prdt(void)
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
}
@@ -406,7 +421,7 @@ static void test_bmdma_no_busmaster(void)
PrdtEntry prdt[4096] = { };
status = send_dma_request(CMD_READ_DMA | CMDF_NO_BM, 0, 512,
- prdt, ARRAY_SIZE(prdt));
+ prdt, ARRAY_SIZE(prdt), NULL);
/* Not entirely clear what the expected result is, but this is what we get
* in practice. At least we want to be aware of any changes. */
@@ -602,11 +617,15 @@ typedef struct Read10CDB {
uint16_t padding;
} __attribute__((__packed__)) Read10CDB;
-static void send_scsi_cdb_read10(uint32_t lba, uint16_t nblocks)
+static void send_scsi_cdb_read10(uint64_t lba, int nblocks)
{
Read10CDB pkt = { .padding = 0 };
int i;
+ g_assert_cmpint(lba, <=, UINT32_MAX);
+ g_assert_cmpint(nblocks, <=, UINT16_MAX);
+ g_assert_cmpint(nblocks, >=, 0);
+
/* Construct SCSI CDB packet */
pkt.opcode = 0x28;
pkt.lba = cpu_to_be32(lba);
@@ -739,6 +758,40 @@ static void test_cdrom_pio_large(void)
cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
}
+
+static void test_cdrom_dma(void)
+{
+ static const size_t len = ATAPI_BLOCK_SIZE;
+ char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16);
+ char *rx = g_malloc0(len);
+ uintptr_t guest_buf;
+ PrdtEntry prdt[1];
+ FILE *fh;
+
+ ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
+ "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
+ qtest_irq_intercept_in(global_qtest, "ioapic");
+
+ guest_buf = guest_alloc(guest_malloc, len);
+ prdt[0].addr = cpu_to_le32(guest_buf);
+ prdt[0].size = cpu_to_le32(len | PRDT_EOT);
+
+ generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE);
+ fh = fopen(tmp_path, "w+");
+ fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh);
+ fclose(fh);
+
+ send_dma_request(CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
+
+ /* Read back data from guest memory into local qtest memory */
+ memread(guest_buf, rx, len);
+ g_assert_cmpint(memcmp(pattern, rx, len), ==, 0);
+
+ g_free(pattern);
+ g_free(rx);
+ test_bmdma_teardown();
+}
+
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
@@ -784,6 +837,7 @@ int main(int argc, char **argv)
qtest_add_func("/ide/cdrom/pio", test_cdrom_pio);
qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large);
+ qtest_add_func("/ide/cdrom/dma", test_cdrom_dma);
ret = g_test_run();
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere John Snow
@ 2015-09-10 23:47 ` Eric Blake
0 siblings, 0 replies; 7+ messages in thread
From: Eric Blake @ 2015-09-10 23:47 UTC (permalink / raw)
To: John Snow, qemu-block
Cc: kwolf, armbru, zuban32s, qemu-devel, stefanha, pbonzini
[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]
On 09/10/2015 05:09 PM, John Snow wrote:
> Fix the pattern generation to actually be interesting,
> and make sure all buffers in the ahci-test actually use it.
>
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
> tests/ahci-test.c | 23 ++++++-----------------
> 1 file changed, 6 insertions(+), 17 deletions(-)
>
> diff --git a/tests/ahci-test.c b/tests/ahci-test.c
> index 87d7691..b1a785c 100644
> --- a/tests/ahci-test.c
> +++ b/tests/ahci-test.c
> @@ -80,9 +80,9 @@ static void generate_pattern(void *buffer, size_t len, size_t cycle_len)
>
> /* Write an indicative pattern that varies and is unique per-cycle */
> p = rand() % 256;
> - for (i = j = 0; i < len; i++, j++) {
> - tx[i] = p;
> - if (j % cycle_len == 0) {
> + for (i = 0; i < len; i++) {
> + tx[i] = p++ % 256;
> + if (i % cycle_len == 0) {
> p = rand() % 256;
I'd drop the pointless %256, since the compiler already automatically
truncates int to char when assigning to a char variable.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
` (3 preceding siblings ...)
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 4/4] ide-test: add cdrom dma test John Snow
@ 2015-09-14 18:09 ` John Snow
4 siblings, 0 replies; 7+ messages in thread
From: John Snow @ 2015-09-14 18:09 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, armbru, zuban32s, qemu-devel, stefanha, pbonzini
On 09/10/2015 07:09 PM, John Snow wrote:
> We don't have any CDROM tests yet.
> So, add some for the PCI/BMDMA HBA.
>
> ===
> v2:
> ===
>
> - Some readability feedback from Markus
> - Added an IRQ poll for the DRQ read loop
>
> ________________________________________________________________________________
>
> For convenience, this branch is available at:
> https://github.com/jnsnow/qemu.git branch ide-atapi-test
> https://github.com/jnsnow/qemu/tree/ide-atapi-test
>
> This version is tagged ide-atapi-test-v2:
> https://github.com/jnsnow/qemu/releases/tag/ide-atapi-test-v2
>
> John Snow (4):
> qtest/ahci: use generate_pattern everywhere
> qtest/ahci: export generate_pattern
> ide-test: add cdrom pio test
> ide-test: add cdrom dma test
>
> tests/ahci-test.c | 43 +--------
> tests/ide-test.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++----
> tests/libqos/libqos.c | 26 ++++++
> tests/libqos/libqos.h | 1 +
> 4 files changed, 258 insertions(+), 57 deletions(-)
>
Thanks, applied to my IDE tree:
https://github.com/jnsnow/qemu/commits/ide
https://github.com/jnsnow/qemu.git
--js
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-09-14 18:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-10 23:09 [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 1/4] qtest/ahci: use generate_pattern everywhere John Snow
2015-09-10 23:47 ` [Qemu-devel] [Qemu-block] " Eric Blake
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 2/4] qtest/ahci: export generate_pattern John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 3/4] ide-test: add cdrom pio test John Snow
2015-09-10 23:09 ` [Qemu-devel] [PATCH v2 4/4] ide-test: add cdrom dma test John Snow
2015-09-14 18:09 ` [Qemu-devel] [PATCH v2 0/4] ide: simple ATAPI tests John Snow
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.