1#! /usr/bin/env python
2"""
3Read oprofile events file, generate C data struct for Android opcontrol.
4
5Android does not use script for opcontrol, they use a C binary, which
6has embedded data structures with the event set that is supported.
7Initially that is just Arm V6 and V7.
8
9This tool allows us to convert various MIPS cpu event files for
10inclusion, and should work with other processor arch's as well.
11
12Neither Arm or Mips uses unit_masks, so that file is ignored.
13
14Event entries in file look like this:
15
16    event:0x1 counters:0,1 um:zero minimum:500 name:INSTRUCTIONS : Instructions completed
17
18The format is key:value. A single : appears at the end of line
19and the remaining text is the description
20"""
21
22import os, sys
23
24def number(s):
25    if s == 'zero':
26        return '0'
27    if s == 'one':
28        return '1'
29    if s[0] == 'x':
30        return '0'+s
31
32def parse_event(line,ovf):
33    ''' return dictionary of items from one line of event file '''
34    dict = {}
35    fields = line.split(None, 1)
36    while (fields):
37        first = fields[0].split(':', 1)
38        if first[0] == 'include':
39            ev(first[1] + "/events", ovf)
40            return None
41        line = fields[1]
42        if first[0] == 'um':
43            first[1] = number(first[1])
44        if first[0] == '':
45            dict['description'] = fields[1]
46            fields = None;
47        else:
48            dict[first[0]] = first[1]
49            fields = line.split(None, 1)
50    return dict
51
52def parse_ctr(s):
53    ''' convert comma separated list of integers x,y,... , to CTR(x) | CTR(y) | ... '''
54    if s == 'cpuid':
55        return 0
56    ctrs = s.split(',')
57    c = ''
58    for i in range(len(ctrs)-1):
59        c += ("CTR(%s) | " % ctrs[i])
60    c += ("CTR(%s)" % ctrs[-1])
61    return c
62
63def ev(fname,ovf):
64    ''' read file, parse, generate C data struct to file ovf '''
65    evf = open(fname, "r")
66    all_lines = evf.readlines()
67    lines = [s.strip() for s in all_lines if s.strip()]     # strip blanks
68    lines = [s for s in lines if not s.startswith('#')]     # strip comments
69    eventlist = [parse_event(line,ovf) for line in lines]
70
71    ovf.write("// events from file %s\n" % fname)
72    for d in eventlist:
73        if d!=None:
74            ovf.write('    {%s, %s, %s, "%s",\n' % (d['event'], parse_ctr(d['counters']), d['um'], d['name']))
75            ovf.write('     "%s"},\n' % d['description'])
76
77
78if __name__ == "__main__" :
79    if len(sys.argv) != 2:
80        fname = "events/mips/24K/events"    # convenient testing
81    else:
82        fname = sys.argv[1]
83    ovf = open(fname + ".h", "w")
84    ev(fname, ovf)
85