Search
lxdream.org :: lxdream/test/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/ide.c
changeset 185:6755a04c447f
next243:df1671d533bf
author nkeynes
date Sat Aug 05 00:18:21 2006 +0000 (17 years ago)
permissions -rw-r--r--
last change Add error lines to tests with incomplete polys
Split clip tests to separate data file
Add tests for cmd bit 23 ("use list size field")
view annotate diff log raw
     1 #include <assert.h>
     2 #include <stdlib.h>
     3 #include "ide.h"
     4 #include "lib.h"
     6 #define IDE_BASE 0xA05F7000
     8 #define IDE_ALTSTATUS IDE_BASE+0x018
     9 #define IDE_UNKNOWN   IDE_BASE+0x01C
    10 #define IDE_DATA      IDE_BASE+0x080 /* 16 bits */
    11 #define IDE_FEATURE   IDE_BASE+0x084
    12 #define IDE_COUNT     IDE_BASE+0x088
    13 #define IDE_LBA0      IDE_BASE+0x08C
    14 #define IDE_LBA1      IDE_BASE+0x090
    15 #define IDE_LBA2      IDE_BASE+0x094
    16 #define IDE_DEVICE    IDE_BASE+0x098
    17 #define IDE_COMMAND   IDE_BASE+0x09C
    18 #define IDE_ACTIVATE  IDE_BASE+0x4E4
    20 #define IDE_DEVCONTROL IDE_ALTSTATUS
    21 #define IDE_ERROR      IDE_FEATURE
    22 #define IDE_STATUS     IDE_COMMAND
    24 #define IDE_DMA_ADDR   IDE_BASE+0x404
    25 #define IDE_DMA_SIZE   IDE_BASE+0x408
    26 #define IDE_DMA_DIR    IDE_BASE+0x40C
    27 #define IDE_DMA_CTL1   IDE_BASE+0x414
    28 #define IDE_DMA_CTL2   IDE_BASE+0x418
    29 #define IDE_DMA_MAGIC  IDE_BASE+0x4B8
    30 #define IDE_DMA_STATUS IDE_BASE+0x4F8
    32 #define DMA_BASE 0xFFA00000
    33 #define DMA_SAR1    DMA_BASE+0x010
    34 #define DMA_DAR1    DMA_BASE+0x014
    35 #define DMA_TCR1    DMA_BASE+0x018
    36 #define DMA_CHCR1   DMA_BASE+0x01C
    37 #define DMA_SAR2    DMA_BASE+0x020
    38 #define DMA_DAR2    DMA_BASE+0x024
    39 #define DMA_TCR2    DMA_BASE+0x028
    40 #define DMA_CHCR2   DMA_BASE+0x02C
    41 #define DMA_SAR3    DMA_BASE+0x030
    42 #define DMA_DAR3    DMA_BASE+0x034
    43 #define DMA_TCR3    DMA_BASE+0x038
    44 #define DMA_CHCR3   DMA_BASE+0x03C
    45 #define DMA_DMAOR   DMA_BASE+0x040
    46 #define QUEUECR0    0xFF000038
    47 #define QUEUECR1    0xFF00003C
    49 #define IDE_CMD_RESET 0x08
    50 #define IDE_CMD_PACKET 0xA0
    51 #define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA1
    52 #define IDE_CMD_IDENTIFY_DEVICE 0xEC
    54 #define MMC_CMD_GET_CONFIGURATION 0x46
    55 #define GD_CMD_IDENTIFY 0x11 /* guessing */
    58 #define IDE_DMA_MAGIC_VALUE 0x8843407F
    61 #define MAX_WAIT     10000000
    62 #define MAX_IRQ_WAIT 1000000000
    64 /**
    65  * Dump all ide registers to stdout.
    66  */
    67 void ide_dump_registers() {
    68     int i,j;
    69     printf( "IDE registers:\n");
    70     printf( "Stats: %02X ", byte_read(IDE_ALTSTATUS) );
    71     printf( "Error: %02X ", byte_read(IDE_ERROR) );
    72     printf( "Count: %02X ", byte_read(IDE_COUNT) );
    73     printf( "Dvice: %02X ", byte_read(IDE_DEVICE) );
    74     if( long_read(ASIC_STATUS1)&1 ) {
    75 	printf( "INTRQ! " );
    76     }
    77     if( (long_read(ASIC_STATUS0)>>14)&1 ) {
    78 	printf( "DMARQ! " );
    79     }
    80     printf( "\nLBA 0: %02X ", byte_read(IDE_LBA0) );
    81     printf( "LBA 1: %02X ", byte_read(IDE_LBA1) );
    82     printf( "LBA 2: %02X ", byte_read(IDE_LBA2) );
    83     printf( "0x01C: %02X\n", byte_read(IDE_UNKNOWN) );
    84     printf( "DAddr: %08X ", long_read(IDE_DMA_ADDR) );
    85     printf( "DSize: %08X ", long_read(IDE_DMA_SIZE) );
    86     printf( "DDir : %08X ", long_read(IDE_DMA_DIR) );
    87     printf( "DCtl1: %08X ", long_read(IDE_DMA_CTL1) );
    88     printf( "DCtl2: %08X\n", long_read(IDE_DMA_CTL2) );
    89     printf( "DStat: %08X\n", long_read(IDE_DMA_STATUS) );
    90     printf( "ASIC: " );
    91     for( i=0; i<12; i+=4 ) {
    92 	unsigned int val = long_read(ASIC_STATUS0+i);
    93 	for( j=0; j<32; j++ ) {
    94 	    if( val & (1<<j) ) {
    95 		printf( "%d ", j );
    96 	    }
    97 	}
    98 	printf( "| " );
    99     }
   100     printf( "\n" );
   101 }
   103 /**
   104  * Wait for the IDE INTRQ line to go active (bit 0 of the second word)
   105  * @return 0 on success, non-zero on timeout
   106  */
   107 int ide_wait_irq() {
   108     unsigned int status;
   109     int i;
   110     for( i=0; i<MAX_WAIT; i++ ) {
   111 	status = long_read( ASIC_STATUS1 );
   112 	if( (status&1) != 0 )
   113 	    return 0;
   114     }
   115     printf( "Timeout waiting for IDE INTRQ\n" );
   116     ide_dump_registers();
   117     return 1;
   118 }
   120 /**
   121  * Wait for the IDE BSY flag to be de-asserted.
   122  * @return 0 on success, non-zero on timeout
   123  */
   124 int ide_wait_ready() {
   125     unsigned char status;
   126     int i;
   127     for( i=0; i<MAX_WAIT; i++ ) {
   128         status = byte_read(IDE_ALTSTATUS);
   129 	if( (status & 0x80) != 0x80 )
   130 	    return 0;
   131     }
   132     printf( "Timeout waiting for IDE to become ready\n" );
   133     ide_dump_registers();
   134     return 1;
   135 }
   137 int ide_wait_dma() {
   138     unsigned int status;
   139     int i;
   140     for( i=0; i<MAX_WAIT; i++ ) {
   141 	status = long_read(IDE_DMA_CTL2);
   142 	if( (status & 1) == 0 )
   143 	    return 0;
   144     }
   145     printf( "[IDE] Timeout waiting for DMA to become ready\n" );
   146     return 1;
   147 }
   149 /**
   150  * Write the command packet out to the interface.
   151  * @param cmd 12 byte ATAPI command packet
   152  * @param dma 1 = dma mode, 0 = pio mode
   153  */
   154 int ide_write_command_packet( char *cmd, int dma ) 
   155 {
   156     int i, status;
   157     unsigned short *spkt = (unsigned short *)cmd;
   158     unsigned short length = 8;
   159     if( ide_wait_ready() )
   160 	return 1;
   161     byte_write( IDE_FEATURE, dma );
   162     byte_write( IDE_COUNT, 0 );
   163     byte_write( IDE_LBA0, 0 );
   164     byte_write( IDE_LBA1, (length&0xFF) );
   165     byte_write( IDE_LBA2, (length>>8)&0xFF );
   166     byte_write( IDE_DEVICE, 0 );
   167     byte_write( IDE_COMMAND, IDE_CMD_PACKET );
   168     status = byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle as per spec */
   169     printf( "After writing PACKET command byte:\n" );
   170     ide_dump_registers();
   171     /* Wait until device is ready to accept command */
   172     if( ide_wait_ready() )
   173 	return 1;
   174     printf( "Device ready to receive packet:\n" );
   175     ide_dump_registers();
   177     /* Write the command */
   178     for( i=0; i<6; i++ ) {
   179         word_write( IDE_DATA, spkt[i] );
   180     }
   181     printf( "After writing command packet:\n" );
   182     ide_dump_registers();
   183 }
   185 int ide_read_pio( char *buf, int buflen ) {
   186     int i;
   187     unsigned short *bufptr = (unsigned short *)buf;
   188     unsigned int length = 0, avail;
   189     int status;
   191     while(1) {
   192 	if( ide_wait_ready() )
   193 	    return -1;
   194 	status = byte_read( IDE_STATUS );
   195 	if( (status & 0xE9) == 0x48 ) {
   196 	    /* Bytes available */
   197 	    avail = (byte_read( IDE_LBA1 )) | (byte_read(IDE_LBA2)<<8);
   198 	    for( i=0; i<avail; i+=2 ) {
   199 		if( buflen > 0 ) {
   200 		    *bufptr++ = word_read(IDE_DATA);
   201 		    buflen-=2;
   202 		}
   203 	    }
   204 	    length += avail;
   205 	    if( avail == 0 ) {
   206 		/* Should never happen */
   207 		printf( "[IDE] Unexpected read length 0\n" );
   208 		return -1;
   209 	    }
   210 	} else {
   211 	    if( status&0x01 ) {
   212 		printf( "[IDE] ERROR! (%02X)\n", status );
   213 	    } else if( (status&0x08) == 0 ) {
   214 		/* No more data */
   215 		return length;
   216 	    } else {
   217 		printf( "[IDE] Unexpected status result: %02X\n", status );
   218 		return -1;
   219 	    }
   220 	}
   221     }
   222 }
   224 int ide_read_dma( char *buf, int buflen ) 
   225 {
   226     int status;
   228     long_write( IDE_DMA_CTL1, 1 );
   229     long_write( IDE_DMA_CTL2, 1 );
   231     printf( "Started DMA\n" );
   232     ide_dump_registers();
   234     ide_wait_irq();
   235     printf( "After IRQ\n" );
   236     ide_dump_registers();
   237     long_write( IDE_DMA_CTL1, 0 );
   238     status = ide_wait_dma();
   239     printf( "After DMA finished\n");
   240     ide_dump_registers();
   241     if( status != 0 ) {
   242 	return -1;
   243     }
   244     status = long_read(ASIC_STATUS0);
   245     if( (status & (1<<14)) == 0 ) {
   246 	printf( "DMARQ cleared already\n");
   247     } else {
   248 	/*
   249 	status &= ~(1<<14);
   250 	long_write(ASIC_STATUS0, status);
   251 	status = long_read(ASIC_STATUS0);
   252 	*/
   253 	byte_read(IDE_STATUS );
   254 	if( (status & (1<<14)) == 0 ) {
   255 	    printf( "DMARQ cleared successfully\n" );
   256 	} else {
   257 	    printf( "DMARQ not cleared: %08X\n", long_read(ASIC_STATUS0) );
   258 	}
   259     }
   260     status = ide_wait_ready();
   261     printf( "After IDE ready\n");
   262     ide_dump_registers();
   263     if( status != 0 ) {
   264 	return -1;
   265     }
   266     return long_read( IDE_DMA_STATUS );
   267 }
   269 int ide_do_packet_command_pio( char *cmd, char *buf, int length ) 
   270 {
   271     ide_write_command_packet( cmd, 0 );
   272     length = ide_read_pio( buf, length );
   273     return length;
   274 }
   276 int ide_do_packet_command_dma( char *cmd, char *buf, int length )
   277 {
   278     long_write( QUEUECR0, 0x10 );
   279     long_write( QUEUECR1, 0x10 );
   280     long_write( IDE_DMA_MAGIC, IDE_DMA_MAGIC_VALUE );
   281     long_write( IDE_DMA_ADDR, (unsigned int)buf );
   282     long_write( IDE_DMA_SIZE, length );
   283     long_write( IDE_DMA_DIR, 1 );
   284     ide_write_command_packet( cmd, 1 );
   285     length = ide_read_dma( buf, length );
   286     return length;
   287 }
   289 int ide_init()
   290 {
   291     if( ide_wait_ready() )
   292 	return -1;
   294     /** Set Default PIO mode */
   295     byte_write( IDE_FEATURE, 0x03 );
   296     byte_write( IDE_COUNT, 0x0B );
   297     byte_write( IDE_COMMAND, 0xEF );
   299     if( ide_wait_ready() )
   300 	return -1;
   302     /** Set Multi-word DMA mode 2 */
   303     long_write( 0xA05F7490, 0x222 );
   304     long_write( 0xA05F7494, 0x222 );
   305     byte_write( IDE_FEATURE, 0x03 );
   306     byte_write( IDE_COUNT, 0x22 );
   307     byte_write( IDE_COMMAND, 0xEF );
   308     if( ide_wait_ready() )
   309 	return -1;
   311     word_write( 0xA05F7480, 0x400 );
   312     long_write( 0xA05F7488, 0x200 );
   313     long_write( 0xA05F748C, 0x200 );
   314     long_write( 0xA05F74A0, 0x2001 );
   315     long_write( 0xA05F74A4, 0x2001 );
   316     long_write( 0xA05F74B4, 0x0001 );
   317 }
   319 int ide_sense_error( char *buf ) 
   320 {
   321     char cmd[12] = { 0x13,0,0,0, 10,0,0,0, 0,0,0,0 };
   322     return ide_do_packet_command_pio( cmd, buf, 10 );
   323 }
   325 void ide_print_sense_error()
   326 {
   327     char buf[10];
   328     if( ide_sense_error(buf) != 10 ) {
   329 	printf( "ERROR - Sense error failed!\n" );
   330 	return;
   331     }
   332     int major = buf[2] & 0xFF;
   333     int minor = buf[8] & 0xFF;
   334     printf( "[IDE] Error code %02X,%02X\n", major, minor );
   335 }
   337 int ide_test_ready()
   338 {
   339     char cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };
   340     int length = ide_do_packet_command_pio( cmd, NULL, 0 );
   341     return length;
   342 }
   344 int ide_read_toc( char *buf, int length ) 
   345 {
   346     char cmd[12] = { 0x14,0,0,0, 0x98,0,0,0, 0,0,0,0 };
   347     return ide_do_packet_command_pio( cmd, buf, length );
   348 }
   350 int ide_get_session( int session, struct gdrom_session *session_data )
   351 {
   352     char cmd[12] = {0x15, 0, session, 0, 6,0,0,0, 0,0,0,0 };
   353     char buf[6];
   354     int length = ide_do_packet_command_pio( cmd, buf, sizeof(buf) );
   355     if( length < 0 )
   356 	return length;
   357     if( length != 6 )
   358 	return -1;
   359     assert(length == 6);
   360     session_data->track = ((int)buf[2])&0xFF;
   361     session_data->lba = (((int)buf[3])&0xFF) << 16 | 
   362 	(((int)buf[4])&0xFF) << 8 | 
   363 	(((int)buf[5])&0xFF);
   364     return 0;
   365 }
   367 int ide_spinup( )
   368 {
   369     char cmd[12] = {0x70,0x1F,0,0, 0,0,0,0, 0,0,0,0};
   370     int length = ide_do_packet_command_pio( cmd, NULL, 0 );
   371     return length;
   372 }
   374 int ide_unknown71( char *buf, int length )
   375 {
   376     char cmd[12] = {0x71,0,0,0, 0,0,0,0, 0,0,0,0};
   377     return ide_do_packet_command_pio( cmd, buf, length );
   378 }
   380 int ide_read_sector_pio( uint32_t sector, uint32_t count, int mode,
   381 			 char *buf, int length )
   382 {
   383     char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };
   385     cmd[1] = mode;
   386     cmd[2] = (sector>>16)&0xFF;
   387     cmd[3] = (sector>>8)&0xFF;
   388     cmd[4] = sector&0xFF;
   389     cmd[8] = (count>>16)&0xFF;
   390     cmd[9] = (count>>8)&0xFF;
   391     cmd[10] = count&0xFF;
   392     return ide_do_packet_command_pio( cmd, buf, length );
   393 }
   396 int ide_read_sector_dma( uint32_t sector, uint32_t count, int mode,
   397 			 char *buf, int length )
   398 {
   399     char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };
   401     cmd[1] = mode;
   402     cmd[2] = (sector>>16)&0xFF;
   403     cmd[3] = (sector>>8)&0xFF;
   404     cmd[4] = sector&0xFF;
   405     cmd[8] = (count>>16)&0xFF;
   406     cmd[9] = (count>>8)&0xFF;
   407     cmd[10] = count&0xFF;
   408     return ide_do_packet_command_dma( cmd, buf, length );
   409 }
   411 int ide_read_something( )
   412 {
   413     char cmd[12] = { 0x12,0,0,0, 0x0a,0,0,0, 0,0,0,0 };
   414     char result[10];
   415     ide_do_packet_command_pio( cmd, result, 10 );
   416     debug_dump_buffer(result,10);
   417     return 0;
.