2 * $Id: testide.c,v 1.6 2007-01-03 09:05:13 nkeynes Exp $
4 * IDE interface test cases. Covers all (known) IDE registers in the
5 * 5F7000 - 5F74FF range including DMA, but does not cover any GD-Rom
6 * device behaviour (ie packet comands).
8 * These tests should be run with the drive empty.
10 * Copyright (c) 2006 Nathan Keynes.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
30 unsigned int test_count = 0, test_failures = 0;
32 #define IDE_BASE 0xA05F7000
34 #define IDE_ALTSTATUS IDE_BASE+0x018
35 #define IDE_UNKNOWN IDE_BASE+0x01C
36 #define IDE_DATA IDE_BASE+0x080 /* 16 bits */
37 #define IDE_FEATURE IDE_BASE+0x084
38 #define IDE_COUNT IDE_BASE+0x088
39 #define IDE_LBA0 IDE_BASE+0x08C
40 #define IDE_LBA1 IDE_BASE+0x090
41 #define IDE_LBA2 IDE_BASE+0x094
42 #define IDE_DEVICE IDE_BASE+0x098
43 #define IDE_COMMAND IDE_BASE+0x09C
44 #define IDE_ACTIVATE IDE_BASE+0x4E4
46 #define IDE_DISC IDE_LBA0
47 #define IDE_DEVCONTROL IDE_ALTSTATUS
48 #define IDE_ERROR IDE_FEATURE
49 #define IDE_STATUS IDE_COMMAND
51 #define IDE_DMA_ADDR IDE_BASE+0x404
52 #define IDE_DMA_SIZE IDE_BASE+0x408
53 #define IDE_DMA_DIR IDE_BASE+0x40C
54 #define IDE_DMA_CTL1 IDE_BASE+0x414
55 #define IDE_DMA_CTL2 IDE_BASE+0x418
56 #define IDE_DMA_MAGIC IDE_BASE+0x4B8
57 #define IDE_DMA_STATUS IDE_BASE+0x4F8
59 #define CHECK_REG_EQUALS( a, b, c ) if( b != c ) { fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", __FILE__, __LINE__, __func__, b, a, c ); return -1; }
61 /* Wait for the standard timeout for an INTRQ. If none is received, print an
64 #define EXPECT_INTRQ() if( ide_wait_irq() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for INTRQ\n", __FILE__, __LINE__, __func__ ); return -1; }
66 /* Check if the INTRQ line is currently cleared (ie inactive) */
67 #define CHECK_INTRQ_CLEAR() if ( (long_read( ASIC_STATUS1 ) & 1) != 0 ) { fprintf(stderr, "Assertion failed at %s:%d %s(): expected INTRQ to be cleared, but was raised.\n", __FILE__, __LINE__, __func__ ); return -1; }
69 #define EXPECT_READY() if( ide_wait_ready() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for BSY flag to clear\n", __FILE__, __LINE__, __func__ ); return -1; }
71 int check_regs( uint32_t *regs,const char *file, int line, const char *fn )
75 for( i=0; regs[i] != 0; i+=2 ) {
76 uint32_t addr = regs[i];
77 uint32_t val = regs[i+1];
79 if( addr == IDE_DATA ) {
80 actual = (uint32_t)word_read(addr);
82 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual );
85 } else if( addr <= IDE_COMMAND ) {
86 actual = (uint32_t)byte_read(addr);
88 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual );
92 actual = long_read(addr);
94 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual );
102 #define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; }
105 uint32_t post_packet_ready_regs[] =
106 { IDE_ALTSTATUS, 0x58,
111 IDE_STATUS, 0x58, 0, 0 };
113 uint32_t post_packet_cmd_regs[] =
114 { IDE_ALTSTATUS, 0xD0,
120 IDE_STATUS, 0xD0, 0, 0 };
122 uint32_t packet_cmd_error6_regs[] =
123 { IDE_ALTSTATUS, 0x51,
129 IDE_STATUS, 0x51, 0, 0 };
131 uint32_t packet_data_ready_regs[] =
132 { IDE_ALTSTATUS, 0x58,
138 IDE_STATUS, 0x58, 0, 0 };
141 uint32_t post_packet_data_regs[] =
142 { IDE_ALTSTATUS, 0xD0,
148 IDE_STATUS, 0xD0, 0, 0 };
150 uint32_t packet_complete_regs[] =
151 { IDE_ALTSTATUS, 0x50,
157 IDE_STATUS, 0x50, 0, 0 };
159 int send_packet_command( const char *cmd )
161 unsigned short *spkt = (unsigned short *)cmd;
165 byte_write( IDE_FEATURE, 0 );
166 byte_write( IDE_COUNT, 0 );
167 byte_write( IDE_LBA0, 0 );
168 byte_write( IDE_LBA1, 8 );
169 byte_write( IDE_LBA2, 0 );
170 byte_write( IDE_DEVICE, 0 );
171 byte_write( IDE_COMMAND, 0xA0 );
172 byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle */
173 EXPECT_READY(); /* Wait until device is ready to accept command (usually immediate) */
175 CHECK_REGS( post_packet_ready_regs );
177 /* Write the command */
178 for( i=0; i<6; i++ ) {
179 word_write( IDE_DATA, spkt[i] );
182 byte_read(IDE_ALTSTATUS);
184 // CHECK_REGS( post_packet_cmd_regs );
190 int read_pio( char *buf, int expected_length ) {
191 uint32_t ready_regs[] = {
195 IDE_LBA1, expected_length & 0xFF,
196 IDE_LBA2, (expected_length >> 8),
202 unsigned short *bufptr = (unsigned short *)buf;
203 unsigned int length = 0, avail;
206 CHECK_REGS( ready_regs );
207 for( i=0; i<expected_length; i+=2 ) {
208 *bufptr++ = word_read(IDE_DATA);
213 ready_regs[1] = 0x50;
214 ready_regs[5] = 0x03;
215 ready_regs[13] = 0x50;
216 CHECK_REGS( ready_regs );
220 #define IDE_TEST_PACKET_OK( c,e,l ) if( ide_test_packet_ok( __FILE__, __LINE__, __func__, c, e, l ) != 0 ) { return -1; }
221 int ide_test_packet_ok( const char *file, int line, const char *func,
222 const char *cmd, char *expect, int expect_len )
224 char buf[expect_len];
225 int status = send_packet_command(cmd);
229 status = byte_read( IDE_ALTSTATUS );
230 if( status & 1 ) { /* Error */
231 status = ide_get_sense_code();
232 fprintf( stderr, "Assertion failed at %s:%d %s(): Unexpected error %04X\n",
233 file, line, func, status );
237 status = read_pio( buf, expect_len );
241 if( expect != NULL && memcmp( expect, buf, expect_len ) != 0 ) {
242 fprintf(stderr, "Assertion failed at %s:%d %s(): Results differ from expected:\n",file,line,func );
243 fwrite_diff( stderr, expect, expect_len, buf, expect_len );
249 #define IDE_TEST_PACKET_ERROR( c,e ) if( ide_test_packet_error( __FILE__, __LINE__, __func__, c, e ) != 0 ) { return -1; }
250 int ide_test_packet_error( char *file, int line, char *func,
251 char *cmd, int expect_error )
253 uint32_t error_regs[] =
254 { IDE_ALTSTATUS, 0x51,
255 IDE_ERROR, (expect_error & 0x0F)<<4,
258 IDE_STATUS, 0x51, 0, 0 };
260 int status = send_packet_command(cmd);
264 CHECK_REGS(error_regs);
265 error_code = ide_get_sense_code();
266 CHECK_IEQUALS( expect_error, error_code );
272 uint32_t abort_regs[] = {
283 uint32_t post_reset_regs[] = {
294 uint32_t post_set_feature_regs[] = {
305 uint32_t post_set_feature2_regs[] = {
316 /************************** Interface Tests *******************************/
319 * Test enable/disable of the IDE interface via port
326 /* ensure deactivated */
327 long_write( IDE_ACTIVATE, 0x00042FE );
329 /* test registers to ensure all return 0xFF (need to wait a few cycles?) */
330 for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
331 CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
334 /* enable interface */
337 /* test registers have default settings */
338 // CHECK_REGS( post_reset_regs );
341 /* disable interface and re-test */
342 long_write( IDE_ACTIVATE, 0x00042FE );
344 /* Test registers all 0xFF */
345 for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
346 CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
349 /* Finally leave the interface in an enabled state */
355 uint32_t drive_ready_regs[] = {
367 * Test the reset command
371 byte_write( IDE_COMMAND, 0x08 );
374 CHECK_REGS( post_reset_regs );
376 /** Set Default PIO mode */
377 byte_write( IDE_FEATURE, 0x03 );
378 byte_write( IDE_COUNT, 0x0B );
379 byte_write( IDE_COMMAND, 0xEF );
381 CHECK_REGS( post_set_feature_regs );
383 /** Set Multi-word DMA mode 2 */
384 long_write( 0xA05F7490, 0x222 );
385 long_write( 0xA05F7494, 0x222 );
386 byte_write( IDE_FEATURE, 0x03 );
387 byte_write( IDE_COUNT, 0x22 );
388 byte_write( IDE_COMMAND, 0xEF );
391 CHECK_REGS( post_set_feature2_regs );
393 char test_ready_cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };
394 if( send_packet_command(test_ready_cmd) != 0 ) {
398 CHECK_REGS( packet_cmd_error6_regs );
399 int sense = ide_get_sense_code();
400 CHECK_IEQUALS( 0x2906, sense );
402 if( send_packet_command(test_ready_cmd) != 0 ) {
405 CHECK_REGS( drive_ready_regs );
409 char expect_ident[] = { 0x00, 0xb4, 0x19, 0x00,
410 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20 };
413 * Test the PACKET command (using the Inquiry command)
418 char cmd[12] = { 0x11, 0, 4, 0, 12, 0, 0, 0, 0, 0, 0, 0 };
419 // char cmd[12] = { 0x00,0,0,0, 0,0,0,0, 0,0,0,0 };
420 unsigned short *spkt;
423 send_packet_command( cmd );
424 CHECK_REGS( packet_data_ready_regs );
425 spkt = (unsigned short *)result;
426 *spkt++ = word_read(IDE_DATA);
427 *spkt++ = word_read(IDE_DATA);
428 *spkt++ = word_read(IDE_DATA);
429 *spkt++ = word_read(IDE_DATA);
430 CHECK_REGS( packet_data_ready_regs );
431 *spkt++ = word_read(IDE_DATA);
432 *spkt++ = word_read(IDE_DATA);
433 // CHECK_REGS( post_packet_data_regs );
436 CHECK_REGS( packet_complete_regs );
438 if( memcmp( result, expect_ident, 12 ) != 0 ) {
439 fwrite_diff( stderr, expect_ident, 12, result, 12 );
446 * Test the SET FEATURE command
448 int test_set_feature()
456 * Test DMA transfer (using the Inquiry packet comand)
471 /***************************** GD-Rom Tests **********************************/
475 char cmd[12] = { 0x14,0,0,0x00, 0x0C,0,0,0, 0,0,0,0 };
476 char expect[12] = { 0x41, 0,0, 0x96, 0x41, 0, 0x2E, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF };
478 IDE_TEST_PACKET_OK( cmd, expect, 12 );
485 char cmd[12] = {0x30, 0x28, 0, 0x2E, 0x4C, 0, 0, 0, 0, 0, 7, 0 };
486 uint32_t read_pio_ready_regs[] =
487 { IDE_ALTSTATUS, 0x58,
493 IDE_STATUS, 0x58, 0, 0 };
495 if( send_packet_command(cmd) != 0 ) {
499 for( j=0; j<7; j++ ) {
500 CHECK_REGS(read_pio_ready_regs);
502 for( i=0; i<0x0800; i+=2 ) {
503 word_read(IDE_DATA); // throw away for now.
510 read_pio_ready_regs[1] = 0x50;
511 read_pio_ready_regs[5] = 0x03;
512 read_pio_ready_regs[13] = 0x50;
513 CHECK_REGS( read_pio_ready_regs );
518 * Test interaction of Read CD (0x30) with Status (0x40,1)
522 char cmd[12] = { 0x40, 0x01, 0, 0, 16,0,0,0, 0,0,0,0 };
523 char read1cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4C, 0, 0, 0, 0, 0,1,0 };
524 char expect1[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,1,0,0, 0x2E,0x4D,0,0 };
525 char read2cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4D, 0, 0, 0, 0, 0,1,0 };
526 char expect2[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,4,0,0, 0x2E,0x50,0,0 };
527 char read3cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4E, 0, 0, 0, 0, 0,1,0 };
528 char expect3[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,5,0,0, 0x2E,0x51,0,0 };
529 char expect4[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,2,0,0, 0x2E,0x4E,0,0 };
530 char read5cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x01, 0, 0, 0, 0, 0,1,0 };
531 char expect5[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,0xB6,0,0, 0x2F,0x02,0,0 };
532 char read6cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x50, 0, 0, 0, 0, 0,1,0 };
533 char expect6[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x05,0,0, 0x2F,0x51,0,0 };
534 char read7cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x51, 0, 0, 0, 0, 0,1,0 };
535 char expect7[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x06,0,0, 0x2F,0x52,0,0 };
538 IDE_TEST_PACKET_OK(read1cmd, NULL, 2048);
539 IDE_TEST_PACKET_OK(cmd, expect1, 14 );
540 IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
541 IDE_TEST_PACKET_OK(cmd, expect2, 14 );
542 IDE_TEST_PACKET_OK(read3cmd, NULL, 2048);
543 IDE_TEST_PACKET_OK(cmd, expect3, 14 );
544 IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
545 IDE_TEST_PACKET_OK(cmd, expect4, 14 );
546 IDE_TEST_PACKET_OK(read5cmd, NULL, 2048);
547 IDE_TEST_PACKET_OK(cmd, expect5, 14 );
548 IDE_TEST_PACKET_OK(read6cmd, NULL, 2048);
549 IDE_TEST_PACKET_OK(cmd, expect6, 14 );
554 /********************************* Main **************************************/
556 test_func_t test_fns[] = { test_enable, test_reset, test_packet,
557 test_dma, test_dma_abort, test_read_pio,
559 test_status1, NULL };
565 return run_tests( test_fns );
.