From: ted@telematics.com (Ted Goldblatt)
Subject: 68040 bus error handling question (long-ish)
Organization: Telematics Intl., Inc.; Ft. Lauderdale, FL
Date: Fri, 18 Dec 1992 22:21:01 GMT

We have run into a gotcha in a `040 board that we have built.
It replaces a `020 based board in a bus type system with off
board I/O space.  Most of the off board I/O registers are 16
bits wide.  Those that are longs cannot be written as longs, but
must be written as 2 word writes (this is enforced by the
individual I/O boards, and is true for historical reasons).
Unfortunately, not all software obeys this rule.  The original
(68010 based) processor board didn't have a problem with this
(obviously :-)).  The `020 based board did, so its address
decode logic mapped all I/O space requests (or maybe just
writes) as if they were to 16 bit ports, and used the `020's
dynamic bus sizing feature to avoid the problem.  The `040
doesn't have dynamic bus sizing, so this solution cannot be used
(yes, a 68150 would solve that problem, and we use one for board
local I/O space references, but the off board I/O is referenced
via the same data paths as memory, and we cannot afford the
performance hit of putting a `150 in this data path, or the
complexity and board space to add another parallel data path).

We are (trying to :-)) find all violations of this rule so we
can change the write to be OK, but there is concern that we
cannot find them all (and the failure modes tend to be nasty to
debug).  So far, the h/w types haven't been able to come up with
a practical all h/w solution (they _can_ detect that a violating
write was attempted, but they cannot split the write themselves).
They have suggested that they could raise TEA (and maybe latch
an error flag), and that we could (in our bus error handler)
figure out that this has happened and "fix" it in software.

If we ignore the problem of determining that the bus error _was_
due to this problem, the remaining issue is how to complete the
cycle in s/w (or rather, having done that, how to get back to
where we belong).  This involves 2 things: cleaning up any
pending writebacks, and setting things up so that the next
instruction we execute is the correct one.  It's not clear how
to do the latter.

The `020 manual (mc68020um/ad rev 1, p 6-18) has a section on
how to complete the bus cycle in software.  The `040 book
(m68040um/ad) has no such section, and very much assumes that
either the error was fatal and no recovery will be done, or that
the bus error handler will end with an RTE and re-execute the
(failing) instruction.  We can easily enough just tear down the
stack frame, but the next question would be, where do we go?
The diagram of the access error stack frame (on page 8-24) says
that the stacked PC is for the "next" instruction.  Assuming
that this means "next instruction to be executed when the RTE
occurs" rather than "instruction after the one that caused the
bus error", we need to point this to the instruction after the
one we simulated.  The problem is how do we figure this out
without putting in a fair amount of instruction decode logic
just to figure out how long the faulting instruction was?  Is
there some info in the stack frame (that we overlooked) that
would make this easier?  Even better, is there a simpler way to
do the whole bus error handling in s/w?

Thanx for any suggestions!

ted
-- 
Ted Goldblatt    ted@telematics.com     (305) 351-4367
    Telematics Intl., Inc.   Ft. Lauderdale, FL
Newsgroups: comp.sys.m68k