/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2010 Advanced Micro Devices, Inc.
 *
 * 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
 */

static inline void _WRMSR(u32 addr, u32 lo, u32 hi)
{
	__asm__ volatile (
		"wrmsr"
		:
		:"c"(addr),"a"(lo), "d" (hi)
		);
}

static inline void _RDMSR(u32 addr, u32 *lo, u32 *hi)
{
	__asm__ volatile (
		"rdmsr"
		:"=a"(*lo), "=d" (*hi)
		:"c"(addr)
		);
}

static inline void _RDTSC(u32 *lo, u32 *hi)
{
	__asm__ volatile (
		 "rdtsc"
		 : "=a" (*lo), "=d"(*hi)
		 );
}

static inline void _cpu_id(u32 addr, u32 *val)
{
	__asm__ volatile(
		 "cpuid"
		 : "=a" (val[0]),
		   "=b" (val[1]),
		   "=c" (val[2]),
		   "=d" (val[3])
		 : "0" (addr));

}

static u32 bsr(u32 x)
{
	u8 i;
	u32 ret = 0;

	for(i=31; i>0; i--) {
		if(x & (1<<i)) {
			ret = i;
			break;
		}
	}

	return ret;

}

static u32 bsf(u32 x)
{
	u8 i;
	u32 ret = 32;

	for(i=0; i<32; i++) {
		if(x & (1<<i)) {
			ret = i;
			break;
		}
	}

	return ret;
}

#define _MFENCE asm volatile ( "mfence")

#define _SFENCE asm volatile ( "sfence" )

/* prevent speculative execution of following instructions */
#define _EXECFENCE asm volatile ("outb %al, $0xed")

static inline u32 read_cr4(void)
{
	u32 cr4;
	__asm__ volatile ("movl %%cr4, %0" : "=r" (cr4));
	return cr4;
}

static inline void write_cr4(u32 cr4)
{
	__asm__ volatile ("movl %0, %%cr4" : : "r" (cr4));
}

u32 SetUpperFSbase(u32 addr_hi);

static void proc_CLFLUSH(u32 addr_hi)
{
	SetUpperFSbase(addr_hi);

	__asm__ volatile (
		/* clflush fs:[eax] */
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		 "clflush %%fs:(%0)\n\t"
		"mfence\n\t"
		 ::"a" (addr_hi<<8)
	);
}


static void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num)
{
	__asm__ volatile (
		/*prevent speculative execution of following instructions*/
		/* FIXME: needed ? */
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"1:\n\t"
		"movdqa (%3), %%xmm0\n\t"
		"movntdq %%xmm0, %%fs:(%0)\n\t"	/* xmm0 is 128 bit */
		"addl %1, %0\n\t"
		"addl %1, %3\n\t"
		"loop 1b\n\t"
		"mfence\n\t"

		 :: "a" (addr_lo), "d" (16), "c" (line_num * 4), "b"(buf_a)
	);

}

static u32 read32_fs(u32 addr_lo)
{
	u32 value;
	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"movl %%fs:(%1), %0\n\t"
		:"=b"(value): "a" (addr_lo)
	);
	return value;
}

#ifdef UNUSED_CODE
static u8 read8_fs(u32 addr_lo)
{
	u8 byte;
	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"movb %%fs:(%1), %b0\n\t"
		"mfence\n\t"
		:"=b"(byte): "a" (addr_lo)
	);
	return byte;
}
#endif

static void FlushDQSTestPattern_L9(u32 addr_lo)
{
	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"clflush %%fs:-128(%%ecx)\n\t"
		"clflush %%fs:-64(%%ecx)\n\t"
		"clflush %%fs:(%%ecx)\n\t"
		"clflush %%fs:64(%%ecx)\n\t"

		"clflush %%fs:-128(%%eax)\n\t"
		"clflush %%fs:-64(%%eax)\n\t"
		"clflush %%fs:(%%eax)\n\t"
		"clflush %%fs:64(%%eax)\n\t"

		"clflush %%fs:-128(%%ebx)\n\t"

		 ::  "b" (addr_lo+128+8*64), "c"(addr_lo+128),
		     "a"(addr_lo+128+4*64)
	);

}

static __attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo)
{
	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"clflush %%fs:-128(%%eax)\n\t"
		"clflush %%fs:-64(%%eax)\n\t"
		"clflush %%fs:(%%eax)\n\t"
		"clflush %%fs:64(%%eax)\n\t"

		"clflush %%fs:-128(%%edi)\n\t"
		"clflush %%fs:-64(%%edi)\n\t"
		"clflush %%fs:(%%edi)\n\t"
		"clflush %%fs:64(%%edi)\n\t"

		"clflush %%fs:-128(%%ebx)\n\t"
		"clflush %%fs:-64(%%ebx)\n\t"
		"clflush %%fs:(%%ebx)\n\t"
		"clflush %%fs:64(%%ebx)\n\t"

		"clflush %%fs:-128(%%ecx)\n\t"
		"clflush %%fs:-64(%%ecx)\n\t"
		"clflush %%fs:(%%ecx)\n\t"
		"clflush %%fs:64(%%ecx)\n\t"

		"clflush %%fs:-128(%%edx)\n\t"
		"clflush %%fs:-64(%%edx)\n\t"

		 :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
		    "d" (addr_lo +128+16*64), "a"(addr_lo+128),
		    "D"(addr_lo+128+4*64)
	);
}

static void ReadL18TestPattern(u32 addr_lo)
{
	/* set fs and use fs prefix to access the mem */
	__asm__ volatile (
		"outb %%al, $0xed\n\t"			/* _EXECFENCE */
		"movl %%fs:-128(%%esi), %%eax\n\t" 	/* TestAddr cache line */
		"movl %%fs:-64(%%esi), %%eax\n\t"	/* +1 */
		"movl %%fs:(%%esi), %%eax\n\t"		/* +2 */
		"movl %%fs:64(%%esi), %%eax\n\t"	/* +3 */

		"movl %%fs:-128(%%edi), %%eax\n\t"	/* +4 */
		"movl %%fs:-64(%%edi), %%eax\n\t"	/* +5 */
		"movl %%fs:(%%edi), %%eax\n\t"		/* +6 */
		"movl %%fs:64(%%edi), %%eax\n\t"	/* +7 */

		"movl %%fs:-128(%%ebx), %%eax\n\t"	/* +8 */
		"movl %%fs:-64(%%ebx), %%eax\n\t"	/* +9 */
		"movl %%fs:(%%ebx), %%eax\n\t"		/* +10 */
		"movl %%fs:64(%%ebx), %%eax\n\t"	/* +11 */

		"movl %%fs:-128(%%ecx), %%eax\n\t"	/* +12 */
		"movl %%fs:-64(%%ecx), %%eax\n\t"	/* +13 */
		"movl %%fs:(%%ecx), %%eax\n\t"		/* +14 */
		"movl %%fs:64(%%ecx), %%eax\n\t"	/* +15 */

		"movl %%fs:-128(%%edx), %%eax\n\t"	/* +16 */
		"movl %%fs:-64(%%edx), %%eax\n\t"	/* +17 */
		"mfence\n\t"

		 :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
		    "d" (addr_lo +128+16*64), "S"(addr_lo+128),
		    "D"(addr_lo+128+4*64)
	);

}

static void ReadL9TestPattern(u32 addr_lo)
{

	/* set fs and use fs prefix to access the mem */
	__asm__ volatile (
		"outb %%al, $0xed\n\t"			/* _EXECFENCE */

		"movl %%fs:-128(%%ecx), %%eax\n\t"	/* TestAddr cache line */
		"movl %%fs:-64(%%ecx), %%eax\n\t"	/* +1 */
		"movl %%fs:(%%ecx), %%eax\n\t"		/* +2 */
		"movl %%fs:64(%%ecx), %%eax\n\t"	/* +3 */

		"movl %%fs:-128(%%edx), %%eax\n\t"	/* +4 */
		"movl %%fs:-64(%%edx), %%eax\n\t"	/* +5 */
		"movl %%fs:(%%edx), %%eax\n\t"		/* +6 */
		"movl %%fs:64(%%edx), %%eax\n\t"	/* +7 */

		"movl %%fs:-128(%%ebx), %%eax\n\t"	/* +8 */
		"mfence\n\t"

		 :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128),
		    "d"(addr_lo+128+4*64)
	);

}

static void ReadMaxRdLat1CLTestPattern_D(u32 addr)
{
	SetUpperFSbase(addr);

	__asm__ volatile (
		"outb %%al, $0xed\n\t"			/* _EXECFENCE */
		"movl %%fs:-128(%%esi), %%eax\n\t"	/* TestAddr cache line */
		"movl %%fs:-64(%%esi), %%eax\n\t"	/* +1 */
		"movl %%fs:(%%esi), %%eax\n\t"		/* +2 */
		"mfence\n\t"
		 :: "a"(0), "S"((addr<<8)+128)
	);

}

static void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr)
{
	SetUpperFSbase(addr);

	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"1:\n\t"
		"movdqa (%3), %%xmm0\n\t"
		"movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
		"addl %1, %0\n\t"
		"addl %1, %3\n\t"
		"loop 1b\n\t"
		"mfence\n\t"

		 :: "a" (addr<<8), "d" (16), "c" (3 * 4), "b"(buf)
	);
}

static void FlushMaxRdLatTestPattern_D(u32 addr)
{
	/*  Flush a pattern of 72 bit times (per DQ) from cache.
	 * This procedure is used to ensure cache miss on the next read training.
	 */

	SetUpperFSbase(addr);

	__asm__ volatile (
		"outb %%al, $0xed\n\t"	/* _EXECFENCE */
		"clflush %%fs:-128(%%esi)\n\t"	 /* TestAddr cache line */
		"clflush %%fs:-64(%%esi)\n\t"	 /* +1 */
		"clflush %%fs:(%%esi)\n\t"  /* +2 */
		"mfence\n\t"

		 :: "S"((addr<<8)+128)
	);
}

static u32 stream_to_int(u8 *p)
{
	int i;
	u32 val;
	u32 valx;

	val = 0;

	for(i=3; i>=0; i--) {
		val <<= 8;
		valx = *(p+i);
		val |= valx;
	}

	return val;
}

#ifdef UNUSED_CODE
static void oemSet_NB32(u32 addr, u32 val, u8 *valid)
{
}

static u32 oemGet_NB32(u32 addr,  u8 *valid)
{
	*valid = 0;
	return 0xffffffff;
}
#endif

static u8 oemNodePresent_D(u8 Node, u8 *ret)
{
	*ret = 0;
	return 0;
}
