/*
 * This file is part of the coreinfo project.
 *
 * It is derived from the x86info project, which is GPLv2-licensed.
 *
 * Copyright (C) 2001-2007 Dave Jones <davej@codemonkey.org.uk>
 * Copyright (C) 2008 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.
 */

#include "coreinfo.h"

#if CONFIG(MODULE_CPUINFO)
#include <arch/rdtsc.h>

#define VENDOR_INTEL 0x756e6547
#define VENDOR_AMD   0x68747541
#define VENDOR_CYRIX 0x69727943
#define VENDOR_IDT   0x746e6543
#define VENDOR_GEODE 0x646f6547
#define VENDOR_RISE  0x52697365
#define VENDOR_RISE2 0x65736952
#define VENDOR_SIS   0x20536953

/* CPUID 0x00000001 EDX flags */
static const char *generic_cap_flags[] = {
	"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
	"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
	"pat", "pse36", "psn", "clflsh", NULL, "ds", "acpi", "mmx",
	"fxsr", "sse", "sse2", "ss", "ht", "tm", NULL, "pbe"
};

/* CPUID 0x00000001 ECX flags */
static const char *intel_cap_generic_ecx_flags[] = {
	"sse3", NULL, NULL, "monitor", "ds-cpl", "vmx", NULL, "est",
	"tm2", "ssse3", "cntx-id", NULL, NULL, "cx16", "xTPR", NULL,
	NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

/* CPUID 0x80000001 EDX flags */
static const char *intel_cap_extended_edx_flags[] = {
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, "SYSCALL", NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, "xd", NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, "em64t", NULL, NULL,
};

/* CPUID 0x80000001 ECX flags */
static const char *intel_cap_extended_ecx_flags[] = {
	"lahf_lm", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};

static const char *amd_cap_generic_ecx_flags[] = {
	"sse3", NULL, NULL, "mwait", NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, "cmpxchg16b", NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, "popcnt",
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

static const char *amd_cap_extended_edx_flags[] = {
	"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
	"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
	"pat", "pse36", NULL, "mp", "nx", NULL, "mmxext", "mmx",
	"fxsr", "ffxsr", "page1gb", "rdtscp",
	NULL, "lm", "3dnowext", "3dnow"
}; /* "mp" defined for CPUs prior to AMD family 0xf */

static const char *amd_cap_extended_ecx_flags[] = {
	"lahf/sahf", "CmpLegacy", "svm", "ExtApicSpace",
	"LockMovCr0", "abm", "sse4a", "misalignsse",
	"3dnowPref", "osvw", "ibs", NULL, "skinit", "wdt", NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

static uint32_t vendor;
static unsigned int cpu_khz;

static void decode_flags(WINDOW *win, unsigned long reg, const char **flags,
			 int *row)
{
	int i;
	int lrow = *row;

	wmove(win, lrow, 2);

	for (i = 0; i < 32; i++) {
		if (flags[i] == NULL)
			continue;

		if (reg & (1 << i))
			wprintw(win, "%s ", flags[i]);

		if (i && (i % 16) == 0) {
			lrow++;
			wmove(win, lrow, 2);
		}
	}

	*row = lrow;
}

static void get_features(WINDOW *win, int *row)
{
	uint32_t eax, ebx, ecx, edx;
	int lrow = *row;

	wmove(win, lrow++, 1);
	wprintw(win, "Features: ");

	docpuid(0x00000001, &eax, &ebx, &ecx, &edx);
	decode_flags(win, edx, generic_cap_flags, &lrow);

	lrow++;

	switch (vendor) {
	case VENDOR_AMD:
		wmove(win, lrow++, 1);
		wprintw(win, "AMD Extended Flags: ");
		decode_flags(win, ecx, amd_cap_generic_ecx_flags, &lrow);
		docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
		decode_flags(win, edx, amd_cap_extended_edx_flags, &lrow);
		decode_flags(win, ecx, amd_cap_extended_ecx_flags, &lrow);
		break;
	case VENDOR_INTEL:
		wmove(win, lrow++, 1);
		wprintw(win, "Intel Extended Flags: ");
		decode_flags(win, ecx, intel_cap_generic_ecx_flags, &lrow);
		docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
		decode_flags(win, edx, intel_cap_extended_edx_flags, &lrow);
		decode_flags(win, ecx, intel_cap_extended_ecx_flags, &lrow);
		break;
	}

	*row = lrow;
}

static void do_name(WINDOW *win, int row)
{
	char name[49], *p;
	uint32_t eax, ebx, ecx, edx;
	int t;

	p = name;

	for (uint32_t i = 0x80000002; i <= 0x80000004; i++) {
		docpuid(i, &eax, &ebx, &ecx, &edx);

		if (eax == 0)
			break;

		for (t = 0; t < 4; t++)
			*p++ = eax >> (8 * t);
		for (t = 0; t < 4; t++)
			*p++ = ebx >> (8 * t);
		for (t = 0; t < 4; t++)
			*p++ = ecx >> (8 * t);
		for (t = 0; t < 4; t++)
			*p++ = edx >> (8 * t);
	}

	mvwprintw(win, row, 1, "Processor: %s", name);
}

static int cpuinfo_module_redraw(WINDOW *win)
{
	uint32_t eax, ebx, ecx, edx;
	unsigned int brand;
	char *vstr;
	int row = 2;

	print_module_title(win, "CPU Information");

	docpuid(0, NULL, &vendor, NULL, NULL);

	switch (vendor) {
	case VENDOR_INTEL:
		vstr = "Intel";
		break;
	case VENDOR_AMD:
		vstr = "AMD";
		break;
	case VENDOR_CYRIX:
		vstr = "Cyrix";
		break;
	case VENDOR_IDT:
		vstr = "IDT";
		break;
	case VENDOR_GEODE:
		vstr = "NatSemi Geode";
		break;
	case VENDOR_RISE:
	case VENDOR_RISE2:
		vstr = "RISE";
		break;
	case VENDOR_SIS:
		vstr = "SiS";
		break;
	default:
		vstr = "Unknown";
		break;
	}

	mvwprintw(win, row++, 1, "Vendor: %s", vstr);

	do_name(win, row++);

	docpuid(0x00000001, &eax, &ebx, &ecx, &edx);

	mvwprintw(win, row++, 1, "Family: %X", (eax >> 8) & 0x0f);
	mvwprintw(win, row++, 1, "Model: %X",
		  ((eax >> 4) & 0xf) | ((eax >> 16) & 0xf) << 4);

	mvwprintw(win, row++, 1, "Stepping: %X", eax & 0xf);

	if (vendor == VENDOR_AMD) {
		docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
		brand = ((ebx >> 9) & 0x1f);

		mvwprintw(win, row++, 1, "Brand: %X", brand);
	}

	if (cpu_khz != 0)
		mvwprintw(win, row++, 1, "CPU Speed: %d Mhz", cpu_khz / 1000);
	else
		mvwprintw(win, row++, 1, "CPU Speed: Error");

	row++;
	get_features(win, &row);

	return 0;
}

static unsigned int getticks(void)
{
	unsigned long long start, end;

	/* Read the number of ticks during the period. */
	start = rdtsc();
	mdelay(100);
	end = rdtsc();

	return (unsigned int)((end - start) / 100);
}

static int cpuinfo_module_init(void)
{
	cpu_khz = getticks();
	return 0;
}

struct coreinfo_module cpuinfo_module = {
	.name = "CPU Info",
	.init = cpuinfo_module_init,
	.redraw = cpuinfo_module_redraw,
};

#else

struct coreinfo_module cpuinfo_module = {
};

#endif
