1*63e158a0SMatt Evans /* 2*63e158a0SMatt Evans * PPC64 (SPAPR) platform support 3*63e158a0SMatt Evans * 4*63e158a0SMatt Evans * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation. 5*63e158a0SMatt Evans * 6*63e158a0SMatt Evans * This program is free software; you can redistribute it and/or modify it 7*63e158a0SMatt Evans * under the terms of the GNU General Public License version 2 as published 8*63e158a0SMatt Evans * by the Free Software Foundation. 9*63e158a0SMatt Evans */ 10*63e158a0SMatt Evans 11*63e158a0SMatt Evans #include "kvm/kvm.h" 12*63e158a0SMatt Evans #include "kvm/util.h" 13*63e158a0SMatt Evans 14*63e158a0SMatt Evans #include <linux/kvm.h> 15*63e158a0SMatt Evans 16*63e158a0SMatt Evans #include <sys/types.h> 17*63e158a0SMatt Evans #include <sys/ioctl.h> 18*63e158a0SMatt Evans #include <sys/mman.h> 19*63e158a0SMatt Evans #include <stdbool.h> 20*63e158a0SMatt Evans #include <assert.h> 21*63e158a0SMatt Evans #include <stdlib.h> 22*63e158a0SMatt Evans #include <string.h> 23*63e158a0SMatt Evans #include <unistd.h> 24*63e158a0SMatt Evans #include <stdio.h> 25*63e158a0SMatt Evans #include <fcntl.h> 26*63e158a0SMatt Evans #include <asm/unistd.h> 27*63e158a0SMatt Evans #include <errno.h> 28*63e158a0SMatt Evans 29*63e158a0SMatt Evans #include <linux/byteorder.h> 30*63e158a0SMatt Evans #include <libfdt.h> 31*63e158a0SMatt Evans 32*63e158a0SMatt Evans #define HUGETLBFS_PATH "/var/lib/hugetlbfs/global/pagesize-16MB/" 33*63e158a0SMatt Evans 34*63e158a0SMatt Evans static char kern_cmdline[2048]; 35*63e158a0SMatt Evans 36*63e158a0SMatt Evans struct kvm_ext kvm_req_ext[] = { 37*63e158a0SMatt Evans { 0, 0 } 38*63e158a0SMatt Evans }; 39*63e158a0SMatt Evans 40*63e158a0SMatt Evans bool kvm__arch_cpu_supports_vm(void) 41*63e158a0SMatt Evans { 42*63e158a0SMatt Evans return true; 43*63e158a0SMatt Evans } 44*63e158a0SMatt Evans 45*63e158a0SMatt Evans void kvm__init_ram(struct kvm *kvm) 46*63e158a0SMatt Evans { 47*63e158a0SMatt Evans u64 phys_start, phys_size; 48*63e158a0SMatt Evans void *host_mem; 49*63e158a0SMatt Evans 50*63e158a0SMatt Evans phys_start = 0; 51*63e158a0SMatt Evans phys_size = kvm->ram_size; 52*63e158a0SMatt Evans host_mem = kvm->ram_start; 53*63e158a0SMatt Evans 54*63e158a0SMatt Evans /* 55*63e158a0SMatt Evans * We put MMIO at PPC_MMIO_START, high up. Make sure that this doesn't 56*63e158a0SMatt Evans * crash into the end of RAM -- on PPC64 at least, this is so high 57*63e158a0SMatt Evans * (63TB!) that this is unlikely. 58*63e158a0SMatt Evans */ 59*63e158a0SMatt Evans if (phys_size >= PPC_MMIO_START) 60*63e158a0SMatt Evans die("Too much memory (%lld, what a nice problem): " 61*63e158a0SMatt Evans "overlaps MMIO!\n", 62*63e158a0SMatt Evans phys_size); 63*63e158a0SMatt Evans 64*63e158a0SMatt Evans kvm__register_mem(kvm, phys_start, phys_size, host_mem); 65*63e158a0SMatt Evans } 66*63e158a0SMatt Evans 67*63e158a0SMatt Evans void kvm__arch_set_cmdline(char *cmdline, bool video) 68*63e158a0SMatt Evans { 69*63e158a0SMatt Evans /* We don't need anything unusual in here. */ 70*63e158a0SMatt Evans } 71*63e158a0SMatt Evans 72*63e158a0SMatt Evans /* Architecture-specific KVM init */ 73*63e158a0SMatt Evans void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name) 74*63e158a0SMatt Evans { 75*63e158a0SMatt Evans int cap_ppc_rma; 76*63e158a0SMatt Evans 77*63e158a0SMatt Evans kvm->ram_size = ram_size; 78*63e158a0SMatt Evans 79*63e158a0SMatt Evans /* 80*63e158a0SMatt Evans * Currently, we must map from hugetlbfs; if --hugetlbfs not specified, 81*63e158a0SMatt Evans * try a default path: 82*63e158a0SMatt Evans */ 83*63e158a0SMatt Evans if (!hugetlbfs_path) { 84*63e158a0SMatt Evans hugetlbfs_path = HUGETLBFS_PATH; 85*63e158a0SMatt Evans pr_info("Using default %s for memory", hugetlbfs_path); 86*63e158a0SMatt Evans } 87*63e158a0SMatt Evans 88*63e158a0SMatt Evans kvm->ram_start = mmap_hugetlbfs(hugetlbfs_path, kvm->ram_size); 89*63e158a0SMatt Evans if (kvm->ram_start == MAP_FAILED) 90*63e158a0SMatt Evans die("Couldn't map %lld bytes for RAM (%d)\n", 91*63e158a0SMatt Evans kvm->ram_size, errno); 92*63e158a0SMatt Evans 93*63e158a0SMatt Evans /* FDT goes at top of memory, RTAS just below */ 94*63e158a0SMatt Evans kvm->fdt_gra = kvm->ram_size - FDT_MAX_SIZE; 95*63e158a0SMatt Evans /* FIXME: Not all PPC systems have RTAS */ 96*63e158a0SMatt Evans kvm->rtas_gra = kvm->fdt_gra - RTAS_MAX_SIZE; 97*63e158a0SMatt Evans madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE); 98*63e158a0SMatt Evans 99*63e158a0SMatt Evans /* FIXME: This is book3s-specific */ 100*63e158a0SMatt Evans cap_ppc_rma = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_PPC_RMA); 101*63e158a0SMatt Evans if (cap_ppc_rma == 2) 102*63e158a0SMatt Evans die("Need contiguous RMA allocation on this hardware, " 103*63e158a0SMatt Evans "which is not yet supported."); 104*63e158a0SMatt Evans } 105*63e158a0SMatt Evans 106*63e158a0SMatt Evans void kvm__irq_line(struct kvm *kvm, int irq, int level) 107*63e158a0SMatt Evans { 108*63e158a0SMatt Evans fprintf(stderr, "irq_line(%d, %d)\n", irq, level); 109*63e158a0SMatt Evans } 110*63e158a0SMatt Evans 111*63e158a0SMatt Evans void kvm__irq_trigger(struct kvm *kvm, int irq) 112*63e158a0SMatt Evans { 113*63e158a0SMatt Evans kvm__irq_line(kvm, irq, 1); 114*63e158a0SMatt Evans kvm__irq_line(kvm, irq, 0); 115*63e158a0SMatt Evans } 116*63e158a0SMatt Evans 117*63e158a0SMatt Evans int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline) 118*63e158a0SMatt Evans { 119*63e158a0SMatt Evans void *p; 120*63e158a0SMatt Evans void *k_start; 121*63e158a0SMatt Evans void *i_start; 122*63e158a0SMatt Evans int nr; 123*63e158a0SMatt Evans 124*63e158a0SMatt Evans if (lseek(fd_kernel, 0, SEEK_SET) < 0) 125*63e158a0SMatt Evans die_perror("lseek"); 126*63e158a0SMatt Evans 127*63e158a0SMatt Evans p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR); 128*63e158a0SMatt Evans 129*63e158a0SMatt Evans while ((nr = read(fd_kernel, p, 65536)) > 0) 130*63e158a0SMatt Evans p += nr; 131*63e158a0SMatt Evans 132*63e158a0SMatt Evans pr_info("Loaded kernel to 0x%x (%ld bytes)", KERNEL_LOAD_ADDR, p-k_start); 133*63e158a0SMatt Evans 134*63e158a0SMatt Evans if (fd_initrd != -1) { 135*63e158a0SMatt Evans if (lseek(fd_initrd, 0, SEEK_SET) < 0) 136*63e158a0SMatt Evans die_perror("lseek"); 137*63e158a0SMatt Evans 138*63e158a0SMatt Evans if (p-k_start > INITRD_LOAD_ADDR) 139*63e158a0SMatt Evans die("Kernel overlaps initrd!"); 140*63e158a0SMatt Evans 141*63e158a0SMatt Evans /* Round up kernel size to 8byte alignment, and load initrd right after. */ 142*63e158a0SMatt Evans i_start = p = guest_flat_to_host(kvm, INITRD_LOAD_ADDR); 143*63e158a0SMatt Evans 144*63e158a0SMatt Evans while (((nr = read(fd_initrd, p, 65536)) > 0) && 145*63e158a0SMatt Evans p < (kvm->ram_start + kvm->ram_size)) 146*63e158a0SMatt Evans p += nr; 147*63e158a0SMatt Evans 148*63e158a0SMatt Evans if (p >= (kvm->ram_start + kvm->ram_size)) 149*63e158a0SMatt Evans die("initrd too big to contain in guest RAM.\n"); 150*63e158a0SMatt Evans 151*63e158a0SMatt Evans pr_info("Loaded initrd to 0x%x (%ld bytes)", 152*63e158a0SMatt Evans INITRD_LOAD_ADDR, p-i_start); 153*63e158a0SMatt Evans kvm->initrd_gra = INITRD_LOAD_ADDR; 154*63e158a0SMatt Evans kvm->initrd_size = p-i_start; 155*63e158a0SMatt Evans } else { 156*63e158a0SMatt Evans kvm->initrd_size = 0; 157*63e158a0SMatt Evans } 158*63e158a0SMatt Evans strncpy(kern_cmdline, kernel_cmdline, 2048); 159*63e158a0SMatt Evans kern_cmdline[2047] = '\0'; 160*63e158a0SMatt Evans 161*63e158a0SMatt Evans return true; 162*63e158a0SMatt Evans } 163*63e158a0SMatt Evans 164*63e158a0SMatt Evans bool load_bzimage(struct kvm *kvm, int fd_kernel, 165*63e158a0SMatt Evans int fd_initrd, const char *kernel_cmdline, u16 vidmode) 166*63e158a0SMatt Evans { 167*63e158a0SMatt Evans /* We don't support bzImages. */ 168*63e158a0SMatt Evans return false; 169*63e158a0SMatt Evans } 170*63e158a0SMatt Evans 171*63e158a0SMatt Evans static void setup_fdt(struct kvm *kvm) 172*63e158a0SMatt Evans { 173*63e158a0SMatt Evans 174*63e158a0SMatt Evans } 175*63e158a0SMatt Evans 176*63e158a0SMatt Evans /** 177*63e158a0SMatt Evans * kvm__arch_setup_firmware 178*63e158a0SMatt Evans */ 179*63e158a0SMatt Evans void kvm__arch_setup_firmware(struct kvm *kvm) 180*63e158a0SMatt Evans { 181*63e158a0SMatt Evans /* Load RTAS */ 182*63e158a0SMatt Evans 183*63e158a0SMatt Evans /* Load SLOF */ 184*63e158a0SMatt Evans 185*63e158a0SMatt Evans /* Init FDT */ 186*63e158a0SMatt Evans setup_fdt(kvm); 187*63e158a0SMatt Evans } 188