/*
 * This file is part of the superiotool project.
 *
 * Copyright (C) 2006 Ronald Minnich <rminnich@gmail.com>
 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
 * Copyright (C) 2007 Carl-Daniel Hailfinger
 * Copyright (C) 2008 Robinson P. Tryon <bishop.robinson@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.
 */

#include "superiotool.h"

#if defined(__FreeBSD__)
#include <fcntl.h>
#include <unistd.h>
#endif

/* Command line options. */
int dump = 0, verbose = 0, extra_dump = 0, alternate_dump = 0;

/* Global flag which indicates whether a chip was detected at all. */
int chip_found = 0;

static void set_bank(uint16_t port, uint8_t bank)
{
	OUTB(0x4E, port);
	OUTB(bank, port + 1);
}

static uint8_t datareg(uint16_t port, uint8_t reg)
{
	OUTB(reg, port);
	return INB(port + 1);
}

uint8_t regval(uint16_t port, uint8_t reg)
{
	OUTB(reg, port);
	return INB(port + ((port == 0x3bd) ? 2 : 1)); /* 0x3bd is special. */
}

void regwrite(uint16_t port, uint8_t reg, uint8_t val)
{
	OUTB(reg, port);
	OUTB(val, port + 1);
}

void enter_conf_mode_winbond_fintek_ite_8787(uint16_t port)
{
	OUTB(0x87, port);
	OUTB(0x87, port);
}

void exit_conf_mode_winbond_fintek_ite_8787(uint16_t port)
{
	OUTB(0xaa, port);		/* Fintek, Winbond */
	regwrite(port, 0x02, 0x02);	/* ITE */
}

void enter_conf_mode_fintek_7777(uint16_t port)
{
	OUTB(0x77, port);
	OUTB(0x77, port);
}

void exit_conf_mode_fintek_7777(uint16_t port)
{
	OUTB(0xaa, port);		/* Fintek */
}

int superio_unknown(const struct superio_registers reg_table[], uint16_t id)
{
	return !strncmp(get_superio_name(reg_table, id), "<unknown>", 9);
}


const char *get_superio_name(const struct superio_registers reg_table[],
			     uint16_t id)
{
	int i;

	for (i = 0; /* Nothing */; i++) {
		if (reg_table[i].superio_id == EOT)
			break;

		if ((uint16_t)reg_table[i].superio_id != id)
			continue;

		return reg_table[i].name;
	}

	return "<unknown>";
}

static void dump_regs(const struct superio_registers reg_table[],
		      int i, int j, uint16_t port, uint8_t ldn_sel)
{
	int k;
	const int16_t *idx, *def;

	if (reg_table[i].ldn[j].ldn != NOLDN) {
		printf("LDN 0x%02x", reg_table[i].ldn[j].ldn);
		if (reg_table[i].ldn[j].name != NULL)
			printf(" (%s)", reg_table[i].ldn[j].name);
		regwrite(port, ldn_sel, reg_table[i].ldn[j].ldn);
	} else {
		if (reg_table[i].ldn[j].name == NULL)
			printf("Register dump:");
		else
			printf("(%s)", reg_table[i].ldn[j].name);
	}

	idx = reg_table[i].ldn[j].idx;
	def = reg_table[i].ldn[j].def;

	if (alternate_dump) {
		int skip_def = 0;

		printf("\nidx   val    def\n");

		for (k = 0; idx[k] != EOT; k++) {
			printf("0x%02x: 0x%02x", idx[k], regval(port, idx[k]));

			if (skip_def || def[k] == EOT) {
				skip_def = 1;
				printf("\n");
				continue;
			}
			if (def[k] == NANA)
				printf("   (NA)\n");
			else if (def[k] == RSVD)
				printf("   (RR)\n");
			else if (def[k] == MISC)
				printf("   (MM)\n");
			else
				printf("   (0x%02x)\n", def[k]);
		}
	} else {
		printf("\nidx");
		for (k = 0; idx[k] != EOT; k++) {
			if (k && !(k % 8))
				putchar(' ');
			printf(" %02x", idx[k]);
		}

		printf("\nval");
		for (k = 0; idx[k] != EOT; k++) {
			if (k && !(k % 8))
				putchar(' ');
			printf(" %02x", regval(port, idx[k]));
		}

		printf("\ndef");
		for (k = 0; def[k] != EOT; k++) {
			if (k && !(k % 8))
				putchar(' ');
			if (def[k] == NANA)
				printf(" NA");
			else if (def[k] == RSVD)
				printf(" RR");
			else if (def[k] == MISC)
				printf(" MM");
			else
				printf(" %02x", def[k]);
		}
	}
	printf("\n");
}

void dump_superio(const char *vendor,
		  const struct superio_registers reg_table[],
		  uint16_t port, uint16_t id, uint8_t ldn_sel)
{
	int i, j, no_dump_available = 1;

	if (!dump)
		return;

	for (i = 0; /* Nothing */; i++) {
		if (reg_table[i].superio_id == EOT)
			break;

		if ((uint16_t)reg_table[i].superio_id != id)
			continue;

		for (j = 0; /* Nothing */; j++) {
			if (reg_table[i].ldn[j].ldn == EOT)
				break;
			no_dump_available = 0;
			dump_regs(reg_table, i, j, port, ldn_sel);
		}

		if (no_dump_available)
			printf("No dump available for this Super I/O\n");
	}
}

void dump_io(uint16_t iobase, uint16_t length)
{
	uint16_t i;

	printf("Dumping %d I/O mapped registers at base 0x%04x:\n",
			length, iobase);
	for (i = 0; i < length; i++)
		printf("%02x ", i);
	printf("\n");
	for (i = 0; i < length; i++)
		printf("%02x ", INB(iobase + i));
	printf("\n");
}

void dump_data(uint16_t iobase, int bank)
{
	uint16_t i;

	printf("Bank %d:\n", bank);
	printf("    ");
	for (i = 0; i < 16; i++)
		printf("%02x ", i);
	set_bank(iobase, bank);
	for (i = 0; i < 256; i++) {
		if (i % 16 == 0)
			printf("\n%02x: ", i / 16);
		printf("%02x ", datareg(iobase, i));
	}
	printf("\n");
}

void probing_for(const char *vendor, const char *info, uint16_t port)
{
	if (!verbose)
		return;

	/* Yes, there's no space between '%s' and 'at'! */
	printf("Probing for %s Super I/O %sat 0x%x...\n", vendor, info, port);
}

/** Print a list of all supported chips from the given vendor. */
void print_vendor_chips(const char *vendor,
			const struct superio_registers reg_table[])
{
	int i;

	for (i = 0; reg_table[i].superio_id != EOT; i++) {
		printf("%s %s", vendor, reg_table[i].name);

		/* Unless the ldn is empty, assume this chip has a dump. */
		if (reg_table[i].ldn[0].ldn != EOT)
			printf(" (dump available)");

		printf("\n");
	}

	/* If we printed any chips for this vendor, put in a blank line. */
	if (i != 0)
		printf("\n");
}

/** Print a list of all chips supported by superiotool. */
void print_list_of_supported_chips(void)
{
	int i;

	printf("Supported Super I/O chips:\n\n");

	for (i = 0; i < ARRAY_SIZE(vendor_print_functions); i++)
		vendor_print_functions[i].print_list();

	printf("See <http://coreboot.org/Superiotool#Supported_devices> "
	       "for more information.\n");
}

static void print_version(void)
{
	printf("superiotool r%s\n", SUPERIOTOOL_VERSION);
}

int main(int argc, char *argv[])
{
	int i, j, opt, option_index;
#if defined(__FreeBSD__)
	int io_fd;
#endif

	static const struct option long_options[] = {
		{"dump",		no_argument, NULL, 'd'},
		{"extra-dump",		no_argument, NULL, 'e'},
		{"alternate-dump",	no_argument, NULL, 'a'},
		{"list-supported",	no_argument, NULL, 'l'},
		{"verbose",		no_argument, NULL, 'V'},
		{"version",		no_argument, NULL, 'v'},
		{"help",		no_argument, NULL, 'h'},
		{0, 0, 0, 0}
	};

	while ((opt = getopt_long(argc, argv, "dealVvh",
				  long_options, &option_index)) != EOF) {
		switch (opt) {
		case 'd':
			dump = 1;
			break;
		case 'e':
			extra_dump = 1;
			break;
		case 'a':
			alternate_dump = 1;
			break;
		case 'l':
			print_list_of_supported_chips();
			exit(0);
			break;
		case 'V':
			verbose = 1;
			break;
		case 'v':
			print_version();
			exit(0);
			break;
		case 'h':
			printf(USAGE);
			printf(USAGE_INFO);
			exit(0);
			break;
		default:
			/* Unknown option. */
			exit(1);
			break;
		}
	}

#if defined(__FreeBSD__)
	if ((io_fd = open("/dev/io", O_RDWR)) < 0) {
		perror("/dev/io");
#else
	if (iopl(3) < 0) {
		perror("iopl");
#endif
		printf("Superiotool must be run as root.\n");
		exit(1);
	}

	print_version();

#ifdef PCI_SUPPORT
	/* Do some basic libpci init. */
	pacc = pci_alloc();
	pci_init(pacc);
	pci_scan_bus(pacc);
#endif

	for (i = 0; i < ARRAY_SIZE(superio_ports_table); i++) {
		for (j = 0; superio_ports_table[i].ports[j] != EOT; j++)
			superio_ports_table[i].probe_idregs(
				superio_ports_table[i].ports[j]);
	}

	if (!chip_found)
		printf("No Super I/O found\n");

#if defined(__FreeBSD__)
	close(io_fd);
#endif
	return 0;
}
