1*7c0e8b0cSWill Deacon #include "kvm/devices.h" 2*7c0e8b0cSWill Deacon #include "kvm/fdt.h" 3*7c0e8b0cSWill Deacon #include "kvm/kvm.h" 4*7c0e8b0cSWill Deacon #include "kvm/kvm-cpu.h" 5*7c0e8b0cSWill Deacon #include "kvm/virtio-mmio.h" 6*7c0e8b0cSWill Deacon 7*7c0e8b0cSWill Deacon #include "arm-common/gic.h" 8*7c0e8b0cSWill Deacon 9*7c0e8b0cSWill Deacon #include <stdbool.h> 10*7c0e8b0cSWill Deacon 11*7c0e8b0cSWill Deacon #include <asm/setup.h> 12*7c0e8b0cSWill Deacon #include <linux/byteorder.h> 13*7c0e8b0cSWill Deacon #include <linux/kernel.h> 14*7c0e8b0cSWill Deacon #include <linux/sizes.h> 15*7c0e8b0cSWill Deacon 16*7c0e8b0cSWill Deacon #define DEBUG 0 17*7c0e8b0cSWill Deacon #define DEBUG_FDT_DUMP_FILE "/tmp/kvmtool.dtb" 18*7c0e8b0cSWill Deacon 19*7c0e8b0cSWill Deacon static char kern_cmdline[COMMAND_LINE_SIZE]; 20*7c0e8b0cSWill Deacon 21*7c0e8b0cSWill Deacon bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) 22*7c0e8b0cSWill Deacon { 23*7c0e8b0cSWill Deacon return false; 24*7c0e8b0cSWill Deacon } 25*7c0e8b0cSWill Deacon 26*7c0e8b0cSWill Deacon int kvm__arch_setup_firmware(struct kvm *kvm) 27*7c0e8b0cSWill Deacon { 28*7c0e8b0cSWill Deacon return 0; 29*7c0e8b0cSWill Deacon } 30*7c0e8b0cSWill Deacon 31*7c0e8b0cSWill Deacon #if DEBUG 32*7c0e8b0cSWill Deacon static void dump_fdt(void *fdt) 33*7c0e8b0cSWill Deacon { 34*7c0e8b0cSWill Deacon int count, fd; 35*7c0e8b0cSWill Deacon 36*7c0e8b0cSWill Deacon fd = open(DEBUG_FDT_DUMP_FILE, O_CREAT | O_TRUNC | O_RDWR, 0666); 37*7c0e8b0cSWill Deacon if (fd < 0) 38*7c0e8b0cSWill Deacon die("Failed to write dtb to %s", DEBUG_FDT_DUMP_FILE); 39*7c0e8b0cSWill Deacon 40*7c0e8b0cSWill Deacon count = write(fd, fdt, FDT_MAX_SIZE); 41*7c0e8b0cSWill Deacon if (count < 0) 42*7c0e8b0cSWill Deacon die_perror("Failed to dump dtb"); 43*7c0e8b0cSWill Deacon 44*7c0e8b0cSWill Deacon pr_info("Wrote %d bytes to dtb %s\n", count, DEBUG_FDT_DUMP_FILE); 45*7c0e8b0cSWill Deacon close(fd); 46*7c0e8b0cSWill Deacon } 47*7c0e8b0cSWill Deacon #else 48*7c0e8b0cSWill Deacon static void dump_fdt(void *fdt) { } 49*7c0e8b0cSWill Deacon #endif 50*7c0e8b0cSWill Deacon 51*7c0e8b0cSWill Deacon #define DEVICE_NAME_MAX_LEN 32 52*7c0e8b0cSWill Deacon static void generate_virtio_mmio_node(void *fdt, struct virtio_mmio *vmmio) 53*7c0e8b0cSWill Deacon { 54*7c0e8b0cSWill Deacon char dev_name[DEVICE_NAME_MAX_LEN]; 55*7c0e8b0cSWill Deacon u64 addr = vmmio->addr; 56*7c0e8b0cSWill Deacon u64 reg_prop[] = { 57*7c0e8b0cSWill Deacon cpu_to_fdt64(addr), 58*7c0e8b0cSWill Deacon cpu_to_fdt64(VIRTIO_MMIO_IO_SIZE) 59*7c0e8b0cSWill Deacon }; 60*7c0e8b0cSWill Deacon u32 irq_prop[] = { 61*7c0e8b0cSWill Deacon cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI), 62*7c0e8b0cSWill Deacon cpu_to_fdt32(vmmio->irq - GIC_SPI_IRQ_BASE), 63*7c0e8b0cSWill Deacon cpu_to_fdt32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI), 64*7c0e8b0cSWill Deacon }; 65*7c0e8b0cSWill Deacon 66*7c0e8b0cSWill Deacon snprintf(dev_name, DEVICE_NAME_MAX_LEN, "virtio@%llx", addr); 67*7c0e8b0cSWill Deacon 68*7c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, dev_name)); 69*7c0e8b0cSWill Deacon _FDT(fdt_property_string(fdt, "compatible", "virtio,mmio")); 70*7c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop))); 71*7c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); 72*7c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 73*7c0e8b0cSWill Deacon } 74*7c0e8b0cSWill Deacon 75*7c0e8b0cSWill Deacon static int setup_fdt(struct kvm *kvm) 76*7c0e8b0cSWill Deacon { 77*7c0e8b0cSWill Deacon struct device_header *dev_hdr; 78*7c0e8b0cSWill Deacon u8 staging_fdt[FDT_MAX_SIZE]; 79*7c0e8b0cSWill Deacon u32 gic_phandle = fdt__alloc_phandle(); 80*7c0e8b0cSWill Deacon u64 mem_reg_prop[] = { 81*7c0e8b0cSWill Deacon cpu_to_fdt64(kvm->arch.memory_guest_start), 82*7c0e8b0cSWill Deacon cpu_to_fdt64(kvm->ram_size), 83*7c0e8b0cSWill Deacon }; 84*7c0e8b0cSWill Deacon void *fdt = staging_fdt; 85*7c0e8b0cSWill Deacon void *fdt_dest = guest_flat_to_host(kvm, 86*7c0e8b0cSWill Deacon kvm->arch.dtb_guest_start); 87*7c0e8b0cSWill Deacon void (*generate_cpu_nodes)(void *, struct kvm *, u32) 88*7c0e8b0cSWill Deacon = kvm->cpus[0]->generate_fdt_nodes; 89*7c0e8b0cSWill Deacon 90*7c0e8b0cSWill Deacon /* Create new tree without a reserve map */ 91*7c0e8b0cSWill Deacon _FDT(fdt_create(fdt, FDT_MAX_SIZE)); 92*7c0e8b0cSWill Deacon if (kvm->nrcpus > 1) 93*7c0e8b0cSWill Deacon _FDT(fdt_add_reservemap_entry(fdt, 94*7c0e8b0cSWill Deacon kvm->arch.smp_pen_guest_start, 95*7c0e8b0cSWill Deacon ARM_SMP_PEN_SIZE)); 96*7c0e8b0cSWill Deacon _FDT(fdt_finish_reservemap(fdt)); 97*7c0e8b0cSWill Deacon 98*7c0e8b0cSWill Deacon /* Header */ 99*7c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "")); 100*7c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "interrupt-parent", gic_phandle)); 101*7c0e8b0cSWill Deacon _FDT(fdt_property_string(fdt, "compatible", "linux,dummy-virt")); 102*7c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "#address-cells", 0x2)); 103*7c0e8b0cSWill Deacon _FDT(fdt_property_cell(fdt, "#size-cells", 0x2)); 104*7c0e8b0cSWill Deacon 105*7c0e8b0cSWill Deacon /* /chosen */ 106*7c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "chosen")); 107*7c0e8b0cSWill Deacon _FDT(fdt_property_string(fdt, "bootargs", kern_cmdline)); 108*7c0e8b0cSWill Deacon 109*7c0e8b0cSWill Deacon /* Initrd */ 110*7c0e8b0cSWill Deacon if (kvm->arch.initrd_size != 0) { 111*7c0e8b0cSWill Deacon u32 ird_st_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start); 112*7c0e8b0cSWill Deacon u32 ird_end_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start + 113*7c0e8b0cSWill Deacon kvm->arch.initrd_size); 114*7c0e8b0cSWill Deacon 115*7c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "linux,initrd-start", 116*7c0e8b0cSWill Deacon &ird_st_prop, sizeof(ird_st_prop))); 117*7c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "linux,initrd-end", 118*7c0e8b0cSWill Deacon &ird_end_prop, sizeof(ird_end_prop))); 119*7c0e8b0cSWill Deacon } 120*7c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 121*7c0e8b0cSWill Deacon 122*7c0e8b0cSWill Deacon /* Memory */ 123*7c0e8b0cSWill Deacon _FDT(fdt_begin_node(fdt, "memory")); 124*7c0e8b0cSWill Deacon _FDT(fdt_property_string(fdt, "device_type", "memory")); 125*7c0e8b0cSWill Deacon _FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop))); 126*7c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 127*7c0e8b0cSWill Deacon 128*7c0e8b0cSWill Deacon /* CPU and peripherals (interrupt controller, timers, etc) */ 129*7c0e8b0cSWill Deacon if (generate_cpu_nodes) 130*7c0e8b0cSWill Deacon generate_cpu_nodes(fdt, kvm, gic_phandle); 131*7c0e8b0cSWill Deacon 132*7c0e8b0cSWill Deacon /* Virtio MMIO devices */ 133*7c0e8b0cSWill Deacon dev_hdr = device__first_dev(DEVICE_BUS_MMIO); 134*7c0e8b0cSWill Deacon while (dev_hdr) { 135*7c0e8b0cSWill Deacon generate_virtio_mmio_node(fdt, dev_hdr->data); 136*7c0e8b0cSWill Deacon dev_hdr = device__next_dev(dev_hdr); 137*7c0e8b0cSWill Deacon } 138*7c0e8b0cSWill Deacon 139*7c0e8b0cSWill Deacon /* Finalise. */ 140*7c0e8b0cSWill Deacon _FDT(fdt_end_node(fdt)); 141*7c0e8b0cSWill Deacon _FDT(fdt_finish(fdt)); 142*7c0e8b0cSWill Deacon 143*7c0e8b0cSWill Deacon _FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE)); 144*7c0e8b0cSWill Deacon _FDT(fdt_pack(fdt_dest)); 145*7c0e8b0cSWill Deacon 146*7c0e8b0cSWill Deacon dump_fdt(fdt_dest); 147*7c0e8b0cSWill Deacon return 0; 148*7c0e8b0cSWill Deacon } 149*7c0e8b0cSWill Deacon late_init(setup_fdt); 150*7c0e8b0cSWill Deacon 151*7c0e8b0cSWill Deacon static int read_image(int fd, void **pos, void *limit) 152*7c0e8b0cSWill Deacon { 153*7c0e8b0cSWill Deacon int count; 154*7c0e8b0cSWill Deacon 155*7c0e8b0cSWill Deacon while (((count = xread(fd, *pos, SZ_64K)) > 0) && *pos <= limit) 156*7c0e8b0cSWill Deacon *pos += count; 157*7c0e8b0cSWill Deacon 158*7c0e8b0cSWill Deacon if (pos < 0) 159*7c0e8b0cSWill Deacon die_perror("xread"); 160*7c0e8b0cSWill Deacon 161*7c0e8b0cSWill Deacon return *pos < limit ? 0 : -ENOMEM; 162*7c0e8b0cSWill Deacon } 163*7c0e8b0cSWill Deacon 164*7c0e8b0cSWill Deacon #define FDT_ALIGN SZ_2M 165*7c0e8b0cSWill Deacon #define INITRD_ALIGN 4 166*7c0e8b0cSWill Deacon #define SMP_PEN_ALIGN PAGE_SIZE 167*7c0e8b0cSWill Deacon int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, 168*7c0e8b0cSWill Deacon const char *kernel_cmdline) 169*7c0e8b0cSWill Deacon { 170*7c0e8b0cSWill Deacon void *pos, *kernel_end, *limit; 171*7c0e8b0cSWill Deacon unsigned long guest_addr; 172*7c0e8b0cSWill Deacon 173*7c0e8b0cSWill Deacon if (lseek(fd_kernel, 0, SEEK_SET) < 0) 174*7c0e8b0cSWill Deacon die_perror("lseek"); 175*7c0e8b0cSWill Deacon 176*7c0e8b0cSWill Deacon /* 177*7c0e8b0cSWill Deacon * Linux requires the initrd, pen and dtb to be mapped inside 178*7c0e8b0cSWill Deacon * lowmem, so we can't just place them at the top of memory. 179*7c0e8b0cSWill Deacon */ 180*7c0e8b0cSWill Deacon limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1; 181*7c0e8b0cSWill Deacon 182*7c0e8b0cSWill Deacon pos = kvm->ram_start + ARM_KERN_OFFSET; 183*7c0e8b0cSWill Deacon kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos); 184*7c0e8b0cSWill Deacon if (read_image(fd_kernel, &pos, limit) == -ENOMEM) 185*7c0e8b0cSWill Deacon die("kernel image too big to contain in guest memory."); 186*7c0e8b0cSWill Deacon 187*7c0e8b0cSWill Deacon kernel_end = pos; 188*7c0e8b0cSWill Deacon pr_info("Loaded kernel to 0x%llx (%llu bytes)", 189*7c0e8b0cSWill Deacon kvm->arch.kern_guest_start, 190*7c0e8b0cSWill Deacon host_to_guest_flat(kvm, pos) - kvm->arch.kern_guest_start); 191*7c0e8b0cSWill Deacon 192*7c0e8b0cSWill Deacon /* 193*7c0e8b0cSWill Deacon * Now load backwards from the end of memory so the kernel 194*7c0e8b0cSWill Deacon * decompressor has plenty of space to work with. First up is 195*7c0e8b0cSWill Deacon * the SMP pen if we have more than one virtual CPU... 196*7c0e8b0cSWill Deacon */ 197*7c0e8b0cSWill Deacon pos = limit; 198*7c0e8b0cSWill Deacon if (kvm->cfg.nrcpus > 1) { 199*7c0e8b0cSWill Deacon pos -= (ARM_SMP_PEN_SIZE + SMP_PEN_ALIGN); 200*7c0e8b0cSWill Deacon guest_addr = ALIGN(host_to_guest_flat(kvm, pos), SMP_PEN_ALIGN); 201*7c0e8b0cSWill Deacon pos = guest_flat_to_host(kvm, guest_addr); 202*7c0e8b0cSWill Deacon if (pos < kernel_end) 203*7c0e8b0cSWill Deacon die("SMP pen overlaps with kernel image."); 204*7c0e8b0cSWill Deacon 205*7c0e8b0cSWill Deacon kvm->arch.smp_pen_guest_start = guest_addr; 206*7c0e8b0cSWill Deacon pr_info("Placing SMP pen at 0x%llx - 0x%llx", 207*7c0e8b0cSWill Deacon kvm->arch.smp_pen_guest_start, 208*7c0e8b0cSWill Deacon host_to_guest_flat(kvm, limit)); 209*7c0e8b0cSWill Deacon limit = pos; 210*7c0e8b0cSWill Deacon } 211*7c0e8b0cSWill Deacon 212*7c0e8b0cSWill Deacon /* ...now the device tree blob... */ 213*7c0e8b0cSWill Deacon pos -= (FDT_MAX_SIZE + FDT_ALIGN); 214*7c0e8b0cSWill Deacon guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN); 215*7c0e8b0cSWill Deacon pos = guest_flat_to_host(kvm, guest_addr); 216*7c0e8b0cSWill Deacon if (pos < kernel_end) 217*7c0e8b0cSWill Deacon die("fdt overlaps with kernel image."); 218*7c0e8b0cSWill Deacon 219*7c0e8b0cSWill Deacon kvm->arch.dtb_guest_start = guest_addr; 220*7c0e8b0cSWill Deacon pr_info("Placing fdt at 0x%llx - 0x%llx", 221*7c0e8b0cSWill Deacon kvm->arch.dtb_guest_start, 222*7c0e8b0cSWill Deacon host_to_guest_flat(kvm, limit)); 223*7c0e8b0cSWill Deacon limit = pos; 224*7c0e8b0cSWill Deacon 225*7c0e8b0cSWill Deacon /* ... and finally the initrd, if we have one. */ 226*7c0e8b0cSWill Deacon if (fd_initrd != -1) { 227*7c0e8b0cSWill Deacon struct stat sb; 228*7c0e8b0cSWill Deacon unsigned long initrd_start; 229*7c0e8b0cSWill Deacon 230*7c0e8b0cSWill Deacon if (lseek(fd_initrd, 0, SEEK_SET) < 0) 231*7c0e8b0cSWill Deacon die_perror("lseek"); 232*7c0e8b0cSWill Deacon 233*7c0e8b0cSWill Deacon if (fstat(fd_initrd, &sb)) 234*7c0e8b0cSWill Deacon die_perror("fstat"); 235*7c0e8b0cSWill Deacon 236*7c0e8b0cSWill Deacon pos -= (sb.st_size + INITRD_ALIGN); 237*7c0e8b0cSWill Deacon guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN); 238*7c0e8b0cSWill Deacon pos = guest_flat_to_host(kvm, guest_addr); 239*7c0e8b0cSWill Deacon if (pos < kernel_end) 240*7c0e8b0cSWill Deacon die("initrd overlaps with kernel image."); 241*7c0e8b0cSWill Deacon 242*7c0e8b0cSWill Deacon initrd_start = guest_addr; 243*7c0e8b0cSWill Deacon if (read_image(fd_initrd, &pos, limit) == -ENOMEM) 244*7c0e8b0cSWill Deacon die("initrd too big to contain in guest memory."); 245*7c0e8b0cSWill Deacon 246*7c0e8b0cSWill Deacon kvm->arch.initrd_guest_start = initrd_start; 247*7c0e8b0cSWill Deacon kvm->arch.initrd_size = host_to_guest_flat(kvm, pos) - initrd_start; 248*7c0e8b0cSWill Deacon pr_info("Loaded initrd to 0x%llx (%llu bytes)", 249*7c0e8b0cSWill Deacon kvm->arch.initrd_guest_start, 250*7c0e8b0cSWill Deacon kvm->arch.initrd_size); 251*7c0e8b0cSWill Deacon } else { 252*7c0e8b0cSWill Deacon kvm->arch.initrd_size = 0; 253*7c0e8b0cSWill Deacon } 254*7c0e8b0cSWill Deacon 255*7c0e8b0cSWill Deacon strncpy(kern_cmdline, kernel_cmdline, COMMAND_LINE_SIZE); 256*7c0e8b0cSWill Deacon kern_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; 257*7c0e8b0cSWill Deacon 258*7c0e8b0cSWill Deacon return true; 259*7c0e8b0cSWill Deacon } 260*7c0e8b0cSWill Deacon 261*7c0e8b0cSWill Deacon bool load_bzimage(struct kvm *kvm, int fd_kernel, 262*7c0e8b0cSWill Deacon int fd_initrd, const char *kernel_cmdline, u16 vidmode) 263*7c0e8b0cSWill Deacon { 264*7c0e8b0cSWill Deacon /* To b or not to b? That is the zImage. */ 265*7c0e8b0cSWill Deacon return false; 266*7c0e8b0cSWill Deacon } 267