/*
 * 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;

	/* 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 (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;
	}
}
