qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/3] vga-pci: add qext region to mmio


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH 3/3] vga-pci: add qext region to mmio
Date: Mon, 29 Sep 2014 19:18:36 +0300

On Tue, Sep 23, 2014 at 02:30:57PM +0200, Gerd Hoffmann wrote:
> Add a qemu extented register range to the standard vga mmio bar.
> Right nowe there are two registers:  One readonly register returning the
> size of the region (so we can easily add more registers there if needed)
> and one endian control register, so guests (especially ppc) can flip
> the framebuffer endianness as they need it.
> 
> Signed-off-by: Gerd Hoffmann <address@hidden>
> ---
>  docs/specs/standard-vga.txt |  9 ++++++
>  hw/display/vga-pci.c        | 68 
> +++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/i386/pc.h        |  8 ++++++
>  3 files changed, 85 insertions(+)
> 
> diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt
> index f82773e..19d2a74 100644
> --- a/docs/specs/standard-vga.txt
> +++ b/docs/specs/standard-vga.txt
> @@ -70,3 +70,12 @@ Likewise applies to the pci variant only for obvious 
> reasons.
>  0500 - 0515 : bochs dispi interface registers, mapped flat
>                without index/data ports.  Use (index << 1)
>                as offset for (16bit) register access.
> +
> +0600 - 0607 : qemu extended registers.  qemu 2.2+ only.
> +              The pci revision is 2 (or greater) when
> +              these registers are present.  The registers
> +              are 32bit.
> +  0600      : qemu extended register region size, in bytes.
> +  0604      : framebuffer endianness register.
> +              - 0xbebebebe indicates big endian.
> +              - 0x1e1e1e1e indicates little endian.
> diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
> index 0351d94..3394ec2 100644
> --- a/hw/display/vga-pci.c
> +++ b/hw/display/vga-pci.c
> @@ -35,10 +35,18 @@
>  #define PCI_VGA_IOPORT_SIZE   (0x3e0 - 0x3c0)
>  #define PCI_VGA_BOCHS_OFFSET  0x500
>  #define PCI_VGA_BOCHS_SIZE    (0x0b * 2)
> +#define PCI_VGA_QEXT_OFFSET   0x600
> +#define PCI_VGA_QEXT_SIZE     (2 * 4)
>  #define PCI_VGA_MMIO_SIZE     0x1000
>  
> +#define PCI_VGA_QEXT_REG_SIZE         (0 * 4)
> +#define PCI_VGA_QEXT_REG_BYTEORDER    (1 * 4)
> +#define  PCI_VGA_QEXT_LITTLE_ENDIAN   0x1e1e1e1e
> +#define  PCI_VGA_QEXT_BIG_ENDIAN      0xbebebebe
> +
>  enum vga_pci_flags {
>      PCI_VGA_FLAG_ENABLE_MMIO = 1,
> +    PCI_VGA_FLAG_ENABLE_QEXT = 2,
>  };
>  
>  typedef struct PCIVGAState {
> @@ -48,6 +56,7 @@ typedef struct PCIVGAState {
>      MemoryRegion mmio;
>      MemoryRegion ioport;
>      MemoryRegion bochs;
> +    MemoryRegion qext;
>  } PCIVGAState;
>  
>  static const VMStateDescription vmstate_vga_pci = {
> @@ -140,6 +149,46 @@ static const MemoryRegionOps pci_vga_bochs_ops = {
>      .endianness = DEVICE_LITTLE_ENDIAN,
>  };
>  
> +static uint64_t pci_vga_qext_read(void *ptr, hwaddr addr, unsigned size)
> +{
> +    PCIVGAState *d = ptr;
> +
> +    switch (addr) {
> +    case PCI_VGA_QEXT_REG_SIZE:
> +        return PCI_VGA_QEXT_SIZE;
> +    case PCI_VGA_QEXT_REG_BYTEORDER:
> +        return d->vga.big_endian_fb ?
> +            PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
> +    default:
> +        return 0;
> +    }
> +}
> +
> +static void pci_vga_qext_write(void *ptr, hwaddr addr,
> +                               uint64_t val, unsigned size)
> +{
> +    PCIVGAState *d = ptr;
> +
> +    switch (addr) {
> +    case PCI_VGA_QEXT_REG_BYTEORDER:
> +        if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
> +            d->vga.big_endian_fb = true;
> +        }
> +        if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
> +            d->vga.big_endian_fb = false;
> +        }
> +        break;
> +    }
> +}
> +
> +static const MemoryRegionOps pci_vga_qext_ops = {
> +    .read = pci_vga_qext_read,
> +    .write = pci_vga_qext_write,
> +    .valid.min_access_size = 4,
> +    .valid.max_access_size = 4,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
>  static int pci_std_vga_initfn(PCIDevice *dev)
>  {
>      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
> @@ -167,6 +216,15 @@ static int pci_std_vga_initfn(PCIDevice *dev)
>                                      &d->ioport);
>          memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
>                                      &d->bochs);
> +
> +        if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
> +            memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
> +                                  "qemu extended regs", PCI_VGA_QEXT_SIZE);
> +            memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
> +                                        &d->qext);
> +            pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
> +        }
> +
>          pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, 
> &d->mmio);
>      }
>  
> @@ -199,6 +257,14 @@ static int pci_secondary_vga_initfn(PCIDevice *dev)
>      memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
>                                  &d->bochs);
>  
> +    if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
> +        memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
> +                              "qemu extended regs", PCI_VGA_QEXT_SIZE);
> +        memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
> +                                    &d->qext);
> +        pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
> +    }
> +
>      pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
>      pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
>  
> @@ -215,11 +281,13 @@ static void pci_secondary_vga_reset(DeviceState *dev)
>  static Property vga_pci_properties[] = {
>      DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
>      DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, 
> true),
> +    DEFINE_PROP_BIT("qext", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, 
> true),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
>  static Property secondary_pci_properties[] = {
>      DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
> +    DEFINE_PROP_BIT("qext", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, 
> true),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 77316d5..23acc1f 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -306,6 +306,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t 
> *);
>              .driver   = "intel-hda",\
>              .property = "old_msi_addr",\
>              .value    = "on",\
> +        },{\
> +            .driver   = "VGA",\
> +            .property = "qext",\
> +            .value    = "off",\

I'd prefer a more friendly name like "qemu-extended-registers".
There's very little documentation for properties besides
the name, so the name has to be explicit.


> +        },{\
> +            .driver   = "secondary-vga",\
> +            .property = "qext",\
> +            .value    = "off",\
>          }
>  
>  #define PC_COMPAT_2_0 \
> -- 
> 1.8.3.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]