From: Philippe Mathieu-Daudé Date: Mon, 22 Dec 2025 09:08:50 +0000 (+0100) Subject: system/ioport: Declare x86-specific I/O port in little-endian order X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35ddb78b65802a9ea0166ea494b829529fadbbf4;p=thirdparty%2Fqemu.git system/ioport: Declare x86-specific I/O port in little-endian order X86 in/out port (related to ISA bus) uses little endianness: - enforce little endianness in x86 cpu_in/out() accessors, - serialize QTest in/out port accesses as little-endian. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Fabiano Rosas Reviewed-by: Richard Henderson Message-ID: <20260109165058.59144-22-philmd@linaro.org> --- diff --git a/system/ioport.c b/system/ioport.c index 801e2490c3..4b94f2f811 100644 --- a/system/ioport.c +++ b/system/ioport.c @@ -56,7 +56,7 @@ static void unassigned_io_write(void *opaque, hwaddr addr, uint64_t val, const MemoryRegionOps unassigned_io_ops = { .read = unassigned_io_read, .write = unassigned_io_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; void cpu_outb(uint32_t addr, uint8_t val) @@ -71,7 +71,7 @@ void cpu_outw(uint32_t addr, uint16_t val) uint8_t buf[2]; trace_cpu_out(addr, 'w', val); - stw_p(buf, val); + stw_le_p(buf, val); address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 2); } @@ -81,7 +81,7 @@ void cpu_outl(uint32_t addr, uint32_t val) uint8_t buf[4]; trace_cpu_out(addr, 'l', val); - stl_p(buf, val); + stl_le_p(buf, val); address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 4); } @@ -102,7 +102,7 @@ uint16_t cpu_inw(uint32_t addr) uint16_t val; address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 2); - val = lduw_p(buf); + val = lduw_le_p(buf); trace_cpu_in(addr, 'w', val); return val; } @@ -113,7 +113,7 @@ uint32_t cpu_inl(uint32_t addr) uint32_t val; address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED, buf, 4); - val = ldl_p(buf); + val = ldl_le_p(buf); trace_cpu_in(addr, 'l', val); return val; } diff --git a/tests/qtest/endianness-test.c b/tests/qtest/endianness-test.c index 222d116fae..2b2f92099d 100644 --- a/tests/qtest/endianness-test.c +++ b/tests/qtest/endianness-test.c @@ -65,8 +65,9 @@ static uint16_t isa_inw(QTestState *qts, const TestCase *test, uint16_t addr) value = qtest_inw(qts, addr); } else { value = qtest_readw(qts, test->isa_base + addr); + value = test->bswap ? bswap16(value) : value; } - return test->bswap ? bswap16(value) : value; + return value; } static uint32_t isa_inl(QTestState *qts, const TestCase *test, uint16_t addr) @@ -76,8 +77,9 @@ static uint32_t isa_inl(QTestState *qts, const TestCase *test, uint16_t addr) value = qtest_inl(qts, addr); } else { value = qtest_readl(qts, test->isa_base + addr); + value = test->bswap ? bswap32(value) : value; } - return test->bswap ? bswap32(value) : value; + return value; } static void isa_outb(QTestState *qts, const TestCase *test, uint16_t addr, @@ -93,10 +95,10 @@ static void isa_outb(QTestState *qts, const TestCase *test, uint16_t addr, static void isa_outw(QTestState *qts, const TestCase *test, uint16_t addr, uint16_t value) { - value = test->bswap ? bswap16(value) : value; if (test->isa_base == -1) { qtest_outw(qts, addr, value); } else { + value = test->bswap ? bswap16(value) : value; qtest_writew(qts, test->isa_base + addr, value); } } @@ -104,10 +106,10 @@ static void isa_outw(QTestState *qts, const TestCase *test, uint16_t addr, static void isa_outl(QTestState *qts, const TestCase *test, uint16_t addr, uint32_t value) { - value = test->bswap ? bswap32(value) : value; if (test->isa_base == -1) { qtest_outl(qts, addr, value); } else { + value = test->bswap ? bswap32(value) : value; qtest_writel(qts, test->isa_base + addr, value); } } diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 622464e365..132aa51137 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -31,6 +31,7 @@ #include "libqtest.h" #include "libqmp.h" #include "qemu/accel.h" +#include "qemu/bswap.h" #include "qemu/ctype.h" #include "qemu/cutils.h" #include "qemu/exit-with-parent.h" @@ -1190,12 +1191,12 @@ void qtest_outb(QTestState *s, uint16_t addr, uint8_t value) void qtest_outw(QTestState *s, uint16_t addr, uint16_t value) { - qtest_out(s, "outw", addr, value); + qtest_out(s, "outw", addr, qtest_big_endian(s) ? bswap16(value) : value); } void qtest_outl(QTestState *s, uint16_t addr, uint32_t value) { - qtest_out(s, "outl", addr, value); + qtest_out(s, "outl", addr, qtest_big_endian(s) ? bswap32(value) : value); } static uint32_t qtest_in(QTestState *s, const char *cmd, uint16_t addr) @@ -1220,12 +1221,16 @@ uint8_t qtest_inb(QTestState *s, uint16_t addr) uint16_t qtest_inw(QTestState *s, uint16_t addr) { - return qtest_in(s, "inw", addr); + uint16_t v = qtest_in(s, "inw", addr); + + return qtest_big_endian(s) ? bswap16(v) : v; } uint32_t qtest_inl(QTestState *s, uint16_t addr) { - return qtest_in(s, "inl", addr); + uint32_t v = qtest_in(s, "inl", addr); + + return qtest_big_endian(s) ? bswap32(v) : v; } static void qtest_write(QTestState *s, const char *cmd, uint64_t addr,