On 12/16/14 20:49, Paolo Bonzini wrote: > > > On 16/12/2014 20:00, Laszlo Ersek wrote: >> Yes. >> >> The root of this question is what each of >> >> enum device_endian { >> DEVICE_NATIVE_ENDIAN, >> DEVICE_BIG_ENDIAN, >> DEVICE_LITTLE_ENDIAN, >> }; > > Actually, I think the root of the answer :) is that fw_cfg_read (and > thus fw_cfg_data_mem_read) is not idempotent. The split/compose stuff > accesses the bytes at offsets 8,9,10,11,12,13,14,15 and composes them > according to the endianness. > > In the case of fw_cfg it just retrieves 8 bytes, but in the case of host > big endian it reads them in the "wrong" order for some reason (sorry, I > haven't looked at this thoroughly).
I can't imagine how that would happen; fw_cfg_data_mem_read() ignores both "addr" and "size", and fw_cfg_read() simply advances the "cur_offset" member. > So the solution is: > > 1) make fw_cfg_data_mem_ops DEVICE_LITTLE_ENDIAN > > 2) make fw_cfg_data_mem_read and fw_cfg_data_mem_write call fw_cfg_read > and fw_cfg_write SIZE times and build up a value from the lowest byte up. Nonetheless, that's a really nice idea! I got so stuck with the automatic splitting that I forgot about the possibility to act upon the "size" parameter in fw_cfg_data_mem_read(). Thanks! ... Another thing that Andrew mentioned but I didn't cover in my other email -- what about fw_cfg_ctl_mem_ops? It's currently DEVICE_NATIVE_ENDIAN. You flipped the combined ops to LE in commit 6fdf98f2 (and, apparently, I reviewed it). Shouldn't we do the same for the standalone selector? Thanks Laszlo