/*
 * This file is part of the flashrom project.
 *
 * Copyright 2021 Google LLC
 *
 * 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 "flash.h"
#include "writeprotect.h"
#include "chipdrivers/spi.h"

static void decode_range_generic(size_t *start, size_t *len, const struct wp_bits *bits, size_t chip_len,
				 bool fixed_block_len, bool apply_cmp_to_bp, int coeff_offset)
{
	const bool cmp = bits->cmp_bit_present && bits->cmp == 1;

	/* Interpret BP bits as an integer */
	size_t i;
	size_t bp = 0;
	size_t bp_max = 0;

	for (i = 0; i < bits->bp_bit_count; i++) {
		bp |= bits->bp[i] << i;
		bp_max |= 1 << i;
	}

	/*
	 * Most chips: the CMP bit only negates the range.
	 *
	 * Some MX chips: the CMP bit negates the BP bits and the range.
	 * (CMP bit is often the MSB BP bit in such chips.)
	 */
	if (cmp && apply_cmp_to_bp)
		bp ^= bp_max;

	if (bp == 0) {
		/* Special case: all BP bits are 0 => no write protection */
		*len = 0;
	} else if (bp == bp_max) {
		/* Special case: all BP bits are 1 => full write protection */
		*len = chip_len;
	} else {
		/*
		 * Usual case: the BP bits encode a coefficient in the form
		 * `coeff = 2 ** (bp - offset)` where `offset == 1`.
		 *
		 * The range's length is given by multiplying the coefficient
		 * by a base unit, usually a 4K sector or a 64K block.
		 */

		size_t coeff     = 1 << (bp - coeff_offset);
		size_t max_coeff = 1 << (bp_max - coeff_offset - 1);

		size_t sector_len        = 4  * KiB;
		size_t default_block_len = 64 * KiB;

		if (bits->sec_bit_present && bits->sec == 1) {
			/*
			 * SEC=1, protect 4K sectors. Flash chips clamp the
			 * protection length at 32K, probably to avoid overlap
			 * with the SEC=0 case.
			 */
			*len = min(sector_len * coeff, default_block_len / 2);
		} else {
			/*
			 * SEC=0 or is not present, protect blocks.
			 */
			size_t block_len = default_block_len;

			/*
			 * With very large chips, the 'block' size can be
			 * larger than 64K. This occurs when a larger block
			 * size is needed so that half the chip can be
			 * protected by the maximum possible coefficient.
			 */
			if (!fixed_block_len) {
				size_t min_block_len = chip_len / 2 / max_coeff;
				block_len = max(min_block_len, default_block_len);
			}

			*len = min(block_len * coeff, chip_len);
		}
	}

	/* Apply TB bit */
	bool protect_top = bits->tb_bit_present ? (bits->tb == 0) : 1;

	/* Apply CMP bit */
	if (cmp) {
		*len = chip_len - *len;
		protect_top = !protect_top;
	}

	/* Calculate start address, ensuring that empty ranges start at 0 */
	if (protect_top && *len > 0)
		*start = chip_len - *len;
	else
		*start = 0;
}

/*
 * Protection range calculation that works with many common SPI flash chips.
 */
void decode_range_spi25(size_t *start, size_t *len, const struct wp_bits *bits, size_t chip_len)
{
	decode_range_generic(start, len, bits, chip_len,
			     /*fixed_block_len=*/false, /*apply_cmp_to_bp=*/false, /*coeff_offset=*/1);
}

/*
 * Do not adjust block size to be able to fill half of the chip.
 */
void decode_range_spi25_64k_block(size_t *start, size_t *len, const struct wp_bits *bits, size_t chip_len)
{
	decode_range_generic(start, len, bits, chip_len,
			     /*fixed_block_len=*/true, /*apply_cmp_to_bp=*/false, /*coeff_offset=*/1);
}

/*
 * Inverts BP bits when CMP is set and treats all ones in BP bits as a request to protect whole chip regardless
 * of the CMP bit.
 */
void decode_range_spi25_bit_cmp(size_t *start, size_t *len, const struct wp_bits *bits, size_t chip_len)
{
	decode_range_generic(start, len, bits, chip_len,
			     /*fixed_block_len=*/false, /*apply_cmp_to_bp=*/true, /*coeff_offset=*/1);
}

/*
 * This multiplies coefficient by 2.  To be used with chips which have more BP bits than needed, such that the
 * most significant BP bit effectively acts as "protect whole chip" flag.
 */
void decode_range_spi25_2x_block(size_t *start, size_t *len, const struct wp_bits *bits, size_t chip_len)
{
	decode_range_generic(start, len, bits, chip_len,
			     /*fixed_block_len=*/false, /*apply_cmp_to_bp=*/false, /*coeff_offset=*/0);
}
