forked from len0rd/rockbox
Optimized the sector read loop as much as C allows. I measured an overall speed improvement for file reading of 12.5% for 16-bit aligned and 35% for misaligned. I took the rest of ata_read_sectors() out of IRAM, it's sufficient if only the copy loop stays there.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4247 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
89d2039367
commit
88faf38ef7
1 changed files with 34 additions and 15 deletions
|
|
@ -161,9 +161,39 @@ static int wait_for_end_of_transfer(void)
|
|||
return (ATA_ALT_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY;
|
||||
}
|
||||
|
||||
int ata_read_sectors(unsigned long start,
|
||||
int count,
|
||||
void* buf) __attribute__ ((section (".icode")));
|
||||
|
||||
/* the tight loop of ata_read_sectors(), to avoid the whole in IRAM */
|
||||
static void copy_read_sectors(unsigned char* buf,
|
||||
int wordcount)
|
||||
__attribute__ ((section (".icode")));
|
||||
static void copy_read_sectors(unsigned char* buf, int wordcount)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (wordcount <= 0)
|
||||
return; /* should never happen, but to protect my tail loop */
|
||||
|
||||
if ( (unsigned int)buf & 1 )
|
||||
{
|
||||
unsigned char* bufend = buf + wordcount*2;
|
||||
do
|
||||
{ /* loop compiles to 8 assembler instructions */
|
||||
unsigned short 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 */
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short* wbuf = (unsigned short*)buf;
|
||||
unsigned short* wbufend = wbuf + wordcount;
|
||||
do
|
||||
{ /* loop compiles to 7 assembler instructions */
|
||||
*wbuf = SWAB16(ATA_DATA);
|
||||
} while (++wbuf < wbufend); /* tail loop is faster */
|
||||
}
|
||||
}
|
||||
|
||||
int ata_read_sectors(unsigned long start,
|
||||
int incount,
|
||||
void* inbuf)
|
||||
|
|
@ -235,7 +265,6 @@ int ata_read_sectors(unsigned long start,
|
|||
asm volatile ("nop");
|
||||
|
||||
while (count) {
|
||||
int j;
|
||||
int sectors;
|
||||
int wordcount;
|
||||
int status;
|
||||
|
|
@ -265,17 +294,7 @@ int ata_read_sectors(unsigned long start,
|
|||
|
||||
wordcount = sectors * SECTOR_SIZE / 2;
|
||||
|
||||
if ( (unsigned int)buf & 1 ) {
|
||||
for (j=0; j < wordcount; j++) {
|
||||
unsigned short tmp = SWAB16(ATA_DATA);
|
||||
((unsigned char*)buf)[j*2] = tmp >> 8;
|
||||
((unsigned char*)buf)[j*2+1] = tmp & 0xff;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j=0; j < wordcount; j++)
|
||||
((unsigned short*)buf)[j] = SWAB16(ATA_DATA);
|
||||
}
|
||||
copy_read_sectors(buf, wordcount);
|
||||
|
||||
/*
|
||||
"Device errors encountered during READ MULTIPLE commands are
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue