/*
 * Test sPAPR "Per Virtual Processor Area" and H_REGISTER_VPA hypervisor call
 * (also known as VPA, also known as lppaca in the Linux pseries kernel).
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.
 */
#include <libcflat.h>
#include <libfdt/libfdt.h>
#include <devicetree.h>
#include <util.h>
#include <alloc.h>
#include <asm/processor.h>
#include <asm/time.h>
#include <asm/setup.h>
#include <asm/hcall.h>
#include <asm/vpa.h>
#include <asm/io.h> /* for endian accessors */

static int verbose;

static void print_vpa(struct vpa *vpa)
{
	printf("VPA\n");
	printf("descriptor:			0x%08x\n", be32_to_cpu(vpa->descriptor));
	printf("size:				    0x%04x\n", be16_to_cpu(vpa->size));
	printf("status:				      0x%02x\n", vpa->status);
	printf("fru_node_id:			0x%08x\n", be32_to_cpu(vpa->fru_node_id));
	printf("fru_proc_id:			0x%08x\n", be32_to_cpu(vpa->fru_proc_id));
	printf("vhpn_change_counters:		0x%02x %02x %02x %02x %02x %02x %02x %02x\n", vpa->vhpn_change_counters[0], vpa->vhpn_change_counters[1], vpa->vhpn_change_counters[2], vpa->vhpn_change_counters[3], vpa->vhpn_change_counters[4], vpa->vhpn_change_counters[5], vpa->vhpn_change_counters[6], vpa->vhpn_change_counters[7]);
	printf("vp_dispatch_count:		0x%08x\n", be32_to_cpu(vpa->vp_dispatch_count));
	printf("vp_dispatch_dispersion:		0x%08x\n", be32_to_cpu(vpa->vp_dispatch_dispersion));
	printf("vp_fault_count:			0x%08lx\n", be64_to_cpu(vpa->vp_fault_count));
	printf("vp_fault_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_fault_tb));
	printf("purr_exprop_idle:		0x%08lx\n", be64_to_cpu(vpa->purr_exprop_idle));
	printf("spurr_exprop_idle:		0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_idle));
	printf("purr_exprop_busy:		0x%08lx\n", be64_to_cpu(vpa->purr_exprop_busy));
	printf("spurr_exprop_busy:		0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_busy));
	printf("purr_donate_idle:		0x%08lx\n", be64_to_cpu(vpa->purr_donate_idle));
	printf("spurr_donate_idle:		0x%08lx\n", be64_to_cpu(vpa->spurr_donate_idle));
	printf("purr_donate_busy:		0x%08lx\n", be64_to_cpu(vpa->purr_donate_busy));
	printf("spurr_donate_busy:		0x%08lx\n", be64_to_cpu(vpa->spurr_donate_busy));
	printf("vp_wait3_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait3_tb));
	printf("vp_wait2_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait2_tb));
	printf("vp_wait1_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait1_tb));
	printf("purr_exprop_adjunct_busy:	0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_busy));
	printf("spurr_exprop_adjunct_busy:	0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_busy));
	printf("purr_exprop_adjunct_idle:	0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_idle));
	printf("spurr_exprop_adjunct_idle:	0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_idle));
	printf("adjunct_insns_executed:		0x%08lx\n", be64_to_cpu(vpa->adjunct_insns_executed));
	printf("dtl_index:			0x%08lx\n", be64_to_cpu(vpa->dtl_index));
}

#define SUBFUNC_RESERVED	(0ULL << 45)
#define SUBFUNC_REGISTER	(1ULL << 45)
#define SUBFUNC_DEREGISTER	(5ULL << 45)

/*
 * Test the H_REGISTER_VPA h-call register/deregister calls.
 */
static void test_register_vpa(void)
{
	struct vpa *vpa;
	uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt());
	int rc;

	report_prefix_push("H_REGISTER_VPA");

	vpa = memalign(4096, sizeof(*vpa));

	memset(vpa, 0, sizeof(*vpa));

	vpa->size = cpu_to_be16(sizeof(*vpa));

	rc = hcall(H_REGISTER_VPA, SUBFUNC_RESERVED, cpuid, vpa);
	report(rc == H_PARAMETER, "Reserved sub-function fails with H_PARAMETER");

	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, 0xbadbad, vpa);
	report(rc == H_PARAMETER, "Register with invalid proc-no fails");

	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 8);
	report(rc == H_PARAMETER, "Register with VPA not cacheline aligned fails");


	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 4096 - 128);
	report(rc == H_PARAMETER, "Register with VPA spanning 4096 bytes fails");

	vpa->size = cpu_to_be16(632);
	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa);
	report(rc == H_PARAMETER, "Register with VPA size < 640 bytes fails");
	vpa->size = cpu_to_be16(sizeof(*vpa));

	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, PHYSICAL_END);
	report(rc == H_PARAMETER, "Register with VPA outside guest real memory fails");


	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa);
	report(rc == H_SUCCESS, "VPA registered");

	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL);
	report(rc == H_SUCCESS, "VPA deregistered");

	/*
	 * From PAPR: "note no check is made that a valid VPA registration
	 * exists".
	 */
	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL);
	report(rc == H_SUCCESS, "Deregister succeeds with no VPA registered");

	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, 0xbadbad, NULL);
	report(rc == H_PARAMETER, "Deregister with invalid proc-no fails");

	report_prefix_pop();
}

/*
 * Test some VPA fields.
 */
static void test_vpa(void)
{
	struct vpa *vpa;
	uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt());
	int disp_count1, disp_count2;
	int rc;

	report_prefix_push("VPA");

	vpa = memalign(4096, sizeof(*vpa));

	memset(vpa, 0, sizeof(*vpa));

	vpa->size = cpu_to_be16(sizeof(*vpa));

	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa);
	if (rc != H_SUCCESS) {
		report_skip("VPA could not be registered");
		return;
	}

	if (verbose)
		print_vpa(vpa);

	disp_count1 = be32_to_cpu(vpa->vp_dispatch_count);
	report(disp_count1 % 2 == 0, "Dispatch count is even while running");
	msleep(100);
	disp_count2 = be32_to_cpu(vpa->vp_dispatch_count);
	report(disp_count1 != disp_count2, "Dispatch count increments over H_CEDE");

	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, vpa);
	if (rc != H_SUCCESS)
		report_fail("Could not deregister after registration");

	disp_count1 = be32_to_cpu(vpa->vp_dispatch_count);
	/* TCG known fail, could be wrong test, must verify against PowerVM */
	report_kfail(true, disp_count1 % 2 == 1, "Dispatch count is odd after deregister");

	report_prefix_pop();
}

int main(int argc, char *argv[])
{
	int i;

	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-v") == 0) {
			verbose = 1;
		}
	}

	test_register_vpa();

	test_vpa();

	return report_summary();
}
