1/**
2 * @file op_xml_events.c
3 * routines for generating event files in XML
4 *
5 * @remark Copyright 2008 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Dave Nomura
9 */
10
11#include <stdio.h>
12#include <string.h>
13#include "op_events.h"
14#include "op_list.h"
15#include "op_cpu_type.h"
16#include "op_xml_out.h"
17
18static op_cpu cpu_type;
19#define MAX_BUFFER 16384
20static char buffer[MAX_BUFFER];
21
22void open_xml_events(char const * title, char const * doc, op_cpu the_cpu_type)
23{
24	char const * schema_version = "1.1";
25
26	buffer[0] = '\0';
27	cpu_type = the_cpu_type;
28	open_xml_element(HELP_EVENTS, 1, buffer, MAX_BUFFER);
29	init_xml_str_attr(SCHEMA_VERSION, schema_version, buffer, MAX_BUFFER);
30	close_xml_element(NONE, 1, buffer, MAX_BUFFER);
31	open_xml_element(HELP_HEADER, 1, buffer, MAX_BUFFER);
32	init_xml_str_attr(HELP_TITLE, title, buffer, MAX_BUFFER);
33	init_xml_str_attr(HELP_DOC, doc, buffer, MAX_BUFFER);
34	close_xml_element(NONE, 0, buffer, MAX_BUFFER);
35	printf("%s", buffer);
36}
37
38void close_xml_events(void)
39{
40	buffer[0] = '\0';
41	close_xml_element(HELP_EVENTS, 0, buffer, MAX_BUFFER);
42	printf("%s", buffer);
43}
44
45static void xml_do_arch_specific_event_help(struct op_event const *event,
46					    char *buffer, size_t size)
47{
48	switch (cpu_type) {
49	case CPU_PPC64_CELL:
50		init_xml_int_attr(HELP_EVENT_GROUP, event->val / 100, buffer,
51				  size);
52		break;
53	default:
54		break;
55	}
56}
57
58
59void xml_help_for_event(struct op_event const * event)
60{
61	uint i;
62	int nr_counters;
63	int has_nested = strcmp(event->unit->name, "zero");
64
65	buffer[0] = '\0';
66	open_xml_element(HELP_EVENT, 1, buffer, MAX_BUFFER);
67	init_xml_str_attr(HELP_EVENT_NAME, event->name, buffer, MAX_BUFFER);
68	xml_do_arch_specific_event_help(event, buffer, MAX_BUFFER);
69	init_xml_str_attr(HELP_EVENT_DESC, event->desc, buffer, MAX_BUFFER);
70
71	nr_counters = op_get_nr_counters(cpu_type);
72	init_xml_int_attr(HELP_COUNTER_MASK, event->counter_mask, buffer,
73			  MAX_BUFFER);
74	if (event->ext)
75		init_xml_str_attr(HELP_EXT, event->ext, buffer, MAX_BUFFER);
76	init_xml_int_attr(HELP_MIN_COUNT, event->min_count,
77			  buffer, MAX_BUFFER);
78
79	if (has_nested) {
80		char um_type[10];
81		close_xml_element(NONE, 1, buffer, MAX_BUFFER);
82		open_xml_element(HELP_UNIT_MASKS, 1, buffer, MAX_BUFFER);
83		init_xml_int_attr(HELP_DEFAULT_MASK, event->unit->default_mask,
84				  buffer, MAX_BUFFER);
85		switch (event->unit->unit_type_mask){
86		case utm_bitmask:
87			strncpy(um_type, "bitmask", sizeof(um_type));
88			break;
89		case utm_exclusive:
90			strncpy(um_type, "exclusive", sizeof(um_type));
91			break;
92		case utm_mandatory:
93			strncpy(um_type, "mandatory", sizeof(um_type));
94			break;
95		}
96		init_xml_str_attr(HELP_UNIT_MASKS_CATEGORY, um_type, buffer, MAX_BUFFER);
97		close_xml_element(NONE, 1, buffer, MAX_BUFFER);
98		for (i = 0; i < event->unit->num; i++) {
99			open_xml_element(HELP_UNIT_MASK, 1, buffer, MAX_BUFFER);
100			init_xml_int_attr(HELP_UNIT_MASK_VALUE,
101					  event->unit->um[i].value,
102					  buffer, MAX_BUFFER);
103			init_xml_str_attr(HELP_UNIT_MASK_DESC,
104					  event->unit->um[i].desc,
105					  buffer, MAX_BUFFER);
106			close_xml_element(NONE, 0, buffer, MAX_BUFFER);
107		}
108		close_xml_element(HELP_UNIT_MASKS, 0, buffer, MAX_BUFFER);
109	}
110	close_xml_element(has_nested ? HELP_EVENT : NONE, has_nested,
111			  buffer, MAX_BUFFER);
112	printf("%s", buffer);
113}
114
115