/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "efi.h"
#include "printf.h"
#include <zefi-segments.h>
#include <zephyr/arch/x86/efi.h>

#define PUTCHAR_BUFSZ 128

/* EFI GUID for RSDP
 * See "Finding the RSDP on UEFI Enabled Systems" in ACPI specs.
 */
#define ACPI_1_0_RSDP_EFI_GUID						\
	{								\
		.Data1 = 0xeb9d2d30,					\
		.Data2 = 0x2d88,					\
		.Data3 = 0x11d3,					\
		.Data4 = { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }, \
	}

#define ACPI_2_0_RSDP_EFI_GUID						\
	{								\
		.Data1 = 0x8868e871,					\
		.Data2 = 0xe4f1,					\
		.Data3 = 0x11d3,					\
		.Data4 = { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 }, \
	}

/* The linker places this dummy last in the data memory.  We can't use
 * traditional linker address symbols because we're relocatable; the
 * linker doesn't know what the runtime address will be.  The compiler
 * has to emit code to find this thing's address at runtime via an
 * offset from RIP.  It's a qword so we can guarantee alignment of the
 * stuff after.
 */
static __attribute__((section(".runtime_data_end")))
uint64_t runtime_data_end[1] = { 0x1111aa8888aa1111L };

#define EXT_DATA_START ((void *) &runtime_data_end[1])

static struct efi_system_table *efi;
static struct efi_boot_arg efi_arg;

static void efi_putchar(int c)
{
	static uint16_t efibuf[PUTCHAR_BUFSZ + 1];
	static int n;

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

	efibuf[n++] = c;

	if (c == '\n' || n == PUTCHAR_BUFSZ) {
		efibuf[n] = 0U;
		efi->ConOut->OutputString(efi->ConOut, efibuf);
		n = 0;
	}
}

static inline bool efi_guid_compare(efi_guid_t *s1, efi_guid_t *s2)
{
	return ((s1->Part1 == s2->Part1) && (s1->Part2 == s2->Part2));
}

static void *efi_config_get_vendor_table_by_guid(efi_guid_t *guid)
{
	struct efi_configuration_table *ect_tmp;
	int n_ct;

	if (efi == NULL) {
		return NULL;
	}

	ect_tmp = efi->ConfigurationTable;

	for (n_ct = 0; n_ct < efi->NumberOfTableEntries; n_ct++) {
		if (efi_guid_compare(&ect_tmp->VendorGuid, guid)) {
			return ect_tmp->VendorTable;
		}

		ect_tmp++;
	}

	return NULL;
}

static void efi_prepare_boot_arg(void)
{
	efi_guid_t rsdp_guid_1 = ACPI_1_0_RSDP_EFI_GUID;
	efi_guid_t rsdp_guid_2 = ACPI_2_0_RSDP_EFI_GUID;

	/* Let's lookup for most recent ACPI table first */
	efi_arg.acpi_rsdp = efi_config_get_vendor_table_by_guid(&rsdp_guid_2);
	if (efi_arg.acpi_rsdp == NULL) {
		efi_arg.acpi_rsdp =
			efi_config_get_vendor_table_by_guid(&rsdp_guid_1);
	}

	if (efi_arg.acpi_rsdp != NULL) {
		printf("RSDP found at %p\n", efi_arg.acpi_rsdp);
	}
}

/* Existing x86_64 EFI environments have a bad habit of leaving the
 * HPET timer running.  This then fires later on, once the OS has
 * started.  If the timing isn't right, it can happen before the OS
 * HPET driver gets a chance to disable it.  And because we do the
 * handoff (necessarily) with interrupts disabled, it's not actually
 * possible for the OS to reliably disable it in time anyway.
 *
 * Basically: it's our job as the bootloader to ensure that no
 * interrupt sources are live before entering the OS. Clear the
 * interrupt enable bit of HPET timer zero.
 */
static void disable_hpet(void)
{
	uint64_t *hpet = (uint64_t *)0xfed00000L;

	hpet[32] &= ~4;
}

/* FIXME: if you check the generated code, "ms_abi" calls like this
 * have to SPILL HALF OF THE SSE REGISTER SET TO THE STACK on entry
 * because of the way the conventions collide.  Is there a way to
 * prevent/suppress that?
 */
uintptr_t __abi efi_entry(void *img_handle, struct efi_system_table *sys_tab)
{
	efi = sys_tab;
	z_putchar = efi_putchar;
	printf("*** Zephyr EFI Loader ***\n");

	efi_prepare_boot_arg();

	for (int i = 0; i < sizeof(zefi_zsegs)/sizeof(zefi_zsegs[0]); i++) {
		int bytes = zefi_zsegs[i].sz;
		uint8_t *dst = (uint8_t *)zefi_zsegs[i].addr;

		printf("Zeroing %d bytes of memory at %p\n", bytes, dst);
		for (int j = 0; j < bytes; j++) {
			dst[j] = 0U;
		}
	}

	for (int i = 0; i < sizeof(zefi_dsegs)/sizeof(zefi_dsegs[0]); i++) {
		int bytes = zefi_dsegs[i].sz;
		int off = zefi_dsegs[i].off;
		uint8_t *dst = (uint8_t *)zefi_dsegs[i].addr;
		uint8_t *src = &((uint8_t *)EXT_DATA_START)[off];

		printf("Copying %d data bytes to %p from image offset %d\n",
		       bytes, dst, zefi_dsegs[i].off);
		for (int j = 0; j < bytes; j++) {
			dst[j] = src[j];
		}

		/* Page-aligned blocks below 1M are the .locore
		 * section, which has a jump in its first bytes for
		 * the benefit of 32 bit entry.  Those have to be
		 * written over with NOP instructions. (See comment
		 * about OUTRAGEOUS HACK in locore.S) before Zephyr
		 * starts, because the very first thing it does is
		 * install its own page table that disallows writes.
		 */
		if (((long)dst & 0xfff) == 0 && dst < (uint8_t *)0x100000L) {
			for (int i = 0; i < 8; i++) {
				dst[i] = 0x90; /* 0x90 == 1-byte NOP */
			}
		}
	}

	unsigned char *code = (void *)zefi_entry;

	efi_arg.efi_systab = efi;
	__asm__ volatile("movq %%cr3, %0" : "=r"(efi_arg.efi_cr3));

	printf("Jumping to Entry Point: %p (%x %x %x %x %x %x %x)\n",
	       code, code[0], code[1], code[2], code[3],
	       code[4], code[5], code[6]);

	disable_hpet();

	/* The EFI console seems to be buffered, give it a little time
	 * to drain before we start banging on the same UART from the
	 * OS.
	 */
	for (volatile int i = 0; i < 50000000; i++) {
	}

	__asm__ volatile("cli; movq %0, %%rbx; jmp *%1"
			 :: "r"(&efi_arg), "r"(code) : "rbx");

	return 0;
}

/* Trick cribbed shamelessly from gnu-efi.  We need to emit a ".reloc"
 * section into the image with a single dummy entry for the EFI loader
 * to think we're a valid PE file, gcc won't because it thinks we're
 * ELF.
 */
uint32_t relocation_dummy;
__asm__(".section .reloc\n"
	"base_relocation_block:\n"
	".long relocation_dummy - base_relocation_block\n"
	".long 0x0a\n"
	".word	0\n");
