/*
 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include <errno.h>
#include <signal.h>
#include <string.h>
#include "kern_constants.h"
#include "os.h"
#include "task.h"
#include "user.h"

#define MAXTOKEN 64

/* Set during early boot */
int host_has_cmov = 1;
int host_has_xmm = 0;

static char token(int fd, char *buf, int len, char stop)
{
	int n;
	char *ptr, *end, c;

	ptr = buf;
	end = &buf[len];
	do {
		n = os_read_file(fd, ptr, sizeof(*ptr));
		c = *ptr++;
		if (n != sizeof(*ptr)) {
			if (n == 0)
				return 0;
			printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
			       "err = %d\n", -n);
			if (n < 0)
				return n;
			else return -EIO;
		}
	} while ((c != '\n') && (c != stop) && (ptr < end));

	if (ptr == end) {
		printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
		       stop);
		return -1;
	}
	*(ptr - 1) = '\0';
	return c;
}

static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
{
	int n;
	char c;

	scratch[len - 1] = '\0';
	while (1) {
		c = token(fd, scratch, len - 1, ':');
		if (c <= 0)
			return 0;
		else if (c != ':') {
			printk(UM_KERN_ERR "Failed to find ':' in "
			       "/proc/cpuinfo\n");
			return 0;
		}

		if (!strncmp(scratch, key, strlen(key)))
			return 1;

		do {
			n = os_read_file(fd, &c, sizeof(c));
			if (n != sizeof(c)) {
				printk(UM_KERN_ERR "Failed to find newline in "
				       "/proc/cpuinfo, err = %d\n", -n);
				return 0;
			}
		} while (c != '\n');
	}
	return 0;
}

static int check_cpu_flag(char *feature, int *have_it)
{
	char buf[MAXTOKEN], c;
	int fd, len = ARRAY_SIZE(buf);

	printk(UM_KERN_INFO "Checking for host processor %s support...",
	       feature);
	fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
	if (fd < 0) {
		printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
		       -fd);
		return 0;
	}

	*have_it = 0;
	if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
		goto out;

	c = token(fd, buf, len - 1, ' ');
	if (c < 0)
		goto out;
	else if (c != ' ') {
		printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
		goto out;
	}

	while (1) {
		c = token(fd, buf, len - 1, ' ');
		if (c < 0)
			goto out;
		else if (c == '\n')
			break;

		if (!strcmp(buf, feature)) {
			*have_it = 1;
			goto out;
		}
	}
 out:
	if (*have_it == 0)
		printk("No\n");
	else if (*have_it == 1)
		printk("Yes\n");
	os_close_file(fd);
	return 1;
}

#if 0 /*
       * This doesn't work in tt mode, plus it's causing compilation problems
       * for some people.
       */
static void disable_lcall(void)
{
	struct modify_ldt_ldt_s ldt;
	int err;

	bzero(&ldt, sizeof(ldt));
	ldt.entry_number = 7;
	ldt.base_addr = 0;
	ldt.limit = 0;
	err = modify_ldt(1, &ldt, sizeof(ldt));
	if (err)
		printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
		       errno);
}
#endif

void arch_init_thread(void)
{
#if 0
	disable_lcall();
#endif
}

void arch_check_bugs(void)
{
	int have_it;

	if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
		printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
		       "capability checks\n");
		return;
	}
	if (check_cpu_flag("cmov", &have_it))
		host_has_cmov = have_it;
	if (check_cpu_flag("xmm", &have_it))
		host_has_xmm = have_it;
}

int arch_handle_signal(int sig, struct uml_pt_regs *regs)
{
	unsigned char tmp[2];

	/*
	 * This is testing for a cmov (0x0f 0x4x) instruction causing a
	 * SIGILL in init.
	 */
	if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
		return 0;

	if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
		panic("SIGILL in init, could not read instructions!\n");
	if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
		return 0;

	if (host_has_cmov == 0)
		panic("SIGILL caused by cmov, which this processor doesn't "
		      "implement, boot a filesystem compiled for older "
		      "processors");
	else if (host_has_cmov == 1)
		panic("SIGILL caused by cmov, which this processor claims to "
		      "implement");
	else if (host_has_cmov == -1)
		panic("SIGILL caused by cmov, couldn't tell if this processor "
		      "implements it, boot a filesystem compiled for older "
		      "processors");
	else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
	return 0;
}
