$Id: low-level-ppc32.txt,v 1.1 2004/07/02 18:57:05 mikpe Exp $

PERFCTRS PPC32 LOW-LEVEL API
============================

See low-level-api.txt for the common low-level API.
This document only describes ppc32-specific behaviour.
For detailed hardware control register layouts, see
the manufacturers' documentation.

Supported processors
====================
- PowerPC 604, 604e, 604ev.
- PowerPC 750/740, 750CX, 750FX, 750GX.
- PowerPC 7400, 7410, 7451/7441, 7457/7447.
- Any generic PowerPC with a timebase register.

Contents of <asm-$ARCH/perfctr.h>
=================================

"struct perfctr_sum_ctrs"
-------------------------
struct perfctr_sum_ctrs {
	unsigned long long tsc;
	unsigned long long pmc[8];
};

The pmc[] array has room for 8 counters.

"struct perfctr_cpu_control"
----------------------------
struct perfctr_cpu_control {
	unsigned int tsc_on;
	unsigned int nractrs;		/* # of a-mode counters */
	unsigned int nrictrs;		/* # of i-mode counters */
	unsigned int pmc_map[8];
	unsigned int evntsel[8];	/* one per counter, even on P5 */
	int ireset[8];			/* [0,0x7fffffff], for i-mode counters */
	struct {
		unsigned int mmcr0;	/* sans PMC{1,2}SEL */
		unsigned int mmcr2;	/* only THRESHMULT */
		/* IABR/DABR/BAMR not supported */
	} ppc;
	unsigned int _reserved1;
	unsigned int _reserved2;
	unsigned int _reserved3;
	unsigned int _reserved4;
};

The per-counter arrays have room for 8 elements.

ireset[] values must be non-negative, since overflow occurs on
the non-negative-to-negative transition.

The ppc sub-struct contains PowerPC-specific control data:
- mmcr0: global control data for the MMCR0 SPR; the event
  selectors for PMC1 and PMC2 are in evntsel[], not in mmcr0
- mmcr2: global control data for the MMCR2 SPR; only the
  THRESHMULT field can be specified

"struct perfctr_cpu_state"
--------------------------
struct perfctr_cpu_state {
	unsigned int cstatus;
	struct {	/* k1 is opaque in the user ABI */
		unsigned int id;
		int isuspend_cpu;
	} k1;
	/* The two tsc fields must be inlined. Placing them in a
	   sub-struct causes unwanted internal padding on x86-64. */
	unsigned int tsc_start;
	unsigned long long tsc_sum;
	struct {
		unsigned int map;
		unsigned int start;
		unsigned long long sum;
	} pmc[8];	/* the size is not part of the user ABI */
#ifdef __KERNEL__
	unsigned int ppc_mmcr[3];
	struct perfctr_cpu_control control;
#endif
};

The k1 sub-struct is used by the low-level driver for
caching purposes. "id" identifies the control data, and
"isuspend_cpu" identifies the CPU on which the i-mode
counters were last suspended.

The pmc[] array has room for 8 elements.

ppc_mmcr[] is computed from control by the low-level driver,
and provides the data for the MMCR0, MMCR1, and MMCR2 SPRs.

User-space overflow signal handler items
----------------------------------------
#ifdef __KERNEL__
#define SI_PMC_OVF	(__SI_FAULT|'P')
#else
#define SI_PMC_OVF	('P')
#endif
#define si_pmc_ovf_mask	_sifields._pad[0]

Kernel-internal API
-------------------

In perfctr_cpu_update_control(), the is_global parameter
is ignored. (It is only relevant for x86.)

CONFIG_PERFCTR_CPUS_FORBIDDEN_MASK is never defined.
(It is only relevant for x86.)

Overflow interrupt handling is not yet implemented.

Processor-specific Notes
========================

General
-------
pmc_map[] contains a counter number, an integer between 0 and 5.
It never contains an SPR number.

Basic operation (the strategy for a-mode counters, caching
control register contents, recording "suspend CPU" for i-mode
counters) is the same as in the x86 driver.

PowerPC 604/750/74xx
--------------------
These processors use similar hardware layouts, differing
mainly in the number of counter and control registers.
The set of available events differ greatly, but that only
affects users, not the low-level driver itself.

The hardware has 2 (604), 4 (604e/750/7400/7410), or 6
(745x) counters (PMC1 to PMC6), and 1 (604), 2 (604e/750),
or 3 (74xx) control registers (MMCR0 to MMCR2).

MMCR0 contains global control bits, and the event selection
fields for PMC1 and PMC2. MMCR1 contains event selection fields
for PMC3-PMC6. MMCR2 contains the THRESHMULT flag, which
specifies how MMCR0[THRESHOLD] should be scaled.

In control.ppc.mmcr0, the PMC1SEL and PMC2SEL fields (0x00001FFF)
are reserved. The PMXE flag (0x04000000) may only be set when
the driver supports overflow interrupts.

If FCECE or TRIGGER is set in MMCR0 on a 74xx processor, then
MMCR0 can change asynchronously. The driver handles this, at
the cost of some additional work in perfctr_cpu_suspend().
Not setting these flags avoids that overhead.

In control.ppc.mmcr2, only the THRESHMULT flag (0x80000000)
may be set, and only on 74xx processors.

The SIA (sampled instruction address) register is not used.
The SDA (sampled data address) register is 604/604e-only,
and is not used. The BAMR (breakpoint address mask) register
is not used, but it is cleared by the driver.

Generic PowerPC with timebase
-----------------------------
The driver supports any PowerPC as long as it has a timebase
register, and the TB frequency is available via Open Firmware.
In this case, the only valid usage mode is with tsc_on == 1
and nractrs == nrictrs == 0 in the control data.
