From: Matt Evans <matt@ozlabs.org>
To: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org
Subject: [PATCH 2/8] kvm tools: Generate SPAPR PPC64 guest device tree
Date: Tue, 06 Dec 2011 15:06:03 +1100 [thread overview]
Message-ID: <4EDD94AB.30303@ozlabs.org> (raw)
In-Reply-To: <cover.1323143103.git.matt@ozlabs.org>
The generated DT is the bare minimum structure required for SPAPR (on which
subsequent patches for VIO, XICS, PCI etc. will build); root node, cpus, memory.
Some aspects are currently hardwired for simplicity, for example advertised
page sizes, HPT size, SLB size, VMX/DFP, etc. Future support of a variety
of POWER CPUs should acquire this info from the host and encode appropriately.
This requires a 64-bit libfdt.
Signed-off-by: Matt Evans <matt@ozlabs.org>
---
tools/kvm/Makefile | 3 +-
tools/kvm/powerpc/kvm.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 143 insertions(+), 1 deletions(-)
diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 58815a2..dc18959 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -129,7 +129,8 @@ ifeq ($(uname_M), ppc64)
OBJS += powerpc/kvm.o
OBJS += powerpc/kvm-cpu.o
ARCH_INCLUDE := powerpc/include
- CFLAGS += -m64
+ CFLAGS += -m64
+ LIBS += -lfdt
endif
###
diff --git a/tools/kvm/powerpc/kvm.c b/tools/kvm/powerpc/kvm.c
index 036bfc0..d792bee 100644
--- a/tools/kvm/powerpc/kvm.c
+++ b/tools/kvm/powerpc/kvm.c
@@ -3,6 +3,9 @@
*
* Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
*
+ * Portions of FDT setup borrowed from QEMU, copyright 2010 David Gibson, IBM
+ * Corporation.
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
@@ -28,8 +31,11 @@
#include <asm/unistd.h>
#include <errno.h>
+#include <linux/byteorder.h>
#include <libfdt.h>
+#define HPT_ORDER 24
+
#define HUGETLBFS_PATH "/var/lib/hugetlbfs/global/pagesize-16MB/"
static char kern_cmdline[2048];
@@ -212,9 +218,144 @@ bool load_bzimage(struct kvm *kvm, int fd_kernel,
return false;
}
+#define SMT_THREADS 4
+
+#define _FDT(exp) \
+ do { \
+ int ret = (exp); \
+ if (ret < 0) { \
+ die("Error creating device tree: %s: %s\n", \
+ #exp, fdt_strerror(ret)); \
+ } \
+ } while (0)
+
+static uint32_t mfpvr(void)
+{
+ uint32_t r;
+ asm volatile ("mfpvr %0" : "=r"(r));
+ return r;
+}
+
static void setup_fdt(struct kvm *kvm)
{
+ uint64_t mem_reg_property[] = { 0, cpu_to_be64(kvm->ram_size) };
+ int smp_cpus = kvm->nrcpus;
+ uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
+ char hypertas_prop_kvm[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
+ "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
+ int i, j;
+ char cpu_name[30];
+ u8 staging_fdt[FDT_MAX_SIZE];
+ uint32_t pvr = mfpvr();
+
+ /* Generate an appropriate DT at kvm->fdt_gra */
+ void *fdt_dest = guest_flat_to_host(kvm, kvm->fdt_gra);
+ void *fdt = staging_fdt;
+
+ _FDT(fdt_create(fdt, FDT_MAX_SIZE));
+ _FDT(fdt_finish_reservemap(fdt));
+
+ _FDT(fdt_begin_node(fdt, ""));
+
+ _FDT(fdt_property_string(fdt, "device_type", "chrp"));
+ _FDT(fdt_property_string(fdt, "model", "IBM pSeries (emulated by kvmtool)"));
+ _FDT(fdt_property_cell(fdt, "#address-cells", 0x2));
+ _FDT(fdt_property_cell(fdt, "#size-cells", 0x2));
+
+ /* /chosen */
+ _FDT(fdt_begin_node(fdt, "chosen"));
+ /* cmdline */
+ _FDT(fdt_property_string(fdt, "bootargs", kern_cmdline));
+ /* Initrd */
+ if (kvm->initrd_size != 0) {
+ uint32_t ird_st_prop = cpu_to_be32(kvm->initrd_gra);
+ uint32_t ird_end_prop = cpu_to_be32(kvm->initrd_gra +
+ kvm->initrd_size);
+ _FDT(fdt_property(fdt, "linux,initrd-start",
+ &ird_st_prop, sizeof(ird_st_prop)));
+ _FDT(fdt_property(fdt, "linux,initrd-end",
+ &ird_end_prop, sizeof(ird_end_prop)));
+ }
+
+ /* Memory: We don't alloc. a separate RMA yet. If we ever need to
+ * (CAP_PPC_RMA == 2) then have one memory node for 0->RMAsize, and
+ * another RMAsize->endOfMem.
+ */
+ _FDT(fdt_begin_node(fdt, "memory@0"));
+ _FDT(fdt_property_string(fdt, "device_type", "memory"));
+ _FDT(fdt_property(fdt, "reg", mem_reg_property, sizeof(mem_reg_property)));
+ _FDT(fdt_end_node(fdt));
+
+ /* CPUs */
+ _FDT(fdt_begin_node(fdt, "cpus"));
+ _FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
+ _FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
+
+ for (i = 0; i < smp_cpus; i += SMT_THREADS) {
+ /* These page and segment sizes are a basic minimum set. Really,
+ * we should be fancier and work out what the host supports then
+ * encode this here.
+ */
+ int32_t page_sizes_prop[] = {0xc, 0x0, 0x1, 0xc, 0x0,
+ 0x18, 0x100, 0x1, 0x18, 0x0};
+ int32_t seg_sizes_prop[] = {0x1c, 0x28, 0xffffffff, 0xffffffff};
+ int32_t pft_size_prop[] = { 0, HPT_ORDER };
+ uint32_t servers_prop[SMT_THREADS];
+ uint32_t gservers_prop[SMT_THREADS * 2];
+ int threads = (smp_cpus - i) >= SMT_THREADS ? SMT_THREADS :
+ smp_cpus - i;
+
+ sprintf(cpu_name, "PowerPC,POWER7@%d", i);
+ _FDT(fdt_begin_node(fdt, cpu_name));
+ _FDT(fdt_property_string(fdt, "name", "PowerPC,POWER7"));
+ _FDT(fdt_property_string(fdt, "device_type", "cpu"));
+
+ _FDT(fdt_property_cell(fdt, "reg", i));
+ _FDT(fdt_property_cell(fdt, "cpu-version", pvr));
+ _FDT(fdt_property_cell(fdt, "dcache-block-size", 0x00000080));
+ _FDT(fdt_property_cell(fdt, "icache-block-size", 0x00000080));
+ _FDT(fdt_property_cell(fdt, "timebase-frequency", 512000000));
+ _FDT(fdt_property_cell(fdt, "clock-frequency", 0xddbab200));
+
+ /* SLB size is hardwired as we currently assume POWERn */
+ _FDT(fdt_property_cell(fdt, "ibm,slb-size", 32));
+ /* HPT size is also hardwired; KVM currently fixes it at 16MB
+ * but the moment that changes we'll need to read it out of the
+ * kernel.
+ */
+ _FDT(fdt_property(fdt, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)));
+
+ _FDT(fdt_property_string(fdt, "status", "okay"));
+ _FDT(fdt_property(fdt, "64-bit", NULL, 0));
+ /* A server for each thread in this core */
+ for (j = 0; j < SMT_THREADS; j++) {
+ servers_prop[j] = cpu_to_be32(i+j);
+ /* Hack borrowed from QEMU, direct the group queues back to cpu 0 */
+ gservers_prop[j*2] = cpu_to_be32(i+j);
+ gservers_prop[j*2 + 1] = 0;
+ }
+ _FDT(fdt_property(fdt, "ibm,ppc-interrupt-server#s",
+ servers_prop, threads * sizeof(uint32_t)));
+ _FDT(fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
+ gservers_prop, threads * 2 * sizeof(uint32_t)));
+ _FDT(fdt_property(fdt, "ibm,segment-page-sizes",
+ page_sizes_prop, sizeof(page_sizes_prop)));
+ _FDT(fdt_property(fdt, "ibm,processor-segment-sizes",
+ seg_sizes_prop, sizeof(seg_sizes_prop)));
+ /* And VMX / DFP */
+ _FDT(fdt_property_cell(fdt, "ibm,vmx", 0x2));
+ _FDT(fdt_property_cell(fdt, "ibm,dfp", 0x1));
+ _FDT(fdt_end_node(fdt));
+ }
+ _FDT(fdt_end_node(fdt));
+
+ /* Finalise: */
+ _FDT(fdt_end_node(fdt)); /* Root node */
+ _FDT(fdt_finish(fdt));
+ _FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE));
+ _FDT(fdt_add_mem_rsv(fdt_dest, kvm->rtas_gra, kvm->rtas_size));
+ _FDT(fdt_pack(fdt_dest));
}
/**
next prev parent reply other threads:[~2011-12-06 4:05 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1323143103.git.matt@ozlabs.org>
2011-12-06 4:05 ` [PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support Matt Evans
2011-12-06 18:03 ` Scott Wood
2011-12-06 18:33 ` Pekka Enberg
2011-12-06 18:54 ` Scott Wood
2011-12-07 7:35 ` Matt Evans
2011-12-07 18:31 ` Scott Wood
2011-12-08 2:57 ` Matt Evans
2011-12-06 4:06 ` Matt Evans [this message]
2011-12-06 4:06 ` [PATCH 3/8] kvm tools: Add SPAPR PPC64 hcall & rtascall structure Matt Evans
2011-12-06 4:06 ` [PATCH 4/8] kvm tools: Add SPAPR PPC64 HV console Matt Evans
2011-12-06 4:06 ` [PATCH 5/8] kvm tools: Add PPC64 XICS interrupt controller support Matt Evans
2011-12-06 4:06 ` [PATCH 6/8] kvm tools: Add PPC64 PCI Host Bridge Matt Evans
2011-12-06 4:06 ` [PATCH 7/8] kvm tools: Add PPC64 kvm_cpu__emulate_io() Matt Evans
2011-12-06 4:06 ` [PATCH 8/8] kvm tools: Make virtio-pci's ioeventfd__add_event() fall back gracefully if ioeventfds unavailable Matt Evans
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=4EDD94AB.30303@ozlabs.org \
--to=matt@ozlabs.org \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).