#ifndef PMC_DEV_H
#define PMC_DEV_H

/*----------------------------------------------------------------------------*/

/*
 * Performance-Monitoring Counters Library, for Intel/AMD Processors and Linux
 * Author:  Don Heller, dheller@scl.ameslab.gov
 * Last revised:  5 October 2001
 */

/*----------------------------------------------------------------------------*/

	/* device driver for /dev/pmc */

/*----------------------------------------------------------------------------*/

#include <pmc_arch.h>

/*----------------------------------------------------------------------------*/

/*
 * minor device number for /dev/pmc
 *
 *   The major device number is 10 (non-serial mice, misc features).
 *
 *   The minor device number should be in the range 240-255, which is
 *	reserved for local use.  240 is the default if PMC_MINOR is not
 *	given.  Be sure to coordinate this value with the Makefile.
 *
 *	See /usr/src/linux/Documentation/devices.txt for a proper minor
 *	device number.  The exact location of this file depends on your
 *	Linux distribution and installation.  For the current version, see
 *	http://www.kernel.org/pub/linux/docs/device-list/devices.txt
 *	or http://www.lanana.org/
 */

#ifndef PMC_MINOR
#define PMC_MINOR 240
#endif

/*----------------------------------------------------------------------------*/

/*
 * Intel IA-32 processor control registers
 *   CR0 = system control flags for operating mode and states of the processor
 *   CR1 = reserved (does not really exist, do not try to access it)
 *   CR2 = page-fault linear address (the address that caused the page fault)
 *   CR3 = base address of page directory, or
 *         (with physical address extension) of page directory pointer table
 *   CR4 = system control flags for architectural extensions
 *
 * These should be readable at any CPL, but writeable only at CPL 0.  Do not
 * change the reserved bits; they read as 0.  Note that some bits are always
 * set.
 *
 * Reference:
 * Intel Corp., Intel Architecture Software Developer's Manual,
 *   vol. 3, System Programming Guide, 1997, order no. 243192.
 */

/*----------------------------------------------------------------------------*/

/*
 *				operations allowed
 *	register		read	write	write particular bits
 *	CR0			x	-	x
 *	CR1			-	-	-
 *	CR2			x	-	-
 *	CR3			x	-	-
 *	CR4			x	-	x
 *	TSC			x	-	-
 *	PMC_[0123]		x	x	-
 *	PMC_CONTROL_[0123]	x	x	-
 */

/*----------------------------------------------------------------------------*/

/* for use with pmc_device_read() */

/* used by pmc_read() in pmc_lib.c, obtains 8 bytes per counter */
#define PMC_READ		(8*(1 + pmc_event_counters))

/* used by pmc_open() in pmc_lib.c, obtains 8 bytes per counter */
#define PMC_READ_CONTROL	(PMC_READ + 1)

/* for control registers, obtains 4 bytes */
#define PMC_READ_CR0		(PMC_READ_CONTROL + 1)
#define PMC_READ_CR2		(PMC_READ_CONTROL + 2)
#define PMC_READ_CR3		(PMC_READ_CONTROL + 3)
#define PMC_READ_CR4		(PMC_READ_CONTROL + 4)

/* for model-specific registers, obtains 8 bytes */
#define PMC_READ_TSC		(PMC_READ_CONTROL + 5)
#define PMC_READ_CONTROL_0	(PMC_READ_CONTROL + 6)
#define PMC_READ_CONTROL_1	(PMC_READ_CONTROL + 7)
#define PMC_READ_CONTROL_2	(PMC_READ_CONTROL + 8)
#define PMC_READ_CONTROL_3	(PMC_READ_CONTROL + 9)
#define PMC_READ_0		(PMC_READ_CONTROL + 10)
#define PMC_READ_1		(PMC_READ_CONTROL + 11)
#define PMC_READ_2		(PMC_READ_CONTROL + 12)
#define PMC_READ_3		(PMC_READ_CONTROL + 13)
#if defined(PMC_P6) || defined(PMC_P15)
#define PMC_READ_APICBASE	(PMC_READ_CONTROL + 14)
#define PMC_READ_BUS_FREQUENCY	(PMC_READ_CONTROL + 15)
#define PMC_READ_MISC_ENABLE	(PMC_READ_CONTROL + 16)
#endif	/* PMC_P6 */

#if defined(PMC_P6)
/* for local APIC register address space, up to 4096 bytes */
#define PMC_READ_APIC_SPACE	4096
#endif	/* PMC_P6 */

#if defined(PMC_P15)
/* begin unfinished */
#define PMC_READ_P15_COUNTERS	8192
#define PMC_READ_P15_CCCRS	8193
#define PMC_READ_P15_ESCRS	8194
/* end unfinished */
#endif	/* PMC_P15 */

/*----------------------------------------------------------------------------*/

/* for use with pmc_device_write()
 *
 * Note - write() will not invoke pmc_device_write() for 0 bytes,
 * so do not use 0 for any of these request codes.
 */

/* used by pmc_select() and pmc_reset() in pmc_lib.c,
 * delivers 4 bytes per event counter
 */
#define PMC_SELECT		(4*pmc_event_counters)

/* used by pmc_close() in pmc_lib.c, delivers 8 bytes per counter */
#define PMC_WRITE_CONTROL	(8*(1 + pmc_event_counters))

/* for model-specific registers, delivers 8 bytes */
/* PMC_WRITE_TSC is dangerous -- do not use it */
#define PMC_WRITE_TSC		(PMC_WRITE_CONTROL + 1)
#define PMC_WRITE_CONTROL_0	(PMC_WRITE_CONTROL + 2)
#define PMC_WRITE_CONTROL_1	(PMC_WRITE_CONTROL + 3)
#define PMC_WRITE_CONTROL_2	(PMC_WRITE_CONTROL + 4)
#define PMC_WRITE_CONTROL_3	(PMC_WRITE_CONTROL + 5)
#define PMC_WRITE_0		(PMC_WRITE_CONTROL + 6)
#define PMC_WRITE_1		(PMC_WRITE_CONTROL + 7)
#define PMC_WRITE_2		(PMC_WRITE_CONTROL + 8)
#define PMC_WRITE_3		(PMC_WRITE_CONTROL + 9)

#if defined(PMC_P15)
/* begin unfinished */
#define PMC_WRITE_P15_COUNTERS	8192
#define PMC_WRITE_P15_CCCRS	8193
#define PMC_WRITE_P15_ESCRS	8194
/* end unfinished */
#endif	/* PMC_P15 */

/*----------------------------------------------------------------------------*/

/* for use with pmc_device_seek() */

/* how was the code compiled? */
#define PMC_DEVICE_HARDWARE_TYPE		0
#define PMC_DEVICE_SOFTWARE_VERSION		1
#define PMC_DEVICE_SOFTWARE_VERSION_SMP		2
#define PMC_DEVICE_SOFTWARE_VERSION_KERNEL	3

/* support for pmc_configure() in pmc_lib.c */
#define PMC_FLUSH_CACHE				4
#define PMC_DISABLE_CACHE			5
#define PMC_ENABLE_CACHE			6
#define PMC_QUERY_CACHE				7

#define PMC_DISABLE_RDTSC			8
#define PMC_ENABLE_RDTSC			9
#define PMC_QUERY_RDTSC				10

#define PMC_DISABLE_RDPMC			11
#define PMC_ENABLE_RDPMC			12
#define PMC_QUERY_RDPMC				13

#define PMC_DISABLE_ALIGNMENT_CHECKING		14
#define PMC_ENABLE_ALIGNMENT_CHECKING		15
#define PMC_QUERY_ALIGNMENT_CHECKING		16

/* support for pmc_test.c */
#ifdef PMC_ALLOW_SYSTEM_TEST
#define PMC_TEST_OVERHEAD			17
#define PMC_TEST_CPUID				18
#define PMC_TEST_RDTSC				19
#define PMC_TEST_RDPMC_0			20
#define PMC_TEST_RDPMC_1			21
#define PMC_TEST_RDPMC_2			22
#define PMC_TEST_RDPMC_3			23
#define PMC_TEST_RDPMC_ALL			24
#define PMC_TEST_RDMSR_TSC			25
#define PMC_TEST_RDMSR_0			26
#define PMC_TEST_RDMSR_1			27
#define PMC_TEST_RDMSR_2			28
#define PMC_TEST_RDMSR_3			29
#define PMC_TEST_RDMSR_ALL			30
#define PMC_TEST_RDMSR_CONTROL_0		31
#define PMC_TEST_RDMSR_CONTROL_1		32
#define PMC_TEST_RDMSR_CONTROL_2		33
#define PMC_TEST_RDMSR_CONTROL_3		34
#define PMC_TEST_RDMSR_CONTROL_ALL		35
#define PMC_TEST_RDWRMSR_CONTROL_0		36
#define PMC_TEST_RDWRMSR_CONTROL_1		37
#define PMC_TEST_RDWRMSR_CONTROL_2		38
#define PMC_TEST_RDWRMSR_CONTROL_3		39
#define PMC_TEST_RDWRMSR_CONTROL_ALL		40
#define PMC_TEST_STORE_AND_RELOAD		41
#endif	/* PMC_ALLOW_SYSTEM_TEST */

/*----------------------------------------------------------------------------*/

#endif	/* PMC_DEV_H */
