[PATCH 2/2] qemu: mach-virt: VNC feature relative hardware emulated.

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

 



From: Haibin Wang <wanghaibin.wang@xxxxxxxxxx>

For VNC feature support, there need to add keyborad, mouse, clcd ,panel, vram virtual device
emulated in mach virt, And, relative device dtb node need be created too.

Signed-off-by: Haibin Wang <wanghaibin.wang@xxxxxxxxxx>
---
 hw/arm/virt.c |  188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 188 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8c6b171..9281447 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -67,6 +67,10 @@ enum {
     VIRT_UART,
     VIRT_MMIO,
     VIRT_RTC,
+    VIRT_VRAM,
+    VIRT_CLCD,
+    VIRT_KMI0,
+    VIRT_KMI1,
 };
 
 typedef struct MemMapEntry {
@@ -83,6 +87,9 @@ typedef struct VirtBoardInfo {
     void *fdt;
     int fdt_size;
     uint32_t clock_phandle;
+    uint32_t vram_phandle;
+    uint32_t panel_prot_phandle;
+    uint32_t clcd_pads_phandle;
 } VirtBoardInfo;
 
 /* Addresses and sizes of our components.
@@ -107,6 +114,10 @@ static const MemMapEntry a15memmap[] = {
     [VIRT_UART] =       { 0x09000000, 0x00001000 },
     [VIRT_RTC] =        { 0x09010000, 0x00001000 },
     [VIRT_MMIO] =       { 0x0a000000, 0x00000200 },
+    [VIRT_CLCD] =       { 0x0b000000, 0x1000 },
+    [VIRT_KMI0] =       { 0x0b001000, 0x1000 },
+    [VIRT_KMI1] =       { 0x0b002000, 0x1000 },
+    [VIRT_VRAM] =       { 0x0c000000, 0x800000 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     /* 0x10000000 .. 0x40000000 reserved for PCI */
     [VIRT_MEM] =        { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
@@ -115,6 +126,9 @@ static const MemMapEntry a15memmap[] = {
 static const int a15irqmap[] = {
     [VIRT_UART] = 1,
     [VIRT_RTC] = 2,
+    [VIRT_CLCD] = 8,
+    [VIRT_KMI0] = 9,
+    [VIRT_KMI1] = 10,
     [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
 };
 
@@ -186,6 +200,8 @@ static void create_fdt(VirtBoardInfo *vbi)
                                 "clk24mhz");
     qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
 
+    vbi->clcd_pads_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+    vbi->panel_prot_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
 }
 
 static void fdt_add_psci_node(const VirtBoardInfo *vbi)
@@ -507,6 +523,169 @@ static void create_flash(const VirtBoardInfo *vbi)
     g_free(nodename);
 }
 
+static void create_vram(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_VRAM].base;
+    hwaddr size = vbi->memmap[VIRT_VRAM].size;
+    MemoryRegion *sysmem = get_system_memory();
+    MemoryRegion *vram = g_new(MemoryRegion, 1);
+
+    memory_region_init_ram(vram, NULL, "virt.vram", size,
+                           &error_abort);
+    vmstate_register_ram_global(vram);
+    memory_region_set_log(vram, true, DIRTY_MEMORY_VGA);
+    memory_region_add_subregion(sysmem, base, vram);
+
+    nodename = g_strdup_printf("/vram@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                     2, base, 2, size);
+
+    vbi->vram_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
+    qemu_fdt_setprop_cell(vbi->fdt, nodename, "phandle", vbi->vram_phandle);
+
+    g_free(nodename);
+}
+
+static void create_clcd(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename, *child_nodename;
+    hwaddr base = vbi->memmap[VIRT_CLCD].base;
+    hwaddr size = vbi->memmap[VIRT_CLCD].size;
+    int irq = vbi->irqmap[VIRT_CLCD];
+    const char compat[] = "arm,pl111\0arm,primecell";
+    const char clocknames[] = "clcdclk\0apb_pclk";
+
+    sysbus_create_simple("pl111", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl111@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
+                         compat, sizeof(compat));
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                     2, base, 2, size);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+                               GIC_FDT_IRQ_TYPE_SPI, irq,
+                               GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
+                               vbi->clock_phandle, vbi->clock_phandle);
+    qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
+                         clocknames, sizeof(clocknames));
+
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "max-memory-bandwidth", 36864000);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "memory-region",
+                               vbi->vram_phandle, vbi->vram_phandle);
+
+    child_nodename = g_strconcat(nodename, "/port", NULL);
+    qemu_fdt_add_subnode(vbi->fdt, child_nodename);
+    g_free(child_nodename);
+
+    child_nodename = g_strconcat(nodename, "/port/endpoint", NULL);
+    qemu_fdt_add_subnode(vbi->fdt, child_nodename);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "remote-endpoint",
+                               vbi->panel_prot_phandle, vbi->panel_prot_phandle);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "arm,pl11x,tft-r0g0b0-pads",
+                               0, 8, 16);
+
+    qemu_fdt_setprop_cell(vbi->fdt, child_nodename, "phandle", vbi->clcd_pads_phandle);
+
+    g_free(child_nodename);
+    g_free(nodename);
+}
+
+static void create_panel(VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    const char *nodename = "/panel";
+    const char compat[] = "panel-dpi";
+    char *child_nodename;
+
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
+                         compat, sizeof(compat));
+
+    child_nodename = g_strconcat(nodename, "/port", NULL);
+    qemu_fdt_add_subnode(vbi->fdt, child_nodename);
+    g_free(child_nodename);
+
+    child_nodename = g_strconcat(nodename, "/port/endpoint", NULL);
+    qemu_fdt_add_subnode(vbi->fdt, child_nodename);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "remote-endpoint",
+                               vbi->clcd_pads_phandle, vbi->clcd_pads_phandle);
+    qemu_fdt_setprop_cell(vbi->fdt, child_nodename, "phandle", vbi->panel_prot_phandle);
+    g_free(child_nodename);
+
+    child_nodename = g_strconcat(nodename, "/panel-timing", NULL);
+    qemu_fdt_add_subnode(vbi->fdt, child_nodename);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "clock-frequency", 25175000);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "hactive", 640);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "hback-porch", 40);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "hfront-porch", 24);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "hsync-len", 96);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "vactive", 480);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "vback-porch", 32);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "vfront-porch", 11);
+    qemu_fdt_setprop_cells(vbi->fdt, child_nodename, "vsync-len", 2);
+    g_free(child_nodename);
+}
+
+static void create_keyboard(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_KMI0].base;
+    hwaddr size = vbi->memmap[VIRT_KMI0].size;
+    int irq = vbi->irqmap[VIRT_KMI0];
+    const char compat[] = "arm,pl050\0arm,primecell";
+    const char clocknames[] = "KMIREFCLK\0apb_pclk";
+
+    sysbus_create_simple("pl050_keyboard", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl050_keyboard@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
+                         compat, sizeof(compat));
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                     2, base, 2, size);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+                               GIC_FDT_IRQ_TYPE_SPI, irq,
+                               GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
+                               vbi->clock_phandle, vbi->clock_phandle);
+    qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
+                         clocknames, sizeof(clocknames));
+    g_free(nodename);
+}
+
+static void create_mouse(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_KMI1].base;
+    hwaddr size = vbi->memmap[VIRT_KMI1].size;
+    int irq = vbi->irqmap[VIRT_KMI1];
+    const char compat[] = "arm,pl050\0arm,primecell";
+    const char clocknames[] = "KMIREFCLK\0apb_pclk";
+
+    sysbus_create_simple("pl050_mouse", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl050_mouse@%" PRIx64, base);
+    qemu_fdt_add_subnode(vbi->fdt, nodename);
+
+    qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
+                         compat, sizeof(compat));
+    qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                     2, base, 2, size);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
+                               GIC_FDT_IRQ_TYPE_SPI, irq,
+                               GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+    qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
+                               vbi->clock_phandle, vbi->clock_phandle);
+    qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
+                         clocknames, sizeof(clocknames));
+    g_free(nodename);
+}
+
 static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
 {
     const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
@@ -599,6 +778,15 @@ static void machvirt_init(MachineState *machine)
      */
     create_virtio_devices(vbi, pic);
 
+    create_vram(vbi, pic);
+
+    create_clcd(vbi, pic);
+
+    create_panel(vbi, pic);
+
+    create_keyboard(vbi, pic);
+    create_mouse(vbi, pic);
+
     vbi->bootinfo.ram_size = machine->ram_size;
     vbi->bootinfo.kernel_filename = machine->kernel_filename;
     vbi->bootinfo.kernel_cmdline = machine->kernel_cmdline;
-- 
1.7.1


_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux