@@ -320,38 +320,6 @@ static void gt64120_isd_mapping(GT64120State *s)
320
320
memory_region_transaction_commit ();
321
321
}
322
322
323
- static void gt64120_update_pci_cfgdata_mapping (GT64120State * s )
324
- {
325
- /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
326
- static const MemoryRegionOps * pci_host_data_ops [] = {
327
- & pci_host_data_be_ops , & pci_host_data_le_ops
328
- };
329
- PCIHostState * phb = PCI_HOST_BRIDGE (s );
330
-
331
- memory_region_transaction_begin ();
332
-
333
- /*
334
- * The setting of the MByteSwap bit and MWordSwap bit in the PCI Internal
335
- * Command Register determines how data transactions from the CPU to/from
336
- * PCI are handled along with the setting of the Endianness bit in the CPU
337
- * Configuration Register. See:
338
- * - Table 16: 32-bit PCI Transaction Endianness
339
- * - Table 158: PCI_0 Command, Offset: 0xc00
340
- */
341
-
342
- if (memory_region_is_mapped (& phb -> data_mem )) {
343
- memory_region_del_subregion (& s -> ISD_mem , & phb -> data_mem );
344
- object_unparent (OBJECT (& phb -> data_mem ));
345
- }
346
- memory_region_init_io (& phb -> data_mem , OBJECT (phb ),
347
- pci_host_data_ops [s -> regs [GT_PCI0_CMD ] & 1 ],
348
- s , "pci-conf-data" , 4 );
349
- memory_region_add_subregion_overlap (& s -> ISD_mem , GT_PCI0_CFGDATA << 2 ,
350
- & phb -> data_mem , 1 );
351
-
352
- memory_region_transaction_commit ();
353
- }
354
-
355
323
static void gt64120_pci_mapping (GT64120State * s )
356
324
{
357
325
memory_region_transaction_begin ();
@@ -645,7 +613,6 @@ static void gt64120_writel(void *opaque, hwaddr addr,
645
613
case GT_PCI0_CMD :
646
614
case GT_PCI1_CMD :
647
615
s -> regs [saddr ] = val & 0x0401fc0f ;
648
- gt64120_update_pci_cfgdata_mapping (s );
649
616
break ;
650
617
case GT_PCI0_TOR :
651
618
case GT_PCI0_BS_SCS10 :
@@ -1024,6 +991,48 @@ static const MemoryRegionOps isd_mem_ops = {
1024
991
},
1025
992
};
1026
993
994
+ static bool bswap (const GT64120State * s )
995
+ {
996
+ PCIHostState * phb = PCI_HOST_BRIDGE (s );
997
+ /*check for bus == 0 && device == 0, Bits 11:15 = Device , Bits 16:23 = Bus*/
998
+ bool is_phb_dev0 = extract32 (phb -> config_reg , 11 , 13 ) == 0 ;
999
+ bool le_mode = FIELD_EX32 (s -> regs [GT_PCI0_CMD ], GT_PCI0_CMD , MByteSwap );
1000
+ /* Only swap for non-bridge devices in big-endian mode */
1001
+ return !le_mode && !is_phb_dev0 ;
1002
+ }
1003
+
1004
+ static uint64_t gt64120_pci_data_read (void * opaque , hwaddr addr , unsigned size )
1005
+ {
1006
+ GT64120State * s = opaque ;
1007
+ uint32_t val = pci_host_data_le_ops .read (opaque , addr , size );
1008
+
1009
+ if (bswap (s )) {
1010
+ val = bswap32 (val );
1011
+ }
1012
+ return val ;
1013
+ }
1014
+
1015
+ static void gt64120_pci_data_write (void * opaque , hwaddr addr ,
1016
+ uint64_t val , unsigned size )
1017
+ {
1018
+ GT64120State * s = opaque ;
1019
+
1020
+ if (bswap (s )) {
1021
+ val = bswap32 (val );
1022
+ }
1023
+ pci_host_data_le_ops .write (opaque , addr , val , size );
1024
+ }
1025
+
1026
+ static const MemoryRegionOps gt64120_pci_data_ops = {
1027
+ .read = gt64120_pci_data_read ,
1028
+ .write = gt64120_pci_data_write ,
1029
+ .endianness = DEVICE_LITTLE_ENDIAN ,
1030
+ .valid = {
1031
+ .min_access_size = 4 ,
1032
+ .max_access_size = 4 ,
1033
+ },
1034
+ };
1035
+
1027
1036
static void gt64120_reset (DeviceState * dev )
1028
1037
{
1029
1038
GT64120State * s = GT64120_PCI_HOST_BRIDGE (dev );
@@ -1178,7 +1187,6 @@ static void gt64120_reset(DeviceState *dev)
1178
1187
1179
1188
gt64120_isd_mapping (s );
1180
1189
gt64120_pci_mapping (s );
1181
- gt64120_update_pci_cfgdata_mapping (s );
1182
1190
}
1183
1191
1184
1192
static void gt64120_realize (DeviceState * dev , Error * * errp )
@@ -1202,6 +1210,12 @@ static void gt64120_realize(DeviceState *dev, Error **errp)
1202
1210
memory_region_add_subregion_overlap (& s -> ISD_mem , GT_PCI0_CFGADDR << 2 ,
1203
1211
& phb -> conf_mem , 1 );
1204
1212
1213
+ memory_region_init_io (& phb -> data_mem , OBJECT (phb ),
1214
+ & gt64120_pci_data_ops ,
1215
+ s , "pci-conf-data" , 4 );
1216
+ memory_region_add_subregion_overlap (& s -> ISD_mem , GT_PCI0_CFGDATA << 2 ,
1217
+ & phb -> data_mem , 1 );
1218
+
1205
1219
1206
1220
/*
1207
1221
* The whole address space decoded by the GT-64120A doesn't generate
0 commit comments