[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] gt64xxx: access right I/O port when activating byte
From: |
Hervé Poussineau |
Subject: |
[Qemu-devel] [PATCH] gt64xxx: access right I/O port when activating byte swapping |
Date: |
Wed, 10 Jun 2015 22:03:25 +0200 |
Incidentally, this fixes YAMON on big endian guest.
Signed-off-by: Hervé Poussineau <address@hidden>
---
hw/mips/gt64xxx_pci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 60 insertions(+), 2 deletions(-)
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 10fcca3..39dd8ff 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -176,6 +176,7 @@
/* PCI Internal */
#define GT_PCI0_CMD (0xc00 >> 2)
+#define GT_CMD_MWORDSWAP (1 << 10)
#define GT_PCI0_TOR (0xc04 >> 2)
#define GT_PCI0_BS_SCS10 (0xc08 >> 2)
#define GT_PCI0_BS_SCS32 (0xc0c >> 2)
@@ -292,6 +293,62 @@ static void gt64120_isd_mapping(GT64120State *s)
memory_region_add_subregion(get_system_memory(), s->ISD_start,
&s->ISD_mem);
}
+static uint64_t gt64120_pci_io_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ GT64120State *s = opaque;
+ uint8_t buf[4];
+
+ if (s->regs[GT_PCI0_CMD] & GT_CMD_MWORDSWAP) {
+ addr = (addr & ~3) + 4 - size - (addr & 3);
+ }
+
+ address_space_read(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
+ buf, size);
+
+ if (size == 1) {
+ return buf[0];
+ } else if (size == 2) {
+ return lduw_le_p(buf);
+ } else if (size == 4) {
+ return ldl_le_p(buf);
+ } else {
+ g_assert_not_reached();
+ }
+}
+
+static void gt64120_pci_io_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ GT64120State *s = opaque;
+ uint8_t buf[4];
+
+ if (s->regs[GT_PCI0_CMD] & GT_CMD_MWORDSWAP) {
+ addr = (addr & ~3) + 4 - size - (addr & 3);
+ }
+
+ if (size == 1) {
+ buf[0] = data;
+ } else if (size == 2) {
+ stw_le_p(buf, data);
+ } else if (size == 4) {
+ stl_le_p(buf, data);
+ } else {
+ g_assert_not_reached();
+ }
+
+ address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
+ buf, size);
+}
+
+static const MemoryRegionOps gt64120_pci_io_ops = {
+ .read = gt64120_pci_io_read,
+ .write = gt64120_pci_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl.max_access_size = 4,
+ .valid.unaligned = true,
+};
+
static void gt64120_pci_mapping(GT64120State *s)
{
/* Update PCI0IO mapping */
@@ -306,8 +363,9 @@ static void gt64120_pci_mapping(GT64120State *s)
s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) -
(s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
if (s->PCI0IO_length) {
- memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "pci0-io",
- get_system_io(), 0, s->PCI0IO_length);
+ memory_region_init_io(&s->PCI0IO_mem, OBJECT(s),
+ >64120_pci_io_ops,
+ s, "pci0-io", s->PCI0IO_length);
memory_region_add_subregion(get_system_memory(), s->PCI0IO_start,
&s->PCI0IO_mem);
}
--
2.1.4
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] gt64xxx: access right I/O port when activating byte swapping,
Hervé Poussineau <=