Search
lxdream.org :: lxdream/test/testide.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testide.c
changeset 258:8864fae65928
prev252:cfd0ec3bfeec
next263:6f641270b2aa
author nkeynes
date Wed Jan 03 09:00:17 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Adjust timers when they're read rather than waiting until the next time
slice. Also temporarily cut the CPU time by 4.
Initialize the FRQCR register to 0x0E0A for convenience
file annotate diff log raw
nkeynes@248
     1
/**
nkeynes@258
     2
 * $Id: testide.c,v 1.5 2006-12-29 00:23:16 nkeynes Exp $
nkeynes@248
     3
 *
nkeynes@248
     4
 * IDE interface test cases. Covers all (known) IDE registers in the 
nkeynes@248
     5
 * 5F7000 - 5F74FF range including DMA, but does not cover any GD-Rom
nkeynes@248
     6
 * device behaviour (ie packet comands).
nkeynes@248
     7
 *
nkeynes@248
     8
 * These tests should be run with the drive empty.
nkeynes@248
     9
 *
nkeynes@248
    10
 * Copyright (c) 2006 Nathan Keynes.
nkeynes@248
    11
 *
nkeynes@248
    12
 * This program is free software; you can redistribute it and/or modify
nkeynes@248
    13
 * it under the terms of the GNU General Public License as published by
nkeynes@248
    14
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@248
    15
 * (at your option) any later version.
nkeynes@248
    16
 *
nkeynes@248
    17
 * This program is distributed in the hope that it will be useful,
nkeynes@248
    18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@248
    19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@248
    20
 * GNU General Public License for more details.
nkeynes@248
    21
 */
nkeynes@248
    22
nkeynes@248
    23
#include <stdlib.h>
nkeynes@248
    24
#include <stdio.h>
nkeynes@248
    25
#include "lib.h"
nkeynes@185
    26
#include "ide.h"
nkeynes@248
    27
#include "asic.h"
nkeynes@248
    28
nkeynes@248
    29
unsigned int test_count = 0, test_failures = 0;
nkeynes@248
    30
nkeynes@248
    31
#define IDE_BASE 0xA05F7000
nkeynes@248
    32
nkeynes@248
    33
#define IDE_ALTSTATUS IDE_BASE+0x018
nkeynes@248
    34
#define IDE_UNKNOWN   IDE_BASE+0x01C
nkeynes@248
    35
#define IDE_DATA      IDE_BASE+0x080 /* 16 bits */
nkeynes@248
    36
#define IDE_FEATURE   IDE_BASE+0x084
nkeynes@248
    37
#define IDE_COUNT     IDE_BASE+0x088
nkeynes@248
    38
#define IDE_LBA0      IDE_BASE+0x08C
nkeynes@248
    39
#define IDE_LBA1      IDE_BASE+0x090
nkeynes@248
    40
#define IDE_LBA2      IDE_BASE+0x094
nkeynes@248
    41
#define IDE_DEVICE    IDE_BASE+0x098
nkeynes@248
    42
#define IDE_COMMAND   IDE_BASE+0x09C
nkeynes@248
    43
#define IDE_ACTIVATE  IDE_BASE+0x4E4
nkeynes@248
    44
nkeynes@252
    45
#define IDE_DISC       IDE_LBA0
nkeynes@248
    46
#define IDE_DEVCONTROL IDE_ALTSTATUS
nkeynes@248
    47
#define IDE_ERROR      IDE_FEATURE
nkeynes@248
    48
#define IDE_STATUS     IDE_COMMAND
nkeynes@248
    49
nkeynes@248
    50
#define IDE_DMA_ADDR   IDE_BASE+0x404
nkeynes@248
    51
#define IDE_DMA_SIZE   IDE_BASE+0x408
nkeynes@248
    52
#define IDE_DMA_DIR    IDE_BASE+0x40C
nkeynes@248
    53
#define IDE_DMA_CTL1   IDE_BASE+0x414
nkeynes@248
    54
#define IDE_DMA_CTL2   IDE_BASE+0x418
nkeynes@248
    55
#define IDE_DMA_MAGIC  IDE_BASE+0x4B8
nkeynes@248
    56
#define IDE_DMA_STATUS IDE_BASE+0x4F8
nkeynes@248
    57
nkeynes@248
    58
#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; }
nkeynes@248
    59
nkeynes@248
    60
/* Wait for the standard timeout for an INTRQ. If none is received, print an
nkeynes@248
    61
 * error and return -1
nkeynes@248
    62
 */
nkeynes@248
    63
#define EXPECT_INTRQ() if( ide_wait_irq() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for INTRQ\n", __FILE__, __LINE__, __func__ ); return -1; }
nkeynes@248
    64
nkeynes@248
    65
/* Check if the INTRQ line is currently cleared (ie inactive) */
nkeynes@248
    66
#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; }
nkeynes@248
    67
nkeynes@248
    68
#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; }
nkeynes@248
    69
nkeynes@248
    70
int check_regs( uint32_t *regs,const char *file, int line, const char *fn ) 
nkeynes@185
    71
{
nkeynes@248
    72
    int i;
nkeynes@248
    73
    int rv = 0;
nkeynes@248
    74
    for( i=0; regs[i] != 0; i+=2 ) {
nkeynes@248
    75
	uint32_t addr = regs[i];
nkeynes@248
    76
	uint32_t val = regs[i+1];
nkeynes@248
    77
	uint32_t actual;
nkeynes@248
    78
	if( addr == IDE_DATA ) {
nkeynes@248
    79
	    actual = (uint32_t)word_read(addr);
nkeynes@248
    80
	    if( val != actual ) { 
nkeynes@248
    81
		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual ); 
nkeynes@248
    82
		rv = -1;
nkeynes@248
    83
	    }
nkeynes@248
    84
	} else if( addr <= IDE_COMMAND ) {
nkeynes@248
    85
	    actual = (uint32_t)byte_read(addr);
nkeynes@248
    86
	    if( val != actual ) { 
nkeynes@248
    87
		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual ); 
nkeynes@248
    88
		rv = -1;
nkeynes@248
    89
	    }
nkeynes@248
    90
	} else {
nkeynes@248
    91
	    actual = long_read(addr);
nkeynes@248
    92
	    if( val != actual ) { 
nkeynes@248
    93
		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual ); 
nkeynes@248
    94
		rv = -1;
nkeynes@248
    95
	    }
nkeynes@185
    96
	}
nkeynes@185
    97
    }
nkeynes@248
    98
    return rv;
nkeynes@185
    99
}
nkeynes@185
   100
nkeynes@248
   101
#define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; }
nkeynes@248
   102
nkeynes@251
   103
nkeynes@251
   104
uint32_t post_packet_ready_regs[] = 
nkeynes@251
   105
    { IDE_ALTSTATUS, 0x58,
nkeynes@251
   106
      IDE_COUNT, 0x01,
nkeynes@251
   107
      IDE_LBA1, 8,
nkeynes@251
   108
      IDE_LBA2, 0,
nkeynes@251
   109
      IDE_DEVICE, 0,
nkeynes@251
   110
      IDE_STATUS, 0x58, 0, 0 };
nkeynes@251
   111
nkeynes@251
   112
uint32_t post_packet_cmd_regs[] = 
nkeynes@251
   113
    { IDE_ALTSTATUS, 0xD0,
nkeynes@251
   114
      IDE_ERROR, 0x00,
nkeynes@251
   115
      IDE_COUNT, 0x01,
nkeynes@251
   116
      IDE_LBA1, 8,
nkeynes@251
   117
      IDE_LBA2, 0,
nkeynes@251
   118
      IDE_DEVICE, 0,
nkeynes@251
   119
      IDE_STATUS, 0xD0, 0, 0 };
nkeynes@251
   120
nkeynes@251
   121
uint32_t packet_cmd_error6_regs[] = 
nkeynes@251
   122
    { IDE_ALTSTATUS, 0x51,
nkeynes@251
   123
      IDE_ERROR, 0x60,
nkeynes@251
   124
      IDE_COUNT, 0x03,
nkeynes@251
   125
      IDE_LBA1, 8,
nkeynes@251
   126
      IDE_LBA2, 0,
nkeynes@251
   127
      IDE_DEVICE, 0,
nkeynes@251
   128
      IDE_STATUS, 0x51, 0, 0 };
nkeynes@251
   129
nkeynes@251
   130
uint32_t packet_data_ready_regs[] = 
nkeynes@251
   131
    { IDE_ALTSTATUS, 0x58,
nkeynes@251
   132
      IDE_ERROR, 0x00,
nkeynes@251
   133
      IDE_COUNT, 0x02,
nkeynes@251
   134
      IDE_LBA1, 0x0C,
nkeynes@251
   135
      IDE_LBA2, 0,
nkeynes@251
   136
      IDE_DEVICE, 0,
nkeynes@251
   137
      IDE_STATUS, 0x58, 0, 0 };
nkeynes@251
   138
nkeynes@251
   139
nkeynes@251
   140
uint32_t post_packet_data_regs[] = 
nkeynes@251
   141
    { IDE_ALTSTATUS, 0xD0,
nkeynes@251
   142
      IDE_ERROR, 0x00,
nkeynes@251
   143
      IDE_COUNT, 0x02,
nkeynes@251
   144
      IDE_LBA1, 0x0C,
nkeynes@251
   145
      IDE_LBA2, 0,
nkeynes@251
   146
      IDE_DEVICE, 0,
nkeynes@251
   147
      IDE_STATUS, 0xD0, 0, 0 };
nkeynes@251
   148
nkeynes@251
   149
uint32_t packet_complete_regs[] = 
nkeynes@251
   150
    { IDE_ALTSTATUS, 0x50,
nkeynes@251
   151
      IDE_ERROR, 0x00,
nkeynes@251
   152
      IDE_COUNT, 0x03,
nkeynes@251
   153
      IDE_LBA1, 0x0C,
nkeynes@251
   154
      IDE_LBA2, 0,
nkeynes@251
   155
      IDE_DEVICE, 0,
nkeynes@251
   156
      IDE_STATUS, 0x50, 0, 0 };
nkeynes@251
   157
nkeynes@252
   158
int send_packet_command( const char *cmd )
nkeynes@251
   159
{
nkeynes@251
   160
    unsigned short *spkt = (unsigned short *)cmd;
nkeynes@251
   161
    int i;
nkeynes@251
   162
nkeynes@251
   163
    EXPECT_READY();
nkeynes@251
   164
    byte_write( IDE_FEATURE, 0 );
nkeynes@251
   165
    byte_write( IDE_COUNT, 0 );
nkeynes@251
   166
    byte_write( IDE_LBA0, 0 );
nkeynes@251
   167
    byte_write( IDE_LBA1, 8 );
nkeynes@251
   168
    byte_write( IDE_LBA2, 0 );
nkeynes@251
   169
    byte_write( IDE_DEVICE, 0 );
nkeynes@251
   170
    byte_write( IDE_COMMAND, 0xA0 );
nkeynes@251
   171
    byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle */
nkeynes@251
   172
    EXPECT_READY(); /* Wait until device is ready to accept command (usually immediate) */
nkeynes@251
   173
    CHECK_INTRQ_CLEAR();
nkeynes@251
   174
    CHECK_REGS( post_packet_ready_regs );
nkeynes@251
   175
    
nkeynes@251
   176
    /* Write the command */
nkeynes@251
   177
    for( i=0; i<6; i++ ) {
nkeynes@251
   178
        word_write( IDE_DATA, spkt[i] );
nkeynes@251
   179
    }
nkeynes@251
   180
nkeynes@251
   181
    byte_read(IDE_ALTSTATUS); 
nkeynes@251
   182
nkeynes@251
   183
    // CHECK_REGS( post_packet_cmd_regs );
nkeynes@251
   184
    EXPECT_INTRQ();
nkeynes@251
   185
    EXPECT_READY();
nkeynes@251
   186
    return 0;
nkeynes@251
   187
}
nkeynes@251
   188
nkeynes@252
   189
int read_pio( char *buf, int expected_length ) {
nkeynes@252
   190
    uint32_t ready_regs[] = {
nkeynes@252
   191
	IDE_ALTSTATUS, 0x58,
nkeynes@252
   192
	IDE_ERROR, 0x00,
nkeynes@252
   193
	IDE_COUNT, 0x02,
nkeynes@252
   194
	IDE_LBA1, expected_length & 0xFF,
nkeynes@252
   195
	IDE_LBA2, (expected_length >> 8),
nkeynes@252
   196
	IDE_DEVICE, 0,
nkeynes@252
   197
	IDE_STATUS, 0x58, 
nkeynes@252
   198
	0, 0 };    
nkeynes@252
   199
nkeynes@252
   200
    int i;
nkeynes@252
   201
    unsigned short *bufptr = (unsigned short *)buf;
nkeynes@252
   202
    unsigned int length = 0, avail;
nkeynes@252
   203
    int status;
nkeynes@252
   204
    
nkeynes@252
   205
    CHECK_REGS( ready_regs );
nkeynes@252
   206
    for( i=0; i<expected_length; i+=2 ) {
nkeynes@252
   207
	*bufptr++ = word_read(IDE_DATA);
nkeynes@252
   208
    }
nkeynes@252
   209
nkeynes@252
   210
    EXPECT_INTRQ();
nkeynes@252
   211
    EXPECT_READY();
nkeynes@252
   212
    ready_regs[1] = 0x50;
nkeynes@252
   213
    ready_regs[5] = 0x03;
nkeynes@252
   214
    ready_regs[13] = 0x50;
nkeynes@252
   215
    CHECK_REGS( ready_regs );
nkeynes@252
   216
    return 0;
nkeynes@252
   217
}
nkeynes@252
   218
nkeynes@252
   219
#define IDE_TEST_PACKET_OK( c,e,l ) if( ide_test_packet_ok( __FILE__, __LINE__, __func__, c, e, l ) != 0 ) { return -1; }
nkeynes@252
   220
int ide_test_packet_ok( const char *file, int line, const char *func, 
nkeynes@252
   221
			const char *cmd, char *expect, int expect_len ) 
nkeynes@252
   222
{
nkeynes@252
   223
    char buf[expect_len];
nkeynes@252
   224
    int status = send_packet_command(cmd);
nkeynes@252
   225
    if( status != 0 ) {
nkeynes@252
   226
	return status;
nkeynes@252
   227
    }
nkeynes@252
   228
    status = byte_read( IDE_ALTSTATUS );
nkeynes@252
   229
    if( status & 1 ) { /* Error */
nkeynes@252
   230
	status = ide_get_sense_code();
nkeynes@252
   231
	fprintf( stderr, "Assertion failed at %s:%d %s(): Unexpected error %04X\n",
nkeynes@252
   232
		 file, line, func, status );
nkeynes@252
   233
	return -1;
nkeynes@252
   234
    }
nkeynes@252
   235
nkeynes@252
   236
    status = read_pio( buf, expect_len );
nkeynes@252
   237
    if( status != 0 ) {
nkeynes@252
   238
	return status;
nkeynes@252
   239
    }
nkeynes@252
   240
    if( expect != NULL && memcmp( expect, buf, expect_len ) != 0 ) {
nkeynes@252
   241
	fprintf(stderr, "Assertion failed at %s:%d %s(): Results differ from expected:\n",file,line,func );
nkeynes@252
   242
	fwrite_diff( stderr, expect, expect_len, buf, expect_len );
nkeynes@252
   243
	return -1;
nkeynes@252
   244
    }
nkeynes@252
   245
    return 0;
nkeynes@252
   246
}
nkeynes@252
   247
nkeynes@252
   248
#define IDE_TEST_PACKET_ERROR( c,e ) if( ide_test_packet_error( __FILE__, __LINE__, __func__, c, e ) != 0 ) { return -1; }
nkeynes@252
   249
int ide_test_packet_error( char *file, int line, char *func,
nkeynes@252
   250
			   char *cmd, int expect_error )
nkeynes@252
   251
{
nkeynes@252
   252
    uint32_t error_regs[] = 
nkeynes@252
   253
    { IDE_ALTSTATUS, 0x51,
nkeynes@252
   254
      IDE_ERROR, (expect_error & 0x0F)<<4,
nkeynes@252
   255
      IDE_COUNT, 0x03,
nkeynes@252
   256
      IDE_DEVICE, 0,
nkeynes@252
   257
      IDE_STATUS, 0x51, 0, 0 };
nkeynes@252
   258
    uint32_t error_code;
nkeynes@252
   259
    int status = send_packet_command(cmd);
nkeynes@252
   260
    if( status != 0 ) {
nkeynes@252
   261
	return status;
nkeynes@252
   262
    }
nkeynes@252
   263
    CHECK_REGS(error_regs);
nkeynes@252
   264
    error_code = ide_get_sense_code();
nkeynes@252
   265
    CHECK_IEQUALS( expect_error, error_code );
nkeynes@252
   266
nkeynes@252
   267
    return 0;
nkeynes@252
   268
}
nkeynes@252
   269
    
nkeynes@251
   270
nkeynes@248
   271
uint32_t abort_regs[] = {
nkeynes@248
   272
    IDE_ALTSTATUS, 0x51,
nkeynes@248
   273
    IDE_ERROR, 0x04,
nkeynes@248
   274
    IDE_COUNT, 0x02,
nkeynes@248
   275
    IDE_LBA1, 0x00,
nkeynes@248
   276
    IDE_LBA2, 0x50,
nkeynes@248
   277
    IDE_DEVICE, 0,
nkeynes@248
   278
    IDE_DATA, 0x0000,
nkeynes@248
   279
    IDE_STATUS, 0x51, 
nkeynes@248
   280
    0, 0 };
nkeynes@248
   281
nkeynes@248
   282
uint32_t post_reset_regs[] = {
nkeynes@248
   283
    IDE_ALTSTATUS, 0x00,
nkeynes@248
   284
    IDE_ERROR, 0x01,
nkeynes@248
   285
    IDE_COUNT, 0x01,
nkeynes@248
   286
    IDE_LBA1, 0x14,
nkeynes@248
   287
    IDE_LBA2, 0xEB,
nkeynes@248
   288
    IDE_DEVICE, 0,
nkeynes@248
   289
    IDE_DATA, 0xFFFF,
nkeynes@248
   290
    IDE_STATUS, 0x00, 
nkeynes@248
   291
    0, 0 };
nkeynes@248
   292
nkeynes@248
   293
uint32_t post_set_feature_regs[] = {
nkeynes@248
   294
    IDE_ALTSTATUS, 0x50,
nkeynes@248
   295
    IDE_ERROR, 0x00,
nkeynes@248
   296
    IDE_COUNT, 0x0B,
nkeynes@248
   297
    IDE_LBA1, 0x00,
nkeynes@248
   298
    IDE_LBA2, 0x00,
nkeynes@248
   299
    IDE_DEVICE, 0,
nkeynes@248
   300
    IDE_DATA, 0xFFFF,
nkeynes@248
   301
    IDE_STATUS, 0x50, 
nkeynes@248
   302
    0, 0 };    
nkeynes@248
   303
nkeynes@248
   304
uint32_t post_set_feature2_regs[] = {
nkeynes@248
   305
    IDE_ALTSTATUS, 0x50,
nkeynes@248
   306
    IDE_ERROR, 0x00,
nkeynes@248
   307
    IDE_COUNT, 0x22,
nkeynes@248
   308
    IDE_LBA1, 0x00,
nkeynes@248
   309
    IDE_LBA2, 0x00,
nkeynes@248
   310
    IDE_DEVICE, 0,
nkeynes@248
   311
    IDE_DATA, 0xFFFF,
nkeynes@248
   312
    IDE_STATUS, 0x50, 
nkeynes@248
   313
    0, 0 };    
nkeynes@248
   314
nkeynes@252
   315
/************************** Interface Tests *******************************/
nkeynes@252
   316
nkeynes@248
   317
/**
nkeynes@248
   318
 * Test enable/disable of the IDE interface via port
nkeynes@248
   319
 * 0x4E4. 
nkeynes@248
   320
 */
nkeynes@248
   321
int test_enable()
nkeynes@185
   322
{
nkeynes@248
   323
    int i;
nkeynes@248
   324
    int failed = 0;
nkeynes@248
   325
    /* ensure deactivated */
nkeynes@248
   326
    long_write( IDE_ACTIVATE, 0x00042FE );
nkeynes@185
   327
nkeynes@248
   328
    /* test registers to ensure all return 0xFF (need to wait a few cycles?) */
nkeynes@248
   329
    for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
nkeynes@248
   330
	CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
nkeynes@185
   331
    }
nkeynes@185
   332
nkeynes@248
   333
    /* enable interface */
nkeynes@248
   334
    ide_activate();
nkeynes@248
   335
nkeynes@248
   336
    /* test registers have default settings */
nkeynes@248
   337
    //    CHECK_REGS( post_reset_regs );
nkeynes@248
   338
    
nkeynes@248
   339
nkeynes@248
   340
    /* disable interface and re-test */
nkeynes@248
   341
    long_write( IDE_ACTIVATE, 0x00042FE );
nkeynes@248
   342
nkeynes@248
   343
    /* Test registers all 0xFF */
nkeynes@248
   344
    for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
nkeynes@248
   345
	CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
nkeynes@185
   346
    }
nkeynes@185
   347
nkeynes@248
   348
    /* Finally leave the interface in an enabled state */
nkeynes@248
   349
    ide_activate();
nkeynes@185
   350
    return 0;
nkeynes@185
   351
}
nkeynes@185
   352
nkeynes@251
   353
nkeynes@251
   354
uint32_t drive_ready_regs[] = {
nkeynes@251
   355
    IDE_ALTSTATUS, 0x50,
nkeynes@251
   356
    IDE_ERROR, 0x00,
nkeynes@251
   357
    IDE_COUNT, 0x03,
nkeynes@251
   358
    IDE_LBA1, 0x08,
nkeynes@251
   359
    IDE_LBA2, 0x00,
nkeynes@251
   360
    IDE_DEVICE, 0,
nkeynes@251
   361
    IDE_DATA, 0xFFFF,
nkeynes@251
   362
    IDE_STATUS, 0x50, 
nkeynes@251
   363
    0, 0 };    
nkeynes@251
   364
nkeynes@248
   365
/**
nkeynes@248
   366
 * Test the reset command
nkeynes@248
   367
 */
nkeynes@248
   368
int test_reset()
nkeynes@248
   369
{
nkeynes@248
   370
    byte_write( IDE_COMMAND, 0x08 );
nkeynes@248
   371
    EXPECT_READY();
nkeynes@248
   372
    CHECK_INTRQ_CLEAR();
nkeynes@248
   373
    CHECK_REGS( post_reset_regs );
nkeynes@248
   374
    
nkeynes@248
   375
    /** Set Default PIO mode */
nkeynes@248
   376
    byte_write( IDE_FEATURE, 0x03 );
nkeynes@248
   377
    byte_write( IDE_COUNT, 0x0B );
nkeynes@248
   378
    byte_write( IDE_COMMAND, 0xEF );
nkeynes@248
   379
    EXPECT_READY();
nkeynes@248
   380
    CHECK_REGS( post_set_feature_regs );
nkeynes@248
   381
    
nkeynes@248
   382
    /** Set Multi-word DMA mode 2 */
nkeynes@248
   383
    long_write( 0xA05F7490, 0x222 );
nkeynes@248
   384
    long_write( 0xA05F7494, 0x222 );
nkeynes@248
   385
    byte_write( IDE_FEATURE, 0x03 );
nkeynes@248
   386
    byte_write( IDE_COUNT, 0x22 );
nkeynes@248
   387
    byte_write( IDE_COMMAND, 0xEF );
nkeynes@248
   388
    EXPECT_READY();
nkeynes@248
   389
    CHECK_INTRQ_CLEAR();
nkeynes@248
   390
    CHECK_REGS( post_set_feature2_regs );
nkeynes@185
   391
nkeynes@251
   392
    char test_ready_cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };
nkeynes@251
   393
    if( send_packet_command(test_ready_cmd) != 0 ) {
nkeynes@251
   394
	return -1;
nkeynes@251
   395
    }
nkeynes@251
   396
nkeynes@251
   397
    CHECK_REGS( packet_cmd_error6_regs );
nkeynes@251
   398
    int sense = ide_get_sense_code();
nkeynes@251
   399
    CHECK_IEQUALS( 0x2906, sense );
nkeynes@251
   400
nkeynes@251
   401
    if( send_packet_command(test_ready_cmd) != 0 ) {
nkeynes@251
   402
	return -1;
nkeynes@251
   403
    }
nkeynes@251
   404
    CHECK_REGS( drive_ready_regs );
nkeynes@248
   405
    return 0;
nkeynes@248
   406
}
nkeynes@248
   407
nkeynes@248
   408
char expect_ident[] = { 0x00, 0xb4, 0x19, 0x00,
nkeynes@248
   409
			0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20 };
nkeynes@251
   410
nkeynes@248
   411
/**
nkeynes@248
   412
 * Test the PACKET command (using the Inquiry command)
nkeynes@248
   413
 */
nkeynes@248
   414
int test_packet()
nkeynes@185
   415
{
nkeynes@248
   416
    int i;
nkeynes@248
   417
    char cmd[12] = { 0x11, 0, 4, 0,  12, 0, 0, 0,  0, 0, 0, 0 };
nkeynes@248
   418
    // char cmd[12] = { 0x00,0,0,0, 0,0,0,0, 0,0,0,0 };
nkeynes@251
   419
    unsigned short *spkt;
nkeynes@248
   420
    char result[12];
nkeynes@248
   421
nkeynes@251
   422
    send_packet_command( cmd );
nkeynes@248
   423
    CHECK_REGS( packet_data_ready_regs );
nkeynes@248
   424
    spkt = (unsigned short *)result;
nkeynes@248
   425
    *spkt++ = word_read(IDE_DATA);
nkeynes@248
   426
    *spkt++ = word_read(IDE_DATA);
nkeynes@248
   427
    *spkt++ = word_read(IDE_DATA);
nkeynes@248
   428
    *spkt++ = word_read(IDE_DATA);
nkeynes@248
   429
    CHECK_REGS( packet_data_ready_regs );
nkeynes@248
   430
    *spkt++ = word_read(IDE_DATA);
nkeynes@248
   431
    *spkt++ = word_read(IDE_DATA);
nkeynes@252
   432
//    CHECK_REGS( post_packet_data_regs );
nkeynes@248
   433
    EXPECT_READY();
nkeynes@251
   434
    EXPECT_INTRQ();
nkeynes@248
   435
    CHECK_REGS( packet_complete_regs );
nkeynes@251
   436
nkeynes@248
   437
    if( memcmp( result, expect_ident, 12 ) != 0 ) {
nkeynes@248
   438
	fwrite_diff( stderr, expect_ident, 12, result, 12 );
nkeynes@252
   439
	return -1;
nkeynes@248
   440
    }
nkeynes@248
   441
    return 0;
nkeynes@185
   442
}
nkeynes@248
   443
nkeynes@248
   444
/**
nkeynes@248
   445
 * Test the SET FEATURE command
nkeynes@248
   446
 */
nkeynes@248
   447
int test_set_feature()
nkeynes@248
   448
{
nkeynes@248
   449
    return 0;
nkeynes@248
   450
}
nkeynes@248
   451
nkeynes@258
   452
nkeynes@258
   453
nkeynes@248
   454
/**
nkeynes@248
   455
 * Test DMA transfer (using the Inquiry packet comand)
nkeynes@248
   456
 */
nkeynes@248
   457
int test_dma()
nkeynes@248
   458
{
nkeynes@248
   459
    return 0;
nkeynes@248
   460
}
nkeynes@248
   461
nkeynes@248
   462
/**
nkeynes@248
   463
 * Test DMA abort
nkeynes@248
   464
 */
nkeynes@248
   465
int test_dma_abort()
nkeynes@248
   466
{
nkeynes@248
   467
    return 0;
nkeynes@248
   468
}
nkeynes@248
   469
nkeynes@252
   470
/***************************** GD-Rom Tests **********************************/
nkeynes@252
   471
nkeynes@252
   472
int test_read_toc()
nkeynes@252
   473
{
nkeynes@252
   474
    char cmd[12] = { 0x14,0,0,0x00, 0x0C,0,0,0, 0,0,0,0 };
nkeynes@252
   475
    char expect[12] = { 0x41, 0,0, 0x96, 0x41, 0, 0x2E, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF };
nkeynes@252
   476
    
nkeynes@252
   477
    IDE_TEST_PACKET_OK( cmd, expect, 12 );
nkeynes@252
   478
    return 0;
nkeynes@252
   479
}
nkeynes@252
   480
nkeynes@258
   481
int test_read_pio()
nkeynes@258
   482
{
nkeynes@258
   483
    int i,j;
nkeynes@258
   484
    char cmd[12] = {0x30, 0x28, 0, 0x2E,  0x4C, 0, 0, 0,  0, 0, 7, 0 };
nkeynes@258
   485
    uint32_t read_pio_ready_regs[] = 
nkeynes@258
   486
	{ IDE_ALTSTATUS, 0x58,
nkeynes@258
   487
	  IDE_ERROR, 0x00,
nkeynes@258
   488
	  IDE_COUNT, 0x02,
nkeynes@258
   489
	  IDE_LBA1, 0x00,
nkeynes@258
   490
	  IDE_LBA2, 0x08,
nkeynes@258
   491
	  IDE_DEVICE, 0,
nkeynes@258
   492
	  IDE_STATUS, 0x58, 0, 0 };
nkeynes@258
   493
nkeynes@258
   494
    if( send_packet_command(cmd) != 0 ) {
nkeynes@258
   495
	return -1;
nkeynes@258
   496
    }
nkeynes@258
   497
nkeynes@258
   498
    for( j=0; j<7; j++ ) {
nkeynes@258
   499
	CHECK_REGS(read_pio_ready_regs);
nkeynes@258
   500
	CHECK_INTRQ_CLEAR();
nkeynes@258
   501
	for( i=0; i<0x0800; i+=2 ) {
nkeynes@258
   502
	    word_read(IDE_DATA); // throw away for now.
nkeynes@258
   503
	}
nkeynes@258
   504
	
nkeynes@258
   505
	EXPECT_INTRQ();
nkeynes@258
   506
	EXPECT_READY();
nkeynes@258
   507
    }
nkeynes@258
   508
nkeynes@258
   509
    read_pio_ready_regs[1] = 0x50;
nkeynes@258
   510
    read_pio_ready_regs[5] = 0x03;
nkeynes@258
   511
    read_pio_ready_regs[13] = 0x50;
nkeynes@258
   512
    CHECK_REGS( read_pio_ready_regs );
nkeynes@258
   513
    return 0;
nkeynes@258
   514
}
nkeynes@258
   515
nkeynes@252
   516
/**
nkeynes@252
   517
 * Test interaction of Read CD (0x30) with Status (0x40,1)
nkeynes@252
   518
 */
nkeynes@252
   519
int test_status1() 
nkeynes@252
   520
{
nkeynes@252
   521
    char cmd[12] = { 0x40, 0x01, 0, 0, 16,0,0,0, 0,0,0,0 };
nkeynes@252
   522
    char read1cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4C, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   523
    char expect1[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,1,0,0, 0x2E,0x4D,0,0 };
nkeynes@252
   524
    char read2cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4D, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   525
    char expect2[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,4,0,0, 0x2E,0x50,0,0 };
nkeynes@252
   526
    char read3cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4E, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   527
    char expect3[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,5,0,0, 0x2E,0x51,0,0 };
nkeynes@252
   528
    char expect4[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,2,0,0, 0x2E,0x4E,0,0 };
nkeynes@252
   529
    char read5cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x01, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   530
    char expect5[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,0xB6,0,0, 0x2F,0x02,0,0 };
nkeynes@252
   531
    char read6cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x50, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   532
    char expect6[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x05,0,0, 0x2F,0x51,0,0 };
nkeynes@252
   533
    char read7cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x51, 0, 0, 0, 0, 0,1,0 };
nkeynes@252
   534
    char expect7[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x06,0,0, 0x2F,0x52,0,0 };
nkeynes@252
   535
    
nkeynes@252
   536
nkeynes@252
   537
    IDE_TEST_PACKET_OK(read1cmd, NULL, 2048);
nkeynes@252
   538
    IDE_TEST_PACKET_OK(cmd, expect1, 14 );
nkeynes@252
   539
    IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
nkeynes@252
   540
    IDE_TEST_PACKET_OK(cmd, expect2, 14 );
nkeynes@252
   541
    IDE_TEST_PACKET_OK(read3cmd, NULL, 2048);
nkeynes@252
   542
    IDE_TEST_PACKET_OK(cmd, expect3, 14 );
nkeynes@252
   543
    IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
nkeynes@252
   544
    IDE_TEST_PACKET_OK(cmd, expect4, 14 );
nkeynes@252
   545
    IDE_TEST_PACKET_OK(read5cmd, NULL, 2048);
nkeynes@252
   546
    IDE_TEST_PACKET_OK(cmd, expect5, 14 );
nkeynes@252
   547
    IDE_TEST_PACKET_OK(read6cmd, NULL, 2048);
nkeynes@252
   548
    IDE_TEST_PACKET_OK(cmd, expect6, 14 );
nkeynes@252
   549
nkeynes@252
   550
    return 0;
nkeynes@252
   551
}
nkeynes@252
   552
nkeynes@252
   553
/********************************* Main **************************************/
nkeynes@252
   554
nkeynes@248
   555
typedef int (*test_func_t)();
nkeynes@248
   556
nkeynes@251
   557
test_func_t test_fns[] = { test_enable, test_reset, test_packet,
nkeynes@258
   558
			   test_dma, test_dma_abort, test_read_pio,
nkeynes@252
   559
			   test_read_toc,
nkeynes@252
   560
			   test_status1, NULL };
nkeynes@248
   561
nkeynes@248
   562
int main() 
nkeynes@248
   563
{
nkeynes@248
   564
    int i;
nkeynes@248
   565
    ide_init();
nkeynes@248
   566
nkeynes@248
   567
    /* run tests */
nkeynes@248
   568
    for( i=0; test_fns[i] != NULL; i++ ) {
nkeynes@248
   569
	test_count++;
nkeynes@248
   570
	if( test_fns[i]() != 0 ) {
nkeynes@252
   571
	    fprintf( stderr, "Test %d failed\n", i+1 );
nkeynes@248
   572
	    test_failures++;
nkeynes@248
   573
	}
nkeynes@248
   574
    }
nkeynes@248
   575
nkeynes@248
   576
    /* report */
nkeynes@248
   577
    fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count );
nkeynes@248
   578
    return test_failures;
nkeynes@248
   579
}
.