Search
lxdream.org :: lxdream/test/testide.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testide.c
changeset 248:f8022f2ef2a2
prev185:6755a04c447f
next251:3c5953d944e0
author nkeynes
date Tue Dec 19 11:53:39 2006 +0000 (16 years ago)
permissions -rw-r--r--
last change IDE system test work-in-progress
view annotate diff log raw
     1 /**
     2  * $Id: testide.c,v 1.2 2006-12-19 11:53:39 nkeynes Exp $
     3  *
     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).
     7  *
     8  * These tests should be run with the drive empty.
     9  *
    10  * Copyright (c) 2006 Nathan Keynes.
    11  *
    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.
    16  *
    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.
    21  */
    23 #include <stdlib.h>
    24 #include <stdio.h>
    25 #include "lib.h"
    26 #include "ide.h"
    27 #include "asic.h"
    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
    60  * error and return -1
    61  */
    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 ) 
    70 {
    71     int i;
    72     int rv = 0;
    73     for( i=0; regs[i] != 0; i+=2 ) {
    74 	uint32_t addr = regs[i];
    75 	uint32_t val = regs[i+1];
    76 	uint32_t actual;
    77 	if( addr == IDE_DATA ) {
    78 	    actual = (uint32_t)word_read(addr);
    79 	    if( val != actual ) { 
    80 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual ); 
    81 		rv = -1;
    82 	    }
    83 	} else if( addr <= IDE_COMMAND ) {
    84 	    actual = (uint32_t)byte_read(addr);
    85 	    if( val != actual ) { 
    86 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual ); 
    87 		rv = -1;
    88 	    }
    89 	} else {
    90 	    actual = long_read(addr);
    91 	    if( val != actual ) { 
    92 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual ); 
    93 		rv = -1;
    94 	    }
    95 	}
    96     }
    97     return rv;
    98 }
   100 #define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; }
   102 uint32_t abort_regs[] = {
   103     IDE_ALTSTATUS, 0x51,
   104     IDE_ERROR, 0x04,
   105     IDE_COUNT, 0x02,
   106     IDE_LBA0, 0x06,
   107     IDE_LBA1, 0x00,
   108     IDE_LBA2, 0x50,
   109     IDE_DEVICE, 0,
   110     IDE_DATA, 0x0000,
   111     IDE_STATUS, 0x51, 
   112     0, 0 };
   114 uint32_t post_reset_regs[] = {
   115     IDE_ALTSTATUS, 0x00,
   116     IDE_ERROR, 0x01,
   117     IDE_COUNT, 0x01,
   118     IDE_LBA0, 0x01,
   119     IDE_LBA1, 0x14,
   120     IDE_LBA2, 0xEB,
   121     IDE_DEVICE, 0,
   122     IDE_DATA, 0xFFFF,
   123     IDE_STATUS, 0x00, 
   124     0, 0 };
   126 uint32_t post_set_feature_regs[] = {
   127     IDE_ALTSTATUS, 0x50,
   128     IDE_ERROR, 0x00,
   129     IDE_COUNT, 0x0B,
   130     IDE_LBA0, 0x01,
   131     IDE_LBA1, 0x00,
   132     IDE_LBA2, 0x00,
   133     IDE_DEVICE, 0,
   134     IDE_DATA, 0xFFFF,
   135     IDE_STATUS, 0x50, 
   136     0, 0 };    
   138 uint32_t post_set_feature2_regs[] = {
   139     IDE_ALTSTATUS, 0x50,
   140     IDE_ERROR, 0x00,
   141     IDE_COUNT, 0x22,
   142     IDE_LBA0, 0x01,
   143     IDE_LBA1, 0x00,
   144     IDE_LBA2, 0x00,
   145     IDE_DEVICE, 0,
   146     IDE_DATA, 0xFFFF,
   147     IDE_STATUS, 0x50, 
   148     0, 0 };    
   150 /**
   151  * Test enable/disable of the IDE interface via port
   152  * 0x4E4. 
   153  */
   154 int test_enable()
   155 {
   156     int i;
   157     int failed = 0;
   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 ) );
   164     }
   166     /* enable interface */
   167     ide_activate();
   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 ) );
   179     }
   181     /* Finally leave the interface in an enabled state */
   182     ide_activate();
   183     return 0;
   184 }
   186 /**
   187  * Test the reset command
   188  */
   189 int test_reset()
   190 {
   191     byte_write( IDE_COMMAND, 0x08 );
   192     EXPECT_READY();
   193     CHECK_INTRQ_CLEAR();
   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 );
   200     EXPECT_READY();
   201     CHECK_INTRQ_CLEAR();
   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 );
   210     EXPECT_READY();
   211     CHECK_INTRQ_CLEAR();
   212     CHECK_REGS( post_set_feature2_regs );
   214     return 0;
   215 }
   217 uint32_t post_packet_ready_regs[] = 
   218     { IDE_ALTSTATUS, 0x58,
   219       IDE_ERROR, 0x00,
   220       IDE_COUNT, 0x01,
   221       IDE_LBA0, 0x00,
   222       IDE_LBA1, 8,
   223       IDE_LBA2, 0,
   224       IDE_DEVICE, 0,
   225       IDE_STATUS, 0x58, 0, 0 };
   227 uint32_t post_packet_cmd_regs[] = 
   228     { IDE_ALTSTATUS, 0xD0,
   229       IDE_ERROR, 0x00,
   230       IDE_COUNT, 0x01,
   231       IDE_LBA1, 8,
   232       IDE_LBA2, 0,
   233       IDE_DEVICE, 0,
   234       IDE_STATUS, 0xD0, 0, 0 };
   236 uint32_t packet_cmd_error6_regs[] = 
   237     { IDE_ALTSTATUS, 0x51,
   238       IDE_ERROR, 0x60,
   239       IDE_COUNT, 0x03,
   240       IDE_LBA1, 8,
   241       IDE_LBA2, 0,
   242       IDE_DEVICE, 0,
   243       IDE_STATUS, 0x51, 0, 0 };
   245 uint32_t packet_data_ready_regs[] = 
   246     { IDE_ALTSTATUS, 0x58,
   247       IDE_ERROR, 0x00,
   248       IDE_COUNT, 0x02,
   249       IDE_LBA0, 0x00,
   250       IDE_LBA1, 0x0C,
   251       IDE_LBA2, 0,
   252       IDE_DEVICE, 0,
   253       IDE_STATUS, 0x58, 0, 0 };
   256 uint32_t post_packet_data_regs[] = 
   257     { IDE_ALTSTATUS, 0xD0,
   258       IDE_ERROR, 0x00,
   259       IDE_COUNT, 0x02,
   260       IDE_LBA0, 0x00,
   261       IDE_LBA1, 0x0C,
   262       IDE_LBA2, 0,
   263       IDE_DEVICE, 0,
   264       IDE_STATUS, 0xD0, 0, 0 };
   266 uint32_t packet_complete_regs[] = 
   267     { IDE_ALTSTATUS, 0x50,
   268       IDE_ERROR, 0x00,
   269       IDE_COUNT, 0x03,
   270       IDE_LBA1, 0x0C,
   271       IDE_LBA2, 0,
   272       IDE_DEVICE, 0,
   273       IDE_STATUS, 0x50, 0, 0 };
   275 char expect_ident[] = { 0x00, 0xb4, 0x19, 0x00,
   276 			0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20 };
   277 /**
   278  * Test the PACKET command (using the Inquiry command)
   279  */
   280 int test_packet()
   281 {
   282     int i;
   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;
   286     char result[12];
   288     ide_print_sense_error();
   289     EXPECT_READY();
   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) */
   299     CHECK_INTRQ_CLEAR();
   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] );
   305     }
   307     byte_read(IDE_ALTSTATUS); 
   309     CHECK_REGS( post_packet_cmd_regs );
   310     EXPECT_INTRQ();
   311     EXPECT_READY();
   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 );
   323     EXPECT_READY();
   324     CHECK_INTRQ_CLEAR();
   325     CHECK_REGS( packet_complete_regs );
   326     if( memcmp( result, expect_ident, 12 ) != 0 ) {
   327 	fwrite_diff( stderr, expect_ident, 12, result, 12 );
   328     }
   329     return 0;
   330 }
   332 /**
   333  * Test the SET FEATURE command
   334  */
   335 int test_set_feature()
   336 {
   337     return 0;
   338 }
   340 /**
   341  * Test DMA transfer (using the Inquiry packet comand)
   342  */
   343 int test_dma()
   344 {
   345     return 0;
   346 }
   348 /**
   349  * Test DMA abort
   350  */
   351 int test_dma_abort()
   352 {
   353     return 0;
   354 }
   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 };
   361 int main() 
   362 {
   363     int i;
   364     ide_init();
   366     /* run tests */
   367     for( i=0; test_fns[i] != NULL; i++ ) {
   368 	test_count++;
   369 	if( test_fns[i]() != 0 ) {
   370 	    test_failures++;
   371 	}
   372     }
   374     /* report */
   375     fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count );
   376     return test_failures;
   377 }
.