filename | test/ide.c |
changeset | 185:6755a04c447f |
next | 243:df1671d533bf |
author | nkeynes |
date | Wed Sep 27 10:21:34 2006 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Add user mode/system mode switch Add undefined instruction tests |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/test/ide.c Wed Sep 27 10:21:34 2006 +00001.3 @@ -0,0 +1,418 @@1.4 +#include <assert.h>1.5 +#include <stdlib.h>1.6 +#include "ide.h"1.7 +#include "lib.h"1.8 +1.9 +#define IDE_BASE 0xA05F70001.10 +1.11 +#define IDE_ALTSTATUS IDE_BASE+0x0181.12 +#define IDE_UNKNOWN IDE_BASE+0x01C1.13 +#define IDE_DATA IDE_BASE+0x080 /* 16 bits */1.14 +#define IDE_FEATURE IDE_BASE+0x0841.15 +#define IDE_COUNT IDE_BASE+0x0881.16 +#define IDE_LBA0 IDE_BASE+0x08C1.17 +#define IDE_LBA1 IDE_BASE+0x0901.18 +#define IDE_LBA2 IDE_BASE+0x0941.19 +#define IDE_DEVICE IDE_BASE+0x0981.20 +#define IDE_COMMAND IDE_BASE+0x09C1.21 +#define IDE_ACTIVATE IDE_BASE+0x4E41.22 +1.23 +#define IDE_DEVCONTROL IDE_ALTSTATUS1.24 +#define IDE_ERROR IDE_FEATURE1.25 +#define IDE_STATUS IDE_COMMAND1.26 +1.27 +#define IDE_DMA_ADDR IDE_BASE+0x4041.28 +#define IDE_DMA_SIZE IDE_BASE+0x4081.29 +#define IDE_DMA_DIR IDE_BASE+0x40C1.30 +#define IDE_DMA_CTL1 IDE_BASE+0x4141.31 +#define IDE_DMA_CTL2 IDE_BASE+0x4181.32 +#define IDE_DMA_MAGIC IDE_BASE+0x4B81.33 +#define IDE_DMA_STATUS IDE_BASE+0x4F81.34 +1.35 +#define DMA_BASE 0xFFA000001.36 +#define DMA_SAR1 DMA_BASE+0x0101.37 +#define DMA_DAR1 DMA_BASE+0x0141.38 +#define DMA_TCR1 DMA_BASE+0x0181.39 +#define DMA_CHCR1 DMA_BASE+0x01C1.40 +#define DMA_SAR2 DMA_BASE+0x0201.41 +#define DMA_DAR2 DMA_BASE+0x0241.42 +#define DMA_TCR2 DMA_BASE+0x0281.43 +#define DMA_CHCR2 DMA_BASE+0x02C1.44 +#define DMA_SAR3 DMA_BASE+0x0301.45 +#define DMA_DAR3 DMA_BASE+0x0341.46 +#define DMA_TCR3 DMA_BASE+0x0381.47 +#define DMA_CHCR3 DMA_BASE+0x03C1.48 +#define DMA_DMAOR DMA_BASE+0x0401.49 +#define QUEUECR0 0xFF0000381.50 +#define QUEUECR1 0xFF00003C1.51 +1.52 +#define IDE_CMD_RESET 0x081.53 +#define IDE_CMD_PACKET 0xA01.54 +#define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA11.55 +#define IDE_CMD_IDENTIFY_DEVICE 0xEC1.56 +1.57 +#define MMC_CMD_GET_CONFIGURATION 0x461.58 +#define GD_CMD_IDENTIFY 0x11 /* guessing */1.59 +1.60 +1.61 +#define IDE_DMA_MAGIC_VALUE 0x8843407F1.62 +1.63 +1.64 +#define MAX_WAIT 100000001.65 +#define MAX_IRQ_WAIT 10000000001.66 +1.67 +/**1.68 + * Dump all ide registers to stdout.1.69 + */1.70 +void ide_dump_registers() {1.71 + int i,j;1.72 + printf( "IDE registers:\n");1.73 + printf( "Stats: %02X ", byte_read(IDE_ALTSTATUS) );1.74 + printf( "Error: %02X ", byte_read(IDE_ERROR) );1.75 + printf( "Count: %02X ", byte_read(IDE_COUNT) );1.76 + printf( "Dvice: %02X ", byte_read(IDE_DEVICE) );1.77 + if( long_read(ASIC_STATUS1)&1 ) {1.78 + printf( "INTRQ! " );1.79 + }1.80 + if( (long_read(ASIC_STATUS0)>>14)&1 ) {1.81 + printf( "DMARQ! " );1.82 + }1.83 + printf( "\nLBA 0: %02X ", byte_read(IDE_LBA0) );1.84 + printf( "LBA 1: %02X ", byte_read(IDE_LBA1) );1.85 + printf( "LBA 2: %02X ", byte_read(IDE_LBA2) );1.86 + printf( "0x01C: %02X\n", byte_read(IDE_UNKNOWN) );1.87 + printf( "DAddr: %08X ", long_read(IDE_DMA_ADDR) );1.88 + printf( "DSize: %08X ", long_read(IDE_DMA_SIZE) );1.89 + printf( "DDir : %08X ", long_read(IDE_DMA_DIR) );1.90 + printf( "DCtl1: %08X ", long_read(IDE_DMA_CTL1) );1.91 + printf( "DCtl2: %08X\n", long_read(IDE_DMA_CTL2) );1.92 + printf( "DStat: %08X\n", long_read(IDE_DMA_STATUS) );1.93 + printf( "ASIC: " );1.94 + for( i=0; i<12; i+=4 ) {1.95 + unsigned int val = long_read(ASIC_STATUS0+i);1.96 + for( j=0; j<32; j++ ) {1.97 + if( val & (1<<j) ) {1.98 + printf( "%d ", j );1.99 + }1.100 + }1.101 + printf( "| " );1.102 + }1.103 + printf( "\n" );1.104 +}1.105 +1.106 +/**1.107 + * Wait for the IDE INTRQ line to go active (bit 0 of the second word)1.108 + * @return 0 on success, non-zero on timeout1.109 + */1.110 +int ide_wait_irq() {1.111 + unsigned int status;1.112 + int i;1.113 + for( i=0; i<MAX_WAIT; i++ ) {1.114 + status = long_read( ASIC_STATUS1 );1.115 + if( (status&1) != 0 )1.116 + return 0;1.117 + }1.118 + printf( "Timeout waiting for IDE INTRQ\n" );1.119 + ide_dump_registers();1.120 + return 1;1.121 +}1.122 +1.123 +/**1.124 + * Wait for the IDE BSY flag to be de-asserted.1.125 + * @return 0 on success, non-zero on timeout1.126 + */1.127 +int ide_wait_ready() {1.128 + unsigned char status;1.129 + int i;1.130 + for( i=0; i<MAX_WAIT; i++ ) {1.131 + status = byte_read(IDE_ALTSTATUS);1.132 + if( (status & 0x80) != 0x80 )1.133 + return 0;1.134 + }1.135 + printf( "Timeout waiting for IDE to become ready\n" );1.136 + ide_dump_registers();1.137 + return 1;1.138 +}1.139 +1.140 +int ide_wait_dma() {1.141 + unsigned int status;1.142 + int i;1.143 + for( i=0; i<MAX_WAIT; i++ ) {1.144 + status = long_read(IDE_DMA_CTL2);1.145 + if( (status & 1) == 0 )1.146 + return 0;1.147 + }1.148 + printf( "[IDE] Timeout waiting for DMA to become ready\n" );1.149 + return 1;1.150 +}1.151 +1.152 +/**1.153 + * Write the command packet out to the interface.1.154 + * @param cmd 12 byte ATAPI command packet1.155 + * @param dma 1 = dma mode, 0 = pio mode1.156 + */1.157 +int ide_write_command_packet( char *cmd, int dma )1.158 +{1.159 + int i, status;1.160 + unsigned short *spkt = (unsigned short *)cmd;1.161 + unsigned short length = 8;1.162 + if( ide_wait_ready() )1.163 + return 1;1.164 + byte_write( IDE_FEATURE, dma );1.165 + byte_write( IDE_COUNT, 0 );1.166 + byte_write( IDE_LBA0, 0 );1.167 + byte_write( IDE_LBA1, (length&0xFF) );1.168 + byte_write( IDE_LBA2, (length>>8)&0xFF );1.169 + byte_write( IDE_DEVICE, 0 );1.170 + byte_write( IDE_COMMAND, IDE_CMD_PACKET );1.171 + status = byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle as per spec */1.172 + printf( "After writing PACKET command byte:\n" );1.173 + ide_dump_registers();1.174 + /* Wait until device is ready to accept command */1.175 + if( ide_wait_ready() )1.176 + return 1;1.177 + printf( "Device ready to receive packet:\n" );1.178 + ide_dump_registers();1.179 +1.180 + /* Write the command */1.181 + for( i=0; i<6; i++ ) {1.182 + word_write( IDE_DATA, spkt[i] );1.183 + }1.184 + printf( "After writing command packet:\n" );1.185 + ide_dump_registers();1.186 +}1.187 +1.188 +int ide_read_pio( char *buf, int buflen ) {1.189 + int i;1.190 + unsigned short *bufptr = (unsigned short *)buf;1.191 + unsigned int length = 0, avail;1.192 + int status;1.193 +1.194 + while(1) {1.195 + if( ide_wait_ready() )1.196 + return -1;1.197 + status = byte_read( IDE_STATUS );1.198 + if( (status & 0xE9) == 0x48 ) {1.199 + /* Bytes available */1.200 + avail = (byte_read( IDE_LBA1 )) | (byte_read(IDE_LBA2)<<8);1.201 + for( i=0; i<avail; i+=2 ) {1.202 + if( buflen > 0 ) {1.203 + *bufptr++ = word_read(IDE_DATA);1.204 + buflen-=2;1.205 + }1.206 + }1.207 + length += avail;1.208 + if( avail == 0 ) {1.209 + /* Should never happen */1.210 + printf( "[IDE] Unexpected read length 0\n" );1.211 + return -1;1.212 + }1.213 + } else {1.214 + if( status&0x01 ) {1.215 + printf( "[IDE] ERROR! (%02X)\n", status );1.216 + } else if( (status&0x08) == 0 ) {1.217 + /* No more data */1.218 + return length;1.219 + } else {1.220 + printf( "[IDE] Unexpected status result: %02X\n", status );1.221 + return -1;1.222 + }1.223 + }1.224 + }1.225 +}1.226 +1.227 +int ide_read_dma( char *buf, int buflen )1.228 +{1.229 + int status;1.230 +1.231 + long_write( IDE_DMA_CTL1, 1 );1.232 + long_write( IDE_DMA_CTL2, 1 );1.233 +1.234 + printf( "Started DMA\n" );1.235 + ide_dump_registers();1.236 +1.237 + ide_wait_irq();1.238 + printf( "After IRQ\n" );1.239 + ide_dump_registers();1.240 + long_write( IDE_DMA_CTL1, 0 );1.241 + status = ide_wait_dma();1.242 + printf( "After DMA finished\n");1.243 + ide_dump_registers();1.244 + if( status != 0 ) {1.245 + return -1;1.246 + }1.247 + status = long_read(ASIC_STATUS0);1.248 + if( (status & (1<<14)) == 0 ) {1.249 + printf( "DMARQ cleared already\n");1.250 + } else {1.251 + /*1.252 + status &= ~(1<<14);1.253 + long_write(ASIC_STATUS0, status);1.254 + status = long_read(ASIC_STATUS0);1.255 + */1.256 + byte_read(IDE_STATUS );1.257 + if( (status & (1<<14)) == 0 ) {1.258 + printf( "DMARQ cleared successfully\n" );1.259 + } else {1.260 + printf( "DMARQ not cleared: %08X\n", long_read(ASIC_STATUS0) );1.261 + }1.262 + }1.263 + status = ide_wait_ready();1.264 + printf( "After IDE ready\n");1.265 + ide_dump_registers();1.266 + if( status != 0 ) {1.267 + return -1;1.268 + }1.269 + return long_read( IDE_DMA_STATUS );1.270 +}1.271 +1.272 +int ide_do_packet_command_pio( char *cmd, char *buf, int length )1.273 +{1.274 + ide_write_command_packet( cmd, 0 );1.275 + length = ide_read_pio( buf, length );1.276 + return length;1.277 +}1.278 +1.279 +int ide_do_packet_command_dma( char *cmd, char *buf, int length )1.280 +{1.281 + long_write( QUEUECR0, 0x10 );1.282 + long_write( QUEUECR1, 0x10 );1.283 + long_write( IDE_DMA_MAGIC, IDE_DMA_MAGIC_VALUE );1.284 + long_write( IDE_DMA_ADDR, (unsigned int)buf );1.285 + long_write( IDE_DMA_SIZE, length );1.286 + long_write( IDE_DMA_DIR, 1 );1.287 + ide_write_command_packet( cmd, 1 );1.288 + length = ide_read_dma( buf, length );1.289 + return length;1.290 +}1.291 +1.292 +int ide_init()1.293 +{1.294 + if( ide_wait_ready() )1.295 + return -1;1.296 +1.297 + /** Set Default PIO mode */1.298 + byte_write( IDE_FEATURE, 0x03 );1.299 + byte_write( IDE_COUNT, 0x0B );1.300 + byte_write( IDE_COMMAND, 0xEF );1.301 +1.302 + if( ide_wait_ready() )1.303 + return -1;1.304 +1.305 + /** Set Multi-word DMA mode 2 */1.306 + long_write( 0xA05F7490, 0x222 );1.307 + long_write( 0xA05F7494, 0x222 );1.308 + byte_write( IDE_FEATURE, 0x03 );1.309 + byte_write( IDE_COUNT, 0x22 );1.310 + byte_write( IDE_COMMAND, 0xEF );1.311 + if( ide_wait_ready() )1.312 + return -1;1.313 +1.314 + word_write( 0xA05F7480, 0x400 );1.315 + long_write( 0xA05F7488, 0x200 );1.316 + long_write( 0xA05F748C, 0x200 );1.317 + long_write( 0xA05F74A0, 0x2001 );1.318 + long_write( 0xA05F74A4, 0x2001 );1.319 + long_write( 0xA05F74B4, 0x0001 );1.320 +}1.321 +1.322 +int ide_sense_error( char *buf )1.323 +{1.324 + char cmd[12] = { 0x13,0,0,0, 10,0,0,0, 0,0,0,0 };1.325 + return ide_do_packet_command_pio( cmd, buf, 10 );1.326 +}1.327 +1.328 +void ide_print_sense_error()1.329 +{1.330 + char buf[10];1.331 + if( ide_sense_error(buf) != 10 ) {1.332 + printf( "ERROR - Sense error failed!\n" );1.333 + return;1.334 + }1.335 + int major = buf[2] & 0xFF;1.336 + int minor = buf[8] & 0xFF;1.337 + printf( "[IDE] Error code %02X,%02X\n", major, minor );1.338 +}1.339 +1.340 +int ide_test_ready()1.341 +{1.342 + char cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };1.343 + int length = ide_do_packet_command_pio( cmd, NULL, 0 );1.344 + return length;1.345 +}1.346 +1.347 +int ide_read_toc( char *buf, int length )1.348 +{1.349 + char cmd[12] = { 0x14,0,0,0, 0x98,0,0,0, 0,0,0,0 };1.350 + return ide_do_packet_command_pio( cmd, buf, length );1.351 +}1.352 +1.353 +int ide_get_session( int session, struct gdrom_session *session_data )1.354 +{1.355 + char cmd[12] = {0x15, 0, session, 0, 6,0,0,0, 0,0,0,0 };1.356 + char buf[6];1.357 + int length = ide_do_packet_command_pio( cmd, buf, sizeof(buf) );1.358 + if( length < 0 )1.359 + return length;1.360 + if( length != 6 )1.361 + return -1;1.362 + assert(length == 6);1.363 + session_data->track = ((int)buf[2])&0xFF;1.364 + session_data->lba = (((int)buf[3])&0xFF) << 16 |1.365 + (((int)buf[4])&0xFF) << 8 |1.366 + (((int)buf[5])&0xFF);1.367 + return 0;1.368 +}1.369 +1.370 +int ide_spinup( )1.371 +{1.372 + char cmd[12] = {0x70,0x1F,0,0, 0,0,0,0, 0,0,0,0};1.373 + int length = ide_do_packet_command_pio( cmd, NULL, 0 );1.374 + return length;1.375 +}1.376 +1.377 +int ide_unknown71( char *buf, int length )1.378 +{1.379 + char cmd[12] = {0x71,0,0,0, 0,0,0,0, 0,0,0,0};1.380 + return ide_do_packet_command_pio( cmd, buf, length );1.381 +}1.382 +1.383 +int ide_read_sector_pio( uint32_t sector, uint32_t count, int mode,1.384 + char *buf, int length )1.385 +{1.386 + char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };1.387 +1.388 + cmd[1] = mode;1.389 + cmd[2] = (sector>>16)&0xFF;1.390 + cmd[3] = (sector>>8)&0xFF;1.391 + cmd[4] = sector&0xFF;1.392 + cmd[8] = (count>>16)&0xFF;1.393 + cmd[9] = (count>>8)&0xFF;1.394 + cmd[10] = count&0xFF;1.395 + return ide_do_packet_command_pio( cmd, buf, length );1.396 +}1.397 +1.398 +1.399 +int ide_read_sector_dma( uint32_t sector, uint32_t count, int mode,1.400 + char *buf, int length )1.401 +{1.402 + char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };1.403 +1.404 + cmd[1] = mode;1.405 + cmd[2] = (sector>>16)&0xFF;1.406 + cmd[3] = (sector>>8)&0xFF;1.407 + cmd[4] = sector&0xFF;1.408 + cmd[8] = (count>>16)&0xFF;1.409 + cmd[9] = (count>>8)&0xFF;1.410 + cmd[10] = count&0xFF;1.411 + return ide_do_packet_command_dma( cmd, buf, length );1.412 +}1.413 +1.414 +int ide_read_something( )1.415 +{1.416 + char cmd[12] = { 0x12,0,0,0, 0x0a,0,0,0, 0,0,0,0 };1.417 + char result[10];1.418 + ide_do_packet_command_pio( cmd, result, 10 );1.419 + debug_dump_buffer(result,10);1.420 + return 0;1.421 +}1.422 \ No newline at end of file
.