/* To get an executable first compile this C file then use something like
 xlf  -bI:/usr/lpp/PMkex/PMkex.exp pmutil.o yourfile.f or
 xlc -bI:/usr/lpp/PMkex/PMkex.exp pmutil.o yourfile.c

 Before running you code don't forget to load the kernel extension by
 typing /usr/lpp/PMkex/load_PMkex

 To start, stop, and clear the PM counters call ph_start(), ph_stop(),
 and ph_clear()

 pm_init() initializes PM: it reads MMCR and IMR registers from the
 file MMCR (in hex) but does not start the counters

 pm_read() reads the current values of the counters and prints them to
 the standard output in the following format:

mmcr = 40000000
cycles =        46868
scu =          10         762         183           0           0
icu =         109        7995       17352          10           0
fpu =       12019        8956       25108       20165       20165
fxu =       30005       29081         747          45           0
serror =            0

        */


#include <stdlib.h>
#include <stdio.h>
#include "/usr/lpp/PMkex/PMkex2.h"

void pm_init(void);
void pm_read(void);

void printcounts(pm2_data data);
void print5(unsigned int *data);

void pm_init() {
  unsigned int MMCR, IMR;
  FILE *fp;

  /* Read in MMCR and IMR from file MMCR */
  fp = fopen("MMCR","r");
  fscanf(fp,"%x%x",&MMCR,&IMR);
  fclose(fp);

  /* Initialize the monitor */
  ph_init(MMCR,IMR);
}


void pm_read(void) {
  pm2_data data;
  unsigned int MMCR, IMR;
  FILE *fp;

  /* Read in MMCR and IMR from file MMCR */
  fp = fopen("MMCR","r");
  fscanf(fp,"%x%x",&MMCR,&IMR);
  fclose(fp);

  ph_read(&data);

  data.mmcr = MMCR;
  printcounts(data);
}
  

void print5(unsigned int *data) {
  int i;
  for (i=0;i<5;i++)
    printf("%12u",data[i]);
  printf("\n");
}

void printcounts(pm2_data data) {
  printf("mmcr = %8x\n", data.mmcr);
  printf("cycles = %12u\n", data.cycles);
  printf("scu ="); print5(data.scu);  
  printf("icu ="); print5(data.icu);
  printf("fpu ="); print5(data.fpu);
  printf("fxu ="); print5(data.fxu);
  printf("serror = %12u\n",data.serrors);
}