summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/include/pctr.h
blob: 427bcb52ee04115a6802d18015d14026a99b0d3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*	$OpenBSD: pctr.h,v 1.3 2007/10/24 17:56:57 mikeb Exp $	*/

/*
 * Pentium performance counter driver for OpenBSD.
 * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
 *
 * Modification and redistribution in source and binary forms is
 * permitted provided that due credit is given to the author and the
 * OpenBSD project by leaving this copyright notice intact.
 */

#ifndef _AMD64_PCTR_H_
#define _AMD64_PCTR_H_

#include <sys/ioccom.h>

typedef u_int64_t	pctrval;

#define PCTR_NUM	4

struct pctrst {
	u_int pctr_fn[PCTR_NUM];	/* Current settings of counters */
	pctrval pctr_tsc;		/* Free-running 64-bit cycle counter */
	pctrval	pctr_hwc[PCTR_NUM];	/* Values of the hardware counters */
};

/* Bit values in fn fields and PIOCS ioctl's */
#define PCTR_U		0x010000	/* Monitor user-level events */
#define PCTR_K		0x020000	/* Monitor kernel-level events */
#define PCTR_E		0x040000	/* Edge detect */
#define PCTR_EN		0x400000	/* Enable counters (counter 0 only) */
#define PCTR_I		0x800000	/* Invert counter mask */

/* Unit Mask values to distinguish cache coherent states */
#define PCTR_UM_M	0x0800		/* Modified cache lines */
#define PCTR_UM_E	0x0400		/* Exclusive cache lines */
#define PCTR_UM_S	0x0200		/* Shared cache lines */
#define PCTR_UM_I	0x0100		/* Invalid cache lines */
#define PCTR_UM_MESI	(PCTR_UM_M|PCTR_UM_E|PCTR_UM_S|PCTR_UM_I)
#define PCTR_UM_A	0x2000		/* Any initiator */

#define PCTR_UM_SHIFT	8		/* Left shift for unit mask */
#define PCTR_CM_SHIFT	24		/* Left shift for counter mask */

/* ioctl to set which counter a device tracks */
#define PCIOCRD	_IOR('c', 1,  struct pctrst)	/* Read counter value */
#define PCIOCS0	_IOW('c', 8,  unsigned int)	/* Set counter 0 function */
#define PCIOCS1 _IOW('c', 9,  unsigned int)	/* Set counter 1 function */
#define PCIOCS2 _IOW('c', 10, unsigned int)	/* Set counter 2 function */
#define PCIOCS3 _IOW('c', 11, unsigned int)	/* Set counter 3 function */

#define _PATH_PCTR	"/dev/pctr"

#define rdtsc()							\
({								\
	u_int32_t hi, lo;					\
	__asm __volatile("rdtsc" : "=d" (hi), "=a" (lo));	\
	((u_int64_t)hi << 32) | (u_int64_t)lo;			\
})

#define rdpmc(pmc)						\
({								\
	u_int32_t hi, lo;					\
	__asm __volatile("rdpmc"				\
	    : "=d" (hi), "=a" (lo) : "c" (pmc));		\
	hi &= 0xffffff;						\
	(((u_int64_t)hi << 32) | (u_int64_t)lo);		\
})

#ifdef _KERNEL

#define rdmsr(msr)						\
({								\
	u_int32_t hi, lo;					\
	__asm __volatile("rdmsr"				\
	     : "=d" (hi), "=a" (lo) : "c" (msr));		\
	((u_int64_t)hi << 32) | (u_int64_t) lo;			\
})

#define wrmsr(msr, v)						\
({								\
	__asm __volatile("wrmsr" :				\
	    : "a" ((u_int64_t)v & 0xffffffff),			\
	      "d" ((u_int64_t)v >> 32), "c" (msr));		\
})

void	pctrattach(int);
int	pctropen(dev_t, int, int, struct proc *);
int	pctrclose(dev_t, int, int, struct proc *);
int	pctrioctl(dev_t, u_long, caddr_t, int, struct proc *);

#endif /* _KERNEL */
#endif /* ! _AMD64_PCTR_H_ */