/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Kernel fatal error handler
 */

#include <kernel.h>
#include <kernel_internal.h>
#include <drivers/interrupt_controller/sysapic.h>
#include <arch/x86/ia32/segmentation.h>
#include <arch/syscall.h>
#include <ia32/exception.h>
#include <inttypes.h>
#include <exc_handle.h>
#include <logging/log.h>
#include <x86_mmu.h>
#include <sys/mem_manage.h>

LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);

#ifdef CONFIG_DEBUG_COREDUMP
unsigned int z_x86_exception_vector;
#endif

__weak void z_debug_fatal_hook(const z_arch_esf_t *esf) { ARG_UNUSED(esf); }

__pinned_func
void z_x86_spurious_irq(const z_arch_esf_t *esf)
{
	int vector = z_irq_controller_isr_vector_get();

	if (vector >= 0) {
		LOG_ERR("IRQ vector: %d", vector);
	}

	z_x86_fatal_error(K_ERR_SPURIOUS_IRQ, esf);
}

__pinned_func
void arch_syscall_oops(void *ssf)
{
	struct _x86_syscall_stack_frame *ssf_ptr =
		(struct _x86_syscall_stack_frame *)ssf;
	z_arch_esf_t oops = {
		.eip = ssf_ptr->eip,
		.cs = ssf_ptr->cs,
		.eflags = ssf_ptr->eflags
	};

	if (oops.cs == USER_CODE_SEG) {
		oops.esp = ssf_ptr->esp;
	}

	z_x86_fatal_error(K_ERR_KERNEL_OOPS, &oops);
}

extern void (*_kernel_oops_handler)(void);
NANO_CPU_INT_REGISTER(_kernel_oops_handler, NANO_SOFT_IRQ,
		      Z_X86_OOPS_VECTOR / 16, Z_X86_OOPS_VECTOR, 3);

#if CONFIG_EXCEPTION_DEBUG
__pinned_func
FUNC_NORETURN static void generic_exc_handle(unsigned int vector,
					     const z_arch_esf_t *pEsf)
{
#ifdef CONFIG_DEBUG_COREDUMP
	z_x86_exception_vector = vector;
#endif

	z_x86_unhandled_cpu_exception(vector, pEsf);
}

#define _EXC_FUNC(vector) \
__pinned_func \
FUNC_NORETURN __used static void handle_exc_##vector(const z_arch_esf_t *pEsf) \
{ \
	generic_exc_handle(vector, pEsf); \
}

#define Z_EXC_FUNC_CODE(vector, dpl) \
	_EXC_FUNC(vector) \
	_EXCEPTION_CONNECT_CODE(handle_exc_##vector, vector, dpl)

#define Z_EXC_FUNC_NOCODE(vector, dpl)	\
	_EXC_FUNC(vector) \
	_EXCEPTION_CONNECT_NOCODE(handle_exc_##vector, vector, dpl)

/* Necessary indirection to ensure 'vector' is expanded before we expand
 * the handle_exc_##vector
 */
#define EXC_FUNC_NOCODE(vector, dpl)		\
	Z_EXC_FUNC_NOCODE(vector, dpl)

#define EXC_FUNC_CODE(vector, dpl)		\
	Z_EXC_FUNC_CODE(vector, dpl)

EXC_FUNC_NOCODE(IV_DIVIDE_ERROR, 0);
EXC_FUNC_NOCODE(IV_NON_MASKABLE_INTERRUPT, 0);
EXC_FUNC_NOCODE(IV_OVERFLOW, 0);
EXC_FUNC_NOCODE(IV_BOUND_RANGE, 0);
EXC_FUNC_NOCODE(IV_INVALID_OPCODE, 0);
EXC_FUNC_NOCODE(IV_DEVICE_NOT_AVAILABLE, 0);
#ifndef CONFIG_X86_ENABLE_TSS
EXC_FUNC_NOCODE(IV_DOUBLE_FAULT, 0);
#endif
EXC_FUNC_CODE(IV_INVALID_TSS, 0);
EXC_FUNC_CODE(IV_SEGMENT_NOT_PRESENT, 0);
EXC_FUNC_CODE(IV_STACK_FAULT, 0);
EXC_FUNC_CODE(IV_GENERAL_PROTECTION, 0);
EXC_FUNC_NOCODE(IV_X87_FPU_FP_ERROR, 0);
EXC_FUNC_CODE(IV_ALIGNMENT_CHECK, 0);
EXC_FUNC_NOCODE(IV_MACHINE_CHECK, 0);
#endif

_EXCEPTION_CONNECT_CODE(z_x86_page_fault_handler, IV_PAGE_FAULT, 0);

#ifdef CONFIG_X86_ENABLE_TSS
static __pinned_noinit volatile z_arch_esf_t _df_esf;

/* Very tiny stack; just enough for the bogus error code pushed by the CPU
 * and a frame pointer push by the compiler. All df_handler_top does is
 * shuffle some data around with 'mov' statements and then 'iret'.
 */
static __pinned_noinit char _df_stack[8];

static FUNC_NORETURN __used void df_handler_top(void);

#ifdef CONFIG_X86_KPTI
extern char z_trampoline_stack_end[];
#endif

Z_GENERIC_SECTION(.tss)
struct task_state_segment _main_tss = {
	.ss0 = DATA_SEG,
#ifdef CONFIG_X86_KPTI
	/* Stack to land on when we get a soft/hard IRQ in user mode.
	 * In a special kernel page that, unlike all other kernel pages,
	 * is marked present in the user page table.
	 */
	.esp0 = (uint32_t)&z_trampoline_stack_end
#endif
};

/* Special TSS for handling double-faults with a known good stack */
Z_GENERIC_SECTION(.tss)
struct task_state_segment _df_tss = {
	.esp = (uint32_t)(_df_stack + sizeof(_df_stack)),
	.cs = CODE_SEG,
	.ds = DATA_SEG,
	.es = DATA_SEG,
	.ss = DATA_SEG,
	.eip = (uint32_t)df_handler_top,
	.cr3 = (uint32_t)
		Z_MEM_PHYS_ADDR(POINTER_TO_UINT(&z_x86_kernel_ptables[0]))
};

__pinned_func
static __used void df_handler_bottom(void)
{
	/* We're back in the main hardware task on the interrupt stack */
	unsigned int reason = K_ERR_CPU_EXCEPTION;

	/* Restore the top half so it is runnable again */
	_df_tss.esp = (uint32_t)(_df_stack + sizeof(_df_stack));
	_df_tss.eip = (uint32_t)df_handler_top;

	LOG_ERR("Double Fault");
#ifdef CONFIG_THREAD_STACK_INFO
	/* To comply with MISRA 13.2 rule necessary to exclude code that depends
	 * on the order of evaluation of function arguments.
	 * Create 2 variables to store volatile data from the structure _df_esf
	 */
	uint32_t df_esf_esp = _df_esf.esp;
	uint16_t df_esf_cs = _df_esf.cs;

	if (z_x86_check_stack_bounds(df_esf_esp, 0, df_esf_cs)) {
		reason = K_ERR_STACK_CHK_FAIL;
	}
#endif
	z_x86_fatal_error(reason, (z_arch_esf_t *)&_df_esf);
}

__pinned_func
static FUNC_NORETURN __used void df_handler_top(void)
{
	/* State of the system when the double-fault forced a task switch
	 * will be in _main_tss. Set up a z_arch_esf_t and copy system state into
	 * it
	 */
	_df_esf.esp = _main_tss.esp;
	_df_esf.ebp = _main_tss.ebp;
	_df_esf.ebx = _main_tss.ebx;
	_df_esf.esi = _main_tss.esi;
	_df_esf.edi = _main_tss.edi;
	_df_esf.edx = _main_tss.edx;
	_df_esf.eax = _main_tss.eax;
	_df_esf.ecx = _main_tss.ecx;
	_df_esf.errorCode = 0;
	_df_esf.eip = _main_tss.eip;
	_df_esf.cs = _main_tss.cs;
	_df_esf.eflags = _main_tss.eflags;

	/* Restore the main IA task to a runnable state */
	_main_tss.esp = (uint32_t)(Z_KERNEL_STACK_BUFFER(
		z_interrupt_stacks[0]) + CONFIG_ISR_STACK_SIZE);
	_main_tss.cs = CODE_SEG;
	_main_tss.ds = DATA_SEG;
	_main_tss.es = DATA_SEG;
	_main_tss.ss = DATA_SEG;
	_main_tss.eip = (uint32_t)df_handler_bottom;
	_main_tss.cr3 = z_mem_phys_addr(z_x86_kernel_ptables);
	_main_tss.eflags = 0U;

	/* NT bit is set in EFLAGS so we will task switch back to _main_tss
	 * and run df_handler_bottom
	 */
	__asm__ volatile ("iret");
	CODE_UNREACHABLE;
}

/* Configure a task gate descriptor in the IDT for the double fault
 * exception
 */
_X86_IDT_TSS_REGISTER(DF_TSS, -1, -1, IV_DOUBLE_FAULT, 0);

#endif /* CONFIG_X86_ENABLE_TSS */
