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

#include <zephyr/spinlock.h>
#include <zephyr/arch/x86/efi.h>
#include <zephyr/kernel/mm.h>
#include "../zefi/efi.h" /* ZEFI not on include path */
#include <zephyr/kernel.h>
#include <kernel_arch_func.h>

#define EFI_CON_BUFSZ 128

/* Big stack for the EFI code to use */
static uint64_t __aligned(64) efi_stack[1024];

struct efi_boot_arg *efi;

void *efi_get_acpi_rsdp(void)
{
	if (efi == NULL) {
		return NULL;
	}

	return efi->acpi_rsdp;
}

void efi_init(struct efi_boot_arg *efi_arg)
{
	if (efi_arg == NULL) {
		return;
	}

	z_phys_map((uint8_t **)&efi, (uintptr_t)efi_arg,
		   sizeof(struct efi_boot_arg), 0);
}

/* EFI thunk.  Not a lot of code, but lots of context:
 *
 * We need to swap in the original EFI page tables for this to work,
 * as Zephyr has only mapped memory it uses and IO it knows about.  In
 * theory we might need to restore more state too (maybe the EFI code
 * uses special segment descriptors from its own GDT, maybe it relies
 * on interrupts in its own IDT, maybe it twiddles custom MSRs or
 * plays with the IO-MMU... the posibilities are endless).  But
 * experimentally, only the memory state seems to be required on known
 * hardware.  This is safe because in the existing architecture Zephyr
 * has already initialized all its own memory and left the rest of the
 * system as-is; we already know it doesn't overlap with the EFI
 * environment (because we've always just assumed that's the case,
 * heh).
 *
 * Similarly we need to swap the stack: EFI firmware was written in an
 * environment where it would be running on multi-gigabyte systems and
 * likes to overflow the tiny stacks Zephyr code uses.  (There is also
 * the problem of the red zone -- SysV reserves 128 bytes of
 * unpreserved data "under" the stack pointer for the use of the
 * current function.  Our compiler would be free to write things there
 * that might be clobbered by the EFI call, which doesn't understand
 * that rule.  Inspection of generated code shows that we're safe, but
 * still, best to swap stacks explicitly.)
 *
 * And the calling conventions are different: the EFI function uses
 * Microsoft's ABI, not SysV.  Parameters go in RCX/RDX/R8/R9 (though
 * we only pass two here), and return value is in RAX (which we
 * multiplex as an input to hold the function pointer).  R10 and R11
 * are also caller-save.  Technically X/YMM0-5 are caller-save too,
 * but as long as this (SysV) function was called per its own ABI they
 * have already been saved by our own caller.  Also note that there is
 * a 32 byte region ABOVE the return value that must be allocated by
 * the caller as spill space for the 4 register-passed arguments (this
 * ABI is so weird...).  We also need two call-preserved scratch
 * registers (for preserving the stack pointer and page table), those
 * are R12/R13.
 *
 * Finally: note that the firmware on at least one board (an Up
 * Squared APL device) will internally ENABLE INTERRUPTS before
 * returing from its OutputString method.  This is... unfortunate, and
 * says poor things about reliability using this code as it will
 * implicitly break the spinlock we're using.  The OS will be able to
 * take an interrupt just fine, but if the resulting ISR tries to log,
 * we'll end up in EFI firmware reentrantly!  The best we can do is an
 * unconditional CLI immediately after returning.
 */
static uint64_t efi_call(void *fn, uint64_t arg1, uint64_t arg2)
{
	void *stack_top = &efi_stack[ARRAY_SIZE(efi_stack) - 4];

	/* During the efi_call window the interrupt is enabled, that
	 * means an interrupt could happen and trigger scheduler at
	 * end of the interrupt. Try to prevent swap happening.
	 */
	k_sched_lock();

	__asm__ volatile("movq %%cr3, %%r12;" /* save zephyr page table */
			 "movq %%rsp, %%r13;" /* save stack pointer */
			 "movq %%rsi, %%rsp;" /* set stack */
			 "movq %%rdi, %%cr3;" /* set EFI page table */
			 "callq *%%rax;"
			 "cli;"
			 "movq %%r12, %%cr3;" /* reset paging */
			 "movq %%r13, %%rsp;" /* reset stack */
			 : "+a"(fn)
			 : "c"(arg1), "d"(arg2), "S"(stack_top), "D"(efi->efi_cr3)
			 : "r8", "r9", "r10", "r11", "r12", "r13");

	k_sched_unlock();
	return (uint64_t) fn;
}

int efi_console_putchar(int c)
{
	static struct k_spinlock lock;
	static uint16_t efibuf[EFI_CON_BUFSZ + 1];
	static int n;
	static void *conout;
	static void *output_string_fn;
	struct efi_system_table *efist = efi->efi_systab;

	/* Limit the printk call in interrupt context for
	 * EFI cosnsole. This is a workaround that prevents
	 * the printk call re-entries when an interrupt
	 * happens during the EFI call window.
	 */
	if (arch_is_in_isr()) {
		return 0;
	}

	if (c == '\n') {
		efi_console_putchar('\r');
	}

	k_spinlock_key_t key = k_spin_lock(&lock);

	/* These structs live in EFI memory and aren't mapped by
	 * Zephyr.  Extract the needed pointers by swapping page
	 * tables.  Do it via lazy evaluation because this code is
	 * routinely needed much earlier than any feasible init hook.
	 */
	if (conout == NULL) {
		uint64_t cr3;

		__asm__ volatile("movq %%cr3, %0" : "=r"(cr3));
		__asm__ volatile("movq %0, %%cr3" :: "r"(efi->efi_cr3));
		conout = efist->ConOut;
		output_string_fn = efist->ConOut->OutputString;
		__asm__ volatile("movq %0, %%cr3" :: "r"(cr3));
	}

	/* Buffer, to reduce trips through the thunking layer.
	 * Flushes when full and at newlines.
	 */
	efibuf[n++] = c;
	if (c == '\n' || n == EFI_CON_BUFSZ) {
		efibuf[n] = 0U;
		(void)efi_call(output_string_fn, (uint64_t)conout, (uint64_t)efibuf);
		n = 0;
	}

	k_spin_unlock(&lock, key);
	return 0;
}

#ifdef CONFIG_X86_EFI_CONSOLE
int arch_printk_char_out(int c)
{
	return efi_console_putchar(c);
}
#endif
