[U-Boot-Users] Endian patch for AU1x00
Ed Okerson
eokerson at texasconnect.net
Mon Dec 8 01:49:45 CET 2003
Attached is an patch to cmd_ide.c that fixes endian issues for the AU1x00
family of processors. Previously these processors could only read Compact
Flash cards (and perhaps other IDE devices) if the drive was byte swapped
from what is written by a standard PC. With this patch they can now read
them without the bytes needing to be swapped.
Ed Okerson
-------------- next part --------------
--- ../../u-boot/common/cmd_ide.c 2003-11-07 05:42:26.000000000 -0800
+++ cmd_ide.c 2003-11-30 13:13:53.000000000 -0800
@@ -172,7 +172,7 @@ static void __inline__ ide_outb(int dev,
static unsigned char __inline__ ide_inb(int dev, int port);
static void input_data(int dev, ulong *sect_buf, int words);
static void output_data(int dev, ulong *sect_buf, int words);
-static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len, int swap);
#ifdef CONFIG_ATAPI
@@ -239,7 +239,7 @@ int do_ide (cmd_tbl_t *cmdtp, int flag,
}
}
if (!ok) {
- puts ("\nno IDE devices available\n");
+ puts ("\nno IDE devices with partitions available\n");
rcode ++;
}
return rcode;
@@ -631,7 +631,6 @@ void ide_init (void)
#ifdef CONFIG_IDE_LED
int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
#endif
- ide_dev_desc[i].type=DEV_TYPE_UNKNOWN;
ide_dev_desc[i].if_type=IF_TYPE_IDE;
ide_dev_desc[i].dev=i;
ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
@@ -817,8 +816,12 @@ output_data_short(int dev, ulong *sect_b
/* We only need to swap data if we are running on a big endian cpu. */
/* But Au1x00 cpu:s already swaps data in big endian mode! */
-#if defined(__LITTLE_ENDIAN) || defined(CONFIG_AU1X00)
-#define input_swap_data(x,y,z) input_data(x,y,z)
+#if (defined(__LITTLE_ENDIAN) || defined(CONFIG_AU1X00))
+static void
+input_swap_data(int dev, ulong *sect_buf, int words)
+{
+ insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+}
#else
static void
input_swap_data(int dev, ulong *sect_buf, int words)
@@ -875,11 +878,25 @@ input_data(int dev, ulong *sect_buf, int
}
}
#else /* ! __PPC__ */
+#if (!defined(__LITTLE_ENDIAN) && defined(CONFIG_AU1X00))
+static void
+input_data(int dev, ulong *sect_buf, int words)
+{
+ volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ ushort *dbuf = (ushort *)sect_buf;
+
+ while (words--) {
+ *dbuf++ = swab16(*pbuf);
+ *dbuf++ = swab16(*pbuf);
+ }
+}
+#else
static void
input_data(int dev, ulong *sect_buf, int words)
{
insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
}
+#endif /* CONFIG_AU1X00 */
#endif /* __PPC__ */
@@ -912,6 +929,7 @@ static void ide_ident (block_dev_desc_t
{
ulong iobuf[ATA_SECTORWORDS];
unsigned char c;
+ unsigned char *l;
hd_driveid_t *iop = (hd_driveid_t *)iobuf;
#ifdef CONFIG_AMIGAONEG3SE
@@ -992,9 +1010,11 @@ static void ide_ident (block_dev_desc_t
if (retries == 0) {
do_retry = 1;
} else {
+ dev_desc->type=DEV_TYPE_UNKNOWN;
return;
}
#else
+ dev_desc->type=DEV_TYPE_UNKNOWN;
return;
#endif /* CONFIG_AMIGAONEG3SE */
}
@@ -1017,10 +1037,14 @@ static void ide_ident (block_dev_desc_t
input_swap_data (device, iobuf, ATA_SECTORWORDS);
- ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
- ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
- ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
-
+#if defined(__LITTLE_ENDIAN)
+ ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision), 1);
+ ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor), 1);
+#else
+ ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision), 0);
+ ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor), 0);
+#endif
+ ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product), 0);
if ((iop->config & 0x0080)==0x0080)
dev_desc->removable = 1;
else
@@ -1062,7 +1086,11 @@ static void ide_ident (block_dev_desc_t
#endif /* CONFIG_ATAPI */
/* swap shorts */
+#if (defined(__LITTLE_ENDIAN) && defined(CONFIG_AU1X00))
+ dev_desc->lba = iop->lba_capacity;
+#else
dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
+#endif
/* assuming HD */
dev_desc->type=DEV_TYPE_HARDDISK;
dev_desc->blksz=ATA_BLOCKSIZE;
@@ -1162,7 +1190,6 @@ ulong ide_read (int device, ulong blknr,
device, blknr, c);
break;
}
-
input_data (device, buffer, ATA_SECTORWORDS);
(void) ide_inb (device, ATA_STATUS); /* clear IRQ */
@@ -1234,9 +1261,10 @@ WR_OUT:
* copy src to dest, skipping leading and trailing blanks and null
* terminate the string
*/
-static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len, int swap)
{
- int start,end;
+ int start, save, end;
+ unsigned char s, *d = dest;
start=0;
while (start<len) {
@@ -1246,14 +1274,28 @@ static void ident_cpy (unsigned char *de
}
end=len-1;
while (end>start) {
+ if(swap)
+ end--;
if (src[end]!=' ')
break;
- end--;
+ if(!swap)
+ end--;
}
+ save = start;
for ( ; start<=end; start++) {
*dest++=src[start];
}
*dest='\0';
+ dest = d;
+
+ if(swap)
+ {
+ for ( ; save<=end; save+=2) {
+ s = d[save];
+ *dest++=d[save+1];
+ *dest++=s;
+ }
+ }
}
/* ------------------------------------------------------------------------- */
@@ -1423,19 +1465,18 @@ input_data_shorts(int dev, ushort *sect_
}
#else /* ! __PPC__ */
+
static void
output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
}
-
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
}
-
#endif /* __PPC__ */
/*
@@ -1705,10 +1746,15 @@ static void atapi_inquiry(block_dev_desc
return;
/* copy device ident strings */
- ident_cpy(dev_desc->vendor,&iobuf[8],8);
- ident_cpy(dev_desc->product,&iobuf[16],16);
- ident_cpy(dev_desc->revision,&iobuf[32],5);
-
+#if defined(__LITTLE_ENDIAN)
+ ident_cpy(dev_desc->vendor,&iobuf[8],8, 1);
+ ident_cpy(dev_desc->product,&iobuf[16],16, 0);
+ ident_cpy(dev_desc->revision,&iobuf[32],5, 1);
+#else
+ ident_cpy(dev_desc->vendor,&iobuf[8],8, 0);
+ ident_cpy(dev_desc->product,&iobuf[16],16, 0);
+ ident_cpy(dev_desc->revision,&iobuf[32],5, 0);
+#endif
dev_desc->lun=0;
dev_desc->lba=0;
dev_desc->blksz=0;
More information about the U-Boot
mailing list