--- a/test/testide.c Tue Jul 11 01:35:27 2006 +0000 +++ b/test/testide.c Tue Dec 19 11:53:39 2006 +0000 @@ -1,90 +1,377 @@ -#include -#include +/** + * $Id: testide.c,v 1.2 2006-12-19 11:53:39 nkeynes Exp $ + * + * IDE interface test cases. Covers all (known) IDE registers in the + * 5F7000 - 5F74FF range including DMA, but does not cover any GD-Rom + * device behaviour (ie packet comands). + * + * These tests should be run with the drive empty. + * + * Copyright (c) 2006 Nathan Keynes. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "lib.h" #include "ide.h" -void debug_dump_buffer(char *buf, int length) +#include "asic.h" + +unsigned int test_count = 0, test_failures = 0; + +#define IDE_BASE 0xA05F7000 + +#define IDE_ALTSTATUS IDE_BASE+0x018 +#define IDE_UNKNOWN IDE_BASE+0x01C +#define IDE_DATA IDE_BASE+0x080 /* 16 bits */ +#define IDE_FEATURE IDE_BASE+0x084 +#define IDE_COUNT IDE_BASE+0x088 +#define IDE_LBA0 IDE_BASE+0x08C +#define IDE_LBA1 IDE_BASE+0x090 +#define IDE_LBA2 IDE_BASE+0x094 +#define IDE_DEVICE IDE_BASE+0x098 +#define IDE_COMMAND IDE_BASE+0x09C +#define IDE_ACTIVATE IDE_BASE+0x4E4 + +#define IDE_DEVCONTROL IDE_ALTSTATUS +#define IDE_ERROR IDE_FEATURE +#define IDE_STATUS IDE_COMMAND + +#define IDE_DMA_ADDR IDE_BASE+0x404 +#define IDE_DMA_SIZE IDE_BASE+0x408 +#define IDE_DMA_DIR IDE_BASE+0x40C +#define IDE_DMA_CTL1 IDE_BASE+0x414 +#define IDE_DMA_CTL2 IDE_BASE+0x418 +#define IDE_DMA_MAGIC IDE_BASE+0x4B8 +#define IDE_DMA_STATUS IDE_BASE+0x4F8 + +#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; } + +/* Wait for the standard timeout for an INTRQ. If none is received, print an + * error and return -1 + */ +#define EXPECT_INTRQ() if( ide_wait_irq() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for INTRQ\n", __FILE__, __LINE__, __func__ ); return -1; } + +/* Check if the INTRQ line is currently cleared (ie inactive) */ +#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; } + +#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; } + +int check_regs( uint32_t *regs,const char *file, int line, const char *fn ) { - int i,j; - for( i=0; i>8)&0xFF, (val>>16)&0xFF, (val>>24)&0xFF ); - } - for( j=0; j<16 && i+j < length; j++ ) { - printf( "%c", isprint(buf[i+j]) ? buf[i+j] : '.' ); + int i; + int rv = 0; + for( i=0; regs[i] != 0; i+=2 ) { + uint32_t addr = regs[i]; + uint32_t val = regs[i+1]; + uint32_t actual; + if( addr == IDE_DATA ) { + actual = (uint32_t)word_read(addr); + if( val != actual ) { + fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual ); + rv = -1; + } + } else if( addr <= IDE_COMMAND ) { + actual = (uint32_t)byte_read(addr); + if( val != actual ) { + fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual ); + rv = -1; + } + } else { + actual = long_read(addr); + if( val != actual ) { + fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual ); + rv = -1; + } } - printf("\n"); } + return rv; } -void debug_dump_int_buffer(volatile char *buf, int length) +#define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; } + +uint32_t abort_regs[] = { + IDE_ALTSTATUS, 0x51, + IDE_ERROR, 0x04, + IDE_COUNT, 0x02, + IDE_LBA0, 0x06, + IDE_LBA1, 0x00, + IDE_LBA2, 0x50, + IDE_DEVICE, 0, + IDE_DATA, 0x0000, + IDE_STATUS, 0x51, + 0, 0 }; + +uint32_t post_reset_regs[] = { + IDE_ALTSTATUS, 0x00, + IDE_ERROR, 0x01, + IDE_COUNT, 0x01, + IDE_LBA0, 0x01, + IDE_LBA1, 0x14, + IDE_LBA2, 0xEB, + IDE_DEVICE, 0, + IDE_DATA, 0xFFFF, + IDE_STATUS, 0x00, + 0, 0 }; + +uint32_t post_set_feature_regs[] = { + IDE_ALTSTATUS, 0x50, + IDE_ERROR, 0x00, + IDE_COUNT, 0x0B, + IDE_LBA0, 0x01, + IDE_LBA1, 0x00, + IDE_LBA2, 0x00, + IDE_DEVICE, 0, + IDE_DATA, 0xFFFF, + IDE_STATUS, 0x50, + 0, 0 }; + +uint32_t post_set_feature2_regs[] = { + IDE_ALTSTATUS, 0x50, + IDE_ERROR, 0x00, + IDE_COUNT, 0x22, + IDE_LBA0, 0x01, + IDE_LBA1, 0x00, + IDE_LBA2, 0x00, + IDE_DEVICE, 0, + IDE_DATA, 0xFFFF, + IDE_STATUS, 0x50, + 0, 0 }; + +/** + * Test enable/disable of the IDE interface via port + * 0x4E4. + */ +int test_enable() { - int i,j; - for( i=0; i