From patchwork Mon Feb 8 18:53:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 580466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BE8BE140C37 for ; Tue, 9 Feb 2016 05:53:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754414AbcBHSxn (ORCPT ); Mon, 8 Feb 2016 13:53:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52372 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754218AbcBHSxl (ORCPT ); Mon, 8 Feb 2016 13:53:41 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id CB4D639F50C; Mon, 8 Feb 2016 18:53:41 +0000 (UTC) Received: from hawk.localdomain.com (dhcp-1-158.brq.redhat.com [10.34.1.158]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u18IrHax006285; Mon, 8 Feb 2016 13:53:39 -0500 From: Andrew Jones To: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org Cc: thuth@redhat.com, dgibson@redhat.com, david@gibson.dropbear.id.au, agraf@suse.de, lvivier@redhat.com, pbonzini@redhat.com Subject: [kvm-unit-tests PATCH v2 09/14] powerpc/ppc64: adapt arm's setup Date: Mon, 8 Feb 2016 19:53:09 +0100 Message-Id: <1454957594-30601-10-git-send-email-drjones@redhat.com> In-Reply-To: <1454957594-30601-1-git-send-email-drjones@redhat.com> References: <1454957594-30601-1-git-send-email-drjones@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Copy arm's setup code (also DT based) over to powerpc, adapting it a bit. Also bring over arm's setup selftest, giving powerpc its first test. Signed-off-by: Andrew Jones --- lib/powerpc/asm/setup.h | 27 +++++++++++++++ lib/powerpc/setup.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/ppc64/asm/setup.h | 1 + powerpc/cstart64.S | 9 +++++ powerpc/selftest.c | 64 ++++++++++++++++++++++++++++++++-- 5 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 lib/powerpc/asm/setup.h create mode 100644 lib/ppc64/asm/setup.h diff --git a/lib/powerpc/asm/setup.h b/lib/powerpc/asm/setup.h new file mode 100644 index 0000000000000..b9c1c270a2225 --- /dev/null +++ b/lib/powerpc/asm/setup.h @@ -0,0 +1,27 @@ +#ifndef _ASMPOWERPC_SETUP_H_ +#define _ASMPOWERPC_SETUP_H_ +/* + * Copyright (C) 2016, Red Hat Inc, Andrew Jones + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include + +#define NR_CPUS 8 /* arbitrarily set for now */ +extern u32 cpus[NR_CPUS]; +extern int nr_cpus; + +extern phys_addr_t __physical_start, __physical_end; + +#define PHYSICAL_START (__physical_start) +#define PHYSICAL_END (__physical_end) + +#ifdef __powerpc64__ +#define L1_CACHE_SHIFT 7 +#else +#define L1_CACHE_SHIFT 5 +#endif +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define SMP_CACHE_BYTES L1_CACHE_BYTES + +#endif /* _ASMPOWERPC_SETUP_H_ */ diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c index e69de29bb2d1d..a87e0f7642eb0 100644 --- a/lib/powerpc/setup.c +++ b/lib/powerpc/setup.c @@ -0,0 +1,91 @@ +/* + * Initialize machine setup information and I/O. + * + * After running setup() unit tests may query how many cpus they have + * (nr_cpus), how much memory they have (PHYSICAL_END - PHYSICAL_START), + * may use dynamic memory allocation (malloc, etc.), printf, and exit. + * Finally, argc and argv are also ready to be passed to main(). + * + * Copyright (C) 2016, Red Hat Inc, Andrew Jones + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include +#include +#include +#include +#include +#include + +extern unsigned long stacktop; +extern void io_init(void); +extern void setup_args(const char *args); + +u32 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0U) }; +int nr_cpus; + +phys_addr_t __physical_start, __physical_end; + +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused) +{ + int cpu = nr_cpus++; + assert(cpu < NR_CPUS); + cpus[cpu] = regval; +} + +static void cpu_init(void) +{ + int ret; + + nr_cpus = 0; + ret = dt_for_each_cpu_node(cpu_set, NULL); + assert(ret == 0); +} + +static void mem_init(phys_addr_t freemem_start) +{ + /* we only expect one membank to be defined in the DT */ + struct dt_pbus_reg regs[1]; + phys_addr_t mem_start, mem_end; + int ret; + + ret = dt_get_memory_params(regs, 1); + assert(ret != 0); + + mem_start = regs[0].addr; + mem_end = mem_start + regs[0].size; + +// assert(!(mem_start & ~PHYS_MASK) && !((mem_end-1) & ~PHYS_MASK)); + assert(freemem_start >= mem_start && freemem_start < mem_end); + + __physical_start = mem_start; /* PHYSICAL_START */ + __physical_end = mem_end; /* PHYSICAL_END */ + + phys_alloc_init(freemem_start, mem_end - freemem_start); + phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES); +} + +void setup(const void *fdt) +{ + const char *bootargs; + u32 fdt_size; + int ret; + + /* + * Move the fdt to just above the stack. The free memory + * then starts just after the fdt. + */ + fdt_size = fdt_totalsize(fdt); + ret = fdt_move(fdt, &stacktop, fdt_size); + assert(ret == 0); + ret = dt_init(&stacktop); + assert(ret == 0); + + mem_init(PAGE_ALIGN((unsigned long)&stacktop + fdt_size)); + io_init(); + cpu_init(); + + ret = dt_get_bootargs(&bootargs); + assert(ret == 0); + setup_args(bootargs); +} diff --git a/lib/ppc64/asm/setup.h b/lib/ppc64/asm/setup.h new file mode 100644 index 0000000000000..20192985928a4 --- /dev/null +++ b/lib/ppc64/asm/setup.h @@ -0,0 +1 @@ +#include "../../powerpc/asm/setup.h" diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index 466ec800313b3..ce942f93bef05 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -20,10 +20,19 @@ .section .init +/* + * start is the entry point. r3 points to the DTB + */ .globl start start: LOAD_REG_IMMEDIATE(r1, stackptr) LOAD_REG_IMMEDIATE(r2, tocptr) + bl setup + + /* run the test */ + LOAD_REG_IMMEDIATE(r5, __argc) + LOAD_REG_IMMEDIATE(r4, __argv) + lwz r3, 0(r5) bl main bl exit b halt diff --git a/powerpc/selftest.c b/powerpc/selftest.c index 2f2a5215dd55c..3dd7ce9945307 100644 --- a/powerpc/selftest.c +++ b/powerpc/selftest.c @@ -1,7 +1,65 @@ +/* + * Test the framework itself. These tests confirm that setup works. + * + * Copyright (C) 2016, Red Hat Inc, Andrew Jones + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ #include +#include +#include /* phys_addr_t */ +#include -int main(void) +static void check_setup(int argc, char **argv) { - printf("hello world\n"); - return 0; + int nr_tests = 0, len, i; + long val; + + for (i = 0; i < argc; ++i) { + + len = parse_keyval(argv[i], &val); + if (len == -1) + continue; + + argv[i][len] = '\0'; + report_prefix_push(argv[i]); + + if (strcmp(argv[i], "mem") == 0) { + + phys_addr_t memsize = PHYSICAL_END - PHYSICAL_START; + phys_addr_t expected = ((phys_addr_t)val)*1024*1024; + + report("size = %d MB", memsize == expected, + memsize/1024/1024); + ++nr_tests; + + } else if (strcmp(argv[i], "smp") == 0) { + + report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus); + ++nr_tests; + } + + report_prefix_pop(); + } + + if (nr_tests < 2) + report_abort("missing input"); +} + +int main(int argc, char **argv) +{ + report_prefix_push("selftest"); + + if (argc < 1) + report_abort("no test specified"); + + report_prefix_push(argv[0]); + + if (strcmp(argv[0], "setup") == 0) { + + check_setup(argc-1, &argv[1]); + + } + + return report_summary(); }