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:
parent
e370776120
commit
ebcd762fb2
1 changed files with 24 additions and 11 deletions
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue