/*
 * Copyright (C) 2017 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <environment.h>

DECLARE_GLOBAL_DATA_PTR;

static struct env_driver *env_driver_lookup(enum env_location loc)
{
	struct env_driver *drv;
	const int n_ents = ll_entry_count(struct env_driver, env_driver);
	struct env_driver *entry;

	drv = ll_entry_start(struct env_driver, env_driver);
	for (entry = drv; entry != drv + n_ents; entry++) {
		if (loc == entry->location)
			return entry;
	}

	/* Not found */
	return NULL;
}

static enum env_location env_get_default_location(void)
{
	if IS_ENABLED(CONFIG_ENV_IS_IN_DATAFLASH)
		return ENVL_DATAFLASH;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
		return ENVL_EEPROM;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
		return ENVL_FAT;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
		return ENVL_FLASH;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
		return ENVL_MMC;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND)
		return ENVL_NAND;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM)
		return ENVL_NVRAM;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE)
		return ENVL_REMOTE;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
		return ENVL_SPI_FLASH;
	else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
		return ENVL_UBI;
	else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
		return ENVL_NOWHERE;
	else
		return ENVL_UNKNOWN;
}

struct env_driver *env_driver_lookup_default(void)
{
	enum env_location loc = env_get_default_location();
	struct env_driver *drv;

	drv = env_driver_lookup(loc);
	if (!drv) {
		debug("%s: No environment driver for location %d\n", __func__,
		      loc);
		return NULL;
	}

	return drv;
}

int env_get_char(int index)
{
	struct env_driver *drv = env_driver_lookup_default();
	int ret;

	if (!gd->env_valid)
		return default_environment[index];
	if (!drv)
		return -ENODEV;
	if (!drv->get_char)
		return *(uchar *)(gd->env_addr + index);
	ret = drv->get_char(index);
	if (ret < 0) {
		debug("%s: Environment failed to load (err=%d)\n",
		      __func__, ret);
	}

	return ret;
}

int env_load(void)
{
	struct env_driver *drv = env_driver_lookup_default();
	int ret = 0;

	if (!drv)
		return -ENODEV;
	if (!drv->load)
		return 0;
	drv->load();  /* TODO(sjg@chromium.org): Make this return an error */
	if (ret) {
		debug("%s: Environment failed to load (err=%d)\n", __func__,
		      ret);
		return ret;
	}

	return 0;
}

int env_save(void)
{
	struct env_driver *drv = env_driver_lookup_default();
	int ret;

	if (!drv)
		return -ENODEV;
	if (!drv->save)
		return -ENOSYS;
	ret = drv->save();
	if (ret) {
		debug("%s: Environment failed to save (err=%d)\n", __func__,
		      ret);
		return ret;
	}

	return 0;
}

int env_init(void)
{
	struct env_driver *drv = env_driver_lookup_default();
	int ret = -ENOENT;

	if (!drv)
		return -ENODEV;
	if (drv->init)
		ret = drv->init();
	if (ret == -ENOENT) {
		gd->env_addr = (ulong)&default_environment[0];
		gd->env_valid = 0;

		return 0;
	} else if (ret) {
		debug("%s: Environment failed to init (err=%d)\n", __func__,
		      ret);
		return ret;
	}

	return 0;
}

void env_relocate_spec(void)
{
	env_load();
}

int saveenv(void)
{
	return env_save();
}

