/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <kernel.h>
#include <string.h>
#include <misc/printk.h>
#include <kernel_structs.h>
#include <sys_io.h>
#include <ksched.h>
#include <syscall.h>
#include <syscall_handler.h>

const char *otype_to_str(enum k_objects otype)
{
	/* -fdata-sections doesn't work right except in very very recent
	 * GCC and these literal strings would appear in the binary even if
	 * otype_to_str was omitted by the linker
	 */
#ifdef CONFIG_PRINTK
	switch (otype) {
	/* Core kernel objects */
	case K_OBJ_ALERT:
		return "k_alert";
	case K_OBJ_MSGQ:
		return "k_msgq";
	case K_OBJ_MUTEX:
		return "k_mutex";
	case K_OBJ_PIPE:
		return "k_pipe";
	case K_OBJ_SEM:
		return "k_sem";
	case K_OBJ_STACK:
		return "k_stack";
	case K_OBJ_THREAD:
		return "k_thread";
	case K_OBJ_TIMER:
		return "k_timer";

	/* Driver subsystems */
	case K_OBJ_DRIVER_ADC:
		return "adc driver";
	case K_OBJ_DRIVER_AIO_CMP:
		return "aio comparator driver";
	case K_OBJ_DRIVER_CLOCK_CONTROL:
		return "clock control driver";
	case K_OBJ_DRIVER_COUNTER:
		return "counter driver";
	case K_OBJ_DRIVER_CRYPTO:
		return "crypto driver";
	case K_OBJ_DRIVER_DMA:
		return "dma driver";
	case K_OBJ_DRIVER_ETH:
		return "ethernet driver";
	case K_OBJ_DRIVER_FLASH:
		return "flash driver";
	case K_OBJ_DRIVER_GPIO:
		return "gpio driver";
	case K_OBJ_DRIVER_I2C:
		return "i2c driver";
	case K_OBJ_DRIVER_I2S:
		return "i2s driver";
	case K_OBJ_DRIVER_IPM:
		return "ipm driver";
	case K_OBJ_DRIVER_PINMUX:
		return "pinmux driver";
	case K_OBJ_DRIVER_PWM:
		return "pwm driver";
	case K_OBJ_DRIVER_RANDOM:
		return "random driver";
	case K_OBJ_DRIVER_RTC:
		return "realtime clock driver";
	case K_OBJ_DRIVER_SENSOR:
		return "sensor driver";
	case K_OBJ_DRIVER_SHARED_IRQ:
		return "shared irq driver";
	case K_OBJ_DRIVER_SPI:
		return "spi driver";
	case K_OBJ_DRIVER_UART:
		return "uart driver";
	case K_OBJ_DRIVER_WDT:
		return "watchdog timer driver";
	default:
		return "?";
	}
#else
	ARG_UNUSED(otype);
	return NULL;
#endif
}

void _thread_perms_set(struct _k_object *ko, struct k_thread *thread)
{
	if (thread->base.perm_index < 8 * CONFIG_MAX_THREAD_BYTES) {
		sys_bitfield_set_bit((mem_addr_t)&ko->perms,
				     thread->base.perm_index);
	}
}

static int thread_perms_test(struct _k_object *ko)
{
	if (_current->base.perm_index < 8 * CONFIG_MAX_THREAD_BYTES) {
		return sys_bitfield_test_bit((mem_addr_t)&ko->perms,
					     _current->base.perm_index);
	}
	return 0;
}

void _thread_perms_all_set(struct _k_object *ko)
{
	memset(ko->perms, 0xFF, CONFIG_MAX_THREAD_BYTES);
}

static void dump_permission_error(struct _k_object *ko)
{
	printk("thread %p (%d) does not have permission on %s %p [",
	       _current, _current->base.perm_index,
	       otype_to_str(ko->type), ko->name);
	for (int i = CONFIG_MAX_THREAD_BYTES - 1; i >= 0; i--) {
		printk("%02x", ko->perms[i]);
	}
	printk("]\n");
}

void _dump_object_error(int retval, void *obj, struct _k_object *ko,
			enum k_objects otype)
{
	switch (retval) {
	case -EBADF:
		printk("%p is not a valid %s\n", obj, otype_to_str(otype));
		break;
	case -EPERM:
		dump_permission_error(ko);
		break;
	case -EINVAL:
		printk("%p used before initialization\n", obj);
		break;
	}
}

void _impl_k_object_access_grant(void *object, struct k_thread *thread)
{
	struct _k_object *ko = _k_object_find(object);

	if (ko) {
		_thread_perms_set(ko, thread);
	}
}

void _impl_k_object_access_all_grant(void *object)
{
	struct _k_object *ko = _k_object_find(object);

	if (ko) {
		_thread_perms_all_set(ko);
	}
}

int _k_object_validate(struct _k_object *ko, enum k_objects otype, int init)
{
	if (!ko || (otype != K_OBJ_ANY && ko->type != otype)) {
		return -EBADF;
	}

	/* Manipulation of any kernel objects by a user thread requires that
	 * thread be granted access first, even for uninitialized objects
	 */
	if (!thread_perms_test(ko)) {
		return -EPERM;
	}

	/* If we are not initializing an object, and the object is not
	 * initialized, we should freak out
	 */
	if (!init && !(ko->flags & K_OBJ_FLAG_INITIALIZED)) {
		return -EINVAL;
	}

	return 0;
}

void _k_object_init(void *object)
{
	struct _k_object *ko;

	/* By the time we get here, if the caller was from userspace, all the
	 * necessary checks have been done in _k_object_validate(), which takes
	 * place before the object is initialized.
	 *
	 * This function runs after the object has been initialized and
	 * finalizes it
	 */

	ko = _k_object_find(object);
	if (!ko) {
		/* Supervisor threads can ignore rules about kernel objects
		 * and may declare them on stacks, etc. Such objects will never
		 * be usable from userspace, but we shouldn't explode.
		 */
		return;
	}

	/* Initializing an object implicitly grants access to the calling
	 * thread and nobody else
	 */
	memset(ko->perms, 0, CONFIG_MAX_THREAD_BYTES);
	_thread_perms_set(ko, _current);

	/* Allows non-initialization system calls to be made on this object */
	ko->flags |= K_OBJ_FLAG_INITIALIZED;
}

static u32_t _handler_bad_syscall(u32_t bad_id, u32_t arg2, u32_t arg3,
				  u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
	printk("Bad system call id %u invoked\n", bad_id);
	_arch_syscall_oops(ssf);
	CODE_UNREACHABLE;
}

static u32_t _handler_no_syscall(u32_t arg1, u32_t arg2, u32_t arg3,
				 u32_t arg4, u32_t arg5, u32_t arg6, void *ssf)
{
	printk("Unimplemented system call\n");
	_arch_syscall_oops(ssf);
	CODE_UNREACHABLE;
}

#include <syscall_dispatch.c>

