/* Copyright (c) 2015 Google Inc
 * Davide Libenzi <dlibenzi@google.com>
 * See LICENSE for details.
 *
 * Part of this code coming from a Linux kernel file:
 *
 * linux/arch/x86/include/asm/uaccess.h
 *
 * Which, even though missing specific copyright, it is supposed to be
 * ruled by the overall Linux copyright.
 */

#pragma once

#include <ros/errno.h>
#include <compiler.h>
#include <stdint.h>
#include <umem.h>
#include <arch/fixup.h>

#define __m(x) *(x)

struct extable_ip_fixup {
	uint64_t insn;
	uint64_t fixup;
};

#define __read_msr_asm(eax, edx, addr, err, errret)						\
	asm volatile(ASM_STAC "\n"											\
	             "1:		rdmsr\n"									\
	             "			mfence\n"									\
	             "2: " ASM_CLAC "\n"									\
	             ".section .fixup,\"ax\"\n"								\
	             "3:		mov %4,%0\n"								\
	             "	jmp 2b\n"											\
	             ".previous\n"											\
	             _ASM_EXTABLE(1b, 3b)									\
	             : "=r" (err), "=d" (edx), "=a" (eax)					\
	             : "c" (addr), "i" (errret), "0" (err))

#define __write_msr_asm(val, addr, err, errret)							\
	asm volatile(ASM_STAC "\n"											\
				 "1:		wrmsr\n"									\
				 "2: " ASM_CLAC "\n"									\
				 ".section .fixup,\"ax\"\n"								\
				 "3:		mov %4,%0\n"								\
				 "	jmp 2b\n"											\
				 ".previous\n"											\
				 _ASM_EXTABLE(1b, 3b)									\
				 : "=r" (err)											\
				 : "d" ((uint32_t) (val >> 32)),						\
				   "a" ((uint32_t) (val & 0xffffffff)), "c" (addr),		\
				   "i" (errret), "0" (err))

#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)		\
	asm volatile(ASM_STAC "\n"											\
				 "1:		mov"itype" %"rtype"1,%2\n"					\
				 "2: " ASM_CLAC "\n"									\
				 ".section .fixup,\"ax\"\n"								\
				 "3:		mov %3,%0\n"								\
				 "	jmp 2b\n"											\
				 ".previous\n"											\
				 _ASM_EXTABLE(1b, 3b)									\
				 : "=r"(err)											\
				 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))

#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
	asm volatile(ASM_STAC "\n"										\
				 "1:		mov"itype" %2,%"rtype"1\n"				\
				 "2: " ASM_CLAC "\n"								\
				 ".section .fixup,\"ax\"\n"							\
				 "3:		mov %3,%0\n"							\
				 "	xor"itype" %"rtype"1,%"rtype"1\n"				\
				 "	jmp 2b\n"										\
				 ".previous\n"										\
				 _ASM_EXTABLE(1b, 3b)								\
				 : "=r" (err), ltype(x)								\
				 : "m" (__m(addr)), "i" (errret), "0" (err))

#define __user_memcpy(dst, src, count, err, errret)						\
	asm volatile(ASM_STAC "\n"											\
				 "  		cld\n"										\
				 "1:		rep movsb\n"								\
				 "2: " ASM_CLAC "\n"									\
				 ".section .fixup,\"ax\"\n"								\
				 "3:		mov %4,%0\n"								\
				 "	jmp 2b\n"											\
				 ".previous\n"											\
				 _ASM_EXTABLE(1b, 3b)									\
				 : "=r"(err), "+D" (dst), "+S" (src), "+c" (count)		\
				 : "i" (errret), "0" (err)								\
				 : "memory")

static inline int __put_user(void *dst, const void *src, unsigned int count)
{
	int err = 0;

	switch (count) {
	case 1:
		__put_user_asm(*(const uint8_t *) src, (uint8_t *) dst, err, "b",
		               "b", "iq", -EFAULT);
		break;
	case 2:
		__put_user_asm(*(const uint16_t *) src, (uint16_t *) dst, err, "w",
		               "w", "ir", -EFAULT);
		break;
	case 4:
		__put_user_asm(*(const uint32_t *) src, (uint32_t *) dst, err, "l",
		               "k", "ir", -EFAULT);
		break;
	case 8:
		__put_user_asm(*(const uint64_t *) src, (uint64_t *) dst, err, "q",
		               "", "er", -EFAULT);
		break;
	default:
		__user_memcpy(dst, src, count, err, -EFAULT);
	}

	return err;
}

static inline int copy_to_user(void *dst, const void *src, unsigned int count)
{
	int err = 0;

	if (unlikely(!is_user_rwaddr(dst, count))) {
		err = -EFAULT;
	} else if (!__builtin_constant_p(count)) {
		__user_memcpy(dst, src, count, err, -EFAULT);
	} else {
		err = __put_user(dst, src, count);
	}

	return err;
}

static inline int __get_user(void *dst, const void *src, unsigned int count)
{
	int err = 0;

	switch (count) {
	case 1:
		__get_user_asm(*(uint8_t *) dst, (const uint8_t *) src, err, "b",
		               "b", "=q", -EFAULT);
		break;
	case 2:
		__get_user_asm(*(uint16_t *) dst, (const uint16_t *) src, err, "w",
		               "w", "=r", -EFAULT);
		break;
	case 4:
		__get_user_asm(*(uint32_t *) dst, (const uint32_t *) src, err, "l",
		               "k", "=r", -EFAULT);
		break;
	case 8:
		__get_user_asm(*(uint64_t *) dst, (const uint64_t *) src, err, "q",
		               "", "=r", -EFAULT);
		break;
	default:
		__user_memcpy(dst, src, count, err, -EFAULT);
	}

	return err;
}

static inline int copy_from_user(void *dst, const void *src,
                                 unsigned int count)
{
	int err = 0;

	if (unlikely(!is_user_raddr((void *) src, count))) {
		err = -EFAULT;
	} else if (!__builtin_constant_p(count)) {
		__user_memcpy(dst, src, count, err, -EFAULT);
	} else {
		err = __get_user(dst, src, count);
	}

	return err;
}

static inline int read_msr_safe(uint32_t addr, uint64_t *value)
{
	int err = 0;
	uint32_t edx, eax;

	__read_msr_asm(eax, edx, addr, err, -EFAULT);
	if (likely(err == 0))
		*value = ((uint64_t) edx << 32) | eax;

	return err;
}

static inline int write_msr_safe(uint32_t addr, uint64_t value)
{
	int err = 0;

	__write_msr_asm(value, addr, err, -EFAULT);

	return err;
}

static inline uintptr_t ex_insn_addr(const struct extable_ip_fixup *x)
{
	return (uintptr_t) &x->insn + x->insn;
}

static inline uintptr_t ex_fixup_addr(const struct extable_ip_fixup *x)
{
	return (uintptr_t) &x->fixup + x->fixup;
}
