From: David Gibson <david@gibson.dropbear.id.au>
To: Andrew Jones <drjones@redhat.com>
Cc: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org, thuth@redhat.com,
dgibson@redhat.com, agraf@suse.de, lvivier@redhat.com,
pbonzini@redhat.com, rkrcmar@redhat.com
Subject: Re: [kvm-unit-tests PATCH v6 13/18] powerpc/ppc64: adapt arm's setup
Date: Mon, 29 Feb 2016 00:54:27 +0000 [thread overview]
Message-ID: <20160229005427.GA5427@voom.redhat.com> (raw)
In-Reply-To: <20160226130824.uwmnuwrbtopfwkx7@hawk.localdomain>
[-- Attachment #1: Type: text/plain, Size: 13306 bytes --]
On Fri, Feb 26, 2016 at 02:08:24PM +0100, Andrew Jones wrote:
> On Wed, Feb 24, 2016 at 11:31:23AM +1100, David Gibson wrote:
> > On Tue, Feb 23, 2016 at 04:04:52PM +0100, Andrew Jones wrote:
> > > On Fri, Feb 19, 2016 at 04:58:18PM +0100, Andrew Jones wrote:
> > > > 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.
> > > >
> > > > The largest change from arm's setup.c is that instead of using a
> > > > hardcoded SMP_CACHE_BYTES, cpu_set() is extended to extract the
> > > > icache and dcache line sizes from the cpu DT nodes. That change
> > > > also requires that we call cpu_init() before mem_init() in setup().
> > > >
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > > > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > >
> > > Hi David,
> > >
> > > Any comments on this one?
> >
> > Uh.. not really. I'm kind of not sure what to say, since by design
> > it's a broken interim step, that won't work until the fixups in the
> > next patch.
> >
> > Given that, nothing looks obvious more broken than is expected, so
> >
> > Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>
> Well, actually setup.c is done changing after this patch, so fixup-wise,
> the later patches (reloc, hcalls) only enable it to actually do
> something. So if there's something (e.g. the cache line size acquisition
> from the DT) that you don't like, then I should fix it here.
Oh, sorry. Somehow I mixed this one up with the earlier patch which
just copies files about.
>
> Thanks,
> drew
>
> >
> > >
> > > Thanks,
> > > drew
> > >
> > > > ---
> > > > lib/powerpc/asm/setup.h | 29 ++++++++++
> > > > lib/powerpc/setup.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > lib/ppc64/asm/setup.h | 1 +
> > > > powerpc/Makefile.common | 1 +
> > > > powerpc/cstart64.S | 16 +++++-
> > > > powerpc/selftest.c | 63 +++++++++++++++++++-
> > > > 6 files changed, 256 insertions(+), 4 deletions(-)
> > > > create mode 100644 lib/powerpc/asm/setup.h
> > > > create mode 100644 lib/powerpc/setup.c
> > > > 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..29a6d7d5f705a
> > > > --- /dev/null
> > > > +++ b/lib/powerpc/asm/setup.h
> > > > @@ -0,0 +1,29 @@
> > > > +#ifndef _ASMPOWERPC_SETUP_H_
> > > > +#define _ASMPOWERPC_SETUP_H_
> > > > +/*
> > > > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > +#include <libcflat.h>
> > > > +#include <alloc.h> /* phys_addr_t */
> > > > +
> > > > +#define NR_CPUS 8 /* arbitrarily set for now */
> > > > +extern u32 cpus[NR_CPUS];
> > > > +extern int nr_cpus;
> > > > +
> > > > +#define NR_MEM_REGIONS 8
> > > > +#define MR_F_PRIMARY (1U << 0)
> > > > +struct mem_region {
> > > > + phys_addr_t start;
> > > > + phys_addr_t end;
> > > > + unsigned int flags;
> > > > +};
> > > > +extern struct mem_region mem_regions[NR_MEM_REGIONS];
> > > > +extern phys_addr_t __physical_start, __physical_end;
> > > > +extern unsigned __icache_bytes, __dcache_bytes;
> > > > +
> > > > +#define PHYSICAL_START (__physical_start)
> > > > +#define PHYSICAL_END (__physical_end)
> > > > +
> > > > +#endif /* _ASMPOWERPC_SETUP_H_ */
> > > > diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
> > > > new file mode 100644
> > > > index 0000000000000..0c0c882a44a10
> > > > --- /dev/null
> > > > +++ b/lib/powerpc/setup.c
> > > > @@ -0,0 +1,150 @@
> > > > +/*
> > > > + * 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 <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > +#include <libcflat.h>
> > > > +#include <libfdt/libfdt.h>
> > > > +#include <devicetree.h>
> > > > +#include <alloc.h>
> > > > +#include <asm/setup.h>
> > > > +#include <asm/page.h>
> > > > +
> > > > +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;
> > > > +
> > > > +struct mem_region mem_regions[NR_MEM_REGIONS];
> > > > +phys_addr_t __physical_start, __physical_end;
> > > > +unsigned __icache_bytes, __dcache_bytes;
> > > > +
> > > > +struct cpu_set_params {
> > > > + unsigned icache_bytes;
> > > > + unsigned dcache_bytes;
> > > > +};
> > > > +
> > > > +static void cpu_set(int fdtnode, u32 regval, void *info)
> > > > +{
> > > > + static bool read_common_info = false;
> > > > + struct cpu_set_params *params = info;
> > > > + int cpu = nr_cpus++;
> > > > +
> > > > + if (cpu >= NR_CPUS) {
> > > > + printf("Number cpus exceeds maximum supported (%d).\n",
> > > > + NR_CPUS);
> > > > + assert(0);
> > > > + }
> > > > + cpus[cpu] = regval;
> > > > +
> > > > + if (!read_common_info) {
> > > > + const struct fdt_property *prop;
> > > > + u32 *data;
> > > > +
> > > > + prop = fdt_get_property(dt_fdt(), fdtnode,
> > > > + "i-cache-line-size", NULL);
> > > > + assert(prop != NULL);
> > > > + data = (u32 *)prop->data;
> > > > + params->icache_bytes = fdt32_to_cpu(*data);
> > > > +
> > > > + prop = fdt_get_property(dt_fdt(), fdtnode,
> > > > + "d-cache-line-size", NULL);
> > > > + assert(prop != NULL);
> > > > + data = (u32 *)prop->data;
> > > > + params->dcache_bytes = fdt32_to_cpu(*data);
> > > > +
> > > > + read_common_info = true;
> > > > + }
> > > > +}
> > > > +
> > > > +static void cpu_init(void)
> > > > +{
> > > > + struct cpu_set_params params;
> > > > + int ret;
> > > > +
> > > > + nr_cpus = 0;
> > > > + ret = dt_for_each_cpu_node(cpu_set, ¶ms);
> > > > + assert(ret == 0);
> > > > + __icache_bytes = params.icache_bytes;
> > > > + __dcache_bytes = params.dcache_bytes;
> > > > +}
> > > > +
> > > > +static void mem_init(phys_addr_t freemem_start)
> > > > +{
> > > > + struct dt_pbus_reg regs[NR_MEM_REGIONS];
> > > > + struct mem_region primary, mem = {
> > > > + .start = (phys_addr_t)-1,
> > > > + };
> > > > + int nr_regs, i;
> > > > +
> > > > + nr_regs = dt_get_memory_params(regs, NR_MEM_REGIONS);
> > > > + assert(nr_regs > 0);
> > > > +
> > > > + primary.end = 0;
> > > > +
> > > > + for (i = 0; i < nr_regs; ++i) {
> > > > + mem_regions[i].start = regs[i].addr;
> > > > + mem_regions[i].end = regs[i].addr + regs[i].size;
> > > > +
> > > > + /*
> > > > + * pick the region we're in for our primary region
> > > > + */
> > > > + if (freemem_start >= mem_regions[i].start
> > > > + && freemem_start < mem_regions[i].end) {
> > > > + mem_regions[i].flags |= MR_F_PRIMARY;
> > > > + primary = mem_regions[i];
> > > > + }
> > > > +
> > > > + /*
> > > > + * set the lowest and highest addresses found,
> > > > + * ignoring potential gaps
> > > > + */
> > > > + if (mem_regions[i].start < mem.start)
> > > > + mem.start = mem_regions[i].start;
> > > > + if (mem_regions[i].end > mem.end)
> > > > + mem.end = mem_regions[i].end;
> > > > + }
> > > > + assert(primary.end != 0);
> > > > +// assert(!(mem.start & ~PHYS_MASK) && !((mem.end - 1) & ~PHYS_MASK));
> > > > +
> > > > + __physical_start = mem.start; /* PHYSICAL_START */
> > > > + __physical_end = mem.end; /* PHYSICAL_END */
> > > > +
> > > > + phys_alloc_init(freemem_start, primary.end - freemem_start);
> > > > + phys_alloc_set_minimum_alignment(__icache_bytes > __dcache_bytes
> > > > + ? __icache_bytes : __dcache_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);
> > > > +
> > > > + cpu_init();
> > > > + mem_init(PAGE_ALIGN((unsigned long)&stacktop + fdt_size));
> > > > + io_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/Makefile.common b/powerpc/Makefile.common
> > > > index b21e3933d0643..539bd33d1c309 100644
> > > > --- a/powerpc/Makefile.common
> > > > +++ b/powerpc/Makefile.common
> > > > @@ -26,6 +26,7 @@ cflatobjs += lib/alloc.o
> > > > cflatobjs += lib/devicetree.o
> > > > cflatobjs += lib/powerpc/io.o
> > > > cflatobjs += lib/powerpc/hcall.o
> > > > +cflatobjs += lib/powerpc/setup.o
> > > >
> > > > libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> > > >
> > > > diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> > > > index 1884d79871ba5..526452835754f 100644
> > > > --- a/powerpc/cstart64.S
> > > > +++ b/powerpc/cstart64.S
> > > > @@ -20,11 +20,17 @@
> > > >
> > > > .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)
> > > >
> > > > + /* save DTB pointer */
> > > > + std r3, 56(r1)
> > > > +
> > > > /* patch sc1 if needed */
> > > > bl hcall_have_broken_sc1
> > > > cmpwi r3, 0
> > > > @@ -33,7 +39,15 @@ start:
> > > > LOAD_REG_IMMEDIATE(r4, SC1_REPLACEMENT)
> > > > stw r4, 0(r3)
> > > >
> > > > -1: bl main
> > > > + /* complete setup */
> > > > +1: ld r3, 56(r1)
> > > > + 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..84867e482d2a2 100644
> > > > --- a/powerpc/selftest.c
> > > > +++ b/powerpc/selftest.c
> > > > @@ -1,7 +1,64 @@
> > > > +/*
> > > > + * Test the framework itself. These tests confirm that setup works.
> > > > + *
> > > > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > #include <libcflat.h>
> > > > +#include <util.h>
> > > > +#include <asm/setup.h>
> > > >
> > > > -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)
> > > > + 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();
> > > > }
> > >
> >
>
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: David Gibson <david@gibson.dropbear.id.au>
To: Andrew Jones <drjones@redhat.com>
Cc: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org, thuth@redhat.com,
dgibson@redhat.com, agraf@suse.de, lvivier@redhat.com,
pbonzini@redhat.com, rkrcmar@redhat.com
Subject: Re: [kvm-unit-tests PATCH v6 13/18] powerpc/ppc64: adapt arm's setup
Date: Mon, 29 Feb 2016 11:54:27 +1100 [thread overview]
Message-ID: <20160229005427.GA5427@voom.redhat.com> (raw)
In-Reply-To: <20160226130824.uwmnuwrbtopfwkx7@hawk.localdomain>
[-- Attachment #1: Type: text/plain, Size: 13306 bytes --]
On Fri, Feb 26, 2016 at 02:08:24PM +0100, Andrew Jones wrote:
> On Wed, Feb 24, 2016 at 11:31:23AM +1100, David Gibson wrote:
> > On Tue, Feb 23, 2016 at 04:04:52PM +0100, Andrew Jones wrote:
> > > On Fri, Feb 19, 2016 at 04:58:18PM +0100, Andrew Jones wrote:
> > > > 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.
> > > >
> > > > The largest change from arm's setup.c is that instead of using a
> > > > hardcoded SMP_CACHE_BYTES, cpu_set() is extended to extract the
> > > > icache and dcache line sizes from the cpu DT nodes. That change
> > > > also requires that we call cpu_init() before mem_init() in setup().
> > > >
> > > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > > > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > >
> > > Hi David,
> > >
> > > Any comments on this one?
> >
> > Uh.. not really. I'm kind of not sure what to say, since by design
> > it's a broken interim step, that won't work until the fixups in the
> > next patch.
> >
> > Given that, nothing looks obvious more broken than is expected, so
> >
> > Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>
> Well, actually setup.c is done changing after this patch, so fixup-wise,
> the later patches (reloc, hcalls) only enable it to actually do
> something. So if there's something (e.g. the cache line size acquisition
> from the DT) that you don't like, then I should fix it here.
Oh, sorry. Somehow I mixed this one up with the earlier patch which
just copies files about.
>
> Thanks,
> drew
>
> >
> > >
> > > Thanks,
> > > drew
> > >
> > > > ---
> > > > lib/powerpc/asm/setup.h | 29 ++++++++++
> > > > lib/powerpc/setup.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > lib/ppc64/asm/setup.h | 1 +
> > > > powerpc/Makefile.common | 1 +
> > > > powerpc/cstart64.S | 16 +++++-
> > > > powerpc/selftest.c | 63 +++++++++++++++++++-
> > > > 6 files changed, 256 insertions(+), 4 deletions(-)
> > > > create mode 100644 lib/powerpc/asm/setup.h
> > > > create mode 100644 lib/powerpc/setup.c
> > > > 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..29a6d7d5f705a
> > > > --- /dev/null
> > > > +++ b/lib/powerpc/asm/setup.h
> > > > @@ -0,0 +1,29 @@
> > > > +#ifndef _ASMPOWERPC_SETUP_H_
> > > > +#define _ASMPOWERPC_SETUP_H_
> > > > +/*
> > > > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > +#include <libcflat.h>
> > > > +#include <alloc.h> /* phys_addr_t */
> > > > +
> > > > +#define NR_CPUS 8 /* arbitrarily set for now */
> > > > +extern u32 cpus[NR_CPUS];
> > > > +extern int nr_cpus;
> > > > +
> > > > +#define NR_MEM_REGIONS 8
> > > > +#define MR_F_PRIMARY (1U << 0)
> > > > +struct mem_region {
> > > > + phys_addr_t start;
> > > > + phys_addr_t end;
> > > > + unsigned int flags;
> > > > +};
> > > > +extern struct mem_region mem_regions[NR_MEM_REGIONS];
> > > > +extern phys_addr_t __physical_start, __physical_end;
> > > > +extern unsigned __icache_bytes, __dcache_bytes;
> > > > +
> > > > +#define PHYSICAL_START (__physical_start)
> > > > +#define PHYSICAL_END (__physical_end)
> > > > +
> > > > +#endif /* _ASMPOWERPC_SETUP_H_ */
> > > > diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c
> > > > new file mode 100644
> > > > index 0000000000000..0c0c882a44a10
> > > > --- /dev/null
> > > > +++ b/lib/powerpc/setup.c
> > > > @@ -0,0 +1,150 @@
> > > > +/*
> > > > + * 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 <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > +#include <libcflat.h>
> > > > +#include <libfdt/libfdt.h>
> > > > +#include <devicetree.h>
> > > > +#include <alloc.h>
> > > > +#include <asm/setup.h>
> > > > +#include <asm/page.h>
> > > > +
> > > > +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;
> > > > +
> > > > +struct mem_region mem_regions[NR_MEM_REGIONS];
> > > > +phys_addr_t __physical_start, __physical_end;
> > > > +unsigned __icache_bytes, __dcache_bytes;
> > > > +
> > > > +struct cpu_set_params {
> > > > + unsigned icache_bytes;
> > > > + unsigned dcache_bytes;
> > > > +};
> > > > +
> > > > +static void cpu_set(int fdtnode, u32 regval, void *info)
> > > > +{
> > > > + static bool read_common_info = false;
> > > > + struct cpu_set_params *params = info;
> > > > + int cpu = nr_cpus++;
> > > > +
> > > > + if (cpu >= NR_CPUS) {
> > > > + printf("Number cpus exceeds maximum supported (%d).\n",
> > > > + NR_CPUS);
> > > > + assert(0);
> > > > + }
> > > > + cpus[cpu] = regval;
> > > > +
> > > > + if (!read_common_info) {
> > > > + const struct fdt_property *prop;
> > > > + u32 *data;
> > > > +
> > > > + prop = fdt_get_property(dt_fdt(), fdtnode,
> > > > + "i-cache-line-size", NULL);
> > > > + assert(prop != NULL);
> > > > + data = (u32 *)prop->data;
> > > > + params->icache_bytes = fdt32_to_cpu(*data);
> > > > +
> > > > + prop = fdt_get_property(dt_fdt(), fdtnode,
> > > > + "d-cache-line-size", NULL);
> > > > + assert(prop != NULL);
> > > > + data = (u32 *)prop->data;
> > > > + params->dcache_bytes = fdt32_to_cpu(*data);
> > > > +
> > > > + read_common_info = true;
> > > > + }
> > > > +}
> > > > +
> > > > +static void cpu_init(void)
> > > > +{
> > > > + struct cpu_set_params params;
> > > > + int ret;
> > > > +
> > > > + nr_cpus = 0;
> > > > + ret = dt_for_each_cpu_node(cpu_set, ¶ms);
> > > > + assert(ret == 0);
> > > > + __icache_bytes = params.icache_bytes;
> > > > + __dcache_bytes = params.dcache_bytes;
> > > > +}
> > > > +
> > > > +static void mem_init(phys_addr_t freemem_start)
> > > > +{
> > > > + struct dt_pbus_reg regs[NR_MEM_REGIONS];
> > > > + struct mem_region primary, mem = {
> > > > + .start = (phys_addr_t)-1,
> > > > + };
> > > > + int nr_regs, i;
> > > > +
> > > > + nr_regs = dt_get_memory_params(regs, NR_MEM_REGIONS);
> > > > + assert(nr_regs > 0);
> > > > +
> > > > + primary.end = 0;
> > > > +
> > > > + for (i = 0; i < nr_regs; ++i) {
> > > > + mem_regions[i].start = regs[i].addr;
> > > > + mem_regions[i].end = regs[i].addr + regs[i].size;
> > > > +
> > > > + /*
> > > > + * pick the region we're in for our primary region
> > > > + */
> > > > + if (freemem_start >= mem_regions[i].start
> > > > + && freemem_start < mem_regions[i].end) {
> > > > + mem_regions[i].flags |= MR_F_PRIMARY;
> > > > + primary = mem_regions[i];
> > > > + }
> > > > +
> > > > + /*
> > > > + * set the lowest and highest addresses found,
> > > > + * ignoring potential gaps
> > > > + */
> > > > + if (mem_regions[i].start < mem.start)
> > > > + mem.start = mem_regions[i].start;
> > > > + if (mem_regions[i].end > mem.end)
> > > > + mem.end = mem_regions[i].end;
> > > > + }
> > > > + assert(primary.end != 0);
> > > > +// assert(!(mem.start & ~PHYS_MASK) && !((mem.end - 1) & ~PHYS_MASK));
> > > > +
> > > > + __physical_start = mem.start; /* PHYSICAL_START */
> > > > + __physical_end = mem.end; /* PHYSICAL_END */
> > > > +
> > > > + phys_alloc_init(freemem_start, primary.end - freemem_start);
> > > > + phys_alloc_set_minimum_alignment(__icache_bytes > __dcache_bytes
> > > > + ? __icache_bytes : __dcache_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);
> > > > +
> > > > + cpu_init();
> > > > + mem_init(PAGE_ALIGN((unsigned long)&stacktop + fdt_size));
> > > > + io_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/Makefile.common b/powerpc/Makefile.common
> > > > index b21e3933d0643..539bd33d1c309 100644
> > > > --- a/powerpc/Makefile.common
> > > > +++ b/powerpc/Makefile.common
> > > > @@ -26,6 +26,7 @@ cflatobjs += lib/alloc.o
> > > > cflatobjs += lib/devicetree.o
> > > > cflatobjs += lib/powerpc/io.o
> > > > cflatobjs += lib/powerpc/hcall.o
> > > > +cflatobjs += lib/powerpc/setup.o
> > > >
> > > > libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> > > >
> > > > diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> > > > index 1884d79871ba5..526452835754f 100644
> > > > --- a/powerpc/cstart64.S
> > > > +++ b/powerpc/cstart64.S
> > > > @@ -20,11 +20,17 @@
> > > >
> > > > .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)
> > > >
> > > > + /* save DTB pointer */
> > > > + std r3, 56(r1)
> > > > +
> > > > /* patch sc1 if needed */
> > > > bl hcall_have_broken_sc1
> > > > cmpwi r3, 0
> > > > @@ -33,7 +39,15 @@ start:
> > > > LOAD_REG_IMMEDIATE(r4, SC1_REPLACEMENT)
> > > > stw r4, 0(r3)
> > > >
> > > > -1: bl main
> > > > + /* complete setup */
> > > > +1: ld r3, 56(r1)
> > > > + 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..84867e482d2a2 100644
> > > > --- a/powerpc/selftest.c
> > > > +++ b/powerpc/selftest.c
> > > > @@ -1,7 +1,64 @@
> > > > +/*
> > > > + * Test the framework itself. These tests confirm that setup works.
> > > > + *
> > > > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > > > + *
> > > > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > > > + */
> > > > #include <libcflat.h>
> > > > +#include <util.h>
> > > > +#include <asm/setup.h>
> > > >
> > > > -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)
> > > > + 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();
> > > > }
> > >
> >
>
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
next prev parent reply other threads:[~2016-02-29 0:54 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-19 15:58 [kvm-unit-tests PATCH v6 00/18] ppc64: initial drop Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 01/18] arm/arm64: trivial: another assert fix Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 02/18] Makefile: cscope: also look in arch shared asm Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 03/18] lib: asm-generic: add missing casts Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 04/18] devicetree: fix dt_get_memory_params Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 05/18] arm/arm64: setup improvements Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 06/18] lib: add vprintf Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 07/18] lib: share arm-selftest utility functions Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 08/18] config: no need to mix arch makefiles Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 09/18] powerpc/ppc64: start skeleton framework Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 10/18] powerpc/ppc64: ppc-ify makefiles and linker script Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-23 15:07 ` Laurent Vivier
2016-02-23 15:07 ` Laurent Vivier
2016-02-23 15:45 ` Andrew Jones
2016-02-23 15:45 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 11/18] powerpc/ppc64: add a boot rom Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 12/18] powerpc/ppc64: add hcall support and putchar Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 13/18] powerpc/ppc64: adapt arm's setup Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-23 15:04 ` Andrew Jones
2016-02-23 15:04 ` Andrew Jones
2016-02-24 0:31 ` David Gibson
2016-02-24 0:31 ` David Gibson
2016-02-26 13:08 ` Andrew Jones
2016-02-26 13:08 ` Andrew Jones
2016-02-29 0:54 ` David Gibson [this message]
2016-02-29 0:54 ` David Gibson
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 14/18] powerpc/ppc64: relocate linker VMAs Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 15/18] powerpc/ppc64: add run script and unittests.cfg Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 16/18] mkstandalone: add support for powerpc Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 17/18] powerpc/ppc64: add RTAS support Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-19 16:10 ` Andrew Jones
2016-02-19 16:10 ` Andrew Jones
2016-02-22 3:26 ` David Gibson
2016-02-22 3:26 ` David Gibson
2016-02-22 7:39 ` Thomas Huth
2016-02-22 7:39 ` Thomas Huth
2016-02-22 7:56 ` David Gibson
2016-02-22 7:56 ` David Gibson
2016-02-23 15:03 ` Andrew Jones
2016-02-23 15:03 ` Andrew Jones
2016-02-24 0:30 ` David Gibson
2016-02-24 0:30 ` David Gibson
2016-02-19 15:58 ` [kvm-unit-tests PATCH v6 18/18] powerpc/ppc64: make a fake debug-exit Andrew Jones
2016-02-19 15:58 ` Andrew Jones
2016-02-25 15:10 ` [kvm-unit-tests PATCH v6 00/18] ppc64: initial drop Laurent Vivier
2016-02-25 15:10 ` Laurent Vivier
2016-02-26 4:24 ` David Gibson
2016-02-26 4:24 ` David Gibson
2016-02-26 13:05 ` Andrew Jones
2016-02-26 13:05 ` Andrew Jones
2016-02-26 13:15 ` Laurent Vivier
2016-02-26 13:15 ` Laurent Vivier
2016-02-26 13:41 ` David Gibson
2016-02-26 13:41 ` David Gibson
2016-02-26 13:47 ` Laurent Vivier
2016-02-26 13:47 ` Laurent Vivier
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=20160229005427.GA5427@voom.redhat.com \
--to=david@gibson.dropbear.id.au \
--cc=agraf@suse.de \
--cc=dgibson@redhat.com \
--cc=drjones@redhat.com \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
--cc=thuth@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.