/*
 * 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.
 */

#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;
}
