/*
 * Copyright 2013 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <stdio.h>
#include <stdlib.h>

#include "drivers/net/net.h"
#include "drivers/timer/timer.h"
#include "module/module.h"
#include "module/uefi/fwdb.h"
#include "net/gigaboot/gigaboot.h"
#include "net/netboot/netboot.h"
#include "net/netboot/params.h"


static GigabootBuffer *resize_gigaboot_buffer(GigabootBuffer *buf, size_t size)
{
	EFI_SYSTEM_TABLE *st = uefi_system_table_ptr();
	if (!st)
		return NULL;
	EFI_BOOT_SERVICES *bs = st->BootServices;

	if (buf->size < size) {
		EFI_PHYSICAL_ADDRESS data = (EFI_PHYSICAL_ADDRESS)(buf->data);
		if (bs->FreePages(data, buf->size / 4096)) {
			printf("Could not free previous gigaboot buffer.\n");
			buf->size = 0;
			return NULL;
		}
		buf->size = 0;

		data = 0xffffffff;
		if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
				      size / 4096, &data)) {
			printf("Failed to allocate gigaboot buffer.\n");
			return NULL;
		}
		buf->data = (void *)data;
		buf->size = size;
	}
	return buf;
}

GigabootBuffer *gigaboot_get_buffer(const char *name, size_t size)
{
	static GigabootBuffer kernel = {
		.data = (void *)(uintptr_t)CONFIG_KERNEL_START,
		.size = CONFIG_KERNEL_SIZE,
	};

	static char cmdline_buf[4096];
	static GigabootBuffer cmdline = {
		.data = cmdline_buf,
		.size = sizeof(cmdline_buf),
	};

	static GigabootBuffer ramdisk;

	if (!strcmp(name, gigaboot_buffer_kernel))
		return &kernel;
	if (!strcmp(name, gigaboot_buffer_cmdline))
		return &cmdline;
	if (!strcmp(name, gigaboot_buffer_ramdisk)) {
		if (ramdisk.size != 0 && size == 0)
			return &ramdisk;

		size_t buf_size =
			size > 0 ? (size + 4095) & ~4095 : 512 * 1024 * 1024;

		return resize_gigaboot_buffer(&ramdisk, buf_size);
	}
	return NULL;
}

void module_main(void)
{
	static char cmd_line[4096];

	srand(timer_raw_value());

	if (uefi_prepare_fwdb_file(L"depthcharge\\netboot_params",
				   "netboot_params") ||
	    uefi_prepare_fwdb_e820_map() ||
	    uefi_prepare_fwdb_acpi_rsdp()) {
		halt();
	}

	if (CONFIG_GIGABOOT)
		gigaboot();
	else
		netboot(cmd_line, sizeof(cmd_line));
}
