aboutsummaryrefslogtreecommitdiffstats
path: root/samples/xilinx_apm/main.c
blob: 2a7eda4ab256c7d88dcbc4fc04d0447230c1a2d4 (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Xilinx AXI Performance Monitor Example
 *
 * Copyright (c) 2013 Xilinx Inc.
 *
 * The code may be used by anyone for any purpose and can serve as a
 * starting point for developing applications using Xilinx AXI
 * Performance Monitor.
 *
 * This example based on Xilinx AXI Performance Monitor UIO driver shows
 * sequence to read metrics from Xilinx AXI Performance Monitor IP.
 * User need to provide the uio device file with option -d:
 * main -d /dev/uio0, say /dev/uio0 as device file for AXI Performance
 * Monitor driver. User need not clear Interrupt Status Register after
 * waiting for interrupt on read since driver clears it.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdint.h>
#include "xaxipmon.h"

#define MAP_SIZE 4096

void usage(void)
{
	printf("*argv[0] -d <UIO_DEV_FILE> -i|-o <VALUE>\n");
	printf(" -d UIO device file. e.g. /dev/uio0\n");
	return;
}

static void start(int fd)
{
	u8 slot = 2;
	int tmp;
	u32 isr;

	setmetrics(slot, XAPM_METRIC_SET_4, XAPM_METRIC_COUNTER_0);
	setsampleinterval(0x3FFFFFF);

	loadsic();

	intrenable(XAPM_IXR_SIC_OVERFLOW_MASK);

	intrglobalenable();

	enablemetricscounter();

	enablesic();

	isr = intrgetstatus();
	/* Wait for SIC overflow interrupt */
	if (read(fd, &tmp, 4) < 0)
		perror("Read\n");
	/* Driver clears the interrupt and occured interrupt status is
		stored in param->isr */
	isr = intrgetstatus();
	if (isr & XAPM_IXR_SIC_OVERFLOW_MASK)
		disablesic();

	disablemetricscounter();

	intrdisable(XAPM_IXR_SIC_OVERFLOW_MASK);

	intrglobaldisable();

	printf("Required metrics: %u\n",
		getsampledmetriccounter(XAPM_METRIC_COUNTER_0) *
		params->scalefactor);
}

int main(int argc, char *argv[])
{
	int c;
	char *uiod;
	int fd;

	while ((c = getopt(argc, argv, "d:h")) != -1) {
		switch (c) {
		case 'd':
			uiod = optarg;
			break;
		case 'h':
			usage();
			return 0;
		default:
			printf("invalid option: %c\n", (char)c);
			usage();
			return -1;
		}
	}

	/* Open the UIO device file */
	fd = open(uiod, O_RDWR);
	if (fd < 1) {
		perror(argv[0]);
		printf("Invalid UIO device file:%s.\n", uiod);
		usage();
		return -1;
	}

	baseaddr = (ulong)mmap(0, MAP_SIZE , PROT_READ|PROT_WRITE,
				MAP_SHARED , fd, 0);
	if ((u32 *)baseaddr == MAP_FAILED)
		perror("mmap failed\n");

	/* mmap the UIO device */
	params = (struct xapm_param *)mmap(0, MAP_SIZE , PROT_READ|PROT_WRITE,
				MAP_SHARED , fd, getpagesize());
	if (params == MAP_FAILED)
		perror("mmap failed\n");

	if (params->mode == 1)
		printf("AXI PMON is in Advanced Mode\n");
	else if (params->mode == 2)
		printf("AXI PMON is in Profile Mode\n");
	else
		printf("AXI PMON is in trace Mode\n");

	start(fd);

	close(fd);
	munmap((u32 *)baseaddr, MAP_SIZE);
	munmap(params, MAP_SIZE);

	return 0;
}