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:03:50 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Fix to actually work (need the write read/write sizes)
Implement the microsecond conversion function
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
}
.