All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
@ 2016-02-15 13:49 ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

This series brings basic setup; starts a test's C entry point, main(),
and printf, exit, and malloc work. Three more series should follow this
one which must bring; vector support, mmu support, and smp support, at
which point I believe the framework could just evolve with the creation
of unit tests.

Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
to hearing more testing feedback from others though.

v4:
 - check for H_PRIVILEGE in broken sc1 probe [David]
 - rename rtas' lock from lock to rtas_lock [Thomas]
 - rtas: should only iterate to size/4 [drew]
 - add powerpc/.gitignore (ignore boot_rom.bin) [drew]

v3:
Paolo's comments:
 - got rid of zero-sized files

Thomas' review comments:
 - remove useless casts in needed cast adding patch
 - got rid of build_romfs building (and committing a binary), just
   offset the rom binary by 256 bytes now
 - added a better error message for a -smp N, N > NR_CPUS user error
 - got rid of infinite loop with broken rtas-poweroff
 - one r-b (wasn't sure the "looks good"'s counted, so didn't add more)

Laurent's testing led me to
 - fix a problem on kvm_pr with broken sc1
 - fix handling of memory regions, expect more than one
   - and a fix to DT code so that works

Additionally:
 - new patches
   - cscope: ppc64 needs to look in lib/powerpc/asm too,
             and arm64 in lib/arm/asm
   - handle memory regions better also for arm
   - a misc trivial fix for arm...
 - align toc to 256 bytes for later gcc

v2:
  Besides rebasing on latest master, v2 addresses all of David's comments
    - assembler cleanup
    - jump into the RTAS blob we get from DT, instead of reproducing it
    - don't store the RTAS root node, always hunt it down

We still haven't addressed debug-exit. Plugging chr-testdev into an spapr
vty is probably what we should investigate first (as was suggested by Alex
Graf under the v1 review). For now we keep the hack from v1, but simplified.

Patches also available here
https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4


Andrew Jones (17):
  arm/arm64: trivial: another assert fix
  Makefile: cscope: also look in arch shared asm
  lib: asm-generic: add missing casts
  devicetree: fix dt_get_memory_params
  arm/arm64: setup improvements
  lib: share arm-selftest utility functions
  config: no need to mix arch makefiles
  powerpc/ppc64: start skeleton framework
  powerpc/ppc64: ppc-ify makefiles and linker script
  powerpc/ppc64: add a boot rom
  powerpc/ppc64: add hcall support and putchar
  powerpc/ppc64: adapt arm's setup
  powerpc/ppc64: relocate linker VMAs
  powerpc/ppc64: add run script and unittests.cfg
  mkstandalone: add support for powerpc
  powerpc/ppc64: add RTAS support
  powerpc/ppc64: make a fake debug-exit

 Makefile                                           |   8 +-
 README                                             |   3 +-
 arm/Makefile                                       |   1 +
 config/config-arm.mak => arm/Makefile.arm          |   2 +-
 config/config-arm64.mak => arm/Makefile.arm64      |   2 +-
 .../config-arm-common.mak => arm/Makefile.common   |   3 +-
 arm/selftest.c                                     |  45 +++----
 configure                                          |   6 +
 lib/arm/asm/setup.h                                |   9 ++
 lib/arm/io.c                                       |   3 +-
 lib/arm/setup.c                                    |  66 +++++++---
 lib/asm-generic/io.h                               |  12 +-
 lib/devicetree.c                                   |   8 +-
 lib/libcflat.h                                     |  11 +-
 lib/powerpc/.gitignore                             |   1 +
 lib/powerpc/asm/hcall.h                            |  46 +++++++
 lib/powerpc/asm/rtas.h                             |  26 ++++
 lib/powerpc/asm/setup.h                            |  36 ++++++
 lib/powerpc/hcall.c                                |  79 ++++++++++++
 lib/powerpc/io.c                                   |  37 ++++++
 lib/powerpc/rtas.c                                 | 139 +++++++++++++++++++++
 lib/powerpc/setup.c                                | 119 ++++++++++++++++++
 lib/ppc64/.gitignore                               |   1 +
 lib/ppc64/asm-offsets.c                            |  12 ++
 lib/ppc64/asm/asm-offsets.h                        |   1 +
 lib/ppc64/asm/hcall.h                              |   1 +
 lib/ppc64/asm/io.h                                 |   5 +
 lib/ppc64/asm/page.h                               |   1 +
 lib/ppc64/asm/rtas.h                               |   1 +
 lib/ppc64/asm/setup.h                              |   1 +
 lib/ppc64/asm/spinlock.h                           |  11 ++
 lib/ppc64/spinlock.c                               |  11 ++
 lib/report.c                                       |  16 +++
 lib/util.c                                         |  18 +++
 lib/util.h                                         |  23 ++++
 powerpc/.gitignore                                 |   1 +
 powerpc/Makefile                                   |   1 +
 powerpc/Makefile.common                            |  71 +++++++++++
 powerpc/Makefile.ppc64                             |  20 +++
 powerpc/boot_rom.S                                 |   5 +
 powerpc/cstart64.S                                 |  83 ++++++++++++
 powerpc/flat.lds                                   |  44 +++++++
 powerpc/reloc64.c                                  |  55 ++++++++
 powerpc/run                                        |  55 ++++++++
 powerpc/selftest.c                                 |  64 ++++++++++
 powerpc/unittests.cfg                              |  30 +++++
 {config => scripts}/asm-offsets.mak                |   0
 scripts/mkstandalone.sh                            |   5 +
 x86/Makefile                                       |   1 +
 .../config-x86-common.mak => x86/Makefile.common   |   0
 config/config-i386.mak => x86/Makefile.i386        |   2 +-
 config/config-x86_64.mak => x86/Makefile.x86_64    |   2 +-
 52 files changed, 1128 insertions(+), 75 deletions(-)
 create mode 100644 arm/Makefile
 rename config/config-arm.mak => arm/Makefile.arm (90%)
 rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
 rename config/config-arm-common.mak => arm/Makefile.common (96%)
 create mode 100644 lib/powerpc/.gitignore
 create mode 100644 lib/powerpc/asm/hcall.h
 create mode 100644 lib/powerpc/asm/rtas.h
 create mode 100644 lib/powerpc/asm/setup.h
 create mode 100644 lib/powerpc/hcall.c
 create mode 100644 lib/powerpc/io.c
 create mode 100644 lib/powerpc/rtas.c
 create mode 100644 lib/powerpc/setup.c
 create mode 100644 lib/ppc64/.gitignore
 create mode 100644 lib/ppc64/asm-offsets.c
 create mode 100644 lib/ppc64/asm/asm-offsets.h
 create mode 100644 lib/ppc64/asm/hcall.h
 create mode 100644 lib/ppc64/asm/io.h
 create mode 100644 lib/ppc64/asm/page.h
 create mode 100644 lib/ppc64/asm/rtas.h
 create mode 100644 lib/ppc64/asm/setup.h
 create mode 100644 lib/ppc64/asm/spinlock.h
 create mode 100644 lib/ppc64/spinlock.c
 create mode 100644 lib/util.c
 create mode 100644 lib/util.h
 create mode 100644 powerpc/.gitignore
 create mode 100644 powerpc/Makefile
 create mode 100644 powerpc/Makefile.common
 create mode 100644 powerpc/Makefile.ppc64
 create mode 100644 powerpc/boot_rom.S
 create mode 100644 powerpc/cstart64.S
 create mode 100644 powerpc/flat.lds
 create mode 100644 powerpc/reloc64.c
 create mode 100755 powerpc/run
 create mode 100644 powerpc/selftest.c
 create mode 100644 powerpc/unittests.cfg
 rename {config => scripts}/asm-offsets.mak (100%)
 create mode 100644 x86/Makefile
 rename config/config-x86-common.mak => x86/Makefile.common (100%)
 rename config/config-i386.mak => x86/Makefile.i386 (91%)
 rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)

-- 
2.4.3


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
@ 2016-02-15 13:49 ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

This series brings basic setup; starts a test's C entry point, main(),
and printf, exit, and malloc work. Three more series should follow this
one which must bring; vector support, mmu support, and smp support, at
which point I believe the framework could just evolve with the creation
of unit tests.

Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
to hearing more testing feedback from others though.

v4:
 - check for H_PRIVILEGE in broken sc1 probe [David]
 - rename rtas' lock from lock to rtas_lock [Thomas]
 - rtas: should only iterate to size/4 [drew]
 - add powerpc/.gitignore (ignore boot_rom.bin) [drew]

v3:
Paolo's comments:
 - got rid of zero-sized files

Thomas' review comments:
 - remove useless casts in needed cast adding patch
 - got rid of build_romfs building (and committing a binary), just
   offset the rom binary by 256 bytes now
 - added a better error message for a -smp N, N > NR_CPUS user error
 - got rid of infinite loop with broken rtas-poweroff
 - one r-b (wasn't sure the "looks good"'s counted, so didn't add more)

Laurent's testing led me to
 - fix a problem on kvm_pr with broken sc1
 - fix handling of memory regions, expect more than one
   - and a fix to DT code so that works

Additionally:
 - new patches
   - cscope: ppc64 needs to look in lib/powerpc/asm too,
             and arm64 in lib/arm/asm
   - handle memory regions better also for arm
   - a misc trivial fix for arm...
 - align toc to 256 bytes for later gcc

v2:
  Besides rebasing on latest master, v2 addresses all of David's comments
    - assembler cleanup
    - jump into the RTAS blob we get from DT, instead of reproducing it
    - don't store the RTAS root node, always hunt it down

We still haven't addressed debug-exit. Plugging chr-testdev into an spapr
vty is probably what we should investigate first (as was suggested by Alex
Graf under the v1 review). For now we keep the hack from v1, but simplified.

Patches also available here
https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4


Andrew Jones (17):
  arm/arm64: trivial: another assert fix
  Makefile: cscope: also look in arch shared asm
  lib: asm-generic: add missing casts
  devicetree: fix dt_get_memory_params
  arm/arm64: setup improvements
  lib: share arm-selftest utility functions
  config: no need to mix arch makefiles
  powerpc/ppc64: start skeleton framework
  powerpc/ppc64: ppc-ify makefiles and linker script
  powerpc/ppc64: add a boot rom
  powerpc/ppc64: add hcall support and putchar
  powerpc/ppc64: adapt arm's setup
  powerpc/ppc64: relocate linker VMAs
  powerpc/ppc64: add run script and unittests.cfg
  mkstandalone: add support for powerpc
  powerpc/ppc64: add RTAS support
  powerpc/ppc64: make a fake debug-exit

 Makefile                                           |   8 +-
 README                                             |   3 +-
 arm/Makefile                                       |   1 +
 config/config-arm.mak => arm/Makefile.arm          |   2 +-
 config/config-arm64.mak => arm/Makefile.arm64      |   2 +-
 .../config-arm-common.mak => arm/Makefile.common   |   3 +-
 arm/selftest.c                                     |  45 +++----
 configure                                          |   6 +
 lib/arm/asm/setup.h                                |   9 ++
 lib/arm/io.c                                       |   3 +-
 lib/arm/setup.c                                    |  66 +++++++---
 lib/asm-generic/io.h                               |  12 +-
 lib/devicetree.c                                   |   8 +-
 lib/libcflat.h                                     |  11 +-
 lib/powerpc/.gitignore                             |   1 +
 lib/powerpc/asm/hcall.h                            |  46 +++++++
 lib/powerpc/asm/rtas.h                             |  26 ++++
 lib/powerpc/asm/setup.h                            |  36 ++++++
 lib/powerpc/hcall.c                                |  79 ++++++++++++
 lib/powerpc/io.c                                   |  37 ++++++
 lib/powerpc/rtas.c                                 | 139 +++++++++++++++++++++
 lib/powerpc/setup.c                                | 119 ++++++++++++++++++
 lib/ppc64/.gitignore                               |   1 +
 lib/ppc64/asm-offsets.c                            |  12 ++
 lib/ppc64/asm/asm-offsets.h                        |   1 +
 lib/ppc64/asm/hcall.h                              |   1 +
 lib/ppc64/asm/io.h                                 |   5 +
 lib/ppc64/asm/page.h                               |   1 +
 lib/ppc64/asm/rtas.h                               |   1 +
 lib/ppc64/asm/setup.h                              |   1 +
 lib/ppc64/asm/spinlock.h                           |  11 ++
 lib/ppc64/spinlock.c                               |  11 ++
 lib/report.c                                       |  16 +++
 lib/util.c                                         |  18 +++
 lib/util.h                                         |  23 ++++
 powerpc/.gitignore                                 |   1 +
 powerpc/Makefile                                   |   1 +
 powerpc/Makefile.common                            |  71 +++++++++++
 powerpc/Makefile.ppc64                             |  20 +++
 powerpc/boot_rom.S                                 |   5 +
 powerpc/cstart64.S                                 |  83 ++++++++++++
 powerpc/flat.lds                                   |  44 +++++++
 powerpc/reloc64.c                                  |  55 ++++++++
 powerpc/run                                        |  55 ++++++++
 powerpc/selftest.c                                 |  64 ++++++++++
 powerpc/unittests.cfg                              |  30 +++++
 {config => scripts}/asm-offsets.mak                |   0
 scripts/mkstandalone.sh                            |   5 +
 x86/Makefile                                       |   1 +
 .../config-x86-common.mak => x86/Makefile.common   |   0
 config/config-i386.mak => x86/Makefile.i386        |   2 +-
 config/config-x86_64.mak => x86/Makefile.x86_64    |   2 +-
 52 files changed, 1128 insertions(+), 75 deletions(-)
 create mode 100644 arm/Makefile
 rename config/config-arm.mak => arm/Makefile.arm (90%)
 rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
 rename config/config-arm-common.mak => arm/Makefile.common (96%)
 create mode 100644 lib/powerpc/.gitignore
 create mode 100644 lib/powerpc/asm/hcall.h
 create mode 100644 lib/powerpc/asm/rtas.h
 create mode 100644 lib/powerpc/asm/setup.h
 create mode 100644 lib/powerpc/hcall.c
 create mode 100644 lib/powerpc/io.c
 create mode 100644 lib/powerpc/rtas.c
 create mode 100644 lib/powerpc/setup.c
 create mode 100644 lib/ppc64/.gitignore
 create mode 100644 lib/ppc64/asm-offsets.c
 create mode 100644 lib/ppc64/asm/asm-offsets.h
 create mode 100644 lib/ppc64/asm/hcall.h
 create mode 100644 lib/ppc64/asm/io.h
 create mode 100644 lib/ppc64/asm/page.h
 create mode 100644 lib/ppc64/asm/rtas.h
 create mode 100644 lib/ppc64/asm/setup.h
 create mode 100644 lib/ppc64/asm/spinlock.h
 create mode 100644 lib/ppc64/spinlock.c
 create mode 100644 lib/util.c
 create mode 100644 lib/util.h
 create mode 100644 powerpc/.gitignore
 create mode 100644 powerpc/Makefile
 create mode 100644 powerpc/Makefile.common
 create mode 100644 powerpc/Makefile.ppc64
 create mode 100644 powerpc/boot_rom.S
 create mode 100644 powerpc/cstart64.S
 create mode 100644 powerpc/flat.lds
 create mode 100644 powerpc/reloc64.c
 create mode 100755 powerpc/run
 create mode 100644 powerpc/selftest.c
 create mode 100644 powerpc/unittests.cfg
 rename {config => scripts}/asm-offsets.mak (100%)
 create mode 100644 x86/Makefile
 rename config/config-x86-common.mak => x86/Makefile.common (100%)
 rename config/config-i386.mak => x86/Makefile.i386 (91%)
 rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)

-- 
2.4.3


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 01/17] arm/arm64: trivial: another assert fix
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Thomas Huth <thuth@redhat.com>

---
Unrelated to the powerpc initial drop, but found it while working
on that, so just posting it now. Anyway, it's a trivial fix.
---
 lib/arm/io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/arm/io.c b/lib/arm/io.c
index a08d394e4aa1c..a111530f4802d 100644
--- a/lib/arm/io.c
+++ b/lib/arm/io.c
@@ -50,7 +50,8 @@ static void uart0_init(void)
 		}
 
 	} else {
-		assert(dt_pbus_translate_node(ret, 0, &base) == 0);
+		ret = dt_pbus_translate_node(ret, 0, &base);
+		assert(ret == 0);
 	}
 
 	uart0_base = ioremap(base.addr, base.size);
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 01/17] arm/arm64: trivial: another assert fix
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Thomas Huth <thuth@redhat.com>

---
Unrelated to the powerpc initial drop, but found it while working
on that, so just posting it now. Anyway, it's a trivial fix.
---
 lib/arm/io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/arm/io.c b/lib/arm/io.c
index a08d394e4aa1c..a111530f4802d 100644
--- a/lib/arm/io.c
+++ b/lib/arm/io.c
@@ -50,7 +50,8 @@ static void uart0_init(void)
 		}
 
 	} else {
-		assert(dt_pbus_translate_node(ret, 0, &base) = 0);
+		ret = dt_pbus_translate_node(ret, 0, &base);
+		assert(ret = 0);
 	}
 
 	uart0_base = ioremap(base.addr, base.size);
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 02/17] Makefile: cscope: also look in arch shared asm
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>

---
Not exactly related to the powerpc initial drop, but ppc64 will
need it too.
---
 Makefile | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 0be2b6670daf6..fe5cc620d473b 100644
--- a/Makefile
+++ b/Makefile
@@ -85,9 +85,11 @@ distclean: clean libfdt_clean
 	$(RM) lib/asm config.mak $(TEST_DIR)-run test.log msr.out cscope.*
 	$(RM) -r tests
 
-cscope: common_dirs = lib lib/libfdt lib/linux lib/asm lib/asm-generic
+cscope: cscope_dirs = lib lib/libfdt lib/linux
+cscope: cscope_dirs += lib/$(ARCH)/asm lib/$(TEST_DIR)/asm lib/asm-generic
+cscope: cscope_dirs += $(TEST_DIR) lib/$(TEST_DIR) lib/$(ARCH)
 cscope:
 	$(RM) ./cscope.*
-	find -L $(TEST_DIR) lib/$(TEST_DIR) lib/$(ARCH) $(common_dirs) -maxdepth 1 \
+	find -L $(cscope_dirs) -maxdepth 1 \
 		-name '*.[chsS]' -print | sed 's,^\./,,' | sort -u > ./cscope.files
 	cscope -bk
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 02/17] Makefile: cscope: also look in arch shared asm
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>

---
Not exactly related to the powerpc initial drop, but ppc64 will
need it too.
---
 Makefile | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 0be2b6670daf6..fe5cc620d473b 100644
--- a/Makefile
+++ b/Makefile
@@ -85,9 +85,11 @@ distclean: clean libfdt_clean
 	$(RM) lib/asm config.mak $(TEST_DIR)-run test.log msr.out cscope.*
 	$(RM) -r tests
 
-cscope: common_dirs = lib lib/libfdt lib/linux lib/asm lib/asm-generic
+cscope: cscope_dirs = lib lib/libfdt lib/linux
+cscope: cscope_dirs += lib/$(ARCH)/asm lib/$(TEST_DIR)/asm lib/asm-generic
+cscope: cscope_dirs += $(TEST_DIR) lib/$(TEST_DIR) lib/$(ARCH)
 cscope:
 	$(RM) ./cscope.*
-	find -L $(TEST_DIR) lib/$(TEST_DIR) lib/$(ARCH) $(common_dirs) -maxdepth 1 \
+	find -L $(cscope_dirs) -maxdepth 1 \
 		-name '*.[chsS]' -print | sed 's,^\./,,' | sort -u > ./cscope.files
 	cscope -bk
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 03/17] lib: asm-generic: add missing casts
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/asm-generic/io.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/asm-generic/io.h b/lib/asm-generic/io.h
index a9939d3a5921f..931415a465b74 100644
--- a/lib/asm-generic/io.h
+++ b/lib/asm-generic/io.h
@@ -104,27 +104,27 @@ static inline u64 __bswap64(u64 x)
 #endif
 
 #define le16_to_cpu(x) \
-	({ u16 __r = __cpu_is_be() ? __bswap16(x) : (x); __r; })
+	({ u16 __r = __cpu_is_be() ? __bswap16(x) : ((u16)x); __r; })
 #define cpu_to_le16 le16_to_cpu
 
 #define le32_to_cpu(x) \
-	({ u32 __r = __cpu_is_be() ? __bswap32(x) : (x); __r; })
+	({ u32 __r = __cpu_is_be() ? __bswap32(x) : ((u32)x); __r; })
 #define cpu_to_le32 le32_to_cpu
 
 #define le64_to_cpu(x) \
-	({ u64 __r = __cpu_is_be() ? __bswap64(x) : (x); __r; })
+	({ u64 __r = __cpu_is_be() ? __bswap64(x) : ((u64)x); __r; })
 #define cpu_to_le64 le64_to_cpu
 
 #define be16_to_cpu(x) \
-	({ u16 __r = !__cpu_is_be() ? __bswap16(x) : (x); __r; })
+	({ u16 __r = !__cpu_is_be() ? __bswap16(x) : ((u16)x); __r; })
 #define cpu_to_be16 be16_to_cpu
 
 #define be32_to_cpu(x) \
-	({ u32 __r = !__cpu_is_be() ? __bswap32(x) : (x); __r; })
+	({ u32 __r = !__cpu_is_be() ? __bswap32(x) : ((u32)x); __r; })
 #define cpu_to_be32 be32_to_cpu
 
 #define be64_to_cpu(x) \
-	({ u64 __r = !__cpu_is_be() ? __bswap64(x) : (x); __r; })
+	({ u64 __r = !__cpu_is_be() ? __bswap64(x) : ((u64)x); __r; })
 #define cpu_to_be64 be64_to_cpu
 
 #ifndef rmb
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 03/17] lib: asm-generic: add missing casts
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/asm-generic/io.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/asm-generic/io.h b/lib/asm-generic/io.h
index a9939d3a5921f..931415a465b74 100644
--- a/lib/asm-generic/io.h
+++ b/lib/asm-generic/io.h
@@ -104,27 +104,27 @@ static inline u64 __bswap64(u64 x)
 #endif
 
 #define le16_to_cpu(x) \
-	({ u16 __r = __cpu_is_be() ? __bswap16(x) : (x); __r; })
+	({ u16 __r = __cpu_is_be() ? __bswap16(x) : ((u16)x); __r; })
 #define cpu_to_le16 le16_to_cpu
 
 #define le32_to_cpu(x) \
-	({ u32 __r = __cpu_is_be() ? __bswap32(x) : (x); __r; })
+	({ u32 __r = __cpu_is_be() ? __bswap32(x) : ((u32)x); __r; })
 #define cpu_to_le32 le32_to_cpu
 
 #define le64_to_cpu(x) \
-	({ u64 __r = __cpu_is_be() ? __bswap64(x) : (x); __r; })
+	({ u64 __r = __cpu_is_be() ? __bswap64(x) : ((u64)x); __r; })
 #define cpu_to_le64 le64_to_cpu
 
 #define be16_to_cpu(x) \
-	({ u16 __r = !__cpu_is_be() ? __bswap16(x) : (x); __r; })
+	({ u16 __r = !__cpu_is_be() ? __bswap16(x) : ((u16)x); __r; })
 #define cpu_to_be16 be16_to_cpu
 
 #define be32_to_cpu(x) \
-	({ u32 __r = !__cpu_is_be() ? __bswap32(x) : (x); __r; })
+	({ u32 __r = !__cpu_is_be() ? __bswap32(x) : ((u32)x); __r; })
 #define cpu_to_be32 be32_to_cpu
 
 #define be64_to_cpu(x) \
-	({ u64 __r = !__cpu_is_be() ? __bswap64(x) : (x); __r; })
+	({ u64 __r = !__cpu_is_be() ? __bswap64(x) : ((u64)x); __r; })
 #define cpu_to_be64 be64_to_cpu
 
 #ifndef rmb
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 04/17] devicetree: fix dt_get_memory_params
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Index nr was overreaching with its indexing. It should only
index the caller's regs array. We need a different index for
the memory nodes' reg properties.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>

---
The next patch needs this fix.
---
 lib/devicetree.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/devicetree.c b/lib/devicetree.c
index 36cb28610ff41..a5c7f7c69ddfd 100644
--- a/lib/devicetree.c
+++ b/lib/devicetree.c
@@ -165,22 +165,24 @@ int dt_pbus_get_base_compatible(const char *compatible,
 int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs)
 {
 	const char *pn = "device_type", *pv = "memory";
-	int node, ret, pl = strlen(pv) + 1, nr = 0;
+	int node, ret, reg_idx, pl = strlen(pv) + 1, nr = 0;
 	struct dt_pbus_reg reg;
 
 	node = fdt_node_offset_by_prop_value(fdt, -1, pn, pv, pl);
 
 	while (node >= 0) {
 
+		reg_idx = 0;
+
 		while (nr < nr_regs) {
-			ret = dt_pbus_translate_node(node, nr, &reg);
+			ret = dt_pbus_translate_node(node, reg_idx, &reg);
 			if (ret == -FDT_ERR_NOTFOUND)
 				break;
 			if (ret < 0)
 				return ret;
 			regs[nr].addr = reg.addr;
 			regs[nr].size = reg.size;
-			++nr;
+			++nr, ++reg_idx;
 		}
 
 		node = fdt_node_offset_by_prop_value(fdt, node, pn, pv, pl);
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 04/17] devicetree: fix dt_get_memory_params
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Index nr was overreaching with its indexing. It should only
index the caller's regs array. We need a different index for
the memory nodes' reg properties.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>

---
The next patch needs this fix.
---
 lib/devicetree.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/devicetree.c b/lib/devicetree.c
index 36cb28610ff41..a5c7f7c69ddfd 100644
--- a/lib/devicetree.c
+++ b/lib/devicetree.c
@@ -165,22 +165,24 @@ int dt_pbus_get_base_compatible(const char *compatible,
 int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs)
 {
 	const char *pn = "device_type", *pv = "memory";
-	int node, ret, pl = strlen(pv) + 1, nr = 0;
+	int node, ret, reg_idx, pl = strlen(pv) + 1, nr = 0;
 	struct dt_pbus_reg reg;
 
 	node = fdt_node_offset_by_prop_value(fdt, -1, pn, pv, pl);
 
 	while (node >= 0) {
 
+		reg_idx = 0;
+
 		while (nr < nr_regs) {
-			ret = dt_pbus_translate_node(node, nr, &reg);
+			ret = dt_pbus_translate_node(node, reg_idx, &reg);
 			if (ret = -FDT_ERR_NOTFOUND)
 				break;
 			if (ret < 0)
 				return ret;
 			regs[nr].addr = reg.addr;
 			regs[nr].size = reg.size;
-			++nr;
+			++nr, ++reg_idx;
 		}
 
 		node = fdt_node_offset_by_prop_value(fdt, node, pn, pv, pl);
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 05/17] arm/arm64: setup improvements
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Handle multiple memory regions being described in the DT. Also
add a more informative error message for when a user does -smp N,
N > NR_CPUS.

Signed-off-by: Andrew Jones <drjones@redhat.com>

---
powerpc will adapt arm's setup to be used as it's own, and it
needs these changes. There's no reason to only do them for power,
so we do them in arm first, getting them ready to be adapted.
---
 lib/arm/asm/setup.h |  9 ++++++++
 lib/arm/setup.c     | 66 ++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index 02b668672fca4..cb8fdbd38dd5d 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -6,6 +6,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <alloc.h>	/* phys_addr_t */
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 
@@ -13,6 +14,14 @@
 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 __phys_offset, __phys_end;
 
 #define PHYS_OFFSET		(__phys_offset)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index da6edc1f9d8ff..8c6172ff94106 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -27,12 +27,18 @@ 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 __phys_offset, __phys_end;
 
 static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
 {
 	int cpu = nr_cpus++;
-	assert(cpu < NR_CPUS);
+
+	if (cpu >= NR_CPUS) {
+		printf("Number cpus exceeds maximum supported (%d).\n",
+			NR_CPUS);
+		assert(0);
+	}
 	cpus[cpu] = regval;
 	set_cpu_present(cpu, true);
 }
@@ -49,24 +55,46 @@ static void cpu_init(void)
 
 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);
-
-	__phys_offset = mem_start;	/* PHYS_OFFSET */
-	__phys_end = mem_end;		/* PHYS_END */
-
-	phys_alloc_init(freemem_start, mem_end - 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));
+
+	__phys_offset = mem.start;	/* PHYS_OFFSET */
+	__phys_end = mem.end;		/* PHYS_END */
+
+	phys_alloc_init(freemem_start, primary.end - freemem_start);
 	phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
 
 	mmu_enable_idmap();
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 05/17] arm/arm64: setup improvements
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Handle multiple memory regions being described in the DT. Also
add a more informative error message for when a user does -smp N,
N > NR_CPUS.

Signed-off-by: Andrew Jones <drjones@redhat.com>

---
powerpc will adapt arm's setup to be used as it's own, and it
needs these changes. There's no reason to only do them for power,
so we do them in arm first, getting them ready to be adapted.
---
 lib/arm/asm/setup.h |  9 ++++++++
 lib/arm/setup.c     | 66 ++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index 02b668672fca4..cb8fdbd38dd5d 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -6,6 +6,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <alloc.h>	/* phys_addr_t */
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 
@@ -13,6 +14,14 @@
 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 __phys_offset, __phys_end;
 
 #define PHYS_OFFSET		(__phys_offset)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index da6edc1f9d8ff..8c6172ff94106 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -27,12 +27,18 @@ 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 __phys_offset, __phys_end;
 
 static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
 {
 	int cpu = nr_cpus++;
-	assert(cpu < NR_CPUS);
+
+	if (cpu >= NR_CPUS) {
+		printf("Number cpus exceeds maximum supported (%d).\n",
+			NR_CPUS);
+		assert(0);
+	}
 	cpus[cpu] = regval;
 	set_cpu_present(cpu, true);
 }
@@ -49,24 +55,46 @@ static void cpu_init(void)
 
 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);
-
-	__phys_offset = mem_start;	/* PHYS_OFFSET */
-	__phys_end = mem_end;		/* PHYS_END */
-
-	phys_alloc_init(freemem_start, mem_end - 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));
+
+	__phys_offset = mem.start;	/* PHYS_OFFSET */
+	__phys_end = mem.end;		/* PHYS_END */
+
+	phys_alloc_init(freemem_start, primary.end - freemem_start);
 	phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
 
 	mmu_enable_idmap();
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

arm-selftest has a couple utility functions that could be useful
to other unit tests, even other architectures. So move them out.
split_var moves to lib/util, where we can add other random
utilities over time. assert_args inspires report_abort, which
allows us to report a message, using the current prefix, that
we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
for cases when unit tests can't complete due to missing
dependencies of some sort, such as missing/invalid inputs from
the user.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 arm/selftest.c               | 45 ++++++++++++++------------------------------
 config/config-arm-common.mak |  1 +
 lib/libcflat.h               | 11 ++++++-----
 lib/report.c                 | 16 ++++++++++++++++
 lib/util.c                   | 18 ++++++++++++++++++
 lib/util.h                   | 23 ++++++++++++++++++++++
 6 files changed, 78 insertions(+), 36 deletions(-)
 create mode 100644 lib/util.c
 create mode 100644 lib/util.h

diff --git a/arm/selftest.c b/arm/selftest.c
index aad7eecd529ad..75dc91faab69a 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -6,6 +6,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <util.h>
 #include <alloc.h>
 #include <devicetree.h>
 #include <asm/setup.h>
@@ -18,43 +19,21 @@
 #include <asm/cpumask.h>
 #include <asm/barrier.h>
 
-static void assert_args(int num_args, int needed_args)
-{
-	if (num_args < needed_args) {
-		printf("selftest: not enough arguments\n");
-		abort();
-	}
-}
-
-static char *split_var(char *s, long *val)
-{
-	char *p;
-
-	p = strchr(s, '=');
-	if (!p)
-		return NULL;
-
-	*val = atol(p+1);
-	*p = '\0';
-
-	return s;
-}
-
 static void check_setup(int argc, char **argv)
 {
-	int nr_tests = 0, i;
-	char *var;
+	int nr_tests = 0, len, i;
 	long val;
 
 	for (i = 0; i < argc; ++i) {
 
-		var = split_var(argv[i], &val);
-		if (!var)
+		len = parse_keyval(argv[i], &val);
+		if (len == -1)
 			continue;
 
-		report_prefix_push(var);
+		argv[i][len] = '\0';
+		report_prefix_push(argv[i]);
 
-		if (strcmp(var, "mem") == 0) {
+		if (strcmp(argv[i], "mem") == 0) {
 
 			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
 			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
@@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
 							memsize/1024/1024);
 			++nr_tests;
 
-		} else if (strcmp(var, "smp") == 0) {
+		} else if (strcmp(argv[i], "smp") == 0) {
 
 			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
 			++nr_tests;
@@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
 		report_prefix_pop();
 	}
 
-	assert_args(nr_tests, 2);
+	if (nr_tests < 2)
+		report_abort("missing input");
 }
 
 static struct pt_regs expected_regs;
@@ -343,7 +323,10 @@ static void cpu_report(void)
 int main(int argc, char **argv)
 {
 	report_prefix_push("selftest");
-	assert_args(argc, 1);
+
+	if (!argc)
+		report_abort("no test specified");
+
 	report_prefix_push(argv[0]);
 
 	if (strcmp(argv[0], "setup") == 0) {
diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
index 698555d6a676f..bd153cf6ea5ba 100644
--- a/config/config-arm-common.mak
+++ b/config/config-arm-common.mak
@@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include config/asm-offsets.mak
 
+cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
 cflatobjs += lib/virtio.o
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 9747ccdbc9f1d..8411f6c5d92e3 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
 extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
 extern long atol(const char *ptr);
 
-void report_prefix_push(const char *prefix);
-void report_prefix_pop(void);
-void report(const char *msg_fmt, bool pass, ...);
-void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
-int report_summary(void);
+extern void report_prefix_push(const char *prefix);
+extern void report_prefix_pop(void);
+extern void report(const char *msg_fmt, bool pass, ...);
+extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
+extern void report_abort(const char *msg_fmt, ...);
+extern int report_summary(void);
 
 #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
 
diff --git a/lib/report.c b/lib/report.c
index 35e664108a921..62916c4ac3c8a 100644
--- a/lib/report.c
+++ b/lib/report.c
@@ -96,3 +96,19 @@ int report_summary(void)
 
 	spin_unlock(&lock);
 }
+
+void report_abort(const char *msg_fmt, ...)
+{
+	va_list va;
+	char buf[2000];
+
+	puts("ABORT: ");
+	puts(prefixes);
+	va_start(va, msg_fmt);
+	vsnprintf(buf, sizeof(buf), msg_fmt, va);
+	va_end(va);
+	puts(buf);
+	puts("\n");
+	report_summary();
+	abort();
+}
diff --git a/lib/util.c b/lib/util.c
new file mode 100644
index 0000000000000..69b18100c9722
--- /dev/null
+++ b/lib/util.c
@@ -0,0 +1,18 @@
+/*
+ * 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>
+
+int parse_keyval(char *s, long *val)
+{
+	char *p;
+
+	p = strchr(s, '=');
+	if (!p)
+		return -1;
+
+	*val = atol(p+1);
+	return p - s;
+}
diff --git a/lib/util.h b/lib/util.h
new file mode 100644
index 0000000000000..4c4b441322770
--- /dev/null
+++ b/lib/util.h
@@ -0,0 +1,23 @@
+#ifndef _UTIL_H_
+#define _UTIL_H_
+/*
+ * Collection of utility functions to share between unit tests.
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+/*
+ * parse_keyval extracts the integer from a string formatted as
+ * string=integer. This is useful for passing expected values to
+ * the unit test on the command line, i.e. it helps parse QEMU
+ * command lines that include something like -append var1=1 var2=2
+ * @s is the input string, likely a command line parameter, and
+ * @val is a pointer to where the integer will be stored.
+ *
+ * Returns the offset of the '=', or -1 if no keyval pair is found.
+ */
+extern int parse_keyval(char *s, long *val);
+
+#endif
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

arm-selftest has a couple utility functions that could be useful
to other unit tests, even other architectures. So move them out.
split_var moves to lib/util, where we can add other random
utilities over time. assert_args inspires report_abort, which
allows us to report a message, using the current prefix, that
we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
for cases when unit tests can't complete due to missing
dependencies of some sort, such as missing/invalid inputs from
the user.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 arm/selftest.c               | 45 ++++++++++++++------------------------------
 config/config-arm-common.mak |  1 +
 lib/libcflat.h               | 11 ++++++-----
 lib/report.c                 | 16 ++++++++++++++++
 lib/util.c                   | 18 ++++++++++++++++++
 lib/util.h                   | 23 ++++++++++++++++++++++
 6 files changed, 78 insertions(+), 36 deletions(-)
 create mode 100644 lib/util.c
 create mode 100644 lib/util.h

diff --git a/arm/selftest.c b/arm/selftest.c
index aad7eecd529ad..75dc91faab69a 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -6,6 +6,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <util.h>
 #include <alloc.h>
 #include <devicetree.h>
 #include <asm/setup.h>
@@ -18,43 +19,21 @@
 #include <asm/cpumask.h>
 #include <asm/barrier.h>
 
-static void assert_args(int num_args, int needed_args)
-{
-	if (num_args < needed_args) {
-		printf("selftest: not enough arguments\n");
-		abort();
-	}
-}
-
-static char *split_var(char *s, long *val)
-{
-	char *p;
-
-	p = strchr(s, '=');
-	if (!p)
-		return NULL;
-
-	*val = atol(p+1);
-	*p = '\0';
-
-	return s;
-}
-
 static void check_setup(int argc, char **argv)
 {
-	int nr_tests = 0, i;
-	char *var;
+	int nr_tests = 0, len, i;
 	long val;
 
 	for (i = 0; i < argc; ++i) {
 
-		var = split_var(argv[i], &val);
-		if (!var)
+		len = parse_keyval(argv[i], &val);
+		if (len = -1)
 			continue;
 
-		report_prefix_push(var);
+		argv[i][len] = '\0';
+		report_prefix_push(argv[i]);
 
-		if (strcmp(var, "mem") = 0) {
+		if (strcmp(argv[i], "mem") = 0) {
 
 			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
 			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
@@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
 							memsize/1024/1024);
 			++nr_tests;
 
-		} else if (strcmp(var, "smp") = 0) {
+		} else if (strcmp(argv[i], "smp") = 0) {
 
 			report("nr_cpus = %d", nr_cpus = (int)val, nr_cpus);
 			++nr_tests;
@@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
 		report_prefix_pop();
 	}
 
-	assert_args(nr_tests, 2);
+	if (nr_tests < 2)
+		report_abort("missing input");
 }
 
 static struct pt_regs expected_regs;
@@ -343,7 +323,10 @@ static void cpu_report(void)
 int main(int argc, char **argv)
 {
 	report_prefix_push("selftest");
-	assert_args(argc, 1);
+
+	if (!argc)
+		report_abort("no test specified");
+
 	report_prefix_push(argv[0]);
 
 	if (strcmp(argv[0], "setup") = 0) {
diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
index 698555d6a676f..bd153cf6ea5ba 100644
--- a/config/config-arm-common.mak
+++ b/config/config-arm-common.mak
@@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include config/asm-offsets.mak
 
+cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
 cflatobjs += lib/virtio.o
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 9747ccdbc9f1d..8411f6c5d92e3 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
 extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
 extern long atol(const char *ptr);
 
-void report_prefix_push(const char *prefix);
-void report_prefix_pop(void);
-void report(const char *msg_fmt, bool pass, ...);
-void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
-int report_summary(void);
+extern void report_prefix_push(const char *prefix);
+extern void report_prefix_pop(void);
+extern void report(const char *msg_fmt, bool pass, ...);
+extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
+extern void report_abort(const char *msg_fmt, ...);
+extern int report_summary(void);
 
 #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
 
diff --git a/lib/report.c b/lib/report.c
index 35e664108a921..62916c4ac3c8a 100644
--- a/lib/report.c
+++ b/lib/report.c
@@ -96,3 +96,19 @@ int report_summary(void)
 
 	spin_unlock(&lock);
 }
+
+void report_abort(const char *msg_fmt, ...)
+{
+	va_list va;
+	char buf[2000];
+
+	puts("ABORT: ");
+	puts(prefixes);
+	va_start(va, msg_fmt);
+	vsnprintf(buf, sizeof(buf), msg_fmt, va);
+	va_end(va);
+	puts(buf);
+	puts("\n");
+	report_summary();
+	abort();
+}
diff --git a/lib/util.c b/lib/util.c
new file mode 100644
index 0000000000000..69b18100c9722
--- /dev/null
+++ b/lib/util.c
@@ -0,0 +1,18 @@
+/*
+ * 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>
+
+int parse_keyval(char *s, long *val)
+{
+	char *p;
+
+	p = strchr(s, '=');
+	if (!p)
+		return -1;
+
+	*val = atol(p+1);
+	return p - s;
+}
diff --git a/lib/util.h b/lib/util.h
new file mode 100644
index 0000000000000..4c4b441322770
--- /dev/null
+++ b/lib/util.h
@@ -0,0 +1,23 @@
+#ifndef _UTIL_H_
+#define _UTIL_H_
+/*
+ * Collection of utility functions to share between unit tests.
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+/*
+ * parse_keyval extracts the integer from a string formatted as
+ * string=integer. This is useful for passing expected values to
+ * the unit test on the command line, i.e. it helps parse QEMU
+ * command lines that include something like -append var1=1 var2=2
+ * @s is the input string, likely a command line parameter, and
+ * @val is a pointer to where the integer will be stored.
+ *
+ * Returns the offset of the '=', or -1 if no keyval pair is found.
+ */
+extern int parse_keyval(char *s, long *val);
+
+#endif
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 07/17] config: no need to mix arch makefiles
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Move the config/config-*.mak files to their own directories and
rename to Makefile.* README is also updated to reflect the change,
as well as to remove an optimistic reference to a non-existent
docs directory.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 Makefile                                            | 2 +-
 README                                              | 3 +--
 arm/Makefile                                        | 1 +
 config/config-arm.mak => arm/Makefile.arm           | 2 +-
 config/config-arm64.mak => arm/Makefile.arm64       | 2 +-
 config/config-arm-common.mak => arm/Makefile.common | 2 +-
 {config => scripts}/asm-offsets.mak                 | 0
 x86/Makefile                                        | 1 +
 config/config-x86-common.mak => x86/Makefile.common | 0
 config/config-i386.mak => x86/Makefile.i386         | 2 +-
 config/config-x86_64.mak => x86/Makefile.x86_64     | 2 +-
 11 files changed, 9 insertions(+), 8 deletions(-)
 create mode 100644 arm/Makefile
 rename config/config-arm.mak => arm/Makefile.arm (90%)
 rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
 rename config/config-arm-common.mak => arm/Makefile.common (98%)
 rename {config => scripts}/asm-offsets.mak (100%)
 create mode 100644 x86/Makefile
 rename config/config-x86-common.mak => x86/Makefile.common (100%)
 rename config/config-i386.mak => x86/Makefile.i386 (91%)
 rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)

diff --git a/Makefile b/Makefile
index fe5cc620d473b..ddba941858596 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@ LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
 LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
 
 #include architecure specific make rules
-include config/config-$(ARCH).mak
+include $(TEST_DIR)/Makefile
 
 # cc-option
 # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
diff --git a/README b/README
index 457bd797362cf..f8f196d90bf10 100644
--- a/README
+++ b/README
@@ -34,8 +34,7 @@ each as a standalone test.
 
 Directory structure:
 .:		configure script, top-level Makefile, and run_tests.sh
-./config:	collection of architecture dependent makefiles
-./docs:		documentation files
+./scripts:	helper scripts for building and running tests
 ./lib:		general architecture neutral services for the tests
 ./lib/<ARCH>:	architecture dependent services for the tests
 ./<ARCH>:	the sources of the tests and the created objects/images
diff --git a/arm/Makefile b/arm/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/arm/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/config/config-arm.mak b/arm/Makefile.arm
similarity index 90%
rename from config/config-arm.mak
rename to arm/Makefile.arm
index ae6c2e7134883..946422872532d 100644
--- a/config/config-arm.mak
+++ b/arm/Makefile.arm
@@ -18,6 +18,6 @@ cflatobjs += lib/arm/processor.o
 # arm specific tests
 tests =
 
-include config/config-arm-common.mak
+include $(TEST_DIR)/Makefile.common
 
 arch_clean: arm_clean
diff --git a/config/config-arm64.mak b/arm/Makefile.arm64
similarity index 89%
rename from config/config-arm64.mak
rename to arm/Makefile.arm64
index d61b703c8140e..0b0761c729c7c 100644
--- a/config/config-arm64.mak
+++ b/arm/Makefile.arm64
@@ -14,7 +14,7 @@ cflatobjs += lib/arm64/spinlock.o
 # arm64 specific tests
 tests =
 
-include config/config-arm-common.mak
+include $(TEST_DIR)/Makefile.common
 
 arch_clean: arm_clean
 	$(RM) lib/arm64/.*.d
diff --git a/config/config-arm-common.mak b/arm/Makefile.common
similarity index 98%
rename from config/config-arm-common.mak
rename to arm/Makefile.common
index bd153cf6ea5ba..dd3a0ca327d06 100644
--- a/config/config-arm-common.mak
+++ b/arm/Makefile.common
@@ -25,7 +25,7 @@ CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
-include config/asm-offsets.mak
+include scripts/asm-offsets.mak
 
 cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
diff --git a/config/asm-offsets.mak b/scripts/asm-offsets.mak
similarity index 100%
rename from config/asm-offsets.mak
rename to scripts/asm-offsets.mak
diff --git a/x86/Makefile b/x86/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/x86/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/config/config-x86-common.mak b/x86/Makefile.common
similarity index 100%
rename from config/config-x86-common.mak
rename to x86/Makefile.common
diff --git a/config/config-i386.mak b/x86/Makefile.i386
similarity index 91%
rename from config/config-i386.mak
rename to x86/Makefile.i386
index e353387551585..8a4c45c457476 100644
--- a/config/config-i386.mak
+++ b/x86/Makefile.i386
@@ -8,7 +8,7 @@ cflatobjs += lib/x86/setjmp32.o
 tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \
 	$(TEST_DIR)/cmpxchg8b.flat
 
-include config/config-x86-common.mak
+include $(TEST_DIR)/Makefile.common
 
 $(TEST_DIR)/cmpxchg8b.elf: $(cstart.o) $(TEST_DIR)/cmpxchg8b.o
 $(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
diff --git a/config/config-x86_64.mak b/x86/Makefile.x86_64
similarity index 93%
rename from config/config-x86_64.mak
rename to x86/Makefile.x86_64
index d190be82e0cf2..6b7ccfba550b6 100644
--- a/config/config-x86_64.mak
+++ b/x86/Makefile.x86_64
@@ -15,4 +15,4 @@ tests += $(TEST_DIR)/svm.flat
 tests += $(TEST_DIR)/vmx.flat
 tests += $(TEST_DIR)/tscdeadline_latency.flat
 
-include config/config-x86-common.mak
+include $(TEST_DIR)/Makefile.common
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 07/17] config: no need to mix arch makefiles
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Move the config/config-*.mak files to their own directories and
rename to Makefile.* README is also updated to reflect the change,
as well as to remove an optimistic reference to a non-existent
docs directory.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 Makefile                                            | 2 +-
 README                                              | 3 +--
 arm/Makefile                                        | 1 +
 config/config-arm.mak => arm/Makefile.arm           | 2 +-
 config/config-arm64.mak => arm/Makefile.arm64       | 2 +-
 config/config-arm-common.mak => arm/Makefile.common | 2 +-
 {config => scripts}/asm-offsets.mak                 | 0
 x86/Makefile                                        | 1 +
 config/config-x86-common.mak => x86/Makefile.common | 0
 config/config-i386.mak => x86/Makefile.i386         | 2 +-
 config/config-x86_64.mak => x86/Makefile.x86_64     | 2 +-
 11 files changed, 9 insertions(+), 8 deletions(-)
 create mode 100644 arm/Makefile
 rename config/config-arm.mak => arm/Makefile.arm (90%)
 rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
 rename config/config-arm-common.mak => arm/Makefile.common (98%)
 rename {config => scripts}/asm-offsets.mak (100%)
 create mode 100644 x86/Makefile
 rename config/config-x86-common.mak => x86/Makefile.common (100%)
 rename config/config-i386.mak => x86/Makefile.i386 (91%)
 rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)

diff --git a/Makefile b/Makefile
index fe5cc620d473b..ddba941858596 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@ LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
 LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
 
 #include architecure specific make rules
-include config/config-$(ARCH).mak
+include $(TEST_DIR)/Makefile
 
 # cc-option
 # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
diff --git a/README b/README
index 457bd797362cf..f8f196d90bf10 100644
--- a/README
+++ b/README
@@ -34,8 +34,7 @@ each as a standalone test.
 
 Directory structure:
 .:		configure script, top-level Makefile, and run_tests.sh
-./config:	collection of architecture dependent makefiles
-./docs:		documentation files
+./scripts:	helper scripts for building and running tests
 ./lib:		general architecture neutral services for the tests
 ./lib/<ARCH>:	architecture dependent services for the tests
 ./<ARCH>:	the sources of the tests and the created objects/images
diff --git a/arm/Makefile b/arm/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/arm/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/config/config-arm.mak b/arm/Makefile.arm
similarity index 90%
rename from config/config-arm.mak
rename to arm/Makefile.arm
index ae6c2e7134883..946422872532d 100644
--- a/config/config-arm.mak
+++ b/arm/Makefile.arm
@@ -18,6 +18,6 @@ cflatobjs += lib/arm/processor.o
 # arm specific tests
 tests  
-include config/config-arm-common.mak
+include $(TEST_DIR)/Makefile.common
 
 arch_clean: arm_clean
diff --git a/config/config-arm64.mak b/arm/Makefile.arm64
similarity index 89%
rename from config/config-arm64.mak
rename to arm/Makefile.arm64
index d61b703c8140e..0b0761c729c7c 100644
--- a/config/config-arm64.mak
+++ b/arm/Makefile.arm64
@@ -14,7 +14,7 @@ cflatobjs += lib/arm64/spinlock.o
 # arm64 specific tests
 tests  
-include config/config-arm-common.mak
+include $(TEST_DIR)/Makefile.common
 
 arch_clean: arm_clean
 	$(RM) lib/arm64/.*.d
diff --git a/config/config-arm-common.mak b/arm/Makefile.common
similarity index 98%
rename from config/config-arm-common.mak
rename to arm/Makefile.common
index bd153cf6ea5ba..dd3a0ca327d06 100644
--- a/config/config-arm-common.mak
+++ b/arm/Makefile.common
@@ -25,7 +25,7 @@ CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
-include config/asm-offsets.mak
+include scripts/asm-offsets.mak
 
 cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
diff --git a/config/asm-offsets.mak b/scripts/asm-offsets.mak
similarity index 100%
rename from config/asm-offsets.mak
rename to scripts/asm-offsets.mak
diff --git a/x86/Makefile b/x86/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/x86/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/config/config-x86-common.mak b/x86/Makefile.common
similarity index 100%
rename from config/config-x86-common.mak
rename to x86/Makefile.common
diff --git a/config/config-i386.mak b/x86/Makefile.i386
similarity index 91%
rename from config/config-i386.mak
rename to x86/Makefile.i386
index e353387551585..8a4c45c457476 100644
--- a/config/config-i386.mak
+++ b/x86/Makefile.i386
@@ -8,7 +8,7 @@ cflatobjs += lib/x86/setjmp32.o
 tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \
 	$(TEST_DIR)/cmpxchg8b.flat
 
-include config/config-x86-common.mak
+include $(TEST_DIR)/Makefile.common
 
 $(TEST_DIR)/cmpxchg8b.elf: $(cstart.o) $(TEST_DIR)/cmpxchg8b.o
 $(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
diff --git a/config/config-x86_64.mak b/x86/Makefile.x86_64
similarity index 93%
rename from config/config-x86_64.mak
rename to x86/Makefile.x86_64
index d190be82e0cf2..6b7ccfba550b6 100644
--- a/config/config-x86_64.mak
+++ b/x86/Makefile.x86_64
@@ -15,4 +15,4 @@ tests += $(TEST_DIR)/svm.flat
 tests += $(TEST_DIR)/vmx.flat
 tests += $(TEST_DIR)/tscdeadline_latency.flat
 
-include config/config-x86-common.mak
+include $(TEST_DIR)/Makefile.common
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 08/17] powerpc/ppc64: start skeleton framework
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Use the arm/arm64 framework as a template to start a skeleton
for powerpc/ppc64. Copy the arm makefiles and linker script
verbatim. We'll modify them for powerpc with the next patch,
making it clear what needs to be changed.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 configure                   |  2 ++
 lib/powerpc/.gitignore      |  1 +
 lib/powerpc/io.c            | 20 +++++++++++++
 lib/ppc64/.gitignore        |  1 +
 lib/ppc64/asm-offsets.c     | 12 ++++++++
 lib/ppc64/asm/asm-offsets.h |  1 +
 lib/ppc64/asm/io.h          |  5 ++++
 lib/ppc64/asm/page.h        |  1 +
 lib/ppc64/asm/spinlock.h    | 11 +++++++
 lib/ppc64/spinlock.c        | 11 +++++++
 powerpc/Makefile            |  1 +
 powerpc/Makefile.common     | 73 +++++++++++++++++++++++++++++++++++++++++++++
 powerpc/Makefile.ppc64      | 20 +++++++++++++
 powerpc/cstart64.S          | 20 +++++++++++++
 powerpc/flat.lds            | 27 +++++++++++++++++
 powerpc/selftest.c          |  7 +++++
 16 files changed, 213 insertions(+)
 create mode 100644 lib/powerpc/.gitignore
 create mode 100644 lib/powerpc/io.c
 create mode 100644 lib/ppc64/.gitignore
 create mode 100644 lib/ppc64/asm-offsets.c
 create mode 100644 lib/ppc64/asm/asm-offsets.h
 create mode 100644 lib/ppc64/asm/io.h
 create mode 100644 lib/ppc64/asm/page.h
 create mode 100644 lib/ppc64/asm/spinlock.h
 create mode 100644 lib/ppc64/spinlock.c
 create mode 100644 powerpc/Makefile
 create mode 100644 powerpc/Makefile.common
 create mode 100644 powerpc/Makefile.ppc64
 create mode 100644 powerpc/cstart64.S
 create mode 100644 powerpc/flat.lds
 create mode 100644 powerpc/selftest.c

diff --git a/configure b/configure
index 078b70ce096a6..b367224093369 100755
--- a/configure
+++ b/configure
@@ -80,6 +80,8 @@ if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
     testdir=x86
 elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
     testdir=arm
+elif [ "$arch" = "ppc64" ]; then
+    testdir=powerpc
 else
     testdir=$arch
 fi
diff --git a/lib/powerpc/.gitignore b/lib/powerpc/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/powerpc/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
new file mode 100644
index 0000000000000..0af45742fc900
--- /dev/null
+++ b/lib/powerpc/io.c
@@ -0,0 +1,20 @@
+/*
+ * Each architecture must implement puts() and exit().
+ *
+ * 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>
+
+void io_init(void)
+{
+}
+
+void puts(const char *s __unused)
+{
+}
+
+void exit(int code __unused)
+{
+}
diff --git a/lib/ppc64/.gitignore b/lib/ppc64/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/ppc64/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/ppc64/asm-offsets.c b/lib/ppc64/asm-offsets.c
new file mode 100644
index 0000000000000..2d38a716976f2
--- /dev/null
+++ b/lib/ppc64/asm-offsets.c
@@ -0,0 +1,12 @@
+/*
+ * 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 <kbuild.h>
+
+int main(void)
+{
+	return 0;
+}
diff --git a/lib/ppc64/asm/asm-offsets.h b/lib/ppc64/asm/asm-offsets.h
new file mode 100644
index 0000000000000..d370ee36a182b
--- /dev/null
+++ b/lib/ppc64/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/lib/ppc64/asm/io.h b/lib/ppc64/asm/io.h
new file mode 100644
index 0000000000000..c0801d4762ba6
--- /dev/null
+++ b/lib/ppc64/asm/io.h
@@ -0,0 +1,5 @@
+#ifndef _ASMPPC64_IO_H_
+#define _ASMPPC64_IO_H_
+#define __cpu_is_be() (1)
+#include <asm-generic/io.h>
+#endif
diff --git a/lib/ppc64/asm/page.h b/lib/ppc64/asm/page.h
new file mode 100644
index 0000000000000..1a8b62711f288
--- /dev/null
+++ b/lib/ppc64/asm/page.h
@@ -0,0 +1 @@
+#include <asm-generic/page.h>
diff --git a/lib/ppc64/asm/spinlock.h b/lib/ppc64/asm/spinlock.h
new file mode 100644
index 0000000000000..002cdb194b1db
--- /dev/null
+++ b/lib/ppc64/asm/spinlock.h
@@ -0,0 +1,11 @@
+#ifndef _ASMPPC64_SPINLOCK_H_
+#define _ASMPPC64_SPINLOCK_H_
+
+struct spinlock {
+	int v;
+};
+
+extern void spin_lock(struct spinlock *lock);
+extern void spin_unlock(struct spinlock *lock);
+
+#endif /* _ASMPPC64_SPINLOCK_H_ */
diff --git a/lib/ppc64/spinlock.c b/lib/ppc64/spinlock.c
new file mode 100644
index 0000000000000..522f8d047c970
--- /dev/null
+++ b/lib/ppc64/spinlock.c
@@ -0,0 +1,11 @@
+#include <asm/spinlock.h>
+
+void spin_lock(struct spinlock *lock)
+{
+        lock->v = 1;
+}
+
+void spin_unlock(struct spinlock *lock)
+{
+        lock->v = 0;
+}
diff --git a/powerpc/Makefile b/powerpc/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/powerpc/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
new file mode 100644
index 0000000000000..dd3a0ca327d06
--- /dev/null
+++ b/powerpc/Makefile.common
@@ -0,0 +1,73 @@
+#
+# arm common makefile
+#
+# Authors: Andrew Jones <drjones@redhat.com>
+#
+
+ifeq ($(LOADADDR),)
+	# qemu mach-virt default load address
+	LOADADDR = 0x40000000
+endif
+
+tests-common = \
+	$(TEST_DIR)/selftest.flat \
+	$(TEST_DIR)/spinlock-test.flat
+
+all: test_cases
+
+##################################################################
+phys_base = $(LOADADDR)
+
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -Wextra
+CFLAGS += -O2
+CFLAGS += -I lib -I lib/libfdt
+
+asm-offsets = lib/$(ARCH)/asm-offsets.h
+include scripts/asm-offsets.mak
+
+cflatobjs += lib/util.o
+cflatobjs += lib/alloc.o
+cflatobjs += lib/devicetree.o
+cflatobjs += lib/virtio.o
+cflatobjs += lib/virtio-mmio.o
+cflatobjs += lib/chr-testdev.o
+cflatobjs += lib/arm/io.o
+cflatobjs += lib/arm/setup.o
+cflatobjs += lib/arm/mmu.o
+cflatobjs += lib/arm/bitops.o
+cflatobjs += lib/arm/psci.o
+cflatobjs += lib/arm/smp.o
+
+libeabi = lib/arm/libeabi.a
+eabiobjs = lib/arm/eabi_compat.o
+
+libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
+start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
+
+FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
+%.elf: LDFLAGS = $(CFLAGS) -nostdlib
+%.elf: %.o $(FLATLIBS) arm/flat.lds
+	$(CC) $(LDFLAGS) -o $@ \
+		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+		$(filter %.o, $^) $(FLATLIBS)
+
+%.flat: %.elf
+	$(OBJCOPY) -O binary $^ $@
+
+$(libeabi): $(eabiobjs)
+	$(AR) rcs $@ $^
+
+arm_clean: libfdt_clean asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
+	      $(TEST_DIR)/.*.d lib/arm/.*.d
+
+##################################################################
+
+generated_files = $(asm-offsets)
+
+test_cases: $(generated_files) $(tests-common) $(tests)
+
+$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
+$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
new file mode 100644
index 0000000000000..0b0761c729c7c
--- /dev/null
+++ b/powerpc/Makefile.ppc64
@@ -0,0 +1,20 @@
+#
+# arm64 makefile
+#
+# Authors: Andrew Jones <drjones@redhat.com>
+#
+bits = 64
+ldarch = elf64-littleaarch64
+kernel_offset = 0x80000
+
+cstart.o = $(TEST_DIR)/cstart64.o
+cflatobjs += lib/arm64/processor.o
+cflatobjs += lib/arm64/spinlock.o
+
+# arm64 specific tests
+tests =
+
+include $(TEST_DIR)/Makefile.common
+
+arch_clean: arm_clean
+	$(RM) lib/arm64/.*.d
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
new file mode 100644
index 0000000000000..f90828dee1c19
--- /dev/null
+++ b/powerpc/cstart64.S
@@ -0,0 +1,20 @@
+/*
+ * Entry point and assembler functions for ppc64 tests.
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#define __ASSEMBLY__
+
+.section .init
+
+.globl start
+start:
+	b	halt
+
+.text
+
+.globl halt
+halt:
+1:	b	1b
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
new file mode 100644
index 0000000000000..efdf5d7109ffb
--- /dev/null
+++ b/powerpc/flat.lds
@@ -0,0 +1,27 @@
+
+SECTIONS
+{
+    .text : { *(.init) *(.text) *(.text.*) }
+    . = ALIGN(64K);
+    etext = .;
+    .data : {
+        *(.data)
+    }
+    . = ALIGN(16);
+    .rodata : { *(.rodata) }
+    . = ALIGN(16);
+    .bss : { *(.bss) }
+    . = ALIGN(64K);
+    edata = .;
+    . += 64K;
+    . = ALIGN(64K);
+    /*
+     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
+     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
+     * sp must always be strictly less than the true stacktop
+     */
+    stackptr = . - 16;
+    stacktop = .;
+}
+
+ENTRY(start)
diff --git a/powerpc/selftest.c b/powerpc/selftest.c
new file mode 100644
index 0000000000000..2f2a5215dd55c
--- /dev/null
+++ b/powerpc/selftest.c
@@ -0,0 +1,7 @@
+#include <libcflat.h>
+
+int main(void)
+{
+	printf("hello world\n");
+	return 0;
+}
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 08/17] powerpc/ppc64: start skeleton framework
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Use the arm/arm64 framework as a template to start a skeleton
for powerpc/ppc64. Copy the arm makefiles and linker script
verbatim. We'll modify them for powerpc with the next patch,
making it clear what needs to be changed.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 configure                   |  2 ++
 lib/powerpc/.gitignore      |  1 +
 lib/powerpc/io.c            | 20 +++++++++++++
 lib/ppc64/.gitignore        |  1 +
 lib/ppc64/asm-offsets.c     | 12 ++++++++
 lib/ppc64/asm/asm-offsets.h |  1 +
 lib/ppc64/asm/io.h          |  5 ++++
 lib/ppc64/asm/page.h        |  1 +
 lib/ppc64/asm/spinlock.h    | 11 +++++++
 lib/ppc64/spinlock.c        | 11 +++++++
 powerpc/Makefile            |  1 +
 powerpc/Makefile.common     | 73 +++++++++++++++++++++++++++++++++++++++++++++
 powerpc/Makefile.ppc64      | 20 +++++++++++++
 powerpc/cstart64.S          | 20 +++++++++++++
 powerpc/flat.lds            | 27 +++++++++++++++++
 powerpc/selftest.c          |  7 +++++
 16 files changed, 213 insertions(+)
 create mode 100644 lib/powerpc/.gitignore
 create mode 100644 lib/powerpc/io.c
 create mode 100644 lib/ppc64/.gitignore
 create mode 100644 lib/ppc64/asm-offsets.c
 create mode 100644 lib/ppc64/asm/asm-offsets.h
 create mode 100644 lib/ppc64/asm/io.h
 create mode 100644 lib/ppc64/asm/page.h
 create mode 100644 lib/ppc64/asm/spinlock.h
 create mode 100644 lib/ppc64/spinlock.c
 create mode 100644 powerpc/Makefile
 create mode 100644 powerpc/Makefile.common
 create mode 100644 powerpc/Makefile.ppc64
 create mode 100644 powerpc/cstart64.S
 create mode 100644 powerpc/flat.lds
 create mode 100644 powerpc/selftest.c

diff --git a/configure b/configure
index 078b70ce096a6..b367224093369 100755
--- a/configure
+++ b/configure
@@ -80,6 +80,8 @@ if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
     testdir=x86
 elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
     testdir=arm
+elif [ "$arch" = "ppc64" ]; then
+    testdir=powerpc
 else
     testdir=$arch
 fi
diff --git a/lib/powerpc/.gitignore b/lib/powerpc/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/powerpc/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
new file mode 100644
index 0000000000000..0af45742fc900
--- /dev/null
+++ b/lib/powerpc/io.c
@@ -0,0 +1,20 @@
+/*
+ * Each architecture must implement puts() and exit().
+ *
+ * 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>
+
+void io_init(void)
+{
+}
+
+void puts(const char *s __unused)
+{
+}
+
+void exit(int code __unused)
+{
+}
diff --git a/lib/ppc64/.gitignore b/lib/ppc64/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/ppc64/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/ppc64/asm-offsets.c b/lib/ppc64/asm-offsets.c
new file mode 100644
index 0000000000000..2d38a716976f2
--- /dev/null
+++ b/lib/ppc64/asm-offsets.c
@@ -0,0 +1,12 @@
+/*
+ * 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 <kbuild.h>
+
+int main(void)
+{
+	return 0;
+}
diff --git a/lib/ppc64/asm/asm-offsets.h b/lib/ppc64/asm/asm-offsets.h
new file mode 100644
index 0000000000000..d370ee36a182b
--- /dev/null
+++ b/lib/ppc64/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/lib/ppc64/asm/io.h b/lib/ppc64/asm/io.h
new file mode 100644
index 0000000000000..c0801d4762ba6
--- /dev/null
+++ b/lib/ppc64/asm/io.h
@@ -0,0 +1,5 @@
+#ifndef _ASMPPC64_IO_H_
+#define _ASMPPC64_IO_H_
+#define __cpu_is_be() (1)
+#include <asm-generic/io.h>
+#endif
diff --git a/lib/ppc64/asm/page.h b/lib/ppc64/asm/page.h
new file mode 100644
index 0000000000000..1a8b62711f288
--- /dev/null
+++ b/lib/ppc64/asm/page.h
@@ -0,0 +1 @@
+#include <asm-generic/page.h>
diff --git a/lib/ppc64/asm/spinlock.h b/lib/ppc64/asm/spinlock.h
new file mode 100644
index 0000000000000..002cdb194b1db
--- /dev/null
+++ b/lib/ppc64/asm/spinlock.h
@@ -0,0 +1,11 @@
+#ifndef _ASMPPC64_SPINLOCK_H_
+#define _ASMPPC64_SPINLOCK_H_
+
+struct spinlock {
+	int v;
+};
+
+extern void spin_lock(struct spinlock *lock);
+extern void spin_unlock(struct spinlock *lock);
+
+#endif /* _ASMPPC64_SPINLOCK_H_ */
diff --git a/lib/ppc64/spinlock.c b/lib/ppc64/spinlock.c
new file mode 100644
index 0000000000000..522f8d047c970
--- /dev/null
+++ b/lib/ppc64/spinlock.c
@@ -0,0 +1,11 @@
+#include <asm/spinlock.h>
+
+void spin_lock(struct spinlock *lock)
+{
+        lock->v = 1;
+}
+
+void spin_unlock(struct spinlock *lock)
+{
+        lock->v = 0;
+}
diff --git a/powerpc/Makefile b/powerpc/Makefile
new file mode 100644
index 0000000000000..369a38b2d1703
--- /dev/null
+++ b/powerpc/Makefile
@@ -0,0 +1 @@
+include $(TEST_DIR)/Makefile.$(ARCH)
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
new file mode 100644
index 0000000000000..dd3a0ca327d06
--- /dev/null
+++ b/powerpc/Makefile.common
@@ -0,0 +1,73 @@
+#
+# arm common makefile
+#
+# Authors: Andrew Jones <drjones@redhat.com>
+#
+
+ifeq ($(LOADADDR),)
+	# qemu mach-virt default load address
+	LOADADDR = 0x40000000
+endif
+
+tests-common = \
+	$(TEST_DIR)/selftest.flat \
+	$(TEST_DIR)/spinlock-test.flat
+
+all: test_cases
+
+##################################################################
+phys_base = $(LOADADDR)
+
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -Wextra
+CFLAGS += -O2
+CFLAGS += -I lib -I lib/libfdt
+
+asm-offsets = lib/$(ARCH)/asm-offsets.h
+include scripts/asm-offsets.mak
+
+cflatobjs += lib/util.o
+cflatobjs += lib/alloc.o
+cflatobjs += lib/devicetree.o
+cflatobjs += lib/virtio.o
+cflatobjs += lib/virtio-mmio.o
+cflatobjs += lib/chr-testdev.o
+cflatobjs += lib/arm/io.o
+cflatobjs += lib/arm/setup.o
+cflatobjs += lib/arm/mmu.o
+cflatobjs += lib/arm/bitops.o
+cflatobjs += lib/arm/psci.o
+cflatobjs += lib/arm/smp.o
+
+libeabi = lib/arm/libeabi.a
+eabiobjs = lib/arm/eabi_compat.o
+
+libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
+start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
+
+FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
+%.elf: LDFLAGS = $(CFLAGS) -nostdlib
+%.elf: %.o $(FLATLIBS) arm/flat.lds
+	$(CC) $(LDFLAGS) -o $@ \
+		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+		$(filter %.o, $^) $(FLATLIBS)
+
+%.flat: %.elf
+	$(OBJCOPY) -O binary $^ $@
+
+$(libeabi): $(eabiobjs)
+	$(AR) rcs $@ $^
+
+arm_clean: libfdt_clean asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
+	      $(TEST_DIR)/.*.d lib/arm/.*.d
+
+##################################################################
+
+generated_files = $(asm-offsets)
+
+test_cases: $(generated_files) $(tests-common) $(tests)
+
+$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
+$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
new file mode 100644
index 0000000000000..0b0761c729c7c
--- /dev/null
+++ b/powerpc/Makefile.ppc64
@@ -0,0 +1,20 @@
+#
+# arm64 makefile
+#
+# Authors: Andrew Jones <drjones@redhat.com>
+#
+bits = 64
+ldarch = elf64-littleaarch64
+kernel_offset = 0x80000
+
+cstart.o = $(TEST_DIR)/cstart64.o
+cflatobjs += lib/arm64/processor.o
+cflatobjs += lib/arm64/spinlock.o
+
+# arm64 specific tests
+tests +
+include $(TEST_DIR)/Makefile.common
+
+arch_clean: arm_clean
+	$(RM) lib/arm64/.*.d
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
new file mode 100644
index 0000000000000..f90828dee1c19
--- /dev/null
+++ b/powerpc/cstart64.S
@@ -0,0 +1,20 @@
+/*
+ * Entry point and assembler functions for ppc64 tests.
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#define __ASSEMBLY__
+
+.section .init
+
+.globl start
+start:
+	b	halt
+
+.text
+
+.globl halt
+halt:
+1:	b	1b
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
new file mode 100644
index 0000000000000..efdf5d7109ffb
--- /dev/null
+++ b/powerpc/flat.lds
@@ -0,0 +1,27 @@
+
+SECTIONS
+{
+    .text : { *(.init) *(.text) *(.text.*) }
+    . = ALIGN(64K);
+    etext = .;
+    .data : {
+        *(.data)
+    }
+    . = ALIGN(16);
+    .rodata : { *(.rodata) }
+    . = ALIGN(16);
+    .bss : { *(.bss) }
+    . = ALIGN(64K);
+    edata = .;
+    . += 64K;
+    . = ALIGN(64K);
+    /*
+     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
+     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
+     * sp must always be strictly less than the true stacktop
+     */
+    stackptr = . - 16;
+    stacktop = .;
+}
+
+ENTRY(start)
diff --git a/powerpc/selftest.c b/powerpc/selftest.c
new file mode 100644
index 0000000000000..2f2a5215dd55c
--- /dev/null
+++ b/powerpc/selftest.c
@@ -0,0 +1,7 @@
+#include <libcflat.h>
+
+int main(void)
+{
+	printf("hello world\n");
+	return 0;
+}
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/Makefile.common | 40 ++++++++++------------------------------
 powerpc/Makefile.ppc64  | 15 +++++++--------
 powerpc/flat.lds        | 14 ++++++++++----
 3 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index dd3a0ca327d06..13b828ab171d6 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -1,17 +1,15 @@
 #
-# arm common makefile
+# powerpc common makefile
 #
 # Authors: Andrew Jones <drjones@redhat.com>
 #
 
 ifeq ($(LOADADDR),)
-	# qemu mach-virt default load address
-	LOADADDR = 0x40000000
+	LOADADDR = 0x0
 endif
 
 tests-common = \
-	$(TEST_DIR)/selftest.flat \
-	$(TEST_DIR)/spinlock-test.flat
+	$(TEST_DIR)/selftest.elf
 
 all: test_cases
 
@@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
 cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
-cflatobjs += lib/virtio.o
-cflatobjs += lib/virtio-mmio.o
-cflatobjs += lib/chr-testdev.o
-cflatobjs += lib/arm/io.o
-cflatobjs += lib/arm/setup.o
-cflatobjs += lib/arm/mmu.o
-cflatobjs += lib/arm/bitops.o
-cflatobjs += lib/arm/psci.o
-cflatobjs += lib/arm/smp.o
-
-libeabi = lib/arm/libeabi.a
-eabiobjs = lib/arm/eabi_compat.o
+cflatobjs += lib/powerpc/io.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
 
-FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
+FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
 %.elf: LDFLAGS = $(CFLAGS) -nostdlib
-%.elf: %.o $(FLATLIBS) arm/flat.lds
+%.elf: %.o $(FLATLIBS) powerpc/flat.lds
 	$(CC) $(LDFLAGS) -o $@ \
-		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
 
-%.flat: %.elf
-	$(OBJCOPY) -O binary $^ $@
-
-$(libeabi): $(eabiobjs)
-	$(AR) rcs $@ $^
-
-arm_clean: libfdt_clean asm_offsets_clean
-	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
-	      $(TEST_DIR)/.*.d lib/arm/.*.d
+powerpc_clean: libfdt_clean asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,elf} \
+	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
 
 ##################################################################
 
@@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
 test_cases: $(generated_files) $(tests-common) $(tests)
 
 $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
-$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
index 0b0761c729c7c..95bf6772d65ed 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -1,20 +1,19 @@
 #
-# arm64 makefile
+# ppc64 makefile
 #
 # Authors: Andrew Jones <drjones@redhat.com>
 #
 bits = 64
-ldarch = elf64-littleaarch64
-kernel_offset = 0x80000
+ldarch = elf64-powerpc
+kernel_offset = 0x0
 
 cstart.o = $(TEST_DIR)/cstart64.o
-cflatobjs += lib/arm64/processor.o
-cflatobjs += lib/arm64/spinlock.o
+cflatobjs += lib/ppc64/spinlock.o
 
-# arm64 specific tests
+# ppc64 specific tests
 tests =
 
 include $(TEST_DIR)/Makefile.common
 
-arch_clean: arm_clean
-	$(RM) lib/arm64/.*.d
+arch_clean: powerpc_clean
+	$(RM) lib/ppc64/.*.d
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
index efdf5d7109ffb..84087057c0ce2 100644
--- a/powerpc/flat.lds
+++ b/powerpc/flat.lds
@@ -4,6 +4,8 @@ SECTIONS
     .text : { *(.init) *(.text) *(.text.*) }
     . = ALIGN(64K);
     etext = .;
+    .opd : { *(.opd) }
+    . = ALIGN(16);
     .data : {
         *(.data)
     }
@@ -11,16 +13,20 @@ SECTIONS
     .rodata : { *(.rodata) }
     . = ALIGN(16);
     .bss : { *(.bss) }
+    . = ALIGN(256);
+    /*
+     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
+     */
+    tocptr = . + 32K;
+    .got : { *(.toc) *(.got) }
     . = ALIGN(64K);
     edata = .;
     . += 64K;
     . = ALIGN(64K);
     /*
-     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
-     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
-     * sp must always be strictly less than the true stacktop
+     * stackptr set with initial stack frame (64 bytes) preallocated
      */
-    stackptr = . - 16;
+    stackptr = . - 64;
     stacktop = .;
 }
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/Makefile.common | 40 ++++++++++------------------------------
 powerpc/Makefile.ppc64  | 15 +++++++--------
 powerpc/flat.lds        | 14 ++++++++++----
 3 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index dd3a0ca327d06..13b828ab171d6 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -1,17 +1,15 @@
 #
-# arm common makefile
+# powerpc common makefile
 #
 # Authors: Andrew Jones <drjones@redhat.com>
 #
 
 ifeq ($(LOADADDR),)
-	# qemu mach-virt default load address
-	LOADADDR = 0x40000000
+	LOADADDR = 0x0
 endif
 
 tests-common = \
-	$(TEST_DIR)/selftest.flat \
-	$(TEST_DIR)/spinlock-test.flat
+	$(TEST_DIR)/selftest.elf
 
 all: test_cases
 
@@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
 cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
-cflatobjs += lib/virtio.o
-cflatobjs += lib/virtio-mmio.o
-cflatobjs += lib/chr-testdev.o
-cflatobjs += lib/arm/io.o
-cflatobjs += lib/arm/setup.o
-cflatobjs += lib/arm/mmu.o
-cflatobjs += lib/arm/bitops.o
-cflatobjs += lib/arm/psci.o
-cflatobjs += lib/arm/smp.o
-
-libeabi = lib/arm/libeabi.a
-eabiobjs = lib/arm/eabi_compat.o
+cflatobjs += lib/powerpc/io.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
 
-FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
+FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
 %.elf: LDFLAGS = $(CFLAGS) -nostdlib
-%.elf: %.o $(FLATLIBS) arm/flat.lds
+%.elf: %.o $(FLATLIBS) powerpc/flat.lds
 	$(CC) $(LDFLAGS) -o $@ \
-		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
 
-%.flat: %.elf
-	$(OBJCOPY) -O binary $^ $@
-
-$(libeabi): $(eabiobjs)
-	$(AR) rcs $@ $^
-
-arm_clean: libfdt_clean asm_offsets_clean
-	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
-	      $(TEST_DIR)/.*.d lib/arm/.*.d
+powerpc_clean: libfdt_clean asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,elf} \
+	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
 
 ##################################################################
 
@@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
 test_cases: $(generated_files) $(tests-common) $(tests)
 
 $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
-$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
index 0b0761c729c7c..95bf6772d65ed 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -1,20 +1,19 @@
 #
-# arm64 makefile
+# ppc64 makefile
 #
 # Authors: Andrew Jones <drjones@redhat.com>
 #
 bits = 64
-ldarch = elf64-littleaarch64
-kernel_offset = 0x80000
+ldarch = elf64-powerpc
+kernel_offset = 0x0
 
 cstart.o = $(TEST_DIR)/cstart64.o
-cflatobjs += lib/arm64/processor.o
-cflatobjs += lib/arm64/spinlock.o
+cflatobjs += lib/ppc64/spinlock.o
 
-# arm64 specific tests
+# ppc64 specific tests
 tests  
 include $(TEST_DIR)/Makefile.common
 
-arch_clean: arm_clean
-	$(RM) lib/arm64/.*.d
+arch_clean: powerpc_clean
+	$(RM) lib/ppc64/.*.d
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
index efdf5d7109ffb..84087057c0ce2 100644
--- a/powerpc/flat.lds
+++ b/powerpc/flat.lds
@@ -4,6 +4,8 @@ SECTIONS
     .text : { *(.init) *(.text) *(.text.*) }
     . = ALIGN(64K);
     etext = .;
+    .opd : { *(.opd) }
+    . = ALIGN(16);
     .data : {
         *(.data)
     }
@@ -11,16 +13,20 @@ SECTIONS
     .rodata : { *(.rodata) }
     . = ALIGN(16);
     .bss : { *(.bss) }
+    . = ALIGN(256);
+    /*
+     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
+     */
+    tocptr = . + 32K;
+    .got : { *(.toc) *(.got) }
     . = ALIGN(64K);
     edata = .;
     . += 64K;
     . = ALIGN(64K);
     /*
-     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
-     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
-     * sp must always be strictly less than the true stacktop
+     * stackptr set with initial stack frame (64 bytes) preallocated
      */
-    stackptr = . - 16;
+    stackptr = . - 64;
     stacktop = .;
 }
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 10/17] powerpc/ppc64: add a boot rom
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Make a one line replacement for SLOF. This bootloader just
jumps to 0x400000, because we know the kernel will be there.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/.gitignore      |  1 +
 powerpc/Makefile.common | 11 +++++++++--
 powerpc/boot_rom.S      |  5 +++++
 3 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 powerpc/.gitignore
 create mode 100644 powerpc/boot_rom.S

diff --git a/powerpc/.gitignore b/powerpc/.gitignore
new file mode 100644
index 0000000000000..2f017a8e61d4b
--- /dev/null
+++ b/powerpc/.gitignore
@@ -0,0 +1 @@
+boot_rom.bin
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 13b828ab171d6..0c3eaba0d3aab 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -11,7 +11,7 @@ endif
 tests-common = \
 	$(TEST_DIR)/selftest.elf
 
-all: test_cases
+all: $(TEST_DIR)/boot_rom.bin test_cases
 
 ##################################################################
 phys_base = $(LOADADDR)
@@ -40,8 +40,15 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
 		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
 
+$(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
+	dd if=/dev/zero of=$@ bs=256 count=1
+	$(OBJCOPY) -O binary $^ >(cat - >>$@)
+
+$(TEST_DIR)/boot_rom.elf: $(TEST_DIR)/boot_rom.o
+	$(LD) -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $<
+
 powerpc_clean: libfdt_clean asm_offsets_clean
-	$(RM) $(TEST_DIR)/*.{o,elf} \
+	$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/boot_rom.bin \
 	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
 
 ##################################################################
diff --git a/powerpc/boot_rom.S b/powerpc/boot_rom.S
new file mode 100644
index 0000000000000..ae2c08ddce3c1
--- /dev/null
+++ b/powerpc/boot_rom.S
@@ -0,0 +1,5 @@
+#define SPAPR_KERNEL_LOAD_ADDR 0x400000
+.text
+.globl start
+start:
+	b	SPAPR_KERNEL_LOAD_ADDR - 0x100
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 10/17] powerpc/ppc64: add a boot rom
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Make a one line replacement for SLOF. This bootloader just
jumps to 0x400000, because we know the kernel will be there.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/.gitignore      |  1 +
 powerpc/Makefile.common | 11 +++++++++--
 powerpc/boot_rom.S      |  5 +++++
 3 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 powerpc/.gitignore
 create mode 100644 powerpc/boot_rom.S

diff --git a/powerpc/.gitignore b/powerpc/.gitignore
new file mode 100644
index 0000000000000..2f017a8e61d4b
--- /dev/null
+++ b/powerpc/.gitignore
@@ -0,0 +1 @@
+boot_rom.bin
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 13b828ab171d6..0c3eaba0d3aab 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -11,7 +11,7 @@ endif
 tests-common = \
 	$(TEST_DIR)/selftest.elf
 
-all: test_cases
+all: $(TEST_DIR)/boot_rom.bin test_cases
 
 ##################################################################
 phys_base = $(LOADADDR)
@@ -40,8 +40,15 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
 		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
 
+$(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
+	dd if=/dev/zero of=$@ bs%6 count=1
+	$(OBJCOPY) -O binary $^ >(cat - >>$@)
+
+$(TEST_DIR)/boot_rom.elf: $(TEST_DIR)/boot_rom.o
+	$(LD) -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $<
+
 powerpc_clean: libfdt_clean asm_offsets_clean
-	$(RM) $(TEST_DIR)/*.{o,elf} \
+	$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/boot_rom.bin \
 	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
 
 ##################################################################
diff --git a/powerpc/boot_rom.S b/powerpc/boot_rom.S
new file mode 100644
index 0000000000000..ae2c08ddce3c1
--- /dev/null
+++ b/powerpc/boot_rom.S
@@ -0,0 +1,5 @@
+#define SPAPR_KERNEL_LOAD_ADDR 0x400000
+.text
+.globl start
+start:
+	b	SPAPR_KERNEL_LOAD_ADDR - 0x100
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Add broken sc1 detection and patching and an hcall for putchar,
to use in puts. That, along with a couple more lines in start to
prepare for C code, and a branch to main(), gets us "hello world".
Run with

qemu-system-ppc64 -M pseries            \
        -bios powerpc/boot_rom.bin      \
        -display none -serial stdio     \
        -kernel powerpc/selftest.elf

(We're still not relocating yet, that comes in a later patch. Thus,
 testing hello-world at this point requires a hacked QEMU and linking
 the unit test at QEMU's kernel load address.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
 lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/powerpc/io.c        | 15 ++++++++--
 lib/ppc64/asm/hcall.h   |  1 +
 powerpc/Makefile.common |  2 ++
 powerpc/cstart64.S      | 21 +++++++++++++
 6 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 lib/powerpc/asm/hcall.h
 create mode 100644 lib/powerpc/hcall.c
 create mode 100644 lib/ppc64/asm/hcall.h

diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
new file mode 100644
index 0000000000000..f861287ac2083
--- /dev/null
+++ b/lib/powerpc/asm/hcall.h
@@ -0,0 +1,46 @@
+#ifndef _ASMPOWERPC_HCALL_H_
+#define _ASMPOWERPC_HCALL_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.
+ */
+
+#define SC1			0x44000022
+#define SC1_REPLACEMENT		0x7c000268
+
+#define H_SUCCESS		0
+#define H_HARDWARE		-1
+#define H_FUNCTION		-2
+#define H_PRIVILEGE		-3
+#define H_PARAMETER		-4
+
+#define H_SET_DABR		0x28
+#define H_PUT_TERM_CHAR		0x58
+
+#ifndef __ASSEMBLY__
+#include <libcflat.h>
+
+/*
+ * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
+ * Returns true if we are.
+ */
+extern bool hcall_have_broken_sc1(void);
+
+/*
+ * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
+ * allowing all hypercalls built on it to work.
+ */
+extern void hcall_patch_broken_sc1(void);
+
+/*
+ * hcall is the hypercall wrapper function. unittests may do what
+ * they like, but the framework should make all hypercalls through
+ * here to ensure they use a working sc1 instruction, and properly
+ * handle clobbered registers. @nr is the hypercall number.
+ */
+extern unsigned long
+hcall(unsigned long nr, unsigned long *in, unsigned long *out);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMPOWERPC_HCALL_H_ */
diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
new file mode 100644
index 0000000000000..db99949352133
--- /dev/null
+++ b/lib/powerpc/hcall.c
@@ -0,0 +1,79 @@
+/*
+ * Hypercall helpers
+ *
+ * broken_sc1 probing/patching inspired by SLOF, see
+ *   SLOF:lib/libhvcall/brokensc1.c
+ *
+ * hcall() implementation inspired by Linux's epapr_hypercall, see
+ *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
+
+static u32 sc1[];
+
+bool hcall_have_broken_sc1(void)
+{
+	register unsigned long r3 asm("r3") = H_SET_DABR;
+	register unsigned long r4 asm("r4") = 0;
+
+	asm volatile("sc 1"
+	: "=r" (r3)
+	: "r" (r3), "r" (r4)
+	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+
+	return r3 == (unsigned long)H_PRIVILEGE;
+}
+
+void hcall_patch_broken_sc1(void)
+{
+	if (!hcall_have_broken_sc1())
+		return;
+	sc1[0] = SC1_REPLACEMENT;
+}
+
+unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
+{
+	register unsigned long r3 asm("r3") = nr;
+	register unsigned long r4 asm("r4") = in[0];
+	register unsigned long r5 asm("r5") = in[1];
+	register unsigned long r6 asm("r6") = in[2];
+	register unsigned long r7 asm("r7") = in[3];
+	register unsigned long r8 asm("r8") = in[4];
+	register unsigned long r9 asm("r9") = in[5];
+	register unsigned long r10 asm("r10") = in[6];
+	register unsigned long r11 asm("r11") = in[7];
+
+	asm volatile("bl sc1"
+		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
+		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
+		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
+		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
+		: "r12", "memory", "lr");
+
+	out[0] = r4;
+	out[1] = r5;
+	out[2] = r6;
+	out[3] = r7;
+	out[4] = r8;
+	out[5] = r9;
+	out[6] = r10;
+	out[7] = r11;
+
+	return r3;
+}
+
+void putchar(int c)
+{
+	unsigned long in[8], out[8];
+
+	in[0] = 0; /* default vty */
+	in[1] = 1; /* just 1 byte */
+	in[2] = (unsigned long)c << 56;
+
+	hcall(H_PUT_TERM_CHAR, in, out);
+}
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index 0af45742fc900..5e1fa8dd96ab6 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -6,15 +6,26 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <asm/spinlock.h>
+
+extern void halt(int code);
+extern void putchar(int c);
+
+static struct spinlock uart_lock;
 
 void io_init(void)
 {
 }
 
-void puts(const char *s __unused)
+void puts(const char *s)
 {
+	spin_lock(&uart_lock);
+	while (*s)
+		putchar(*s++);
+	spin_unlock(&uart_lock);
 }
 
-void exit(int code __unused)
+void exit(int code)
 {
+	halt(code);
 }
diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
new file mode 100644
index 0000000000000..daabaca510cd4
--- /dev/null
+++ b/lib/ppc64/asm/hcall.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/hcall.h"
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 0c3eaba0d3aab..89610b525f0c1 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
 CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
+CFLAGS += -Wa,-mregnames
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include scripts/asm-offsets.mak
@@ -29,6 +30,7 @@ cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
 cflatobjs += lib/powerpc/io.o
+cflatobjs += lib/powerpc/hcall.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index f90828dee1c19..623fd693b02d1 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -7,13 +7,34 @@
  */
 #define __ASSEMBLY__
 
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis	reg,(expr)@highest;		\
+	ori	reg,reg,(expr)@higher;		\
+	rldicr	reg,reg,32,31;			\
+	oris	reg,reg,(expr)@h;		\
+	ori	reg,reg,(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)			\
+	ld	reg,name@got(r2)
+
 .section .init
 
 .globl start
 start:
+	LOAD_REG_IMMEDIATE(r1, stackptr)
+	LOAD_REG_IMMEDIATE(r2, tocptr)
+	bl	hcall_patch_broken_sc1
+	bl	main
+	bl	exit
 	b	halt
 
 .text
+.align 3
+
+.globl sc1
+sc1:
+	sc	1
+	blr
 
 .globl halt
 halt:
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Add broken sc1 detection and patching and an hcall for putchar,
to use in puts. That, along with a couple more lines in start to
prepare for C code, and a branch to main(), gets us "hello world".
Run with

qemu-system-ppc64 -M pseries            \
        -bios powerpc/boot_rom.bin      \
        -display none -serial stdio     \
        -kernel powerpc/selftest.elf

(We're still not relocating yet, that comes in a later patch. Thus,
 testing hello-world at this point requires a hacked QEMU and linking
 the unit test at QEMU's kernel load address.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
 lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/powerpc/io.c        | 15 ++++++++--
 lib/ppc64/asm/hcall.h   |  1 +
 powerpc/Makefile.common |  2 ++
 powerpc/cstart64.S      | 21 +++++++++++++
 6 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 lib/powerpc/asm/hcall.h
 create mode 100644 lib/powerpc/hcall.c
 create mode 100644 lib/ppc64/asm/hcall.h

diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
new file mode 100644
index 0000000000000..f861287ac2083
--- /dev/null
+++ b/lib/powerpc/asm/hcall.h
@@ -0,0 +1,46 @@
+#ifndef _ASMPOWERPC_HCALL_H_
+#define _ASMPOWERPC_HCALL_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.
+ */
+
+#define SC1			0x44000022
+#define SC1_REPLACEMENT		0x7c000268
+
+#define H_SUCCESS		0
+#define H_HARDWARE		-1
+#define H_FUNCTION		-2
+#define H_PRIVILEGE		-3
+#define H_PARAMETER		-4
+
+#define H_SET_DABR		0x28
+#define H_PUT_TERM_CHAR		0x58
+
+#ifndef __ASSEMBLY__
+#include <libcflat.h>
+
+/*
+ * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
+ * Returns true if we are.
+ */
+extern bool hcall_have_broken_sc1(void);
+
+/*
+ * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
+ * allowing all hypercalls built on it to work.
+ */
+extern void hcall_patch_broken_sc1(void);
+
+/*
+ * hcall is the hypercall wrapper function. unittests may do what
+ * they like, but the framework should make all hypercalls through
+ * here to ensure they use a working sc1 instruction, and properly
+ * handle clobbered registers. @nr is the hypercall number.
+ */
+extern unsigned long
+hcall(unsigned long nr, unsigned long *in, unsigned long *out);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMPOWERPC_HCALL_H_ */
diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
new file mode 100644
index 0000000000000..db99949352133
--- /dev/null
+++ b/lib/powerpc/hcall.c
@@ -0,0 +1,79 @@
+/*
+ * Hypercall helpers
+ *
+ * broken_sc1 probing/patching inspired by SLOF, see
+ *   SLOF:lib/libhvcall/brokensc1.c
+ *
+ * hcall() implementation inspired by Linux's epapr_hypercall, see
+ *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
+
+static u32 sc1[];
+
+bool hcall_have_broken_sc1(void)
+{
+	register unsigned long r3 asm("r3") = H_SET_DABR;
+	register unsigned long r4 asm("r4") = 0;
+
+	asm volatile("sc 1"
+	: "=r" (r3)
+	: "r" (r3), "r" (r4)
+	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
+
+	return r3 = (unsigned long)H_PRIVILEGE;
+}
+
+void hcall_patch_broken_sc1(void)
+{
+	if (!hcall_have_broken_sc1())
+		return;
+	sc1[0] = SC1_REPLACEMENT;
+}
+
+unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
+{
+	register unsigned long r3 asm("r3") = nr;
+	register unsigned long r4 asm("r4") = in[0];
+	register unsigned long r5 asm("r5") = in[1];
+	register unsigned long r6 asm("r6") = in[2];
+	register unsigned long r7 asm("r7") = in[3];
+	register unsigned long r8 asm("r8") = in[4];
+	register unsigned long r9 asm("r9") = in[5];
+	register unsigned long r10 asm("r10") = in[6];
+	register unsigned long r11 asm("r11") = in[7];
+
+	asm volatile("bl sc1"
+		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
+		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
+		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
+		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
+		: "r12", "memory", "lr");
+
+	out[0] = r4;
+	out[1] = r5;
+	out[2] = r6;
+	out[3] = r7;
+	out[4] = r8;
+	out[5] = r9;
+	out[6] = r10;
+	out[7] = r11;
+
+	return r3;
+}
+
+void putchar(int c)
+{
+	unsigned long in[8], out[8];
+
+	in[0] = 0; /* default vty */
+	in[1] = 1; /* just 1 byte */
+	in[2] = (unsigned long)c << 56;
+
+	hcall(H_PUT_TERM_CHAR, in, out);
+}
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index 0af45742fc900..5e1fa8dd96ab6 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -6,15 +6,26 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <asm/spinlock.h>
+
+extern void halt(int code);
+extern void putchar(int c);
+
+static struct spinlock uart_lock;
 
 void io_init(void)
 {
 }
 
-void puts(const char *s __unused)
+void puts(const char *s)
 {
+	spin_lock(&uart_lock);
+	while (*s)
+		putchar(*s++);
+	spin_unlock(&uart_lock);
 }
 
-void exit(int code __unused)
+void exit(int code)
 {
+	halt(code);
 }
diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
new file mode 100644
index 0000000000000..daabaca510cd4
--- /dev/null
+++ b/lib/ppc64/asm/hcall.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/hcall.h"
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 0c3eaba0d3aab..89610b525f0c1 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
 CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
+CFLAGS += -Wa,-mregnames
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include scripts/asm-offsets.mak
@@ -29,6 +30,7 @@ cflatobjs += lib/util.o
 cflatobjs += lib/alloc.o
 cflatobjs += lib/devicetree.o
 cflatobjs += lib/powerpc/io.o
+cflatobjs += lib/powerpc/hcall.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index f90828dee1c19..623fd693b02d1 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -7,13 +7,34 @@
  */
 #define __ASSEMBLY__
 
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis	reg,(expr)@highest;		\
+	ori	reg,reg,(expr)@higher;		\
+	rldicr	reg,reg,32,31;			\
+	oris	reg,reg,(expr)@h;		\
+	ori	reg,reg,(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)			\
+	ld	reg,name@got(r2)
+
 .section .init
 
 .globl start
 start:
+	LOAD_REG_IMMEDIATE(r1, stackptr)
+	LOAD_REG_IMMEDIATE(r2, tocptr)
+	bl	hcall_patch_broken_sc1
+	bl	main
+	bl	exit
 	b	halt
 
 .text
+.align 3
+
+.globl sc1
+sc1:
+	sc	1
+	blr
 
 .globl halt
 halt:
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

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 <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/setup.h |  36 +++++++++++++++
 lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ppc64/asm/setup.h   |   1 +
 powerpc/Makefile.common |   1 +
 powerpc/cstart64.S      |  16 +++++++
 powerpc/selftest.c      |  63 +++++++++++++++++++++++--
 6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
--- /dev/null
+++ b/lib/powerpc/asm/setup.h
@@ -0,0 +1,36 @@
+#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;
+
+#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
new file mode 100644
index 0000000000000..2514be4fa273c
--- /dev/null
+++ b/lib/powerpc/setup.c
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
+{
+	int cpu = nr_cpus++;
+
+	if (cpu >= NR_CPUS) {
+		printf("Number cpus exceeds maximum supported (%d).\n",
+			NR_CPUS);
+		assert(0);
+	}
+	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)
+{
+	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(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/Makefile.common b/powerpc/Makefile.common
index 89610b525f0c1..de4d1ef3ac816 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -31,6 +31,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)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 623fd693b02d1..6d47eb59bb53e 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -19,11 +19,27 @@
 
 .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)
+
 	bl	hcall_patch_broken_sc1
+
+	/* complete setup */
+	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();
 }
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

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 <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/setup.h |  36 +++++++++++++++
 lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ppc64/asm/setup.h   |   1 +
 powerpc/Makefile.common |   1 +
 powerpc/cstart64.S      |  16 +++++++
 powerpc/selftest.c      |  63 +++++++++++++++++++++++--
 6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
--- /dev/null
+++ b/lib/powerpc/asm/setup.h
@@ -0,0 +1,36 @@
+#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;
+
+#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
new file mode 100644
index 0000000000000..2514be4fa273c
--- /dev/null
+++ b/lib/powerpc/setup.c
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
+{
+	int cpu = nr_cpus++;
+
+	if (cpu >= NR_CPUS) {
+		printf("Number cpus exceeds maximum supported (%d).\n",
+			NR_CPUS);
+		assert(0);
+	}
+	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)
+{
+	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(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/Makefile.common b/powerpc/Makefile.common
index 89610b525f0c1..de4d1ef3ac816 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -31,6 +31,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)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 623fd693b02d1..6d47eb59bb53e 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -19,11 +19,27 @@
 
 .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)
+
 	bl	hcall_patch_broken_sc1
+
+	/* complete setup */
+	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();
 }
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 13/17] powerpc/ppc64: relocate linker VMAs
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

QEMU loads the unit test, but due to the way it translates the
unit test's linker VMA to the LMA, we can't just link such that
VMA == LMA. Thus, we link with VMA == 0x0, and then deal with
relocation.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 configure               |  2 ++
 powerpc/Makefile.common | 11 ++++++++--
 powerpc/Makefile.ppc64  |  1 +
 powerpc/cstart64.S      | 34 ++++++++++++++++++++++++++----
 powerpc/flat.lds        | 13 +++++++++++-
 powerpc/reloc64.c       | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 powerpc/reloc64.c

diff --git a/configure b/configure
index b367224093369..b2ad199da7873 100755
--- a/configure
+++ b/configure
@@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build
 cc=gcc
 ld=ld
 objcopy=objcopy
+objdump=objdump
 ar=ar
 arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
 host=$arch
@@ -132,6 +133,7 @@ PROCESSOR=$processor
 CC=$cross_prefix$cc
 LD=$cross_prefix$ld
 OBJCOPY=$cross_prefix$objcopy
+OBJDUMP=$cross_prefix$objdump
 AR=$cross_prefix$ar
 API=$api
 TEST_DIR=$testdir
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index de4d1ef3ac816..9654bce1752eb 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -22,6 +22,7 @@ CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 CFLAGS += -Wa,-mregnames
+CFLAGS += -fpie
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include scripts/asm-offsets.mak
@@ -37,11 +38,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
 
 FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
-%.elf: LDFLAGS = $(CFLAGS) -nostdlib
+%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie
 %.elf: %.o $(FLATLIBS) powerpc/flat.lds
 	$(CC) $(LDFLAGS) -o $@ \
 		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
+	@echo -n Checking $@ for unsupported reloc types...
+	@if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then	\
+		false;							\
+	else								\
+		echo " looks good.";					\
+	fi
 
 $(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
 	dd if=/dev/zero of=$@ bs=256 count=1
@@ -60,4 +67,4 @@ generated_files = $(asm-offsets)
 
 test_cases: $(generated_files) $(tests-common) $(tests)
 
-$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
+$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
index 95bf6772d65ed..e965627991916 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -8,6 +8,7 @@ ldarch = elf64-powerpc
 kernel_offset = 0x0
 
 cstart.o = $(TEST_DIR)/cstart64.o
+reloc.o  = $(TEST_DIR)/reloc64.o
 cflatobjs += lib/ppc64/spinlock.o
 
 # ppc64 specific tests
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 6d47eb59bb53e..d1a5531eb1c44 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -24,12 +24,33 @@
  */
 .globl start
 start:
-	LOAD_REG_IMMEDIATE(r1, stackptr)
-	LOAD_REG_IMMEDIATE(r2, tocptr)
+	/*
+	 * We were loaded at QEMU's kernel load address, but we're not
+	 * allowed to link there due to how QEMU deals with linker VMAs,
+	 * so we just linked at zero. This means the first thing to do is
+	 * to find our stack and toc, and then do a relocate.
+	 */
+	bl	0f
+0:	mflr	r31
+	subi	r31, r31, 0b - start    /* QEMU's kernel load address */
+	ld	r1, (p_stack - start)(r31)
+	ld	r2, (p_toc - start)(r31)
+	add	r1, r1, r31
+	add	r2, r2, r31
 
 	/* save DTB pointer */
 	std	r3, 56(r1)
 
+	/*
+	 * Call relocate. relocate is C code, but careful to not use
+	 * any global references, as they may use absolute addresses,
+	 * which are, obviously, not yet relocated.
+	 */
+	mr	r3, r31
+	ld	r4, (p_dyn - start)(r31)
+	add	r4, r4, r31
+	bl	relocate
+
 	bl	hcall_patch_broken_sc1
 
 	/* complete setup */
@@ -37,13 +58,18 @@ start:
 	bl	setup
 
 	/* run the test */
-	LOAD_REG_IMMEDIATE(r5, __argc)
-	LOAD_REG_IMMEDIATE(r4, __argv)
+	LOAD_REG_ADDR(r5, __argc)
+	LOAD_REG_ADDR(r4, __argv)
 	lwz	r3, 0(r5)
 	bl	main
 	bl	exit
 	b	halt
 
+.align 3
+p_stack:	.llong  stackptr
+p_toc:		.llong  tocptr
+p_dyn:		.llong  dynamic_start
+
 .text
 .align 3
 
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
index 84087057c0ce2..53221e8b4211c 100644
--- a/powerpc/flat.lds
+++ b/powerpc/flat.lds
@@ -6,11 +6,22 @@ SECTIONS
     etext = .;
     .opd : { *(.opd) }
     . = ALIGN(16);
+    .dynamic : {
+        dynamic_start = .;
+        *(.dynamic)
+    }
+    .dynsym : {
+        dynsym_start = .;
+        *(.dynsym)
+    }
+    .rela.dyn : { *(.rela*) }
+    . = ALIGN(16);
     .data : {
         *(.data)
+        *(.data.rel*)
     }
     . = ALIGN(16);
-    .rodata : { *(.rodata) }
+    .rodata : { *(.rodata) *(.rodata.*) }
     . = ALIGN(16);
     .bss : { *(.bss) }
     . = ALIGN(256);
diff --git a/powerpc/reloc64.c b/powerpc/reloc64.c
new file mode 100644
index 0000000000000..d919372bf9288
--- /dev/null
+++ b/powerpc/reloc64.c
@@ -0,0 +1,55 @@
+/*
+ * relocate R_PPC_RELATIVE RELA entries. Normally this is done in
+ * assembly code to avoid the risk of using absolute addresses before
+ * they're relocated. We use C, but cautiously (no global references).
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#define DT_NULL		0
+#define DT_RELA 	7
+#define DT_RELACOUNT	0x6ffffff9
+#define R_PPC_RELATIVE	22
+
+struct elf64_dyn {
+	signed long long tag;
+	unsigned long long val;
+};
+
+#define RELA_GET_TYPE(rela_ptr) ((rela_ptr)->info & 0xffffffff)
+struct elf64_rela {
+	unsigned long long offset;
+	unsigned long long info;
+	signed long long addend;
+};
+
+void relocate(unsigned long load_addr, struct elf64_dyn *dyn_table)
+{
+	unsigned long long rela_addr = 0, rela_count = 0, *addr;
+	struct elf64_dyn *d = dyn_table;
+	struct elf64_rela *r;
+
+	while (d && d->tag != DT_NULL) {
+		if (d->tag == DT_RELA)
+			rela_addr = d->val;
+		else if (d->tag == DT_RELACOUNT)
+			rela_count = d->val;
+		if (rela_addr && rela_count)
+			break;
+		++d;
+	}
+
+	if (!rela_addr || !rela_count)
+		return;
+
+	r = (void *)(rela_addr + load_addr);
+
+	while (rela_count--) {
+		if (RELA_GET_TYPE(r) == R_PPC_RELATIVE) {
+			addr = (void *)(r->offset + load_addr);
+			*addr = r->addend + load_addr;
+		}
+		++r;
+	}
+}
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 13/17] powerpc/ppc64: relocate linker VMAs
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

QEMU loads the unit test, but due to the way it translates the
unit test's linker VMA to the LMA, we can't just link such that
VMA = LMA. Thus, we link with VMA = 0x0, and then deal with
relocation.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 configure               |  2 ++
 powerpc/Makefile.common | 11 ++++++++--
 powerpc/Makefile.ppc64  |  1 +
 powerpc/cstart64.S      | 34 ++++++++++++++++++++++++++----
 powerpc/flat.lds        | 13 +++++++++++-
 powerpc/reloc64.c       | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 109 insertions(+), 7 deletions(-)
 create mode 100644 powerpc/reloc64.c

diff --git a/configure b/configure
index b367224093369..b2ad199da7873 100755
--- a/configure
+++ b/configure
@@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build
 cc=gcc
 ld=ld
 objcopy=objcopy
+objdump=objdump
 ar=ar
 arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
 host=$arch
@@ -132,6 +133,7 @@ PROCESSOR=$processor
 CC=$cross_prefix$cc
 LD=$cross_prefix$ld
 OBJCOPY=$cross_prefix$objcopy
+OBJDUMP=$cross_prefix$objdump
 AR=$cross_prefix$ar
 API=$api
 TEST_DIR=$testdir
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index de4d1ef3ac816..9654bce1752eb 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -22,6 +22,7 @@ CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 CFLAGS += -Wa,-mregnames
+CFLAGS += -fpie
 
 asm-offsets = lib/$(ARCH)/asm-offsets.h
 include scripts/asm-offsets.mak
@@ -37,11 +38,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
 
 FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
-%.elf: LDFLAGS = $(CFLAGS) -nostdlib
+%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie
 %.elf: %.o $(FLATLIBS) powerpc/flat.lds
 	$(CC) $(LDFLAGS) -o $@ \
 		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
 		$(filter %.o, $^) $(FLATLIBS)
+	@echo -n Checking $@ for unsupported reloc types...
+	@if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then	\
+		false;							\
+	else								\
+		echo " looks good.";					\
+	fi
 
 $(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
 	dd if=/dev/zero of=$@ bs%6 count=1
@@ -60,4 +67,4 @@ generated_files = $(asm-offsets)
 
 test_cases: $(generated_files) $(tests-common) $(tests)
 
-$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
+$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o
diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
index 95bf6772d65ed..e965627991916 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -8,6 +8,7 @@ ldarch = elf64-powerpc
 kernel_offset = 0x0
 
 cstart.o = $(TEST_DIR)/cstart64.o
+reloc.o  = $(TEST_DIR)/reloc64.o
 cflatobjs += lib/ppc64/spinlock.o
 
 # ppc64 specific tests
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 6d47eb59bb53e..d1a5531eb1c44 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -24,12 +24,33 @@
  */
 .globl start
 start:
-	LOAD_REG_IMMEDIATE(r1, stackptr)
-	LOAD_REG_IMMEDIATE(r2, tocptr)
+	/*
+	 * We were loaded at QEMU's kernel load address, but we're not
+	 * allowed to link there due to how QEMU deals with linker VMAs,
+	 * so we just linked at zero. This means the first thing to do is
+	 * to find our stack and toc, and then do a relocate.
+	 */
+	bl	0f
+0:	mflr	r31
+	subi	r31, r31, 0b - start    /* QEMU's kernel load address */
+	ld	r1, (p_stack - start)(r31)
+	ld	r2, (p_toc - start)(r31)
+	add	r1, r1, r31
+	add	r2, r2, r31
 
 	/* save DTB pointer */
 	std	r3, 56(r1)
 
+	/*
+	 * Call relocate. relocate is C code, but careful to not use
+	 * any global references, as they may use absolute addresses,
+	 * which are, obviously, not yet relocated.
+	 */
+	mr	r3, r31
+	ld	r4, (p_dyn - start)(r31)
+	add	r4, r4, r31
+	bl	relocate
+
 	bl	hcall_patch_broken_sc1
 
 	/* complete setup */
@@ -37,13 +58,18 @@ start:
 	bl	setup
 
 	/* run the test */
-	LOAD_REG_IMMEDIATE(r5, __argc)
-	LOAD_REG_IMMEDIATE(r4, __argv)
+	LOAD_REG_ADDR(r5, __argc)
+	LOAD_REG_ADDR(r4, __argv)
 	lwz	r3, 0(r5)
 	bl	main
 	bl	exit
 	b	halt
 
+.align 3
+p_stack:	.llong  stackptr
+p_toc:		.llong  tocptr
+p_dyn:		.llong  dynamic_start
+
 .text
 .align 3
 
diff --git a/powerpc/flat.lds b/powerpc/flat.lds
index 84087057c0ce2..53221e8b4211c 100644
--- a/powerpc/flat.lds
+++ b/powerpc/flat.lds
@@ -6,11 +6,22 @@ SECTIONS
     etext = .;
     .opd : { *(.opd) }
     . = ALIGN(16);
+    .dynamic : {
+        dynamic_start = .;
+        *(.dynamic)
+    }
+    .dynsym : {
+        dynsym_start = .;
+        *(.dynsym)
+    }
+    .rela.dyn : { *(.rela*) }
+    . = ALIGN(16);
     .data : {
         *(.data)
+        *(.data.rel*)
     }
     . = ALIGN(16);
-    .rodata : { *(.rodata) }
+    .rodata : { *(.rodata) *(.rodata.*) }
     . = ALIGN(16);
     .bss : { *(.bss) }
     . = ALIGN(256);
diff --git a/powerpc/reloc64.c b/powerpc/reloc64.c
new file mode 100644
index 0000000000000..d919372bf9288
--- /dev/null
+++ b/powerpc/reloc64.c
@@ -0,0 +1,55 @@
+/*
+ * relocate R_PPC_RELATIVE RELA entries. Normally this is done in
+ * assembly code to avoid the risk of using absolute addresses before
+ * they're relocated. We use C, but cautiously (no global references).
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#define DT_NULL		0
+#define DT_RELA 	7
+#define DT_RELACOUNT	0x6ffffff9
+#define R_PPC_RELATIVE	22
+
+struct elf64_dyn {
+	signed long long tag;
+	unsigned long long val;
+};
+
+#define RELA_GET_TYPE(rela_ptr) ((rela_ptr)->info & 0xffffffff)
+struct elf64_rela {
+	unsigned long long offset;
+	unsigned long long info;
+	signed long long addend;
+};
+
+void relocate(unsigned long load_addr, struct elf64_dyn *dyn_table)
+{
+	unsigned long long rela_addr = 0, rela_count = 0, *addr;
+	struct elf64_dyn *d = dyn_table;
+	struct elf64_rela *r;
+
+	while (d && d->tag != DT_NULL) {
+		if (d->tag = DT_RELA)
+			rela_addr = d->val;
+		else if (d->tag = DT_RELACOUNT)
+			rela_count = d->val;
+		if (rela_addr && rela_count)
+			break;
+		++d;
+	}
+
+	if (!rela_addr || !rela_count)
+		return;
+
+	r = (void *)(rela_addr + load_addr);
+
+	while (rela_count--) {
+		if (RELA_GET_TYPE(r) = R_PPC_RELATIVE) {
+			addr = (void *)(r->offset + load_addr);
+			*addr = r->addend + load_addr;
+		}
+		++r;
+	}
+}
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 14/17] powerpc/ppc64: add run script and unittests.cfg
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Now that we have all the pieces, pull them together into a
run script (adapted from arm's). To run a test do './powerpc-run
powerpc/test.elf'. To run all tests in unittests.cfg do
'./run_tests.sh'

(We can now run simple unit tests, but they don't quit on their
 own yet. Use ^C to quit them.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/run           | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 powerpc/unittests.cfg | 30 +++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100755 powerpc/run
 create mode 100644 powerpc/unittests.cfg

diff --git a/powerpc/run b/powerpc/run
new file mode 100755
index 0000000000000..47aecb7600832
--- /dev/null
+++ b/powerpc/run
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+if [ -z "$STANDALONE" ]; then
+	if [ ! -f config.mak ]; then
+		echo "run ./configure && make first. See ./configure -h"
+		exit 2
+	fi
+	source config.mak
+fi
+
+if [ -c /dev/kvm ]; then
+	if [ "$HOST" = "ppc64" ] && [ "$ARCH" = "ppc64" ]; then
+		kvm_available=yes
+	fi
+fi
+
+if [ "$ACCEL" = "kvm" ] && [ "$kvm_available" != "yes" ]; then
+	echo "skip $TESTNAME (kvm only)"
+	exit 2
+fi
+
+if [ -z "$ACCEL" ]; then
+	if [ "$kvm_available" = "yes" ]; then
+		ACCEL="kvm"
+	else
+		ACCEL="tcg"
+	fi
+fi
+
+qemu="${QEMU:-qemu-system-$ARCH_NAME}"
+qpath=$(which $qemu 2>/dev/null)
+
+if [ -z "$qpath" ]; then
+	echo $qemu not found.
+	exit 2
+fi
+
+if ! $qemu -machine '?' 2>&1 | grep 'pseries' > /dev/null; then
+	echo "$qpath doesn't support pSeries ('-machine pseries'). Exiting."
+	exit 2
+fi
+
+M='-machine pseries'
+M+=",accel=$ACCEL"
+command="$qemu $M -bios powerpc/boot_rom.bin"
+command+=" -display none -serial stdio -kernel"
+echo $command "$@"
+
+$command "$@"
+ret=$?
+echo Return value from qemu: $ret
+exit $ret
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
new file mode 100644
index 0000000000000..60f9be80e8abf
--- /dev/null
+++ b/powerpc/unittests.cfg
@@ -0,0 +1,30 @@
+##############################################################################
+# unittest configuration
+#
+# [unittest_name]
+# file = <name>.flat		# Name of the flat file to be used.
+# smp  = <num>			# Number of processors the VM will use
+#				# during this test. Use $MAX_SMP to use
+#				# the maximum the host supports. Defaults
+#				# to one.
+# extra_params = -append <params...>	# Additional parameters used.
+# arch = ppc64				# Select one if the test case is
+#					# specific to only one.
+# groups = <group_name1> <group_name2> ...	# Used to identify test cases
+#						# with run_tests -g ...
+# accel = kvm|tcg		# Optionally specify if test must run with
+#				# kvm or tcg. If not specified, then kvm will
+#				# be used when available.
+# timeout = <duration>		# Optionally specify a timeout.
+##############################################################################
+
+#
+# Test that the configured number of processors (smp = <num>), and
+# that the configured amount of memory (-m <MB>) are correctly setup
+# by the framework.
+#
+[selftest-setup]
+file = selftest.elf
+smp = 2
+extra_params = -m 256 -append 'setup smp=2 mem=256'
+groups = selftest
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 14/17] powerpc/ppc64: add run script and unittests.cfg
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Now that we have all the pieces, pull them together into a
run script (adapted from arm's). To run a test do './powerpc-run
powerpc/test.elf'. To run all tests in unittests.cfg do
'./run_tests.sh'

(We can now run simple unit tests, but they don't quit on their
 own yet. Use ^C to quit them.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 powerpc/run           | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 powerpc/unittests.cfg | 30 +++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100755 powerpc/run
 create mode 100644 powerpc/unittests.cfg

diff --git a/powerpc/run b/powerpc/run
new file mode 100755
index 0000000000000..47aecb7600832
--- /dev/null
+++ b/powerpc/run
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+if [ -z "$STANDALONE" ]; then
+	if [ ! -f config.mak ]; then
+		echo "run ./configure && make first. See ./configure -h"
+		exit 2
+	fi
+	source config.mak
+fi
+
+if [ -c /dev/kvm ]; then
+	if [ "$HOST" = "ppc64" ] && [ "$ARCH" = "ppc64" ]; then
+		kvm_available=yes
+	fi
+fi
+
+if [ "$ACCEL" = "kvm" ] && [ "$kvm_available" != "yes" ]; then
+	echo "skip $TESTNAME (kvm only)"
+	exit 2
+fi
+
+if [ -z "$ACCEL" ]; then
+	if [ "$kvm_available" = "yes" ]; then
+		ACCEL="kvm"
+	else
+		ACCEL="tcg"
+	fi
+fi
+
+qemu="${QEMU:-qemu-system-$ARCH_NAME}"
+qpath=$(which $qemu 2>/dev/null)
+
+if [ -z "$qpath" ]; then
+	echo $qemu not found.
+	exit 2
+fi
+
+if ! $qemu -machine '?' 2>&1 | grep 'pseries' > /dev/null; then
+	echo "$qpath doesn't support pSeries ('-machine pseries'). Exiting."
+	exit 2
+fi
+
+M='-machine pseries'
+M+=",accel=$ACCEL"
+command="$qemu $M -bios powerpc/boot_rom.bin"
+command+=" -display none -serial stdio -kernel"
+echo $command "$@"
+
+$command "$@"
+ret=$?
+echo Return value from qemu: $ret
+exit $ret
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
new file mode 100644
index 0000000000000..60f9be80e8abf
--- /dev/null
+++ b/powerpc/unittests.cfg
@@ -0,0 +1,30 @@
+##############################################################################
+# unittest configuration
+#
+# [unittest_name]
+# file = <name>.flat		# Name of the flat file to be used.
+# smp  = <num>			# Number of processors the VM will use
+#				# during this test. Use $MAX_SMP to use
+#				# the maximum the host supports. Defaults
+#				# to one.
+# extra_params = -append <params...>	# Additional parameters used.
+# arch = ppc64				# Select one if the test case is
+#					# specific to only one.
+# groups = <group_name1> <group_name2> ...	# Used to identify test cases
+#						# with run_tests -g ...
+# accel = kvm|tcg		# Optionally specify if test must run with
+#				# kvm or tcg. If not specified, then kvm will
+#				# be used when available.
+# timeout = <duration>		# Optionally specify a timeout.
+##############################################################################
+
+#
+# Test that the configured number of processors (smp = <num>), and
+# that the configured amount of memory (-m <MB>) are correctly setup
+# by the framework.
+#
+[selftest-setup]
+file = selftest.elf
+smp = 2
+extra_params = -m 256 -append 'setup smp=2 mem%6'
+groups = selftest
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 15/17] mkstandalone: add support for powerpc
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

PowerPC needs firmware.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 configure               | 2 ++
 powerpc/run             | 2 +-
 scripts/mkstandalone.sh | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index b2ad199da7873..7d5702e28d627 100755
--- a/configure
+++ b/configure
@@ -83,6 +83,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
     testdir=arm
 elif [ "$arch" = "ppc64" ]; then
     testdir=powerpc
+    firmware="$testdir/boot_rom.bin"
 else
     testdir=$arch
 fi
@@ -137,4 +138,5 @@ OBJDUMP=$cross_prefix$objdump
 AR=$cross_prefix$ar
 API=$api
 TEST_DIR=$testdir
+FIRMWARE=$firmware
 EOF
diff --git a/powerpc/run b/powerpc/run
index 47aecb7600832..c5108100fc5e0 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -42,7 +42,7 @@ fi
 
 M='-machine pseries'
 M+=",accel=$ACCEL"
-command="$qemu $M -bios powerpc/boot_rom.bin"
+command="$qemu $M -bios $FIRMWARE"
 command+=" -display none -serial stdio -kernel"
 echo $command "$@"
 
diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh
index b0f1e7c098afb..1788a8ef4e92a 100755
--- a/scripts/mkstandalone.sh
+++ b/scripts/mkstandalone.sh
@@ -51,6 +51,11 @@ generate_test ()
 		return 1
 	fi
 
+	if [ "$FIRMWARE" ]; then
+		temp_file firmware "$FIRMWARE"
+		echo 'export FIRMWARE=$firmware'
+	fi
+
 	echo "trap 'rm -f \$cleanup' EXIT"
 
 	temp_file bin "$kernel"
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 15/17] mkstandalone: add support for powerpc
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

PowerPC needs firmware.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 configure               | 2 ++
 powerpc/run             | 2 +-
 scripts/mkstandalone.sh | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index b2ad199da7873..7d5702e28d627 100755
--- a/configure
+++ b/configure
@@ -83,6 +83,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
     testdir=arm
 elif [ "$arch" = "ppc64" ]; then
     testdir=powerpc
+    firmware="$testdir/boot_rom.bin"
 else
     testdir=$arch
 fi
@@ -137,4 +138,5 @@ OBJDUMP=$cross_prefix$objdump
 AR=$cross_prefix$ar
 API=$api
 TEST_DIR=$testdir
+FIRMWARE=$firmware
 EOF
diff --git a/powerpc/run b/powerpc/run
index 47aecb7600832..c5108100fc5e0 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -42,7 +42,7 @@ fi
 
 M='-machine pseries'
 M+=",accel=$ACCEL"
-command="$qemu $M -bios powerpc/boot_rom.bin"
+command="$qemu $M -bios $FIRMWARE"
 command+=" -display none -serial stdio -kernel"
 echo $command "$@"
 
diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh
index b0f1e7c098afb..1788a8ef4e92a 100755
--- a/scripts/mkstandalone.sh
+++ b/scripts/mkstandalone.sh
@@ -51,6 +51,11 @@ generate_test ()
 		return 1
 	fi
 
+	if [ "$FIRMWARE" ]; then
+		temp_file firmware "$FIRMWARE"
+		echo 'export FIRMWARE=$firmware'
+	fi
+
 	echo "trap 'rm -f \$cleanup' EXIT"
 
 	temp_file bin "$kernel"
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 16/17] powerpc/ppc64: add RTAS support
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Add enough RTAS support to start adding RTAS commands. Just add
power-off for now.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/rtas.h  |  26 +++++++++
 lib/powerpc/io.c        |   2 +
 lib/powerpc/rtas.c      | 139 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ppc64/asm/rtas.h    |   1 +
 powerpc/Makefile.common |   1 +
 5 files changed, 169 insertions(+)
 create mode 100644 lib/powerpc/asm/rtas.h
 create mode 100644 lib/powerpc/rtas.c
 create mode 100644 lib/ppc64/asm/rtas.h

diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
new file mode 100644
index 0000000000000..522225bcb6de3
--- /dev/null
+++ b/lib/powerpc/asm/rtas.h
@@ -0,0 +1,26 @@
+#ifndef _ASMPOWERPC_RTAS_H_
+#define _ASMPOWERPC_RTAS_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>
+
+#define RTAS_UNKNOWN_SERVICE	(-1)
+
+struct rtas_args {
+	u32 token;
+	u32 nargs;
+	u32 nret;
+	u32 args[16];
+	u32 *rets;
+};
+
+extern void rtas_init(void);
+extern int rtas_token(const char *service);
+extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
+
+extern void rtas_power_off(void);
+
+#endif /* _ASMPOWERPC_RTAS_H_ */
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index 5e1fa8dd96ab6..e57a28c583eb0 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -7,6 +7,7 @@
  */
 #include <libcflat.h>
 #include <asm/spinlock.h>
+#include <asm/rtas.h>
 
 extern void halt(int code);
 extern void putchar(int c);
@@ -15,6 +16,7 @@ static struct spinlock uart_lock;
 
 void io_init(void)
 {
+	rtas_init();
 }
 
 void puts(const char *s)
diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
new file mode 100644
index 0000000000000..c51c52c734b38
--- /dev/null
+++ b/lib/powerpc/rtas.c
@@ -0,0 +1,139 @@
+/*
+ * powerpc RTAS
+ *
+ * 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 <asm/spinlock.h>
+#include <asm/hcall.h>
+#include <asm/io.h>
+#include <asm/rtas.h>
+
+#if defined(__powerpc64__)
+struct func_ptr {
+	unsigned long ptr;
+	unsigned long toc;
+};
+static struct func_ptr rtas_entry_funcptr;
+#endif
+typedef void (*rtas_entry_t)(unsigned long);
+static rtas_entry_t enter_rtas;
+static struct rtas_args rtas_args;
+static struct spinlock rtas_lock;
+
+static int rtas_node(void)
+{
+	int node = fdt_path_offset(dt_fdt(), "/rtas");
+
+	if (node < 0) {
+		printf("%s: /rtas: %s\n", __func__, fdt_strerror(node));
+		abort();
+	}
+
+	return node;
+}
+
+void rtas_init(void)
+{
+	const struct fdt_property *prop;
+	int node = rtas_node(), len;
+	unsigned long entry;
+	u32 *data;
+
+	if (!dt_available()) {
+		printf("%s: No device tree!\n", __func__);
+		abort();
+	}
+
+	prop = fdt_get_property(dt_fdt(), node,
+				"linux,rtas-entry", &len);
+	if (!prop) {
+		printf("%s: /rtas/linux,rtas-entry: %s\n",
+				__func__, fdt_strerror(len));
+		abort();
+	}
+
+	data = (u32 *)prop->data;
+	entry = (unsigned long)fdt32_to_cpu(*data);
+
+	if (hcall_have_broken_sc1()) {
+		u32 *insn = (u32 *)entry;
+		int size, i;
+
+		prop = fdt_get_property(dt_fdt(), node,
+					"rtas-size", &len);
+		if (!prop) {
+			printf("%s: /rtas/rtas-size: %s\n",
+					__func__, fdt_strerror(len));
+			abort();
+		}
+		data = (u32 *)prop->data;
+		size = (int)fdt32_to_cpu(*data);
+
+		for (i = 0; i < size/4; ++i)
+			if (insn[i] == SC1)
+				insn[i] = SC1_REPLACEMENT;
+	}
+
+#if defined(__powerpc64__)
+	rtas_entry_funcptr.ptr = entry;
+	enter_rtas = (rtas_entry_t)&rtas_entry_funcptr;
+#else
+	enter_rtas = (rtas_entry_t)entry;
+#endif
+}
+
+int rtas_token(const char *service)
+{
+	const struct fdt_property *prop;
+	u32 *token;
+
+	prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
+	if (prop) {
+		token = (u32 *)prop->data;
+		return fdt32_to_cpu(*token);
+	}
+	return RTAS_UNKNOWN_SERVICE;
+}
+
+int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+{
+	va_list list;
+	int ret, i;
+
+	spin_lock(&rtas_lock);
+
+	rtas_args.token = cpu_to_be32(token);
+	rtas_args.nargs = cpu_to_be32(nargs);
+	rtas_args.nret = cpu_to_be32(nret);
+	rtas_args.rets = &rtas_args.args[nargs];
+
+	va_start(list, outputs);
+	for (i = 0; i < nargs; ++i)
+		rtas_args.args[i] = cpu_to_be32(va_arg(list, u32));
+	va_end(list);
+
+	for (i = 0; i < nret; ++i)
+		rtas_args.rets[i] = 0;
+
+	enter_rtas(__pa(&rtas_args));
+
+	if (nret > 1 && outputs != NULL)
+		for (i = 0; i < nret - 1; ++i)
+			outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]);
+
+	ret = nret > 0 ? be32_to_cpu(rtas_args.rets[0]) : 0;
+
+	spin_unlock(&rtas_lock);
+	return ret;
+}
+
+void rtas_power_off(void)
+{
+	int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
+	printf("RTAS power-off returned %d\n", ret);
+}
diff --git a/lib/ppc64/asm/rtas.h b/lib/ppc64/asm/rtas.h
new file mode 100644
index 0000000000000..fe77f635cd860
--- /dev/null
+++ b/lib/ppc64/asm/rtas.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/rtas.h"
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 9654bce1752eb..3a03ab6dfc3e9 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -33,6 +33,7 @@ cflatobjs += lib/devicetree.o
 cflatobjs += lib/powerpc/io.o
 cflatobjs += lib/powerpc/hcall.o
 cflatobjs += lib/powerpc/setup.o
+cflatobjs += lib/powerpc/rtas.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 16/17] powerpc/ppc64: add RTAS support
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

Add enough RTAS support to start adding RTAS commands. Just add
power-off for now.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/asm/rtas.h  |  26 +++++++++
 lib/powerpc/io.c        |   2 +
 lib/powerpc/rtas.c      | 139 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ppc64/asm/rtas.h    |   1 +
 powerpc/Makefile.common |   1 +
 5 files changed, 169 insertions(+)
 create mode 100644 lib/powerpc/asm/rtas.h
 create mode 100644 lib/powerpc/rtas.c
 create mode 100644 lib/ppc64/asm/rtas.h

diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h
new file mode 100644
index 0000000000000..522225bcb6de3
--- /dev/null
+++ b/lib/powerpc/asm/rtas.h
@@ -0,0 +1,26 @@
+#ifndef _ASMPOWERPC_RTAS_H_
+#define _ASMPOWERPC_RTAS_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>
+
+#define RTAS_UNKNOWN_SERVICE	(-1)
+
+struct rtas_args {
+	u32 token;
+	u32 nargs;
+	u32 nret;
+	u32 args[16];
+	u32 *rets;
+};
+
+extern void rtas_init(void);
+extern int rtas_token(const char *service);
+extern int rtas_call(int token, int nargs, int nret, int *outputs, ...);
+
+extern void rtas_power_off(void);
+
+#endif /* _ASMPOWERPC_RTAS_H_ */
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index 5e1fa8dd96ab6..e57a28c583eb0 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -7,6 +7,7 @@
  */
 #include <libcflat.h>
 #include <asm/spinlock.h>
+#include <asm/rtas.h>
 
 extern void halt(int code);
 extern void putchar(int c);
@@ -15,6 +16,7 @@ static struct spinlock uart_lock;
 
 void io_init(void)
 {
+	rtas_init();
 }
 
 void puts(const char *s)
diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c
new file mode 100644
index 0000000000000..c51c52c734b38
--- /dev/null
+++ b/lib/powerpc/rtas.c
@@ -0,0 +1,139 @@
+/*
+ * powerpc RTAS
+ *
+ * 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 <asm/spinlock.h>
+#include <asm/hcall.h>
+#include <asm/io.h>
+#include <asm/rtas.h>
+
+#if defined(__powerpc64__)
+struct func_ptr {
+	unsigned long ptr;
+	unsigned long toc;
+};
+static struct func_ptr rtas_entry_funcptr;
+#endif
+typedef void (*rtas_entry_t)(unsigned long);
+static rtas_entry_t enter_rtas;
+static struct rtas_args rtas_args;
+static struct spinlock rtas_lock;
+
+static int rtas_node(void)
+{
+	int node = fdt_path_offset(dt_fdt(), "/rtas");
+
+	if (node < 0) {
+		printf("%s: /rtas: %s\n", __func__, fdt_strerror(node));
+		abort();
+	}
+
+	return node;
+}
+
+void rtas_init(void)
+{
+	const struct fdt_property *prop;
+	int node = rtas_node(), len;
+	unsigned long entry;
+	u32 *data;
+
+	if (!dt_available()) {
+		printf("%s: No device tree!\n", __func__);
+		abort();
+	}
+
+	prop = fdt_get_property(dt_fdt(), node,
+				"linux,rtas-entry", &len);
+	if (!prop) {
+		printf("%s: /rtas/linux,rtas-entry: %s\n",
+				__func__, fdt_strerror(len));
+		abort();
+	}
+
+	data = (u32 *)prop->data;
+	entry = (unsigned long)fdt32_to_cpu(*data);
+
+	if (hcall_have_broken_sc1()) {
+		u32 *insn = (u32 *)entry;
+		int size, i;
+
+		prop = fdt_get_property(dt_fdt(), node,
+					"rtas-size", &len);
+		if (!prop) {
+			printf("%s: /rtas/rtas-size: %s\n",
+					__func__, fdt_strerror(len));
+			abort();
+		}
+		data = (u32 *)prop->data;
+		size = (int)fdt32_to_cpu(*data);
+
+		for (i = 0; i < size/4; ++i)
+			if (insn[i] = SC1)
+				insn[i] = SC1_REPLACEMENT;
+	}
+
+#if defined(__powerpc64__)
+	rtas_entry_funcptr.ptr = entry;
+	enter_rtas = (rtas_entry_t)&rtas_entry_funcptr;
+#else
+	enter_rtas = (rtas_entry_t)entry;
+#endif
+}
+
+int rtas_token(const char *service)
+{
+	const struct fdt_property *prop;
+	u32 *token;
+
+	prop = fdt_get_property(dt_fdt(), rtas_node(), service, NULL);
+	if (prop) {
+		token = (u32 *)prop->data;
+		return fdt32_to_cpu(*token);
+	}
+	return RTAS_UNKNOWN_SERVICE;
+}
+
+int rtas_call(int token, int nargs, int nret, int *outputs, ...)
+{
+	va_list list;
+	int ret, i;
+
+	spin_lock(&rtas_lock);
+
+	rtas_args.token = cpu_to_be32(token);
+	rtas_args.nargs = cpu_to_be32(nargs);
+	rtas_args.nret = cpu_to_be32(nret);
+	rtas_args.rets = &rtas_args.args[nargs];
+
+	va_start(list, outputs);
+	for (i = 0; i < nargs; ++i)
+		rtas_args.args[i] = cpu_to_be32(va_arg(list, u32));
+	va_end(list);
+
+	for (i = 0; i < nret; ++i)
+		rtas_args.rets[i] = 0;
+
+	enter_rtas(__pa(&rtas_args));
+
+	if (nret > 1 && outputs != NULL)
+		for (i = 0; i < nret - 1; ++i)
+			outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]);
+
+	ret = nret > 0 ? be32_to_cpu(rtas_args.rets[0]) : 0;
+
+	spin_unlock(&rtas_lock);
+	return ret;
+}
+
+void rtas_power_off(void)
+{
+	int ret = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
+	printf("RTAS power-off returned %d\n", ret);
+}
diff --git a/lib/ppc64/asm/rtas.h b/lib/ppc64/asm/rtas.h
new file mode 100644
index 0000000000000..fe77f635cd860
--- /dev/null
+++ b/lib/ppc64/asm/rtas.h
@@ -0,0 +1 @@
+#include "../../powerpc/asm/rtas.h"
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index 9654bce1752eb..3a03ab6dfc3e9 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -33,6 +33,7 @@ cflatobjs += lib/devicetree.o
 cflatobjs += lib/powerpc/io.o
 cflatobjs += lib/powerpc/hcall.o
 cflatobjs += lib/powerpc/setup.o
+cflatobjs += lib/powerpc/rtas.o
 
 libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
 start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 17/17] powerpc/ppc64: make a fake debug-exit
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-15 13:49   ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

We should use a QEMU debug-exit device like chr-testdev, but for
now we just fake things by outputting the exit code (which we
parse later) and quitting with RTAS (which always exits with zero).

(When we've got a real debug-exit working, then this patch can
 be reverted.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/io.c | 4 ++++
 powerpc/run      | 7 +++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index e57a28c583eb0..ba90a08650b9d 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -29,5 +29,9 @@ void puts(const char *s)
 
 void exit(int code)
 {
+// FIXME: change this print-exit/rtas-poweroff to chr_testdev_exit(),
+//        maybe by plugging chr-testdev into a spapr-vty.
+	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+	rtas_power_off();
 	halt(code);
 }
diff --git a/powerpc/run b/powerpc/run
index c5108100fc5e0..45492a1cb8afc 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -46,7 +46,10 @@ command="$qemu $M -bios $FIRMWARE"
 command+=" -display none -serial stdio -kernel"
 echo $command "$@"
 
-$command "$@"
-ret=$?
+#FIXME: rtas-poweroff always exits with zero, so we have to parse
+#       the true exit code from the output.
+lines=$($command "$@")
+echo "$lines"
+ret=$(grep '^EXIT: ' <<<"$lines" | sed 's/.*STATUS=\([0-9][0-9]*\).*/\1/')
 echo Return value from qemu: $ret
 exit $ret
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [kvm-unit-tests PATCH v4 17/17] powerpc/ppc64: make a fake debug-exit
@ 2016-02-15 13:49   ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-15 13:49 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini

We should use a QEMU debug-exit device like chr-testdev, but for
now we just fake things by outputting the exit code (which we
parse later) and quitting with RTAS (which always exits with zero).

(When we've got a real debug-exit working, then this patch can
 be reverted.)

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
---
 lib/powerpc/io.c | 4 ++++
 powerpc/run      | 7 +++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
index e57a28c583eb0..ba90a08650b9d 100644
--- a/lib/powerpc/io.c
+++ b/lib/powerpc/io.c
@@ -29,5 +29,9 @@ void puts(const char *s)
 
 void exit(int code)
 {
+// FIXME: change this print-exit/rtas-poweroff to chr_testdev_exit(),
+//        maybe by plugging chr-testdev into a spapr-vty.
+	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+	rtas_power_off();
 	halt(code);
 }
diff --git a/powerpc/run b/powerpc/run
index c5108100fc5e0..45492a1cb8afc 100755
--- a/powerpc/run
+++ b/powerpc/run
@@ -46,7 +46,10 @@ command="$qemu $M -bios $FIRMWARE"
 command+=" -display none -serial stdio -kernel"
 echo $command "$@"
 
-$command "$@"
-ret=$?
+#FIXME: rtas-poweroff always exits with zero, so we have to parse
+#       the true exit code from the output.
+lines=$($command "$@")
+echo "$lines"
+ret=$(grep '^EXIT: ' <<<"$lines" | sed 's/.*STATUS=\([0-9][0-9]*\).*/\1/')
 echo Return value from qemu: $ret
 exit $ret
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 04/17] devicetree: fix dt_get_memory_params
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-16  6:11     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-16  6:11 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 635 bytes --]

On Mon, Feb 15, 2016 at 02:49:13PM +0100, Andrew Jones wrote:
> Index nr was overreaching with its indexing. It should only
> index the caller's regs array. We need a different index for
> the memory nodes' reg properties.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 04/17] devicetree: fix dt_get_memory_params
@ 2016-02-16  6:11     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-16  6:11 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 635 bytes --]

On Mon, Feb 15, 2016 at 02:49:13PM +0100, Andrew Jones wrote:
> Index nr was overreaching with its indexing. It should only
> index the caller's regs array. We need a different index for
> the memory nodes' reg properties.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 05/17] arm/arm64: setup improvements
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-16  6:15     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-16  6:15 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 4559 bytes --]

On Mon, Feb 15, 2016 at 02:49:14PM +0100, Andrew Jones wrote:
> Handle multiple memory regions being described in the DT. Also
> add a more informative error message for when a user does -smp N,
> N > NR_CPUS.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

For whatever that's worth, given that I don't know ARM or
kvm-unit-tests at all well.


> 
> ---
> powerpc will adapt arm's setup to be used as it's own, and it
> needs these changes. There's no reason to only do them for power,
> so we do them in arm first, getting them ready to be adapted.
> ---
>  lib/arm/asm/setup.h |  9 ++++++++
>  lib/arm/setup.c     | 66 ++++++++++++++++++++++++++++++++++++++---------------
>  2 files changed, 56 insertions(+), 19 deletions(-)
> 
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> index 02b668672fca4..cb8fdbd38dd5d 100644
> --- a/lib/arm/asm/setup.h
> +++ b/lib/arm/asm/setup.h
> @@ -6,6 +6,7 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <alloc.h>	/* phys_addr_t */
>  #include <asm/page.h>
>  #include <asm/pgtable-hwdef.h>
>  
> @@ -13,6 +14,14 @@
>  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 __phys_offset, __phys_end;
>  
>  #define PHYS_OFFSET		(__phys_offset)
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index da6edc1f9d8ff..8c6172ff94106 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -27,12 +27,18 @@ 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 __phys_offset, __phys_end;
>  
>  static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
>  {
>  	int cpu = nr_cpus++;
> -	assert(cpu < NR_CPUS);
> +
> +	if (cpu >= NR_CPUS) {
> +		printf("Number cpus exceeds maximum supported (%d).\n",
> +			NR_CPUS);
> +		assert(0);
> +	}
>  	cpus[cpu] = regval;
>  	set_cpu_present(cpu, true);
>  }
> @@ -49,24 +55,46 @@ static void cpu_init(void)
>  
>  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);
> -
> -	__phys_offset = mem_start;	/* PHYS_OFFSET */
> -	__phys_end = mem_end;		/* PHYS_END */
> -
> -	phys_alloc_init(freemem_start, mem_end - 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));
> +
> +	__phys_offset = mem.start;	/* PHYS_OFFSET */
> +	__phys_end = mem.end;		/* PHYS_END */
> +
> +	phys_alloc_init(freemem_start, primary.end - freemem_start);
>  	phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
>  
>  	mmu_enable_idmap();

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 05/17] arm/arm64: setup improvements
@ 2016-02-16  6:15     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-16  6:15 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 4559 bytes --]

On Mon, Feb 15, 2016 at 02:49:14PM +0100, Andrew Jones wrote:
> Handle multiple memory regions being described in the DT. Also
> add a more informative error message for when a user does -smp N,
> N > NR_CPUS.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

For whatever that's worth, given that I don't know ARM or
kvm-unit-tests at all well.


> 
> ---
> powerpc will adapt arm's setup to be used as it's own, and it
> needs these changes. There's no reason to only do them for power,
> so we do them in arm first, getting them ready to be adapted.
> ---
>  lib/arm/asm/setup.h |  9 ++++++++
>  lib/arm/setup.c     | 66 ++++++++++++++++++++++++++++++++++++++---------------
>  2 files changed, 56 insertions(+), 19 deletions(-)
> 
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> index 02b668672fca4..cb8fdbd38dd5d 100644
> --- a/lib/arm/asm/setup.h
> +++ b/lib/arm/asm/setup.h
> @@ -6,6 +6,7 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <alloc.h>	/* phys_addr_t */
>  #include <asm/page.h>
>  #include <asm/pgtable-hwdef.h>
>  
> @@ -13,6 +14,14 @@
>  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 __phys_offset, __phys_end;
>  
>  #define PHYS_OFFSET		(__phys_offset)
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index da6edc1f9d8ff..8c6172ff94106 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -27,12 +27,18 @@ 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 __phys_offset, __phys_end;
>  
>  static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
>  {
>  	int cpu = nr_cpus++;
> -	assert(cpu < NR_CPUS);
> +
> +	if (cpu >= NR_CPUS) {
> +		printf("Number cpus exceeds maximum supported (%d).\n",
> +			NR_CPUS);
> +		assert(0);
> +	}
>  	cpus[cpu] = regval;
>  	set_cpu_present(cpu, true);
>  }
> @@ -49,24 +55,46 @@ static void cpu_init(void)
>  
>  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);
> -
> -	__phys_offset = mem_start;	/* PHYS_OFFSET */
> -	__phys_end = mem_end;		/* PHYS_END */
> -
> -	phys_alloc_init(freemem_start, mem_end - 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));
> +
> +	__phys_offset = mem.start;	/* PHYS_OFFSET */
> +	__phys_end = mem.end;		/* PHYS_END */
> +
> +	phys_alloc_init(freemem_start, primary.end - freemem_start);
>  	phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
>  
>  	mmu_enable_idmap();

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
  2016-02-15 13:49 ` Andrew Jones
@ 2016-02-16 17:32   ` Paolo Bonzini
  -1 siblings, 0 replies; 72+ messages in thread
From: Paolo Bonzini @ 2016-02-16 17:32 UTC (permalink / raw)
  To: Andrew Jones, kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier



On 15/02/2016 14:49, Andrew Jones wrote:
> This series brings basic setup; starts a test's C entry point, main(),
> and printf, exit, and malloc work. Three more series should follow this
> one which must bring; vector support, mmu support, and smp support, at
> which point I believe the framework could just evolve with the creation
> of unit tests.
> 
> Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
> both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
> to hearing more testing feedback from others though.

In case everything's fine, do you have a branch that I can pull from?

Paolo

> v4:
>  - check for H_PRIVILEGE in broken sc1 probe [David]
>  - rename rtas' lock from lock to rtas_lock [Thomas]
>  - rtas: should only iterate to size/4 [drew]
>  - add powerpc/.gitignore (ignore boot_rom.bin) [drew]
> 
> v3:
> Paolo's comments:
>  - got rid of zero-sized files
> 
> Thomas' review comments:
>  - remove useless casts in needed cast adding patch
>  - got rid of build_romfs building (and committing a binary), just
>    offset the rom binary by 256 bytes now
>  - added a better error message for a -smp N, N > NR_CPUS user error
>  - got rid of infinite loop with broken rtas-poweroff
>  - one r-b (wasn't sure the "looks good"'s counted, so didn't add more)
> 
> Laurent's testing led me to
>  - fix a problem on kvm_pr with broken sc1
>  - fix handling of memory regions, expect more than one
>    - and a fix to DT code so that works
> 
> Additionally:
>  - new patches
>    - cscope: ppc64 needs to look in lib/powerpc/asm too,
>              and arm64 in lib/arm/asm
>    - handle memory regions better also for arm
>    - a misc trivial fix for arm...
>  - align toc to 256 bytes for later gcc
> 
> v2:
>   Besides rebasing on latest master, v2 addresses all of David's comments
>     - assembler cleanup
>     - jump into the RTAS blob we get from DT, instead of reproducing it
>     - don't store the RTAS root node, always hunt it down
> 
> We still haven't addressed debug-exit. Plugging chr-testdev into an spapr
> vty is probably what we should investigate first (as was suggested by Alex
> Graf under the v1 review). For now we keep the hack from v1, but simplified.
> 
> Patches also available here
> https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4
> 
> 
> Andrew Jones (17):
>   arm/arm64: trivial: another assert fix
>   Makefile: cscope: also look in arch shared asm
>   lib: asm-generic: add missing casts
>   devicetree: fix dt_get_memory_params
>   arm/arm64: setup improvements
>   lib: share arm-selftest utility functions
>   config: no need to mix arch makefiles
>   powerpc/ppc64: start skeleton framework
>   powerpc/ppc64: ppc-ify makefiles and linker script
>   powerpc/ppc64: add a boot rom
>   powerpc/ppc64: add hcall support and putchar
>   powerpc/ppc64: adapt arm's setup
>   powerpc/ppc64: relocate linker VMAs
>   powerpc/ppc64: add run script and unittests.cfg
>   mkstandalone: add support for powerpc
>   powerpc/ppc64: add RTAS support
>   powerpc/ppc64: make a fake debug-exit
> 
>  Makefile                                           |   8 +-
>  README                                             |   3 +-
>  arm/Makefile                                       |   1 +
>  config/config-arm.mak => arm/Makefile.arm          |   2 +-
>  config/config-arm64.mak => arm/Makefile.arm64      |   2 +-
>  .../config-arm-common.mak => arm/Makefile.common   |   3 +-
>  arm/selftest.c                                     |  45 +++----
>  configure                                          |   6 +
>  lib/arm/asm/setup.h                                |   9 ++
>  lib/arm/io.c                                       |   3 +-
>  lib/arm/setup.c                                    |  66 +++++++---
>  lib/asm-generic/io.h                               |  12 +-
>  lib/devicetree.c                                   |   8 +-
>  lib/libcflat.h                                     |  11 +-
>  lib/powerpc/.gitignore                             |   1 +
>  lib/powerpc/asm/hcall.h                            |  46 +++++++
>  lib/powerpc/asm/rtas.h                             |  26 ++++
>  lib/powerpc/asm/setup.h                            |  36 ++++++
>  lib/powerpc/hcall.c                                |  79 ++++++++++++
>  lib/powerpc/io.c                                   |  37 ++++++
>  lib/powerpc/rtas.c                                 | 139 +++++++++++++++++++++
>  lib/powerpc/setup.c                                | 119 ++++++++++++++++++
>  lib/ppc64/.gitignore                               |   1 +
>  lib/ppc64/asm-offsets.c                            |  12 ++
>  lib/ppc64/asm/asm-offsets.h                        |   1 +
>  lib/ppc64/asm/hcall.h                              |   1 +
>  lib/ppc64/asm/io.h                                 |   5 +
>  lib/ppc64/asm/page.h                               |   1 +
>  lib/ppc64/asm/rtas.h                               |   1 +
>  lib/ppc64/asm/setup.h                              |   1 +
>  lib/ppc64/asm/spinlock.h                           |  11 ++
>  lib/ppc64/spinlock.c                               |  11 ++
>  lib/report.c                                       |  16 +++
>  lib/util.c                                         |  18 +++
>  lib/util.h                                         |  23 ++++
>  powerpc/.gitignore                                 |   1 +
>  powerpc/Makefile                                   |   1 +
>  powerpc/Makefile.common                            |  71 +++++++++++
>  powerpc/Makefile.ppc64                             |  20 +++
>  powerpc/boot_rom.S                                 |   5 +
>  powerpc/cstart64.S                                 |  83 ++++++++++++
>  powerpc/flat.lds                                   |  44 +++++++
>  powerpc/reloc64.c                                  |  55 ++++++++
>  powerpc/run                                        |  55 ++++++++
>  powerpc/selftest.c                                 |  64 ++++++++++
>  powerpc/unittests.cfg                              |  30 +++++
>  {config => scripts}/asm-offsets.mak                |   0
>  scripts/mkstandalone.sh                            |   5 +
>  x86/Makefile                                       |   1 +
>  .../config-x86-common.mak => x86/Makefile.common   |   0
>  config/config-i386.mak => x86/Makefile.i386        |   2 +-
>  config/config-x86_64.mak => x86/Makefile.x86_64    |   2 +-
>  52 files changed, 1128 insertions(+), 75 deletions(-)
>  create mode 100644 arm/Makefile
>  rename config/config-arm.mak => arm/Makefile.arm (90%)
>  rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
>  rename config/config-arm-common.mak => arm/Makefile.common (96%)
>  create mode 100644 lib/powerpc/.gitignore
>  create mode 100644 lib/powerpc/asm/hcall.h
>  create mode 100644 lib/powerpc/asm/rtas.h
>  create mode 100644 lib/powerpc/asm/setup.h
>  create mode 100644 lib/powerpc/hcall.c
>  create mode 100644 lib/powerpc/io.c
>  create mode 100644 lib/powerpc/rtas.c
>  create mode 100644 lib/powerpc/setup.c
>  create mode 100644 lib/ppc64/.gitignore
>  create mode 100644 lib/ppc64/asm-offsets.c
>  create mode 100644 lib/ppc64/asm/asm-offsets.h
>  create mode 100644 lib/ppc64/asm/hcall.h
>  create mode 100644 lib/ppc64/asm/io.h
>  create mode 100644 lib/ppc64/asm/page.h
>  create mode 100644 lib/ppc64/asm/rtas.h
>  create mode 100644 lib/ppc64/asm/setup.h
>  create mode 100644 lib/ppc64/asm/spinlock.h
>  create mode 100644 lib/ppc64/spinlock.c
>  create mode 100644 lib/util.c
>  create mode 100644 lib/util.h
>  create mode 100644 powerpc/.gitignore
>  create mode 100644 powerpc/Makefile
>  create mode 100644 powerpc/Makefile.common
>  create mode 100644 powerpc/Makefile.ppc64
>  create mode 100644 powerpc/boot_rom.S
>  create mode 100644 powerpc/cstart64.S
>  create mode 100644 powerpc/flat.lds
>  create mode 100644 powerpc/reloc64.c
>  create mode 100755 powerpc/run
>  create mode 100644 powerpc/selftest.c
>  create mode 100644 powerpc/unittests.cfg
>  rename {config => scripts}/asm-offsets.mak (100%)
>  create mode 100644 x86/Makefile
>  rename config/config-x86-common.mak => x86/Makefile.common (100%)
>  rename config/config-i386.mak => x86/Makefile.i386 (91%)
>  rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
@ 2016-02-16 17:32   ` Paolo Bonzini
  0 siblings, 0 replies; 72+ messages in thread
From: Paolo Bonzini @ 2016-02-16 17:32 UTC (permalink / raw)
  To: Andrew Jones, kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier



On 15/02/2016 14:49, Andrew Jones wrote:
> This series brings basic setup; starts a test's C entry point, main(),
> and printf, exit, and malloc work. Three more series should follow this
> one which must bring; vector support, mmu support, and smp support, at
> which point I believe the framework could just evolve with the creation
> of unit tests.
> 
> Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
> both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
> to hearing more testing feedback from others though.

In case everything's fine, do you have a branch that I can pull from?

Paolo

> v4:
>  - check for H_PRIVILEGE in broken sc1 probe [David]
>  - rename rtas' lock from lock to rtas_lock [Thomas]
>  - rtas: should only iterate to size/4 [drew]
>  - add powerpc/.gitignore (ignore boot_rom.bin) [drew]
> 
> v3:
> Paolo's comments:
>  - got rid of zero-sized files
> 
> Thomas' review comments:
>  - remove useless casts in needed cast adding patch
>  - got rid of build_romfs building (and committing a binary), just
>    offset the rom binary by 256 bytes now
>  - added a better error message for a -smp N, N > NR_CPUS user error
>  - got rid of infinite loop with broken rtas-poweroff
>  - one r-b (wasn't sure the "looks good"'s counted, so didn't add more)
> 
> Laurent's testing led me to
>  - fix a problem on kvm_pr with broken sc1
>  - fix handling of memory regions, expect more than one
>    - and a fix to DT code so that works
> 
> Additionally:
>  - new patches
>    - cscope: ppc64 needs to look in lib/powerpc/asm too,
>              and arm64 in lib/arm/asm
>    - handle memory regions better also for arm
>    - a misc trivial fix for arm...
>  - align toc to 256 bytes for later gcc
> 
> v2:
>   Besides rebasing on latest master, v2 addresses all of David's comments
>     - assembler cleanup
>     - jump into the RTAS blob we get from DT, instead of reproducing it
>     - don't store the RTAS root node, always hunt it down
> 
> We still haven't addressed debug-exit. Plugging chr-testdev into an spapr
> vty is probably what we should investigate first (as was suggested by Alex
> Graf under the v1 review). For now we keep the hack from v1, but simplified.
> 
> Patches also available here
> https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4
> 
> 
> Andrew Jones (17):
>   arm/arm64: trivial: another assert fix
>   Makefile: cscope: also look in arch shared asm
>   lib: asm-generic: add missing casts
>   devicetree: fix dt_get_memory_params
>   arm/arm64: setup improvements
>   lib: share arm-selftest utility functions
>   config: no need to mix arch makefiles
>   powerpc/ppc64: start skeleton framework
>   powerpc/ppc64: ppc-ify makefiles and linker script
>   powerpc/ppc64: add a boot rom
>   powerpc/ppc64: add hcall support and putchar
>   powerpc/ppc64: adapt arm's setup
>   powerpc/ppc64: relocate linker VMAs
>   powerpc/ppc64: add run script and unittests.cfg
>   mkstandalone: add support for powerpc
>   powerpc/ppc64: add RTAS support
>   powerpc/ppc64: make a fake debug-exit
> 
>  Makefile                                           |   8 +-
>  README                                             |   3 +-
>  arm/Makefile                                       |   1 +
>  config/config-arm.mak => arm/Makefile.arm          |   2 +-
>  config/config-arm64.mak => arm/Makefile.arm64      |   2 +-
>  .../config-arm-common.mak => arm/Makefile.common   |   3 +-
>  arm/selftest.c                                     |  45 +++----
>  configure                                          |   6 +
>  lib/arm/asm/setup.h                                |   9 ++
>  lib/arm/io.c                                       |   3 +-
>  lib/arm/setup.c                                    |  66 +++++++---
>  lib/asm-generic/io.h                               |  12 +-
>  lib/devicetree.c                                   |   8 +-
>  lib/libcflat.h                                     |  11 +-
>  lib/powerpc/.gitignore                             |   1 +
>  lib/powerpc/asm/hcall.h                            |  46 +++++++
>  lib/powerpc/asm/rtas.h                             |  26 ++++
>  lib/powerpc/asm/setup.h                            |  36 ++++++
>  lib/powerpc/hcall.c                                |  79 ++++++++++++
>  lib/powerpc/io.c                                   |  37 ++++++
>  lib/powerpc/rtas.c                                 | 139 +++++++++++++++++++++
>  lib/powerpc/setup.c                                | 119 ++++++++++++++++++
>  lib/ppc64/.gitignore                               |   1 +
>  lib/ppc64/asm-offsets.c                            |  12 ++
>  lib/ppc64/asm/asm-offsets.h                        |   1 +
>  lib/ppc64/asm/hcall.h                              |   1 +
>  lib/ppc64/asm/io.h                                 |   5 +
>  lib/ppc64/asm/page.h                               |   1 +
>  lib/ppc64/asm/rtas.h                               |   1 +
>  lib/ppc64/asm/setup.h                              |   1 +
>  lib/ppc64/asm/spinlock.h                           |  11 ++
>  lib/ppc64/spinlock.c                               |  11 ++
>  lib/report.c                                       |  16 +++
>  lib/util.c                                         |  18 +++
>  lib/util.h                                         |  23 ++++
>  powerpc/.gitignore                                 |   1 +
>  powerpc/Makefile                                   |   1 +
>  powerpc/Makefile.common                            |  71 +++++++++++
>  powerpc/Makefile.ppc64                             |  20 +++
>  powerpc/boot_rom.S                                 |   5 +
>  powerpc/cstart64.S                                 |  83 ++++++++++++
>  powerpc/flat.lds                                   |  44 +++++++
>  powerpc/reloc64.c                                  |  55 ++++++++
>  powerpc/run                                        |  55 ++++++++
>  powerpc/selftest.c                                 |  64 ++++++++++
>  powerpc/unittests.cfg                              |  30 +++++
>  {config => scripts}/asm-offsets.mak                |   0
>  scripts/mkstandalone.sh                            |   5 +
>  x86/Makefile                                       |   1 +
>  .../config-x86-common.mak => x86/Makefile.common   |   0
>  config/config-i386.mak => x86/Makefile.i386        |   2 +-
>  config/config-x86_64.mak => x86/Makefile.x86_64    |   2 +-
>  52 files changed, 1128 insertions(+), 75 deletions(-)
>  create mode 100644 arm/Makefile
>  rename config/config-arm.mak => arm/Makefile.arm (90%)
>  rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
>  rename config/config-arm-common.mak => arm/Makefile.common (96%)
>  create mode 100644 lib/powerpc/.gitignore
>  create mode 100644 lib/powerpc/asm/hcall.h
>  create mode 100644 lib/powerpc/asm/rtas.h
>  create mode 100644 lib/powerpc/asm/setup.h
>  create mode 100644 lib/powerpc/hcall.c
>  create mode 100644 lib/powerpc/io.c
>  create mode 100644 lib/powerpc/rtas.c
>  create mode 100644 lib/powerpc/setup.c
>  create mode 100644 lib/ppc64/.gitignore
>  create mode 100644 lib/ppc64/asm-offsets.c
>  create mode 100644 lib/ppc64/asm/asm-offsets.h
>  create mode 100644 lib/ppc64/asm/hcall.h
>  create mode 100644 lib/ppc64/asm/io.h
>  create mode 100644 lib/ppc64/asm/page.h
>  create mode 100644 lib/ppc64/asm/rtas.h
>  create mode 100644 lib/ppc64/asm/setup.h
>  create mode 100644 lib/ppc64/asm/spinlock.h
>  create mode 100644 lib/ppc64/spinlock.c
>  create mode 100644 lib/util.c
>  create mode 100644 lib/util.h
>  create mode 100644 powerpc/.gitignore
>  create mode 100644 powerpc/Makefile
>  create mode 100644 powerpc/Makefile.common
>  create mode 100644 powerpc/Makefile.ppc64
>  create mode 100644 powerpc/boot_rom.S
>  create mode 100644 powerpc/cstart64.S
>  create mode 100644 powerpc/flat.lds
>  create mode 100644 powerpc/reloc64.c
>  create mode 100755 powerpc/run
>  create mode 100644 powerpc/selftest.c
>  create mode 100644 powerpc/unittests.cfg
>  rename {config => scripts}/asm-offsets.mak (100%)
>  create mode 100644 x86/Makefile
>  rename config/config-x86-common.mak => x86/Makefile.common (100%)
>  rename config/config-i386.mak => x86/Makefile.i386 (91%)
>  rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
  2016-02-16 17:32   ` Paolo Bonzini
@ 2016-02-16 17:44     ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-16 17:44 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, kvm-ppc, thuth, dgibson, david, agraf, lvivier

On Tue, Feb 16, 2016 at 06:32:07PM +0100, Paolo Bonzini wrote:
> 
> 
> On 15/02/2016 14:49, Andrew Jones wrote:
> > This series brings basic setup; starts a test's C entry point, main(),
> > and printf, exit, and malloc work. Three more series should follow this
> > one which must bring; vector support, mmu support, and smp support, at
> > which point I believe the framework could just evolve with the creation
> > of unit tests.
> > 
> > Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
> > both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
> > to hearing more testing feedback from others though.
> 
> In case everything's fine, do you have a branch that I can pull from?

Sure do.  

https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4

I just refreshed it with the two additional r-b's from David now.

Thanks!
drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop
@ 2016-02-16 17:44     ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-16 17:44 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, kvm-ppc, thuth, dgibson, david, agraf, lvivier

On Tue, Feb 16, 2016 at 06:32:07PM +0100, Paolo Bonzini wrote:
> 
> 
> On 15/02/2016 14:49, Andrew Jones wrote:
> > This series brings basic setup; starts a test's C entry point, main(),
> > and printf, exit, and malloc work. Three more series should follow this
> > one which must bring; vector support, mmu support, and smp support, at
> > which point I believe the framework could just evolve with the creation
> > of unit tests.
> > 
> > Tested on TCG and a P8 kvm_pr machine, and Laurent has tested it on
> > both a PowerMac G5 (kvm_pr) and a kvm_hv machine. I'm looking forward
> > to hearing more testing feedback from others though.
> 
> In case everything's fine, do you have a branch that I can pull from?

Sure do.  

https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop-v4

I just refreshed it with the two additional r-b's from David now.

Thanks!
drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  0:14     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  0:14 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 7413 bytes --]

On Mon, Feb 15, 2016 at 02:49:15PM +0100, Andrew Jones wrote:
> arm-selftest has a couple utility functions that could be useful
> to other unit tests, even other architectures. So move them out.
> split_var moves to lib/util, where we can add other random
> utilities over time. assert_args inspires report_abort, which
> allows us to report a message, using the current prefix, that
> we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
> for cases when unit tests can't complete due to missing
> dependencies of some sort, such as missing/invalid inputs from
> the user.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  arm/selftest.c               | 45 ++++++++++++++------------------------------
>  config/config-arm-common.mak |  1 +
>  lib/libcflat.h               | 11 ++++++-----
>  lib/report.c                 | 16 ++++++++++++++++
>  lib/util.c                   | 18 ++++++++++++++++++
>  lib/util.h                   | 23 ++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 36 deletions(-)
>  create mode 100644 lib/util.c
>  create mode 100644 lib/util.h
> 
> diff --git a/arm/selftest.c b/arm/selftest.c
> index aad7eecd529ad..75dc91faab69a 100644
> --- a/arm/selftest.c
> +++ b/arm/selftest.c
> @@ -6,6 +6,7 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <util.h>
>  #include <alloc.h>
>  #include <devicetree.h>
>  #include <asm/setup.h>
> @@ -18,43 +19,21 @@
>  #include <asm/cpumask.h>
>  #include <asm/barrier.h>
>  
> -static void assert_args(int num_args, int needed_args)
> -{
> -	if (num_args < needed_args) {
> -		printf("selftest: not enough arguments\n");
> -		abort();
> -	}
> -}
> -
> -static char *split_var(char *s, long *val)
> -{
> -	char *p;
> -
> -	p = strchr(s, '=');
> -	if (!p)
> -		return NULL;
> -
> -	*val = atol(p+1);
> -	*p = '\0';
> -
> -	return s;
> -}
> -
>  static void check_setup(int argc, char **argv)
>  {
> -	int nr_tests = 0, i;
> -	char *var;
> +	int nr_tests = 0, len, i;
>  	long val;
>  
>  	for (i = 0; i < argc; ++i) {
>  
> -		var = split_var(argv[i], &val);
> -		if (!var)
> +		len = parse_keyval(argv[i], &val);
> +		if (len == -1)
>  			continue;
>  
> -		report_prefix_push(var);
> +		argv[i][len] = '\0';
> +		report_prefix_push(argv[i]);
>  
> -		if (strcmp(var, "mem") == 0) {
> +		if (strcmp(argv[i], "mem") == 0) {
>  
>  			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
>  			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> @@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
>  							memsize/1024/1024);
>  			++nr_tests;
>  
> -		} else if (strcmp(var, "smp") == 0) {
> +		} else if (strcmp(argv[i], "smp") == 0) {
>  
>  			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
>  			++nr_tests;
> @@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
>  		report_prefix_pop();
>  	}
>  
> -	assert_args(nr_tests, 2);
> +	if (nr_tests < 2)
> +		report_abort("missing input");
>  }
>  
>  static struct pt_regs expected_regs;
> @@ -343,7 +323,10 @@ static void cpu_report(void)
>  int main(int argc, char **argv)
>  {
>  	report_prefix_push("selftest");
> -	assert_args(argc, 1);
> +
> +	if (!argc)
> +		report_abort("no test specified");
> +
>  	report_prefix_push(argv[0]);
>  
>  	if (strcmp(argv[0], "setup") == 0) {
> diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
> index 698555d6a676f..bd153cf6ea5ba 100644
> --- a/config/config-arm-common.mak
> +++ b/config/config-arm-common.mak
> @@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include config/asm-offsets.mak
>  
> +cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
>  cflatobjs += lib/virtio.o
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 9747ccdbc9f1d..8411f6c5d92e3 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
>  extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
>  extern long atol(const char *ptr);
>  
> -void report_prefix_push(const char *prefix);
> -void report_prefix_pop(void);
> -void report(const char *msg_fmt, bool pass, ...);
> -void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> -int report_summary(void);
> +extern void report_prefix_push(const char *prefix);
> +extern void report_prefix_pop(void);
> +extern void report(const char *msg_fmt, bool pass, ...);
> +extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> +extern void report_abort(const char *msg_fmt, ...);
> +extern int report_summary(void);
>  
>  #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
>  
> diff --git a/lib/report.c b/lib/report.c
> index 35e664108a921..62916c4ac3c8a 100644
> --- a/lib/report.c
> +++ b/lib/report.c
> @@ -96,3 +96,19 @@ int report_summary(void)
>  
>  	spin_unlock(&lock);
>  }
> +
> +void report_abort(const char *msg_fmt, ...)
> +{
> +	va_list va;
> +	char buf[2000];
> +
> +	puts("ABORT: ");
> +	puts(prefixes);
> +	va_start(va, msg_fmt);
> +	vsnprintf(buf, sizeof(buf), msg_fmt, va);

Is there a reason for using vsnprintf() rather than just vprintf()
here?

Apart from that,

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>


> +	va_end(va);
> +	puts(buf);
> +	puts("\n");
> +	report_summary();
> +	abort();
> +}
> diff --git a/lib/util.c b/lib/util.c
> new file mode 100644
> index 0000000000000..69b18100c9722
> --- /dev/null
> +++ b/lib/util.c
> @@ -0,0 +1,18 @@
> +/*
> + * 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>
> +
> +int parse_keyval(char *s, long *val)
> +{
> +	char *p;
> +
> +	p = strchr(s, '=');
> +	if (!p)
> +		return -1;
> +
> +	*val = atol(p+1);
> +	return p - s;
> +}
> diff --git a/lib/util.h b/lib/util.h
> new file mode 100644
> index 0000000000000..4c4b441322770
> --- /dev/null
> +++ b/lib/util.h
> @@ -0,0 +1,23 @@
> +#ifndef _UTIL_H_
> +#define _UTIL_H_
> +/*
> + * Collection of utility functions to share between unit tests.
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +
> +/*
> + * parse_keyval extracts the integer from a string formatted as
> + * string=integer. This is useful for passing expected values to
> + * the unit test on the command line, i.e. it helps parse QEMU
> + * command lines that include something like -append var1=1 var2=2
> + * @s is the input string, likely a command line parameter, and
> + * @val is a pointer to where the integer will be stored.
> + *
> + * Returns the offset of the '=', or -1 if no keyval pair is found.
> + */
> +extern int parse_keyval(char *s, long *val);
> +
> +#endif

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
@ 2016-02-17  0:14     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  0:14 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 7413 bytes --]

On Mon, Feb 15, 2016 at 02:49:15PM +0100, Andrew Jones wrote:
> arm-selftest has a couple utility functions that could be useful
> to other unit tests, even other architectures. So move them out.
> split_var moves to lib/util, where we can add other random
> utilities over time. assert_args inspires report_abort, which
> allows us to report a message, using the current prefix, that
> we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
> for cases when unit tests can't complete due to missing
> dependencies of some sort, such as missing/invalid inputs from
> the user.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  arm/selftest.c               | 45 ++++++++++++++------------------------------
>  config/config-arm-common.mak |  1 +
>  lib/libcflat.h               | 11 ++++++-----
>  lib/report.c                 | 16 ++++++++++++++++
>  lib/util.c                   | 18 ++++++++++++++++++
>  lib/util.h                   | 23 ++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 36 deletions(-)
>  create mode 100644 lib/util.c
>  create mode 100644 lib/util.h
> 
> diff --git a/arm/selftest.c b/arm/selftest.c
> index aad7eecd529ad..75dc91faab69a 100644
> --- a/arm/selftest.c
> +++ b/arm/selftest.c
> @@ -6,6 +6,7 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <util.h>
>  #include <alloc.h>
>  #include <devicetree.h>
>  #include <asm/setup.h>
> @@ -18,43 +19,21 @@
>  #include <asm/cpumask.h>
>  #include <asm/barrier.h>
>  
> -static void assert_args(int num_args, int needed_args)
> -{
> -	if (num_args < needed_args) {
> -		printf("selftest: not enough arguments\n");
> -		abort();
> -	}
> -}
> -
> -static char *split_var(char *s, long *val)
> -{
> -	char *p;
> -
> -	p = strchr(s, '=');
> -	if (!p)
> -		return NULL;
> -
> -	*val = atol(p+1);
> -	*p = '\0';
> -
> -	return s;
> -}
> -
>  static void check_setup(int argc, char **argv)
>  {
> -	int nr_tests = 0, i;
> -	char *var;
> +	int nr_tests = 0, len, i;
>  	long val;
>  
>  	for (i = 0; i < argc; ++i) {
>  
> -		var = split_var(argv[i], &val);
> -		if (!var)
> +		len = parse_keyval(argv[i], &val);
> +		if (len == -1)
>  			continue;
>  
> -		report_prefix_push(var);
> +		argv[i][len] = '\0';
> +		report_prefix_push(argv[i]);
>  
> -		if (strcmp(var, "mem") == 0) {
> +		if (strcmp(argv[i], "mem") == 0) {
>  
>  			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
>  			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> @@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
>  							memsize/1024/1024);
>  			++nr_tests;
>  
> -		} else if (strcmp(var, "smp") == 0) {
> +		} else if (strcmp(argv[i], "smp") == 0) {
>  
>  			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
>  			++nr_tests;
> @@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
>  		report_prefix_pop();
>  	}
>  
> -	assert_args(nr_tests, 2);
> +	if (nr_tests < 2)
> +		report_abort("missing input");
>  }
>  
>  static struct pt_regs expected_regs;
> @@ -343,7 +323,10 @@ static void cpu_report(void)
>  int main(int argc, char **argv)
>  {
>  	report_prefix_push("selftest");
> -	assert_args(argc, 1);
> +
> +	if (!argc)
> +		report_abort("no test specified");
> +
>  	report_prefix_push(argv[0]);
>  
>  	if (strcmp(argv[0], "setup") == 0) {
> diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
> index 698555d6a676f..bd153cf6ea5ba 100644
> --- a/config/config-arm-common.mak
> +++ b/config/config-arm-common.mak
> @@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include config/asm-offsets.mak
>  
> +cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
>  cflatobjs += lib/virtio.o
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 9747ccdbc9f1d..8411f6c5d92e3 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
>  extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
>  extern long atol(const char *ptr);
>  
> -void report_prefix_push(const char *prefix);
> -void report_prefix_pop(void);
> -void report(const char *msg_fmt, bool pass, ...);
> -void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> -int report_summary(void);
> +extern void report_prefix_push(const char *prefix);
> +extern void report_prefix_pop(void);
> +extern void report(const char *msg_fmt, bool pass, ...);
> +extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> +extern void report_abort(const char *msg_fmt, ...);
> +extern int report_summary(void);
>  
>  #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
>  
> diff --git a/lib/report.c b/lib/report.c
> index 35e664108a921..62916c4ac3c8a 100644
> --- a/lib/report.c
> +++ b/lib/report.c
> @@ -96,3 +96,19 @@ int report_summary(void)
>  
>  	spin_unlock(&lock);
>  }
> +
> +void report_abort(const char *msg_fmt, ...)
> +{
> +	va_list va;
> +	char buf[2000];
> +
> +	puts("ABORT: ");
> +	puts(prefixes);
> +	va_start(va, msg_fmt);
> +	vsnprintf(buf, sizeof(buf), msg_fmt, va);

Is there a reason for using vsnprintf() rather than just vprintf()
here?

Apart from that,

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>


> +	va_end(va);
> +	puts(buf);
> +	puts("\n");
> +	report_summary();
> +	abort();
> +}
> diff --git a/lib/util.c b/lib/util.c
> new file mode 100644
> index 0000000000000..69b18100c9722
> --- /dev/null
> +++ b/lib/util.c
> @@ -0,0 +1,18 @@
> +/*
> + * 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>
> +
> +int parse_keyval(char *s, long *val)
> +{
> +	char *p;
> +
> +	p = strchr(s, '=');
> +	if (!p)
> +		return -1;
> +
> +	*val = atol(p+1);
> +	return p - s;
> +}
> diff --git a/lib/util.h b/lib/util.h
> new file mode 100644
> index 0000000000000..4c4b441322770
> --- /dev/null
> +++ b/lib/util.h
> @@ -0,0 +1,23 @@
> +#ifndef _UTIL_H_
> +#define _UTIL_H_
> +/*
> + * Collection of utility functions to share between unit tests.
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +
> +/*
> + * parse_keyval extracts the integer from a string formatted as
> + * string=integer. This is useful for passing expected values to
> + * the unit test on the command line, i.e. it helps parse QEMU
> + * command lines that include something like -append var1=1 var2=2
> + * @s is the input string, likely a command line parameter, and
> + * @val is a pointer to where the integer will be stored.
> + *
> + * Returns the offset of the '=', or -1 if no keyval pair is found.
> + */
> +extern int parse_keyval(char *s, long *val);
> +
> +#endif

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 07/17] config: no need to mix arch makefiles
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  1:18     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:18 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 6447 bytes --]

On Mon, Feb 15, 2016 at 02:49:16PM +0100, Andrew Jones wrote:
> Move the config/config-*.mak files to their own directories and
> rename to Makefile.* README is also updated to reflect the change,
> as well as to remove an optimistic reference to a non-existent
> docs directory.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

For what little that's worth.  It looks sane to me, but I know
basically nothing about the kvm-unit-tests build system.


> ---
>  Makefile                                            | 2 +-
>  README                                              | 3 +--
>  arm/Makefile                                        | 1 +
>  config/config-arm.mak => arm/Makefile.arm           | 2 +-
>  config/config-arm64.mak => arm/Makefile.arm64       | 2 +-
>  config/config-arm-common.mak => arm/Makefile.common | 2 +-
>  {config => scripts}/asm-offsets.mak                 | 0
>  x86/Makefile                                        | 1 +
>  config/config-x86-common.mak => x86/Makefile.common | 0
>  config/config-i386.mak => x86/Makefile.i386         | 2 +-
>  config/config-x86_64.mak => x86/Makefile.x86_64     | 2 +-
>  11 files changed, 9 insertions(+), 8 deletions(-)
>  create mode 100644 arm/Makefile
>  rename config/config-arm.mak => arm/Makefile.arm (90%)
>  rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
>  rename config/config-arm-common.mak => arm/Makefile.common (98%)
>  rename {config => scripts}/asm-offsets.mak (100%)
>  create mode 100644 x86/Makefile
>  rename config/config-x86-common.mak => x86/Makefile.common (100%)
>  rename config/config-i386.mak => x86/Makefile.i386 (91%)
>  rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)
> 
> diff --git a/Makefile b/Makefile
> index fe5cc620d473b..ddba941858596 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -32,7 +32,7 @@ LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
>  LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
>  
>  #include architecure specific make rules
> -include config/config-$(ARCH).mak
> +include $(TEST_DIR)/Makefile
>  
>  # cc-option
>  # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
> diff --git a/README b/README
> index 457bd797362cf..f8f196d90bf10 100644
> --- a/README
> +++ b/README
> @@ -34,8 +34,7 @@ each as a standalone test.
>  
>  Directory structure:
>  .:		configure script, top-level Makefile, and run_tests.sh
> -./config:	collection of architecture dependent makefiles
> -./docs:		documentation files
> +./scripts:	helper scripts for building and running tests
>  ./lib:		general architecture neutral services for the tests
>  ./lib/<ARCH>:	architecture dependent services for the tests
>  ./<ARCH>:	the sources of the tests and the created objects/images
> diff --git a/arm/Makefile b/arm/Makefile
> new file mode 100644
> index 0000000000000..369a38b2d1703
> --- /dev/null
> +++ b/arm/Makefile
> @@ -0,0 +1 @@
> +include $(TEST_DIR)/Makefile.$(ARCH)
> diff --git a/config/config-arm.mak b/arm/Makefile.arm
> similarity index 90%
> rename from config/config-arm.mak
> rename to arm/Makefile.arm
> index ae6c2e7134883..946422872532d 100644
> --- a/config/config-arm.mak
> +++ b/arm/Makefile.arm
> @@ -18,6 +18,6 @@ cflatobjs += lib/arm/processor.o
>  # arm specific tests
>  tests =
>  
> -include config/config-arm-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  arch_clean: arm_clean
> diff --git a/config/config-arm64.mak b/arm/Makefile.arm64
> similarity index 89%
> rename from config/config-arm64.mak
> rename to arm/Makefile.arm64
> index d61b703c8140e..0b0761c729c7c 100644
> --- a/config/config-arm64.mak
> +++ b/arm/Makefile.arm64
> @@ -14,7 +14,7 @@ cflatobjs += lib/arm64/spinlock.o
>  # arm64 specific tests
>  tests =
>  
> -include config/config-arm-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  arch_clean: arm_clean
>  	$(RM) lib/arm64/.*.d
> diff --git a/config/config-arm-common.mak b/arm/Makefile.common
> similarity index 98%
> rename from config/config-arm-common.mak
> rename to arm/Makefile.common
> index bd153cf6ea5ba..dd3a0ca327d06 100644
> --- a/config/config-arm-common.mak
> +++ b/arm/Makefile.common
> @@ -25,7 +25,7 @@ CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
> -include config/asm-offsets.mak
> +include scripts/asm-offsets.mak
>  
>  cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
> diff --git a/config/asm-offsets.mak b/scripts/asm-offsets.mak
> similarity index 100%
> rename from config/asm-offsets.mak
> rename to scripts/asm-offsets.mak
> diff --git a/x86/Makefile b/x86/Makefile
> new file mode 100644
> index 0000000000000..369a38b2d1703
> --- /dev/null
> +++ b/x86/Makefile
> @@ -0,0 +1 @@
> +include $(TEST_DIR)/Makefile.$(ARCH)
> diff --git a/config/config-x86-common.mak b/x86/Makefile.common
> similarity index 100%
> rename from config/config-x86-common.mak
> rename to x86/Makefile.common
> diff --git a/config/config-i386.mak b/x86/Makefile.i386
> similarity index 91%
> rename from config/config-i386.mak
> rename to x86/Makefile.i386
> index e353387551585..8a4c45c457476 100644
> --- a/config/config-i386.mak
> +++ b/x86/Makefile.i386
> @@ -8,7 +8,7 @@ cflatobjs += lib/x86/setjmp32.o
>  tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \
>  	$(TEST_DIR)/cmpxchg8b.flat
>  
> -include config/config-x86-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  $(TEST_DIR)/cmpxchg8b.elf: $(cstart.o) $(TEST_DIR)/cmpxchg8b.o
>  $(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
> diff --git a/config/config-x86_64.mak b/x86/Makefile.x86_64
> similarity index 93%
> rename from config/config-x86_64.mak
> rename to x86/Makefile.x86_64
> index d190be82e0cf2..6b7ccfba550b6 100644
> --- a/config/config-x86_64.mak
> +++ b/x86/Makefile.x86_64
> @@ -15,4 +15,4 @@ tests += $(TEST_DIR)/svm.flat
>  tests += $(TEST_DIR)/vmx.flat
>  tests += $(TEST_DIR)/tscdeadline_latency.flat
>  
> -include config/config-x86-common.mak
> +include $(TEST_DIR)/Makefile.common

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 07/17] config: no need to mix arch makefiles
@ 2016-02-17  1:18     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:18 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 6447 bytes --]

On Mon, Feb 15, 2016 at 02:49:16PM +0100, Andrew Jones wrote:
> Move the config/config-*.mak files to their own directories and
> rename to Makefile.* README is also updated to reflect the change,
> as well as to remove an optimistic reference to a non-existent
> docs directory.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

For what little that's worth.  It looks sane to me, but I know
basically nothing about the kvm-unit-tests build system.


> ---
>  Makefile                                            | 2 +-
>  README                                              | 3 +--
>  arm/Makefile                                        | 1 +
>  config/config-arm.mak => arm/Makefile.arm           | 2 +-
>  config/config-arm64.mak => arm/Makefile.arm64       | 2 +-
>  config/config-arm-common.mak => arm/Makefile.common | 2 +-
>  {config => scripts}/asm-offsets.mak                 | 0
>  x86/Makefile                                        | 1 +
>  config/config-x86-common.mak => x86/Makefile.common | 0
>  config/config-i386.mak => x86/Makefile.i386         | 2 +-
>  config/config-x86_64.mak => x86/Makefile.x86_64     | 2 +-
>  11 files changed, 9 insertions(+), 8 deletions(-)
>  create mode 100644 arm/Makefile
>  rename config/config-arm.mak => arm/Makefile.arm (90%)
>  rename config/config-arm64.mak => arm/Makefile.arm64 (89%)
>  rename config/config-arm-common.mak => arm/Makefile.common (98%)
>  rename {config => scripts}/asm-offsets.mak (100%)
>  create mode 100644 x86/Makefile
>  rename config/config-x86-common.mak => x86/Makefile.common (100%)
>  rename config/config-i386.mak => x86/Makefile.i386 (91%)
>  rename config/config-x86_64.mak => x86/Makefile.x86_64 (93%)
> 
> diff --git a/Makefile b/Makefile
> index fe5cc620d473b..ddba941858596 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -32,7 +32,7 @@ LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
>  LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
>  
>  #include architecure specific make rules
> -include config/config-$(ARCH).mak
> +include $(TEST_DIR)/Makefile
>  
>  # cc-option
>  # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
> diff --git a/README b/README
> index 457bd797362cf..f8f196d90bf10 100644
> --- a/README
> +++ b/README
> @@ -34,8 +34,7 @@ each as a standalone test.
>  
>  Directory structure:
>  .:		configure script, top-level Makefile, and run_tests.sh
> -./config:	collection of architecture dependent makefiles
> -./docs:		documentation files
> +./scripts:	helper scripts for building and running tests
>  ./lib:		general architecture neutral services for the tests
>  ./lib/<ARCH>:	architecture dependent services for the tests
>  ./<ARCH>:	the sources of the tests and the created objects/images
> diff --git a/arm/Makefile b/arm/Makefile
> new file mode 100644
> index 0000000000000..369a38b2d1703
> --- /dev/null
> +++ b/arm/Makefile
> @@ -0,0 +1 @@
> +include $(TEST_DIR)/Makefile.$(ARCH)
> diff --git a/config/config-arm.mak b/arm/Makefile.arm
> similarity index 90%
> rename from config/config-arm.mak
> rename to arm/Makefile.arm
> index ae6c2e7134883..946422872532d 100644
> --- a/config/config-arm.mak
> +++ b/arm/Makefile.arm
> @@ -18,6 +18,6 @@ cflatobjs += lib/arm/processor.o
>  # arm specific tests
>  tests =
>  
> -include config/config-arm-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  arch_clean: arm_clean
> diff --git a/config/config-arm64.mak b/arm/Makefile.arm64
> similarity index 89%
> rename from config/config-arm64.mak
> rename to arm/Makefile.arm64
> index d61b703c8140e..0b0761c729c7c 100644
> --- a/config/config-arm64.mak
> +++ b/arm/Makefile.arm64
> @@ -14,7 +14,7 @@ cflatobjs += lib/arm64/spinlock.o
>  # arm64 specific tests
>  tests =
>  
> -include config/config-arm-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  arch_clean: arm_clean
>  	$(RM) lib/arm64/.*.d
> diff --git a/config/config-arm-common.mak b/arm/Makefile.common
> similarity index 98%
> rename from config/config-arm-common.mak
> rename to arm/Makefile.common
> index bd153cf6ea5ba..dd3a0ca327d06 100644
> --- a/config/config-arm-common.mak
> +++ b/arm/Makefile.common
> @@ -25,7 +25,7 @@ CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
> -include config/asm-offsets.mak
> +include scripts/asm-offsets.mak
>  
>  cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
> diff --git a/config/asm-offsets.mak b/scripts/asm-offsets.mak
> similarity index 100%
> rename from config/asm-offsets.mak
> rename to scripts/asm-offsets.mak
> diff --git a/x86/Makefile b/x86/Makefile
> new file mode 100644
> index 0000000000000..369a38b2d1703
> --- /dev/null
> +++ b/x86/Makefile
> @@ -0,0 +1 @@
> +include $(TEST_DIR)/Makefile.$(ARCH)
> diff --git a/config/config-x86-common.mak b/x86/Makefile.common
> similarity index 100%
> rename from config/config-x86-common.mak
> rename to x86/Makefile.common
> diff --git a/config/config-i386.mak b/x86/Makefile.i386
> similarity index 91%
> rename from config/config-i386.mak
> rename to x86/Makefile.i386
> index e353387551585..8a4c45c457476 100644
> --- a/config/config-i386.mak
> +++ b/x86/Makefile.i386
> @@ -8,7 +8,7 @@ cflatobjs += lib/x86/setjmp32.o
>  tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \
>  	$(TEST_DIR)/cmpxchg8b.flat
>  
> -include config/config-x86-common.mak
> +include $(TEST_DIR)/Makefile.common
>  
>  $(TEST_DIR)/cmpxchg8b.elf: $(cstart.o) $(TEST_DIR)/cmpxchg8b.o
>  $(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
> diff --git a/config/config-x86_64.mak b/x86/Makefile.x86_64
> similarity index 93%
> rename from config/config-x86_64.mak
> rename to x86/Makefile.x86_64
> index d190be82e0cf2..6b7ccfba550b6 100644
> --- a/config/config-x86_64.mak
> +++ b/x86/Makefile.x86_64
> @@ -15,4 +15,4 @@ tests += $(TEST_DIR)/svm.flat
>  tests += $(TEST_DIR)/vmx.flat
>  tests += $(TEST_DIR)/tscdeadline_latency.flat
>  
> -include config/config-x86-common.mak
> +include $(TEST_DIR)/Makefile.common

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  1:45     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:45 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 5295 bytes --]

On Mon, Feb 15, 2016 at 02:49:18PM +0100, Andrew Jones wrote:
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  powerpc/Makefile.common | 40 ++++++++++------------------------------
>  powerpc/Makefile.ppc64  | 15 +++++++--------
>  powerpc/flat.lds        | 14 ++++++++++----
>  3 files changed, 27 insertions(+), 42 deletions(-)
> 
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index dd3a0ca327d06..13b828ab171d6 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -1,17 +1,15 @@
>  #
> -# arm common makefile
> +# powerpc common makefile
>  #
>  # Authors: Andrew Jones <drjones@redhat.com>
>  #
>  
>  ifeq ($(LOADADDR),)
> -	# qemu mach-virt default load address
> -	LOADADDR = 0x40000000
> +	LOADADDR = 0x0

I was trying to check what LOADADDR means, to see if this was correct,
but it appears it isn't actually being used yet.

Otherwise,

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

>  endif
>  
>  tests-common = \
> -	$(TEST_DIR)/selftest.flat \
> -	$(TEST_DIR)/spinlock-test.flat
> +	$(TEST_DIR)/selftest.elf
>  
>  all: test_cases
>  
> @@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
>  cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
> -cflatobjs += lib/virtio.o
> -cflatobjs += lib/virtio-mmio.o
> -cflatobjs += lib/chr-testdev.o
> -cflatobjs += lib/arm/io.o
> -cflatobjs += lib/arm/setup.o
> -cflatobjs += lib/arm/mmu.o
> -cflatobjs += lib/arm/bitops.o
> -cflatobjs += lib/arm/psci.o
> -cflatobjs += lib/arm/smp.o
> -
> -libeabi = lib/arm/libeabi.a
> -eabiobjs = lib/arm/eabi_compat.o
> +cflatobjs += lib/powerpc/io.o
>  
>  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
>  
> -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
>  %.elf: LDFLAGS = $(CFLAGS) -nostdlib
> -%.elf: %.o $(FLATLIBS) arm/flat.lds
> +%.elf: %.o $(FLATLIBS) powerpc/flat.lds
>  	$(CC) $(LDFLAGS) -o $@ \
> -		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> +		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
>  
> -%.flat: %.elf
> -	$(OBJCOPY) -O binary $^ $@
> -
> -$(libeabi): $(eabiobjs)
> -	$(AR) rcs $@ $^
> -
> -arm_clean: libfdt_clean asm_offsets_clean
> -	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> -	      $(TEST_DIR)/.*.d lib/arm/.*.d
> +powerpc_clean: libfdt_clean asm_offsets_clean
> +	$(RM) $(TEST_DIR)/*.{o,elf} \
> +	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
>  
>  ##################################################################
>  
> @@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
>  test_cases: $(generated_files) $(tests-common) $(tests)
>  
>  $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> -$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
> diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> index 0b0761c729c7c..95bf6772d65ed 100644
> --- a/powerpc/Makefile.ppc64
> +++ b/powerpc/Makefile.ppc64
> @@ -1,20 +1,19 @@
>  #
> -# arm64 makefile
> +# ppc64 makefile
>  #
>  # Authors: Andrew Jones <drjones@redhat.com>
>  #
>  bits = 64
> -ldarch = elf64-littleaarch64
> -kernel_offset = 0x80000
> +ldarch = elf64-powerpc
> +kernel_offset = 0x0
>  
>  cstart.o = $(TEST_DIR)/cstart64.o
> -cflatobjs += lib/arm64/processor.o
> -cflatobjs += lib/arm64/spinlock.o
> +cflatobjs += lib/ppc64/spinlock.o
>  
> -# arm64 specific tests
> +# ppc64 specific tests
>  tests =
>  
>  include $(TEST_DIR)/Makefile.common
>  
> -arch_clean: arm_clean
> -	$(RM) lib/arm64/.*.d
> +arch_clean: powerpc_clean
> +	$(RM) lib/ppc64/.*.d
> diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> index efdf5d7109ffb..84087057c0ce2 100644
> --- a/powerpc/flat.lds
> +++ b/powerpc/flat.lds
> @@ -4,6 +4,8 @@ SECTIONS
>      .text : { *(.init) *(.text) *(.text.*) }
>      . = ALIGN(64K);
>      etext = .;
> +    .opd : { *(.opd) }
> +    . = ALIGN(16);
>      .data : {
>          *(.data)
>      }
> @@ -11,16 +13,20 @@ SECTIONS
>      .rodata : { *(.rodata) }
>      . = ALIGN(16);
>      .bss : { *(.bss) }
> +    . = ALIGN(256);
> +    /*
> +     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
> +     */
> +    tocptr = . + 32K;
> +    .got : { *(.toc) *(.got) }
>      . = ALIGN(64K);
>      edata = .;
>      . += 64K;
>      . = ALIGN(64K);
>      /*
> -     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
> -     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
> -     * sp must always be strictly less than the true stacktop
> +     * stackptr set with initial stack frame (64 bytes) preallocated
>       */
> -    stackptr = . - 16;
> +    stackptr = . - 64;
>      stacktop = .;
>  }
>  

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
@ 2016-02-17  1:45     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:45 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 5295 bytes --]

On Mon, Feb 15, 2016 at 02:49:18PM +0100, Andrew Jones wrote:
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  powerpc/Makefile.common | 40 ++++++++++------------------------------
>  powerpc/Makefile.ppc64  | 15 +++++++--------
>  powerpc/flat.lds        | 14 ++++++++++----
>  3 files changed, 27 insertions(+), 42 deletions(-)
> 
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index dd3a0ca327d06..13b828ab171d6 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -1,17 +1,15 @@
>  #
> -# arm common makefile
> +# powerpc common makefile
>  #
>  # Authors: Andrew Jones <drjones@redhat.com>
>  #
>  
>  ifeq ($(LOADADDR),)
> -	# qemu mach-virt default load address
> -	LOADADDR = 0x40000000
> +	LOADADDR = 0x0

I was trying to check what LOADADDR means, to see if this was correct,
but it appears it isn't actually being used yet.

Otherwise,

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

>  endif
>  
>  tests-common = \
> -	$(TEST_DIR)/selftest.flat \
> -	$(TEST_DIR)/spinlock-test.flat
> +	$(TEST_DIR)/selftest.elf
>  
>  all: test_cases
>  
> @@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
>  cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
> -cflatobjs += lib/virtio.o
> -cflatobjs += lib/virtio-mmio.o
> -cflatobjs += lib/chr-testdev.o
> -cflatobjs += lib/arm/io.o
> -cflatobjs += lib/arm/setup.o
> -cflatobjs += lib/arm/mmu.o
> -cflatobjs += lib/arm/bitops.o
> -cflatobjs += lib/arm/psci.o
> -cflatobjs += lib/arm/smp.o
> -
> -libeabi = lib/arm/libeabi.a
> -eabiobjs = lib/arm/eabi_compat.o
> +cflatobjs += lib/powerpc/io.o
>  
>  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
>  
> -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
>  %.elf: LDFLAGS = $(CFLAGS) -nostdlib
> -%.elf: %.o $(FLATLIBS) arm/flat.lds
> +%.elf: %.o $(FLATLIBS) powerpc/flat.lds
>  	$(CC) $(LDFLAGS) -o $@ \
> -		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> +		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
>  
> -%.flat: %.elf
> -	$(OBJCOPY) -O binary $^ $@
> -
> -$(libeabi): $(eabiobjs)
> -	$(AR) rcs $@ $^
> -
> -arm_clean: libfdt_clean asm_offsets_clean
> -	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> -	      $(TEST_DIR)/.*.d lib/arm/.*.d
> +powerpc_clean: libfdt_clean asm_offsets_clean
> +	$(RM) $(TEST_DIR)/*.{o,elf} \
> +	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
>  
>  ##################################################################
>  
> @@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
>  test_cases: $(generated_files) $(tests-common) $(tests)
>  
>  $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> -$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
> diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> index 0b0761c729c7c..95bf6772d65ed 100644
> --- a/powerpc/Makefile.ppc64
> +++ b/powerpc/Makefile.ppc64
> @@ -1,20 +1,19 @@
>  #
> -# arm64 makefile
> +# ppc64 makefile
>  #
>  # Authors: Andrew Jones <drjones@redhat.com>
>  #
>  bits = 64
> -ldarch = elf64-littleaarch64
> -kernel_offset = 0x80000
> +ldarch = elf64-powerpc
> +kernel_offset = 0x0
>  
>  cstart.o = $(TEST_DIR)/cstart64.o
> -cflatobjs += lib/arm64/processor.o
> -cflatobjs += lib/arm64/spinlock.o
> +cflatobjs += lib/ppc64/spinlock.o
>  
> -# arm64 specific tests
> +# ppc64 specific tests
>  tests =
>  
>  include $(TEST_DIR)/Makefile.common
>  
> -arch_clean: arm_clean
> -	$(RM) lib/arm64/.*.d
> +arch_clean: powerpc_clean
> +	$(RM) lib/ppc64/.*.d
> diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> index efdf5d7109ffb..84087057c0ce2 100644
> --- a/powerpc/flat.lds
> +++ b/powerpc/flat.lds
> @@ -4,6 +4,8 @@ SECTIONS
>      .text : { *(.init) *(.text) *(.text.*) }
>      . = ALIGN(64K);
>      etext = .;
> +    .opd : { *(.opd) }
> +    . = ALIGN(16);
>      .data : {
>          *(.data)
>      }
> @@ -11,16 +13,20 @@ SECTIONS
>      .rodata : { *(.rodata) }
>      . = ALIGN(16);
>      .bss : { *(.bss) }
> +    . = ALIGN(256);
> +    /*
> +     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
> +     */
> +    tocptr = . + 32K;
> +    .got : { *(.toc) *(.got) }
>      . = ALIGN(64K);
>      edata = .;
>      . += 64K;
>      . = ALIGN(64K);
>      /*
> -     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
> -     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
> -     * sp must always be strictly less than the true stacktop
> +     * stackptr set with initial stack frame (64 bytes) preallocated
>       */
> -    stackptr = . - 16;
> +    stackptr = . - 64;
>      stacktop = .;
>  }
>  

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 10/17] powerpc/ppc64: add a boot rom
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  1:50     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:50 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 2520 bytes --]

On Mon, Feb 15, 2016 at 02:49:19PM +0100, Andrew Jones wrote:
> Make a one line replacement for SLOF. This bootloader just
> jumps to 0x400000, because we know the kernel will be there.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  powerpc/.gitignore      |  1 +
>  powerpc/Makefile.common | 11 +++++++++--
>  powerpc/boot_rom.S      |  5 +++++
>  3 files changed, 15 insertions(+), 2 deletions(-)
>  create mode 100644 powerpc/.gitignore
>  create mode 100644 powerpc/boot_rom.S
> 
> diff --git a/powerpc/.gitignore b/powerpc/.gitignore
> new file mode 100644
> index 0000000000000..2f017a8e61d4b
> --- /dev/null
> +++ b/powerpc/.gitignore
> @@ -0,0 +1 @@
> +boot_rom.bin
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index 13b828ab171d6..0c3eaba0d3aab 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -11,7 +11,7 @@ endif
>  tests-common = \
>  	$(TEST_DIR)/selftest.elf
>  
> -all: test_cases
> +all: $(TEST_DIR)/boot_rom.bin test_cases
>  
>  ##################################################################
>  phys_base = $(LOADADDR)
> @@ -40,8 +40,15 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
>  		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
>  
> +$(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
> +	dd if=/dev/zero of=$@ bs=256 count=1
> +	$(OBJCOPY) -O binary $^ >(cat - >>$@)
> +
> +$(TEST_DIR)/boot_rom.elf: $(TEST_DIR)/boot_rom.o
> +	$(LD) -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $<
> +
>  powerpc_clean: libfdt_clean asm_offsets_clean
> -	$(RM) $(TEST_DIR)/*.{o,elf} \
> +	$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/boot_rom.bin \
>  	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
>  
>  ##################################################################
> diff --git a/powerpc/boot_rom.S b/powerpc/boot_rom.S
> new file mode 100644
> index 0000000000000..ae2c08ddce3c1
> --- /dev/null
> +++ b/powerpc/boot_rom.S
> @@ -0,0 +1,5 @@
> +#define SPAPR_KERNEL_LOAD_ADDR 0x400000
> +.text
> +.globl start
> +start:
> +	b	SPAPR_KERNEL_LOAD_ADDR - 0x100

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 10/17] powerpc/ppc64: add a boot rom
@ 2016-02-17  1:50     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  1:50 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 2520 bytes --]

On Mon, Feb 15, 2016 at 02:49:19PM +0100, Andrew Jones wrote:
> Make a one line replacement for SLOF. This bootloader just
> jumps to 0x400000, because we know the kernel will be there.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  powerpc/.gitignore      |  1 +
>  powerpc/Makefile.common | 11 +++++++++--
>  powerpc/boot_rom.S      |  5 +++++
>  3 files changed, 15 insertions(+), 2 deletions(-)
>  create mode 100644 powerpc/.gitignore
>  create mode 100644 powerpc/boot_rom.S
> 
> diff --git a/powerpc/.gitignore b/powerpc/.gitignore
> new file mode 100644
> index 0000000000000..2f017a8e61d4b
> --- /dev/null
> +++ b/powerpc/.gitignore
> @@ -0,0 +1 @@
> +boot_rom.bin
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index 13b828ab171d6..0c3eaba0d3aab 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -11,7 +11,7 @@ endif
>  tests-common = \
>  	$(TEST_DIR)/selftest.elf
>  
> -all: test_cases
> +all: $(TEST_DIR)/boot_rom.bin test_cases
>  
>  ##################################################################
>  phys_base = $(LOADADDR)
> @@ -40,8 +40,15 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
>  		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
>  
> +$(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
> +	dd if=/dev/zero of=$@ bs=256 count=1
> +	$(OBJCOPY) -O binary $^ >(cat - >>$@)
> +
> +$(TEST_DIR)/boot_rom.elf: $(TEST_DIR)/boot_rom.o
> +	$(LD) -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $<
> +
>  powerpc_clean: libfdt_clean asm_offsets_clean
> -	$(RM) $(TEST_DIR)/*.{o,elf} \
> +	$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/boot_rom.bin \
>  	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
>  
>  ##################################################################
> diff --git a/powerpc/boot_rom.S b/powerpc/boot_rom.S
> new file mode 100644
> index 0000000000000..ae2c08ddce3c1
> --- /dev/null
> +++ b/powerpc/boot_rom.S
> @@ -0,0 +1,5 @@
> +#define SPAPR_KERNEL_LOAD_ADDR 0x400000
> +.text
> +.globl start
> +start:
> +	b	SPAPR_KERNEL_LOAD_ADDR - 0x100

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  2:04     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:04 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 8479 bytes --]

On Mon, Feb 15, 2016 at 02:49:20PM +0100, Andrew Jones wrote:
> Add broken sc1 detection and patching and an hcall for putchar,
> to use in puts. That, along with a couple more lines in start to
> prepare for C code, and a branch to main(), gets us "hello world".
> Run with
> 
> qemu-system-ppc64 -M pseries            \
>         -bios powerpc/boot_rom.bin      \
>         -display none -serial stdio     \
>         -kernel powerpc/selftest.elf
> 
> (We're still not relocating yet, that comes in a later patch. Thus,
>  testing hello-world at this point requires a hacked QEMU and linking
>  the unit test at QEMU's kernel load address.)
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
>  lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/powerpc/io.c        | 15 ++++++++--
>  lib/ppc64/asm/hcall.h   |  1 +
>  powerpc/Makefile.common |  2 ++
>  powerpc/cstart64.S      | 21 +++++++++++++
>  6 files changed, 162 insertions(+), 2 deletions(-)
>  create mode 100644 lib/powerpc/asm/hcall.h
>  create mode 100644 lib/powerpc/hcall.c
>  create mode 100644 lib/ppc64/asm/hcall.h
> 
> diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
> new file mode 100644
> index 0000000000000..f861287ac2083
> --- /dev/null
> +++ b/lib/powerpc/asm/hcall.h
> @@ -0,0 +1,46 @@
> +#ifndef _ASMPOWERPC_HCALL_H_
> +#define _ASMPOWERPC_HCALL_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.
> + */
> +
> +#define SC1			0x44000022
> +#define SC1_REPLACEMENT		0x7c000268
> +
> +#define H_SUCCESS		0
> +#define H_HARDWARE		-1
> +#define H_FUNCTION		-2
> +#define H_PRIVILEGE		-3
> +#define H_PARAMETER		-4
> +
> +#define H_SET_DABR		0x28
> +#define H_PUT_TERM_CHAR		0x58
> +
> +#ifndef __ASSEMBLY__
> +#include <libcflat.h>
> +
> +/*
> + * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
> + * Returns true if we are.
> + */
> +extern bool hcall_have_broken_sc1(void);
> +
> +/*
> + * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
> + * allowing all hypercalls built on it to work.
> + */
> +extern void hcall_patch_broken_sc1(void);
> +
> +/*
> + * hcall is the hypercall wrapper function. unittests may do what
> + * they like, but the framework should make all hypercalls through
> + * here to ensure they use a working sc1 instruction, and properly
> + * handle clobbered registers. @nr is the hypercall number.
> + */
> +extern unsigned long
> +hcall(unsigned long nr, unsigned long *in, unsigned long *out);
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* _ASMPOWERPC_HCALL_H_ */
> diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
> new file mode 100644
> index 0000000000000..db99949352133
> --- /dev/null
> +++ b/lib/powerpc/hcall.c
> @@ -0,0 +1,79 @@
> +/*
> + * Hypercall helpers
> + *
> + * broken_sc1 probing/patching inspired by SLOF, see
> + *   SLOF:lib/libhvcall/brokensc1.c
> + *
> + * hcall() implementation inspired by Linux's epapr_hypercall, see
> + *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
> +
> +static u32 sc1[];
> +
> +bool hcall_have_broken_sc1(void)
> +{
> +	register unsigned long r3 asm("r3") = H_SET_DABR;
> +	register unsigned long r4 asm("r4") = 0;
> +
> +	asm volatile("sc 1"
> +	: "=r" (r3)
> +	: "r" (r3), "r" (r4)
> +	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
> +	return r3 == (unsigned long)H_PRIVILEGE;
> +}
> +
> +void hcall_patch_broken_sc1(void)
> +{
> +	if (!hcall_have_broken_sc1())
> +		return;
> +	sc1[0] = SC1_REPLACEMENT;
> +}
> +
> +unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
> +{
> +	register unsigned long r3 asm("r3") = nr;
> +	register unsigned long r4 asm("r4") = in[0];
> +	register unsigned long r5 asm("r5") = in[1];
> +	register unsigned long r6 asm("r6") = in[2];
> +	register unsigned long r7 asm("r7") = in[3];
> +	register unsigned long r8 asm("r8") = in[4];
> +	register unsigned long r9 asm("r9") = in[5];
> +	register unsigned long r10 asm("r10") = in[6];
> +	register unsigned long r11 asm("r11") = in[7];
> +
> +	asm volatile("bl sc1"
> +		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
> +		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
> +		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
> +		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
> +		: "r12", "memory", "lr");
> +
> +	out[0] = r4;
> +	out[1] = r5;
> +	out[2] = r6;
> +	out[3] = r7;
> +	out[4] = r8;
> +	out[5] = r9;
> +	out[6] = r10;
> +	out[7] = r11;
> +
> +	return r3;

I'm not sure there's much advantage to having this in C, rather than
folding this and the sc1 symbol into a single asm implemented hcall
function.

Doing it that way might more easily allow you to avoid packing the
arguments into an array, before unpacking them into registers again,
which seems a bit perverse.

> +}
> +
> +void putchar(int c)
> +{
> +	unsigned long in[8], out[8];
> +
> +	in[0] = 0; /* default vty */
> +	in[1] = 1; /* just 1 byte */
> +	in[2] = (unsigned long)c << 56;
> +
> +	hcall(H_PUT_TERM_CHAR, in, out);
> +}
> diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
> index 0af45742fc900..5e1fa8dd96ab6 100644
> --- a/lib/powerpc/io.c
> +++ b/lib/powerpc/io.c
> @@ -6,15 +6,26 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <asm/spinlock.h>
> +
> +extern void halt(int code);
> +extern void putchar(int c);
> +
> +static struct spinlock uart_lock;
>  
>  void io_init(void)
>  {
>  }
>  
> -void puts(const char *s __unused)
> +void puts(const char *s)
>  {
> +	spin_lock(&uart_lock);

The name uart_lock isn't really accurate, since it's a hypervisor
console rather than serial.

> +	while (*s)
> +		putchar(*s++);
> +	spin_unlock(&uart_lock);
>  }
>  
> -void exit(int code __unused)
> +void exit(int code)
>  {
> +	halt(code);
>  }
> diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
> new file mode 100644
> index 0000000000000..daabaca510cd4
> --- /dev/null
> +++ b/lib/ppc64/asm/hcall.h
> @@ -0,0 +1 @@
> +#include "../../powerpc/asm/hcall.h"
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index 0c3eaba0d3aab..89610b525f0c1 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
>  CFLAGS += -Wextra
>  CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
> +CFLAGS += -Wa,-mregnames
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include scripts/asm-offsets.mak
> @@ -29,6 +30,7 @@ cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
>  cflatobjs += lib/powerpc/io.o
> +cflatobjs += lib/powerpc/hcall.o
>  
>  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index f90828dee1c19..623fd693b02d1 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -7,13 +7,34 @@
>   */
>  #define __ASSEMBLY__
>  
> +#define LOAD_REG_IMMEDIATE(reg,expr)		\
> +	lis	reg,(expr)@highest;		\
> +	ori	reg,reg,(expr)@higher;		\
> +	rldicr	reg,reg,32,31;			\
> +	oris	reg,reg,(expr)@h;		\
> +	ori	reg,reg,(expr)@l;
> +
> +#define LOAD_REG_ADDR(reg,name)			\
> +	ld	reg,name@got(r2)
> +
>  .section .init
>  
>  .globl start
>  start:
> +	LOAD_REG_IMMEDIATE(r1, stackptr)
> +	LOAD_REG_IMMEDIATE(r2, tocptr)
> +	bl	hcall_patch_broken_sc1

Come to that, is there any point putting hcall_patch_broken_sc1 in C,
rather than just doing it inline here.

> +	bl	main
> +	bl	exit
>  	b	halt
>  
>  .text
> +.align 3
> +
> +.globl sc1
> +sc1:
> +	sc	1
> +	blr
>  
>  .globl halt
>  halt:

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
@ 2016-02-17  2:04     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:04 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 8479 bytes --]

On Mon, Feb 15, 2016 at 02:49:20PM +0100, Andrew Jones wrote:
> Add broken sc1 detection and patching and an hcall for putchar,
> to use in puts. That, along with a couple more lines in start to
> prepare for C code, and a branch to main(), gets us "hello world".
> Run with
> 
> qemu-system-ppc64 -M pseries            \
>         -bios powerpc/boot_rom.bin      \
>         -display none -serial stdio     \
>         -kernel powerpc/selftest.elf
> 
> (We're still not relocating yet, that comes in a later patch. Thus,
>  testing hello-world at this point requires a hacked QEMU and linking
>  the unit test at QEMU's kernel load address.)
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
>  lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/powerpc/io.c        | 15 ++++++++--
>  lib/ppc64/asm/hcall.h   |  1 +
>  powerpc/Makefile.common |  2 ++
>  powerpc/cstart64.S      | 21 +++++++++++++
>  6 files changed, 162 insertions(+), 2 deletions(-)
>  create mode 100644 lib/powerpc/asm/hcall.h
>  create mode 100644 lib/powerpc/hcall.c
>  create mode 100644 lib/ppc64/asm/hcall.h
> 
> diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
> new file mode 100644
> index 0000000000000..f861287ac2083
> --- /dev/null
> +++ b/lib/powerpc/asm/hcall.h
> @@ -0,0 +1,46 @@
> +#ifndef _ASMPOWERPC_HCALL_H_
> +#define _ASMPOWERPC_HCALL_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.
> + */
> +
> +#define SC1			0x44000022
> +#define SC1_REPLACEMENT		0x7c000268
> +
> +#define H_SUCCESS		0
> +#define H_HARDWARE		-1
> +#define H_FUNCTION		-2
> +#define H_PRIVILEGE		-3
> +#define H_PARAMETER		-4
> +
> +#define H_SET_DABR		0x28
> +#define H_PUT_TERM_CHAR		0x58
> +
> +#ifndef __ASSEMBLY__
> +#include <libcflat.h>
> +
> +/*
> + * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
> + * Returns true if we are.
> + */
> +extern bool hcall_have_broken_sc1(void);
> +
> +/*
> + * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
> + * allowing all hypercalls built on it to work.
> + */
> +extern void hcall_patch_broken_sc1(void);
> +
> +/*
> + * hcall is the hypercall wrapper function. unittests may do what
> + * they like, but the framework should make all hypercalls through
> + * here to ensure they use a working sc1 instruction, and properly
> + * handle clobbered registers. @nr is the hypercall number.
> + */
> +extern unsigned long
> +hcall(unsigned long nr, unsigned long *in, unsigned long *out);
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* _ASMPOWERPC_HCALL_H_ */
> diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
> new file mode 100644
> index 0000000000000..db99949352133
> --- /dev/null
> +++ b/lib/powerpc/hcall.c
> @@ -0,0 +1,79 @@
> +/*
> + * Hypercall helpers
> + *
> + * broken_sc1 probing/patching inspired by SLOF, see
> + *   SLOF:lib/libhvcall/brokensc1.c
> + *
> + * hcall() implementation inspired by Linux's epapr_hypercall, see
> + *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
> +
> +static u32 sc1[];
> +
> +bool hcall_have_broken_sc1(void)
> +{
> +	register unsigned long r3 asm("r3") = H_SET_DABR;
> +	register unsigned long r4 asm("r4") = 0;
> +
> +	asm volatile("sc 1"
> +	: "=r" (r3)
> +	: "r" (r3), "r" (r4)
> +	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
> +	return r3 == (unsigned long)H_PRIVILEGE;
> +}
> +
> +void hcall_patch_broken_sc1(void)
> +{
> +	if (!hcall_have_broken_sc1())
> +		return;
> +	sc1[0] = SC1_REPLACEMENT;
> +}
> +
> +unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
> +{
> +	register unsigned long r3 asm("r3") = nr;
> +	register unsigned long r4 asm("r4") = in[0];
> +	register unsigned long r5 asm("r5") = in[1];
> +	register unsigned long r6 asm("r6") = in[2];
> +	register unsigned long r7 asm("r7") = in[3];
> +	register unsigned long r8 asm("r8") = in[4];
> +	register unsigned long r9 asm("r9") = in[5];
> +	register unsigned long r10 asm("r10") = in[6];
> +	register unsigned long r11 asm("r11") = in[7];
> +
> +	asm volatile("bl sc1"
> +		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
> +		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
> +		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
> +		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
> +		: "r12", "memory", "lr");
> +
> +	out[0] = r4;
> +	out[1] = r5;
> +	out[2] = r6;
> +	out[3] = r7;
> +	out[4] = r8;
> +	out[5] = r9;
> +	out[6] = r10;
> +	out[7] = r11;
> +
> +	return r3;

I'm not sure there's much advantage to having this in C, rather than
folding this and the sc1 symbol into a single asm implemented hcall
function.

Doing it that way might more easily allow you to avoid packing the
arguments into an array, before unpacking them into registers again,
which seems a bit perverse.

> +}
> +
> +void putchar(int c)
> +{
> +	unsigned long in[8], out[8];
> +
> +	in[0] = 0; /* default vty */
> +	in[1] = 1; /* just 1 byte */
> +	in[2] = (unsigned long)c << 56;
> +
> +	hcall(H_PUT_TERM_CHAR, in, out);
> +}
> diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
> index 0af45742fc900..5e1fa8dd96ab6 100644
> --- a/lib/powerpc/io.c
> +++ b/lib/powerpc/io.c
> @@ -6,15 +6,26 @@
>   * This work is licensed under the terms of the GNU LGPL, version 2.
>   */
>  #include <libcflat.h>
> +#include <asm/spinlock.h>
> +
> +extern void halt(int code);
> +extern void putchar(int c);
> +
> +static struct spinlock uart_lock;
>  
>  void io_init(void)
>  {
>  }
>  
> -void puts(const char *s __unused)
> +void puts(const char *s)
>  {
> +	spin_lock(&uart_lock);

The name uart_lock isn't really accurate, since it's a hypervisor
console rather than serial.

> +	while (*s)
> +		putchar(*s++);
> +	spin_unlock(&uart_lock);
>  }
>  
> -void exit(int code __unused)
> +void exit(int code)
>  {
> +	halt(code);
>  }
> diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
> new file mode 100644
> index 0000000000000..daabaca510cd4
> --- /dev/null
> +++ b/lib/ppc64/asm/hcall.h
> @@ -0,0 +1 @@
> +#include "../../powerpc/asm/hcall.h"
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index 0c3eaba0d3aab..89610b525f0c1 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
>  CFLAGS += -Wextra
>  CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
> +CFLAGS += -Wa,-mregnames
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include scripts/asm-offsets.mak
> @@ -29,6 +30,7 @@ cflatobjs += lib/util.o
>  cflatobjs += lib/alloc.o
>  cflatobjs += lib/devicetree.o
>  cflatobjs += lib/powerpc/io.o
> +cflatobjs += lib/powerpc/hcall.o
>  
>  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index f90828dee1c19..623fd693b02d1 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -7,13 +7,34 @@
>   */
>  #define __ASSEMBLY__
>  
> +#define LOAD_REG_IMMEDIATE(reg,expr)		\
> +	lis	reg,(expr)@highest;		\
> +	ori	reg,reg,(expr)@higher;		\
> +	rldicr	reg,reg,32,31;			\
> +	oris	reg,reg,(expr)@h;		\
> +	ori	reg,reg,(expr)@l;
> +
> +#define LOAD_REG_ADDR(reg,name)			\
> +	ld	reg,name@got(r2)
> +
>  .section .init
>  
>  .globl start
>  start:
> +	LOAD_REG_IMMEDIATE(r1, stackptr)
> +	LOAD_REG_IMMEDIATE(r2, tocptr)
> +	bl	hcall_patch_broken_sc1

Come to that, is there any point putting hcall_patch_broken_sc1 in C,
rather than just doing it inline here.

> +	bl	main
> +	bl	exit
>  	b	halt
>  
>  .text
> +.align 3
> +
> +.globl sc1
> +sc1:
> +	sc	1
> +	blr
>  
>  .globl halt
>  halt:

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  2:11     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:11 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 9411 bytes --]

On Mon, Feb 15, 2016 at 02:49:21PM +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.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  lib/powerpc/asm/setup.h |  36 +++++++++++++++
>  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/ppc64/asm/setup.h   |   1 +
>  powerpc/Makefile.common |   1 +
>  powerpc/cstart64.S      |  16 +++++++
>  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
>  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> --- /dev/null
> +++ b/lib/powerpc/asm/setup.h
> @@ -0,0 +1,36 @@
> +#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;
> +
> +#define PHYSICAL_START		(__physical_start)
> +#define PHYSICAL_END		(__physical_end)
> +
> +#ifdef __powerpc64__
> +#define L1_CACHE_SHIFT		7
> +#else
> +#define L1_CACHE_SHIFT		5
> +#endif

These aren't necessarily true for all systems, although it's probably
right for all BE, BookS systems supporting KVM at present.  It would
be better to get the cache alignment from the device tree if possible.

Also, is this correct for LE, which I imagine you'll want to support
soon (I don't recall if __powerpc64__ is defined for both BE and LE
systems).

> +#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
> new file mode 100644
> index 0000000000000..2514be4fa273c
> --- /dev/null
> +++ b/lib/powerpc/setup.c
> @@ -0,0 +1,119 @@
> +/*
> + * 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;
> +
> +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
> +{
> +	int cpu = nr_cpus++;
> +
> +	if (cpu >= NR_CPUS) {
> +		printf("Number cpus exceeds maximum supported (%d).\n",
> +			NR_CPUS);
> +		assert(0);
> +	}
> +	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)
> +{
> +	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(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/Makefile.common b/powerpc/Makefile.common
> index 89610b525f0c1..de4d1ef3ac816 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -31,6 +31,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)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index 623fd693b02d1..6d47eb59bb53e 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -19,11 +19,27 @@
>  
>  .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)
> +
>  	bl	hcall_patch_broken_sc1
> +
> +	/* complete setup */
> +	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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
@ 2016-02-17  2:11     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:11 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 9411 bytes --]

On Mon, Feb 15, 2016 at 02:49:21PM +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.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  lib/powerpc/asm/setup.h |  36 +++++++++++++++
>  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/ppc64/asm/setup.h   |   1 +
>  powerpc/Makefile.common |   1 +
>  powerpc/cstart64.S      |  16 +++++++
>  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
>  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> --- /dev/null
> +++ b/lib/powerpc/asm/setup.h
> @@ -0,0 +1,36 @@
> +#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;
> +
> +#define PHYSICAL_START		(__physical_start)
> +#define PHYSICAL_END		(__physical_end)
> +
> +#ifdef __powerpc64__
> +#define L1_CACHE_SHIFT		7
> +#else
> +#define L1_CACHE_SHIFT		5
> +#endif

These aren't necessarily true for all systems, although it's probably
right for all BE, BookS systems supporting KVM at present.  It would
be better to get the cache alignment from the device tree if possible.

Also, is this correct for LE, which I imagine you'll want to support
soon (I don't recall if __powerpc64__ is defined for both BE and LE
systems).

> +#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
> new file mode 100644
> index 0000000000000..2514be4fa273c
> --- /dev/null
> +++ b/lib/powerpc/setup.c
> @@ -0,0 +1,119 @@
> +/*
> + * 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;
> +
> +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
> +{
> +	int cpu = nr_cpus++;
> +
> +	if (cpu >= NR_CPUS) {
> +		printf("Number cpus exceeds maximum supported (%d).\n",
> +			NR_CPUS);
> +		assert(0);
> +	}
> +	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)
> +{
> +	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(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/Makefile.common b/powerpc/Makefile.common
> index 89610b525f0c1..de4d1ef3ac816 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -31,6 +31,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)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index 623fd693b02d1..6d47eb59bb53e 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -19,11 +19,27 @@
>  
>  .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)
> +
>  	bl	hcall_patch_broken_sc1
> +
> +	/* complete setup */
> +	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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 13/17] powerpc/ppc64: relocate linker VMAs
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17  2:14     ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:14 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 7503 bytes --]

On Mon, Feb 15, 2016 at 02:49:22PM +0100, Andrew Jones wrote:
> QEMU loads the unit test, but due to the way it translates the
> unit test's linker VMA to the LMA, we can't just link such that
> VMA == LMA. Thus, we link with VMA == 0x0, and then deal with
> relocation.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  configure               |  2 ++
>  powerpc/Makefile.common | 11 ++++++++--
>  powerpc/Makefile.ppc64  |  1 +
>  powerpc/cstart64.S      | 34 ++++++++++++++++++++++++++----
>  powerpc/flat.lds        | 13 +++++++++++-
>  powerpc/reloc64.c       | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 109 insertions(+), 7 deletions(-)
>  create mode 100644 powerpc/reloc64.c
> 
> diff --git a/configure b/configure
> index b367224093369..b2ad199da7873 100755
> --- a/configure
> +++ b/configure
> @@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build
>  cc=gcc
>  ld=ld
>  objcopy=objcopy
> +objdump=objdump
>  ar=ar
>  arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
>  host=$arch
> @@ -132,6 +133,7 @@ PROCESSOR=$processor
>  CC=$cross_prefix$cc
>  LD=$cross_prefix$ld
>  OBJCOPY=$cross_prefix$objcopy
> +OBJDUMP=$cross_prefix$objdump
>  AR=$cross_prefix$ar
>  API=$api
>  TEST_DIR=$testdir
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index de4d1ef3ac816..9654bce1752eb 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -22,6 +22,7 @@ CFLAGS += -Wextra
>  CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
>  CFLAGS += -Wa,-mregnames
> +CFLAGS += -fpie
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include scripts/asm-offsets.mak
> @@ -37,11 +38,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
>  
>  FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
> -%.elf: LDFLAGS = $(CFLAGS) -nostdlib
> +%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie
>  %.elf: %.o $(FLATLIBS) powerpc/flat.lds
>  	$(CC) $(LDFLAGS) -o $@ \
>  		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
> +	@echo -n Checking $@ for unsupported reloc types...
> +	@if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then	\
> +		false;							\
> +	else								\
> +		echo " looks good.";					\
> +	fi
>  
>  $(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
>  	dd if=/dev/zero of=$@ bs=256 count=1
> @@ -60,4 +67,4 @@ generated_files = $(asm-offsets)
>  
>  test_cases: $(generated_files) $(tests-common) $(tests)
>  
> -$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> +$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o
> diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> index 95bf6772d65ed..e965627991916 100644
> --- a/powerpc/Makefile.ppc64
> +++ b/powerpc/Makefile.ppc64
> @@ -8,6 +8,7 @@ ldarch = elf64-powerpc
>  kernel_offset = 0x0
>  
>  cstart.o = $(TEST_DIR)/cstart64.o
> +reloc.o  = $(TEST_DIR)/reloc64.o
>  cflatobjs += lib/ppc64/spinlock.o
>  
>  # ppc64 specific tests
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index 6d47eb59bb53e..d1a5531eb1c44 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -24,12 +24,33 @@
>   */
>  .globl start
>  start:
> -	LOAD_REG_IMMEDIATE(r1, stackptr)
> -	LOAD_REG_IMMEDIATE(r2, tocptr)
> +	/*
> +	 * We were loaded at QEMU's kernel load address, but we're not
> +	 * allowed to link there due to how QEMU deals with linker VMAs,
> +	 * so we just linked at zero. This means the first thing to do is
> +	 * to find our stack and toc, and then do a relocate.
> +	 */
> +	bl	0f
> +0:	mflr	r31
> +	subi	r31, r31, 0b - start    /* QEMU's kernel load address */
> +	ld	r1, (p_stack - start)(r31)
> +	ld	r2, (p_toc - start)(r31)
> +	add	r1, r1, r31
> +	add	r2, r2, r31
>  
>  	/* save DTB pointer */
>  	std	r3, 56(r1)
>  
> +	/*
> +	 * Call relocate. relocate is C code, but careful to not use
> +	 * any global references, as they may use absolute addresses,
> +	 * which are, obviously, not yet relocated.
> +	 */
> +	mr	r3, r31
> +	ld	r4, (p_dyn - start)(r31)
> +	add	r4, r4, r31
> +	bl	relocate
> +
>  	bl	hcall_patch_broken_sc1
>  
>  	/* complete setup */
> @@ -37,13 +58,18 @@ start:
>  	bl	setup
>  
>  	/* run the test */
> -	LOAD_REG_IMMEDIATE(r5, __argc)
> -	LOAD_REG_IMMEDIATE(r4, __argv)
> +	LOAD_REG_ADDR(r5, __argc)
> +	LOAD_REG_ADDR(r4, __argv)
>  	lwz	r3, 0(r5)
>  	bl	main
>  	bl	exit
>  	b	halt
>  
> +.align 3
> +p_stack:	.llong  stackptr
> +p_toc:		.llong  tocptr
> +p_dyn:		.llong  dynamic_start
> +
>  .text
>  .align 3
>  
> diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> index 84087057c0ce2..53221e8b4211c 100644
> --- a/powerpc/flat.lds
> +++ b/powerpc/flat.lds
> @@ -6,11 +6,22 @@ SECTIONS
>      etext = .;
>      .opd : { *(.opd) }
>      . = ALIGN(16);
> +    .dynamic : {
> +        dynamic_start = .;
> +        *(.dynamic)
> +    }
> +    .dynsym : {
> +        dynsym_start = .;
> +        *(.dynsym)
> +    }
> +    .rela.dyn : { *(.rela*) }
> +    . = ALIGN(16);
>      .data : {
>          *(.data)
> +        *(.data.rel*)
>      }
>      . = ALIGN(16);
> -    .rodata : { *(.rodata) }
> +    .rodata : { *(.rodata) *(.rodata.*) }
>      . = ALIGN(16);
>      .bss : { *(.bss) }
>      . = ALIGN(256);
> diff --git a/powerpc/reloc64.c b/powerpc/reloc64.c
> new file mode 100644
> index 0000000000000..d919372bf9288
> --- /dev/null
> +++ b/powerpc/reloc64.c
> @@ -0,0 +1,55 @@
> +/*
> + * relocate R_PPC_RELATIVE RELA entries. Normally this is done in
> + * assembly code to avoid the risk of using absolute addresses before
> + * they're relocated. We use C, but cautiously (no global references).
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#define DT_NULL		0
> +#define DT_RELA 	7
> +#define DT_RELACOUNT	0x6ffffff9
> +#define R_PPC_RELATIVE	22
> +
> +struct elf64_dyn {
> +	signed long long tag;
> +	unsigned long long val;
> +};
> +
> +#define RELA_GET_TYPE(rela_ptr) ((rela_ptr)->info & 0xffffffff)
> +struct elf64_rela {
> +	unsigned long long offset;
> +	unsigned long long info;
> +	signed long long addend;
> +};
> +
> +void relocate(unsigned long load_addr, struct elf64_dyn *dyn_table)
> +{
> +	unsigned long long rela_addr = 0, rela_count = 0, *addr;
> +	struct elf64_dyn *d = dyn_table;
> +	struct elf64_rela *r;
> +
> +	while (d && d->tag != DT_NULL) {
> +		if (d->tag == DT_RELA)
> +			rela_addr = d->val;
> +		else if (d->tag == DT_RELACOUNT)
> +			rela_count = d->val;
> +		if (rela_addr && rela_count)
> +			break;
> +		++d;
> +	}
> +
> +	if (!rela_addr || !rela_count)
> +		return;
> +
> +	r = (void *)(rela_addr + load_addr);
> +
> +	while (rela_count--) {
> +		if (RELA_GET_TYPE(r) == R_PPC_RELATIVE) {
> +			addr = (void *)(r->offset + load_addr);
> +			*addr = r->addend + load_addr;
> +		}
> +		++r;
> +	}
> +}

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 13/17] powerpc/ppc64: relocate linker VMAs
@ 2016-02-17  2:14     ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-17  2:14 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 7503 bytes --]

On Mon, Feb 15, 2016 at 02:49:22PM +0100, Andrew Jones wrote:
> QEMU loads the unit test, but due to the way it translates the
> unit test's linker VMA to the LMA, we can't just link such that
> VMA == LMA. Thus, we link with VMA == 0x0, and then deal with
> relocation.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Tested-by: Laurent Vivier <lvivier@redhat.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  configure               |  2 ++
>  powerpc/Makefile.common | 11 ++++++++--
>  powerpc/Makefile.ppc64  |  1 +
>  powerpc/cstart64.S      | 34 ++++++++++++++++++++++++++----
>  powerpc/flat.lds        | 13 +++++++++++-
>  powerpc/reloc64.c       | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 109 insertions(+), 7 deletions(-)
>  create mode 100644 powerpc/reloc64.c
> 
> diff --git a/configure b/configure
> index b367224093369..b2ad199da7873 100755
> --- a/configure
> +++ b/configure
> @@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build
>  cc=gcc
>  ld=ld
>  objcopy=objcopy
> +objdump=objdump
>  ar=ar
>  arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
>  host=$arch
> @@ -132,6 +133,7 @@ PROCESSOR=$processor
>  CC=$cross_prefix$cc
>  LD=$cross_prefix$ld
>  OBJCOPY=$cross_prefix$objcopy
> +OBJDUMP=$cross_prefix$objdump
>  AR=$cross_prefix$ar
>  API=$api
>  TEST_DIR=$testdir
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index de4d1ef3ac816..9654bce1752eb 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -22,6 +22,7 @@ CFLAGS += -Wextra
>  CFLAGS += -O2
>  CFLAGS += -I lib -I lib/libfdt
>  CFLAGS += -Wa,-mregnames
> +CFLAGS += -fpie
>  
>  asm-offsets = lib/$(ARCH)/asm-offsets.h
>  include scripts/asm-offsets.mak
> @@ -37,11 +38,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
>  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
>  
>  FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
> -%.elf: LDFLAGS = $(CFLAGS) -nostdlib
> +%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie
>  %.elf: %.o $(FLATLIBS) powerpc/flat.lds
>  	$(CC) $(LDFLAGS) -o $@ \
>  		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
>  		$(filter %.o, $^) $(FLATLIBS)
> +	@echo -n Checking $@ for unsupported reloc types...
> +	@if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then	\
> +		false;							\
> +	else								\
> +		echo " looks good.";					\
> +	fi
>  
>  $(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf
>  	dd if=/dev/zero of=$@ bs=256 count=1
> @@ -60,4 +67,4 @@ generated_files = $(asm-offsets)
>  
>  test_cases: $(generated_files) $(tests-common) $(tests)
>  
> -$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> +$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o
> diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> index 95bf6772d65ed..e965627991916 100644
> --- a/powerpc/Makefile.ppc64
> +++ b/powerpc/Makefile.ppc64
> @@ -8,6 +8,7 @@ ldarch = elf64-powerpc
>  kernel_offset = 0x0
>  
>  cstart.o = $(TEST_DIR)/cstart64.o
> +reloc.o  = $(TEST_DIR)/reloc64.o
>  cflatobjs += lib/ppc64/spinlock.o
>  
>  # ppc64 specific tests
> diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> index 6d47eb59bb53e..d1a5531eb1c44 100644
> --- a/powerpc/cstart64.S
> +++ b/powerpc/cstart64.S
> @@ -24,12 +24,33 @@
>   */
>  .globl start
>  start:
> -	LOAD_REG_IMMEDIATE(r1, stackptr)
> -	LOAD_REG_IMMEDIATE(r2, tocptr)
> +	/*
> +	 * We were loaded at QEMU's kernel load address, but we're not
> +	 * allowed to link there due to how QEMU deals with linker VMAs,
> +	 * so we just linked at zero. This means the first thing to do is
> +	 * to find our stack and toc, and then do a relocate.
> +	 */
> +	bl	0f
> +0:	mflr	r31
> +	subi	r31, r31, 0b - start    /* QEMU's kernel load address */
> +	ld	r1, (p_stack - start)(r31)
> +	ld	r2, (p_toc - start)(r31)
> +	add	r1, r1, r31
> +	add	r2, r2, r31
>  
>  	/* save DTB pointer */
>  	std	r3, 56(r1)
>  
> +	/*
> +	 * Call relocate. relocate is C code, but careful to not use
> +	 * any global references, as they may use absolute addresses,
> +	 * which are, obviously, not yet relocated.
> +	 */
> +	mr	r3, r31
> +	ld	r4, (p_dyn - start)(r31)
> +	add	r4, r4, r31
> +	bl	relocate
> +
>  	bl	hcall_patch_broken_sc1
>  
>  	/* complete setup */
> @@ -37,13 +58,18 @@ start:
>  	bl	setup
>  
>  	/* run the test */
> -	LOAD_REG_IMMEDIATE(r5, __argc)
> -	LOAD_REG_IMMEDIATE(r4, __argv)
> +	LOAD_REG_ADDR(r5, __argc)
> +	LOAD_REG_ADDR(r4, __argv)
>  	lwz	r3, 0(r5)
>  	bl	main
>  	bl	exit
>  	b	halt
>  
> +.align 3
> +p_stack:	.llong  stackptr
> +p_toc:		.llong  tocptr
> +p_dyn:		.llong  dynamic_start
> +
>  .text
>  .align 3
>  
> diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> index 84087057c0ce2..53221e8b4211c 100644
> --- a/powerpc/flat.lds
> +++ b/powerpc/flat.lds
> @@ -6,11 +6,22 @@ SECTIONS
>      etext = .;
>      .opd : { *(.opd) }
>      . = ALIGN(16);
> +    .dynamic : {
> +        dynamic_start = .;
> +        *(.dynamic)
> +    }
> +    .dynsym : {
> +        dynsym_start = .;
> +        *(.dynsym)
> +    }
> +    .rela.dyn : { *(.rela*) }
> +    . = ALIGN(16);
>      .data : {
>          *(.data)
> +        *(.data.rel*)
>      }
>      . = ALIGN(16);
> -    .rodata : { *(.rodata) }
> +    .rodata : { *(.rodata) *(.rodata.*) }
>      . = ALIGN(16);
>      .bss : { *(.bss) }
>      . = ALIGN(256);
> diff --git a/powerpc/reloc64.c b/powerpc/reloc64.c
> new file mode 100644
> index 0000000000000..d919372bf9288
> --- /dev/null
> +++ b/powerpc/reloc64.c
> @@ -0,0 +1,55 @@
> +/*
> + * relocate R_PPC_RELATIVE RELA entries. Normally this is done in
> + * assembly code to avoid the risk of using absolute addresses before
> + * they're relocated. We use C, but cautiously (no global references).
> + *
> + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#define DT_NULL		0
> +#define DT_RELA 	7
> +#define DT_RELACOUNT	0x6ffffff9
> +#define R_PPC_RELATIVE	22
> +
> +struct elf64_dyn {
> +	signed long long tag;
> +	unsigned long long val;
> +};
> +
> +#define RELA_GET_TYPE(rela_ptr) ((rela_ptr)->info & 0xffffffff)
> +struct elf64_rela {
> +	unsigned long long offset;
> +	unsigned long long info;
> +	signed long long addend;
> +};
> +
> +void relocate(unsigned long load_addr, struct elf64_dyn *dyn_table)
> +{
> +	unsigned long long rela_addr = 0, rela_count = 0, *addr;
> +	struct elf64_dyn *d = dyn_table;
> +	struct elf64_rela *r;
> +
> +	while (d && d->tag != DT_NULL) {
> +		if (d->tag == DT_RELA)
> +			rela_addr = d->val;
> +		else if (d->tag == DT_RELACOUNT)
> +			rela_count = d->val;
> +		if (rela_addr && rela_count)
> +			break;
> +		++d;
> +	}
> +
> +	if (!rela_addr || !rela_count)
> +		return;
> +
> +	r = (void *)(rela_addr + load_addr);
> +
> +	while (rela_count--) {
> +		if (RELA_GET_TYPE(r) == R_PPC_RELATIVE) {
> +			addr = (void *)(r->offset + load_addr);
> +			*addr = r->addend + load_addr;
> +		}
> +		++r;
> +	}
> +}

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
  2016-02-17  0:14     ` David Gibson
@ 2016-02-17 12:17       ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:17 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 11:14:36AM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:15PM +0100, Andrew Jones wrote:
> > arm-selftest has a couple utility functions that could be useful
> > to other unit tests, even other architectures. So move them out.
> > split_var moves to lib/util, where we can add other random
> > utilities over time. assert_args inspires report_abort, which
> > allows us to report a message, using the current prefix, that
> > we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
> > for cases when unit tests can't complete due to missing
> > dependencies of some sort, such as missing/invalid inputs from
> > the user.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  arm/selftest.c               | 45 ++++++++++++++------------------------------
> >  config/config-arm-common.mak |  1 +
> >  lib/libcflat.h               | 11 ++++++-----
> >  lib/report.c                 | 16 ++++++++++++++++
> >  lib/util.c                   | 18 ++++++++++++++++++
> >  lib/util.h                   | 23 ++++++++++++++++++++++
> >  6 files changed, 78 insertions(+), 36 deletions(-)
> >  create mode 100644 lib/util.c
> >  create mode 100644 lib/util.h
> > 
> > diff --git a/arm/selftest.c b/arm/selftest.c
> > index aad7eecd529ad..75dc91faab69a 100644
> > --- a/arm/selftest.c
> > +++ b/arm/selftest.c
> > @@ -6,6 +6,7 @@
> >   * This work is licensed under the terms of the GNU LGPL, version 2.
> >   */
> >  #include <libcflat.h>
> > +#include <util.h>
> >  #include <alloc.h>
> >  #include <devicetree.h>
> >  #include <asm/setup.h>
> > @@ -18,43 +19,21 @@
> >  #include <asm/cpumask.h>
> >  #include <asm/barrier.h>
> >  
> > -static void assert_args(int num_args, int needed_args)
> > -{
> > -	if (num_args < needed_args) {
> > -		printf("selftest: not enough arguments\n");
> > -		abort();
> > -	}
> > -}
> > -
> > -static char *split_var(char *s, long *val)
> > -{
> > -	char *p;
> > -
> > -	p = strchr(s, '=');
> > -	if (!p)
> > -		return NULL;
> > -
> > -	*val = atol(p+1);
> > -	*p = '\0';
> > -
> > -	return s;
> > -}
> > -
> >  static void check_setup(int argc, char **argv)
> >  {
> > -	int nr_tests = 0, i;
> > -	char *var;
> > +	int nr_tests = 0, len, i;
> >  	long val;
> >  
> >  	for (i = 0; i < argc; ++i) {
> >  
> > -		var = split_var(argv[i], &val);
> > -		if (!var)
> > +		len = parse_keyval(argv[i], &val);
> > +		if (len == -1)
> >  			continue;
> >  
> > -		report_prefix_push(var);
> > +		argv[i][len] = '\0';
> > +		report_prefix_push(argv[i]);
> >  
> > -		if (strcmp(var, "mem") == 0) {
> > +		if (strcmp(argv[i], "mem") == 0) {
> >  
> >  			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
> >  			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> > @@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
> >  							memsize/1024/1024);
> >  			++nr_tests;
> >  
> > -		} else if (strcmp(var, "smp") == 0) {
> > +		} else if (strcmp(argv[i], "smp") == 0) {
> >  
> >  			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
> >  			++nr_tests;
> > @@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
> >  		report_prefix_pop();
> >  	}
> >  
> > -	assert_args(nr_tests, 2);
> > +	if (nr_tests < 2)
> > +		report_abort("missing input");
> >  }
> >  
> >  static struct pt_regs expected_regs;
> > @@ -343,7 +323,10 @@ static void cpu_report(void)
> >  int main(int argc, char **argv)
> >  {
> >  	report_prefix_push("selftest");
> > -	assert_args(argc, 1);
> > +
> > +	if (!argc)
> > +		report_abort("no test specified");
> > +
> >  	report_prefix_push(argv[0]);
> >  
> >  	if (strcmp(argv[0], "setup") == 0) {
> > diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
> > index 698555d6a676f..bd153cf6ea5ba 100644
> > --- a/config/config-arm-common.mak
> > +++ b/config/config-arm-common.mak
> > @@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
> >  asm-offsets = lib/$(ARCH)/asm-offsets.h
> >  include config/asm-offsets.mak
> >  
> > +cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> >  cflatobjs += lib/virtio.o
> > diff --git a/lib/libcflat.h b/lib/libcflat.h
> > index 9747ccdbc9f1d..8411f6c5d92e3 100644
> > --- a/lib/libcflat.h
> > +++ b/lib/libcflat.h
> > @@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
> >  extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
> >  extern long atol(const char *ptr);
> >  
> > -void report_prefix_push(const char *prefix);
> > -void report_prefix_pop(void);
> > -void report(const char *msg_fmt, bool pass, ...);
> > -void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> > -int report_summary(void);
> > +extern void report_prefix_push(const char *prefix);
> > +extern void report_prefix_pop(void);
> > +extern void report(const char *msg_fmt, bool pass, ...);
> > +extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> > +extern void report_abort(const char *msg_fmt, ...);
> > +extern int report_summary(void);
> >  
> >  #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
> >  
> > diff --git a/lib/report.c b/lib/report.c
> > index 35e664108a921..62916c4ac3c8a 100644
> > --- a/lib/report.c
> > +++ b/lib/report.c
> > @@ -96,3 +96,19 @@ int report_summary(void)
> >  
> >  	spin_unlock(&lock);
> >  }
> > +
> > +void report_abort(const char *msg_fmt, ...)
> > +{
> > +	va_list va;
> > +	char buf[2000];
> > +
> > +	puts("ABORT: ");
> > +	puts(prefixes);
> > +	va_start(va, msg_fmt);
> > +	vsnprintf(buf, sizeof(buf), msg_fmt, va);
> 
> Is there a reason for using vsnprintf() rather than just vprintf()
> here?

Only because we haven't implemented a vprintf yet :-) Currently
vsnprintf is the only va_list taking printf we have. This pattern
has occurred enough times though that adding vprintf is a pretty
good idea.

> 
> Apart from that,
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Thanks,
drew

> 
> 
> > +	va_end(va);
> > +	puts(buf);
> > +	puts("\n");
> > +	report_summary();
> > +	abort();
> > +}
> > diff --git a/lib/util.c b/lib/util.c
> > new file mode 100644
> > index 0000000000000..69b18100c9722
> > --- /dev/null
> > +++ b/lib/util.c
> > @@ -0,0 +1,18 @@
> > +/*
> > + * 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>
> > +
> > +int parse_keyval(char *s, long *val)
> > +{
> > +	char *p;
> > +
> > +	p = strchr(s, '=');
> > +	if (!p)
> > +		return -1;
> > +
> > +	*val = atol(p+1);
> > +	return p - s;
> > +}
> > diff --git a/lib/util.h b/lib/util.h
> > new file mode 100644
> > index 0000000000000..4c4b441322770
> > --- /dev/null
> > +++ b/lib/util.h
> > @@ -0,0 +1,23 @@
> > +#ifndef _UTIL_H_
> > +#define _UTIL_H_
> > +/*
> > + * Collection of utility functions to share between unit tests.
> > + *
> > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +
> > +/*
> > + * parse_keyval extracts the integer from a string formatted as
> > + * string=integer. This is useful for passing expected values to
> > + * the unit test on the command line, i.e. it helps parse QEMU
> > + * command lines that include something like -append var1=1 var2=2
> > + * @s is the input string, likely a command line parameter, and
> > + * @val is a pointer to where the integer will be stored.
> > + *
> > + * Returns the offset of the '=', or -1 if no keyval pair is found.
> > + */
> > +extern int parse_keyval(char *s, long *val);
> > +
> > +#endif
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions
@ 2016-02-17 12:17       ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:17 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 11:14:36AM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:15PM +0100, Andrew Jones wrote:
> > arm-selftest has a couple utility functions that could be useful
> > to other unit tests, even other architectures. So move them out.
> > split_var moves to lib/util, where we can add other random
> > utilities over time. assert_args inspires report_abort, which
> > allows us to report a message, using the current prefix, that
> > we're aborting (outputs ABORT vs. PASS/FAIL). This is useful
> > for cases when unit tests can't complete due to missing
> > dependencies of some sort, such as missing/invalid inputs from
> > the user.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  arm/selftest.c               | 45 ++++++++++++++------------------------------
> >  config/config-arm-common.mak |  1 +
> >  lib/libcflat.h               | 11 ++++++-----
> >  lib/report.c                 | 16 ++++++++++++++++
> >  lib/util.c                   | 18 ++++++++++++++++++
> >  lib/util.h                   | 23 ++++++++++++++++++++++
> >  6 files changed, 78 insertions(+), 36 deletions(-)
> >  create mode 100644 lib/util.c
> >  create mode 100644 lib/util.h
> > 
> > diff --git a/arm/selftest.c b/arm/selftest.c
> > index aad7eecd529ad..75dc91faab69a 100644
> > --- a/arm/selftest.c
> > +++ b/arm/selftest.c
> > @@ -6,6 +6,7 @@
> >   * This work is licensed under the terms of the GNU LGPL, version 2.
> >   */
> >  #include <libcflat.h>
> > +#include <util.h>
> >  #include <alloc.h>
> >  #include <devicetree.h>
> >  #include <asm/setup.h>
> > @@ -18,43 +19,21 @@
> >  #include <asm/cpumask.h>
> >  #include <asm/barrier.h>
> >  
> > -static void assert_args(int num_args, int needed_args)
> > -{
> > -	if (num_args < needed_args) {
> > -		printf("selftest: not enough arguments\n");
> > -		abort();
> > -	}
> > -}
> > -
> > -static char *split_var(char *s, long *val)
> > -{
> > -	char *p;
> > -
> > -	p = strchr(s, '=');
> > -	if (!p)
> > -		return NULL;
> > -
> > -	*val = atol(p+1);
> > -	*p = '\0';
> > -
> > -	return s;
> > -}
> > -
> >  static void check_setup(int argc, char **argv)
> >  {
> > -	int nr_tests = 0, i;
> > -	char *var;
> > +	int nr_tests = 0, len, i;
> >  	long val;
> >  
> >  	for (i = 0; i < argc; ++i) {
> >  
> > -		var = split_var(argv[i], &val);
> > -		if (!var)
> > +		len = parse_keyval(argv[i], &val);
> > +		if (len = -1)
> >  			continue;
> >  
> > -		report_prefix_push(var);
> > +		argv[i][len] = '\0';
> > +		report_prefix_push(argv[i]);
> >  
> > -		if (strcmp(var, "mem") = 0) {
> > +		if (strcmp(argv[i], "mem") = 0) {
> >  
> >  			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
> >  			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> > @@ -63,7 +42,7 @@ static void check_setup(int argc, char **argv)
> >  							memsize/1024/1024);
> >  			++nr_tests;
> >  
> > -		} else if (strcmp(var, "smp") = 0) {
> > +		} else if (strcmp(argv[i], "smp") = 0) {
> >  
> >  			report("nr_cpus = %d", nr_cpus = (int)val, nr_cpus);
> >  			++nr_tests;
> > @@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv)
> >  		report_prefix_pop();
> >  	}
> >  
> > -	assert_args(nr_tests, 2);
> > +	if (nr_tests < 2)
> > +		report_abort("missing input");
> >  }
> >  
> >  static struct pt_regs expected_regs;
> > @@ -343,7 +323,10 @@ static void cpu_report(void)
> >  int main(int argc, char **argv)
> >  {
> >  	report_prefix_push("selftest");
> > -	assert_args(argc, 1);
> > +
> > +	if (!argc)
> > +		report_abort("no test specified");
> > +
> >  	report_prefix_push(argv[0]);
> >  
> >  	if (strcmp(argv[0], "setup") = 0) {
> > diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak
> > index 698555d6a676f..bd153cf6ea5ba 100644
> > --- a/config/config-arm-common.mak
> > +++ b/config/config-arm-common.mak
> > @@ -27,6 +27,7 @@ CFLAGS += -I lib -I lib/libfdt
> >  asm-offsets = lib/$(ARCH)/asm-offsets.h
> >  include config/asm-offsets.mak
> >  
> > +cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> >  cflatobjs += lib/virtio.o
> > diff --git a/lib/libcflat.h b/lib/libcflat.h
> > index 9747ccdbc9f1d..8411f6c5d92e3 100644
> > --- a/lib/libcflat.h
> > +++ b/lib/libcflat.h
> > @@ -57,11 +57,12 @@ extern int snprintf(char *buf, int size, const char *fmt, ...);
> >  extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
> >  extern long atol(const char *ptr);
> >  
> > -void report_prefix_push(const char *prefix);
> > -void report_prefix_pop(void);
> > -void report(const char *msg_fmt, bool pass, ...);
> > -void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> > -int report_summary(void);
> > +extern void report_prefix_push(const char *prefix);
> > +extern void report_prefix_pop(void);
> > +extern void report(const char *msg_fmt, bool pass, ...);
> > +extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
> > +extern void report_abort(const char *msg_fmt, ...);
> > +extern int report_summary(void);
> >  
> >  #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
> >  
> > diff --git a/lib/report.c b/lib/report.c
> > index 35e664108a921..62916c4ac3c8a 100644
> > --- a/lib/report.c
> > +++ b/lib/report.c
> > @@ -96,3 +96,19 @@ int report_summary(void)
> >  
> >  	spin_unlock(&lock);
> >  }
> > +
> > +void report_abort(const char *msg_fmt, ...)
> > +{
> > +	va_list va;
> > +	char buf[2000];
> > +
> > +	puts("ABORT: ");
> > +	puts(prefixes);
> > +	va_start(va, msg_fmt);
> > +	vsnprintf(buf, sizeof(buf), msg_fmt, va);
> 
> Is there a reason for using vsnprintf() rather than just vprintf()
> here?

Only because we haven't implemented a vprintf yet :-) Currently
vsnprintf is the only va_list taking printf we have. This pattern
has occurred enough times though that adding vprintf is a pretty
good idea.

> 
> Apart from that,
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Thanks,
drew

> 
> 
> > +	va_end(va);
> > +	puts(buf);
> > +	puts("\n");
> > +	report_summary();
> > +	abort();
> > +}
> > diff --git a/lib/util.c b/lib/util.c
> > new file mode 100644
> > index 0000000000000..69b18100c9722
> > --- /dev/null
> > +++ b/lib/util.c
> > @@ -0,0 +1,18 @@
> > +/*
> > + * 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>
> > +
> > +int parse_keyval(char *s, long *val)
> > +{
> > +	char *p;
> > +
> > +	p = strchr(s, '=');
> > +	if (!p)
> > +		return -1;
> > +
> > +	*val = atol(p+1);
> > +	return p - s;
> > +}
> > diff --git a/lib/util.h b/lib/util.h
> > new file mode 100644
> > index 0000000000000..4c4b441322770
> > --- /dev/null
> > +++ b/lib/util.h
> > @@ -0,0 +1,23 @@
> > +#ifndef _UTIL_H_
> > +#define _UTIL_H_
> > +/*
> > + * Collection of utility functions to share between unit tests.
> > + *
> > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +
> > +/*
> > + * parse_keyval extracts the integer from a string formatted as
> > + * string=integer. This is useful for passing expected values to
> > + * the unit test on the command line, i.e. it helps parse QEMU
> > + * command lines that include something like -append var1=1 var2=2
> > + * @s is the input string, likely a command line parameter, and
> > + * @val is a pointer to where the integer will be stored.
> > + *
> > + * Returns the offset of the '=', or -1 if no keyval pair is found.
> > + */
> > +extern int parse_keyval(char *s, long *val);
> > +
> > +#endif
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
  2016-02-17  1:45     ` David Gibson
@ 2016-02-17 12:21       ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:21 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 12:45:08PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:18PM +0100, Andrew Jones wrote:
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  powerpc/Makefile.common | 40 ++++++++++------------------------------
> >  powerpc/Makefile.ppc64  | 15 +++++++--------
> >  powerpc/flat.lds        | 14 ++++++++++----
> >  3 files changed, 27 insertions(+), 42 deletions(-)
> > 
> > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> > index dd3a0ca327d06..13b828ab171d6 100644
> > --- a/powerpc/Makefile.common
> > +++ b/powerpc/Makefile.common
> > @@ -1,17 +1,15 @@
> >  #
> > -# arm common makefile
> > +# powerpc common makefile
> >  #
> >  # Authors: Andrew Jones <drjones@redhat.com>
> >  #
> >  
> >  ifeq ($(LOADADDR),)
> > -	# qemu mach-virt default load address
> > -	LOADADDR = 0x40000000
> > +	LOADADDR = 0x0
> 
> I was trying to check what LOADADDR means, to see if this was correct,
> but it appears it isn't actually being used yet.

Yeah, we probably won't ever need it for powerpc. I probably should
just remove the unused variable to avoid confusion.

> 
> Otherwise,
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Thanks,
drew

> 
> >  endif
> >  
> >  tests-common = \
> > -	$(TEST_DIR)/selftest.flat \
> > -	$(TEST_DIR)/spinlock-test.flat
> > +	$(TEST_DIR)/selftest.elf
> >  
> >  all: test_cases
> >  
> > @@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
> >  cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> > -cflatobjs += lib/virtio.o
> > -cflatobjs += lib/virtio-mmio.o
> > -cflatobjs += lib/chr-testdev.o
> > -cflatobjs += lib/arm/io.o
> > -cflatobjs += lib/arm/setup.o
> > -cflatobjs += lib/arm/mmu.o
> > -cflatobjs += lib/arm/bitops.o
> > -cflatobjs += lib/arm/psci.o
> > -cflatobjs += lib/arm/smp.o
> > -
> > -libeabi = lib/arm/libeabi.a
> > -eabiobjs = lib/arm/eabi_compat.o
> > +cflatobjs += lib/powerpc/io.o
> >  
> >  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> >  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> >  
> > -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> > +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
> >  %.elf: LDFLAGS = $(CFLAGS) -nostdlib
> > -%.elf: %.o $(FLATLIBS) arm/flat.lds
> > +%.elf: %.o $(FLATLIBS) powerpc/flat.lds
> >  	$(CC) $(LDFLAGS) -o $@ \
> > -		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> > +		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> >  		$(filter %.o, $^) $(FLATLIBS)
> >  
> > -%.flat: %.elf
> > -	$(OBJCOPY) -O binary $^ $@
> > -
> > -$(libeabi): $(eabiobjs)
> > -	$(AR) rcs $@ $^
> > -
> > -arm_clean: libfdt_clean asm_offsets_clean
> > -	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> > -	      $(TEST_DIR)/.*.d lib/arm/.*.d
> > +powerpc_clean: libfdt_clean asm_offsets_clean
> > +	$(RM) $(TEST_DIR)/*.{o,elf} \
> > +	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
> >  
> >  ##################################################################
> >  
> > @@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
> >  test_cases: $(generated_files) $(tests-common) $(tests)
> >  
> >  $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> > -$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
> > diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> > index 0b0761c729c7c..95bf6772d65ed 100644
> > --- a/powerpc/Makefile.ppc64
> > +++ b/powerpc/Makefile.ppc64
> > @@ -1,20 +1,19 @@
> >  #
> > -# arm64 makefile
> > +# ppc64 makefile
> >  #
> >  # Authors: Andrew Jones <drjones@redhat.com>
> >  #
> >  bits = 64
> > -ldarch = elf64-littleaarch64
> > -kernel_offset = 0x80000
> > +ldarch = elf64-powerpc
> > +kernel_offset = 0x0
> >  
> >  cstart.o = $(TEST_DIR)/cstart64.o
> > -cflatobjs += lib/arm64/processor.o
> > -cflatobjs += lib/arm64/spinlock.o
> > +cflatobjs += lib/ppc64/spinlock.o
> >  
> > -# arm64 specific tests
> > +# ppc64 specific tests
> >  tests =
> >  
> >  include $(TEST_DIR)/Makefile.common
> >  
> > -arch_clean: arm_clean
> > -	$(RM) lib/arm64/.*.d
> > +arch_clean: powerpc_clean
> > +	$(RM) lib/ppc64/.*.d
> > diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> > index efdf5d7109ffb..84087057c0ce2 100644
> > --- a/powerpc/flat.lds
> > +++ b/powerpc/flat.lds
> > @@ -4,6 +4,8 @@ SECTIONS
> >      .text : { *(.init) *(.text) *(.text.*) }
> >      . = ALIGN(64K);
> >      etext = .;
> > +    .opd : { *(.opd) }
> > +    . = ALIGN(16);
> >      .data : {
> >          *(.data)
> >      }
> > @@ -11,16 +13,20 @@ SECTIONS
> >      .rodata : { *(.rodata) }
> >      . = ALIGN(16);
> >      .bss : { *(.bss) }
> > +    . = ALIGN(256);
> > +    /*
> > +     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
> > +     */
> > +    tocptr = . + 32K;
> > +    .got : { *(.toc) *(.got) }
> >      . = ALIGN(64K);
> >      edata = .;
> >      . += 64K;
> >      . = ALIGN(64K);
> >      /*
> > -     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
> > -     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
> > -     * sp must always be strictly less than the true stacktop
> > +     * stackptr set with initial stack frame (64 bytes) preallocated
> >       */
> > -    stackptr = . - 16;
> > +    stackptr = . - 64;
> >      stacktop = .;
> >  }
> >  
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script
@ 2016-02-17 12:21       ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:21 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 12:45:08PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:18PM +0100, Andrew Jones wrote:
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  powerpc/Makefile.common | 40 ++++++++++------------------------------
> >  powerpc/Makefile.ppc64  | 15 +++++++--------
> >  powerpc/flat.lds        | 14 ++++++++++----
> >  3 files changed, 27 insertions(+), 42 deletions(-)
> > 
> > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> > index dd3a0ca327d06..13b828ab171d6 100644
> > --- a/powerpc/Makefile.common
> > +++ b/powerpc/Makefile.common
> > @@ -1,17 +1,15 @@
> >  #
> > -# arm common makefile
> > +# powerpc common makefile
> >  #
> >  # Authors: Andrew Jones <drjones@redhat.com>
> >  #
> >  
> >  ifeq ($(LOADADDR),)
> > -	# qemu mach-virt default load address
> > -	LOADADDR = 0x40000000
> > +	LOADADDR = 0x0
> 
> I was trying to check what LOADADDR means, to see if this was correct,
> but it appears it isn't actually being used yet.

Yeah, we probably won't ever need it for powerpc. I probably should
just remove the unused variable to avoid confusion.

> 
> Otherwise,
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Thanks,
drew

> 
> >  endif
> >  
> >  tests-common = \
> > -	$(TEST_DIR)/selftest.flat \
> > -	$(TEST_DIR)/spinlock-test.flat
> > +	$(TEST_DIR)/selftest.elf
> >  
> >  all: test_cases
> >  
> > @@ -30,38 +28,21 @@ include scripts/asm-offsets.mak
> >  cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> > -cflatobjs += lib/virtio.o
> > -cflatobjs += lib/virtio-mmio.o
> > -cflatobjs += lib/chr-testdev.o
> > -cflatobjs += lib/arm/io.o
> > -cflatobjs += lib/arm/setup.o
> > -cflatobjs += lib/arm/mmu.o
> > -cflatobjs += lib/arm/bitops.o
> > -cflatobjs += lib/arm/psci.o
> > -cflatobjs += lib/arm/smp.o
> > -
> > -libeabi = lib/arm/libeabi.a
> > -eabiobjs = lib/arm/eabi_compat.o
> > +cflatobjs += lib/powerpc/io.o
> >  
> >  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> >  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> >  
> > -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> > +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc)
> >  %.elf: LDFLAGS = $(CFLAGS) -nostdlib
> > -%.elf: %.o $(FLATLIBS) arm/flat.lds
> > +%.elf: %.o $(FLATLIBS) powerpc/flat.lds
> >  	$(CC) $(LDFLAGS) -o $@ \
> > -		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> > +		-Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> >  		$(filter %.o, $^) $(FLATLIBS)
> >  
> > -%.flat: %.elf
> > -	$(OBJCOPY) -O binary $^ $@
> > -
> > -$(libeabi): $(eabiobjs)
> > -	$(AR) rcs $@ $^
> > -
> > -arm_clean: libfdt_clean asm_offsets_clean
> > -	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> > -	      $(TEST_DIR)/.*.d lib/arm/.*.d
> > +powerpc_clean: libfdt_clean asm_offsets_clean
> > +	$(RM) $(TEST_DIR)/*.{o,elf} \
> > +	      $(TEST_DIR)/.*.d lib/powerpc/.*.d
> >  
> >  ##################################################################
> >  
> > @@ -70,4 +51,3 @@ generated_files = $(asm-offsets)
> >  test_cases: $(generated_files) $(tests-common) $(tests)
> >  
> >  $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> > -$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o
> > diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64
> > index 0b0761c729c7c..95bf6772d65ed 100644
> > --- a/powerpc/Makefile.ppc64
> > +++ b/powerpc/Makefile.ppc64
> > @@ -1,20 +1,19 @@
> >  #
> > -# arm64 makefile
> > +# ppc64 makefile
> >  #
> >  # Authors: Andrew Jones <drjones@redhat.com>
> >  #
> >  bits = 64
> > -ldarch = elf64-littleaarch64
> > -kernel_offset = 0x80000
> > +ldarch = elf64-powerpc
> > +kernel_offset = 0x0
> >  
> >  cstart.o = $(TEST_DIR)/cstart64.o
> > -cflatobjs += lib/arm64/processor.o
> > -cflatobjs += lib/arm64/spinlock.o
> > +cflatobjs += lib/ppc64/spinlock.o
> >  
> > -# arm64 specific tests
> > +# ppc64 specific tests
> >  tests > >  
> >  include $(TEST_DIR)/Makefile.common
> >  
> > -arch_clean: arm_clean
> > -	$(RM) lib/arm64/.*.d
> > +arch_clean: powerpc_clean
> > +	$(RM) lib/ppc64/.*.d
> > diff --git a/powerpc/flat.lds b/powerpc/flat.lds
> > index efdf5d7109ffb..84087057c0ce2 100644
> > --- a/powerpc/flat.lds
> > +++ b/powerpc/flat.lds
> > @@ -4,6 +4,8 @@ SECTIONS
> >      .text : { *(.init) *(.text) *(.text.*) }
> >      . = ALIGN(64K);
> >      etext = .;
> > +    .opd : { *(.opd) }
> > +    . = ALIGN(16);
> >      .data : {
> >          *(.data)
> >      }
> > @@ -11,16 +13,20 @@ SECTIONS
> >      .rodata : { *(.rodata) }
> >      . = ALIGN(16);
> >      .bss : { *(.bss) }
> > +    . = ALIGN(256);
> > +    /*
> > +     * tocptr is tocbase + 32K, allowing toc offsets to be +-32K
> > +     */
> > +    tocptr = . + 32K;
> > +    .got : { *(.toc) *(.got) }
> >      . = ALIGN(64K);
> >      edata = .;
> >      . += 64K;
> >      . = ALIGN(64K);
> >      /*
> > -     * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
> > -     * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
> > -     * sp must always be strictly less than the true stacktop
> > +     * stackptr set with initial stack frame (64 bytes) preallocated
> >       */
> > -    stackptr = . - 16;
> > +    stackptr = . - 64;
> >      stacktop = .;
> >  }
> >  
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
  2016-02-17  2:04     ` David Gibson
@ 2016-02-17 12:34       ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:34 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:04:25PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:20PM +0100, Andrew Jones wrote:
> > Add broken sc1 detection and patching and an hcall for putchar,
> > to use in puts. That, along with a couple more lines in start to
> > prepare for C code, and a branch to main(), gets us "hello world".
> > Run with
> > 
> > qemu-system-ppc64 -M pseries            \
> >         -bios powerpc/boot_rom.bin      \
> >         -display none -serial stdio     \
> >         -kernel powerpc/selftest.elf
> > 
> > (We're still not relocating yet, that comes in a later patch. Thus,
> >  testing hello-world at this point requires a hacked QEMU and linking
> >  the unit test at QEMU's kernel load address.)
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
> >  lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/powerpc/io.c        | 15 ++++++++--
> >  lib/ppc64/asm/hcall.h   |  1 +
> >  powerpc/Makefile.common |  2 ++
> >  powerpc/cstart64.S      | 21 +++++++++++++
> >  6 files changed, 162 insertions(+), 2 deletions(-)
> >  create mode 100644 lib/powerpc/asm/hcall.h
> >  create mode 100644 lib/powerpc/hcall.c
> >  create mode 100644 lib/ppc64/asm/hcall.h
> > 
> > diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
> > new file mode 100644
> > index 0000000000000..f861287ac2083
> > --- /dev/null
> > +++ b/lib/powerpc/asm/hcall.h
> > @@ -0,0 +1,46 @@
> > +#ifndef _ASMPOWERPC_HCALL_H_
> > +#define _ASMPOWERPC_HCALL_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.
> > + */
> > +
> > +#define SC1			0x44000022
> > +#define SC1_REPLACEMENT		0x7c000268
> > +
> > +#define H_SUCCESS		0
> > +#define H_HARDWARE		-1
> > +#define H_FUNCTION		-2
> > +#define H_PRIVILEGE		-3
> > +#define H_PARAMETER		-4
> > +
> > +#define H_SET_DABR		0x28
> > +#define H_PUT_TERM_CHAR		0x58
> > +
> > +#ifndef __ASSEMBLY__
> > +#include <libcflat.h>
> > +
> > +/*
> > + * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
> > + * Returns true if we are.
> > + */
> > +extern bool hcall_have_broken_sc1(void);
> > +
> > +/*
> > + * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
> > + * allowing all hypercalls built on it to work.
> > + */
> > +extern void hcall_patch_broken_sc1(void);
> > +
> > +/*
> > + * hcall is the hypercall wrapper function. unittests may do what
> > + * they like, but the framework should make all hypercalls through
> > + * here to ensure they use a working sc1 instruction, and properly
> > + * handle clobbered registers. @nr is the hypercall number.
> > + */
> > +extern unsigned long
> > +hcall(unsigned long nr, unsigned long *in, unsigned long *out);
> > +
> > +#endif /* !__ASSEMBLY__ */
> > +#endif /* _ASMPOWERPC_HCALL_H_ */
> > diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
> > new file mode 100644
> > index 0000000000000..db99949352133
> > --- /dev/null
> > +++ b/lib/powerpc/hcall.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Hypercall helpers
> > + *
> > + * broken_sc1 probing/patching inspired by SLOF, see
> > + *   SLOF:lib/libhvcall/brokensc1.c
> > + *
> > + * hcall() implementation inspired by Linux's epapr_hypercall, see
> > + *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
> > +
> > +static u32 sc1[];
> > +
> > +bool hcall_have_broken_sc1(void)
> > +{
> > +	register unsigned long r3 asm("r3") = H_SET_DABR;
> > +	register unsigned long r4 asm("r4") = 0;
> > +
> > +	asm volatile("sc 1"
> > +	: "=r" (r3)
> > +	: "r" (r3), "r" (r4)
> > +	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
> > +	return r3 == (unsigned long)H_PRIVILEGE;
> > +}
> > +
> > +void hcall_patch_broken_sc1(void)
> > +{
> > +	if (!hcall_have_broken_sc1())
> > +		return;
> > +	sc1[0] = SC1_REPLACEMENT;
> > +}
> > +
> > +unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
> > +{
> > +	register unsigned long r3 asm("r3") = nr;
> > +	register unsigned long r4 asm("r4") = in[0];
> > +	register unsigned long r5 asm("r5") = in[1];
> > +	register unsigned long r6 asm("r6") = in[2];
> > +	register unsigned long r7 asm("r7") = in[3];
> > +	register unsigned long r8 asm("r8") = in[4];
> > +	register unsigned long r9 asm("r9") = in[5];
> > +	register unsigned long r10 asm("r10") = in[6];
> > +	register unsigned long r11 asm("r11") = in[7];
> > +
> > +	asm volatile("bl sc1"
> > +		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
> > +		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
> > +		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
> > +		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
> > +		: "r12", "memory", "lr");
> > +
> > +	out[0] = r4;
> > +	out[1] = r5;
> > +	out[2] = r6;
> > +	out[3] = r7;
> > +	out[4] = r8;
> > +	out[5] = r9;
> > +	out[6] = r10;
> > +	out[7] = r11;
> > +
> > +	return r3;
> 
> I'm not sure there's much advantage to having this in C, rather than
> folding this and the sc1 symbol into a single asm implemented hcall
> function.
> 
> Doing it that way might more easily allow you to avoid packing the
> arguments into an array, before unpacking them into registers again,
> which seems a bit perverse.

Once I'd moved putchar to C, I decided to minimize the assembly,
but I agree that hcall might as well just be assembly.

> 
> > +}
> > +
> > +void putchar(int c)
> > +{
> > +	unsigned long in[8], out[8];
> > +
> > +	in[0] = 0; /* default vty */
> > +	in[1] = 1; /* just 1 byte */
> > +	in[2] = (unsigned long)c << 56;
> > +
> > +	hcall(H_PUT_TERM_CHAR, in, out);
> > +}
> > diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
> > index 0af45742fc900..5e1fa8dd96ab6 100644
> > --- a/lib/powerpc/io.c
> > +++ b/lib/powerpc/io.c
> > @@ -6,15 +6,26 @@
> >   * This work is licensed under the terms of the GNU LGPL, version 2.
> >   */
> >  #include <libcflat.h>
> > +#include <asm/spinlock.h>
> > +
> > +extern void halt(int code);
> > +extern void putchar(int c);
> > +
> > +static struct spinlock uart_lock;
> >  
> >  void io_init(void)
> >  {
> >  }
> >  
> > -void puts(const char *s __unused)
> > +void puts(const char *s)
> >  {
> > +	spin_lock(&uart_lock);
> 
> The name uart_lock isn't really accurate, since it's a hypervisor
> console rather than serial.

Will rename.

> 
> > +	while (*s)
> > +		putchar(*s++);
> > +	spin_unlock(&uart_lock);
> >  }
> >  
> > -void exit(int code __unused)
> > +void exit(int code)
> >  {
> > +	halt(code);
> >  }
> > diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
> > new file mode 100644
> > index 0000000000000..daabaca510cd4
> > --- /dev/null
> > +++ b/lib/ppc64/asm/hcall.h
> > @@ -0,0 +1 @@
> > +#include "../../powerpc/asm/hcall.h"
> > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> > index 0c3eaba0d3aab..89610b525f0c1 100644
> > --- a/powerpc/Makefile.common
> > +++ b/powerpc/Makefile.common
> > @@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
> >  CFLAGS += -Wextra
> >  CFLAGS += -O2
> >  CFLAGS += -I lib -I lib/libfdt
> > +CFLAGS += -Wa,-mregnames
> >  
> >  asm-offsets = lib/$(ARCH)/asm-offsets.h
> >  include scripts/asm-offsets.mak
> > @@ -29,6 +30,7 @@ cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> >  cflatobjs += lib/powerpc/io.o
> > +cflatobjs += lib/powerpc/hcall.o
> >  
> >  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> >  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> > diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> > index f90828dee1c19..623fd693b02d1 100644
> > --- a/powerpc/cstart64.S
> > +++ b/powerpc/cstart64.S
> > @@ -7,13 +7,34 @@
> >   */
> >  #define __ASSEMBLY__
> >  
> > +#define LOAD_REG_IMMEDIATE(reg,expr)		\
> > +	lis	reg,(expr)@highest;		\
> > +	ori	reg,reg,(expr)@higher;		\
> > +	rldicr	reg,reg,32,31;			\
> > +	oris	reg,reg,(expr)@h;		\
> > +	ori	reg,reg,(expr)@l;
> > +
> > +#define LOAD_REG_ADDR(reg,name)			\
> > +	ld	reg,name@got(r2)
> > +
> >  .section .init
> >  
> >  .globl start
> >  start:
> > +	LOAD_REG_IMMEDIATE(r1, stackptr)
> > +	LOAD_REG_IMMEDIATE(r2, tocptr)
> > +	bl	hcall_patch_broken_sc1
> 
> Come to that, is there any point putting hcall_patch_broken_sc1 in C,
> rather than just doing it inline here.

Hmm, actually no. I'll change that too.

Thanks,
drew

> 
> > +	bl	main
> > +	bl	exit
> >  	b	halt
> >  
> >  .text
> > +.align 3
> > +
> > +.globl sc1
> > +sc1:
> > +	sc	1
> > +	blr
> >  
> >  .globl halt
> >  halt:
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar
@ 2016-02-17 12:34       ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:34 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:04:25PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:20PM +0100, Andrew Jones wrote:
> > Add broken sc1 detection and patching and an hcall for putchar,
> > to use in puts. That, along with a couple more lines in start to
> > prepare for C code, and a branch to main(), gets us "hello world".
> > Run with
> > 
> > qemu-system-ppc64 -M pseries            \
> >         -bios powerpc/boot_rom.bin      \
> >         -display none -serial stdio     \
> >         -kernel powerpc/selftest.elf
> > 
> > (We're still not relocating yet, that comes in a later patch. Thus,
> >  testing hello-world at this point requires a hacked QEMU and linking
> >  the unit test at QEMU's kernel load address.)
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  lib/powerpc/asm/hcall.h | 46 ++++++++++++++++++++++++++++
> >  lib/powerpc/hcall.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/powerpc/io.c        | 15 ++++++++--
> >  lib/ppc64/asm/hcall.h   |  1 +
> >  powerpc/Makefile.common |  2 ++
> >  powerpc/cstart64.S      | 21 +++++++++++++
> >  6 files changed, 162 insertions(+), 2 deletions(-)
> >  create mode 100644 lib/powerpc/asm/hcall.h
> >  create mode 100644 lib/powerpc/hcall.c
> >  create mode 100644 lib/ppc64/asm/hcall.h
> > 
> > diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
> > new file mode 100644
> > index 0000000000000..f861287ac2083
> > --- /dev/null
> > +++ b/lib/powerpc/asm/hcall.h
> > @@ -0,0 +1,46 @@
> > +#ifndef _ASMPOWERPC_HCALL_H_
> > +#define _ASMPOWERPC_HCALL_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.
> > + */
> > +
> > +#define SC1			0x44000022
> > +#define SC1_REPLACEMENT		0x7c000268
> > +
> > +#define H_SUCCESS		0
> > +#define H_HARDWARE		-1
> > +#define H_FUNCTION		-2
> > +#define H_PRIVILEGE		-3
> > +#define H_PARAMETER		-4
> > +
> > +#define H_SET_DABR		0x28
> > +#define H_PUT_TERM_CHAR		0x58
> > +
> > +#ifndef __ASSEMBLY__
> > +#include <libcflat.h>
> > +
> > +/*
> > + * hcall_have_broken_sc1 checks if we're on a host with a broken sc1.
> > + * Returns true if we are.
> > + */
> > +extern bool hcall_have_broken_sc1(void);
> > +
> > +/*
> > + * hcall_patch_broken_sc1 patches hcall's sc1 instruction, if needed,
> > + * allowing all hypercalls built on it to work.
> > + */
> > +extern void hcall_patch_broken_sc1(void);
> > +
> > +/*
> > + * hcall is the hypercall wrapper function. unittests may do what
> > + * they like, but the framework should make all hypercalls through
> > + * here to ensure they use a working sc1 instruction, and properly
> > + * handle clobbered registers. @nr is the hypercall number.
> > + */
> > +extern unsigned long
> > +hcall(unsigned long nr, unsigned long *in, unsigned long *out);
> > +
> > +#endif /* !__ASSEMBLY__ */
> > +#endif /* _ASMPOWERPC_HCALL_H_ */
> > diff --git a/lib/powerpc/hcall.c b/lib/powerpc/hcall.c
> > new file mode 100644
> > index 0000000000000..db99949352133
> > --- /dev/null
> > +++ b/lib/powerpc/hcall.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Hypercall helpers
> > + *
> > + * broken_sc1 probing/patching inspired by SLOF, see
> > + *   SLOF:lib/libhvcall/brokensc1.c
> > + *
> > + * hcall() implementation inspired by Linux's epapr_hypercall, see
> > + *   arch/powerpc/include/asm/epapr_hcalls.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 <asm/hcall.h>
> > +
> > +static u32 sc1[];
> > +
> > +bool hcall_have_broken_sc1(void)
> > +{
> > +	register unsigned long r3 asm("r3") = H_SET_DABR;
> > +	register unsigned long r4 asm("r4") = 0;
> > +
> > +	asm volatile("sc 1"
> > +	: "=r" (r3)
> > +	: "r" (r3), "r" (r4)
> > +	: "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
> > +	return r3 = (unsigned long)H_PRIVILEGE;
> > +}
> > +
> > +void hcall_patch_broken_sc1(void)
> > +{
> > +	if (!hcall_have_broken_sc1())
> > +		return;
> > +	sc1[0] = SC1_REPLACEMENT;
> > +}
> > +
> > +unsigned long hcall(unsigned long nr, unsigned long *in, unsigned long *out)
> > +{
> > +	register unsigned long r3 asm("r3") = nr;
> > +	register unsigned long r4 asm("r4") = in[0];
> > +	register unsigned long r5 asm("r5") = in[1];
> > +	register unsigned long r6 asm("r6") = in[2];
> > +	register unsigned long r7 asm("r7") = in[3];
> > +	register unsigned long r8 asm("r8") = in[4];
> > +	register unsigned long r9 asm("r9") = in[5];
> > +	register unsigned long r10 asm("r10") = in[6];
> > +	register unsigned long r11 asm("r11") = in[7];
> > +
> > +	asm volatile("bl sc1"
> > +		: "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7),
> > +		  "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11)
> > +		: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7),
> > +		  "r"(r8), "r"(r9), "r"(r10), "r"(r11)
> > +		: "r12", "memory", "lr");
> > +
> > +	out[0] = r4;
> > +	out[1] = r5;
> > +	out[2] = r6;
> > +	out[3] = r7;
> > +	out[4] = r8;
> > +	out[5] = r9;
> > +	out[6] = r10;
> > +	out[7] = r11;
> > +
> > +	return r3;
> 
> I'm not sure there's much advantage to having this in C, rather than
> folding this and the sc1 symbol into a single asm implemented hcall
> function.
> 
> Doing it that way might more easily allow you to avoid packing the
> arguments into an array, before unpacking them into registers again,
> which seems a bit perverse.

Once I'd moved putchar to C, I decided to minimize the assembly,
but I agree that hcall might as well just be assembly.

> 
> > +}
> > +
> > +void putchar(int c)
> > +{
> > +	unsigned long in[8], out[8];
> > +
> > +	in[0] = 0; /* default vty */
> > +	in[1] = 1; /* just 1 byte */
> > +	in[2] = (unsigned long)c << 56;
> > +
> > +	hcall(H_PUT_TERM_CHAR, in, out);
> > +}
> > diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
> > index 0af45742fc900..5e1fa8dd96ab6 100644
> > --- a/lib/powerpc/io.c
> > +++ b/lib/powerpc/io.c
> > @@ -6,15 +6,26 @@
> >   * This work is licensed under the terms of the GNU LGPL, version 2.
> >   */
> >  #include <libcflat.h>
> > +#include <asm/spinlock.h>
> > +
> > +extern void halt(int code);
> > +extern void putchar(int c);
> > +
> > +static struct spinlock uart_lock;
> >  
> >  void io_init(void)
> >  {
> >  }
> >  
> > -void puts(const char *s __unused)
> > +void puts(const char *s)
> >  {
> > +	spin_lock(&uart_lock);
> 
> The name uart_lock isn't really accurate, since it's a hypervisor
> console rather than serial.

Will rename.

> 
> > +	while (*s)
> > +		putchar(*s++);
> > +	spin_unlock(&uart_lock);
> >  }
> >  
> > -void exit(int code __unused)
> > +void exit(int code)
> >  {
> > +	halt(code);
> >  }
> > diff --git a/lib/ppc64/asm/hcall.h b/lib/ppc64/asm/hcall.h
> > new file mode 100644
> > index 0000000000000..daabaca510cd4
> > --- /dev/null
> > +++ b/lib/ppc64/asm/hcall.h
> > @@ -0,0 +1 @@
> > +#include "../../powerpc/asm/hcall.h"
> > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> > index 0c3eaba0d3aab..89610b525f0c1 100644
> > --- a/powerpc/Makefile.common
> > +++ b/powerpc/Makefile.common
> > @@ -21,6 +21,7 @@ CFLAGS += -ffreestanding
> >  CFLAGS += -Wextra
> >  CFLAGS += -O2
> >  CFLAGS += -I lib -I lib/libfdt
> > +CFLAGS += -Wa,-mregnames
> >  
> >  asm-offsets = lib/$(ARCH)/asm-offsets.h
> >  include scripts/asm-offsets.mak
> > @@ -29,6 +30,7 @@ cflatobjs += lib/util.o
> >  cflatobjs += lib/alloc.o
> >  cflatobjs += lib/devicetree.o
> >  cflatobjs += lib/powerpc/io.o
> > +cflatobjs += lib/powerpc/hcall.o
> >  
> >  libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name)
> >  start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> > diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
> > index f90828dee1c19..623fd693b02d1 100644
> > --- a/powerpc/cstart64.S
> > +++ b/powerpc/cstart64.S
> > @@ -7,13 +7,34 @@
> >   */
> >  #define __ASSEMBLY__
> >  
> > +#define LOAD_REG_IMMEDIATE(reg,expr)		\
> > +	lis	reg,(expr)@highest;		\
> > +	ori	reg,reg,(expr)@higher;		\
> > +	rldicr	reg,reg,32,31;			\
> > +	oris	reg,reg,(expr)@h;		\
> > +	ori	reg,reg,(expr)@l;
> > +
> > +#define LOAD_REG_ADDR(reg,name)			\
> > +	ld	reg,name@got(r2)
> > +
> >  .section .init
> >  
> >  .globl start
> >  start:
> > +	LOAD_REG_IMMEDIATE(r1, stackptr)
> > +	LOAD_REG_IMMEDIATE(r2, tocptr)
> > +	bl	hcall_patch_broken_sc1
> 
> Come to that, is there any point putting hcall_patch_broken_sc1 in C,
> rather than just doing it inline here.

Hmm, actually no. I'll change that too.

Thanks,
drew

> 
> > +	bl	main
> > +	bl	exit
> >  	b	halt
> >  
> >  .text
> > +.align 3
> > +
> > +.globl sc1
> > +sc1:
> > +	sc	1
> > +	blr
> >  
> >  .globl halt
> >  halt:
> 
> -- 
> 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



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
  2016-02-17  2:11     ` David Gibson
@ 2016-02-17 12:45       ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:45 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:21PM +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.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  lib/powerpc/asm/setup.h |  36 +++++++++++++++
> >  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/ppc64/asm/setup.h   |   1 +
> >  powerpc/Makefile.common |   1 +
> >  powerpc/cstart64.S      |  16 +++++++
> >  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
> >  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> > --- /dev/null
> > +++ b/lib/powerpc/asm/setup.h
> > @@ -0,0 +1,36 @@
> > +#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;
> > +
> > +#define PHYSICAL_START		(__physical_start)
> > +#define PHYSICAL_END		(__physical_end)
> > +
> > +#ifdef __powerpc64__
> > +#define L1_CACHE_SHIFT		7
> > +#else
> > +#define L1_CACHE_SHIFT		5
> > +#endif
> 
> These aren't necessarily true for all systems, although it's probably
> right for all BE, BookS systems supporting KVM at present.  It would
> be better to get the cache alignment from the device tree if possible.

Ah, I hadn't considered being able to do that. I presume I can expect
i-cache-line-size to always == d-cache-line-size, right?

> 
> Also, is this correct for LE, which I imagine you'll want to support
> soon (I don't recall if __powerpc64__ is defined for both BE and LE
> systems).

This use of __powerpc64__ will go away with the above change, but I
have another one in rtas.c. I don't know if it's valid for LE, but
I'd prefer to ignore LE for now, and then create a new series that
modifies everything necessary for enabling both BE and LE compiles.

Thanks,
drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
@ 2016-02-17 12:45       ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:45 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> On Mon, Feb 15, 2016 at 02:49:21PM +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.
> > 
> > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > ---
> >  lib/powerpc/asm/setup.h |  36 +++++++++++++++
> >  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  lib/ppc64/asm/setup.h   |   1 +
> >  powerpc/Makefile.common |   1 +
> >  powerpc/cstart64.S      |  16 +++++++
> >  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
> >  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> > --- /dev/null
> > +++ b/lib/powerpc/asm/setup.h
> > @@ -0,0 +1,36 @@
> > +#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;
> > +
> > +#define PHYSICAL_START		(__physical_start)
> > +#define PHYSICAL_END		(__physical_end)
> > +
> > +#ifdef __powerpc64__
> > +#define L1_CACHE_SHIFT		7
> > +#else
> > +#define L1_CACHE_SHIFT		5
> > +#endif
> 
> These aren't necessarily true for all systems, although it's probably
> right for all BE, BookS systems supporting KVM at present.  It would
> be better to get the cache alignment from the device tree if possible.

Ah, I hadn't considered being able to do that. I presume I can expect
i-cache-line-size to always = d-cache-line-size, right?

> 
> Also, is this correct for LE, which I imagine you'll want to support
> soon (I don't recall if __powerpc64__ is defined for both BE and LE
> systems).

This use of __powerpc64__ will go away with the above change, but I
have another one in rtas.c. I don't know if it's valid for LE, but
I'd prefer to ignore LE for now, and then create a new series that
modifies everything necessary for enabling both BE and LE compiles.

Thanks,
drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 15/17] mkstandalone: add support for powerpc
  2016-02-15 13:49   ` Andrew Jones
@ 2016-02-17 12:51     ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:51 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini, rkrcmar

On Mon, Feb 15, 2016 at 02:49:24PM +0100, Andrew Jones wrote:
> PowerPC needs firmware.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  configure               | 2 ++
>  powerpc/run             | 2 +-
>  scripts/mkstandalone.sh | 5 +++++
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/configure b/configure
> index b2ad199da7873..7d5702e28d627 100755
> --- a/configure
> +++ b/configure
> @@ -83,6 +83,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
>      testdir=arm
>  elif [ "$arch" = "ppc64" ]; then
>      testdir=powerpc
> +    firmware="$testdir/boot_rom.bin"
>  else
>      testdir=$arch
>  fi
> @@ -137,4 +138,5 @@ OBJDUMP=$cross_prefix$objdump
>  AR=$cross_prefix$ar
>  API=$api
>  TEST_DIR=$testdir
> +FIRMWARE=$firmware
>  EOF
> diff --git a/powerpc/run b/powerpc/run
> index 47aecb7600832..c5108100fc5e0 100755
> --- a/powerpc/run
> +++ b/powerpc/run
> @@ -42,7 +42,7 @@ fi
>  
>  M='-machine pseries'
>  M+=",accel=$ACCEL"
> -command="$qemu $M -bios powerpc/boot_rom.bin"
> +command="$qemu $M -bios $FIRMWARE"
>  command+=" -display none -serial stdio -kernel"
>  echo $command "$@"
>  
> diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh
> index b0f1e7c098afb..1788a8ef4e92a 100755
> --- a/scripts/mkstandalone.sh
> +++ b/scripts/mkstandalone.sh
> @@ -51,6 +51,11 @@ generate_test ()
>  		return 1
>  	fi
>  
> +	if [ "$FIRMWARE" ]; then
> +		temp_file firmware "$FIRMWARE"
> +		echo 'export FIRMWARE=$firmware'

Radim pointed out that there's no need for two firmware
(firmware,FIRMWARE) variables. As I need a v5 I'll throw
that change in too. (After which I'll expect his r-b :-)

drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 15/17] mkstandalone: add support for powerpc
@ 2016-02-17 12:51     ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 12:51 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: thuth, dgibson, david, agraf, lvivier, pbonzini, rkrcmar

On Mon, Feb 15, 2016 at 02:49:24PM +0100, Andrew Jones wrote:
> PowerPC needs firmware.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  configure               | 2 ++
>  powerpc/run             | 2 +-
>  scripts/mkstandalone.sh | 5 +++++
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/configure b/configure
> index b2ad199da7873..7d5702e28d627 100755
> --- a/configure
> +++ b/configure
> @@ -83,6 +83,7 @@ elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
>      testdir=arm
>  elif [ "$arch" = "ppc64" ]; then
>      testdir=powerpc
> +    firmware="$testdir/boot_rom.bin"
>  else
>      testdir=$arch
>  fi
> @@ -137,4 +138,5 @@ OBJDUMP=$cross_prefix$objdump
>  AR=$cross_prefix$ar
>  API=$api
>  TEST_DIR=$testdir
> +FIRMWARE=$firmware
>  EOF
> diff --git a/powerpc/run b/powerpc/run
> index 47aecb7600832..c5108100fc5e0 100755
> --- a/powerpc/run
> +++ b/powerpc/run
> @@ -42,7 +42,7 @@ fi
>  
>  M='-machine pseries'
>  M+=",accel=$ACCEL"
> -command="$qemu $M -bios powerpc/boot_rom.bin"
> +command="$qemu $M -bios $FIRMWARE"
>  command+=" -display none -serial stdio -kernel"
>  echo $command "$@"
>  
> diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh
> index b0f1e7c098afb..1788a8ef4e92a 100755
> --- a/scripts/mkstandalone.sh
> +++ b/scripts/mkstandalone.sh
> @@ -51,6 +51,11 @@ generate_test ()
>  		return 1
>  	fi
>  
> +	if [ "$FIRMWARE" ]; then
> +		temp_file firmware "$FIRMWARE"
> +		echo 'export FIRMWARE=$firmware'

Radim pointed out that there's no need for two firmware
(firmware,FIRMWARE) variables. As I need a v5 I'll throw
that change in too. (After which I'll expect his r-b :-)

drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
  2016-02-17 12:45       ` Andrew Jones
@ 2016-02-17 17:34         ` Andrew Jones
  -1 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 17:34 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:45:40PM +0100, Andrew Jones wrote:
> On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> > These aren't necessarily true for all systems, although it's probably
> > right for all BE, BookS systems supporting KVM at present.  It would
> > be better to get the cache alignment from the device tree if possible.
> 
> Ah, I hadn't considered being able to do that. I presume I can expect
> i-cache-line-size to always == d-cache-line-size, right?
>

I see that I can't. There's at least one QEMU processor that has them
different. I don't need to make that assumption anyway. I just need to
know the greater of the two, and can just look at both to figure that
out.

drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
@ 2016-02-17 17:34         ` Andrew Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Andrew Jones @ 2016-02-17 17:34 UTC (permalink / raw)
  To: David Gibson; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

On Wed, Feb 17, 2016 at 01:45:40PM +0100, Andrew Jones wrote:
> On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> > These aren't necessarily true for all systems, although it's probably
> > right for all BE, BookS systems supporting KVM at present.  It would
> > be better to get the cache alignment from the device tree if possible.
> 
> Ah, I hadn't considered being able to do that. I presume I can expect
> i-cache-line-size to always = d-cache-line-size, right?
>

I see that I can't. There's at least one QEMU processor that has them
different. I don't need to make that assumption anyway. I just need to
know the greater of the two, and can just look at both to figure that
out.

drew

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
  2016-02-17 12:45       ` Andrew Jones
@ 2016-02-18  0:05         ` David Gibson
  -1 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-18  0:05 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 3500 bytes --]

On Wed, Feb 17, 2016 at 01:45:40PM +0100, Andrew Jones wrote:
> On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> > On Mon, Feb 15, 2016 at 02:49:21PM +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.
> > > 
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > > ---
> > >  lib/powerpc/asm/setup.h |  36 +++++++++++++++
> > >  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/ppc64/asm/setup.h   |   1 +
> > >  powerpc/Makefile.common |   1 +
> > >  powerpc/cstart64.S      |  16 +++++++
> > >  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
> > >  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> > > --- /dev/null
> > > +++ b/lib/powerpc/asm/setup.h
> > > @@ -0,0 +1,36 @@
> > > +#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;
> > > +
> > > +#define PHYSICAL_START		(__physical_start)
> > > +#define PHYSICAL_END		(__physical_end)
> > > +
> > > +#ifdef __powerpc64__
> > > +#define L1_CACHE_SHIFT		7
> > > +#else
> > > +#define L1_CACHE_SHIFT		5
> > > +#endif
> > 
> > These aren't necessarily true for all systems, although it's probably
> > right for all BE, BookS systems supporting KVM at present.  It would
> > be better to get the cache alignment from the device tree if possible.
> 
> Ah, I hadn't considered being able to do that. I presume I can expect
> i-cache-line-size to always == d-cache-line-size, right?

In theory, no.  In practice, I don't think I've ever seen a machine
with them different, at least not anything even vaguely recent.

> > Also, is this correct for LE, which I imagine you'll want to support
> > soon (I don't recall if __powerpc64__ is defined for both BE and LE
> > systems).
> 
> This use of __powerpc64__ will go away with the above change, but I
> have another one in rtas.c. I don't know if it's valid for LE, but
> I'd prefer to ignore LE for now, and then create a new series that
> modifies everything necessary for enabling both BE and LE compiles.

Ok.

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup
@ 2016-02-18  0:05         ` David Gibson
  0 siblings, 0 replies; 72+ messages in thread
From: David Gibson @ 2016-02-18  0:05 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvm, kvm-ppc, thuth, dgibson, agraf, lvivier, pbonzini

[-- Attachment #1: Type: text/plain, Size: 3500 bytes --]

On Wed, Feb 17, 2016 at 01:45:40PM +0100, Andrew Jones wrote:
> On Wed, Feb 17, 2016 at 01:11:58PM +1100, David Gibson wrote:
> > On Mon, Feb 15, 2016 at 02:49:21PM +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.
> > > 
> > > Signed-off-by: Andrew Jones <drjones@redhat.com>
> > > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > > Tested-by: Laurent Vivier <lvivier@redhat.com>
> > > ---
> > >  lib/powerpc/asm/setup.h |  36 +++++++++++++++
> > >  lib/powerpc/setup.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
> > >  lib/ppc64/asm/setup.h   |   1 +
> > >  powerpc/Makefile.common |   1 +
> > >  powerpc/cstart64.S      |  16 +++++++
> > >  powerpc/selftest.c      |  63 +++++++++++++++++++++++--
> > >  6 files changed, 233 insertions(+), 3 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..0b9f04b4b7289
> > > --- /dev/null
> > > +++ b/lib/powerpc/asm/setup.h
> > > @@ -0,0 +1,36 @@
> > > +#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;
> > > +
> > > +#define PHYSICAL_START		(__physical_start)
> > > +#define PHYSICAL_END		(__physical_end)
> > > +
> > > +#ifdef __powerpc64__
> > > +#define L1_CACHE_SHIFT		7
> > > +#else
> > > +#define L1_CACHE_SHIFT		5
> > > +#endif
> > 
> > These aren't necessarily true for all systems, although it's probably
> > right for all BE, BookS systems supporting KVM at present.  It would
> > be better to get the cache alignment from the device tree if possible.
> 
> Ah, I hadn't considered being able to do that. I presume I can expect
> i-cache-line-size to always == d-cache-line-size, right?

In theory, no.  In practice, I don't think I've ever seen a machine
with them different, at least not anything even vaguely recent.

> > Also, is this correct for LE, which I imagine you'll want to support
> > soon (I don't recall if __powerpc64__ is defined for both BE and LE
> > systems).
> 
> This use of __powerpc64__ will go away with the above change, but I
> have another one in rtas.c. I don't know if it's valid for LE, but
> I'd prefer to ignore LE for now, and then create a new series that
> modifies everything necessary for enabling both BE and LE compiles.

Ok.

-- 
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 --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2016-02-18  0:17 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-15 13:49 [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop Andrew Jones
2016-02-15 13:49 ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 01/17] arm/arm64: trivial: another assert fix Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 02/17] Makefile: cscope: also look in arch shared asm Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 03/17] lib: asm-generic: add missing casts Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 04/17] devicetree: fix dt_get_memory_params Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-16  6:11   ` David Gibson
2016-02-16  6:11     ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 05/17] arm/arm64: setup improvements Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-16  6:15   ` David Gibson
2016-02-16  6:15     ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 06/17] lib: share arm-selftest utility functions Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  0:14   ` David Gibson
2016-02-17  0:14     ` David Gibson
2016-02-17 12:17     ` Andrew Jones
2016-02-17 12:17       ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 07/17] config: no need to mix arch makefiles Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  1:18   ` David Gibson
2016-02-17  1:18     ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 08/17] powerpc/ppc64: start skeleton framework Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 09/17] powerpc/ppc64: ppc-ify makefiles and linker script Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  1:45   ` David Gibson
2016-02-17  1:45     ` David Gibson
2016-02-17 12:21     ` Andrew Jones
2016-02-17 12:21       ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 10/17] powerpc/ppc64: add a boot rom Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  1:50   ` David Gibson
2016-02-17  1:50     ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 11/17] powerpc/ppc64: add hcall support and putchar Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  2:04   ` David Gibson
2016-02-17  2:04     ` David Gibson
2016-02-17 12:34     ` Andrew Jones
2016-02-17 12:34       ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 12/17] powerpc/ppc64: adapt arm's setup Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  2:11   ` David Gibson
2016-02-17  2:11     ` David Gibson
2016-02-17 12:45     ` Andrew Jones
2016-02-17 12:45       ` Andrew Jones
2016-02-17 17:34       ` Andrew Jones
2016-02-17 17:34         ` Andrew Jones
2016-02-18  0:05       ` David Gibson
2016-02-18  0:05         ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 13/17] powerpc/ppc64: relocate linker VMAs Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17  2:14   ` David Gibson
2016-02-17  2:14     ` David Gibson
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 14/17] powerpc/ppc64: add run script and unittests.cfg Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 15/17] mkstandalone: add support for powerpc Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-17 12:51   ` Andrew Jones
2016-02-17 12:51     ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 16/17] powerpc/ppc64: add RTAS support Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-15 13:49 ` [kvm-unit-tests PATCH v4 17/17] powerpc/ppc64: make a fake debug-exit Andrew Jones
2016-02-15 13:49   ` Andrew Jones
2016-02-16 17:32 ` [kvm-unit-tests PATCH v4 00/17] ppc64: initial drop Paolo Bonzini
2016-02-16 17:32   ` Paolo Bonzini
2016-02-16 17:44   ` Andrew Jones
2016-02-16 17:44     ` Andrew Jones

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.