powerpc updates for 4.1

- Numerous minor fixes, cleanups etc.
 - More EEH work from Gavin to remove its dependency on device_nodes.
 - Memory hotplug implemented entirely in the kernel from Nathan Fontenot.
 - Removal of redundant CONFIG_PPC_OF by Kevin Hao.
 - Rewrite of VPHN parsing logic & tests from Greg Kurz.
 - A fix from Nish Aravamudan to reduce memory usage by clamping
   nodes_possible_map.
 - Support for pstore on powernv from Hari Bathini.
 - Removal of old powerpc specific byte swap routines by David Gibson.
 - Fix from Vasant Hegde to prevent the flash driver telling you it was flashing
   your firmware when it wasn't.
 - Patch from Ben Herrenschmidt to add an OPAL heartbeat driver.
 - Fix for an oops causing get/put_cpu_var() imbalance in perf by Jan Stancek.
 - Some fixes for migration from Tyrel Datwyler.
 - A new syscall to switch the cpu endian by Michael Ellerman.
 - Large series from Wei Yang to implement SRIOV, reviewed and acked by Bjorn.
 - A fix for the OPAL sensor driver from Cédric Le Goater.
 - Fixes to get STRICT_MM_TYPECHECKS building again by Michael Ellerman.
 - Large series from Daniel Axtens to make our PCI hooks per PHB rather than per
   machine.
 - Small patch from Sam Bobroff to explicitly abort non-suspended transactions
   on syscalls, plus a test to exercise it.
 - Numerous reworks and fixes for the 24x7 PMU from Sukadev Bhattiprolu.
 - Small patch to enable the hard lockup detector from Anton Blanchard.
 - Fix from Dave Olson for missing L2 cache information on some CPUs.
 - Some fixes from Michael Ellerman to get Cell machines booting again.
 - Freescale updates from Scott: Highlights include BMan device tree nodes, an
   MSI erratum workaround, a couple minor performance improvements, config
   updates, and misc fixes/cleanup.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVL2cxAAoJEFHr6jzI4aWAR8cP/19VTo/CzCE4ffPSx7qR464n
 F+WFZcbNjIMXu6+B0YLuJZEsuWtKKrCit/MCg3+mSgE4iqvxmtI+HDD0445Buszj
 UD4E4HMdPrXQ+KUSUDORvRjv/FFUXIa94LSv/0g2UeMsPz/HeZlhMxEu7AkXw9Nf
 rTxsmRTsOWME85Y/c9ss7XHuWKXT3DJV7fOoK9roSaN3dJAuWTtG3WaKS0nUu0ok
 0M81D6ZczoD6ybwh2DUMPD9K6SGxLdQ4OzQwtW6vWzcQIBDfy5Pdeo0iAFhGPvXf
 T4LLPkv4cF4AwHsAC4rKDPHQNa+oZBoLlScrHClaebAlDiv+XYKNdMogawUObvSh
 h7avKmQr0Ygp1OvvZAaXLhuDJI9FJJ8lf6AOIeULgHsDR9SyKMjZWxRzPe11uarO
 Fyi0qj3oJaQu6LjazZraApu8mo+JBtQuD3z3o5GhLxeFtBBF60JXj6zAXJikufnl
 kk1/BUF10nKUhtKcDX767AMUCtMH3fp5hx8K/z9T5v+pobJB26Wup1bbdT68pNBT
 NjdKUppV6QTjZvCsA6U2/ECu6E9KeIaFtFSL2IRRoiI0dWBN5/5eYn3RGkO2ZFoL
 1NdwKA2XJcchwTPkpSRrUG70sYH0uM2AldNYyaLfjzrQqza7Y6lF699ilxWmCN/H
 OplzJAE5cQ8Am078veTW
 =03Yh
 -----END PGP SIGNATURE-----

Merge tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux

Pull powerpc updates from Michael Ellerman:

 - Numerous minor fixes, cleanups etc.

 - More EEH work from Gavin to remove its dependency on device_nodes.

 - Memory hotplug implemented entirely in the kernel from Nathan
   Fontenot.

 - Removal of redundant CONFIG_PPC_OF by Kevin Hao.

 - Rewrite of VPHN parsing logic & tests from Greg Kurz.

 - A fix from Nish Aravamudan to reduce memory usage by clamping
   nodes_possible_map.

 - Support for pstore on powernv from Hari Bathini.

 - Removal of old powerpc specific byte swap routines by David Gibson.

 - Fix from Vasant Hegde to prevent the flash driver telling you it was
   flashing your firmware when it wasn't.

 - Patch from Ben Herrenschmidt to add an OPAL heartbeat driver.

 - Fix for an oops causing get/put_cpu_var() imbalance in perf by Jan
   Stancek.

 - Some fixes for migration from Tyrel Datwyler.

 - A new syscall to switch the cpu endian by Michael Ellerman.

 - Large series from Wei Yang to implement SRIOV, reviewed and acked by
   Bjorn.

 - A fix for the OPAL sensor driver from Cédric Le Goater.

 - Fixes to get STRICT_MM_TYPECHECKS building again by Michael Ellerman.

 - Large series from Daniel Axtens to make our PCI hooks per PHB rather
   than per machine.

 - Small patch from Sam Bobroff to explicitly abort non-suspended
   transactions on syscalls, plus a test to exercise it.

 - Numerous reworks and fixes for the 24x7 PMU from Sukadev Bhattiprolu.

 - Small patch to enable the hard lockup detector from Anton Blanchard.

 - Fix from Dave Olson for missing L2 cache information on some CPUs.

 - Some fixes from Michael Ellerman to get Cell machines booting again.

 - Freescale updates from Scott: Highlights include BMan device tree
   nodes, an MSI erratum workaround, a couple minor performance
   improvements, config updates, and misc fixes/cleanup.

* tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (196 commits)
  powerpc/powermac: Fix build error seen with powermac smp builds
  powerpc/pseries: Fix compile of memory hotplug without CONFIG_MEMORY_HOTREMOVE
  powerpc: Remove PPC32 code from pseries specific find_and_init_phbs()
  powerpc/cell: Fix iommu breakage caused by controller_ops change
  powerpc/eeh: Fix crash in eeh_add_device_early() on Cell
  powerpc/perf: Cap 64bit userspace backtraces to PERF_MAX_STACK_DEPTH
  powerpc/perf/hv-24x7: Fail 24x7 initcall if create_events_from_catalog() fails
  powerpc/pseries: Correct memory hotplug locking
  powerpc: Fix missing L2 cache size in /sys/devices/system/cpu
  powerpc: Add ppc64 hard lockup detector support
  oprofile: Disable oprofile NMI timer on ppc64
  powerpc/perf/hv-24x7: Add missing put_cpu_var()
  powerpc/perf/hv-24x7: Break up single_24x7_request
  powerpc/perf/hv-24x7: Define update_event_count()
  powerpc/perf/hv-24x7: Whitespace cleanup
  powerpc/perf/hv-24x7: Define add_event_to_24x7_request()
  powerpc/perf/hv-24x7: Rename hv_24x7_event_update
  powerpc/perf/hv-24x7: Move debug prints to separate function
  powerpc/perf/hv-24x7: Drop event_24x7_request()
  powerpc/perf/hv-24x7: Use pr_devel() to log message
  ...

Conflicts:
	tools/testing/selftests/powerpc/Makefile
	tools/testing/selftests/powerpc/tm/Makefile
This commit is contained in:
Linus Torvalds 2015-04-16 13:53:32 -05:00
commit d19d5efd8c
299 changed files with 8765 additions and 9770 deletions

View file

@ -12,37 +12,37 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
export CFLAGS
TARGETS = pmu copyloops mm tm primitives stringloops
SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian
endif
all: $(TARGETS)
all: $(SUB_DIRS)
$(TARGETS):
$(SUB_DIRS):
$(MAKE) -k -C $@ all
include ../lib.mk
override define RUN_TESTS
@for TARGET in $(TARGETS); do \
@for TARGET in $(SUB_DIRS); do \
$(MAKE) -C $$TARGET run_tests; \
done;
endef
override define INSTALL_RULE
@for TARGET in $(TARGETS); do \
@for TARGET in $(SUB_DIRS); do \
$(MAKE) -C $$TARGET install; \
done;
endef
override define EMIT_TESTS
@for TARGET in $(TARGETS); do \
@for TARGET in $(SUB_DIRS); do \
$(MAKE) -s -C $$TARGET emit_tests; \
done;
endef
clean:
@for TARGET in $(TARGETS); do \
@for TARGET in $(SUB_DIRS); do \
$(MAKE) -C $$TARGET clean; \
done;
rm -f tags
@ -50,4 +50,4 @@ clean:
tags:
find . -name '*.c' -o -name '*.h' | xargs ctags
.PHONY: tags $(TARGETS)
.PHONY: tags $(SUB_DIRS)

View file

@ -2,6 +2,7 @@
CFLAGS += -m64
CFLAGS += -I$(CURDIR)
CFLAGS += -D SELFTEST
CFLAGS += -maltivec
# Use our CFLAGS for the implicit .S rule
ASFLAGS = $(CFLAGS)

View file

@ -4,39 +4,6 @@
#define r1 1
#define vr0 0
#define vr1 1
#define vr2 2
#define vr3 3
#define vr4 4
#define vr5 5
#define vr6 6
#define vr7 7
#define vr8 8
#define vr9 9
#define vr10 10
#define vr11 11
#define vr12 12
#define vr13 13
#define vr14 14
#define vr15 15
#define vr16 16
#define vr17 17
#define vr18 18
#define vr19 19
#define vr20 20
#define vr21 21
#define vr22 22
#define vr23 23
#define vr24 24
#define vr25 25
#define vr26 26
#define vr27 27
#define vr28 28
#define vr29 29
#define vr30 30
#define vr31 31
#define R14 r14
#define R15 r15
#define R16 r16

View file

@ -11,6 +11,10 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <elf.h>
#include <fcntl.h>
#include <link.h>
#include <sys/stat.h>
#include "subunit.h"
#include "utils.h"
@ -112,3 +116,46 @@ int test_harness(int (test_function)(void), char *name)
return rc;
}
static char auxv[4096];
void *get_auxv_entry(int type)
{
ElfW(auxv_t) *p;
void *result;
ssize_t num;
int fd;
fd = open("/proc/self/auxv", O_RDONLY);
if (fd == -1) {
perror("open");
return NULL;
}
result = NULL;
num = read(fd, auxv, sizeof(auxv));
if (num < 0) {
perror("read");
goto out;
}
if (num > sizeof(auxv)) {
printf("Overflowed auxv buffer\n");
goto out;
}
p = (ElfW(auxv_t) *)auxv;
while (p->a_type != AT_NULL) {
if (p->a_type == type) {
result = (void *)p->a_un.a_val;
break;
}
p++;
}
out:
close(fd);
return result;
}

View file

@ -5,15 +5,10 @@
#define _GNU_SOURCE /* For CPU_ZERO etc. */
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <link.h>
#include <sched.h>
#include <setjmp.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "utils.h"
@ -256,45 +251,3 @@ out:
return rc;
}
static char auxv[4096];
void *get_auxv_entry(int type)
{
ElfW(auxv_t) *p;
void *result;
ssize_t num;
int fd;
fd = open("/proc/self/auxv", O_RDONLY);
if (fd == -1) {
perror("open");
return NULL;
}
result = NULL;
num = read(fd, auxv, sizeof(auxv));
if (num < 0) {
perror("read");
goto out;
}
if (num > sizeof(auxv)) {
printf("Overflowed auxv buffer\n");
goto out;
}
p = (ElfW(auxv_t) *)auxv;
while (p->a_type != AT_NULL) {
if (p->a_type == type) {
result = (void *)p->a_un.a_val;
break;
}
p++;
}
out:
close(fd);
return result;
}

View file

@ -29,7 +29,6 @@ extern int notify_parent(union pipe write_pipe);
extern int notify_parent_of_error(union pipe write_pipe);
extern pid_t eat_cpu(int (test_function)(void));
extern bool require_paranoia_below(int level);
extern void *get_auxv_entry(int type);
struct addr_range {
uint64_t first, last;

View file

@ -0,0 +1,2 @@
switch_endian_test
check-reversed.S

View file

@ -0,0 +1,24 @@
CC := $(CROSS_COMPILE)gcc
PROGS := switch_endian_test
ASFLAGS += -O2 -Wall -g -nostdlib -m64
all: $(PROGS)
switch_endian_test: check-reversed.S
check-reversed.o: check.o
$(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@
check-reversed.S: check-reversed.o
hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
run_tests: all
@-for PROG in $(PROGS); do \
./$$PROG; \
done;
clean:
rm -f $(PROGS) *.o check-reversed.S
.PHONY: all run_tests clean

View file

@ -0,0 +1,100 @@
#include "common.h"
/*
* Checks that registers contain what we expect, ie. they were not clobbered by
* the syscall.
*
* r15: pattern to check registers against.
*
* At the end r3 == 0 if everything's OK.
*/
nop # guaranteed to be illegal in reverse-endian
mr r9,r15
cmpd r9,r3 # check r3
bne 1f
addi r9,r15,4 # check r4
cmpd r9,r4
bne 1f
lis r9,0x00FF # check CR
ori r9,r9,0xF000
mfcr r10
and r10,r10,r9
cmpw r9,r10
addi r9,r15,34
bne 1f
addi r9,r15,32 # check LR
mflr r10
cmpd r9,r10
bne 1f
addi r9,r15,5 # check r5
cmpd r9,r5
bne 1f
addi r9,r15,6 # check r6
cmpd r9,r6
bne 1f
addi r9,r15,7 # check r7
cmpd r9,r7
bne 1f
addi r9,r15,8 # check r8
cmpd r9,r8
bne 1f
addi r9,r15,13 # check r13
cmpd r9,r13
bne 1f
addi r9,r15,14 # check r14
cmpd r9,r14
bne 1f
addi r9,r15,16 # check r16
cmpd r9,r16
bne 1f
addi r9,r15,17 # check r17
cmpd r9,r17
bne 1f
addi r9,r15,18 # check r18
cmpd r9,r18
bne 1f
addi r9,r15,19 # check r19
cmpd r9,r19
bne 1f
addi r9,r15,20 # check r20
cmpd r9,r20
bne 1f
addi r9,r15,21 # check r21
cmpd r9,r21
bne 1f
addi r9,r15,22 # check r22
cmpd r9,r22
bne 1f
addi r9,r15,23 # check r23
cmpd r9,r23
bne 1f
addi r9,r15,24 # check r24
cmpd r9,r24
bne 1f
addi r9,r15,25 # check r25
cmpd r9,r25
bne 1f
addi r9,r15,26 # check r26
cmpd r9,r26
bne 1f
addi r9,r15,27 # check r27
cmpd r9,r27
bne 1f
addi r9,r15,28 # check r28
cmpd r9,r28
bne 1f
addi r9,r15,29 # check r29
cmpd r9,r29
bne 1f
addi r9,r15,30 # check r30
cmpd r9,r30
bne 1f
addi r9,r15,31 # check r31
cmpd r9,r31
bne 1f
b 2f
1: mr r3, r9
li r0, __NR_exit
sc
2: li r0, __NR_switch_endian
nop

View file

@ -0,0 +1,6 @@
#include <ppc-asm.h>
#include <asm/unistd.h>
#ifndef __NR_switch_endian
#define __NR_switch_endian 363
#endif

View file

@ -0,0 +1,81 @@
#include "common.h"
.data
.balign 8
message:
.ascii "success: switch_endian_test\n\0"
.section ".toc"
.balign 8
pattern:
.llong 0x5555AAAA5555AAAA
.text
FUNC_START(_start)
/* Load the pattern */
ld r15, pattern@TOC(%r2)
/* Setup CR, only CR2-CR4 are maintained */
lis r3, 0x00FF
ori r3, r3, 0xF000
mtcr r3
/* Load the pattern slightly modified into the registers */
mr r3, r15
addi r4, r15, 4
addi r5, r15, 32
mtlr r5
addi r5, r15, 5
addi r6, r15, 6
addi r7, r15, 7
addi r8, r15, 8
/* r9 - r12 are clobbered */
addi r13, r15, 13
addi r14, r15, 14
/* Skip r15 we're using it */
addi r16, r15, 16
addi r17, r15, 17
addi r18, r15, 18
addi r19, r15, 19
addi r20, r15, 20
addi r21, r15, 21
addi r22, r15, 22
addi r23, r15, 23
addi r24, r15, 24
addi r25, r15, 25
addi r26, r15, 26
addi r27, r15, 27
addi r28, r15, 28
addi r29, r15, 29
addi r30, r15, 30
addi r31, r15, 31
/*
* Call the syscall to switch endian.
* It clobbers r9-r12, XER, CTR and CR0-1,5-7.
*/
li r0, __NR_switch_endian
sc
#include "check-reversed.S"
/* Flip back, r0 already has the switch syscall number */
.long 0x02000044 /* sc */
#include "check.S"
li r0, __NR_write
li r3, 1 /* stdout */
ld r4, message@got(%r2)
li r5, 28 /* strlen(message3) */
sc
li r0, __NR_exit
li r3, 0
sc
b .

View file

@ -1 +1,2 @@
tm-resched-dscr
tm-syscall

View file

@ -1,9 +1,12 @@
TEST_PROGS := tm-resched-dscr
TEST_PROGS := tm-resched-dscr tm-syscall
all: $(TEST_PROGS)
$(TEST_PROGS): ../harness.c
tm-syscall: tm-syscall-asm.S
tm-syscall: CFLAGS += -mhtm
include ../../lib.mk
clean:

View file

@ -0,0 +1,27 @@
#include <ppc-asm.h>
#include <asm/unistd.h>
.text
FUNC_START(getppid_tm_active)
tbegin.
beq 1f
li r0, __NR_getppid
sc
tend.
blr
1:
li r3, -1
blr
FUNC_START(getppid_tm_suspended)
tbegin.
beq 1f
li r0, __NR_getppid
tsuspend.
sc
tresume.
tend.
blr
1:
li r3, -1
blr

View file

@ -0,0 +1,121 @@
/*
* Copyright 2015, Sam Bobroff, IBM Corp.
* Licensed under GPLv2.
*
* Test the kernel's system call code to ensure that a system call
* made from within an active HTM transaction is aborted with the
* correct failure code.
* Conversely, ensure that a system call made from within a
* suspended transaction can succeed.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/tm.h>
#include <asm/cputable.h>
#include <linux/auxvec.h>
#include <sys/time.h>
#include <stdlib.h>
#include "utils.h"
extern int getppid_tm_active(void);
extern int getppid_tm_suspended(void);
unsigned retries = 0;
#define TEST_DURATION 10 /* seconds */
#define TM_RETRIES 100
long failure_code(void)
{
return __builtin_get_texasru() >> 24;
}
bool failure_is_persistent(void)
{
return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
}
bool failure_is_syscall(void)
{
return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
}
pid_t getppid_tm(bool suspend)
{
int i;
pid_t pid;
for (i = 0; i < TM_RETRIES; i++) {
if (suspend)
pid = getppid_tm_suspended();
else
pid = getppid_tm_active();
if (pid >= 0)
return pid;
if (failure_is_persistent()) {
if (failure_is_syscall())
return -1;
printf("Unexpected persistent transaction failure.\n");
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
__builtin_get_texasr(), __builtin_get_tfiar());
exit(-1);
}
retries++;
}
printf("Exceeded limit of %d temporary transaction failures.\n", TM_RETRIES);
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
__builtin_get_texasr(), __builtin_get_tfiar());
exit(-1);
}
int tm_syscall(void)
{
unsigned count = 0;
struct timeval end, now;
SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM));
setbuf(stdout, NULL);
printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
gettimeofday(&end, NULL);
now.tv_sec = TEST_DURATION;
now.tv_usec = 0;
timeradd(&end, &now, &end);
for (count = 0; timercmp(&now, &end, <); count++) {
/*
* Test a syscall within a suspended transaction and verify
* that it succeeds.
*/
FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
/*
* Test a syscall within an active transaction and verify that
* it fails with the correct failure code.
*/
FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
gettimeofday(&now, 0);
}
printf("%d active and suspended transactions behaved correctly.\n", count);
printf("(There were %d transaction retries.)\n", retries);
return 0;
}
int main(void)
{
return test_harness(tm_syscall, "tm_syscall");
}

View file

@ -15,11 +15,12 @@ typedef signed long long s64;
/* Just for familiarity */
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
int test_harness(int (test_function)(void), char *name);
extern void *get_auxv_entry(int type);
/* Yes, this is evil */
#define FAIL_IF(x) \

View file

@ -0,0 +1 @@
test-vphn

View file

@ -0,0 +1,15 @@
PROG := test-vphn
CFLAGS += -m64
all: $(PROG)
$(PROG): ../harness.c
run_tests: all
./$(PROG)
clean:
rm -f $(PROG)
.PHONY: all run_tests clean

View file

@ -0,0 +1,410 @@
#include <stdio.h>
#include <byteswap.h>
#include "utils.h"
#include "subunit.h"
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define cpu_to_be32(x) bswap_32(x)
#define be32_to_cpu(x) bswap_32(x)
#define be16_to_cpup(x) bswap_16(*x)
#define cpu_to_be64(x) bswap_64(x)
#else
#define cpu_to_be32(x) (x)
#define be32_to_cpu(x) (x)
#define be16_to_cpup(x) (*x)
#define cpu_to_be64(x) (x)
#endif
#include "vphn.c"
static struct test {
char *descr;
long input[VPHN_REGISTER_COUNT];
u32 expected[VPHN_ASSOC_BUFSIZE];
} all_tests[] = {
{
"vphn: no data",
{
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000000
}
},
{
"vphn: 1 x 16-bit value",
{
0x8001ffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000001,
0x00000001
}
},
{
"vphn: 2 x 16-bit values",
{
0x80018002ffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000002,
0x00000001,
0x00000002
}
},
{
"vphn: 3 x 16-bit values",
{
0x800180028003ffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000003,
0x00000001,
0x00000002,
0x00000003
}
},
{
"vphn: 4 x 16-bit values",
{
0x8001800280038004,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000004,
0x00000001,
0x00000002,
0x00000003,
0x00000004
}
},
{
/* Parsing the next 16-bit value out of the next 64-bit input
* value.
*/
"vphn: 5 x 16-bit values",
{
0x8001800280038004,
0x8005ffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
},
{
0x00000005,
0x00000001,
0x00000002,
0x00000003,
0x00000004,
0x00000005
}
},
{
/* Parse at most 6 x 64-bit input values */
"vphn: 24 x 16-bit values",
{
0x8001800280038004,
0x8005800680078008,
0x8009800a800b800c,
0x800d800e800f8010,
0x8011801280138014,
0x8015801680178018
},
{
0x00000018,
0x00000001,
0x00000002,
0x00000003,
0x00000004,
0x00000005,
0x00000006,
0x00000007,
0x00000008,
0x00000009,
0x0000000a,
0x0000000b,
0x0000000c,
0x0000000d,
0x0000000e,
0x0000000f,
0x00000010,
0x00000011,
0x00000012,
0x00000013,
0x00000014,
0x00000015,
0x00000016,
0x00000017,
0x00000018
}
},
{
"vphn: 1 x 32-bit value",
{
0x00000001ffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000001,
0x00000001
}
},
{
"vphn: 2 x 32-bit values",
{
0x0000000100000002,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000002,
0x00000001,
0x00000002
}
},
{
/* Parsing the next 32-bit value out of the next 64-bit input
* value.
*/
"vphn: 3 x 32-bit values",
{
0x0000000100000002,
0x00000003ffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000003,
0x00000001,
0x00000002,
0x00000003
}
},
{
/* Parse at most 6 x 64-bit input values */
"vphn: 12 x 32-bit values",
{
0x0000000100000002,
0x0000000300000004,
0x0000000500000006,
0x0000000700000008,
0x000000090000000a,
0x0000000b0000000c
},
{
0x0000000c,
0x00000001,
0x00000002,
0x00000003,
0x00000004,
0x00000005,
0x00000006,
0x00000007,
0x00000008,
0x00000009,
0x0000000a,
0x0000000b,
0x0000000c
}
},
{
"vphn: 16-bit value followed by 32-bit value",
{
0x800100000002ffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000002,
0x00000001,
0x00000002
}
},
{
"vphn: 32-bit value followed by 16-bit value",
{
0x000000018002ffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000002,
0x00000001,
0x00000002
}
},
{
/* Parse a 32-bit value split accross two consecutives 64-bit
* input values.
*/
"vphn: 16-bit value followed by 2 x 32-bit values",
{
0x8001000000020000,
0x0003ffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000003,
0x00000001,
0x00000002,
0x00000003,
0x00000004,
0x00000005
}
},
{
/* The lower bits in 0x0001ffff don't get mixed up with the
* 0xffff terminator.
*/
"vphn: 32-bit value has all ones in 16 lower bits",
{
0x0001ffff80028003,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff,
0xffffffffffffffff
},
{
0x00000003,
0x0001ffff,
0x00000002,
0x00000003
}
},
{
/* The following input doesn't follow the specification.
*/
"vphn: last 32-bit value is truncated",
{
0x0000000100000002,
0x0000000300000004,
0x0000000500000006,
0x0000000700000008,
0x000000090000000a,
0x0000000b800c2bad
},
{
0x0000000c,
0x00000001,
0x00000002,
0x00000003,
0x00000004,
0x00000005,
0x00000006,
0x00000007,
0x00000008,
0x00000009,
0x0000000a,
0x0000000b,
0x0000000c
}
},
{
"vphn: garbage after terminator",
{
0xffff2bad2bad2bad,
0x2bad2bad2bad2bad,
0x2bad2bad2bad2bad,
0x2bad2bad2bad2bad,
0x2bad2bad2bad2bad,
0x2bad2bad2bad2bad
},
{
0x00000000
}
},
{
NULL
}
};
static int test_one(struct test *test)
{
__be32 output[VPHN_ASSOC_BUFSIZE] = { 0 };
int i, len;
vphn_unpack_associativity(test->input, output);
len = be32_to_cpu(output[0]);
if (len != test->expected[0]) {
printf("expected %d elements, got %d\n", test->expected[0],
len);
return 1;
}
for (i = 1; i < len; i++) {
u32 val = be32_to_cpu(output[i]);
if (val != test->expected[i]) {
printf("element #%d is 0x%x, should be 0x%x\n", i, val,
test->expected[i]);
return 1;
}
}
return 0;
}
static int test_vphn(void)
{
static struct test *test;
for (test = all_tests; test->descr; test++) {
int ret;
ret = test_one(test);
test_finish(test->descr, ret);
if (ret)
return ret;
}
return 0;
}
int main(int argc, char **argv)
{
return test_harness(test_vphn, "test-vphn");
}

View file

@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.c

View file

@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.h