/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2012  Alexandru Gagniuc <mr.nuke.me@gmail.com>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "update_ucode.h"
#include <cpu/x86/msr.h>
#include <console/console.h>
#include <stddef.h>
#include <cpu/cpu.h>
#include <arch/cpu.h>
#include <cbfs.h>

static ucode_update_status nano_apply_ucode(const nano_ucode_header *ucode)
{
	printk(BIOS_SPEW, "Attempting to apply microcode update\n");

	msr_t msr;
	/* Address of ucode block goes in msr.lo for 32-bit mode
	 * Now remember, we need to pass the address of the actual microcode,
	 * not the header. The header is just there to help us. */
	msr.lo = (unsigned int)(&(ucode->ucode_start));
	msr.hi = 0;
	wrmsr(MSR_IA32_BIOS_UPDT_TRIG, msr);

	/* Let's see if we updated succesfully */
	msr = rdmsr(MSR_UCODE_UPDATE_STATUS);

	return msr.lo & 0x07;
}

static void nano_print_ucode_info(const nano_ucode_header *ucode)
{
	printk(BIOS_SPEW, "Microcode update information:\n");
	printk(BIOS_SPEW, "Name: %8s\n", ucode->name );
	printk(BIOS_SPEW, "Date: %u/%u/%u\n", ucode->month,
	       ucode->day, ucode->year );
}

static ucode_validity nano_ucode_is_valid(const nano_ucode_header *ucode)
{
	/* We must have a valid signature */
	if(ucode->signature != NANO_UCODE_SIGNATURE)
		return NANO_UCODE_SIGNATURE_ERROR;
	/* The size of the head must be exactly 12 double words */
	if( (ucode->total_size - ucode->payload_size) != NANO_UCODE_HEADER_SIZE)
		return NANO_UCODE_WRONG_SIZE;

	/* How about a checksum ? Checksum must be 0
	 * Two's complement done over the entire file, including the header */
	int i;
	u32 check = 0;
	u32 *raw = (void*) ucode;
	for(i = 0 ; i < ((ucode->total_size) >> 2); i++) {
		check += raw[i];
	}
	if(check != 0)
		return NANO_UCODE_CHECKSUM_FAIL;
	/* Made it here huh? Then it looks valid to us.
	 * If there's anything else wrong, the CPU will reject the update */
	return NANO_UCODE_VALID;
}

static void nano_print_ucode_status(ucode_update_status stat)
{
	switch(stat)
	{
	case UCODE_UPDATE_SUCCESS:
		printk(BIOS_INFO, "Microcode update succesful.\n");
		break;
	case UCODE_UPDATE_FAIL:
		printk(BIOS_ALERT, "Microcode update failed, bad environment."
				   "Update was not applied.\n");
		break;
	case UCODE_UPDATE_WRONG_CPU:
		printk(BIOS_ALERT, "Update not applicable to this CPU.\n");
		break;
	case UCODE_INVALID_UPDATE_BLOCK:
		printk(BIOS_ALERT, "Microcode block invalid."
				   "Update was not applied.\n");
		break;
	default:
		printk(BIOS_ALERT, "Unknown status. No update applied.\n");
	}
}

unsigned int nano_update_ucode(void)
{
	size_t i;
	unsigned int n_updates = 0;
	const struct cbfs_file *cbfs_ucode;
	u32 fms = cpuid_eax(0x1);

	cbfs_ucode = cbfs_get_file(CBFS_DEFAULT_MEDIA, "cpu_microcode_blob.bin");
	/* Oops, did you forget to include the microcode ? */
	if(cbfs_ucode == NULL) {
		printk(BIOS_ALERT, "WARNING: No microcode file found in CBFS. "
				   "Aborting microcode updates\n");
		return 0;
	}

	/* Considering we are running with eXecute-In-Place (XIP), there's no
	 * need to worry that accessing data from ROM will slow us down.
	 * Microcode data should be aligned to a 4-byte boundary, but CBFS
	 * already does that for us (Do you, CBFS?) */
	const u32 *ucode_data = CBFS_SUBHEADER(cbfs_ucode);
	const u32 ucode_len = ntohl(cbfs_ucode->len);

	/* We might do a lot of loops searching for the microcode updates, but
	 * keep in mind, nano_ucode_is_valid searches for the signature before
	 * doing anything else. */
	for( i = 0; i < (ucode_len >> 2); /* don't increment i here */ )
	{
		ucode_update_status stat;
		const nano_ucode_header * ucode = (void *)(&ucode_data[i]);
		if(nano_ucode_is_valid(ucode) != NANO_UCODE_VALID) {
			i++;
			continue;
		}
		/* Since we have a valid microcode, there's no need to search
		 * in this region, so we restart our search at the end of this
		 * microcode */
		i += (ucode->total_size >> 2);
		/* Is the microcode compatible with our CPU? */
		if(ucode->applicable_fms != fms) continue;
		/* For our most curious users */
		nano_print_ucode_info(ucode);
		/* The meat of the pie */
		stat = nano_apply_ucode(ucode);
		/* The user might want to know how the update went */
		nano_print_ucode_status(stat);
		if(stat == UCODE_UPDATE_SUCCESS) n_updates++;
	}

	return n_updates;
}
