[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [v8][RESEND][PATCH 06/10] xen, gfx passthrough: retriev
From: |
Stefano Stabellini |
Subject: |
Re: [Qemu-devel] [v8][RESEND][PATCH 06/10] xen, gfx passthrough: retrieve VGA BIOS to work |
Date: |
Wed, 1 Jul 2015 16:51:12 +0100 |
User-agent: |
Alpine 2.02 (DEB 1266 2009-07-14) |
On Fri, 5 Jun 2015, Tiejun Chen wrote:
> Now we retrieve VGA bios like kvm stuff in qemu but we need to
> fix Device Identification in case if its not matched with the
> real IGD device since Seabios is always trying to compare this
> ID to work out VGA BIOS.
>
> Signed-off-by: Tiejun Chen <address@hidden>
Acked-by: Stefano Stabellini <address@hidden>
> hw/xen/xen_pt.c | 10 ++++++
> hw/xen/xen_pt.h | 5 +++
> hw/xen/xen_pt_graphics.c | 79
> ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 94 insertions(+)
>
> diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
> index 50bdf6f..3bf2233 100644
> --- a/hw/xen/xen_pt.c
> +++ b/hw/xen/xen_pt.c
> @@ -717,6 +717,16 @@ static int xen_pt_initfn(PCIDevice *d)
> s->memory_listener = xen_pt_memory_listener;
> s->io_listener = xen_pt_io_listener;
>
> + /* Setup VGA bios for passthrough GFX */
> + if ((s->real_device.domain == 0) && (s->real_device.bus == 0) &&
> + (s->real_device.dev == 2) && (s->real_device.func == 0)) {
> + if (xen_pt_setup_vga(s, &s->real_device) < 0) {
> + XEN_PT_ERR(d, "Setup VGA BIOS of passthrough GFX failed!\n");
> + xen_host_pci_device_put(&s->real_device);
> + return -1;
> + }
> + }
> +
> /* Handle real device's MMIO/PIO BARs */
> xen_pt_register_regions(s, &cmd);
>
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index dfa6171..6c42754 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -301,6 +301,11 @@ static inline bool
> xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
> return s->msix && s->msix->bar_index == bar;
> }
>
> +extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
> + struct Object *owner, int *size,
> + unsigned int domain,
> + unsigned int bus, unsigned int
> slot,
> + unsigned int function);
> extern bool has_igd_gfx_passthru;
> static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
> {
> diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
> index 9b3df81..3232296 100644
> --- a/hw/xen/xen_pt_graphics.c
> +++ b/hw/xen/xen_pt_graphics.c
> @@ -109,3 +109,82 @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
>
> return 0;
> }
> +
> +static void *get_vgabios(XenPCIPassthroughState *s, int *size,
> + XenHostPCIDevice *dev)
> +{
> + return pci_assign_dev_load_option_rom(&s->dev, OBJECT(&s->dev), size,
> + dev->domain, dev->bus,
> + dev->dev, dev->func);
> +}
> +
> +/* Refer to Seabios. */
> +struct rom_header {
> + uint16_t signature;
> + uint8_t size;
> + uint8_t initVector[4];
> + uint8_t reserved[17];
> + uint16_t pcioffset;
> + uint16_t pnpoffset;
> +} __attribute__((packed));
> +
> +struct pci_data {
> + uint32_t signature;
> + uint16_t vendor;
> + uint16_t device;
> + uint16_t vitaldata;
> + uint16_t dlen;
> + uint8_t drevision;
> + uint8_t class_lo;
> + uint16_t class_hi;
> + uint16_t ilen;
> + uint16_t irevision;
> + uint8_t type;
> + uint8_t indicator;
> + uint16_t reserved;
> +} __attribute__((packed));
> +
> +int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev)
> +{
> + unsigned char *bios = NULL;
> + struct rom_header *rom;
> + int bios_size;
> + char *c = NULL;
> + char checksum = 0;
> + uint32_t len = 0;
> + struct pci_data *pd = NULL;
> +
> + if (!is_igd_vga_passthrough(dev)) {
> + return -1;
> + }
> +
> + bios = get_vgabios(s, &bios_size, dev);
> + if (!bios) {
> + XEN_PT_ERR(&s->dev, "VGA: Can't getting VBIOS!\n");
> + return -1;
> + }
> +
> + /* Currently we fixed this address as a primary. */
> + rom = (struct rom_header *)bios;
> + pd = (void *)(bios + (unsigned char)rom->pcioffset);
> +
> + /* We may need to fixup Device Identification. */
> + if (pd->device != s->real_device.device_id) {
> + pd->device = s->real_device.device_id;
> +
> + len = rom->size * 512;
> + /* Then adjust the bios checksum */
> + for (c = (char *)bios; c < ((char *)bios + len); c++) {
> + checksum += *c;
> + }
> + if (checksum) {
> + bios[len - 1] -= checksum;
> + XEN_PT_LOG(&s->dev, "vga bios checksum is adjusted %x!\n",
> + checksum);
> + }
> + }
> +
> + /* Currently we fixed this address as a primary for legacy BIOS. */
> + cpu_physical_memory_rw(0xc0000, bios, bios_size, 1);
> + return 0;
> +}
> --
> 1.9.1
>
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [v8][RESEND][PATCH 06/10] xen, gfx passthrough: retrieve VGA BIOS to work,
Stefano Stabellini <=