/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2000 Denis Dowling <dpd@alphalink.com.au>
 * Copyright (C) 2010 Keith Hui <buurin@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.
 */

/*
 * Intel Pentium L2 Cache initialization.
 * This code was developed by reverse engineering
 * the BIOS. Where the code accesses documented
 * registers I have added comments as best I can.
 * Some undocumented registers on the Pentium II are
 * used so some of the documentation is incomplete.
 *
 * References:
 * Intel Architecture Software Developer's Manual
 * Volume 3B: System Programming Guide, Part 2 (#253669)
 * Appendix B.9
 */

/* This code is ported from coreboot v1.
 * The L2 cache initialization sequence here only apply to SECC/SECC2 P6 family
 * CPUs with Klamath (63x), Deschutes (65x) and Katmai (67x) cores.
 * It is not required for Coppermine (68x) and Tualatin (6bx) cores.
 * It is currently not known if Celerons with Mendocino (66x) core require the
 * special initialization.
 * Covington-core Celerons do not have L2 cache.
 */

#include <stdint.h>
#include <console/console.h>
#include <string.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/intel/l2_cache.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/msr.h>

/* Latency Tables */
struct latency_entry {
	u8 key;
	u8 value;
};
/*
Latency maps for Deschutes and Katmai.
No such mapping is available for Klamath.

Cache latency to
be written to L2 -----++++
control register      ||||
0000 xx 00 -----> 000 cccc 0
||||    00 66MHz
||||    10 100MHz
||||    01 133MHz (Katmai "B" only)
++++------ CPU frequency multiplier

0000 2x
0001 3x
0010 4x
0011 5x
0100 2.5x
0101 3.5x
0110 4.5x
0111 5.5x
1000 6x
1001 7x
1010 8x
1011 Reserved
1100 6.5x
1101 7.5x
1110 1.5x
1111 2x

*/
static const struct latency_entry latency_650_t0[] = {
	{0x10, 0x02}, {0x50, 0x02}, {0x20, 0x04}, {0x60, 0x06},
	{0x00, 0x08}, {0x40, 0x0C}, {0x12, 0x06}, {0x52, 0x0A},
	{0x22, 0x0E}, {0x62, 0x10}, {0x02, 0x10}, {0xFF, 0x00}
};

static const struct latency_entry latency_650_t1[] = {
	{0x12, 0x14}, {0x52, 0x16}, {0x22, 0x16}, {0x62, 0x16},
	{0xFF, 0x00}
};

static const struct latency_entry latency_670_t0[] = {
	{0x60, 0x06}, {0x00, 0x08}, {0x12, 0x06}, {0x52, 0x0A},
	{0x22, 0x0E}, {0x62, 0x10}, {0x02, 0x10}, {0x42, 0x02},
	{0x11, 0x0E}, {0x51, 0x0C}, {0x21, 0x02}, {0x61, 0x10},
	{0x01, 0x10}, {0x41, 0x02}, {0xFF, 0x00}
};

static const struct latency_entry latency_670_t1[] = {
	{0x22, 0x18}, {0x62, 0x18}, {0x02, 0x1A}, {0x11, 0x18},
	{0xFF, 0x00}
};

static const struct latency_entry latency_670_t2[] = {
	{0x22, 0x12}, {0x62, 0x14}, {0x02, 0x16}, {0x42, 0x1E},
	{0x11, 0x12}, {0x51, 0x16}, {0x21, 0x1E}, {0x61, 0x14},
	{0x01, 0x16}, {0x41, 0x1E}, {0xFF, 0x00}
};

/* Latency tables for 650 model/type */
static const struct latency_entry *latency_650[] = {
	latency_650_t0, latency_650_t1, latency_650_t1
};

/* Latency tables for 670 model/type */
static const struct latency_entry *latency_670[] = {
	latency_670_t0, latency_670_t1, latency_670_t2
};

int calculate_l2_latency(void)
{
	u32 eax, l, signature;
	const struct latency_entry *latency_table, *le;
	msr_t msr;

	/* First, attempt to get cache latency value from
	   IA32_PLATFORM_ID[56:53]. (L2 Cache Latency Read)
	 */
	msr = rdmsr(IA32_PLATFORM_ID);

	printk(BIOS_DEBUG,"rdmsr(IA32_PLATFORM_ID) = %x:%x\n", msr.hi, msr.lo);

	l = (msr.hi >> 20) & 0x1e;

	if (l == 0) {
		/* If latency value isn't available from
		   IA32_PLATFORM_ID[56:53], read it from
		   L2 control register 0 for lookup from
		   tables. */
		int t, a;

		/* The raw code is read from L2 register 0, bits [7:4]. */
		a = read_l2(0);
		if (a < 0)
			return -1;

		a &= 0xf0;

		if ((a & 0x20) == 0)
			t = 0;
		else if (a == 0x20)
			t = 1;
		else if (a == 0x30)
			t = 2;
		else
			return -1;

		printk(BIOS_DEBUG,"L2 latency type = %x\n", t);

		/* Get CPUID family/model */
		signature = cpuid_eax(1) & 0xfff0;

		/* Read EBL_CR_POWERON */
		msr = rdmsr(EBL_CR_POWERON);
		/* Get clock multiplier and FSB frequency.
		 * Multiplier is in [25:22].
		 * FSB is in [19:18] in Katmai, [19] in Deschutes ([18] is zero for them).
		 */
		eax = msr.lo >> 18;
		if (signature == 0x650) {
			eax &= ~0xf2;
			latency_table = latency_650[t];
		} else if (signature == 0x670) {
			eax &= ~0xf3;
			latency_table = latency_670[t];
		} else
			return -1;

		/* Search table for matching entry */
		for (le = latency_table; le->key != eax; le++) {
			/* Fail if we get to the end of the table */
			if (le->key == 0xff) {
				printk(BIOS_DEBUG, "Could not find key %02x in latency table\n", eax);
				return -1;
			}
		}

		l = le->value;
	}

	printk(BIOS_DEBUG,"L2 Cache latency is %d\n", l / 2);

	/* Writes the calculated latency in BBL_CR_CTL3[4:1]. */
	msr = rdmsr(BBL_CR_CTL3);
	msr.lo &= 0xffffffe1;
	msr.lo |= l;
	wrmsr(BBL_CR_CTL3, msr);

	return 0;
}


/* Setup address, data_high:data_low into the L2
 * control registers and then issue command with correct cache way
 */
int signal_l2(u32 address, u32 data_high, u32 data_low, int way, u8 command)
{
	int i;
	msr_t msr;

	/* Write L2 Address to BBL_CR_ADDR */
	msr.lo = address;
	msr.hi = 0;
	wrmsr(BBL_CR_ADDR, msr);

	/* Write data to BBL_CR_D{0..3} */
	msr.lo = data_low;
	msr.hi = data_high;
	for (i = BBL_CR_D0; i <= BBL_CR_D3; i++) {
		wrmsr(i, msr);
	}

	/* Put the command and way into BBL_CR_CTL */
	msr = rdmsr(BBL_CR_CTL);
	msr.lo = (msr.lo & 0xfffffce0) | command | (way << 8);
	wrmsr(BBL_CR_CTL, msr);

	/* Trigger L2 controller */
	msr.lo = 0;
	msr.hi = 0;
	wrmsr(BBL_CR_TRIG, msr);

	/* Poll the controller to see when done */
	for (i = 0; i < 0x100; i++) {
		/* Read BBL_CR_BUSY */
		msr = rdmsr(BBL_CR_BUSY);
		/* If not busy then return */
		if ((msr.lo & 1) == 0)
			return 0;
	}

	/* Return timeout code */
	return -1;
}

/* Read the L2 Cache controller register at given address */
int read_l2(u32 address)
{
	msr_t msr;

	/* Send a L2 Control Register Read to L2 controller */
	if (signal_l2(address << 5, 0, 0, 0, L2CMD_CR) != 0)
		return -1;

	/* If OK then get the result from BBL_CR_ADDR */
	msr = rdmsr(BBL_CR_ADDR);
	return (msr.lo >> 0x15);

}

/* Write data into the L2 controller register at address */
int write_l2(u32 address, u32 data)
{
	int v1, v2, i;

	v1 = read_l2(0);
	if (v1 < 0)
		return -1;

	v2 = read_l2(2);
	if (v2 < 0)
		return -1;

	if ((v1 & 0x20) == 0) {
		v2 &= 0x3;
		v2++;
	} else
		v2 &= 0x7;

	/* This write has to be replicated to a number of places. Not sure what. */

	for (i = 0; i < v2; i++) {

		u32 data1, data2;
		// Bits legend
		// data1   = ffffffff
		// data2   = 000000dc
		// address = 00aaaaaa
		// Final address signaled:
		// 000fffff fff000c0 000dcaaa aaa00000
		data1 = data & 0xff;
		data1 = data1 << 21;
		data2 = (i << 11) & 0x1800;
		data1 |= data2;
		data2 <<= 6;
		data2 &= 0x20000;
		data1 |= data2;

		/* Signal L2 controller */
		if (signal_l2((address << 5) | data1, 0, 0, 0, 3))
			return -1;
	}
	return 0;
}

/* Write data_high:data_low into the cache at address1. Test address2
 * to see if the same data is returned. Return 0 if the data matches.
 * return lower 16 bits if mismatched data if mismatch. Return -1
 * on error
 */
int test_l2_address_alias(u32 address1, u32 address2,
				 u32 data_high, u32 data_low)
{
	int d;
	msr_t msr;

	/* Tag Write with Data Write for L2 */
	if (signal_l2(address1, data_high, data_low, 0, L2CMD_TWW))
		return -1;

	/* Tag Read with Data Read for L2 */
	if (signal_l2(address2, 0, 0, 0, L2CMD_TRR))
		return -1;

	/* Read data from BBL_CR_D[0-3] */
	for (d = BBL_CR_D0; d <= BBL_CR_D3; d++) {
		msr = rdmsr(d);
		if (msr.lo != data_low || msr.hi != data_high)
			return (msr.lo & 0xffff);
	}

	return 0;
}

/* Calculates the L2 cache size.
 *
 * Reference: Intel(R) 64 and IA-32 Architectures Software Developer�s Manual
 *            Volume 3B: System Programming Guide, Part 2, Intel pub. 253669, pg. B-172.
 *
 */
int calculate_l2_cache_size(void)
{
	int v;
	msr_t msr;
	u32 cache_setting;
	u32 address, size, eax, bblcr3;

	v = read_l2(0);
	if (v < 0)
		return -1;
	if ((v & 0x20) == 0) {
		msr = rdmsr(BBL_CR_CTL3);
		bblcr3 = msr.lo & ~BBLCR3_L2_SIZE;
		/*
		 * Successively write in all the possible cache size per bank
		 * into BBL_CR_CTL3[17:13], starting from 256KB (00001) to 4MB (10000),
		 * and read the last value written and accepted by the cache.
		 *
		 * No idea why these bits are writable at all.
		 */
		for (cache_setting = BBLCR3_L2_SIZE_256K;
		     cache_setting <= BBLCR3_L2_SIZE_4M; cache_setting <<= 1) {

			eax = bblcr3 | cache_setting;
			msr.lo = eax;
			wrmsr(BBL_CR_CTL3, msr);
			msr = rdmsr(BBL_CR_CTL3);

			/* Value not accepted */
			if (msr.lo != eax)
				break;
		}

		/* Backtrack to the last value that worked... */
		cache_setting >>= 1;

		/* and write it into BBL_CR_CTL3 */
		msr.lo &= ~BBLCR3_L2_SIZE;
		msr.lo |= (cache_setting & BBLCR3_L2_SIZE);

		wrmsr(BBL_CR_CTL3, msr);

		printk(BIOS_DEBUG,"Maximum cache mask is %x\n", cache_setting);

		/* For now, BBL_CR_CTL3 has the highest cache "size" that register
		 * will accept. Now we'll ping the cache and see where it wraps.
		 */

		/* Write aaaaaaaa:aaaaaaaa to address 0 in the l2 cache.
		 * If this "alias test" returns an "address", it means the
		 * cache cannot be written to properly, and we have a problem.
		 */
		v = test_l2_address_alias(0, 0, 0xaaaaaaaa, 0xaaaaaaaa);
		if (v != 0)
			return -1;

		/* Start with 32K wrap point (256KB actually) */
		size = 1;
		address = 0x8000;

		while (1) {
			v = test_l2_address_alias(address, 0, 0x55555555,
						  0x55555555);
			// Write failed.
			if (v < 0)
				return -1;
			// It wraps here.
			else if (v == 0)
				break;

			size <<= 1;
			address <<= 1;

			if (address > 0x200000)
				return -1;
		}

		/* Mask size */
		size &= 0x3e;

		/* Shift to [17:13] */
		size <<= 12;

		/* Set this into BBL_CR_CTL3 */
		msr = rdmsr(BBL_CR_CTL3);
		msr.lo &= ~BBLCR3_L2_SIZE;
		msr.lo |= size;
		wrmsr(BBL_CR_CTL3, msr);

		printk(BIOS_DEBUG,"L2 Cache Mask is %x\n", size);

		/* Shift to [6:2] */
		size >>= 11;

		v = read_l2(2);

		if (v < 0)
			return -1;

		printk(BIOS_DEBUG,"L2(2): %x ", v);

		v &= 0x3;

		/* Shift size right by v */
		size >>= v;

		/* Or in this size */
		v |= size;

		printk(BIOS_DEBUG,"-> %x\n", v);

		if (write_l2(2, v) != 0)
			return -1;
	} else {
		// Some cache size information is available from L2 registers.
		// Work from there.
		int b, c;

		v = read_l2(2);

		printk(BIOS_DEBUG,"L2(2) = %x\n", v);

		if (v < 0)
			return -1;

		// L2 register 2 bitmap: cc---bbb
		b = v & 0x7;
		c = v >> 6;

		v = 1 << c * b;

		v &= 0xf;

		printk(BIOS_DEBUG,"Calculated a = %x\n", v);

		if (v == 0)
			return -1;

		/* Shift to 17:14 */
		v <<= 14;

		/* Write this size into BBL_CR_CTL3 */
		msr = rdmsr(BBL_CR_CTL3);
		msr.lo &= ~BBLCR3_L2_SIZE;
		msr.lo |= v;
		wrmsr(BBL_CR_CTL3, msr);
	}

	return 0;
}

// L2 physical address range can be found from L2 control register 3, bits [2:0].
int calculate_l2_physical_address_range(void)
{
	int r0, r3;
	msr_t msr;

	r3 = read_l2(3);
	if (r3 < 0)
		return -1;

	r0 = read_l2(0);
	if (r0 < 0)
		return -1;

	if (r0 & 0x20)
		r3 = 0x7;
	else
		r3 &= 0x7;

	printk(BIOS_DEBUG,"L2 Physical Address Range is %dM\n", (1 << r3) * 512);

	/* Shift into [22:20] to be saved into BBL_CR_CTL3. */
	r3 = r3 << 20;

	msr = rdmsr(BBL_CR_CTL3);
	msr.lo &= ~BBLCR3_L2_PHYSICAL_RANGE;
	msr.lo |= r3;
	wrmsr(BBL_CR_CTL3, msr);

	return 0;
}

int set_l2_ecc(void)
{
	u32 eax;
	const u32 data1 = 0xaa55aa55;
	const u32 data2 = 0xaaaaaaaa;
	msr_t msr;

	/* Set User Supplied ECC in BBL_CR_CTL */
	msr = rdmsr(BBL_CR_CTL);
	msr.lo |= BBLCR3_L2_SUPPLIED_ECC;
	wrmsr(BBL_CR_CTL, msr);

	/* Write a value into the L2 Data ECC register BBL_CR_DECC */
	msr.lo = data1;
	msr.hi = 0;
	wrmsr(BBL_CR_DECC, msr);

	if (test_l2_address_alias(0, 0, data2, data2) < 0)
		return -1;

	/* Read back ECC from BBL_CR_DECC */
	msr = rdmsr(BBL_CR_DECC);
	eax = msr.lo;

	if (eax == data1) {
		printk(BIOS_DEBUG,"L2 ECC Checking is enabled\n");

		/* Set ECC Check Enable in BBL_CR_CTL3 */
		msr = rdmsr(BBL_CR_CTL3);
		msr.lo |= BBLCR3_L2_ECC_CHECK_ENABLE;
		wrmsr(BBL_CR_CTL3, msr);
	}

	/* Clear User Supplied ECC in BBL_CR_CTL */
	msr = rdmsr(BBL_CR_CTL);
	msr.lo &= ~BBLCR3_L2_SUPPLIED_ECC;
	wrmsr(BBL_CR_CTL, msr);

	return 0;
}

/*
 * This is the function called from CPU initialization
 * driver to set up P6 family L2 cache.
 */

int p6_configure_l2_cache(void)
{
	msr_t msr, bblctl3;
	unsigned int eax;
	u16 signature;
	int cache_size, bank;
	int result, calc_eax;
	int v, a;

	int badclk1, badclk2, clkratio;
	int crctl3_or;

	printk(BIOS_INFO, "Configuring L2 cache... ");

	/* Read BBL_CR_CTL3 */
	bblctl3 = rdmsr(BBL_CR_CTL3);
	/* If bit 23 (L2 Hardware disable) is set then done */
	/* These would be Covington core Celerons with no L2 cache */
	if (bblctl3.lo & BBLCR3_L2_NOT_PRESENT) {
		printk(BIOS_INFO,"hardware disabled\n");
		return 0;
	}

	signature = cpuid_eax(1) & 0xfff0;

	/* Klamath-specific bit settings for certain
	   preliminary checks.
	 */
	if (signature == 0x630) {
		clkratio = 0x1c00000;
		badclk2 = 0x1000000;
		crctl3_or = 0x44000;
	} else {
		clkratio = 0x3c00000;
		badclk2 = 0x3000000;
		crctl3_or = 0x40000;
	}
	badclk1 = 0xc00000;

	/* Read EBL_CR_POWERON */
	msr = rdmsr(EBL_CR_POWERON);
	eax = msr.lo;
	/* Mask out [22-25] Clock frequency ratio */
	eax &= clkratio;
	if (eax == badclk1 || eax == badclk2) {
		printk(BIOS_ERR, "Incorrect clock frequency ratio %x\n", eax);
		return -1;
	}

	disable_cache();

	/* Mask out from BBL_CR_CTL3:
	 * [0] L2 Configured
	 * [5] ECC Check Enable
	 * [6] Address Parity Check Enable
	 * [7] CRTN Parity Check Enable
	 * [8] L2 Enabled
	 * [12:11] Number of L2 banks
	 * [17:13] Cache size per bank
	 * [18] (Set below)
	 * [22:20] L2 Physical Address Range Support
	 */
	bblctl3.lo &= 0xff88061e;
	/* Set:
	 * [17:13] = 00010 = 512Kbyte Cache size per bank (63x)
	 * [17:13] = 00000 = 128Kbyte Cache size per bank (all others)
	 * [18] Cache state error checking enable
	 */
	bblctl3.lo |= crctl3_or;

	/* Write BBL_CR_CTL3 */
	wrmsr(BBL_CR_CTL3, bblctl3);

	if (signature != 0x630) {
		eax = bblctl3.lo;

		/* Set the l2 latency in BBL_CR_CTL3 */
		if (calculate_l2_latency() != 0)
			goto bad;

		/* Read the new latency values back */
		bblctl3 = rdmsr(BBL_CR_CTL3);
		calc_eax = bblctl3.lo;

		/* Write back the original default value */
		bblctl3.lo = eax;
		wrmsr(BBL_CR_CTL3, bblctl3);

		/* Write BBL_CR_CTL3[27:26] (reserved??) to bits [1:0] of L2 register 4.
		 * Apparently all other bits must be preserved, hence these code.
		 */

		v = (calc_eax >> 26) & 0x3;

		printk(BIOS_DEBUG,"write_l2(4, %x)\n", v);

		a = read_l2(4);
		if (a >= 0)
		{
			a &= 0xfffc;
			a |= v;
			a = write_l2(4, a);
			/* a now contains result code from write_l2() */
		}
		if (a != 0)
			goto bad;

		/* Restore the correct latency value into BBL_CR_CTL3 */
		bblctl3.lo = calc_eax;
		wrmsr(BBL_CR_CTL3, bblctl3);
	} /* ! 63x CPU */

	/* Read L2 register 0 */
	v = read_l2(0);

	/* If L2(0)[5] set (and can be read properly), enable CRTN and address parity
	 */
	if (v >= 0 && (v & 0x20)) {
		bblctl3 = rdmsr(BBL_CR_CTL3);
		bblctl3.lo |= (BBLCR3_L2_ADDR_PARITY_ENABLE |
		               BBLCR3_L2_CRTN_PARITY_ENABLE);
		wrmsr(BBL_CR_CTL3, bblctl3);
	}

	/* If something goes wrong at L2 ECC setup, cache ECC
	 * will just remain disabled.
	 */
	set_l2_ecc();

	if (calculate_l2_physical_address_range() != 0) {
		printk(BIOS_ERR, "Failed to calculate L2 physical address range");
		goto bad;
	}

	if (calculate_l2_cache_size() != 0) {
		printk(BIOS_ERR, "Failed to calculate L2 cache size");
		goto bad;
	}

	/* Turn on cache. Only L1 is active at this time. */
	enable_cache();

	/* Get the calculated cache size from BBL_CR_CTL3[17:13] */
	bblctl3 = rdmsr(BBL_CR_CTL3);
	cache_size = (bblctl3.lo & BBLCR3_L2_SIZE);
	if (cache_size == 0)
		cache_size = 0x1000;
	cache_size = cache_size << 3;

	/* TODO: Cache size above is per bank. We're supposed to get
	 * the number of banks from BBL_CR_CTL3[12:11].
	 * Confirm that this still provides the correct answer.
	 */
	bank = (bblctl3.lo >> 11) & 0x3;
	if (bank == 0)
		bank = 1;

	printk(BIOS_INFO, "size %dK... ", cache_size * bank * 4 / 1024);

	/* Write to all cache lines to initialize */

	while (cache_size > 0) {

		/* Each cache line is 32 bytes. */
		cache_size -= 32;

		/* Update each way */

		/* We're supposed to get L2 associativity from BBL_CR_CTL3[10:9].
		 * But this code only applies to certain members of the P6 processor family
		 * and since all P6 processors have 4-way L2 cache, we can safely assume
		 * 4 way for all cache operations.
		 */

		for (v = 0; v < 4; v++) {
			/* Send Tag Write w/Data Write (TWW) to L2 controller
			 * MESI = Invalid
			 */
			if (signal_l2(cache_size, 0, 0, v, L2CMD_TWW | L2CMD_MESI_I) != 0) {
				printk(BIOS_ERR, "Failed on signal_l2(%x, %x)\n",
				       cache_size, v);
				goto bad;
			}
		}
	}
	printk(BIOS_DEBUG, "L2 Cache lines initialized\n");

	/* Disable cache */
	disable_cache();

	/* Set L2 cache configured in BBL_CR_CTL3 */
	bblctl3 = rdmsr(BBL_CR_CTL3);
	bblctl3.lo |= BBLCR3_L2_CONFIGURED;
	wrmsr(BBL_CR_CTL3, bblctl3);

	/* Invalidate cache and discard unsaved writes */
	asm volatile ("invd");

	/* Write 0 to L2 control register 5 */
	if (write_l2(5, 0) != 0) {
		printk(BIOS_ERR,"write_l2(5, 0) failed\n");
		goto done;
	}

	bblctl3 = rdmsr(BBL_CR_CTL3);
	if (signature == 0x650) {
		/* Change the L2 latency to 0101 then back to
		 * original value. I don't know why this is needed - dpd
		 */
		eax = bblctl3.lo;
		bblctl3.lo &= ~BBLCR3_L2_LATENCY;
		bblctl3.lo |= 0x0a;
		wrmsr(BBL_CR_CTL3, bblctl3);
		bblctl3.lo = eax;
		wrmsr(BBL_CR_CTL3, bblctl3);
	}

	/* Enable L2 in BBL_CR_CTL3 */
	bblctl3.lo |= BBLCR3_L2_ENABLED;
	wrmsr(BBL_CR_CTL3, bblctl3);

	/* Turn on cache. Both L1 and L2 are now active. Wahoo! */
done:
	result = 0;
	goto out;
bad:
	result = -1;
out:
	printk(BIOS_INFO, "done.\n");
	return result;
}
