Commit 63e3e24d authored by Gerd Hoffmann's avatar Gerd Hoffmann
Browse files

vga: add secondary stdvga variant



Add a standard vga variant which doesn't occupy any legacy
resources and thus can easily be used as secondary (or legacy-free)
graphics adapter.  Programming must be done using the MMIO bar.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent e2bbfc8e
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ command line switches:
    -vga std               [ picks isa for -M isapc, otherwise pci ]
    -device VGA            [ pci variant ]
    -device isa-vga        [ isa variant ]
    -device secondary-vga  [ legacy-free pci variant ]


PCI spec
@@ -31,9 +32,15 @@ PCI ROM Region:
   Holds the vgabios (qemu 0.14+).


The legacy-free variant has no ROM and has PCI_CLASS_DISPLAY_OTHER
instead of PCI_CLASS_DISPLAY_VGA.


IO ports used
-------------

Doesn't apply to the legacy-free pci variant, use the MMIO bar instead.

03c0 - 03df : standard vga ports
01ce        : bochs vbe interface index port
01cf        : bochs vbe interface data port (x86 only)
+61 −0
Original line number Diff line number Diff line
@@ -179,12 +179,51 @@ static int pci_std_vga_initfn(PCIDevice *dev)
    return 0;
}

static int pci_secondary_vga_initfn(PCIDevice *dev)
{
    PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
    VGACommonState *s = &d->vga;

    /* vga + console init */
    vga_common_init(s, OBJECT(dev), false);
    s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);

    /* mmio bar */
    memory_region_init(&d->mmio, OBJECT(dev), "vga.mmio", 4096);
    memory_region_init_io(&d->ioport, OBJECT(dev), &pci_vga_ioport_ops, d,
                          "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
    memory_region_init_io(&d->bochs, OBJECT(dev), &pci_vga_bochs_ops, d,
                          "bochs dispi interface", PCI_VGA_BOCHS_SIZE);

    memory_region_add_subregion(&d->mmio, PCI_VGA_IOPORT_OFFSET,
                                &d->ioport);
    memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
                                &d->bochs);

    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);

    return 0;
}

static void pci_secondary_vga_reset(DeviceState *dev)
{
    PCIVGAState *d = DO_UPCAST(PCIVGAState, dev.qdev, dev);

    vga_common_reset(&d->vga);
}

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_END_OF_LIST(),
};

static Property secondary_pci_properties[] = {
    DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
    DEFINE_PROP_END_OF_LIST(),
};

static void vga_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
@@ -201,6 +240,20 @@ static void vga_class_init(ObjectClass *klass, void *data)
    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
}

static void secondary_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->init = pci_secondary_vga_initfn;
    k->vendor_id = PCI_VENDOR_ID_QEMU;
    k->device_id = PCI_DEVICE_ID_QEMU_VGA;
    k->class_id = PCI_CLASS_DISPLAY_OTHER;
    dc->vmsd = &vmstate_vga_pci;
    dc->props = secondary_pci_properties;
    dc->reset = pci_secondary_vga_reset;
}

static const TypeInfo vga_info = {
    .name          = "VGA",
    .parent        = TYPE_PCI_DEVICE,
@@ -208,9 +261,17 @@ static const TypeInfo vga_info = {
    .class_init    = vga_class_init,
};

static const TypeInfo secondary_info = {
    .name          = "secondary-vga",
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(PCIVGAState),
    .class_init    = secondary_class_init,
};

static void vga_register_types(void)
{
    type_register_static(&vga_info);
    type_register_static(&secondary_info);
}

type_init(vga_register_types)
+4 −0
Original line number Diff line number Diff line
@@ -171,6 +171,10 @@ static void vga_update_memory_access(VGACommonState *s)
    MemoryRegion *region, *old_region = s->chain4_alias;
    hwaddr base, offset, size;

    if (s->legacy_address_space == NULL) {
        return;
    }

    s->chain4_alias = NULL;

    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==