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

#include <zephyr/kernel.h>
#include <string.h>
#include <zephyr/arch/x86/multiboot.h>
#include <zephyr/arch/x86/memmap.h>

struct multiboot_info multiboot_info;

/*
 * called very early in the boot process to fetch data out of the multiboot
 * info struct. we need to grab the relevant data before any dynamic memory
 * allocation takes place, lest the struct itself or any data it points to
 * be overwritten before we read it.
 */

static inline void clear_memmap(int index)
{
	while (index < CONFIG_X86_MEMMAP_ENTRIES) {
		x86_memmap[index].type = X86_MEMMAP_ENTRY_UNUSED;
		++index;
	}
}

void z_multiboot_init(struct multiboot_info *info_pa)
{
	struct multiboot_info *info;

#if defined(CONFIG_ARCH_MAPS_ALL_RAM) || !defined(CONFIG_X86_MMU)
	/*
	 * Since the struct from bootloader resides in memory
	 * and all memory is mapped, there is no need to
	 * manually map it before accessing.
	 *
	 * Without MMU, all memory are identity-mapped already
	 * so there is no need to map them again.
	 */
	info = info_pa;
#else
	z_phys_map((uint8_t **)&info, POINTER_TO_UINT(info_pa),
		   sizeof(*info_pa), K_MEM_CACHE_NONE);
#endif /* CONFIG_ARCH_MAPS_ALL_RAM */

	if (info == NULL) {
		return;
	}

	memcpy(&multiboot_info, info, sizeof(*info));

#ifdef CONFIG_MULTIBOOT_MEMMAP
	/*
	 * If the extended map (basically, the equivalent of
	 * the BIOS E820 map) is available, then use that.
	 */

	if ((info->flags & MULTIBOOT_INFO_FLAGS_MMAP) &&
	    (x86_memmap_source < X86_MEMMAP_SOURCE_MULTIBOOT_MMAP)) {
		uintptr_t address;
		uintptr_t address_end;
		struct multiboot_mmap *mmap;
		int index = 0;
		uint32_t type;

#if defined(CONFIG_ARCH_MAPS_ALL_RAM) || !defined(CONFIG_X86_MMU)
		address = info->mmap_addr;
#else
		uint8_t *address_va;

		z_phys_map(&address_va, info->mmap_addr, info->mmap_length,
			   K_MEM_CACHE_NONE);

		address = POINTER_TO_UINT(address_va);
#endif /* CONFIG_ARCH_MAPS_ALL_RAM */

		address_end = address + info->mmap_length;

		while ((address < address_end) &&
		       (index < CONFIG_X86_MEMMAP_ENTRIES)) {
			mmap = UINT_TO_POINTER(address);

			x86_memmap[index].base = mmap->base;
			x86_memmap[index].length = mmap->length;

			switch (mmap->type) {
			case MULTIBOOT_MMAP_RAM:
				type = X86_MEMMAP_ENTRY_RAM;
				break;
			case MULTIBOOT_MMAP_ACPI:
				type = X86_MEMMAP_ENTRY_ACPI;
				break;
			case MULTIBOOT_MMAP_NVS:
				type = X86_MEMMAP_ENTRY_NVS;
				break;
			case MULTIBOOT_MMAP_DEFECTIVE:
				type = X86_MEMMAP_ENTRY_DEFECTIVE;
				break;
			default:
				type = X86_MEMMAP_ENTRY_UNKNOWN;
			}

			x86_memmap[index].type = type;
			++index;
			address += mmap->size + sizeof(mmap->size);
		}

		x86_memmap_source = X86_MEMMAP_SOURCE_MULTIBOOT_MMAP;
		clear_memmap(index);
	}

	/* If no extended map is available, fall back to the basic map. */

	if ((info->flags & MULTIBOOT_INFO_FLAGS_MEM) &&
	    (x86_memmap_source < X86_MEMMAP_SOURCE_MULTIBOOT_MEM)) {
		x86_memmap[0].base = 0;
		x86_memmap[0].length = info->mem_lower * 1024ULL;
		x86_memmap[0].type = X86_MEMMAP_ENTRY_RAM;

		if (CONFIG_X86_MEMMAP_ENTRIES > 1) {
			x86_memmap[1].base = 1048576U; /* 1MB */
			x86_memmap[1].length = info->mem_upper * 1024ULL;
			x86_memmap[1].type = X86_MEMMAP_ENTRY_RAM;
			clear_memmap(2);
		}

		x86_memmap_source = X86_MEMMAP_SOURCE_MULTIBOOT_MEM;
	}
#endif /* CONFIG_MULTIBOOT_MEMMAP */
}

#ifdef CONFIG_MULTIBOOT_FRAMEBUF

#include <zephyr/display/framebuf.h>

static struct framebuf_dev_data multiboot_framebuf_data = {
	.width = CONFIG_MULTIBOOT_FRAMEBUF_X,
	.height = CONFIG_MULTIBOOT_FRAMEBUF_Y
};

static int multiboot_framebuf_init(const struct device *dev)
{
	struct framebuf_dev_data *data = FRAMEBUF_DATA(dev);
	struct multiboot_info *info = &multiboot_info;

	if ((info->flags & MULTIBOOT_INFO_FLAGS_FB) &&
	    (info->fb_width >= CONFIG_MULTIBOOT_FRAMEBUF_X) &&
	    (info->fb_height >= CONFIG_MULTIBOOT_FRAMEBUF_Y) &&
	    (info->fb_bpp == 32) && (info->fb_addr_hi == 0)) {
		/*
		 * We have a usable multiboot framebuffer - it is 32 bpp
		 * and at least as large as the requested dimensions. Compute
		 * the pitch and adjust the start address center our canvas.
		 */

		uint16_t adj_x;
		uint16_t adj_y;
		uint32_t *buffer;

		adj_x = info->fb_width - CONFIG_MULTIBOOT_FRAMEBUF_X;
		adj_y = info->fb_height - CONFIG_MULTIBOOT_FRAMEBUF_Y;
		data->pitch = (info->fb_pitch / 4) + adj_x;
		adj_x /= 2U;
		adj_y /= 2U;
		buffer = (uint32_t *) (uintptr_t) info->fb_addr_lo;
		buffer += adj_x;
		buffer += adj_y * data->pitch;
		data->buffer = buffer;
		return 0;
	} else {
		return -ENOTSUP;
	}
}

DEVICE_DEFINE(multiboot_framebuf,
		    "FRAMEBUF",
		    multiboot_framebuf_init,
		    NULL,
		    &multiboot_framebuf_data,
		    NULL,
		    PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &framebuf_display_api);

#endif /* CONFIG_MULTIBOOT_FRAMEBUF */
