/* $Id: marshal.h,v 1.1 2003/08/19 13:37:07 mikpe Exp $
* Performance-monitoring counters driver.
* Structure marshalling support.
*
* Copyright (C) 2003 Mikael Pettersson
*/
/*
* Each encoded datum starts with a 32-bit header word, containing
* the datum's type (1 bit: UINT32 or UINT64), the target's field
* tag (16 bits), and the target field's array index (15 bits).
*
* After the header follows the datum's value, in one (for UINT32)
* or two (for UINT64) words. Multi-word values are emitted in
* native word order.
*
* To encode a struct, encode each field with a non-zero value,
* and place the encodings in sequence. The field order is arbitrary.
*
* To decode an encoded struct, first memset() the target struct
* to zero. Then decode each encoded field in the sequence and
* update the corresponding field in the target struct.
*/
#define PERFCTR_HEADER(TYPE,TAG,ITEMNR) (((TAG)<<16)|((ITEMNR)<<1)|(TYPE))
#define PERFCTR_HEADER_TYPE(H) ((H) & 0x1)
#define PERFCTR_HEADER_ITEMNR(H) (((H) >> 1) & 0x7FFF)
#define PERFCTR_HEADER_TAG(H) ((H) >> 16)
#define PERFCTR_HEADER_UINT32 0
#define PERFCTR_HEADER_UINT64 1
/*
* A field descriptor describes a struct field to the
* encoding and decoding procedures.
*
* To keep the descriptors small, field tags and array sizes
* are currently restricted to 8 and 7 bits, respectively.
* This does not change the encoded format.
*/
struct perfctr_field_desc {
unsigned short offset; /* offsetof() for this field */
unsigned char tag; /* identifying tag in encoded format */
unsigned char type; /* base type (1 bit), array size - 1 (7 bits) */
};
#define PERFCTR_TYPE_ARRAY(N,T) ((((N) - 1) << 1) | (T))
#define PERFCTR_TYPE_BASE(T) ((T) & 0x1)
#define PERFCTR_TYPE_NRITEMS(T) (((T) >> 1) + 1)
#define PERFCTR_TYPE_BYTES4 0 /* uint32 or char[4] */
#define PERFCTR_TYPE_UINT64 1 /* long long */
struct perfctr_struct_desc {
unsigned short total_sizeof; /* for buffer allocation and decode memset() */
unsigned short total_nrfields; /* for buffer allocation */
unsigned short nrfields;
unsigned short nrsubs;
/* Note: the fields must be in ascending tag order */
const struct perfctr_field_desc *fields;
const struct perfctr_sub_struct_desc {
unsigned short offset;
const struct perfctr_struct_desc *sdesc;
} *subs;
};
struct perfctr_marshal_stream {
unsigned int size;
unsigned int *buffer;
unsigned int pos;
unsigned int error;
};
extern void perfctr_encode_struct(const void *address,
const struct perfctr_struct_desc *sdesc,
struct perfctr_marshal_stream *stream);
extern int perfctr_decode_struct(void *address,
const struct perfctr_struct_desc *sdesc,
struct perfctr_marshal_stream *stream);
extern const struct perfctr_struct_desc perfctr_sum_ctrs_sdesc;
extern const struct perfctr_struct_desc perfctr_cpu_control_sdesc;
extern const struct perfctr_struct_desc perfctr_info_sdesc;
extern const struct perfctr_struct_desc vperfctr_control_sdesc;
extern const struct perfctr_struct_desc gperfctr_cpu_control_sdesc;
extern const struct perfctr_struct_desc gperfctr_cpu_state_only_cpu_sdesc;
extern const struct perfctr_struct_desc gperfctr_cpu_state_sdesc;
#ifdef __KERNEL__
extern int perfctr_copy_to_user(struct perfctr_struct_buf *argp,
void *struct_address,
const struct perfctr_struct_desc *sdesc);
extern int perfctr_copy_from_user(void *struct_address,
struct perfctr_struct_buf *argp,
const struct perfctr_struct_desc *sdesc);
#else
extern int perfctr_ioctl_w(int fd, unsigned int cmd, const void *arg,
const struct perfctr_struct_desc *sdesc);
extern int perfctr_ioctl_r(int fd, unsigned int cmd, void *res,
const struct perfctr_struct_desc *sdesc);
extern int perfctr_ioctl_wr(int fd, unsigned int cmd, void *argres,
const struct perfctr_struct_desc *arg_sdesc,
const struct perfctr_struct_desc *res_sdesc);
#endif /* __KERNEL__ */