On Mon, Jan 16, 2012 at 5:08 PM, Anthony Liguori <anth...@codemonkey.ws> wrote: > On 01/16/2012 10:59 AM, Stefan Hajnoczi wrote: >> >> On Fri, Jan 13, 2012 at 6:32 PM, Anthony Liguori<aligu...@us.ibm.com> >> wrote: >>> >>> + if (strcmp(words[0], "outb") == 0 || >>> + strcmp(words[0], "outw") == 0 || >>> + strcmp(words[0], "outl") == 0) { >>> + uint16_t addr; >>> + uint32_t value; >>> + >>> + g_assert(words[1]&& words[2]); >>> + addr = strtol(words[1], NULL, 0); >>> + value = strtol(words[2], NULL, 0); >>> + >>> + if (words[0][3] == 'b') { >>> + cpu_outb(addr, value); >>> + } else if (words[0][3] == 'w') { >>> + cpu_outw(addr, value); >>> + } else if (words[0][3] == 'l') { >>> + cpu_outl(addr, value); >>> + } >>> + qtest_send_prefix(chr); >>> + qtest_send(chr, "OK\n"); >>> + } else if (strcmp(words[0], "inb") == 0 || >>> + strcmp(words[0], "inw") == 0 || >>> + strcmp(words[0], "inl") == 0) { >>> + uint16_t addr; >>> + uint32_t value = -1U; >>> + >>> + g_assert(words[1]); >>> + addr = strtol(words[1], NULL, 0); >>> + >>> + if (words[0][2] == 'b') { >>> + value = cpu_inb(addr); >>> + } else if (words[0][2] == 'w') { >>> + value = cpu_inw(addr); >>> + } else if (words[0][2] == 'l') { >>> + value = cpu_inl(addr); >>> + } >>> + qtest_send_prefix(chr); >>> + qtest_send(chr, "OK 0x%04x\n", value); >> >> >> Endianness is a little weird here. memory.c will byteswap if target >> and device endianness differ. >> >> Imagine the case where we're on an x86 host, running a ppc guest, >> reading from PCI configuration space (little-endian). > > > These functions expect to get host native endian. The qtest wire protocol > is a string (which has no endianness) and converts it to host native endian.
The cpu_inl() return value is not host native endian. We perform a byteswap if the memory region endianness is different from the target endianness. For example, big-endian target and little-endian device means we byteswap. Little-endian target and little-endian device means we do not byteswap. Running the same test binary against qemu-system-x86_64 and qemu-system-$be_arch results in 0 and 1 byteswaps, respectively. Both can't be right. >> Since ppc >> (target endian) is big-endian and the device is little-endian the >> value read/written will be byteswapped. However, our qtest runs on >> the host and therefore we don't want that automatic swap (or we need >> to neutralize it by performing another byteswap on top). > > > ppc wouldn't use outb/inb. It would do mmio to the PIO region which would > send it through the host controller (which would do byte swapping as > necessary). > > So a qtest test case would have to do little endian MMIO to interact with > the PCI bus. Maybe ppc is a bad example, but are there other targets where in/out is used? Stefan