All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Airlie <airlied@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 7/8] virtio-vga: v1
Date: Wed, 20 Nov 2013 15:52:40 +1000	[thread overview]
Message-ID: <1384926761-9962-8-git-send-email-airlied@gmail.com> (raw)
In-Reply-To: <1384926761-9962-1-git-send-email-airlied@gmail.com>

From: Dave Airlie <airlied@redhat.com>

This is a virtio-vga device built on top of the virtio-gpu device.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 Makefile                           |   2 +-
 default-configs/x86_64-softmmu.mak |   1 +
 hw/display/Makefile.objs           |   1 +
 hw/display/virtio-vga.c            | 156 +++++++++++++++++++++++++++++++++++++
 hw/pci/pci.c                       |   2 +
 include/sysemu/sysemu.h            |   2 +-
 pc-bios/vgabios-virtio.bin         | Bin 0 -> 40448 bytes
 roms/Makefile                      |   2 +-
 roms/config.vga.virtio             |   6 ++
 vl.c                               |  13 ++++
 10 files changed, 182 insertions(+), 3 deletions(-)
 create mode 100644 hw/display/virtio-vga.c
 create mode 100644 pc-bios/vgabios-virtio.bin
 create mode 100644 roms/config.vga.virtio

diff --git a/Makefile b/Makefile
index b15003f..093ff9a 100644
--- a/Makefile
+++ b/Makefile
@@ -284,7 +284,7 @@ bepo
 
 ifdef INSTALL_BLOBS
 BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
-vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
+vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
 acpi-dsdt.aml q35-acpi-dsdt.aml \
 ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
 pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 1a00b78..22d8587 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -10,6 +10,7 @@ CONFIG_VGA_ISA=y
 CONFIG_VGA_CIRRUS=y
 CONFIG_VMWARE_VGA=y
 CONFIG_VIRTIO_GPU=y
+CONFIG_VIRTIO_VGA=y
 CONFIG_VMMOUSE=y
 CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 10e4066..63427e9 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -34,3 +34,4 @@ obj-$(CONFIG_VGA) += vga.o
 common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
 
 obj-$(CONFIG_VIRTIO_GPU) += virtio-gpu.o
+obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
new file mode 100644
index 0000000..a6c9438
--- /dev/null
+++ b/hw/display/virtio-vga.c
@@ -0,0 +1,156 @@
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "ui/console.h"
+#include "vga_int.h"
+#include "hw/virtio/virtio-pci.h"
+
+/*
+ * virtio-vga: This extends VirtIOGPUPCI
+ */
+#define TYPE_VIRTIO_VGA "virtio-vga"
+#define VIRTIO_VGA(obj) \
+        OBJECT_CHECK(VirtIOVGA, (obj), TYPE_VIRTIO_VGA)
+
+typedef struct VirtIOVGA VirtIOVGA;
+struct VirtIOVGA {
+    struct VirtIOGPUPCI gpu;
+    VGACommonState     vga;
+    const struct GraphicHwOps *wrapped_ops;
+    void *wrapped_opaque;
+};
+
+static void virtio_vga_invalidate_display(void *opaque)
+{
+    VirtIOVGA *vvga = opaque;
+
+    if (!vvga->gpu.vdev.enable) {
+	vvga->vga.hw_ops->invalidate(&vvga->vga);
+	return;
+    }
+
+    vvga->wrapped_ops->invalidate(vvga->wrapped_opaque);
+}
+
+static void virtio_vga_update_display(void *opaque)
+{
+    VirtIOVGA *vvga = opaque;
+
+    if (!vvga->gpu.vdev.enable) {
+	vvga->vga.hw_ops->gfx_update(&vvga->vga);
+    }
+    vvga->wrapped_ops->gfx_update(vvga->wrapped_opaque);
+}
+
+static void virtio_vga_text_update(void *opaque, console_ch_t *chardata)
+{
+    VirtIOVGA *vvga = opaque;
+
+    if (!vvga->gpu.vdev.enable) {
+	if (vvga->vga.hw_ops->text_update)
+	    vvga->vga.hw_ops->text_update(&vvga->vga, chardata);
+    }
+    vvga->wrapped_ops->text_update(vvga->wrapped_opaque, chardata);
+}
+
+static void virtio_vga_notify_state(void *opaque, int idx, int x, int y, uint32_t width, uint32_t height)
+{
+    VirtIOVGA *vvga = opaque;
+
+    if (!vvga->gpu.vdev.enable) {
+        if (vvga->vga.hw_ops->notify_state)
+	    vvga->vga.hw_ops->notify_state(&vvga->vga, idx, x, y, width, height);
+    }
+    vvga->wrapped_ops->notify_state(vvga->wrapped_opaque, idx, x, y, width, height);
+}
+
+static const GraphicHwOps virtio_vga_ops = {
+    .invalidate = virtio_vga_invalidate_display,
+    .gfx_update = virtio_vga_update_display,
+    .text_update = virtio_vga_text_update,
+    .notify_state = virtio_vga_notify_state,
+};
+
+/* VGA device wrapper around PCI device around virtio GPU */
+static int virtio_vga_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
+    DeviceState *vdev = DEVICE(&vvga->gpu.vdev);
+    VGACommonState *vga = &vvga->vga;
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+	return -1;
+    }
+
+    graphic_console_wrap(vvga->gpu.vdev.con[0], DEVICE(vpci_dev), &virtio_vga_ops, vvga, &vvga->wrapped_ops, &vvga->wrapped_opaque);
+    vga->con = vvga->gpu.vdev.con[0];
+
+    vga_common_init(vga, OBJECT(vpci_dev));
+    vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev), pci_address_space_io(&vpci_dev->pci_dev), true);
+
+    pci_register_bar(&vpci_dev->pci_dev, 2, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
+
+    if (!vpci_dev->pci_dev.rom_bar) {
+        /* compatibility with pc-0.13 and older */
+        vga_init_vbe(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev));
+    }
+
+    return 0;
+}
+
+static void virtio_vga_reset(DeviceState *dev)
+{
+    VirtIOVGA *vvga = VIRTIO_VGA(dev);
+    vvga->gpu.vdev.enable = 0;
+
+    vga_dirty_log_start(&vvga->vga);
+}
+
+static Property virtio_vga_properties[] = {
+    DEFINE_VIRTIO_GPU_FEATURES(VirtIOVGA, gpu.vdev.conf),
+    DEFINE_VIRTIO_GPU_PCI_FEATURES(VirtIOPCIProxy),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_UINT32("vgamem_mb", VirtIOVGA, vga.vram_size_mb, 16),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_vga_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+    dc->props = virtio_vga_properties;
+    dc->reset = virtio_vga_reset;
+
+    k->init = virtio_vga_init;
+    pcidev_k->no_hotplug = 1;
+    pcidev_k->romfile = "vgabios-virtio.bin";
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_GPU;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
+
+static void virtio_vga_inst_initfn(Object *obj)
+{
+    VirtIOVGA *dev = VIRTIO_VGA(obj);
+    object_initialize(&dev->gpu.vdev, sizeof(dev->gpu.vdev), TYPE_VIRTIO_GPU);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->gpu.vdev), NULL);
+}
+
+static TypeInfo virtio_vga_info = {
+    .name          = TYPE_VIRTIO_VGA,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(struct VirtIOVGA),
+    .instance_init = virtio_vga_inst_initfn,
+    .class_init    = virtio_vga_class_init,
+};
+
+static void virgl_register_types(void)
+{
+    type_register_static(&virtio_vga_info);
+}
+
+type_init(virgl_register_types)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index a98c8a0..32eb43f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1673,6 +1673,8 @@ PCIDevice *pci_vga_init(PCIBus *bus)
         return pci_create_simple(bus, -1, "VGA");
     case VGA_VMWARE:
         return pci_create_simple(bus, -1, "vmware-svga");
+    case VGA_VIRTIO:
+        return pci_create_simple(bus, -1, "virtio-vga");
     case VGA_NONE:
     default: /* Other non-PCI types. Checking for unsupported types is already
                 done in vl.c. */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index cd5791e..3523bc9 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -103,7 +103,7 @@ typedef enum DisplayType
 extern int autostart;
 
 typedef enum {
-    VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
+    VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL, VGA_VIRTIO
 } VGAInterfaceType;
 
 extern int vga_interface_type;
diff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin
new file mode 100644
index 0000000000000000000000000000000000000000..2b70d272f2704e7839712a61613844321b93b465
GIT binary patch
literal 40448
zcmeHwe_&MAmH(X|nG9jb3=m+1l#Ch_Dae2d5e5<=4%%86r7B`eqrj+a3T#M1+)ZJS
zA7&C!xBY&*b=$grb-UXiyKUOK?MPZX5RAG_RjRdASR1Q_7Y74X3?U3N-_JSszBlh>
z5`T2}yZgs}Uy^zEo_p@O=bn4+x#!$>-{j`+uIRncCh{&X!>(WQ84;;n-&8Sg_L5C&
z@7@x)W!W`L?%A{@Fg>#L`pW`hZ9`q%`i=Fo);4Yl%$XNhv9>-iH#p~tqA_Cn(#wzx
zRs`zrULUw&S>y(z>bmuf>uWb{USGE*@Y(fud=a>xz55=fJo}a<*9Mq8@^$NL*Wa;a
z{klNI#&zrKn9Q=}H#4cCF{lK#P#kEyXUjeHfdxfl0+$EwuCL#`VD{`giPOusY-*@m
zyFR+9?ymKhZ(Lt*M%cP_>*X6aZM<t^!{sQR-FVj>ccM>{>eB0PIz8Fv6T(j-ajX!K
zLre(m)+@E`S87*$dFq_xgNGA0+McKq36Xqai73-Lu1q+@uYB5*S8CUM`Ip~_rM(R<
z?e{gkKNGR^WF&31y+1^9G?IO{_Wq+-<QR+OQ+M@#9nf(Ni(}_}$U8Rlwu#ueAd;mU
zdSgh=X(-UvZAdl7&do)tc|)o;cJ2zK9^R0;Gj{IEh85a(H>6fAn&PX!HkS6G;LA0s
z>tpE^4f8?{<i7LO)WT2!67`Ry=7wBIeC?6cWuZbOjy{qKgxpBj{w_5sRD?wE?^4CC
zsWlxU`QQ;Pc;y{sh2MM;{dbB))(#2q-LCEqb$8nAc9h!+)ZJwRD)NQG<`nH&F~;U}
zipR3HVs-c095&>IPv-4oW!^qc<;U9!+$eW!Q29xd{C;PFt8h&5*m0AmlzyVJvNB79
z@;~{S?sp6KD2K4GoptH-hd&wnMVZ(y<?)RNA1V=Fed_V77(Zc>-RUayjU6|>WWvNr
zHh}@7E9muR|D*LIXy0eE3D?>$tccwAS!?^#(f)y~m}I?dG==yY<IP6=KH&pH_9)fA
zc?bAkF{YSG!T)scSD$(!E8Oz(`Q=qCyl$@UEAsx2AAc6af8c}0KQPLR@iX)%Dak4Q
zc{3|)b_Y$noc?%Kg9S8xZc$~U`o{R@>eKjtNPR`=zwH+B7mFD2|AfJRm1Jh;?$1y6
zuH6Uzp>2M${-kxd=k%BR|KasnekFw!S1(u?TC}**CQR~^ZT-*voR0bLc4PkE#rpS{
zW&W3x@%$emKaVm0i%s_9uHo#*$Eg2j+MmcL;2Mzryeai(^kPvZNAv9mem`9tcS3(E
ztv{CW|0wl`^xsmS<}bBhoST2w$o9#8R^{a9Ds+!38toZV?7c?UzbfeOx^kWW?Q7TW
z{EI1dr$mjcf7{+$=Zagm==1ku>hFw?d0{Od_L98he|}8zGlnG&AXA<pW(Wa__`q#~
zOrm5M_yoEt@iPIHIfWZ1hll?+(5F72D-#6Njyh90Lrj<<D$%hSGb#y8ITUhF8OA6R
z!~`hn1W{QzW5R?P6Dns^PJq-19aM+}DicMJ<Ej&Y3OqvMny5x~K!$1qgbZPzm`Q#-
z`H+~0lQZO5P*4DeVD#wG#l^*A$Br#2DS=;5T3Q+i1j@_Hr%#_gYu2o}bLUo6RPgv#
z`b1@!sGJQh=y!IdD614c>Wits1RcJhtgQ0VvdY<ImGjFgE9rNBW!db?vP&zi1t#e5
z1+!*V&Y4v?Z&u}kS(TOayP$H`yvkW~Dy;=3=<o$XlopE8Vo^Fll$O%(gi=vlDhf-j
z1t#e51;xdsV~a~C6qovoOH1k3Us^n&w0LZ(wZH@&zM!O}bYe-Vzoc|>NogtlPA)C+
zmzGQ{wHBD5!xsqQa|$1PN{>L$g<lWW2cK}lN|_5x(BTW*ZeNkx=W+Xr-98`v7W>>D
zpS#FsEigfcFBm=A=NauAGur1J?eo#E*Ef2MZ?wl}EigfcFJL<`%ty9|oq<BT`?$wk
zyluy~cKrO29ox2Lk7PTKXSda6GMVNINTi~f?-k7z1Zeh2Kr=j(PzcURHha7i_*oH(
zE?E){iEQU1KmYk7omp?8_e<T~-A$orG#c`6^H*L`84PYd)w6vq?EYQHl8>wo9X}pg
z{Yb25AT!Vt6ZYc8nZ?C+P~GPDZwvWREgBV3vHi%Azn(H>idek1qPDi8yNP(-wrv~Z
z0WHh;@RrC`M;>f>G9KJSuqIOzB<y4|nZd0*nvIs@jtbzG7-w{(_zE^P1%o0eYHMpb
zUt62OPpt?xC!0J2Ak@|E4@SF0MQugn(e6f3Q<G#of3T*eCg>OV^CK-pG?WcRQ4|cO
zK~P>nDiCRvqcY+006Q5I&0R0N-hZrF1UCn9rA1S>r=q4?-aY7UX{fe4<C!Yb$pH`L
zD{7Jh5UWUcg8=9>Awzk5G<*D;nKsc^e>Kz!@yE@B1Ei^CYR6CgZSH#g_1BY4A_xNM
z?rxEeMw_G2G=>v$!*~wVVjOA*MCQ)Bo9@0dBkwh*xcr6aVu3M6wQd3F;c607Jzx|3
z9E;XA)kcqrQxMOc(TwQo%Vb{d>JnYY`d@zm_lnxCuCCe&Zm$OP(0upNrc%yRy{7J-
z&85`OCna4J<4RL|ARiQ{{c5HU^gsl(2o4sSM5gNj|6H`!gm!Ccngn&;<Fbn;QV@R=
z^cl#xD;s3l5TMD^jB)L$sX_mbQocKh_Dekg15Wug<Wx~xgD#yyzL6w8&{I>}7zMvU
zv6=ht5mEp>H6(yz3?;sV=q3T+K0rNSdL$<yjzZ!@km*fDzA?)5S@DD~*c=RAN#jS=
zh!5P*e<<XunGESF1i)Pa9Q<IMzZP7V7Nx;pPcT?Y^Md~<1CVH>uF*w;=z^T6mwr!^
z=qAG3M5*fMw$6}iakLU(lFK&HqweSn=OK?IW<~|@qT6ahgvas$9^bo_Jes>Iz(NT1
zrF^>3YzE`cs+;acd+C~{8k!p0J=?pti^Wj)?(P>r1-~R8{Z53D2b}o?L3yV<`rYXd
zk)e^@03NJCG6_>sQM>L`%`wuOrZmk+NPn>F#ja<Ir}#sD|KZK(FZZWH@y7z7c1sog
z0Uj_+-tH6WqunA@Tf10n6VL-FZ!@MD3=QcCu5>a<H<9+hvUYZLzkWru+l%{=`I}yJ
zC=(?FfYB>}h0iF|;G!1!bMtrQ&ylT1`sfcrGp+$n4fyFk4_80_sG$tsb$Gvv;QED9
zmG5_v`6D>p{h$IR;Y-r>`^y;a_mf$qE6eQxjyvb^K_Ce)V>r>9PapH<2P+9lR0d`K
zjF5D);*2UMIH)pw-n=smr`8CMP;`8vPn5D;Z{9qjOI(x@P{?*ERjJAekGRtL)%!(!
zXVpdclsu&_ueu0EWtewIpF4_q)zm%EJ%ABRcf;@{AwH}Gu>a}qnjqO@tU8AeAKnc6
zj;pyQiE1PgktW006il;PLnUZd)z<c5{`p}ynyB89BhVL@hwe2=vfs&?3Q}gepe_7^
z`2gia66OllIW6!B%aj(yQ>IWm@&W^lMD`sMndUO<AzHyDg+~eed0~c5)P_o%xEDff
z20`LRh!8GL4EsTT06PL)O5Omw0}_{<0`>+ttGfoAfj4mc_;H%)bnzmK*=IB)oduMT
z+?C6qMnE|Zs!X{LTsF0M@?4UW;v0e|Pl9>}9Uy;#916~{SF!f4<HwSe_4|*6j)#sY
z%vh3L46L<u*<I{tU`3!ydJnoIKtoGTN0iIpd9dp-g>ubZH9WEvo~~vtr4I;$(*_lc
zvrZEOCd+u_^cGO6+!HR$IVm!$Tosv_4*z4iOp>*(Xl_=`QNzv66>!dmxgcoRHKhya
z4Y@q}MLrGx0pRyHcO6JJyY_T7D^3q|!6S%vF*0ct+#FtSpqlKy=v3J6z_JM=hYNSQ
z;7iC$cYkCKR#;J2#c0<+6;gV73GNElt~*CuBt4`qC3k;Cla#0`V^pkTbTxOmTp^cB
zVS1$N1mB6S3}l-&$}kI)X}Az_EHhn11s7vB6Wl1H)HavPBXv-6Xmp7adWV=3ayFO>
zKA;Ww<%^vVv{A!3(Db0HB7+=Uu%k)Ii(Hn`C}XBEf^bLRkI@y19zZV+L_?fo&y0OD
z%4VYMpuzLW<)ojY>b>3-UBG3aO)Ic!0m{Ocq)FbJ^xp^-J{)`)^2X>QPfq%BlvDnk
zq5`ijLvEd}Jw%?oJG!_JsCkNWB+sr_UvKvCo;#Pp!;~$ctOgTIjmoxdt4*9yHM*pf
zWV%*O0m{AlYNolCTVRinCM)M4JXj6g5|MWptT~|cB}8M6OZFXhVsk}lv9b&ymW0Pc
zWkY;MrYk?Pm>hDRn}Fm{$eBalB)njZp<dkFl}xHWz_WyJuVVtCxhtcW!D}HmQ^^cv
za1P<+uq6adaygaEphOiUCfNs<OBB0sq0guUOyz}B^NeO-0&pVp>Z|OLQYpEixHyRq
z9wvipDr+{lk-VsR#qMg3&*rYprK*2EUebc|N_Cp(f~mLE8pUh!;sKQ72Y~YFjWU{o
z<l54e>4ue(T3(FaY{nm}5?K~@btO%PQ#n^Myk5>3&M)V9R$)?kT-0AI$vHkTV@;z1
zHDG5^jV%Q|#z@m*oy#FeH03}w6s@5KXi$iXX{13Vmm?~<94$l@)GMlnrOKQm%v@Pl
zmu@zINR5;Flb4NZusNA%O>>Qs8G6__53bBcqDkI1x!dr!aY@cha}2!bImwxxgU@4<
z5|!m-hKLNmJYr24N%Hq`Nn4<b)GS8FqR>!Uu5jrp4_}=wxz?-I15W$E!S2_)yLnE-
zb?0@3+;`c*oaAZ5a&n>0=lVc76Q9rtL+6p!O&B$<JNcAWE*9yAys%7QLDVe~!Dwxf
zWt_wO<6JV?)qOZvb99f#zgP&Fi@xyaVlHM~rL|gBoL76emYsUeBVBu#Q)8>mKYElP
z@BhBl`~#unUjrr(9DkWp?sLDqD+VZ-z{NQ$rZupTXga1IWJstCH9$fk$!W?n6KxNu
zmgLRMnP0j15|cs$^QF7@l6i9OaVZ3aDPcw+Kv@|sAfb4X!HLZ1A&VrU2QIQq4_{=N
z9>nPN6csL%0SuB{D8m{gnHOuB9^&XURgYxW2zO)~l@iKS^w39wj2@|adKe_@sh~-=
zZjpq4h~$+7;bNOEofiqxqa}IQV<vf5l~e`3H6A^Dm|`ftn!D0nU5JINkb@1v+`xr2
zT{5VWc0SVu!-0vUltcztG^6>V<pE1hQs!i^B?o;QMfwy8aFMcf%GY3H10T1K%cjB`
zTTHl;h#rb@&f!8l_8tN<&XoqS?Nd_|ER~pSGhnr34h+g)&MKEyDjvCeWO5`gNTEv}
zm9s={JS;F+djFun*u&JdSP$l?0aHLHn>XBIBdZb=;>jS70Ea2iGgi>eFg(whCtNdM
zI*AXu>k;4%*(ssNfLWCn!WstB!XfvF6;*2}NGlh1T+P8Cfpo(swMp(FQ<`byLP8lY
z=7K_$>rtT!3$eCJb<m|LBSRxJ6f!n6f<qGLknr#nwxCb-<O0O0i!+O->W<)$7*TEj
zphZ1Qq#bG*Cvu>O^`?fju+|bOLWA^RF-K3yQ$~-ZAX0uxRdOLCIJN|h2)gvWZG9Xu
z!!mjrcYUv0fvmwJ@iJogh#E42G{O^f)f__t!5l_Hm@<wu1(Jdz$(pV`vUxq0RBjXe
z?HXC2J~3<fQURsF4B{&nCmMU|dcFLxl19~3AwRSv1iiX7z6?b>JC7Xc?9|PK9$_j2
zg8}8pE~y(T6=k}Vn=AA<Q+J3}q-m7vv8IlXXp;!ylKhad$vG*~^+v>Lgq(`=9Q(2-
zx$ZK1WQp|tkpVI$tK9Nu9HTu%pT_udgQftKqa9O#DC0MpW708GQK%7y$|nRU#zO+W
zWF*R){^q<9KCr+2dY2xKva`tXs4};DM5=Ed=`pE3-;bfGCW@+#$@XMinrn}qMqxN{
z$#UJX)6KbV-1YHDgLl||gFjWC7o+O!p&U`F%Wwd*M;?(=RxL9aPI)!U_L&t@FQtE+
zKXN3i2U}c(HBILi<>V9VAswEm?V*Kbf2XvKLXTQi*eZlIa20yw%AqTdrsQLoPf#2t
ze#KrW#WiZa8Zm5C^#^n)iq%6^dP2f+td7s+m;}0fb;mvzByu#H7tiYQg=$u?K$SdQ
zDyFqYwfu02yCjiw@&fQ!7B>0F5iX_=>E}m{yd2_Oe`L8e!X^InDNT=L4E+EVvhl`7
zpijoRra)Il876tqkQ?KV`pA+382nHn6u`(!{jtWphNGlMy(;V_!zbfjrC)mFt3qGi
zB{nE?f`difoaJ_vWB`mOC>H*qd+2X&JSj@F=m+r4d5Q+jc_S9i$wP*HG8|S>XO6yr
z88Ej;^vroY6Sn9F1ZT+;zElaRKV3P4Mx8fB$7l$)RgaHz0kRMq7f#uB_~=$D&&9|x
zNLKvP2r2zxesg)rZ!T}d%BufV&QYi?57Z}YBVtBx<t6ENsZzZ?tbLuBeVzKosxiG(
z;4Da)<TDXwALgz3&gdo>x%W7qi=H`rW&xPTi^kh5KN666zEIx6zY#}cVED0wVQ{%U
zYb>1?O_K$pcsi-~k1Np{n&g!H$hdIHBsM_lQGCq{Uw3)R08;tr3tyFiHLZ@A5vI@@
z0h%SaCSO?(uZ20frnEJ}zWKZ62%FL%J=`^50UGhM5q<W{AWg;BaKSA3q4*<2+*F5!
zV2!%*K+t7)e~PY=XTCsR3eWho^6S^*Z+4@oidt(7d}|C2e5Q*Jg<;?;xE0@sTn%}c
zqw(A$M7=p{L{5(k4f>2?jmoLMK~I$%_$&`2HXj<D8#@&SzFvQ5|CC(yTcyq_<5}Z$
z{ZS<sDLiYej{N|g5F_OtVd~8e9WO)P6eF20Mc)8fBllCMtg$-|;LA&AU*0KxHv)Ki
z;&!+jCJ2U|E+d9da+V+*Y8t_2ULenpN{vugMNGM19xIaUrlMyJ=*dFx=A{bhIg3ZC
zdQdO)s9yKiK?R{aJ!4guHMGZ*SdQ(D;NGyWFud}@WRbrrZwc}F5f{17hD(h!jJO`=
zTc6PC<A+FJ5B1r9HwXL1vs-R%n0Oy>V`3?m<l8`$(W8Dm+vPHA+>ZynhlfP|SWZ7M
z_}_QH(cam&@1UdI*|+Z*N4veR<C|Bl)Sd}fS9j`fTa{nGu6#_9n3|{(4<7FDiMGON
zFJ{LCM7*$Lw`ljZ6n5M%+G}uY5$$Jji;MOfaa%9iN3|4|b^gFElFaNdADs!j@^kp<
zi-a~_JiS<GW5m<DgjOh?eoAOI(fPpP2b1wLbDlqQD40yY`~5SAuD>xM932AhJKdJB
zjqeyO;_v^;*LidNk8R;`Ej_`vdVlL|4UY@H717EIs;iMK-<~Q*Sup9TjEBdi7Rhvw
z(sN`wK<Q~SMct`T;npd^w+{8hJ1@`v(>Lb*rRirq(y14Fe+BA3P;U$SsI`c8%jlg4
zoxMMCW*dv!!X63xyoX?qJNK?BUb%OTZ>3RCJ!a=YS8v=oCy6HM!$TiF`Y7(L(;5HD
znCj}@b<TuML=ssMX$=>1gT+kT+PqF#b@}Mnod<ormx2Drt@$|DJn7iGW?YWlulT7S
zuQ{@fzSgjZnUFnH%_Tmu^PszT--zX{WmNumC@*FbG%PyD+K~&X@JrmHL@<gzS58HD
zIuds3JvA)lz{7g&B~*AVHJWYoX!p+~9_Km0Qtul=Cn0M|ve`y=wsE3jIeYoegT=ib
zn?z8+J+q0%8DRmsg9QA875Fy{{FRV2wefQZ=V{>35b2GAFKSWi2XayGV~T>N1u?8&
z)^kTFw@c5xK)FVtE6m<CZYa*g+(`U@NTqH`eRihs?z$j5)8^e3;?GZKXWG5HR%d5=
zyt`}+Dd*2C7`}wzH!=h`s8z?Gf5o5oacOI|cYwr^3TYS5O)X`a>C!qe7y2qE$vB=Q
zN?^a4TU~7e7pFWk1NF(76YBTRwACN!{kBb)xmj~Z(xNyT@%7fD4kpn=8q=Lu7|l*W
zv%Rap-?-Ejd)IhYf{6C!m5_QW2u#NJY5f4WQe`>74;B!B*b?>6gQZvS_l9J+ln55u
zv{zT{PI`CI;EYRclueWFYggTds=a$K!jc;wL+`yEN|*Xe9q3_T>~jSCoMa1(lah16
z*S|ocwKO4YB(#O<eucV!5|-w4sA%hjhNW>W+`Zsy3;tz6YQX{g$)6(&-dvFSRm!C*
zVd!VUlCM})Dz+|F25Qm5mGgc$@40zL=e<AAGk@~@o990?{~zWboWE`1Tk~xdr4`#2
zUR`lr#h$BQy?Wb1^H0%&OBT#p0Yy5S`8-+98(PE8@>okayYpa5d-~Sh$$B>oh_>Tq
zvY*cK?JZ$gCMOhJyQ;Ffx+R=x4QE2x250=l=R1)Mz7_9mz5na>mhjou@Y&#7KXkne
z1KN8359}xjpEkjEU?pf>W+U*sd0@sqmAD^9uS!I;pHyOyTf%*b76tg01iX`oE5QGf
zfRnA^ljZJRN$>7!p(fzwhYo6gN9Po@<s#eB<%no66Ec~_=aA{5Odf7w>Y|R>Me#L*
zsTmz7`F>Hy4@Ogda>phQ-N&VTP^j0SOt0hb5BNJqrn|rQdr+exEf-3$d=K4P81Aq8
zTwAz5e&A4#?IlNe5Yj<$B=J0WSwOrPg;hgJORc3ti_b4c<<zCrFQU~)Sv~WHIr9o-
z&`K4!#cdH@;kobAS(2PRWN#P)C5zCIFSrzFiPu1C@8are?pvxN+t{B-0`xG^7&2_2
zW$SERb}{vaaB7FNGhQ?%6D1fhDqNv+M42Ue<{&axQ3fwDM-tB<cPZy=0=%XwsdYjb
zM?f@p9n7quWTa4SVa?VFO<h(%Oi=yfizKSvS*K`x%G8$^fO3#f@(6KX<`bD0f%Di9
zGH&!GZ<y^NTSGzONk__&c*PM9znvH>BH6~bwJlUR*C>G^Bez+EHrv8)S4Ff>4r$cS
zjaoX~x@;7&cmOP(522MrK*{$c=V<g^4AIoh(xlj*ubQ@9$%ac3qAHRI6w<H{=~Q;B
zQ~U8kT4Z;lt}`@dOF1C}ad_PO2{*Nx7Hb}<yO|9di0i;cOZa@ks|I#Cmx$QNv=$Pr
z*6?|KC`+k^G(L&zL4_>C0pPf@ji(czQh?_PFk~>ZTOElTRQY#gg|`!H72s<U@NQz4
z0&J3iQ;FRQ&?re}JvGFMZj-JfXyPnzbfYwnA-YAfBL{m)Rdmn<MsTA_t0L_nNXJ`O
ztxSAdK}Io-NJbLhRgg2ZenHxa^$PHU4u~qi&j~PO;9y!Yvc-u);J6^D4q@ovco4%(
z(mHJbne2dD)cp}fTEIaHGsJ{RYR<7ghO?b;@J)XE!1nP^H1oF)Y!hW|;ZwbpLczUH
zcx>?JpD4DK^<J$5C*^>tX$o<g2{tz6o#htwKbz$e_1&}VqW%aiELfLz9vq<cr;^tn
zS9w`W7(K>1)N(MGw1-`>S70I1*~WCDMhPW(HI0uh`g-KBf}G6_DgolOe4Q;v-|C}n
z;mjh;>NTxlSIE8PR#NuB7EA}UQH2{8518(~(SiC264tgnbEX%|i*_AYN|i81RSrnd
zp)l}ls9k>rw?CLDA{#NNRT4i;8IykylmBu8Bu2~93uP&-V6xQ5?CYYzy6OxSHu55z
zZIpsJ)Kd^qqWD*|<x1SCa`#Znn2D&fAbj4tJ0Xn8bBE59J{J}d00M}IA$=FTf;I>u
zNwJ4q`Gaq@EgwA7OH8#bA2`$N$znMpk$t5q{<|~1_HY&h;|RZ7T@Cwf^nGwXsKOga
z6jSd`YfGsWD59hcVyCJ91SD%g7#C8e6&TciD)kXSsm2XApd3TVY7JwM(GH>knlkKp
zX0(5$tVu+Mj{GGt0xYidkisHQ%n;oQg#jNvqkWMu41I*xVhG)^M;^j&3BT7Geh<8A
zW9O041LnKBkF<A92Ht#nB}*xyRc4vBcdecZO}353sQhvs^))<TSg3y@0FMgR?}4`E
z{bza)^$Za`#7kyzxf=8zp$eRLiJXs`DhG?Y@1}cg?4i+MwykiS>80_~ZRXXIqrrqn
zs^@)_$G{i^NDBN#0w(a?D5TyslxYQquD~lK0MsLfX1;$Fn1rB}Y%V^JI)=ChIj$o0
z!Ym-=q9nq>uSi96vIRg@L>W}#9vLZ}D6mBmwDP}(2AyC!d@i-LHB1XHlcf6RWPL|C
z6G@22hJmLUj_+H6dk^#~5W#IhxVY|L69teu(f=!=Z}cE-5I6Mzjaqw<D6q@Qi*)AB
zr{-{fz=Vt}QHNN>!bpABS=5dpQlj+|tYC7VUl8`xJ!`OXlHw$Tl@Ao=A<Z8C2;$74
zrCEf%--d^9j*aOpx-cQdLz;P@Fnu!xBH#%3S64%T3G`_=oHXOWY%q>?3wl<RS~4P4
zDS}~%Il?qh3HXde!!l6b`<7=7iG1MT<hq)nuAWadK)&453hT&VNMwKYVa@BWR)q-H
zotpI__4FQTV+q|ls5=d&VOZQ4W@-2#9cZ6S8}_If)nSj|-Dk-j?U*w(W;2Y+O@t|p
zieY(fBpBO%AMDpyW1?Onsrp!<DWWMPXS^lsVGUgv9w5K~0L46&fzen%f`bKs2G0l=
z#f}O&Ve-8U@9qfPc&k;zCYxMPI97DRI^Knz<5q)C<93^h1z-*qhEMH{zT2>j+LseX
zL9PN0uTg+v{yimZXL<|ZEoU1cMGG6`^Zo*REbiV;+G_~eyt|J=waKD{Pxl_czS3zq
zK|sl9v91tZ1uIZeDD;pvP=lMcqvx-PLp@j#fsxnfr>N1??UI7gilyc-)jlHeCA4b<
zT&(4A7ntwU-ko!^y|1Hh$Wq^)mEDxRTNpmQ^*^Cg4cJdJcWMS~%Te*4)Tu9mI3~61
z%@%uVJUVzCcMzk64tV#>%J%-o!Lo)K!p4MUaa)Fc3YbdEK(sEi_x=rPU@*PA<0KGD
z#E>9OyEjkM?#k1&n++5GSG1R?>zy*$Z0)6fj1WUj#kQo|Fx>NaKk`Cd6I<mFp^vF8
zhKhh(o+4htYK{_$pR$ec-$*av6QCnx3jX5k&V!!R^!#!&RmR*t0L&qpvt?)RgWyE!
zO{$4!N1obz7z-K^&SL>BNgXjUn?3`~4;<&_Z0|eyTRx7KFbq4*%dOI2Y?i}#Pu?)z
znm3Hs4mWT#h-tNCf8ZeAhOKCKZ#7s-V^gJ+g?^}~B}_{Yd6;k)&>}YP$g^e}^Pe`d
zmw)7ueV4@g|6*jn_mM|-(?=NDR7q+a?QEB2XxDmenm#|DR;wVq|BGkB``>x+U1QbT
z^GROy$RQ(DZ<|4@9(<m`oEQEsyzo=H7yi_H(hG+*XoDZD0-Ut5HqIk@L)ONt2*#r~
znD4wJiiDOZBX^!{K0E>Iq6UI;QFDa*C_W;89W0uO(Mt5I8E6Mnfn$^uGOm;`8~{`(
zPWd~wPm(*6+o$o)WXE<d-HT=x*S|H>UazJ4c-<x4CD$>}cXqSy3_Vo7GdN=;c>H#+
z+{bArE)2W&IOSkp%43L}u^r%-9%~zcQ^mY@NAB-mQ=ZoSEWT(^8Vj%hM?|`<1BeN!
zG?Thl8R$ez#DDklfb?HwZ0~VP+Ovrk?f=0U*Z%P`WY|v0_>wnKFAARrH<O4hFIzf^
z`xtOtDWBZ);Mxxo1T9vn-D|h^zHQ_nAx}3rQQrF^*?liK67K9t*x{4t(8-+0rF2=8
zPgTK*fElpH94g+0JRwNlfab^uQur~<0lI%kdnzKxaVH4?!k*+Pm>YP#fV9V00LA2Z
z{1|eRVjjnxha>x)>F7M{T8dpN_PsNyO~XrLnO-}9ji4Ff3|3yUTIJYwZ(IKE%RSZA
zbHiz(HFc!&A};4u;*cg+OG9pTt*quyPKX+uT?Niua3Xp;^0|JGc9Vy4EmyF-G5oa7
z^+k}p<oZw#^X(YQcVJ|U58&Kcx5vu)UxPb@$GjzuzS4>xGO0ueDpH-vR{>i7a+8Xl
zb%0BF9yI79Yr&4ZxghaL8+h#Hr1%Wo(!-A{)EB!kSlVD^U|9O?7}{45bkgMb0iKDX
zoI{bJ1NP53HK#r`=Hj1IhVi@}^=YIeac%iDGM;2g^NlC%M`_J{+}^vGO(x@c-Y}kL
zr-9xO<2gVuHl8rhJVn$q8ru2Tz|1S-N&Uj$4>g`>*=jsl?s79w#;&KbjYZi;e8NUr
z8X=?F!w;3;!$6=2LpYpci1D}7Yh4C!VvsG_5V$=B?}FkhcC*OeVtXca0iWo7L|Z;c
z&d!}|;Xe@ZYv%~@>JOsTgq@M1)WlQ?to!$AHQdh6aPP%u{j<ulwS|k|2^THOX6xZO
z!No;b=Dlypa3g*zq+uHI&t3c>Bi?%AgGaoO=nWZh7r{mv@r{4Zh^H=-k{y18zjHCq
z=+jjc@8o3B@XOx+(otW<j?hOK^~c$1`@m7Z4~p?08TD9J)VpF?TYXh$WaW)F?R(8}
zVqenHF8W#ymwUhMuD3hgeLu9t-t+<5@?77({f-mmC*6mU>&xtqopm-GZx8gXzU}r^
zMs>ornXog%V$0oo!@l(5tOvA>%qz`{zQE8e3D(x3MuGRP@=ENz7u${9iYJJ0+wvmb
zk9LEA#@kG+bnbF~2KxaH#tT&2@Nklp!xUtTI$v@O8z`4zcsR=Ad4x&;mUEwxg8;dP
zI1jyF874HLumFmwoB>!k_aW_&!E$P{wanU`BHd*eV3%QlImHURHvoRvS`Ue79cV2K
z8(Hp%@QT?FPoTQmysGw-H^62;4=LV>I&jQ-u$-i-h)Q9E{RK${7EXB-W*Qb0P{1Qx
zNkNz5XxLZwKF+0Z!~|CJ%u5%A&&j2R*KXy$>wWue83dd9lrh{-BJU(M;URZ~-8|6d
zq4*Zp@TVqH@bD!L9uA!+bNNer*8jv<&-=AE%CPnt8oG=q=QQ+&ssAAjy~}2>Y$L*L
z%iXM@E;*#9$@hn^=o+e_y!_M0U<wWq;sRRTJWlBj2Z)lcpMN_Q8Mwbvc5s4A7~c>&
zOB3t)AUrpYf}C~V@71u61&w1*6w2q4%BOSV9znroQd1)-*fi>eQn1rX!N@<NHTHKe
zYvmM;r!M5KO8t>YW)vHtEH?!9(kIZI9AgO05q3dTdawTvl@WRwODg53QJ%pI;a(o=
z`|(--Wa<re1p2jIgda>o7+8Mc8uV-51SI!7=M)&T>~dDg23&?-%vLQb&*;k14_PPg
z#8XRnVk3G+zb_?@=;>O&(c{+%#tPx=P1$-!*<tfAqS%PbU_Uj3<5|?(Oz$aJ6yE9Y
zJ%$wR)366ba}jAe2B1yPVhdvL8a>h_xc1^(!?MJNwY(4w{kZq5pf|+9fmi0;eIL9f
z%+inTmy!1~{2E<=zCu1l_=fn4CHJ%!fi75@Cx7k86kzuL`p@v!h7hCOy{#bgVcyzf
zr#_;$_V%AX)LZ*E>@IxRx}CakW}$bNm-W`epO^9H1(}%+@2=6A-VJ!PC7rki4{LxL
zejXESuzPnuFQr4XML+Sx<3`~I#_hU~IdCHl#f-^3?c8)CRVo|roFNFg&N#|}5GX?B
z+N$F?&X>A$WL$*hj5wPRC7&F#fMM+QBc33mCsQ)UL7I2$S(|Nd&}6|=aCsPcWyhVO
zwea?qXIJ6~a_gnBw_+XF1K{rI_!P3Ymvx3jgFSTzPU+ZF4OkH2w?p+Dz26l0M+6T1
ziv;`|0!Q!fL}(OlJtE}8ZL%#i4!4=M(0JTFV+&2dEp7`<!tI;3kRP|FZJ`TrJ75b<
z#;wcN89P_9wIrfDSS^S9S_b;abz0TA^2cMfp6u=HK*e7s5A26R`cId%7WOSAH_O-X
zr}nXZl+AftI;nP_^vce_?MlAsklq%d!6&0er<xlj|E=X&-OJ<VBh>zHvMmFUk@Vu?
zFM|Q;2r8HFl9ocn$8o*xSZ);sIzV>=Z`${q1Kr#Aykk|QrKhh&>jM#Vlif=$T746`
z`MiUBm;1QBLH8qv^bGxK7*oDIdA!g)Kz?WHf{5N`N#CmSSc4;Z+#WmbRRSef^rn5!
z5)Z3d4x*hCdwL=#TAn%4vR~(d3l$e9sBgIsgNvK?brA`wLdg>?oieE$WGVEP&Sc6E
zKnY8v<yo-O-)RF^C+#|)ENJEO(($XvBsx4N5529P1bwB0U;{WOjPs+3XMu1n0r|+@
zG@!!m;PeHY&Tx7Rr|Fq4o?De-=Li!Iw&1D1l}XsLr#{2`Nm#wv<t>N_I-?QCsf_U8
zqDs-|N>mEus7X5W`0I&iQbwZOz=0w89}USrPWiU56Dt*N1Go*~wlM7S-dB<3BZ3<y
zR#zKm&$bXcO-sB;fYXF06L#mxgtPD@4(p#J&)8{~+iEW7$sCFUDEK3kZUi2-WRKlb
z)N-($d}$P67p}l}vUAR_&%7s(1LaO5d~X6Z7tSO`(bK$)cAD~d&Rm6)o)bu-XE;!#
z$AM?cA(qi}9)+Q2V5cNvlIj2r7QknmnY#Z7fGI!ME;ye>eXL~#=`7ARPzh%v#)+a8
zAmK`klRRwB@vs6s&{zx*UE=Svxw0#mKkNbamsiP+5H!+XPEV-{)fQ3}ZxhPR#CRvf
zt_@~d!tb|+--k_)7`rS_l~C*YDY&m82a&+%16JGeG#wC$7-!(VMYx9dJD}Z4$0o|r
zH!`-get?PMa_qHn9=lp9j=~8WC{e1KUppXP2IWRBdEPi|kK?L8EFk0zw@hzFz*pm)
z>okW(4~@q{NavTNVlE69)jg@5r-Mi#Umd~$s-az&fkUhxY#PuyQ0yAQ8=TCMc)Ny}
zIzWB6>?MA<f_#oCI&jpsW?)C>_DL&oG!5)Y#`?!u7{iI!x}R$66l0^PmezXS!dCgm
zV{0L?K?^ep%FGZB14@Rx7KYa6GxT%qWeg`tYE%NXw6kf+5KPuVN6XQ6$4MA1X?L_e
z!2B3OWA2>8aOcyxn`YteS-c-&8b=b>&$X)z?odm+U2#WmI}=xUO7kVWH2_6(_Aa$0
zng#g^+Mhtkc(&n1pIwP<vgEg_gwI{QkBqB#jxFJlCzJP?s~x7oM6oP+%v|kht~N-A
z6EV{K{N#HC!s8OWI>3~_&M3b%qqImAua45hC{LPE)=QM}I?BzA@;7FbB@*Q-9c3=%
zQ=3ez1SG~Z9mB^MpD|%%e8g<bpwUP9)F)|j@Ec0~mN%3Z|Alr>*@jy-+`Hi$8-B6j
zjSY^!Nd3mJO%13j{cr?68SNj4l3_Yl8HIR<BBR|;h1AGYI%50a;ov)XldIJmd&AqY
z7B72sIK-kS9S!!M+E$fyc1~S+Q_BJQCK#TT(>q`Ay9RCb6Y4$@8?@KkQ!~o9dwj9C
zPQ|)MHI$TZQmLZylb#r--FQEY-xX`QG%;@6YB*_3GWG{s@(+$2;qo)?ms$!H2HNa|
zrx1J3_R^cYSe%C^bimQa#YX+uySA79V4`r|L_u!@I3|pY34^s3hfe9N-rhBXcv8q7
z=R?1RaPTM#f#NuXfjHsPhCO)oz)(J+hL&SZk$x+s?BQa5zLtS-6_x8>#c-rn;3X88
z!g1F@JAK-(ivi=;CY<GV1Y#2`rBBLIH#TBmoXNkIr1+$BL|gPHgnFi3&TnC!Q3T)M
zg^5#*zVaJ1K;s$`^#vhY{X~6$JMiSWu%$DYUDeV9@kds&NaBY9Zz;T;ftbM^o4j}h
z$xSm!TUQ)EL5hleRTV>SBFI!cfw&%jIGBx+0;k}jN5-Itj`OQSrBrm0EZRmz`dR2h
z$nbjXE|?~Z{|E@o1XZ|1LSCi{WR(EARDzN@r0Ej!eL^C`3Z%;<=<5W+nREipkf4@a
zy-!L=V-7M?Le^0=uuj$HNYITrq`4AONk};6s5resLT~e^MeK$fXw@Xcr*Elb3c^A`
zXrS@nF9W6&1ZNc_#ECZuNPP@4T4)R)aN)FXXK^r2S+w7I)NEBQr+!59tAN7;z;+L}
z>)jQ#^MU;R9`Z&|8}`qo?WEf19n=u{LG1}k>3UNspJ&`<DGr;9$<<wtVt%>fbBu?@
zj@N%~=>jwIzX7?zLTeCjPU?&xAVfz~S75#{%jKx*<d->|mO5RgIuI24K=N9IH$0vp
zhnrp$=>>|c`uu2fzuQbzd3d-rlE6=?2G;1Ri1t-Wl~txHrq=LI23jM2tJx901C?6C
z1LXnoGjVp5UT;~;T<k|`sfA?0@Fek`%#%!O0<d%3@d)^t6upr$P-O1VzM`D`Ox)o>
z`!nd38ts44k!ZLfA_d;2gDudzhlSoWEHq?-lEOi)y}LHsbz`9QkAhHhS~tdoZn&&}
zBpjV3hmJv<8h+~mGfEFKtTBwDtNq`bQGRYgQRYXxhfs3N#B?NTX}7dq+A1@dMjeA&
z(%=8M$V%pF9f`=aC^8whrKt&K9R1CN*Q_{yLe`iF`nwFz6OJyM<2r^MMN+-l7;@90
z^}jQtC(P&;)u?;kI39ktxyBxI4dcw`Ttdl-?Rp)F`m5Zzi_BE2bOe@~a_fW{W2yy1
z`F5`tn!1`sCO5{)$NQNX<25q|sU98M+x4%4BkSK3ny1L$>ZrsqMZrI@6gQcR=`F#(
zwG`iGDkkef1lj=Oa6Xf|gyZOSmMWK+s+a^X9Cg3WO+K3i$*rvY&Vz^vmEr!bosEGT
zv}ql};!2kLCoZ&&I13;SD%=GHf;uK`=astc)Cf(@^UajT2(l@Ckuu8io0x;~Jg6Jb
ze>T;<(p>i|rn>SSx3u;U!KASYf!?CAqW%&v0rx{&XQFeWK=J^u2^RKKCPF4AU{imV
z=!SqxT-DX(*y+GJ#&6W6>2*{XXAj<`g;5*i_udMKh|b0U(I+vT&9a!9E$zJ~O9u+D
zrjroY$Wq#Wr}gVw_>utC1&YGWCj2qNRC1iIXtHg;Uy|e%)YJvo@SoAK7&8Cs2!$J{
zHX7goqBBy<OoU%_0+9xY?EB@z6NW`UNW(_6iu&oKQI}!1_K;qmmcBm9sLdKxzDbqS
zpm1B(;)q_I`1*mVx)tp*g@z$4a3R#&ZNfAee<iGQ4%H{+7-~MC>jqBYyiGU}V<m9u
z7}Q6F@~lMB-{N}{S;H_Wlz)&Y`bv--24y3mkbw2IV5g3hYw7cnjJ^`wt7Dj$xl|{k
zuLU6;DM!Yk<LGOFKOg7!cEygq7MuoPh-_XUoQUzp(%U))u_JYLw%&ingbtckf(|pf
zNj>qZ-}9>47i9zbi$Za84TUnFP)Kb0D`Yq5NV)!ABFU(gV5yE^lA2RusFmQtVKDw+
z<G!kuAdB44F-}ShwG#Zh8N)FCU!@0|rgrb8I%+f248KFd<tyP#Sk=?b`#%$cl<}oX
z60`I=^oI2Vlu>m|vW0y=WN<LZ3&ouZ)9~fnvv`I_k8!doJo&-~u6%0KdjAyrg0Qmz
zFMJR}3a?M-rxHWn##gcHt0+Wnblr-_-aF5VdS6@E`Ct+caN{`n<4(W#-7gg0wu)bw
z93Ba*rQiFW1!?LnZOc7GYf_FD&>lRDh%(-le(xXFlzlAxZ<+8{P9>U$+t#>R3(Ib2
zzH*>89TdsI&<T7^%<ZZRIXD=K8}OUjZgHMi&D1FQj!Z@<jc6A;`BDIshh(rb_W8~S
zUXr_GC-$y!#@F;~eOVj~qR~y$$6&7$k3F-YX?SIpmQV$xhvZmvyt`hcXNI9*9nQ;V
zLsxIT5I1ZEzm!F2i2cSxJ@hg^z1Q(JJ<T8NeU#Cgyu1ImXj{|2bSWCdYJjJpS_TJ|
zv2Nqh*5K}Bg9{tmz$Xr9V-N?nPH{SQBVMH?s<g}cE<ZfSnbvr?uPxlSXq4EB_Z<2P
zg77j$K}2)nIj=J{mO%3r=ugxNNDx6~y>VL@9<2K(?sCe<9gy`8GV&THxWp3Yq`+RQ
zCK%L{9{e6-t;30-Xe8b_=lLHAZIPg3W#f>#LR@{ge$3AO?j2`^y{>Q0uTztM<kLPO
zzVoMSebJ9f@I5|AHE7ZOnlFAJx+?w>&JT4)6ZoP^5q~bazsKG3(!K#t^knRSGx|=a
zuzg(=;(wS{3GtZxdZ3s+W`Ee`_SxL{_uT-St{$0=*-bDcZNt*&VH#L1ud-nG$lOpG
zc3asHKGxx#wN-Yv&*`)|M74#6%B&j#bmZ|7a7Y?9x7#T$w4nFMTtNMEY`x5x$489*
z-MNGKusg(MI-dCs49iuJ#|J1d4V&BJ6eSkq9+h)ipu&~M$7A?cn8HbXI2^g}qcYb5
zhUF^E=c7Q<u(?Z|VzdRhN977EQ2Z13eEq1hJ%@kNX!F`#;yzJOgn!UU|B@D0kE}~$
zYX%pOOv5K>jCO&Byv#IAU~e9cq(kxHceunYU<m&u)Jh|Xu{DEzc{D^p%+7l1Epmy;
z7N!*+ke3BKc4QhpNyEgnnT82GE{{g6Q1RjSy2Mxu)4Dtgt$i7vN2AK6blnRYJ`2-|
zMwQFjmy(fb_#_Pz(`Fhb@Ps@XHKP<C{)sM8G+bY5Mp^qZF^>lR_qLobUcXC>8m=$&
z-?_~?HfdxUK1svGv_39G!vyx{)9@%h{N*m;8m=$GW9`cY`80~uobyh1A!TM-=cCBl
zm&qg3@JSjbrp+`=;3@euyowKh$R!-Z_63vJJYP!lXjHkXT<x$yHuqE~%(eMae2|Wr
zuTSLBh<OwZ??U2Z7<t4XQ!{w#$TWPChN<I<52j%Pm*vq&j#GU2SGn*{-pw6XG?L@2
z@~FzAAqtcY3OHR@D<uuLpVmi312Q+jfQoDKX%wmTHsEvNUv&>h1NxzZiN=y)X|Np&
zjCVmJb!0OiLuf3`qY?9{c^jDO!q^T&gJi0MiI3_$8n8QZ-Ufm$q;zC6A3iIMYx8N8
zC_N2CT*5vq4XmI#Y2qWCN2AK7#>H)O(g>KY9+|GPnP5mR%cCJKQ2G&Q%;|@9Y%j3#
zaa|sbm^0?Af$soU$f^GucGYf=yvK&D``72u5Tg_gZyAk?d15FUu#gt;r$(mXlQc{d
z!%V{j{&XIV*cio!|MJ|}%1$U6u`#+lB>09r8e*KH5m=P7K~|X>bI#3QZrhYk1NJmP
zGW7*m9ww&szK}gNf$z<y0b9s4{If^s3yqf4G1-^D%BKN6Wg3CXk@_-3Pyaff2KtiZ
zzFfj<gNf-8`qG?F1ASo{{;P9*NTzifL;CWid>ZHr(+GU}BhI;Pc{Hj<KUT1d`!doR
zRRxdJJTBYwX!Q6LjS<(V9>adfF2?d`#3m{lBifJHM15?fj_t^!ajK}PU^1<9K71<@
zEJ*&ioEoBI_vO*J+ox#wt8+57jLY3a`m!^RM$ZIABd~e|8`Lww+Lv8<Gy-EDcFDfX
z<MlSbF9FP3a~F5#(P$s9X!vg&p)c*@bv|Sl_vF#2nyhF9YDefx)nuK99GCm^Xb5kt
zko^zeGUCI`v`N>^;FdfZv5AU?e?yKB%edt9LxSUZG{jUzBe0kJ9ept}uX9s#V4~8R
zPoqQ>Rk=vVzC?VOneL$)xL`lb;I@1kQxy&W&vJaox;^qH3_fK3fqWX%6^+1Pj)v7H
z<Nu)QT_h^{zwT8n{8_gpo7UdFWp<=?eN)A}z%5Izoxb$4z}#T)ioo6V^_v&Wp1tLc
z#yd7{yyNc6H*VT^*T#m+H`U!Wdvo2U4eQs|Z<*bA*By7>vuVq0VWCpJzHxo+rp@c?
zwpihy9=K-R9h>Xd*9rP2Wm!s%2CDDbvbpw-d-dYL`i*zoS-XB+(U_t!V)=>ylV`-0
z4VyP_s;duxt9xn*=R(FI8cV=Qfas!5iTJcgBQ$xz_9A{>veCDFM|YmX=?`qc*gB)}
zm!jCxiSB#B7EKh0=*j4+=)M<ixW5x!9liQM1JG9BKL{jN(23?)eNoJ)8oBYNTW;O|
z2j7l2Ncy7=?SI1_e@;<y5hbGYj`yd}N#YI@=+vs68E5^Zon3|d`yAdMynq9pe~LdF
ze+l>gl;=>do<G!+W6o`6Zgn(1kSiKxDf+^i)wiw6aeWiIhOMTP;O3pxoi{~Pb`|m`
zSJQ4F&dveD#u(V9<b6Vb`P&O$utl_esrU)n5qlBo?<38-ihP!ZO21($eV9v`99|Zu
z23rm$PdL6^SZ~i9MB6L16(Zg_#xAt^BG=|Sk@#Wl60z!b#+aorCNPE~Ll{np!TjSO
ztm2;=L)P3oysU06MOK#XI45lNQ%4<Xm>z%WrU*tGJV?xUR%4{cVW5Ahpj07#;FlQn
zUn-HgtwfPEH#y2$imWV+th_1Ssh!A#oLlXOQu|YmeXr0l#qlTUusROG%i(ZYYa^>@
zlaLDaoOztyiGUCu_nll7*{?aS!wF&ZM0*(T>)SAHT>UyiLBY6_tJ(|umYgX6dH+FM
zz1?H)KZqk~o~k~g07ly<_3itO<Alf2ryt&yN4-7tP9q(^r^Cvwf|GQN+3v;BWgEtx
zTL`)9sz9V2=fH^oC|b^nd#ZE-2h}&JpYXVeT6;m?z87)2`R`F>^(v^^4L5X%ZSggk
z)Y7&!nYOZpYn%;1>{w%Kn2rUJ#-*mB1h1{|cP$veQ2_4jtfrc|B$L>2E}L!m5q5d$
z1fM+0)$tS#c+ormI9-=Wwri);+MDS`$@YecIfQl_&U%$4o@v)!O?NDQXeC}n#CN`H
zKg;5g>u78V<7?SZKiJ#+xJ*udsP``)k4~f6AKm|^FFNY*yy%%}(RgQce~Q0=9p^pw
zYB-v(<KVz~@Uo}>{0%oGE)wxQr_b*^n5I5Idg?r;79J66spGUIz9-Fy1LqUMu8unF
zeKd0($0IY^Ex;&h-IF;Vx~0M2x+i-+w4}k;x<_O}*Wy{p9$O|fw?3fC%eeg7hDlt$
zvcb#c*EAH;zW$zp^X<2^fKdCjEg;jrvIRuiuW11ZG#lSz#|_-NG9671#vgTNAeB9C
zdQh`x6n_@+=V+WWa>e%)<3>l>;(I(9`WnXs8HM|)Gi)&KJdS4pdwiKTGzuYp8rm7(
zGfp-zG1Kuh8Yq#u$(fE<k@L&k)J(@o<VumVM|2UW=TDzG20^6!^cB5BO0J-iHVCzK
z*_7a0bB?TxP^N8Ji6y!BY3;m5-<9Ir`}B$PT8L6KJnx>@Za+sA7A`CC-uD@yZQ@*n
zi7njIcYg0bo;tsEUK<b>qDxz65^i=r`tQJq^0V{^7;v>=psQ%K+W^KhYJ8>y;gYTr
zKlE2dD(c;RV>X}2Xd(h*6yGy=KKm2=NewyuM}U?2g&xsYX=k8epFD;KH9HOt(r`=@
zRf|MbgR|Y1vImoRR<dV+!CBzC_C7k8S(*LG0FEQLw3ajx+k;y8qh~u0;NUJFAKv?D
z8fbVp{*AZj8<>{h;2$b3UCM`_jl$<qScE}E-Fg=($i!^o^yG;4@5gAo`$4v!ipJ7?
z&XKQ>c+0c#M=!}jK{I>?uw+iMgVf9oa8b77w!eu#>dsQH@yJhp$2VBdELtHN)JRLV
z_^m~^c0IMvM=LOU(%NBUbF$GU{Sj1fZgn`3@LL;T&DmZ>LTaI}e}>><i$n~9i%HlS
zg0a+)z|rn47t;yGh_?MK9c;t5PRLgeBHE!RaN3WU#!+uNA*&7<T!y#Q@tP*Rc|yXC
z3#z;XmD|<~LY+d+hEa(PI5zNQRF@z;S=Rn>fOFZcC0bNZPSom<r0N%P+h;tsBK`_c
z?LEM?-m@6Z#6HYB9Es5my@_V=f`_Mu9#rcO=AR&_WHMF4dV>Qqu0;-kCvVI;B&c-k
zVM1l2$;V%{zaN-p6ZNAy_TkKPyt82xze+}@WKpq<oCmz>!Ttd38J^<F*&hcHIs4bW
zNlyal%rCe^6IzhyqjAg%`s!NN1o^e;@_}P&0UkBt@M8TZ!4sR3kU?w`h|we?I@%vh
zbm$lj27qdg5{*x*DFTiZ^20#J(?*&JmUgEa9RHRuz$Kfkf1^zA9|bs){dr23a>Lb>
z#@Q4YxyLD~(=@!L2TaJ5a>xx9WSqR=&V9jz{Pr6L<?AfSx>)B*WXa?-%D`Dczv<Mb
zl$Fm!?&~>nXDO*OY8BQqhCR{Ve1qpqTB-ydK=*zJZ)dr*s#j<XafH@I-zi@|N^@uE
zE7|$z5&wUIjJ6sLxOyJ|I-i{nP<uK8CaFui>lIR~91)=5<WiCL4Awzs>a(hz)-$x;
z+20LcuZ&D~s#NMSe=(Nu?vnr1f&P(0{r6LE<#hUIAj>)p*S(>fzWQNe9iH#nI^!>C
zzj|ML?ft7?!uP$y$=6<dKYoA`<m|_vi=DI8m&eZ8>s@t|2_64G<^5o`<xTgIhJyV)
zjvw3R{Cd@y_q2+B&BJi*n*R8HF4RzX=1n+$i|`HiM35qf(L}FAwfvm+?f23A{`a}v
ze||r{Uwa0P^SlB!+*FCEO?^L>bs_4=x*Mj935W*AwBKj7v!{RR(wy&43y6CAPu)7l
zox6@SjQs_ilxKgj{Gq2-Jbc+%y+j3Ph^5wT3EaKDZoT;BpA{kg|4RP_5?K0w0SuIR
AD*ylh

literal 0
HcmV?d00001

diff --git a/roms/Makefile b/roms/Makefile
index 10d5a65..882ac32 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -1,5 +1,5 @@
 
-vgabios_variants := stdvga cirrus vmware qxl isavga
+vgabios_variants := stdvga cirrus vmware qxl isavga virtio
 vgabios_targets  := $(subst -isavga,,$(patsubst %,vgabios-%.bin,$(vgabios_variants)))
 pxerom_variants  := e1000 eepro100 ne2k_pci pcnet rtl8139 virtio
 pxerom_targets   := 8086100e 80861209 10500940 10222000 10ec8139 1af41000
diff --git a/roms/config.vga.virtio b/roms/config.vga.virtio
new file mode 100644
index 0000000..9a78983
--- /dev/null
+++ b/roms/config.vga.virtio
@@ -0,0 +1,6 @@
+CONFIG_BUILD_VGABIOS=y
+CONFIG_VGA_BOCHS=y
+CONFIG_VGA_PCI=y
+CONFIG_OVERRIDE_PCI_ID=y
+CONFIG_VGA_VID=0x1af4
+CONFIG_VGA_DID=0x1010
diff --git a/vl.c b/vl.c
index 4ad15b8..de5c40b 100644
--- a/vl.c
+++ b/vl.c
@@ -301,6 +301,7 @@ static struct {
     { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
     { .driver = "vmware-svga",          .flag = &default_vga       },
     { .driver = "qxl-vga",              .flag = &default_vga       },
+    { .driver = "virtio-vga",           .flag = &default_vga       },
 };
 
 static QemuOptsList qemu_rtc_opts = {
@@ -2080,6 +2081,11 @@ static bool qxl_vga_available(void)
     return object_class_by_name("qxl-vga");
 }
 
+static bool virtio_vga_available(void)
+{
+    return object_class_by_name("virtio-vga");
+}
+
 static void select_vgahw (const char *p)
 {
     const char *opts;
@@ -2106,6 +2112,13 @@ static void select_vgahw (const char *p)
             fprintf(stderr, "Error: VMWare SVGA not available\n");
             exit(0);
         }
+    } else if (strstart(p, "virtio", &opts)) {
+        if (virtio_vga_available()) {
+            vga_interface_type = VGA_VIRTIO;
+        } else {
+            fprintf(stderr, "Error: Virtio VGA not available\n");
+            exit(0);
+        }
     } else if (strstart(p, "xenfb", &opts)) {
         vga_interface_type = VGA_XENFB;
     } else if (strstart(p, "qxl", &opts)) {
-- 
1.8.3.1

  parent reply	other threads:[~2013-11-20  5:53 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-20  5:52 [Qemu-devel] [RFC] virtio-gpu and sdl2 so far Dave Airlie
2013-11-20  5:52 ` [Qemu-devel] [PATCH 1/8] ui/sdl2 : initial port to SDL 2.0 (v1.2) Dave Airlie
2013-11-20 10:52   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 2/8] console: add state notifiers for ui<->display Dave Airlie
2013-11-20 11:04   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 3/8] console: add information retrival wrappers Dave Airlie
2013-11-20 11:12   ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 4/8] console: add ability to wrap a console Dave Airlie
2013-11-20  5:52 ` [Qemu-devel] [PATCH 5/8] sdl2: update for multihead support Dave Airlie
2013-11-20  5:52 ` [Qemu-devel] [PATCH 6/8] virtio-gpu: v0.1 of the virtio based GPU code Dave Airlie
2013-11-20 11:26   ` Gerd Hoffmann
2013-11-20  5:52 ` Dave Airlie [this message]
2013-11-20 12:02   ` [Qemu-devel] [PATCH 7/8] virtio-vga: v1 Gerd Hoffmann
2013-11-21  3:12     ` Dave Airlie
2013-11-21  6:17       ` Paolo Bonzini
2013-11-21 11:06       ` Gerd Hoffmann
2013-12-06  5:24         ` Dave Airlie
2013-12-06  8:24           ` Gerd Hoffmann
2013-12-06  8:58             ` Dave Airlie
2014-01-07 23:35               ` Dave Airlie
2014-01-13  8:01                 ` Gerd Hoffmann
2013-11-20  5:52 ` [Qemu-devel] [PATCH 8/8] HACK: just to make things start easier with libvirt Dave Airlie
  -- strict thread matches above, loose matches on Subject: below --
2013-12-10  4:05 [Qemu-devel] [RFC] sdl2 + virtio-gpu repost Dave Airlie
2013-12-10  4:05 ` [Qemu-devel] [PATCH 7/8] virtio-vga: v1 Dave Airlie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1384926761-9962-8-git-send-email-airlied@gmail.com \
    --to=airlied@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.