You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The issue is that writing 32 bit to 0x01000000 will only trigger one MMIO callback. As the size is wrong for control_a some code might choose to ignore this. In other cases, the size is not checked, and control_a gets a value which is far too big for it to handle.
Also, given the example from before, there is no additional callback for access to control_b and control_c as the code often looks like:
(Callback is only executed for address == CONTROL_A)
The first time I've encountered this was in AC97 when trying to use OpenXDK.
The OpenXDK audio code does access more than 1 register at a time atomically by writing 32 bits at once (almost exactly like my example above).
The AC97 issue in particular should be fixed upstream, as it also affects QEMU.
However, I'm sure we have other cases in our own Xbox specific code too.
These problems are insanely hard to track and we should always at least assert for the expected size.
I did not look for other existing solutions to this problem.
It's possible that QEMU already has some way of dealing with this somehow.
My workaround for AC97 (not implemented in XQEMU at time of writing), was to manually loop over all affected registers.
The reason we don't see this problem more often is because most operating systems have only one function to access such standard hardware registers. So implementing only one way to access a register is fine most of the time.
The text was updated successfully, but these errors were encountered:
@PatrickvL Only for the nVidia cards and only for reads. 86Box actually deals with this by having up to 6 MMIO handlers. One is 8-bit reads, one is 8-bit writes, one is 16-bit reads, and so on.
QEMUs MMIO design is quite horrible. Let me provide an example MMIO interface with address, type and use:
0x01000000:
uint8_t control_a
0x01000001:
uint8_t control_b
0x01000002:
uint16_t control_c
The issue is that writing 32 bit to 0x01000000 will only trigger one MMIO callback. As the size is wrong for
control_a
some code might choose to ignore this. In other cases, the size is not checked, andcontrol_a
gets a value which is far too big for it to handle.Also, given the example from before, there is no additional callback for access to
control_b
andcontrol_c
as the code often looks like:(Callback is only executed for
address == CONTROL_A
)The first time I've encountered this was in AC97 when trying to use OpenXDK.
The OpenXDK audio code does access more than 1 register at a time atomically by writing 32 bits at once (almost exactly like my example above).
The AC97 issue in particular should be fixed upstream, as it also affects QEMU.
However, I'm sure we have other cases in our own Xbox specific code too.
These problems are insanely hard to track and we should always at least
assert
for the expected size.I did not look for other existing solutions to this problem.
It's possible that QEMU already has some way of dealing with this somehow.
My workaround for AC97 (not implemented in XQEMU at time of writing), was to manually loop over all affected registers.
The reason we don't see this problem more often is because most operating systems have only one function to access such standard hardware registers. So implementing only one way to access a register is fine most of the time.
The text was updated successfully, but these errors were encountered: