/*
 * This file is part of the flashprog project.
 *
 * Copyright (C) 2014 Stefan Tauner
 *
 * 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.
 */

#include <stddef.h>
#include <stdint.h>

#include "flash.h"
#include "programmer.h"

#include "chipdrivers/memory_bus.h"

static void *programmer_map_flash_region(const struct par_master *par, const char *descr,
					 uintptr_t phys_addr, chipsize_t len)
{
	void *ret;
	if (par->map_flash)
		ret = par->map_flash(descr, phys_addr, len);
	else
		ret = fallback_map(descr, phys_addr, len);
	msg_gspew("%s: mapping%s%s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
		  __func__, *descr ? " " : "", descr,
		  PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t)ret);
	return ret;
}

void programmer_unmap_flash_region(const struct par_master *par, void *virt_addr, chipsize_t len)
{
	if (par->unmap_flash)
		par->unmap_flash(virt_addr, len);
	else
		fallback_unmap(virt_addr, len);
	msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
}

static uintptr_t calculate_flash_data_base(const struct par_master *par, chipsize_t size)
{
	return par->rom_base ? par->rom_base : (0xffffffff - size + 1);
}

void *programmer_map_flash_data(const struct par_master *par, chipsize_t size, const char *descr)
{
	uintptr_t base = calculate_flash_data_base(par, size);
	void *const addr = programmer_map_flash_region(par, descr, base, size);
	if (addr == ERROR_PTR) {
		msg_perr("Could not map flash chip%s%s at 0x%0*" PRIxPTR ".\n",
			 *descr ? " " : "", descr, PRIxPTR_WIDTH, base);
	}
	return addr;
}

int prepare_memory_access(struct flashctx *flash, enum preparation_steps prep)
{
	const struct par_master *const par = flash->mst.par;

	if (prep == PREPARE_POST_PROBE)
		return 0;

	/* Init pointers to the fail-safe state to distinguish them later from legit values. */
	flash->virtual_memory = (chipaddr)ERROR_PTR;
	flash->virtual_registers = (chipaddr)ERROR_PTR;

	const chipsize_t size = flash->chip->total_size * 1024;
	void *const addr = programmer_map_flash_data(par, size, flash->chip->name);
	if (addr == ERROR_PTR)
		return 1;

	flash->physical_memory = calculate_flash_data_base(par, size);
	flash->virtual_memory = (chipaddr)addr;

	return 0;
}

int prepare_memory_register_access(struct flashctx *flash, enum preparation_steps prep)
{
	const struct par_master *const par = flash->mst.par;

	if (prep == PREPARE_POST_PROBE)
		return 0;

	if (prepare_memory_access(flash, prep))
		return 1;

	/*
	 * FIXME: Special function registers normally live 4 MByte below flash space,
	 * but it might be somewhere completely different on some chips and programmers,
	 * or not mappable at all. Ignore these problems for now and always report success.
	 */
	const chipsize_t size = flash->chip->total_size * 1024;
	const uintptr_t base = 0xffffffff - size - 0x400000 + 1;
	void *const addr = programmer_map_flash_region(par, "flash chip registers", base, size);
	if (addr == ERROR_PTR) {
		msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
			 flash->chip->name, PRIxPTR_WIDTH, base);
		return 0;
	}
	flash->physical_registers = base;
	flash->virtual_registers = (chipaddr)addr;

	return 0;
}

void finish_memory_access(struct flashctx *flash)
{
	const size_t size = flashprog_flash_getsize(flash);

	if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
		programmer_unmap_flash_region(flash->mst.par, (void *)flash->virtual_registers, size);
		flash->physical_registers = 0;
		flash->virtual_registers = (chipaddr)ERROR_PTR;
	}

	if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
		programmer_unmap_flash_region(flash->mst.par, (void *)flash->virtual_memory, size);
		flash->physical_memory = 0;
		flash->virtual_memory = (chipaddr)ERROR_PTR;
	}
}
