/*
 *  linux/arch/mips/kernel/proc.c
 *
 *  Copyright (C) 1995, 1996, 2001  Ralf Baechle
 *  Copyright (C) 2001, 2004  MIPS Technologies, Inc.
 *  Copyright (C) 2004  Maciej W. Rozycki
 */
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>

unsigned int vced_count, vcei_count;

static const char *cpu_name[] = {
	[CPU_UNKNOWN]	= "unknown",
	[CPU_R2000]	= "R2000",
	[CPU_R3000]	= "R3000",
	[CPU_R3000A]	= "R3000A",
	[CPU_R3041]	= "R3041",
	[CPU_R3051]	= "R3051",
	[CPU_R3052]	= "R3052",
	[CPU_R3081]	= "R3081",
	[CPU_R3081E]	= "R3081E",
	[CPU_R4000PC]	= "R4000PC",
	[CPU_R4000SC]	= "R4000SC",
	[CPU_R4000MC]	= "R4000MC",
	[CPU_R4200]	= "R4200",
	[CPU_R4400PC]	= "R4400PC",
	[CPU_R4400SC]	= "R4400SC",
	[CPU_R4400MC]	= "R4400MC",
	[CPU_R4600]	= "R4600",
	[CPU_R6000]	= "R6000",
	[CPU_R6000A]	= "R6000A",
	[CPU_R8000]	= "R8000",
	[CPU_R10000]	= "R10000",
	[CPU_R12000]	= "R12000",
	[CPU_R14000]	= "R14000",
	[CPU_R4300]	= "R4300",
	[CPU_R4650]	= "R4650",
	[CPU_R4700]	= "R4700",
	[CPU_R5000]	= "R5000",
	[CPU_R5000A]	= "R5000A",
	[CPU_R4640]	= "R4640",
	[CPU_NEVADA]	= "Nevada",
	[CPU_RM7000]	= "RM7000",
	[CPU_RM9000]	= "RM9000",
	[CPU_R5432]	= "R5432",
	[CPU_4KC]	= "MIPS 4Kc",
	[CPU_5KC]	= "MIPS 5Kc",
	[CPU_R4310]	= "R4310",
	[CPU_SB1]	= "SiByte SB1",
	[CPU_SB1A]	= "SiByte SB1A",
	[CPU_TX3912]	= "TX3912",
	[CPU_TX3922]	= "TX3922",
	[CPU_TX3927]	= "TX3927",
	[CPU_AU1000]	= "Au1000",
	[CPU_AU1500]	= "Au1500",
	[CPU_AU1100]	= "Au1100",
	[CPU_AU1550]	= "Au1550",
	[CPU_AU1200]	= "Au1200",
	[CPU_4KEC]	= "MIPS 4KEc",
	[CPU_4KSC]	= "MIPS 4KSc",
	[CPU_VR41XX]	= "NEC Vr41xx",
	[CPU_R5500]	= "R5500",
	[CPU_TX49XX]	= "TX49xx",
	[CPU_20KC]	= "MIPS 20Kc",
	[CPU_24K]	= "MIPS 24K",
	[CPU_25KF]	= "MIPS 25Kf",
	[CPU_34K]	= "MIPS 34K",
	[CPU_74K]	= "MIPS 74K",
	[CPU_VR4111]	= "NEC VR4111",
	[CPU_VR4121]	= "NEC VR4121",
	[CPU_VR4122]	= "NEC VR4122",
	[CPU_VR4131]	= "NEC VR4131",
	[CPU_VR4133]	= "NEC VR4133",
	[CPU_VR4181]	= "NEC VR4181",
	[CPU_VR4181A]	= "NEC VR4181A",
	[CPU_SR71000]	= "Sandcraft SR71000",
	[CPU_PR4450]	= "Philips PR4450",
	[CPU_LOONGSON2]	= "ICT Loongson-2",
};


static int show_cpuinfo(struct seq_file *m, void *v)
{
	unsigned long n = (unsigned long) v - 1;
	unsigned int version = cpu_data[n].processor_id;
	unsigned int fp_vers = cpu_data[n].fpu_id;
	char fmt [64];

#ifdef CONFIG_SMP
	if (!cpu_isset(n, cpu_online_map))
		return 0;
#endif

	/*
	 * For the first processor also print the system type
	 */
	if (n == 0)
		seq_printf(m, "system type\t\t: %s\n", get_system_type());

	seq_printf(m, "processor\t\t: %ld\n", n);
	sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
	        cpu_data[n].options & MIPS_CPU_FPU ? "  FPU V%d.%d" : "");
	seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ?
	                            cpu_data[n].cputype : CPU_UNKNOWN],
	                           (version >> 4) & 0x0f, version & 0x0f,
	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
	              cpu_data[n].udelay_val / (500000/HZ),
	              (cpu_data[n].udelay_val / (5000/HZ)) % 100);
	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
	seq_printf(m, "microsecond timers\t: %s\n",
	              cpu_has_counter ? "yes" : "no");
	seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
	seq_printf(m, "extra interrupt vector\t: %s\n",
	              cpu_has_divec ? "yes" : "no");
	seq_printf(m, "hardware watchpoint\t: %s\n",
	              cpu_has_watch ? "yes" : "no");
	seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
		      cpu_has_mips16 ? " mips16" : "",
		      cpu_has_mdmx ? " mdmx" : "",
		      cpu_has_mips3d ? " mips3d" : "",
		      cpu_has_smartmips ? " smartmips" : "",
		      cpu_has_dsp ? " dsp" : "",
		      cpu_has_mipsmt ? " mt" : ""
		);

	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
	        cpu_has_vce ? "%u" : "not available");
	seq_printf(m, fmt, 'D', vced_count);
	seq_printf(m, fmt, 'I', vcei_count);
	seq_printf(m, "\n");

	return 0;
}

static void *c_start(struct seq_file *m, loff_t *pos)
{
	unsigned long i = *pos;

	return i < NR_CPUS ? (void *) (i + 1) : NULL;
}

static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
	++*pos;
	return c_start(m, pos);
}

static void c_stop(struct seq_file *m, void *v)
{
}

struct seq_operations cpuinfo_op = {
	.start	= c_start,
	.next	= c_next,
	.stop	= c_stop,
	.show	= show_cpuinfo,
};
