/*
 * This file is part of msrtool.
 *
 * Copyright (c) 2008 Peter Stuge <peter@stuge.se>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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 <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "msrtool.h"

static void print_bitdef(FILE *f, const struct msrbits *mb, const char *tail) {
	uint8_t endbit;
	if (!reserved && 0 == strcmp(mb->name, "RSVD"))
		return;
	if (1 == mb->size)
		fprintf(f, "# %5d", mb->start);
	else {
		endbit = mb->start - mb->size + 1;
		fprintf(f, "# %*d:%d", endbit < 10 ? 3 : 2, mb->start, endbit);
	}
	if (0 == strcmp(mb->name, "RSVD"))
		fprintf(f, " [%s]", mb->desc);
	else
		fprintf(f, " %s %s", mb->name, mb->desc);
	fprintf(f, "%s", tail);
}

static void print_bitval(FILE *f, const struct msrbits *mb, const struct msr val) {
	uint8_t i;
	struct msr tmp, mask = MSR1(1);
	const struct msrbitvalues *mbv = mb->bitval;
	while (mbv->text && !msr_eq(mbv->value, val))
		mbv++;
	switch (mb->present) {
	case PRESENT_BIN:
		mask = msr_shl(mask, mb->size - 1);
		for (i = 0; i < mb->size; i++) {
			memcpy(&tmp, &val, sizeof(val));
			msr_and(&tmp, mask);
			fprintf(f, "%d", (tmp.hi || tmp.lo) ? 1 : 0);
			mask = msr_shr(mask, 1);
		}
		break;
	case PRESENT_DEC:
		fprintf(f, "%d", val.lo);
		break;
	case PRESENT_OCT:
		fprintf(f, "0%o", val.lo);
		break;
	case PRESENT_HEX:
		hexprint(f, val, mb->size);
		break;
	case PRESENT_HEXDEC:
		hexprint(f, val, mb->size);
		fprintf(f, " %d", val.lo);
		break;
	}
	if (mbv->text)
		fprintf(f, ": %s", mbv->text);
	fprintf(f, "\n");
}

void hexprint(FILE *f, const struct msr val, const uint8_t bits) {
	if (bits <= 4)
		fprintf(f, "0x%01x", val.lo & 0xf);
	else if (bits <= 8)
		fprintf(f, "0x%02x", val.lo & 0xff);
	else if (bits <= 12)
		fprintf(f, "0x%03x", val.lo & 0xfff);
	else if (bits <= 16)
		fprintf(f, "0x%04x", val.lo & 0xffff);
	else if (bits <= 20)
		fprintf(f, "0x%05x", val.lo & 0xfffff);
	else if (bits <= 24)
		fprintf(f, "0x%06x", val.lo & 0xffffff);
	else if (bits <= 28)
		fprintf(f, "0x%07x", val.lo & 0xfffffff);
	else if (bits <= 32)
		fprintf(f, "0x%08x", val.lo);
	else if (bits <= 36)
		fprintf(f, "0x%01x%08x", val.hi & 0xf, val.lo);
	else if (bits <= 40)
		fprintf(f, "0x%02x%08x", val.hi & 0xff, val.lo);
	else if (bits <= 44)
		fprintf(f, "0x%03x%08x", val.hi & 0xfff, val.lo);
	else if (bits <= 48)
		fprintf(f, "0x%04x%08x", val.hi & 0xffff, val.lo);
	else if (bits <= 52)
		fprintf(f, "0x%05x%08x", val.hi & 0xfffff, val.lo);
	else if (bits <= 56)
		fprintf(f, "0x%06x%08x", val.hi & 0xffffff, val.lo);
	else if (bits <= 60)
		fprintf(f, "0x%07x%08x", val.hi & 0xfffffff, val.lo);
	else
		fprintf(f, "0x%08x%08x", val.hi, val.lo);
}

int msr_eq(const struct msr a, const struct msr b) {
	return a.hi == b.hi && a.lo == b.lo;
}

struct msr msr_shl(const struct msr a, const uint8_t bits) {
	struct msr ret;

	ret.hi = bits < 32 ? a.hi << bits : 0;
	ret.lo = bits < 32 ? a.lo << bits : 0;

	if (bits < 32)
		ret.hi |= bits ? a.lo >> (32 - bits) : 0;
	else
		ret.hi |= a.lo << (bits - 32);

	return ret;
}

struct msr msr_shr(const struct msr a, const uint8_t bits) {
	struct msr ret;

	ret.hi = bits < 32 ? a.hi >> bits : 0;
	ret.lo = bits < 32 ? a.lo >> bits : 0;

	if (bits < 32)
		ret.lo |= bits ? a.hi << (32 - bits) : 0;
	else
		ret.lo |= a.hi >> (bits - 32);

	return ret;
}

void msr_and(struct msr *a, const struct msr b) {
	a->hi &= b.hi;
	a->lo &= b.lo;
}

const struct msrdef *findmsrdef(const uint32_t addr) {
	uint8_t t;
	const struct msrdef *m;
	if (!targets)
		return NULL;
	for (t = 0; t < targets_found; t++)
		for (m = targets[t]->msrs; !MSR_ISEOT(*m); m++)
			if (addr == m->addr)
				return m;
	return NULL;
}

uint32_t msraddrbyname(const char *name) {
	uint8_t t;
	const uint32_t addr = strtoul(name, NULL, 16);
	const struct msrdef *m;
	if (!targets)
		return addr;
	for (t = 0; t < targets_found; t++)
		for (m = targets[t]->msrs; !MSR_ISEOT(*m); m++) {
			if (addr == m->addr)
				return m->addr;
			if (!strcasecmp(name, m->symbol))
				return m->addr;
		}
	return addr;
}

void dumpmsrdefs(const struct targetdef *t) {
	const struct msrdef *m;
	const struct msrbits *mb;
	if (NULL == t)
		return;
	printf("# %s MSRs:\n", t->name);
	for (m = t->msrs; !MSR_ISEOT(*m); m++) {
		if (t->msrs != m)
			printf("\n");
		printf("# %s\n", m->symbol);
		for (mb = m->bits; mb->size; mb++)
			print_bitdef(stdout, mb, "\n");
		printf("0x%08x\n", m->addr);
	}
}

int dumpmsrdefsvals(FILE *f, const struct targetdef *t, const uint8_t cpu) {
	struct msr val = MSR1(0);
	const struct msrdef *m;
	const struct msrbits *mb;
	if (NULL == t)
		return 1;
	fprintf(f, "# %s MSRs:\n", t->name);
	for (m = t->msrs; !MSR_ISEOT(*m); m++) {
		if (t->msrs != m)
			fprintf(f, "\n");
		if (!sys->rdmsr(cpu, m->addr, &val))
			return 1;
		fprintf(f, "# %s\n", m->symbol);
		for (mb = m->bits; mb->size; mb++)
			print_bitdef(f, mb, "\n");
		fprintf(f, "0x%08x 0x%08x%08x\n", m->addr, val.hi, val.lo);
	}
	return 0;
}

/**
 * Parse a hexadecimal string into an MSR value.
 *
 * Leading 0x or 0X is optional, the string is always parsed as hexadecimal.
 * Any non-hexadecimal character except ' ' can separate the high 32 bits and
 * the low 32 bits. If there is such a separator, high and low values do not
 * need to be zero padded. If there is no separator, the last <=8 digits are
 * the low 32 bits and any characters before them are the high 32 bits.
 * When there is no separator and less than eight digits, the high 32 bits
 * are set to 0.
 * Parsing fails when there is a separator and it is followed by another
 * non-hexadecimal character.
 *
 * @param str The string to parse. The string must be writable but will be
 * restored before return.
 * @param msr Pointer to the struct msr where the value will be stored.
 * @param endptr If endptr is not NULL, *endptr will point to after the MSR.
 * @return 1 on success, 0 on parse failure. msr is unchanged on failure.
 */
uint8_t str2msr(char *str, struct msr *msr, char **endptr) {
	char c;
	size_t len, lo;
	if (0 == strncmp(str, "0x", 2) || 0 == strncmp(str, "0X", 2))
		str += 2;
	len = strspn(str, HEXCHARS);
	if (len <= 8 && (0 == str[len] || ' ' == str[len])) {
		msr->hi = 0;
		lo = 0;
	} else if (len <= 8) {
		lo = len + strcspn(str + len, HEXCHARS);
		if (0 == len && 0 == strspn(str + lo, HEXCHARS))
			return 0;
		c = str[len];
		str[len] = 0;
		msr->hi = strtoul(str, NULL, 16);
		str[len] = c;
	} else {
		lo = len - 8;
		c = str[lo];
		str[lo] = 0;
		msr->hi = strtoul(str, NULL, 16);
		str[lo] = c;
	}
	msr->lo = strtoul(str + lo, endptr, 16);
	return 1;
}

void decodemsr(const uint8_t cpu, const uint32_t addr, const struct msr val) {
	struct msr bitval, mask;
	const struct msrdef *m = findmsrdef(addr);
	const struct msrbits *mb;

	if (NULL != m)
		printf("# %s ", m->symbol);
	printf("0x%08x = 0x%08x%08x\n", addr, val.hi, val.lo);
	if (NULL == m) {
		fprintf(stderr, "Sorry - no definition exists for this MSR! Please add it and send a signed-off\n");
		fprintf(stderr, "patch to coreboot@coreboot.org. Thanks for your help!\n");
		return;
	}

	for (mb = m->bits; mb->size; mb++) {
		if (!reserved && 0 == strcmp(mb->name, "RSVD"))
			continue;
		print_bitdef(stdout, mb, " = ");
		mask.hi = mask.lo = 0xffffffff;
		mask = msr_shr(mask, 64 - mb->size);
		bitval = msr_shr(val, mb->start - mb->size + 1);
		msr_and(&bitval, mask);
		print_bitval(stdout, mb, bitval);
	}
}

/**
 * Compare two MSR values and print any differences with field definitions and
 * both old and new values decoded.
 *
 * @param f Output stream.
 * @param addr MSR address.
 * @param a Left value.
 * @param b Right value.
 * @return 1 when a and b differ, 0 when they are equal or only reserved bits
 * differ and processing of reserved bits was not requested (with -r).
 */
uint8_t diff_msr(FILE *f, const uint32_t addr, const struct msr a, const struct msr b) {
	uint8_t ret = 0, first = 1;
	struct msr aval, bval, mask;
	const struct msrdef *m = findmsrdef(addr);
	const struct msrbits *mb;

	if (a.hi == b.hi && a.lo == b.lo)
		return 0;

	if (NULL == m) {
		fprintf(stderr, "MSR 0x%08x has no definition! Please add it and send a Signed-off-by patch\n", addr);
		fprintf(stderr, "to coreboot@coreboot.org. Thank you for your help!\n");
		return 1;
	}

	for (mb = m->bits; mb->size; mb++) {
		if (!reserved && 0 == strcmp(mb->name, "RSVD"))
			continue;
		mask.hi = mask.lo = 0xffffffff;
		mask = msr_shr(mask, 64 - mb->size);
		aval = msr_shr(a, mb->start - mb->size + 1);
		bval = msr_shr(b, mb->start - mb->size + 1);
		msr_and(&aval, mask);
		msr_and(&bval, mask);
		if (msr_eq(aval, bval))
			continue;
		if (first) {
			fprintf(f, "# %s\n", m->symbol);
			fprintf(f, "-0x%08x 0x%08x%08x\n", addr, a.hi, a.lo);
			fprintf(f, "+0x%08x 0x%08x%08x\n", addr, b.hi, b.lo);
			first = 0;
			ret = 1;
		}
		print_bitdef(f, mb, "\n-");
		print_bitval(f, mb, aval);
		fprintf(f, "+");
		print_bitval(f, mb, bval);
	}
	return ret;
}
