/*
 * Check decoding of s390_pci_mmio_read and s390_pci_mmio_write syscalls.
 *
 * Copyright (c) 2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "tests.h"
#include <asm/unistd.h>

#if defined __NR_s390_pci_mmio_read && defined __NR_s390_pci_mmio_write

# include <errno.h>
# include <stdbool.h>
# include <stdint.h>
# include <stdio.h>
# include <unistd.h>

static void
do_call(bool wr, kernel_ulong_t mmio_addr, kernel_ulong_t buf,
	kernel_ulong_t len, bool buf_valid, const char *buf_str)
{
	long saved_errno = 0;
	long rc = 0;

	printf("s390_pci_mmio_%s(%#llx, ", wr ? "write" : "read",
	       (unsigned long long) mmio_addr);

	if (!wr) {
		rc = syscall(__NR_s390_pci_mmio_read, mmio_addr, buf, len);
		saved_errno = errno;
	}

	if (buf_valid && !rc) {
		char *buf_ptr = (char *) (uintptr_t) buf;

		print_quoted_hex(buf_ptr,
				 len > DEFAULT_STRLEN ? DEFAULT_STRLEN : len);

		if (len > DEFAULT_STRLEN)
			printf("...");
	} else {
		if (buf_str)
			printf("%s", buf_str);
		else
			printf("%#llx", (unsigned long long) buf);
	}

	printf(", %llu) = ", (unsigned long long) len);

	if (wr)
		rc = syscall(__NR_s390_pci_mmio_write, mmio_addr, buf, len);
	else
		errno = saved_errno;

	puts(sprintrc(rc));
}

int
main(void)
{
	static const size_t buf_size = DEFAULT_STRLEN + 10;

	char *buf = tail_alloc(buf_size);

	bool bools[] = { true, false };

	kernel_ulong_t addrs[] = {
		0,
		(kernel_ulong_t) 0xdeafbeefdeadc0deULL,
	};

	struct {
		kernel_ulong_t buf;
		const char *str;
		size_t size;
	} bufs[] = {
		{ (kernel_ulong_t) ARG_STR(NULL),            0 },
		{ (kernel_ulong_t) (buf + buf_size), NULL,   0 },
		{ (kernel_ulong_t) (buf),            NULL,   buf_size },
		{ (kernel_ulong_t) (buf + 9),        NULL,   buf_size - 9 },
		{ (kernel_ulong_t) (buf + 10),       NULL,   buf_size - 10 },
		{ (kernel_ulong_t) (buf + 16),       NULL,   buf_size - 16 },
		{ (kernel_ulong_t) (buf + 26),       NULL,   buf_size - 26 },
		{ (kernel_ulong_t) (buf + 28),       NULL,   buf_size - 28 },
	};

	kernel_ulong_t sizes[] = {
		0,
		DEFAULT_STRLEN / 2,
		DEFAULT_STRLEN - 10,
		DEFAULT_STRLEN,
		DEFAULT_STRLEN + 1,
		buf_size,
		buf_size + 10,
		(kernel_ulong_t) 0xfacefeedac0ffeedULL,
	};

	unsigned int i, j, k, l;
	unsigned int ctr = 0;

	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
		for (j = 0; j < ARRAY_SIZE(bufs); j++) {
			for (k = 0; k < ARRAY_SIZE(sizes); k++) {
				for (l = 0; l < ARRAY_SIZE(bools); l++) {
					bool valid = bufs[j].buf &&
						bufs[j].size >=
						MIN(sizes[k],
						    DEFAULT_STRLEN + 1);

					if (bufs[j].size && bools[l])
						fill_memory_ex((char *) buf,
							       bufs[j].size,
							       0xC0 + ctr, 255);

					do_call(bools[l], addrs[i], bufs[j].buf,
						sizes[k], valid, bufs[j].str);

					ctr++;
				}
			}
		}
	}

	puts("+++ exited with 0 +++");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("__NR_s390_pci_mmio_read && __NR_s390_pci_mmio_write");

#endif
