Home | History | Annotate | Download | only in utils
      1 /**
      2  * @file ophelp.c
      3  * Print out PMC event information
      4  *
      5  * @remark Copyright 2002 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author John Levon
      9  * @author Philippe Elie
     10  */
     11 
     12 #define _GNU_SOURCE
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <limits.h>
     17 
     18 #include "op_version.h"
     19 #include "op_events.h"
     20 #include "op_popt.h"
     21 #include "op_cpufreq.h"
     22 #include "op_hw_config.h"
     23 #include "op_string.h"
     24 #include "op_alloc_counter.h"
     25 #include "op_parse_event.h"
     26 #include "op_libiberty.h"
     27 #include "op_xml_events.h"
     28 
     29 static char const ** chosen_events;
     30 static int num_chosen_events;
     31 struct parsed_event * parsed_events;
     32 static op_cpu cpu_type = CPU_NO_GOOD;
     33 static char * cpu_string;
     34 static int callgraph_depth;
     35 static int want_xml;
     36 
     37 static poptContext optcon;
     38 
     39 
     40 /// return the Hamming weight (number of set bits)
     41 static size_t hweight(size_t mask)
     42 {
     43 	size_t count = 0;
     44 
     45 	while (mask) {
     46 		mask &= mask - 1;
     47 		count++;
     48 	}
     49 
     50 	return count;
     51 }
     52 
     53 static void do_arch_specific_event_help(struct op_event * event)
     54 {
     55 	switch (cpu_type) {
     56 	case CPU_PPC64_CELL:
     57 		printf("Group %u :", event->val / 100);
     58 		break;
     59 	default:
     60 		break;
     61 	}
     62 }
     63 
     64 #define LINE_LEN 99
     65 
     66 static void word_wrap(int indent, int *column, char *msg)
     67 {
     68 	while (*msg) {
     69 		int wlen = strcspn(msg, " ");
     70 		if (*column + wlen > LINE_LEN) {
     71 			printf("\n%*s", indent, "");
     72 			*column = indent;
     73 		}
     74 		printf("%.*s ", wlen, msg);
     75 		*column += wlen + 1;
     76 		msg += wlen;
     77 		msg += strspn(msg, " ");
     78 	}
     79 }
     80 
     81 /**
     82  * help_for_event - output event name and description
     83  * @param i  event number
     84  *
     85  * output an help string for the event @i
     86  */
     87 static void help_for_event(struct op_event * event)
     88 {
     89 	int column;
     90 	uint i, j;
     91 	uint mask;
     92 	size_t nr_counters;
     93 	char buf[32];
     94 
     95 	do_arch_specific_event_help(event);
     96 	nr_counters = op_get_nr_counters(cpu_type);
     97 
     98 	/* Sanity check */
     99 	if (!event)
    100 		return;
    101 
    102 	printf("%s", event->name);
    103 
    104 	if(event->counter_mask != 0) {
    105 		printf(": (counter: ");
    106 
    107 		mask = event->counter_mask;
    108 		if (hweight(mask) == nr_counters) {
    109 			printf("all");
    110 		} else {
    111 			for (i = 0; i < CHAR_BIT * sizeof(event->counter_mask); ++i) {
    112 				if (mask & (1 << i)) {
    113 					printf("%d", i);
    114 					mask &= ~(1 << i);
    115 					if (mask)
    116 						printf(", ");
    117 				}
    118 			}
    119 		}
    120 	} else	if (event->ext != NULL) {
    121 		/* Handling extended feature interface */
    122 		printf(": (ext: %s", event->ext);
    123 	} else {
    124 		/* Handling arch_perfmon case */
    125 		printf(": (counter: all");
    126 	}
    127 
    128 	printf(")\n\t");
    129 	column = 8;
    130 	word_wrap(8, &column, event->desc);
    131 	snprintf(buf, sizeof buf, "(min count: %d)", event->min_count);
    132 	word_wrap(8, &column, buf);
    133 	putchar('\n');
    134 
    135 	if (strcmp(event->unit->name, "zero")) {
    136 
    137 		printf("\tUnit masks (default 0x%x)\n",
    138 		       event->unit->default_mask);
    139 		printf("\t----------\n");
    140 
    141 		for (j = 0; j < event->unit->num; j++) {
    142 			printf("\t0x%.2x: ",
    143 			       event->unit->um[j].value);
    144 			column = 14;
    145 			word_wrap(14, &column, event->unit->um[j].desc);
    146 			putchar('\n');
    147 		}
    148 	}
    149 }
    150 
    151 
    152 static void check_event(struct parsed_event * pev,
    153 			struct op_event const * event)
    154 {
    155 	int ret;
    156 	int min_count;
    157 	int const callgraph_min_count_scale = 15;
    158 
    159 	if (!event) {
    160 		event = find_event_by_name(pev->name, 0, 0);
    161 		if (event)
    162 			fprintf(stderr, "Invalid unit mask %x for event %s\n",
    163 				pev->unit_mask, pev->name);
    164 		else
    165 			fprintf(stderr, "No event named %s is available.\n",
    166 				pev->name);
    167 		exit(EXIT_FAILURE);
    168 	}
    169 
    170 	ret = op_check_events(0, event->val, pev->unit_mask, cpu_type);
    171 
    172 	if (ret & OP_INVALID_UM) {
    173 		fprintf(stderr, "Invalid unit mask 0x%x for event %s\n",
    174 		        pev->unit_mask, pev->name);
    175 		exit(EXIT_FAILURE);
    176 	}
    177 
    178 	min_count = event->min_count;
    179 	if (callgraph_depth)
    180 		min_count *= callgraph_min_count_scale;
    181 	if (pev->count < min_count) {
    182 		fprintf(stderr, "Count %d for event %s is below the "
    183 		        "minimum %d\n", pev->count, pev->name, min_count);
    184 		exit(EXIT_FAILURE);
    185 	}
    186 }
    187 
    188 
    189 static void resolve_events(void)
    190 {
    191 	size_t count, count_events;
    192 	size_t i, j;
    193 	size_t * counter_map;
    194 	size_t nr_counters = op_get_nr_counters(cpu_type);
    195 	struct op_event const * selected_events[num_chosen_events];
    196 
    197 	count = parse_events(parsed_events, num_chosen_events, chosen_events);
    198 
    199 	for (i = 0; i < count; ++i) {
    200 		for (j = i + 1; j < count; ++j) {
    201 			struct parsed_event * pev1 = &parsed_events[i];
    202 			struct parsed_event * pev2 = &parsed_events[j];
    203 
    204 			if (!strcmp(pev1->name, pev2->name) &&
    205 			    pev1->count == pev2->count &&
    206 			    pev1->unit_mask == pev2->unit_mask &&
    207 			    pev1->kernel == pev2->kernel &&
    208 			    pev1->user == pev2->user) {
    209 				fprintf(stderr, "All events must be distinct.\n");
    210 				exit(EXIT_FAILURE);
    211 			}
    212 		}
    213 	}
    214 
    215 	for (i = 0, count_events = 0; i < count; ++i) {
    216 		struct parsed_event * pev = &parsed_events[i];
    217 
    218 		/* For 0 unit mask always do wild card match */
    219 		selected_events[i] = find_event_by_name(pev->name, pev->unit_mask,
    220 					pev->unit_mask ? pev->unit_mask_valid : 0);
    221 		check_event(pev, selected_events[i]);
    222 
    223 		if (selected_events[i]->ext == NULL) {
    224 			count_events++;
    225 		}
    226 	}
    227 	if (count_events > nr_counters) {
    228 		fprintf(stderr, "Not enough hardware counters. "
    229 				"Need %lu counters but only has %lu.\n",
    230 				(unsigned long) count_events,
    231 				(unsigned long) nr_counters);
    232 		exit(EXIT_FAILURE);
    233 	}
    234 
    235 	counter_map = map_event_to_counter(selected_events, count, cpu_type);
    236 
    237 	if (!counter_map) {
    238 		fprintf(stderr, "Couldn't allocate hardware counters for the selected events.\n");
    239 		exit(EXIT_FAILURE);
    240 	}
    241 
    242 	for (i = 0; i < count; ++i)
    243 		if(counter_map[i] == (size_t)-1)
    244 			if (selected_events[i]->ext != NULL)
    245 				printf("%s ", (char*) selected_events[i]->ext);
    246 			else
    247 				printf("N/A ");
    248 		else
    249 			printf("%d ", (unsigned int) counter_map[i]);
    250 	printf("\n");
    251 
    252 	free(counter_map);
    253 }
    254 
    255 
    256 static void show_unit_mask(void)
    257 {
    258 	struct op_event * event;
    259 	size_t count;
    260 
    261 	count = parse_events(parsed_events, num_chosen_events, chosen_events);
    262 	if (count > 1) {
    263 		fprintf(stderr, "More than one event specified.\n");
    264 		exit(EXIT_FAILURE);
    265 	}
    266 
    267 	event = find_event_by_name(parsed_events[0].name, 0, 0);
    268 
    269 	if (!event) {
    270 		fprintf(stderr, "No such event found.\n");
    271 		exit(EXIT_FAILURE);
    272 	}
    273 
    274 	printf("%d\n", event->unit->default_mask);
    275 }
    276 
    277 
    278 static void show_default_event(void)
    279 {
    280 	struct op_default_event_descr descr;
    281 
    282 	op_default_event(cpu_type, &descr);
    283 
    284 	if (descr.name[0] == '\0')
    285 		return;
    286 
    287 	printf("%s:%lu:%lu:1:1\n", descr.name, descr.count, descr.um);
    288 }
    289 
    290 
    291 static int show_vers;
    292 static int get_cpu_type;
    293 static int check_events;
    294 static int unit_mask;
    295 static int get_default_event;
    296 
    297 static struct poptOption options[] = {
    298 	{ "cpu-type", 'c', POPT_ARG_STRING, &cpu_string, 0,
    299 	  "use the given CPU type", "cpu type", },
    300 	{ "check-events", 'e', POPT_ARG_NONE, &check_events, 0,
    301 	  "check the given event descriptions for validity", NULL, },
    302 	{ "unit-mask", 'u', POPT_ARG_NONE, &unit_mask, 0,
    303 	  "default unit mask for the given event", NULL, },
    304 	{ "get-cpu-type", 'r', POPT_ARG_NONE, &get_cpu_type, 0,
    305 	  "show the auto-detected CPU type", NULL, },
    306 	{ "get-default-event", 'd', POPT_ARG_NONE, &get_default_event, 0,
    307 	  "get the default event", NULL, },
    308 	{ "callgraph", '\0', POPT_ARG_INT, &callgraph_depth, 0,
    309 	  "use this callgraph depth", "callgraph depth", },
    310 	{ "version", 'v', POPT_ARG_NONE, &show_vers, 0,
    311 	   "show version", NULL, },
    312 	{ "xml", 'X', POPT_ARG_NONE, &want_xml, 0,
    313 	   "list events as XML", NULL, },
    314 	POPT_AUTOHELP
    315 	{ NULL, 0, 0, NULL, 0, NULL, NULL, },
    316 };
    317 
    318 /**
    319  * get_options - process command line
    320  * @param argc  program arg count
    321  * @param argv  program arg array
    322  *
    323  * Process the arguments, fatally complaining on error.
    324  */
    325 static void get_options(int argc, char const * argv[])
    326 {
    327 	optcon = op_poptGetContext(NULL, argc, argv, options, 0);
    328 
    329 	if (show_vers)
    330 		show_version(argv[0]);
    331 
    332 	/* non-option, must be a valid event name or event specs */
    333 	chosen_events = poptGetArgs(optcon);
    334 
    335 	if(chosen_events) {
    336 		num_chosen_events = 0;
    337 		while (chosen_events[num_chosen_events] != NULL)
    338 			num_chosen_events++;
    339 	}
    340 
    341 	/* don't free the context now, we need chosen_events */
    342 }
    343 
    344 
    345 /** make valgrind happy */
    346 static void cleanup(void)
    347 {
    348 	int i;
    349 	if (parsed_events) {
    350 		for (i = 0; i < num_chosen_events; ++i) {
    351 			if (parsed_events[i].name)
    352 				free(parsed_events[i].name);
    353 		}
    354 	}
    355 	op_free_events();
    356 	if (optcon)
    357 		poptFreeContext(optcon);
    358 	if (parsed_events)
    359 		free(parsed_events);
    360 }
    361 
    362 
    363 #define MAX_LINE 256
    364 int main(int argc, char const * argv[])
    365 {
    366 	struct list_head * events;
    367 	struct list_head * pos;
    368 	char const * pretty;
    369 	char title[10 * MAX_LINE];
    370 	char const * event_doc = "";
    371 
    372 	atexit(cleanup);
    373 
    374 	get_options(argc, argv);
    375 
    376 	/* usefull for testing purpose to allow to force the cpu type
    377 	 * with --cpu-type */
    378 	if (cpu_string) {
    379 		cpu_type = op_get_cpu_number(cpu_string);
    380 	} else {
    381 		cpu_type = op_get_cpu_type();
    382 	}
    383 
    384 	if (cpu_type == CPU_NO_GOOD) {
    385 		fprintf(stderr, "cpu_type '%s' is not valid\n",
    386 		        cpu_string ? cpu_string : "unset");
    387 		fprintf(stderr, "you should upgrade oprofile or force the "
    388 			"use of timer mode\n");
    389 		exit(EXIT_FAILURE);
    390 	}
    391 
    392 	parsed_events = (struct parsed_event *)xcalloc(num_chosen_events,
    393 		sizeof(struct parsed_event));
    394 
    395 	pretty = op_get_cpu_type_str(cpu_type);
    396 
    397 	if (get_cpu_type) {
    398 		printf("%s\n", pretty);
    399 		exit(EXIT_SUCCESS);
    400 	}
    401 
    402 	if (get_default_event) {
    403 		show_default_event();
    404 		exit(EXIT_SUCCESS);
    405 	}
    406 
    407 	if (cpu_type == CPU_TIMER_INT) {
    408 		if (!check_events)
    409 			printf("Using timer interrupt.\n");
    410 		exit(EXIT_SUCCESS);
    411 	}
    412 
    413 	events = op_events(cpu_type);
    414 
    415 	if (!chosen_events && (unit_mask || check_events)) {
    416 		fprintf(stderr, "No events given.\n");
    417 		exit(EXIT_FAILURE);
    418 	}
    419 
    420 	if (unit_mask) {
    421 		show_unit_mask();
    422 		exit(EXIT_SUCCESS);
    423 	}
    424 
    425 	if (check_events) {
    426 		resolve_events();
    427 		exit(EXIT_SUCCESS);
    428 	}
    429 
    430 	/* without --check-events, the only argument must be an event name */
    431 	if (chosen_events && chosen_events[0]) {
    432 		if (chosen_events[1]) {
    433 			fprintf(stderr, "Too many arguments.\n");
    434 			exit(EXIT_FAILURE);
    435 		}
    436 
    437 		list_for_each(pos, events) {
    438 			struct op_event * event = list_entry(pos, struct op_event, event_next);
    439 
    440 			if (strcmp(event->name, chosen_events[0]) == 0) {
    441 				char const * map = find_mapping_for_event(event->val, cpu_type);
    442 				if (map) {
    443 					printf("%d %s\n", event->val, map);
    444 				} else {
    445 					printf("%d\n", event->val);
    446 				}
    447 				exit(EXIT_SUCCESS);
    448 			}
    449 		}
    450 		fprintf(stderr, "No such event \"%s\"\n", chosen_events[0]);
    451 		exit(EXIT_FAILURE);
    452 	}
    453 
    454 	/* default: list all events */
    455 
    456 	switch (cpu_type) {
    457 	case CPU_HAMMER:
    458 		event_doc =
    459 			"See BIOS and Kernel Developer's Guide for AMD Athlon and AMD Opteron Processors\n"
    460 			"(26094.pdf), Section 10.2\n\n";
    461 		break;
    462 	case CPU_FAMILY10:
    463 		event_doc =
    464 			"See BIOS and Kernel Developer's Guide for AMD Family 10h Processors\n"
    465 			"(31116.pdf), Section 3.14\n\n";
    466 		break;
    467 	case CPU_FAMILY11H:
    468 		event_doc =
    469 			"See BIOS and Kernel Developer's Guide for AMD Family 11h Processors\n"
    470 			"(41256.pdf), Section 3.14\n\n";
    471 		break;
    472 	case CPU_FAMILY12H:
    473 		event_doc =
    474 			"See BIOS and Kernel Developer's Guide for AMD Family 12h Processors\n";
    475 		break;
    476 	case CPU_FAMILY14H:
    477 		event_doc =
    478 			"See BIOS and Kernel Developer's Guide for AMD Family 14h Processors\n";
    479 		break;
    480 	case CPU_FAMILY15H:
    481 		event_doc =
    482 			"See BIOS and Kernel Developer's Guide for AMD Family 15h Processors\n";
    483 		break;
    484 	case CPU_ATHLON:
    485 		event_doc =
    486 			"See AMD Athlon Processor x86 Code Optimization Guide\n"
    487 			"(22007.pdf), Appendix D\n\n";
    488 		break;
    489 	case CPU_PPRO:
    490 	case CPU_PII:
    491 	case CPU_PIII:
    492 	case CPU_P6_MOBILE:
    493 	case CPU_P4:
    494 	case CPU_P4_HT2:
    495 	case CPU_CORE:
    496 	case CPU_CORE_2:
    497 	case CPU_CORE_I7:
    498 	case CPU_NEHALEM:
    499 	case CPU_WESTMERE:
    500 	case CPU_ATOM:
    501 		event_doc =
    502 			"See Intel Architecture Developer's Manual Volume 3B, Appendix A and\n"
    503 			"Intel Architecture Optimization Reference Manual (730795-001)\n\n";
    504 		break;
    505 
    506 	case CPU_ARCH_PERFMON:
    507 		event_doc =
    508 			"See Intel 64 and IA-32 Architectures Software Developer's Manual\n"
    509 			"Volume 3B (Document 253669) Chapter 18 for architectural perfmon events\n"
    510 			"This is a limited set of fallback events because oprofile doesn't know your CPU\n";
    511 		break;
    512 
    513 	case CPU_IA64:
    514 	case CPU_IA64_1:
    515 	case CPU_IA64_2:
    516 		event_doc =
    517 			"See Intel Itanium Processor Reference Manual\n"
    518 			"for Software Development (Document 245320-003),\n"
    519 			"Intel Itanium Processor Reference Manual\n"
    520 			"for Software Optimization (Document 245473-003),\n"
    521 			"Intel Itanium 2 Processor Reference Manual\n"
    522 			"for Software Development and Optimization (Document 251110-001)\n\n";
    523 		break;
    524 	case CPU_AXP_EV4:
    525 	case CPU_AXP_EV5:
    526 	case CPU_AXP_PCA56:
    527 	case CPU_AXP_EV6:
    528 	case CPU_AXP_EV67:
    529 		event_doc =
    530 			"See Alpha Architecture Reference Manual\n"
    531 			"http://download.majix.org/dec/alpha_arch_ref.pdf\n";
    532 		break;
    533 	case CPU_ARM_XSCALE1:
    534 	case CPU_ARM_XSCALE2:
    535 		event_doc =
    536 			"See Intel XScale Core Developer's Manual\n"
    537 			"Chapter 8 Performance Monitoring\n";
    538 		break;
    539 	case CPU_ARM_MPCORE:
    540 		event_doc =
    541 			"See ARM11 MPCore Processor Technical Reference Manual r1p0\n"
    542 			"Page 3-70, performance counters\n";
    543 		break;
    544 
    545 	case CPU_ARM_V6:
    546 		event_doc = "See ARM11 Technical Reference Manual\n";
    547   		break;
    548 
    549 	case CPU_ARM_V7:
    550 		event_doc =
    551 			"See Cortex-A8 Technical Reference Manual\n"
    552 			"Cortex A8 DDI (ARM DDI 0344B, revision r1p1)\n";
    553 		break;
    554 
    555 	case CPU_ARM_V7_CA9:
    556 		event_doc =
    557 			"See Cortex-A9 Technical Reference Manual\n"
    558 			"Cortex A9 DDI (ARM DDI 0388E, revision r2p0)\n";
    559 		break;
    560 
    561 	case CPU_PPC64_PA6T:
    562 		event_doc =
    563 			"See PA6T Power Implementation Features Book IV\n"
    564 			"Chapter 7 Performance Counters\n";
    565 		break;
    566 
    567 	case CPU_PPC64_POWER4:
    568 	case CPU_PPC64_POWER5:
    569 	case CPU_PPC64_POWER6:
    570 	case CPU_PPC64_POWER5p:
    571 	case CPU_PPC64_POWER5pp:
    572 	case CPU_PPC64_970:
    573 	case CPU_PPC64_970MP:
    574 	case CPU_PPC64_POWER7:
    575 	case CPU_PPC64_IBM_COMPAT_V1:
    576 		event_doc =
    577 			"Obtain PowerPC64 processor documentation at:\n"
    578 			"http://www-306.ibm.com/chips/techlib/techlib.nsf/productfamilies/PowerPC\n";
    579 		break;
    580 
    581 	case CPU_PPC64_CELL:
    582 		event_doc =
    583 			"Obtain Cell Broadband Engine documentation at:\n"
    584 			"http://www-306.ibm.com/chips/techlib/techlib.nsf/products/Cell_Broadband_Engine\n";
    585 		break;
    586 
    587 	case CPU_MIPS_20K:
    588 		event_doc =
    589 			"See Programming the MIPS64 20Kc Processor Core User's "
    590 		"manual available from www.mips.com\n";
    591 		break;
    592 	case CPU_MIPS_24K:
    593 		event_doc =
    594 			"See Programming the MIPS32 24K Core "
    595 			"available from www.mips.com\n";
    596 		break;
    597 	case CPU_MIPS_25K:
    598 		event_doc =
    599 			"See Programming the MIPS64 25Kf Processor Core User's "
    600 			"manual available from www.mips.com\n";
    601 		break;
    602 	case CPU_MIPS_34K:
    603 		event_doc =
    604 			"See Programming the MIPS32 34K Core Family "
    605 			"available from www.mips.com\n";
    606 		break;
    607 	case CPU_MIPS_74K:
    608 		event_doc =
    609 			"See Programming the MIPS32 74K Core Family "
    610 			"available from www.mips.com\n";
    611 		break;
    612 	case CPU_MIPS_1004K:
    613 		event_doc =
    614 			"See Programming the MIPS32 1004K Core Family "
    615 			"available from www.mips.com\n";
    616 		break;
    617 	case CPU_MIPS_5K:
    618 		event_doc =
    619 			"See Programming the MIPS64 5K Processor Core Family "
    620 			"Software User's manual available from www.mips.com\n";
    621 		break;
    622 	case CPU_MIPS_R10000:
    623 	case CPU_MIPS_R12000:
    624 		event_doc =
    625 			"See NEC R10000 / R12000 User's Manual\n"
    626 			"http://www.necelam.com/docs/files/U10278EJ3V0UM00.pdf\n";
    627 		break;
    628 	case CPU_MIPS_RM7000:
    629 		event_doc =
    630 			"See RM7000 Family User Manual "
    631 			"available from www.pmc-sierra.com\n";
    632 		break;
    633 	case CPU_MIPS_RM9000:
    634 		event_doc =
    635 			"See RM9000x2 Family User Manual "
    636 			"available from www.pmc-sierra.com\n";
    637 		break;
    638 	case CPU_MIPS_SB1:
    639 	case CPU_MIPS_VR5432:
    640 		event_doc =
    641 			"See NEC VR5443 User's Manual, Volume 1\n"
    642 			"http://www.necelam.com/docs/files/1375_V1.pdf\n";
    643 		break;
    644 	case CPU_MIPS_VR5500:
    645 		event_doc =
    646 			"See NEC R10000 / R12000 User's Manual\n"
    647 			"http://www.necel.com/nesdis/image/U16677EJ3V0UM00.pdf\n";
    648 		break;
    649 
    650 	case CPU_MIPS_LOONGSON2:
    651 		event_doc =
    652 			"See loongson2 RISC Microprocessor Family Reference Manual\n";
    653 		break;
    654 
    655 	case CPU_PPC_E500:
    656 	case CPU_PPC_E500_2:
    657 		event_doc =
    658 			"See PowerPC e500 Core Complex Reference Manual\n"
    659 			"Chapter 7: Performance Monitor\n"
    660 			"Downloadable from http://www.freescale.com\n";
    661 		break;
    662 
    663 	case CPU_PPC_E300:
    664 		event_doc =
    665 			"See PowerPC e300 Core Reference Manual\n"
    666 			"Downloadable from http://www.freescale.com\n";
    667 		break;
    668 
    669 	case CPU_PPC_7450:
    670 		event_doc =
    671 			"See MPC7450 RISC Microprocessor Family Reference "
    672 			"Manual\n"
    673 			"Chapter 11: Performance Monitor\n"
    674 			"Downloadable from http://www.freescale.com\n";
    675 		break;
    676 
    677 	case CPU_AVR32:
    678 		event_doc =
    679 			"See AVR32 Architecture Manual\n"
    680 			"Chapter 6: Performance Counters\n"
    681 			"http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf\n";
    682 
    683 		case CPU_RTC:
    684 			break;
    685 
    686 		// don't use default, if someone add a cpu he wants a compiler warning
    687 		// if he forgets to handle it here.
    688 		case CPU_TIMER_INT:
    689 		case CPU_NO_GOOD:
    690 		case MAX_CPU_TYPE:
    691 			printf("%d is not a valid processor type.\n", cpu_type);
    692 			exit(EXIT_FAILURE);
    693 	}
    694 
    695 	sprintf(title, "oprofile: available events for CPU type \"%s\"\n\n", pretty);
    696 	if (want_xml)
    697 		open_xml_events(title, event_doc, cpu_type);
    698 	else
    699 		printf("%s%s", title, event_doc);
    700 
    701 	list_for_each(pos, events) {
    702 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    703 		if (want_xml)
    704 			xml_help_for_event(event);
    705 		else
    706 			help_for_event(event);
    707 	}
    708 
    709 	if (want_xml)
    710 		close_xml_events();
    711 
    712 	return EXIT_SUCCESS;
    713 }
    714