1 /* 2 * libqos driver framework 3 * 4 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License version 2.1 as published by the Free Software Foundation. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, see <http://www.gnu.org/licenses/> 17 */ 18 19 #include "qemu/osdep.h" 20 #include "../libqtest.h" 21 #include "qemu/module.h" 22 #include "libqos-malloc.h" 23 #include "qgraph.h" 24 #include "virtio-mmio.h" 25 #include "generic-pcihost.h" 26 #include "hw/pci/pci_regs.h" 27 28 #define LOONGARCH_PAGE_SIZE 0x1000 29 #define LOONGARCH_VIRT_RAM_ADDR 0x100000 30 #define LOONGARCH_VIRT_RAM_SIZE 0xFF00000 31 32 #define LOONGARCH_VIRT_PIO_BASE 0x18000000 33 #define LOONGARCH_VIRT_PCIE_PIO_OFFSET 0x4000 34 #define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x10000 35 #define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x20000000 36 #define LOONGARCH_VIRT_PCIE_MMIO32_BASE 0x40000000 37 #define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT 0x80000000 38 39 typedef struct QVirtMachine QVirtMachine; 40 41 struct QVirtMachine { 42 QOSGraphObject obj; 43 QGuestAllocator alloc; 44 QVirtioMMIODevice virtio_mmio; 45 QGenericPCIHost bridge; 46 }; 47 48 static void virt_destructor(QOSGraphObject *obj) 49 { 50 QVirtMachine *machine = (QVirtMachine *) obj; 51 alloc_destroy(&machine->alloc); 52 } 53 54 static void *virt_get_driver(void *object, const char *interface) 55 { 56 QVirtMachine *machine = object; 57 if (!g_strcmp0(interface, "memory")) { 58 return &machine->alloc; 59 } 60 61 fprintf(stderr, "%s not present in loongarch/virtio\n", interface); 62 g_assert_not_reached(); 63 } 64 65 static QOSGraphObject *virt_get_device(void *obj, const char *device) 66 { 67 QVirtMachine *machine = obj; 68 if (!g_strcmp0(device, "generic-pcihost")) { 69 return &machine->bridge.obj; 70 } else if (!g_strcmp0(device, "virtio-mmio")) { 71 return &machine->virtio_mmio.obj; 72 } 73 74 fprintf(stderr, "%s not present in loongarch/virt\n", device); 75 g_assert_not_reached(); 76 } 77 78 static void loongarch_config_qpci_bus(QGenericPCIBus *qpci) 79 { 80 qpci->gpex_pio_base = LOONGARCH_VIRT_PIO_BASE; 81 qpci->bus.pio_alloc_ptr = LOONGARCH_VIRT_PCIE_PIO_OFFSET; 82 qpci->bus.pio_limit = LOONGARCH_VIRT_PCIE_PIO_LIMIT; 83 qpci->bus.mmio_alloc_ptr = LOONGARCH_VIRT_PCIE_MMIO32_BASE; 84 qpci->bus.mmio_limit = LOONGARCH_VIRT_PCIE_MMIO32_LIMIT; 85 qpci->ecam_alloc_ptr = LOONGARCH_VIRT_PCIE_ECAM_BASE; 86 } 87 88 static void *qos_create_machine_loongarch_virt(QTestState *qts) 89 { 90 QVirtMachine *machine = g_new0(QVirtMachine, 1); 91 92 alloc_init(&machine->alloc, 0, 93 LOONGARCH_VIRT_RAM_ADDR, 94 LOONGARCH_VIRT_RAM_ADDR + LOONGARCH_VIRT_RAM_SIZE, 95 LOONGARCH_PAGE_SIZE); 96 97 qos_create_generic_pcihost(&machine->bridge, qts, &machine->alloc); 98 loongarch_config_qpci_bus(&machine->bridge.pci); 99 100 machine->obj.get_device = virt_get_device; 101 machine->obj.get_driver = virt_get_driver; 102 machine->obj.destructor = virt_destructor; 103 return machine; 104 } 105 106 static void virt_machine_register_nodes(void) 107 { 108 qos_node_create_machine_args("loongarch64/virt", 109 qos_create_machine_loongarch_virt, 110 " -cpu la464"); 111 qos_node_contains("loongarch64/virt", "generic-pcihost", NULL); 112 } 113 114 libqos_init(virt_machine_register_nodes); 115