2 * $Id: testide.c,v 1.2 2006-12-19 11:53:39 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.
29 unsigned int test_count = 0, test_failures = 0;
31 #define IDE_BASE 0xA05F7000
33 #define IDE_ALTSTATUS IDE_BASE+0x018
34 #define IDE_UNKNOWN IDE_BASE+0x01C
35 #define IDE_DATA IDE_BASE+0x080 /* 16 bits */
36 #define IDE_FEATURE IDE_BASE+0x084
37 #define IDE_COUNT IDE_BASE+0x088
38 #define IDE_LBA0 IDE_BASE+0x08C
39 #define IDE_LBA1 IDE_BASE+0x090
40 #define IDE_LBA2 IDE_BASE+0x094
41 #define IDE_DEVICE IDE_BASE+0x098
42 #define IDE_COMMAND IDE_BASE+0x09C
43 #define IDE_ACTIVATE IDE_BASE+0x4E4
45 #define IDE_DEVCONTROL IDE_ALTSTATUS
46 #define IDE_ERROR IDE_FEATURE
47 #define IDE_STATUS IDE_COMMAND
49 #define IDE_DMA_ADDR IDE_BASE+0x404
50 #define IDE_DMA_SIZE IDE_BASE+0x408
51 #define IDE_DMA_DIR IDE_BASE+0x40C
52 #define IDE_DMA_CTL1 IDE_BASE+0x414
53 #define IDE_DMA_CTL2 IDE_BASE+0x418
54 #define IDE_DMA_MAGIC IDE_BASE+0x4B8
55 #define IDE_DMA_STATUS IDE_BASE+0x4F8
57 #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; }
59 /* Wait for the standard timeout for an INTRQ. If none is received, print an
62 #define EXPECT_INTRQ() if( ide_wait_irq() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for INTRQ\n", __FILE__, __LINE__, __func__ ); return -1; }
64 /* Check if the INTRQ line is currently cleared (ie inactive) */
65 #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; }
67 #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; }
69 int check_regs( uint32_t *regs,const char *file, int line, const char *fn )
73 for( i=0; regs[i] != 0; i+=2 ) {
74 uint32_t addr = regs[i];
75 uint32_t val = regs[i+1];
77 if( addr == IDE_DATA ) {
78 actual = (uint32_t)word_read(addr);
80 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual );
83 } else if( addr <= IDE_COMMAND ) {
84 actual = (uint32_t)byte_read(addr);
86 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual );
90 actual = long_read(addr);
92 fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual );
100 #define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; }
102 uint32_t abort_regs[] = {
114 uint32_t post_reset_regs[] = {
126 uint32_t post_set_feature_regs[] = {
138 uint32_t post_set_feature2_regs[] = {
151 * Test enable/disable of the IDE interface via port
158 /* ensure deactivated */
159 long_write( IDE_ACTIVATE, 0x00042FE );
161 /* test registers to ensure all return 0xFF (need to wait a few cycles?) */
162 for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
163 CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
166 /* enable interface */
169 /* test registers have default settings */
170 // CHECK_REGS( post_reset_regs );
173 /* disable interface and re-test */
174 long_write( IDE_ACTIVATE, 0x00042FE );
176 /* Test registers all 0xFF */
177 for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
178 CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
181 /* Finally leave the interface in an enabled state */
187 * Test the reset command
191 byte_write( IDE_COMMAND, 0x08 );
194 CHECK_REGS( post_reset_regs );
196 /** Set Default PIO mode */
197 byte_write( IDE_FEATURE, 0x03 );
198 byte_write( IDE_COUNT, 0x0B );
199 byte_write( IDE_COMMAND, 0xEF );
202 CHECK_REGS( post_set_feature_regs );
204 /** Set Multi-word DMA mode 2 */
205 long_write( 0xA05F7490, 0x222 );
206 long_write( 0xA05F7494, 0x222 );
207 byte_write( IDE_FEATURE, 0x03 );
208 byte_write( IDE_COUNT, 0x22 );
209 byte_write( IDE_COMMAND, 0xEF );
212 CHECK_REGS( post_set_feature2_regs );
217 uint32_t post_packet_ready_regs[] =
218 { IDE_ALTSTATUS, 0x58,
225 IDE_STATUS, 0x58, 0, 0 };
227 uint32_t post_packet_cmd_regs[] =
228 { IDE_ALTSTATUS, 0xD0,
234 IDE_STATUS, 0xD0, 0, 0 };
236 uint32_t packet_cmd_error6_regs[] =
237 { IDE_ALTSTATUS, 0x51,
243 IDE_STATUS, 0x51, 0, 0 };
245 uint32_t packet_data_ready_regs[] =
246 { IDE_ALTSTATUS, 0x58,
253 IDE_STATUS, 0x58, 0, 0 };
256 uint32_t post_packet_data_regs[] =
257 { IDE_ALTSTATUS, 0xD0,
264 IDE_STATUS, 0xD0, 0, 0 };
266 uint32_t packet_complete_regs[] =
267 { IDE_ALTSTATUS, 0x50,
273 IDE_STATUS, 0x50, 0, 0 };
275 char expect_ident[] = { 0x00, 0xb4, 0x19, 0x00,
276 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20 };
278 * Test the PACKET command (using the Inquiry command)
283 char cmd[12] = { 0x11, 0, 4, 0, 12, 0, 0, 0, 0, 0, 0, 0 };
284 // char cmd[12] = { 0x00,0,0,0, 0,0,0,0, 0,0,0,0 };
285 unsigned short *spkt = (unsigned short *)cmd;
288 ide_print_sense_error();
290 byte_write( IDE_FEATURE, 0 );
291 byte_write( IDE_COUNT, 0 );
292 byte_write( IDE_LBA0, 0 );
293 byte_write( IDE_LBA1, 8 );
294 byte_write( IDE_LBA2, 0 );
295 byte_write( IDE_DEVICE, 0 );
296 byte_write( IDE_COMMAND, 0xA0 );
297 byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle */
298 EXPECT_READY(); /* Wait until device is ready to accept command (usually immediate) */
300 CHECK_REGS( post_packet_ready_regs );
302 /* Write the command */
303 for( i=0; i<6; i++ ) {
304 word_write( IDE_DATA, spkt[i] );
307 byte_read(IDE_ALTSTATUS);
309 CHECK_REGS( post_packet_cmd_regs );
312 CHECK_REGS( packet_data_ready_regs );
314 spkt = (unsigned short *)result;
315 *spkt++ = word_read(IDE_DATA);
316 *spkt++ = word_read(IDE_DATA);
317 *spkt++ = word_read(IDE_DATA);
318 *spkt++ = word_read(IDE_DATA);
319 CHECK_REGS( packet_data_ready_regs );
320 *spkt++ = word_read(IDE_DATA);
321 *spkt++ = word_read(IDE_DATA);
322 CHECK_REGS( post_packet_data_regs );
325 CHECK_REGS( packet_complete_regs );
326 if( memcmp( result, expect_ident, 12 ) != 0 ) {
327 fwrite_diff( stderr, expect_ident, 12, result, 12 );
333 * Test the SET FEATURE command
335 int test_set_feature()
341 * Test DMA transfer (using the Inquiry packet comand)
356 typedef int (*test_func_t)();
358 test_func_t test_fns[] = { test_packet, test_enable, test_reset,
359 test_dma, test_dma_abort, NULL };
367 for( i=0; test_fns[i] != NULL; i++ ) {
369 if( test_fns[i]() != 0 ) {
375 fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count );
376 return test_failures;
.