/**
 * @file arch/alpha/oprofile/common.c
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Richard Henderson <rth@twiddle.net>
 */

#include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <asm/ptrace.h>
#include <asm/system.h>

#include "op_impl.h"

extern struct op_axp_model op_model_ev4 __attribute__((weak));
extern struct op_axp_model op_model_ev5 __attribute__((weak));
extern struct op_axp_model op_model_pca56 __attribute__((weak));
extern struct op_axp_model op_model_ev6 __attribute__((weak));
extern struct op_axp_model op_model_ev67 __attribute__((weak));

static struct op_axp_model *model;

extern void (*perf_irq)(unsigned long, struct pt_regs *);
static void (*save_perf_irq)(unsigned long, struct pt_regs *);

static struct op_counter_config ctr[20];
static struct op_system_config sys;
static struct op_register_config reg;

/* Called from do_entInt to handle the performance monitor interrupt.  */

static void
op_handle_interrupt(unsigned long which, struct pt_regs *regs)
{
	model->handle_interrupt(which, regs, ctr);

	/* If the user has selected an interrupt frequency that is
	   not exactly the width of the counter, write a new value
	   into the counter such that it'll overflow after N more
	   events.  */
	if ((reg.need_reset >> which) & 1)
		model->reset_ctr(&reg, which);
}
 
static int
op_axp_setup(void)
{
	unsigned long i, e;

	/* Install our interrupt handler into the existing hook.  */
	save_perf_irq = perf_irq;
	perf_irq = op_handle_interrupt;

	/* Compute the mask of enabled counters.  */
	for (i = e = 0; i < model->num_counters; ++i)
		if (ctr[i].enabled)
			e |= 1 << i;
	reg.enable = e;

	/* Pre-compute the values to stuff in the hardware registers.  */
	model->reg_setup(&reg, ctr, &sys);

	/* Configure the registers on all cpus.  */
	(void)smp_call_function(model->cpu_setup, &reg, 1);
	model->cpu_setup(&reg);
	return 0;
}

static void
op_axp_shutdown(void)
{
	/* Remove our interrupt handler.  We may be removing this module.  */
	perf_irq = save_perf_irq;
}

static void
op_axp_cpu_start(void *dummy)
{
	wrperfmon(1, reg.enable);
}

static int
op_axp_start(void)
{
	(void)smp_call_function(op_axp_cpu_start, NULL, 1);
	op_axp_cpu_start(NULL);
	return 0;
}

static inline void
op_axp_cpu_stop(void *dummy)
{
	/* Disable performance monitoring for all counters.  */
	wrperfmon(0, -1);
}

static void
op_axp_stop(void)
{
	(void)smp_call_function(op_axp_cpu_stop, NULL, 1);
	op_axp_cpu_stop(NULL);
}

static int
op_axp_create_files(struct super_block *sb, struct dentry *root)
{
	int i;

	for (i = 0; i < model->num_counters; ++i) {
		struct dentry *dir;
		char buf[4];

		snprintf(buf, sizeof buf, "%d", i);
		dir = oprofilefs_mkdir(sb, root, buf);

		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
                oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
		/* Dummies.  */
		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
	}

	if (model->can_set_proc_mode) {
		oprofilefs_create_ulong(sb, root, "enable_pal",
					&sys.enable_pal);
		oprofilefs_create_ulong(sb, root, "enable_kernel",
					&sys.enable_kernel);
		oprofilefs_create_ulong(sb, root, "enable_user",
					&sys.enable_user);
	}

	return 0;
}

int __init
oprofile_arch_init(struct oprofile_operations *ops)
{
	struct op_axp_model *lmodel = NULL;

	switch (implver()) {
	case IMPLVER_EV4:
		lmodel = &op_model_ev4;
		break;
	case IMPLVER_EV5:
		/* 21164PC has a slightly different set of events.
		   Recognize the chip by the presence of the MAX insns.  */
		if (!amask(AMASK_MAX))
			lmodel = &op_model_pca56;
		else
			lmodel = &op_model_ev5;
		break;
	case IMPLVER_EV6:
		/* 21264A supports ProfileMe.
		   Recognize the chip by the presence of the CIX insns.  */
		if (!amask(AMASK_CIX))
			lmodel = &op_model_ev67;
		else
			lmodel = &op_model_ev6;
		break;
	}

	if (!lmodel)
		return -ENODEV;
	model = lmodel;

	ops->create_files = op_axp_create_files;
	ops->setup = op_axp_setup;
	ops->shutdown = op_axp_shutdown;
	ops->start = op_axp_start;
	ops->stop = op_axp_stop;
	ops->cpu_type = lmodel->cpu_type;

	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
	       lmodel->cpu_type);

	return 0;
}


void
oprofile_arch_exit(void)
{
}
