Quoting David Gibson (2015-02-09 22:36:16) > When the guest switches the interrupt endian mode, which essentially > means a global machine endian switch, we want to change the VGA > framebuffer endian mode as well in order to be backward compatible > with existing guests who don't know about the new endian control > register. > > Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org> > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au>
I think maybe Gerd's review applied to the whole series, but: Reviewed-by: Michael Roth <mdr...@linux.vnet.ibm.com> > --- > hw/ppc/spapr_hcall.c | 2 ++ > hw/ppc/spapr_pci.c | 28 ++++++++++++++++++++++++++++ > include/hw/ppc/spapr.h | 1 + > 3 files changed, 31 insertions(+) > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index 8651447..4f76f1c 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -731,12 +731,14 @@ static target_ulong h_set_mode_resource_le(PowerPCCPU > *cpu, > CPU_FOREACH(cs) { > set_spr(cs, SPR_LPCR, 0, LPCR_ILE); > } > + spapr_pci_switch_vga(true); > return H_SUCCESS; > > case H_SET_MODE_ENDIAN_LITTLE: > CPU_FOREACH(cs) { > set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE); > } > + spapr_pci_switch_vga(false); > return H_SUCCESS; > } > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c > index 21b95b3..acf9e82 100644 > --- a/hw/ppc/spapr_pci.c > +++ b/hw/ppc/spapr_pci.c > @@ -966,3 +966,31 @@ static void spapr_pci_register_types(void) > } > > type_init(spapr_pci_register_types) > + > +static int spapr_switch_one_vga(DeviceState *dev, void *opaque) > +{ > + bool be = *(bool *)opaque; > + > + if (object_dynamic_cast(OBJECT(dev), "VGA") > + || object_dynamic_cast(OBJECT(dev), "secondary-vga")) { > + object_property_set_bool(OBJECT(dev), be, "big-endian-framebuffer", > + &error_abort); > + } > + return 0; > +} > + > +void spapr_pci_switch_vga(bool big_endian) > +{ > + sPAPRPHBState *sphb; > + > + /* > + * For backward compatibility with existing guests, we switch > + * the endianness of the VGA controller when changing the guest > + * interrupt mode > + */ > + QLIST_FOREACH(sphb, &spapr->phbs, list) { > + BusState *bus = &PCI_HOST_BRIDGE(sphb)->bus->qbus; > + qbus_walk_children(bus, spapr_switch_one_vga, NULL, NULL, NULL, > + &big_endian); > + } > +} > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 716bff4..6aadc94 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -480,5 +480,6 @@ int spapr_dma_dt(void *fdt, int node_off, const char > *propname, > uint32_t liobn, uint64_t window, uint32_t size); > int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, > sPAPRTCETable *tcet); > +void spapr_pci_switch_vga(bool big_endian); > > #endif /* !defined (__HW_SPAPR_H__) */ > -- > 2.1.0