/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
 *
 * 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; version 2 of the License.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <types.h>
#include <string.h>
#include <console/console.h>
#include <pc80/mc146818rtc.h>
#include <cpu/x86/car.h>
#include "chromeos.h"

#define VBNV_BLOCK_SIZE 16	/* Size of NV storage block in bytes */

/* Constants for NV storage.  We use this rather than structs and
 * bitfields so the data format is consistent across platforms and
 * compilers.
 */
#define HEADER_OFFSET                0
#define HEADER_MASK                     0xC0
#define HEADER_SIGNATURE                0x40
#define HEADER_FIRMWARE_SETTINGS_RESET  0x20
#define HEADER_KERNEL_SETTINGS_RESET    0x10

#define BOOT_OFFSET                  1
#define BOOT_DEBUG_RESET_MODE           0x80
#define BOOT_TRY_B_COUNT_MASK           0x0F

#define RECOVERY_OFFSET              2
#define LOCALIZATION_OFFSET          3

#define DEV_FLAGS_OFFSET             4
#define DEV_BOOT_USB_MASK               0x01

#define FIRMWARE_FLAGS_OFFSET        5
#define FIRMWARE_TEST_ERR_FUNC_MASK     0x38
#define FIRMWARE_TEST_ERR_FUNC_SHIFT    3
#define FIRMWARE_TEST_ERR_NUM_MASK      0x07

#define KERNEL_FIELD_OFFSET         11
#define CRC_OFFSET                  15

static int vbnv_initialized CAR_GLOBAL;
uint8_t vbnv[CONFIG_VBNV_SIZE] CAR_GLOBAL;

/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial.  A
 * table-based algorithm would be faster, but for only 15 bytes isn't
 * worth the code size.
 */

static uint8_t crc8(const uint8_t * data, int len)
{
	unsigned crc = 0;
	int i, j;

	for (j = len; j; j--, data++) {
		crc ^= (*data << 8);
		for (i = 8; i; i--) {
			if (crc & 0x8000)
				crc ^= (0x1070 << 3);
			crc <<= 1;
		}
	}

	return (uint8_t) (crc >> 8);
}

static void vbnv_setup(void)
{
	int i;

	for (i = 0; i < CONFIG_VBNV_SIZE; i++)
		vbnv[i] = cmos_read(CONFIG_VBNV_OFFSET + 14 + i);

	/* Check data for consistency */
	if ((HEADER_SIGNATURE != (vbnv[HEADER_OFFSET] & HEADER_MASK))
	    || (crc8(vbnv, CRC_OFFSET) != vbnv[CRC_OFFSET])) {

		/* Data is inconsistent (bad CRC or header),
		 * so reset to defaults
		 */
		memset(vbnv, 0, VBNV_BLOCK_SIZE);
		vbnv[HEADER_OFFSET] =
		    (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
		     HEADER_KERNEL_SETTINGS_RESET);
	}
	vbnv_initialized = 1;
}

int get_recovery_mode_from_vbnv(void)
{
	if (!vbnv_initialized)
		vbnv_setup();
	return vbnv[RECOVERY_OFFSET];
}
