[Freemint-list] Broken udelay() for m68000
Miro Kropáček
miro.kropacek at gmail.com
Sat Oct 14 07:20:50 MSD 2017
While investigating https://github.com/freemint/freemint/issues/70 I have
come to an interesting discovery. Earlier commits seemed to have a bug, a
000 compiled module wouldn't run with 060 compiled usb.km (it raised a lot
of SIGFPEs, as seen on the screenshots).
I thought the issue is still there as it is still required to compile
netusbee.ucd with 020+ CFLAGS. To my surprise, there's no trace of SIGFPEs
anymore and yet the module isn't working.
After some digging and comparing logs I have found the *real* cause of
this: udelay() doesn't work very reliably on m68000. Even David Galvez
complained he couldn't get NetUSBee working due to timing issues. Well, no
wonder, there's no timing at all!
The problematic part is here:
https://github.com/freemint/freemint/blob/master/sys/usb/src.km/ucd/netusbee/isp116x-hcd.c#L1552
... this is supposed to wait 4ms and try again.
mdelay(n) calls udelay(n * 1000) and this results, attention attention, to
totally different code on 000 and 020+:
# if defined (__M68020__)
register ulong tmp;
usecs *= 4295; /* 2**32 / 1000000 */
__asm__
(
"mulul %2,%0:%1"
: "=d" (usecs), "=d" (tmp)
: "d" (usecs), "1" (loops_per_sec)
);
__delay (usecs);
# else /* M68000 */
__delay(usecs); /* Sigh */
# endif
where __delay() is defined as:
__asm__ __volatile__
(
"1: subql #1,%0; jcc 1b"
: "=d" (loops)
: "0" (loops)
);
Basically, mdelay(n) on m68000 equals to doing n*1000 dummy loops. How is
this supposed to work? (on 020+ too, for that matter)
--
MiKRO / Mystic Bytes
http://mikro.atari.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.atariforge.org/pipermail/freemint-list/attachments/20171014/ba72801d/attachment.html
More information about the Freemint-list
mailing list