1
0
Fork 0
forked from len0rd/rockbox

Read byte by byte rather than DMA for unaligned transfer

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11927 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Greg White 2007-01-06 01:26:36 +00:00
parent e370776120
commit ebcd762fb2

View file

@ -54,18 +54,31 @@ void ata_device_init(void)
void copy_read_sectors(unsigned char* buf, int wordcount) void copy_read_sectors(unsigned char* buf, int wordcount)
{ {
/* Unaligned transfer - slow copy */
if ( (unsigned long)buf & 1)
{ /* not 16-bit aligned, copy byte by byte */
unsigned short tmp = 0;
unsigned char* bufend = buf + wordcount*2;
do
{
tmp = ATA_DATA;
*buf++ = tmp & 0xff; /* I assume big endian */
*buf++ = tmp >> 8; /* and don't use the SWAB16 macro */
} while (buf < bufend); /* tail loop is faster */
return;
}
/* This should never happen, but worth watching for */ /* This should never happen, but worth watching for */
if(wordcount > (1 << 18)) if(wordcount > (1 << 18))
panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!"); panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!");
//#define GIGABEAT_DEBUG_ATA //#define GIGABEAT_DEBUG_ATA
#ifdef GIGABEAT_DEBUG_ATA #ifdef GIGABEAT_DEBUG_ATA
static int line = 0; static int line = 0;
static char str[256]; static char str[256];
snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount);
lcd_puts(10, line, str); lcd_puts(10, line, str);
line = (line+1) % 32; line = (line+1) % 32;
lcd_update(); lcd_update();
#endif #endif
/* Reset the channel */ /* Reset the channel */
DMASKTRIG0 |= 4; DMASKTRIG0 |= 4;
@ -87,17 +100,17 @@ void copy_read_sectors(unsigned char* buf, int wordcount)
/* Activate the channel */ /* Activate the channel */
DMASKTRIG0 = 0x2; DMASKTRIG0 = 0x2;
invalidate_dcache_range((void *)buf, wordcount*2); invalidate_dcache_range((void *)buf, wordcount*2);
INTMSK &= ~(1<<17); /* unmask the interrupt */ INTMSK &= ~(1<<17); /* unmask the interrupt */
SRCPND = (1<<17); /* clear any pending interrupts */ SRCPND = (1<<17); /* clear any pending interrupts */
/* Start DMA */ /* Start DMA */
DMASKTRIG0 |= 0x1; DMASKTRIG0 |= 0x1;
/* Wait for transfer to complete */ /* Wait for transfer to complete */
while((DSTAT0 & 0x000fffff)) while((DSTAT0 & 0x000fffff))
CLKCON |= (1 << 2); /* set IDLE bit */ CLKCON |= (1 << 2); /* set IDLE bit */
/* Dump cache for the buffer */ /* Dump cache for the buffer */
} }
void dma0(void) void dma0(void)