Subject: Big endian problem

From: "Hanks Li" <[email-masked]>
Date: Fri, 12 Oct 2001 12:26:07 -0400

Hi,

Has anyone tried to compile in Big Endian mode? When I compile the code in
big endian, I got the following message. Does anybody know how to solve this
problem? The assembler I'm using is "GNU assembler 2.11.90.0.27". I have no
problem compiling the code in little endian at all.

Thanks

Hanshi Li

----------------------------------------------------------------------------
------------------------------------
mips-linux-gcc -I
/home/hli/linux/include/asm/gcc -D__KERNEL__ -I/home/hli/linux/include -Wall
 -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-ali
asing -fno-common -G
0 -mno-abicalls -fno-pic -mcpu=r5000 -mips2 -Wa,--trap -pipe -DEXPORT_SYMTAB
 -c time.c
Assembler messages:
Warning: The -mcpu option is deprecated. Please use -march and -mtune
instead.
time.c: In function `calibrate_div32_gettimeoffset':
time.c:225: Unrecognizable insn:
(insn 60 144 66 (parallel[
(set (reg:SI 8 t0)
(asm_operands (".set push
.set noat
.set noreorder
b 1f
li %4,0x21
0:
sll $1,%0,0x1
srl %3,%0,0x1f
or %0,$1,$2
sll %1,%1,0x1
sll %2,%2,0x1
1:
bnez %3,2f
sltu $2,%0,%z5
bnez $2,3f
2:
addiu %4,%4,-1
subu %0,%0,%z5
addiu %2,%2,1
3:
bnez %4,0b
srl $2,%1,0x1f
.set pop") ("=&r") 0[
(reg/v:SI 4 a0)
(reg:SI 8 t0)
(reg:DI 6 a2)
(reg/v:SI 5 a1)
(reg:SI 9 t1)
]
[
(asm_input:SI ("Jr"))
(asm_input:SI ("0"))
(asm_input:DI ("1"))
(asm_input:SI ("2"))
(asm_input:SI ("3"))
] ("time.c") 201))
(set (reg:SI 6 a2)
(asm_operands (".set push
.set noat
.set noreorder
b 1f
li %4,0x21
0:
sll $1,%0,0x1
srl %3,%0,0x1f
or %0,$1,$2
sll %1,%1,0x1
sll %2,%2,0x1
1:
bnez %3,2f
sltu $2,%0,%z5
bnez $2,3f
2:
addiu %4,%4,-1
subu %0,%0,%z5
addiu %2,%2,1
3:
bnez %4,0b
srl $2,%1,0x1f
.set pop") ("=&r") 1[
(reg/v:SI 4 a0)
(reg:SI 8 t0)
(reg:DI 6 a2)
(reg/v:SI 5 a1)
(reg:SI 9 t1)
]
[
(asm_input:SI ("Jr"))
(asm_input:SI ("0"))
(asm_input:DI ("1"))
(asm_input:SI ("2"))
(asm_input:SI ("3"))
] ("time.c") 201))
(set (reg/v:SI 5 a1)
(asm_operands (".set push
.set noat
.set noreorder
b 1f
li %4,0x21
0:
sll $1,%0,0x1
srl %3,%0,0x1f
or %0,$1,$2
sll %1,%1,0x1
sll %2,%2,0x1
1:
bnez %3,2f
sltu $2,%0,%z5
bnez $2,3f
2:
addiu %4,%4,-1
subu %0,%0,%z5
addiu %2,%2,1
3:
bnez %4,0b
srl $2,%1,0x1f
.set pop") ("=&r") 2[
(reg/v:SI 4 a0)
(reg:SI 8 t0)
(reg:DI 6 a2)
(reg/v:SI 5 a1)
(reg:SI 9 t1)
]
[
(asm_input:SI ("Jr"))
(asm_input:SI ("0"))
(asm_input:DI ("1"))
(asm_input:SI ("2"))
(asm_input:SI ("3"))
] ("time.c") 201))
(set (reg:SI 9 t1)
(asm_operands (".set push
.set noat
.set noreorder
b 1f
li %4,0x21
0:
sll $1,%0,0x1
srl %3,%0,0x1f
or %0,$1,$2
sll %1,%1,0x1
sll %2,%2,0x1
1:
bnez %3,2f
sltu $2,%0,%z5
bnez $2,3f
2:
addiu %4,%4,-1
subu %0,%0,%z5
addiu %2,%2,1
3:
bnez %4,0b
srl $2,%1,0x1f
.set pop") ("=&r") 3[
(reg/v:SI 4 a0)
(reg:SI 8 t0)
(reg:DI 6 a2)
(reg/v:SI 5 a1)
(reg:SI 9 t1)
]
[
(asm_input:SI ("Jr"))
(asm_input:SI ("0"))
(asm_input:DI ("1"))
(asm_input:SI ("2"))
(asm_input:SI ("3"))
] ("time.c") 201))
(set (reg:SI 14 t6)
(asm_operands (".set push
.set noat
.set noreorder
b 1f
li %4,0x21
0:
sll $1,%0,0x1
srl %3,%0,0x1f
or %0,$1,$2
sll %1,%1,0x1
sll %2,%2,0x1
1:
bnez %3,2f
sltu $2,%0,%z5
bnez $2,3f
2:
addiu %4,%4,-1
subu %0,%0,%z5
addiu %2,%2,1
3:
bnez %4,0b
srl $2,%1,0x1f
.set pop") ("=&r") 4[
(reg/v:SI 4 a0)
(reg:SI 8 t0)
(reg:DI 6 a2)
(reg/v:SI 5 a1)
(reg:SI 9 t1)
]
[
(asm_input:SI ("Jr"))
(asm_input:SI ("0"))
(asm_input:DI ("1"))
(asm_input:SI ("2"))
(asm_input:SI ("3"))
] ("time.c") 201))
(clobber (reg:QI 2 v0))
(clobber (reg:QI 1 at))
] ) -1 (insn_list:REG_DEP_OUTPUT 13 (insn_list 38 (insn_list 53 (insn_list
51 (insn_list 41 (nil))))))
(nil))
time.c:225: confused by earlier errors, bailing out
make[1]: *** [time.o] Error 1
make[1]: Leaving directory `/home/hli/linux/arch/mips/kernel'
make: *** [_dir_arch/mips/kernel] Error 2
----------------------------------------------------------------------------
---------------------------------

---

From: Ralf Baechle <[email-masked]>
Date: Fri, 12 Oct 2001 19:45:23 +0200

> problem compiling the code in little endian at all.

What compiler is this?

  Ralf

---

From: Jun Sun <[email-masked]>
Date: Fri, 12 Oct 2001 10:47:56 -0700

Which time.c is this?  I have seen this problem caused by mis-defined
USECS_PER_JIFFY_FRAC macro.  Look at other time.c files for the right one.  

Or better yet, upgrade your port to use the common time.c.  See
Documantation/mips/time.README file.

Jun

---

From: Dan Aizenstros <[email-masked]>
Date: Fri, 12 Oct 2001 16:13:50 -0400

Hello Jun,

The file is the common time.c from linux/arch/mips/kernel as you
can see from the third to last line of Hanshi's email.  The tools
he is using are from H. J. Lu's RedHat 7.1 RPMs on the oss.sgi.com
ftp site.  The file compiles just fine with the little endian version
of the same tools from the same place.

Hanshi and I will look at the USECS_PER_JIFFY_FRAC macro.  Thanks for
the pointer.

-- Dan A.

---

From: Jun Sun <[email-masked]>
Date: Fri, 12 Oct 2001 17:35:52 -0700

> Hanshi and I will look at the USECS_PER_JIFFY_FRAC macro.  Thanks for

It is indeed a strange problem as it only shows up in BE tools.  
Some tool gurus want to look into it?

Meanwhile the following patch seems to fix it (and a couple of other
time.c files)

Jun 
diff -Nru linux/arch/mips/dec/time.c.orig linux/arch/mips/dec/time.c
--- linux/arch/mips/dec/time.c.orig	Thu Aug 23 15:24:23 2001
+++ linux/arch/mips/dec/time.c	Fri Oct 12 17:35:51 2001
@@ -8,6 +8,7 @@
  * found in some MIPS systems.
  *
  */
+#include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -44,7 +45,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ))
 
 /* Cycle counter value at the previous timer interrupt.. */
 
diff -Nru linux/arch/mips/kernel/time.c.orig linux/arch/mips/kernel/time.c
--- linux/arch/mips/kernel/time.c.orig	Sat Oct  6 22:04:40 2001
+++ linux/arch/mips/kernel/time.c	Fri Oct 12 17:35:17 2001
@@ -30,7 +30,7 @@
 
 /* This is for machines which generate the exact clock. */
 #define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ))
 
 /*
  * forward reference

---

From: Thiemo Seufer <[email-masked]>
Date: Sat, 13 Oct 2001 02:55:50 +0200

Jun Sun wrote:
[snip]
> Some tool gurus want to look into it?

I use the BE CVS tools and haven't seen this.
How does the preprocessed code look like?

Thiemo

---

From: "H . J . Lu" <[email-masked]>
Date: Fri, 12 Oct 2001 22:54:33 -0700

> Meanwhile the following patch seems to fix it (and a couple of other

This is what I sent out in July.

H.J.
----

---

From: "Yoshi-K" <[email-masked]>
Date: Sun, 14 Oct 2001 06:02:35 +0900

hello.
As for everybody, does MySQL operate without trouble?

OS: PS2 Linux.
CPU: R5900
gcc 2.95.2 
glibc 2.2.2
$ uname -a 
Linux speed-ps 2.2.1 #94 Thu Apr 19 12:13:01 JST 2001 mips unknown 

# cd mysql-3.23.42
# ./configure --with-charset=ujis --with-mysqld-user=mysql
# make;make install
# chown -R mysql.mysql /usr/local/var

# /usr/local/bin/mysql_install_db --user=mysql
Preparing db table
Preparing host table
Preparing user table
Preparing func table
Preparing tables_priv table
Preparing columns_priv table
Installing all prepared tables
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
ERROR: 1033 Incorrect information in file: './mysql/db.frm'
011006 21:20:23 /usr/local/libexec/mysqld: Shutdown Complete

-------------------------
Yoshikatsu Kida
E-Mail: [email-masked]
http://galaxies.jp/

---

From: "H . J . Lu" <[email-masked]>
Date: Sun, 14 Oct 2001 09:30:52 -0700

> Linux speed-ps 2.2.1 #94 Thu Apr 19 12:13:01 JST 2001 mips unknown 

I ported mysql 3.23.36 to mips II and above in my RedHat 7.1 for
mips.

H.J.

---

From: Ralf Baechle <[email-masked]>
Date: Sun, 14 Oct 2001 23:01:30 +0200

> I ported mysql 3.23.36 to mips II and above in my RedHat 7.1 for

I assume MIPS II means you're using ll/sc in the locking code in the MySQL.
Now that the ll/sc emulation is finally fixed these instructions will
also work for ll/sc-less CPUs.

  Ralf

---

From: "H . J . Lu" <[email-masked]>
Date: Sun, 14 Oct 2001 22:46:54 -0700

> also work for ll/sc-less CPUs.

Yes. It has some Linux/mips patch. I can only guess Linux/mips looks
different than other Linux targets because of IRIX :-). See my RedHat
7.1 port for details.

H.J.

---

From: "Hanks Li" <[email-masked]>
Date: Tue, 16 Oct 2001 10:28:56 -0400

Hi,

We are working on the IDE/ATAPI for mips. When I changed to Big endian mode,
the following information appared, and the program hang.

-------------------------------------
Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
PDC20262: IDE controller on PCI bus 00 dev 30
PDC20262: chipset revision 1
PDC20262: not 100% native mode: will probe irqs later
PDC20262: ROM enabled at 0x06fb0000
PDC20262: (U)DMA Burst Bit DISABLED Primary PCI Mode Secondary PCI Mode.
    ide0: BM-DMA at 0xf800-0xf807, BIOS settings: hda:pio, hdb:pio
    ide1: BM-DMA at 0xf808-0xf80f, BIOS settings: hdc:pio, hdd:pio
hda: QUANTUM FIREBALL EX10.2A, ATA DISK drive
ide0 at 0xec00-0xec07,0xe802 on irq 7
hda: 20044080 sectors (10263 MB) w/418KiB Cache, CHS=19885/16/63, (U)DMA
Partition check:
 hda:hda: dma_timer_expiry: status=0x58 { DriveReady SeekComplete
DataRequest }
hda: timeout waiting for DMA
ide_dmaproc: chipset supported ide_dma_timeout func only: 14
-------------------------------------

When I turned off "IDE,ATA and ATAPI Block Devices->Generic PCI bus-master
DMA support", there was no problem at all. The following information
appared:

Uniform Multi-Platform E-IDE driver Revision: 6.31
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
PDC20262: IDE controller on PCI bus 00 dev 30
PDC20262: chipset revision 1
PDC20262: not 100% native mode: will probe irqs later
hda: QUANTUM FIREBALL EX10.2A, ATA DISK drive
ide0 at 0xec00-0xec07,0xe802 on irq 7
hda: 20044080 sectors (10263 MB) w/418KiB Cache, CHS=19885/16/63
Partition check:
 hda: [PTBL] [1247/255/63] hda1 hda2 hda3
------------------------------------

What could be the cause of this problem?

Regards,

Hanshi Li

---

From: Jun Sun <[email-masked]>
Date: Tue, 16 Oct 2001 10:30:11 -0700

Some host-PCI bridge controller may have smart endian conversion features. 
Make sure you set it up correctly.  The fact that DMA does not work but
polling works might also indicate the smart conversion only happens from PCI
to memory, not in the patch PCI -> CPU.

Perhaps your memory is still in LE mode even when your CPU runs in BE mode?

Jun

---

From: Atsushi Nemoto <[email-masked]>
Date: Wed, 17 Oct 2001 11:38:42 +0900 (JST)

>>>>> On Tue, 16 Oct 2001 10:28:56 -0400, "Hanks Li" <[email-masked]> said:
hli> We are working on the IDE/ATAPI for mips. When I changed to Big
hli> endian mode, the following information appared, and the program
hli> hang.

When I tried PCI-IDE in BigEndian (with 2.4.6 kernel), this patch
solved my problem.

--- linux/drivers/ide/ide-dma.c:1.1.1.1	Fri Jul  6 11:24:54 2001
+++ linux/drivers/ide/ide-dma.c	Fri Aug 17 20:17:30 2001
@@ -492,7 +492,11 @@
 			SELECT_READ_WRITE(hwif,drive,func);
 			if (!(count = ide_build_dmatable(drive, func)))
 				return 1;	/* try PIO instead of DMA */
+#if defined(__mips__) && defined(__BIG_ENDIAN) /* XXX mips only? */
+			outl(cpu_to_le32(hwif->dmatable_dma), dma_base + 4); /* PRD table */
+#else
 			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+#endif
 			outb(reading, dma_base);			/* specify r/w */
 			outb(inb(dma_base+2)|6, dma_base+2);		/* clear INTR & ERROR flags */
 			drive->waiting_for_dma = 1;
---
Atsushi Nemoto

---

From: Geert Uytterhoeven <[email-masked]>
Date: Wed, 17 Oct 2001 07:48:27 +0200 (MEST)

> +++ linux/drivers/ide/ide-dma.c	Fri Aug 17 20:17:30 2001

Since cpu_to_le32() does nothing on little endian, you can rewrite it like

    #if defined(__mips__) /* XXX mips only? */
			    outl(cpu_to_le32(hwif->dmatable_dma), dma_base + 4); /* PRD table */
    #else
			    outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
    #endif

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email-masked]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

---

From: "Gleb O. Raiko" <[email-masked]>
Date: Wed, 17 Oct 2001 13:33:35 +0400

> When I tried PCI-IDE in BigEndian (with 2.4.6 kernel), this patch

It seems you need either own version of outl and outw with byte swapping
or instruct your hw to do that itself (if your hw can, of course).

Regards,
Gleb.

---

From: Atsushi Nemoto <[email-masked]>
Date: Wed, 17 Oct 2001 20:43:58 +0900 (JST)

>>>>> On Wed, 17 Oct 2001 13:33:35 +0400, "Gleb O. Raiko" <[email-masked]> said:
raiko> It seems you need either own version of outl and outw with byte
raiko> swapping or instruct your hw to do that itself (if your hw can,
raiko> of course).

Yes, I depend on hardware swapping on word/dword access.  It seems
many pci drivers depend on this swapping too.

---
Atsushi Nemoto

---

From: "Hanks Li" <[email-masked]>
Date: Wed, 17 Oct 2001 13:52:20 -0400

Thanks Atsushi San, the patch did help. The partition check can pass now.
But my boot (such as: usb, ethernet, etc.) could not continue after solving
the IDE problem.

Could anybody give me a hint?

Thanks

Hanks Li

-----Original Message-----
From: [email-masked]
[mailto:[email-masked]]On Behalf Of Atsushi Nemoto
Sent: Tuesday, October 16, 2001 10:39 PM
To: [email-masked]
Cc: [email-masked]
Subject: Re: IDE DMA mode in Big endian for mips

---

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 18 Oct 2001 11:18:43 +0900 (JST)

>>>>> On Wed, 17 Oct 2001 20:43:58 +0900 (JST), Atsushi Nemoto <[email-masked]> said:
nemoto> Yes, I depend on hardware swapping on word/dword access.  It
nemoto> seems many pci drivers depend on this swapping too.

Sorry, last sentence might be wrong.  I doubt I have been
misunderstanding long time...

Can anybody explain me a PCI driver's policy of endianness?  Should we
use cpu_to_le32 with outl/writel?  Should we use cpu_to_le32 to write
32bit data to DMA area?

Thank you.
---
Atsushi Nemoto

---

From: Geert Uytterhoeven <[email-masked]>
Date: Thu, 18 Oct 2001 07:54:18 +0200 (MEST)

> use cpu_to_le32 with outl/writel?  Should we use cpu_to_le32 to write

The PCI bus is little-endian.
All accesses should be done using one of
  - {read,write}[bwlq]: PCI memory space
  - {in,out}[bwl]: PCI (and ISA) I/O space
  - isa_{read,write}[bwl]: ISA memory space

The functions above should take care of endian conversion.

Gr{oetje,eeting}s,

						Geert

---

From: "Gleb O. Raiko" <[email-masked]>
Date: Thu, 18 Oct 2001 14:33:33 +0400

Atsushi Nemoto wrote:
> Can anybody explain me a PCI driver's policy of endianness?  

It depens on device and board. Most drivers assume PCI is little-endian,
but rely on outl implementation in byte swapping policy.

> Should we use cpu_to_le32 with outl/writel?  

If you can't instruct hw to perform byte-swapping for PCI IO, you have
to add cpu_to_le32, it's clear. For writel, i.e. PCI MEM the situation
is a bit subtle. The problem is your videocard, that may or may not
support byte swapping. So, in order to suport videocards that aren't
able to swap bytes, you have to setup PCI MEM in big-endian mode.

Look, for example, at the tulip driver, it swaps bytes for DMA and
doesn't do it for register access.

> Should we use cpu_to_le32 to write 32bit data to DMA area?

DMA data is stream of bytes. I would treat a device/board as broken, if
it would need byte swapping for DMA data.

Regards,
Gleb.

---

From: Atsushi Nemoto <[email-masked]>
Date: Fri, 19 Oct 2001 18:54:07 +0900 (JST)

>>>>> On Thu, 18 Oct 2001 07:54:18 +0200 (MEST), Geert Uytterhoeven <[email-masked]> said:
geert> The functions above should take care of endian conversion.

This is what I wanted to know.  Thank you.

>>>>> On Wed, 17 Oct 2001 13:52:20 -0400, "Hanks Li" <[email-masked]> said:
hli> Thanks Atsushi San, the patch did help. The partition check can
hli> pass now.

Sorry, my patch is not correct.  You can configure your PCI controller
to swap dword (if your hw have this function), or you can use
CONFIG_SWAP_IO_SPACE.

If your hardware have not this function AND you want to swap entire
I/O access (for example, do swap for PCI, not for other area), you may
have to create your own version of outl/outw etc.  (This is my
case...)

---
Atsushi Nemoto

---

From: Alan Cox <[email-masked]>
Date: Sun, 21 Oct 2001 17:50:00 +0100 (BST)

>  			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */

You should actually just be able to delete the #if stuff. On an LE machine
cpu_to_le32() is a null operation