Subject: The elink3 bug
To: None <port-i386@NetBSD.ORG>
From: Frank van der Linden <frank@wins.uva.nl>
List: port-i386
Date: 08/17/1997 23:37:53
I've done some investigating into the elink3 (ep driver) related crashes,
and found the following:
- Removing the do { } while around mbuf macros did not result
in different code for elink3.o. Perhaps it avoided the problem
by changing code in other places slightly.
- What was wrong, is the emitted code for bus_space_write_multi_X,
as also noted recently by Dave Huang (see message on tech-kern)
- bus_space_write_multi_X clobbers the esi, ecx and eax
registers, and correctly marks them as such. It leaves
the choice for which register will point to the destination
up to gcc.
- This seems to affect elink3.c in particular, because it
uses bus_space_write_multi (possibly) into PCI space.
The PIO part of bus_space_write_multi is fine.
- Somehow, gcc picks eax, which is obviously incorrect, since
it as marked as clobbered (the lodsb instruction overwrites it)
- What's also bad, is that the value that goes into eax is
a variable that was already 'appointed' to be a register
variable in edi, so it could just have used edi, and
saved itself a move instruction.
- After individually disabling all extra optimizations that
-O2 uses over -O, I found that -fno-force-mem makes
gcc do the right thing. I can't be 100% sure that this
is the correct fix at the moment, but could people who have
had this problem perhaps try compiling their kernel with
-fno-force-mem and tell me what happens? This may apply to
other weird bugs too.
- Frank