[Simh] Unaligned references to IO space

Bob Supnik bob at supnik.org
Tue Nov 12 09:51:07 EST 2013


A bug was reported that Ultrix conversational boot fails because the 
handling of unaligned references into IO space was incorrect. The issue 
is that the unaligned code in vax_mmu.c issues a pair of longword reads 
surrounding the unaligned reference, but the Qbus IO routine sees the 
full address (with <1:0> intact) and tries to fetch two sequential 16b 
words starting at the odd word address. The suggested fix was to force 
alignment of the PA by zeroing <1:0> for the unaligned reads. 
Unfortunately, the problem is much more complex, and that fix won't work 
as a general solution.

First of all, the VAX Architecture Spec (DEC STD 032) says of IO space:

"References using a length attribute other than the length of the 
register, or to unaligned addresses, may produce UNPREDICTABLE results."

The code is question is doing a BLBC (longword operand) on a 16b 
register as its odd byte address. This seems to be the result of an 
"optimization" in the C compiler going awry. The code should have 
generated a BITW #xyz,register.

Second, the handling of unaligned longword references, in CVAX anyway, 
is much more nuanced than fetching 8 bytes all the time. CVAX doesn't 
use the low order two bits of the physical address at all; it uses 
bits<29:2> and then a four bit byte mask to indicate which bytes are 
wanted. So an aligned longword read would generate:

pa<29:2> + 1111

while an aligned word read would generate:

pa<29:2> + 0011 or 1100, depending on which half is needed

while a byte read would generate

pa<29:2> + 0001 or 0010 or 0100 or 1000

Unaligned longword reads generate a pair of longword reads:

pa<29:2> +     1110/1100/1000
pa<29:2>+1 + 0001/0011/0111

This is important because the QBus interface generates the transaction 
based on the byte mask, NOT the length. To look at the details for 
unaligned longword read:

pa<1:0> = 01 - generates pa<29:2> + 1110, creating 2 Qbus reads
                        - generates pa<29:2>+1 + 0001, creating 1 Qbus 
read - the upper word isn't read because the byte masks are 0

pa<1:0> = 10 - generates pa<29:2> + 1100, creating 1 Qbus read - the 
lower word isn't read
                        - generates pa<29:2>+1 + 0011, creating 1 Qbus 
read - the upper word isn't read

pa<1:0> = 11 - generates pa<29:2> + 1000, creating 1 Qbus read - the 
lower word isn't read
                        - generates pa<29:2>+1 + 0111, creating 2 Qbus 
reads

The reason this matters is that Qbus reads can have side effects. So if 
a read transaction occurs that wasn't expected, it can mess up state. 
Admittedly, this is not likely, but it can happen and apparently does in 
the QDSS code.

Thus, the unaligned flows are wrong, at least for CVAX. The simulator 
uses PA<1:0> plus length (forced to longword in the unaligned case) as a 
substitute for byte mask. This doesn't work when going to IO space; 
there's not enough detail preserved to parse the second reference 
properly. The simulator will generate 4 Qbus operations on an unaligned 
reference, when in fact either 2 or 3 occur. Ugh! I am not at all sure 
how to fix this. The standard Read and Write routines don't pass enough 
information to lower-level routines to figure out what's going on.

The current fix breaks the 780 as well. Nexus adapters only support 
aligned longword operations and detect unaligned operations by looking 
at address<1:0>. Unibus IO space only supports aligned word and byte 
operations.

One possibility is to make the unaligned flows more nuanced, and fetch 
exactly as many words/longwords as are needed for the extraction. 
However, I suspect that fixing this properly will require generalization 
of the vax_mmu.c Read and Write unaligned flows. I will probably need to 
add a model-dependent test to see whether unaligned non-memory 
references need special handling, and then add model-dependent routines 
for unaligned IO references. This will allow passing enough information 
to create the correct behavior.

This would be fine for my version of the simulator, which just has two 
models. However, I understand that the GIT pool now has many other 
models, and all of them would be affected by this change. Further, the 
authors would need to understand the behavior of unaligned IO space 
accesses, which is quite difficult without going through schematics.

/Bob Supnik



More information about the Simh mailing list