diff mbox series

[v2,1/2] hw/pci-host/gt64120: Fix PCI I/O config register endianness

Message ID 20230118095751.49728-2-philmd@linaro.org
State New
Headers show
Series hw/pci-host/gt64120: Fix regression on big-endian targets | expand

Commit Message

Philippe Mathieu-Daudé Jan. 18, 2023, 9:57 a.m. UTC
The MByteSwap bit only affects the data register endianness,
not the config register. Map the config register once in the
gt64120_realize() handler, and only remap the data register
when the mapping is updated.

Fixes: 145e2198d7 ("gt64xxx: Endian-swap using PCI_HOST_BRIDGE MemoryRegionOps")
Reported-by: Klaus Jensen <its@irrelevant.dk>
Tested-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 hw/pci-host/gt64120.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

Comments

Philippe Mathieu-Daudé Jan. 18, 2023, 11:08 a.m. UTC | #1
On 18/1/23 10:57, Philippe Mathieu-Daudé wrote:
> The MByteSwap bit only affects the data register endianness,
> not the config register. Map the config register once in the
> gt64120_realize() handler, and only remap the data register
> when the mapping is updated.
> 
> Fixes: 145e2198d7 ("gt64xxx: Endian-swap using PCI_HOST_BRIDGE MemoryRegionOps")
> Reported-by: Klaus Jensen <its@irrelevant.dk>
> Tested-by: Klaus Jensen <k.jensen@samsung.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   hw/pci-host/gt64120.c | 25 +++++++------------------
>   1 file changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
> index f226d03420..36ed01c615 100644
> --- a/hw/pci-host/gt64120.c
> +++ b/hw/pci-host/gt64120.c
> @@ -320,13 +320,6 @@ static void gt64120_isd_mapping(GT64120State *s)
>   
>   static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
>   {
> -    /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
> -    static const MemoryRegionOps *pci_host_conf_ops[] = {
> -        &pci_host_conf_be_ops, &pci_host_conf_le_ops
> -    };
> -    static const MemoryRegionOps *pci_host_data_ops[] = {
> -        &pci_host_data_be_ops, &pci_host_data_le_ops
> -    };
>       PCIHostState *phb = PCI_HOST_BRIDGE(s);
>   
>       memory_region_transaction_begin();
> @@ -339,22 +332,13 @@ static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
>        * - Table 16: 32-bit PCI Transaction Endianess
>        * - Table 158: PCI_0 Command, Offset: 0xc00
>        */
> -    if (memory_region_is_mapped(&phb->conf_mem)) {
> -        memory_region_del_subregion(&s->ISD_mem, &phb->conf_mem);
> -        object_unparent(OBJECT(&phb->conf_mem));
> -    }
> -    memory_region_init_io(&phb->conf_mem, OBJECT(phb),
> -                          pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1],
> -                          s, "pci-conf-idx", 4);
> -    memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
> -                                        &phb->conf_mem, 1);
> -
>       if (memory_region_is_mapped(&phb->data_mem)) {
>           memory_region_del_subregion(&s->ISD_mem, &phb->data_mem);
>           object_unparent(OBJECT(&phb->data_mem));
>       }

Self-NACK since the config space reads are swapped:

   $ lspci -v
- 00:00.0 Host bridge: Marvell Technology Group Ltd. 
GT-64120/64120A/64121A System Controller (rev 10)
-     Subsystem: Red Hat, Inc Device 1100
-     Flags: medium devsel
-     Memory at <unassigned> (32-bit, prefetchable) [disabled]
-     Memory at 01000000 (32-bit, prefetchable) [disabled] [size=16M]
-     Memory at <ignored> (32-bit, non-prefetchable) [disabled]
-     Memory at <ignored> (32-bit, non-prefetchable) [disabled]
-     Memory at <ignored> (32-bit, non-prefetchable) [disabled]
-     I/O ports at <ignored> [disabled]
+ 00:00.0 Network and computing encryption device: Device 2046:ab11 (rev 06)
+     Subsystem: Device 0011:f41a
+     Flags: fast devsel
+     Memory at <ignored> (32-bit, non-prefetchable)
+     I/O ports at <ignored> [disabled]
+     Memory at 10040020 (64-bit, prefetchable) [size=16]
+     Memory at 10040030 (64-bit, non-prefetchable) [size=16]
diff mbox series

Patch

diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
index f226d03420..36ed01c615 100644
--- a/hw/pci-host/gt64120.c
+++ b/hw/pci-host/gt64120.c
@@ -320,13 +320,6 @@  static void gt64120_isd_mapping(GT64120State *s)
 
 static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
 {
-    /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
-    static const MemoryRegionOps *pci_host_conf_ops[] = {
-        &pci_host_conf_be_ops, &pci_host_conf_le_ops
-    };
-    static const MemoryRegionOps *pci_host_data_ops[] = {
-        &pci_host_data_be_ops, &pci_host_data_le_ops
-    };
     PCIHostState *phb = PCI_HOST_BRIDGE(s);
 
     memory_region_transaction_begin();
@@ -339,22 +332,13 @@  static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
      * - Table 16: 32-bit PCI Transaction Endianess
      * - Table 158: PCI_0 Command, Offset: 0xc00
      */
-    if (memory_region_is_mapped(&phb->conf_mem)) {
-        memory_region_del_subregion(&s->ISD_mem, &phb->conf_mem);
-        object_unparent(OBJECT(&phb->conf_mem));
-    }
-    memory_region_init_io(&phb->conf_mem, OBJECT(phb),
-                          pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1],
-                          s, "pci-conf-idx", 4);
-    memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
-                                        &phb->conf_mem, 1);
-
     if (memory_region_is_mapped(&phb->data_mem)) {
         memory_region_del_subregion(&s->ISD_mem, &phb->data_mem);
         object_unparent(OBJECT(&phb->data_mem));
     }
     memory_region_init_io(&phb->data_mem, OBJECT(phb),
-                          pci_host_data_ops[s->regs[GT_PCI0_CMD] & 1],
+                          (s->regs[GT_PCI0_CMD] & 1) ? &pci_host_data_le_ops
+                                                     : &pci_host_data_be_ops,
                           s, "pci-conf-data", 4);
     memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2,
                                         &phb->data_mem, 1);
@@ -1207,6 +1191,11 @@  static void gt64120_realize(DeviceState *dev, Error **errp)
                                 get_system_io(),
                                 PCI_DEVFN(18, 0), TYPE_PCI_BUS);
 
+    memory_region_init_io(&phb->conf_mem, OBJECT(phb), &pci_host_conf_le_ops,
+                          s, "pci-conf-idx", 4);
+    memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
+                                        &phb->conf_mem, 1);
+
     pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
 
     /*