gt64xxx: access right I/O port when activating byte swapping
PATCH 1/1 gt64xxx: access right I/O port when activating byte swapping
Incidentally, this fixes YAMON on big endian guest.
Signed-off-by Hervé Poussineau <[email protected]>
--- hw/mips/gt64xxx_pci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-)
hw/mips/gt64xxx_pci.c +60 -2
@@ -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 ] >_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 ] >_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); }
Signature · 1 line
2.1.4