<commit_before>/*	$OpenBSD: pctr.c,v 1.2 1996/08/08 21:37:31 dm Exp $	*/

/*
 * Pentium performance counter driver for OpenBSD.
 * Author: <NAME> <<EMAIL>>
 */

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/ioccom.h>

#include <machine/cputypes.h>
#include <machine/psl.h>
#include <machine/pctr.h>
#include <machine/cpu.h>

pctrval pctr_idlcnt;  /* Gets incremented in locore.s */
static int cpuid;

#define rdtsc()						\
({							\
  pctrval v;						\
  __asm __volatile (".byte 0xf, 0x31" : "=A" (v));	\
  v;							\
})

#define rdmsr(msr)						\
({								\
  pctrval v;							\
  __asm __volatile (".byte 0xf, 0x32" : "=A" (v) : "c" (msr));	\
  v;								\
})

#define wrmsr(msr, v) \
     __asm __volatile (".byte 0xf, 0x30" :: "A" (v), "c" (msr));

void
pctrattach (int num)
{
  if (num > 1)
    panic ("no more than one pctr device");
  
  __asm __volatile ("cli\n"
		    "\tpushfl\n"
		    "\tpopl %%eax\n"
		    "\tmovl %%eax,%%ecx\n"
		    "\txorl %1,%%eax\n"
		    "\tpushl %%eax\n"
		    "\tpopfl\n"
		    "\tpushfl\n"
		    "\tpopl %%eax\n"
		    "\tpushl %%ecx\n"
		    "\tpopfl\n"
		    "\tcmpl %%eax,%%ecx\n"
		    "\tmov $0,%0\n"
		    "\tje 1f\n"
		    "\tcpuid\n"
		    "1:\tsti"
		    : "=a" (cpuid) : "i" (PSL_ID) : "edx", "ecx", "ebx");
}

int
pctropen (dev_t dev, int oflags, int devtype, struct proc *p)
{
  if (minor (dev))
    return ENXIO;
  return 0;
}

int
pctrclose (dev_t dev, int oflags, int devtype, struct proc *p)
{
  return 0;
}

static int
pctrset (int fflag, int cmd, u_short fn)
{
  pctrval msr11;
  int msr;
  int shift;

  switch (cmd) {
  case PCIOCS0:
    msr = 0x12;
    shift = 0;
    break;
  case PCIOCS1:
    msr = 0x13;
    shift = 16;
    break;
  default:
    return EINVAL;
  }

  if (! (fflag & FWRITE))
    return EPERM;
  if (fn >= 0x200)
    return EINVAL;
  msr11 = rdmsr (0x11);
  msr11 &= ~(0x1ffLL << shift);
  msr11 |= fn << shift;
  wrmsr (0x11, msr11);
  wrmsr (msr, 0LL);

  return 0;
}

int
pctrioctl (dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
{

  if (minor (dev) || cpu_class < CPUCLASS_586)
    panic ("pctr: bad device %d should never have been opened.\n", dev);

  switch (cmd) {
  case PCIOCRD:<commit_msg>Allow idle loop to be read even on 486's.<commit_after>/*	$OpenBSD: pctr.c,v 1.3 1996/08/08 22:21:23 dm Exp $	*/

/*
 * Pentium performance counter driver for OpenBSD.
 * Author: <NAME> <<EMAIL>>
 */

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/ioccom.h>

#include <machine/cputypes.h>
#include <machine/psl.h>
#include <machine/pctr.h>
#include <machine/cpu.h>

pctrval pctr_idlcnt;  /* Gets incremented in locore.s */
static int cpuid;

#define rdtsc()						\
({							\
  pctrval v;						\
  __asm __volatile (".byte 0xf, 0x31" : "=A" (v));	\
  v;							\
})

#define rdmsr(msr)						\
({								\
  pctrval v;							\
  __asm __volatile (".byte 0xf, 0x32" : "=A" (v) : "c" (msr));	\
  v;								\
})

#define wrmsr(msr, v) \
     __asm __volatile (".byte 0xf, 0x30" :: "A" (v), "c" (msr));

void
pctrattach (int num)
{
  if (num > 1)
    panic ("no more than one pctr device");
  
  __asm __volatile ("cli\n"
		    "\tpushfl\n"
		    "\tpopl %%eax\n"
		    "\tmovl %%eax,%%ecx\n"
		    "\txorl %1,%%eax\n"
		    "\tpushl %%eax\n"
		    "\tpopfl\n"
		    "\tpushfl\n"
		    "\tpopl %%eax\n"
		    "\tpushl %%ecx\n"
		    "\tpopfl\n"
		    "\tcmpl %%eax,%%ecx\n"
		    "\tmov $0,%0\n"
		    "\tje 1f\n"
		    "\tcpuid\n"
		    "1:\tsti"
		    : "=a" (cpuid) : "i" (PSL_ID) : "edx", "ecx", "ebx");
}

int
pctropen (dev_t dev, int oflags, int devtype, struct proc *p)
{
  if (minor (dev))
    return ENXIO;
  return 0;
}

int
pctrclose (dev_t dev, int oflags, int devtype, struct proc *p)
{
  return 0;
}

static int
pctrset (int fflag, int cmd, u_short fn)
{
  pctrval msr11;
  int msr;
  int shift;

  switch (cmd) {
  case PCIOCS0:
    msr = 0x12;
    shift = 0;
    break;
  case PCIOCS1:
    msr = 0x13;
    shift = 16;
    break;
  default:
    return EINVAL;
  }

  if (! (fflag & FWRITE))
    return EPERM;
  if (fn >= 0x200)
    return EINVAL;
  msr11 = rdmsr (0x11);
  msr11 &= ~(0x1ffLL << shift);
  msr11 |= fn << shift;
  wrmsr (0x11, msr11);
  wrmsr (msr, 0LL);

  return 0;
}

int
pctrioctl (dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
{
  switch (cmd) {
  case PCIOCRD:
{'fraction_non_alphanumeric': 0.1793875685557587, 'fraction_numerical': 0.033820840950639856, 'mean_word_length': 2.346330275229358, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1962116', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2007, 'n_words': 497}