/*
 * Copyright (C) 2013 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

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

#include "base/cbfs/cbfs.h"
#include "base/cbfs/ram_media.h"

// Implementation of a media source based on given memory buffer.
struct ram_media
{
	char *start;
	size_t size;
};

static int ram_open(struct cbfs_media *media)
{
	return 0;
}

static void *ram_map(struct cbfs_media *media, size_t offset, size_t count)
{
	struct ram_media *m = (struct ram_media *)media->context;
	// Assume addressing from top of image in this case.
	if (offset > 0xf0000000)
		offset = m->size + offset;
	if (offset + count > m->size) {
		printf("ERROR: ram_map: request out of range (0x%zx+0x%zx)\n",
		       offset, count);
		return CBFS_MEDIA_INVALID_MAP_ADDRESS;
	}
	return (void *)(m->start + offset);
}

static void *ram_unmap(struct cbfs_media *media, const void *address)
{
	return NULL;
}

static size_t ram_read(struct cbfs_media *media, void *dest, size_t offset,
			   size_t count)
{
	void *ptr = ram_map(media, offset, count);
	if (ptr == CBFS_MEDIA_INVALID_MAP_ADDRESS)
		return 0;
	memcpy(dest, ptr, count);
	ram_unmap(media, ptr);
	return count;
}

static int ram_close(struct cbfs_media *media)
{
	return 0;
}

int init_cbfs_ram_media(struct cbfs_media *media, void *start, size_t size)
{
	// TODO Find a way to release unused media. Maybe adding media->destroy.
	struct ram_media *m = (struct ram_media*)malloc(sizeof(*m));
	m->start = start;
	m->size = size;
	media->context = (void*)m;
	media->open = ram_open;
	media->close = ram_close;
	media->map = ram_map;
	media->unmap = ram_unmap;
	media->read = ram_read;
	return 0;
}

// Legacy setup_cbfs_from_*.
static int is_default_cbfs_media_initialized;
static struct cbfs_media default_cbfs_media;

int setup_cbfs_from_ram(void *start, uint32_t size)
{
	int result = init_cbfs_ram_media(&default_cbfs_media, start, size);
	if (result == 0)
		is_default_cbfs_media_initialized = 1;
	return result;
}

int libpayload_init_default_cbfs_media(struct cbfs_media *media)
	__attribute__((weak));
int libpayload_init_default_cbfs_media(struct cbfs_media *media)
{
	return -1;
}

int setup_cbfs_from_flash(void)
{
	int result = libpayload_init_default_cbfs_media(&default_cbfs_media);
	if (result == 0)
	    is_default_cbfs_media_initialized = 1;
	return result;
}

int init_default_cbfs_media(struct cbfs_media *media)
{
	int result = 0;
	if (is_default_cbfs_media_initialized != 1)
		result = setup_cbfs_from_flash();
	if (result == 0)
		memcpy(media, &default_cbfs_media, sizeof(*media));
	return result;
}
