#include <IOKit/IOReportMacros.h>

IOKit/IOReportMacros.h Kernel.framework

includes: IOKit/IOReportTypes.h, Kernel/string.h, Kernel/os/overflow.h
36 macros · 2 structs · 2 typedefs

macroIOREPORT_ABORT

#define IOREPORT_ABORT panic

macroSIMPLEREPORT_BUFSIZE

#define SIMPLEREPORT_BUFSIZE (sizeof(IOReportElement))

macroSIMPLEREPORT_INIT

#define SIMPLEREPORT_INIT(buf, bufSize, providerID, channelID, cats) do {
    memset((buf), '&', (bufSize));
    IOReportElement     *__elem = (IOReportElement *)(buf);
    IOSimpleReportValues *__vals;
    if ((bufSize) >= SIMPLEREPORT_BUFSIZE) {
	__elem->provider_id = (providerID);
	__elem->channel_id = (channelID);
	__elem->channel_type.report_format = kIOReportFormatSimple;
	__elem->channel_type.reserved = 0;
	__elem->channel_type.categories = (cats);
	__elem->channel_type.nelements = 1;
	__elem->channel_type.element_idx = 0;
	__elem->timestamp = 0;
	__vals = (IOSimpleReportValues*)&__elem->values;
	__vals->simple_value = kIOReportInvalidIntValue;
    }
    else {
	IOREPORT_ABORT("bufSize is smaller than the required size\n");
    }
} while(0)

macroSIMPLEREPORT_SETVALUE

#define SIMPLEREPORT_SETVALUE(simp_buf, new_value) do {
    IOReportElement *__elem = (IOReportElement *)(simp_buf);
    IOSimpleReportValues *__vals;
    __vals = (IOSimpleReportValues*)&__elem->values;
    __vals->simple_value = (new_value);
} while(0)

macroSIMPLEREPORT_INCREMENTVALUE

Increment the value of a SimpleReport. void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT() int64_t increment - amount by which to increment the value
#define SIMPLEREPORT_INCREMENTVALUE(simp_buf, increment_by) do {
    IOReportElement *__elem = (IOReportElement *)(simp_buf);
    IOSimpleReportValues *__vals;
    __vals = (IOSimpleReportValues*)&__elem->values;
    int64_t __simple_value = INT64_MAX;
    if (os_add_overflow(__vals->simple_value, (increment_by), &__simple_value)) {
    __vals->simple_value = INT64_MAX;
    } else {
    __vals->simple_value = __simple_value;
    }
} while(0)

macroSIMPLEREPORT_UPDATEPREP

#define SIMPLEREPORT_UPDATEPREP(simp_buf, ptr2cpy, size2cpy) do {
    (ptr2cpy) = (simp_buf);
    (size2cpy) = sizeof(IOReportElement);
} while(0)

macroSIMPLEREPORT_UPDATERES

#define SIMPLEREPORT_UPDATERES(action, result) do {
    if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
	int *__nElements = (int *)(result);
	*__nElements += 1;
    }
} while (0)

macroSIMPLEREPORT_GETCHID

#define SIMPLEREPORT_GETCHID(simp_buf) (((IOReportElement *)(simp_buf))->channel_id)

macroSIMPLEREPORT_GETCHTYPE

#define SIMPLEREPORT_GETCHTYPE(simp_buf) (*(uint64_t*)&(((IOReportElement *)(simp_buf))->channel_type))

macroSIMPLEREPORT_GETVALUE

#define SIMPLEREPORT_GETVALUE(simp_buf) (((IOSimpleReportValues*)&(((IOReportElement*)(simp_buf))->values))
	    ->simple_value)

structIOStateReportInfo

Internal struct for StateReport
size 16, align 8
uint16_tcurr_state
uint64_tupdate_ts
IOReportElement[]elemArray of elements

typedefIOStateReportInfo

typedef struct IOStateReportInfo IOStateReportInfo;

macroSTATEREPORT_BUFSIZE

Determine the size required for a StateReport buffer. int nstates - number of states to be reported
#define STATEREPORT_BUFSIZE(nstates) (sizeof(IOStateReportInfo) + (nstates) * sizeof(IOReportElement))

macroSTATEREPORT_INIT

Initialize a StateReport buffer. uint16_t nstates - number of states to be reported void* buffer - ptr to STATEREPORT_BUFSIZE(nstates) bytes size_t bufSize - sanity check of buffer's size uint64_t providerID - registry Entry ID of the reporting service uint64_t channelID - ID of this channel, see IOREPORT_MAKEID() IOReportCategories categories - categories of this channel If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT. If that returns, the buffer is left full of '&'.
#define STATEREPORT_INIT(nstates, buf, bufSize, providerID, channelID, cats) do {
    memset((buf), '&', (bufSize));
    IOStateReportInfo *__info = (IOStateReportInfo *)(buf);
    IOStateReportValues *__rep;
    IOReportElement     *__elem;
    if ((bufSize) >= STATEREPORT_BUFSIZE(nstates)) {
	for (uint16_t __no = 0; __no < (nstates); __no++) {
	    __elem =  &(__info->elem[__no]);
	    __rep = (IOStateReportValues *) &(__elem->values);
	    __elem->provider_id = (providerID);
	    __elem->channel_id = (channelID);
	    __elem->channel_type.report_format = kIOReportFormatState;
	    __elem->channel_type.reserved = 0;
	    __elem->channel_type.categories = (cats);
	    __elem->channel_type.nelements = (nstates);
	    __elem->channel_type.element_idx = __no;
	    __elem->timestamp = 0;
	    __rep->state_id = __no;
	    __rep->intransitions = 0;
	    __rep->upticks = 0;
	    __rep->last_intransition = 0;
	}
	__info->curr_state = 0;
	__info->update_ts = 0;
    }
    else {
	IOREPORT_ABORT("bufSize is smaller than the required size\n");
    }
} while(0)

macroSTATEREPORT_SETSTATEID

Initialize the state id field of a state with the specified value. By default, STATEREPORT_INIT() initializes the state IDs with the index of that state. This macro can be used to provide a more descriptive state id. void* state_buf - ptr to memory initialized by STATEREPORT_INIT() unsigned stateIdx - index of the state, out of bounds -> no-op uint64_t stateID - new state id, see IOREPORT_MAKEID()
#define STATEREPORT_SETSTATEID(state_buf, stateIdx, stateID) do {
    IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
    IOStateReportValues *__rep;
    if ((stateIdx) < __info->elem[0].channel_type.nelements) {
	__rep = (IOStateReportValues*) &(__info->elem[(stateIdx)].values);
	__rep->state_id = (stateID);
    }
} while (0)

macroSTATEREPORT_SETSTATE

Set the state of a StateReport. void* state_buf - pointer to memory initialized by STATEREPORT_INIT() unsigned newStateIdx - index of new state, out of bounds -> no-op uint64_t changeTime - time at which the transition occurred
#define STATEREPORT_SETSTATE(state_buf, newStateIdx, changeTime) do {
    IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
    IOStateReportValues *__rep;
    if ((newStateIdx) < __info->elem[0].channel_type.nelements ) {
	__rep = (IOStateReportValues*) &(__info->elem[__info->curr_state].values);
	if (__info->update_ts)
	    __rep->upticks += (changeTime) - __info->update_ts;
	__info->elem[(newStateIdx)].timestamp = (changeTime);
	__rep = (IOStateReportValues*) &(__info->elem[(newStateIdx)].values);
	__rep->intransitions++;
	__info->curr_state = (newStateIdx);
	__info->update_ts = (changeTime);
    }
} while(0)

macroSTATEREPORT_UPDATEPREP

Prepare a StateReport for IOService::updateReport(kIOReportCopyChannelData...) void* state_buf - ptr to memory initialized by STATEREPORT_INIT() uint64_t currentTime - current timestamp void* ptr2cpy - filled in with pointer to buffer to be copied out size_t size2cpy - filled in with the size of the buffer to copy out
#define STATEREPORT_UPDATEPREP(state_buf, currentTime, ptr2cpy, size2cpy) do {
    IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
    IOReportElement     *__elem;
    IOStateReportValues *__state;
    (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement);
    (ptr2cpy) =  (void *) &__info->elem[0];
    if (__info->update_ts)  {
	__elem = &__info->elem[__info->curr_state];
	__state = (IOStateReportValues *)&__elem->values;
	__elem->timestamp = (currentTime);
	__state->upticks  += (currentTime) - __info->update_ts;
	__info->update_ts = (currentTime);
    }
} while(0)

macroSTATEREPORT_UPDATERES

#define STATEREPORT_UPDATERES(state_buf, action, result) do {
    IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
    IOReportElement     *__elem;
    int *__nElements = (int *)(result);
    if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
	__elem =  &(__info->elem[0]);
    if (os_add_overflow(*__nElements, __elem->channel_type.nelements, __nElements)) {
	*__nElements = INT_MAX;
    }
    }
} while (0)

macroSTATEREPORT_GETCHID

Get the 64-bit channel ID of a StateReport. void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
#define STATEREPORT_GETCHID(state_buf) (((IOStateReportInfo *)(state_buf))->elem[0].channel_id)

macroSTATEREPORT_GETCHTYPE

Get the IOReportChannelType of a StateReport. void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
#define STATEREPORT_GETCHTYPE(state_buf) (*(uint64_t*)&(((IOStateReportInfo *)(state_buf))->elem[0].channel_type))

macroSTATEREPORT_GETTRANSITIONS

Get the number of transitions into a given state. void* state_buf - ptr to memory initialized by STATEREPORT_INIT() unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
#define STATEREPORT_GETTRANSITIONS(state_buf, stateIdx) (((stateIdx) < ((IOStateReportInfo *)(state_buf))->elem[0].channel_type.nelements)
	? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->intransitions
	: kIOReportInvalidValue)

macroSTATEREPORT_GETTICKS

Get the total number of ticks spent in a given state. void* state_buf - ptr to memory initialized by STATEREPORT_INIT() unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
#define STATEREPORT_GETTICKS(state_buf, stateIdx) (((stateIdx) < ((IOStateReportInfo*)(state_buf))->elem[0].channel_type.nelements)
	? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->upticks
	: kIOReportInvalidValue)

macroSIMPLEARRAY_BUFSIZE

#define SIMPLEARRAY_BUFSIZE(nValues) ((((nValues)/IOR_VALUES_PER_ELEMENT) + (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1:0))
	* sizeof(IOReportElement))

macroSIMPLEARRAY_INIT

#define SIMPLEARRAY_INIT(nValues, buf, bufSize, providerID, channelID, cats) do {
    memset((buf), '&', (bufSize));
    IOSimpleArrayReportValues *__rep;
    IOReportElement     *__elem;
    uint32_t            __nElems = (((nValues) / IOR_VALUES_PER_ELEMENT) +
	                            (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1 : 0));
    if ((bufSize) >= SIMPLEARRAY_BUFSIZE(nValues)) {
	for (unsigned __no = 0; __no < __nElems; __no++) {
	    __elem =  &(((IOReportElement *)(buf))[__no]);
	    __rep = (IOSimpleArrayReportValues *) &(__elem->values);
	    __elem->provider_id = (providerID);
	    __elem->channel_id = (channelID);
	    __elem->channel_type.report_format = kIOReportFormatSimpleArray;
	    __elem->channel_type.reserved = 0;
	    __elem->channel_type.categories = (cats);
	    __elem->channel_type.nelements = (__nElems);
	    __elem->channel_type.element_idx = __no;
	    __elem->timestamp = 0;
	    __rep->simple_values[0] = kIOReportInvalidIntValue;
	    __rep->simple_values[1] = kIOReportInvalidIntValue;
	    __rep->simple_values[2] = kIOReportInvalidIntValue;
	    __rep->simple_values[3] = kIOReportInvalidIntValue;
	}
    }
    else {
	IOREPORT_ABORT("bufSize is smaller than the required size\n");
    }
} while(0)

macroSIMPLEARRAY_SETVALUE

Set a value at a specified index in a SimpleArrayReport. void* array_bufbuf - ptr to memory initialized by SIMPLEARRAY_INIT() unsigned idx - array index, out of bounds -> no-op uint64_t newValue - new value to be stored at array[idx]
#define SIMPLEARRAY_SETVALUE(array_buf, idx, newValue) do {
    __SA_FINDREP((array_buf), (idx))
	__rep->simple_values[__valueIdx] = (newValue);
    }
} while(0)

macroSIMPLEARRAY_INCREMENTVALUE

Increment an array value within a SimpleArrayReport. void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT() unsigned idx - array index to increment, out of bounds -> no-op int64_t value - amount by which to increment array[idx]
#define SIMPLEARRAY_INCREMENTVALUE(array_buf, idx, value) do {
    __SA_FINDREP((array_buf), (idx))
    if (os_add_overflow(__rep->simple_values[__valueIdx], (value), &__rep->simple_values[__valueIdx])) {
	__rep->simple_values[__valueIdx] = INT64_MAX;
    }
    }
} while(0)

macroSIMPLEARRAY_UPDATEPREP

#define SIMPLEARRAY_UPDATEPREP(array_buf, ptr2cpy, size2cpy) do {
    IOReportElement     *__elem;
    __elem = &(((IOReportElement *)(array_buf))[0]);
    (ptr2cpy) =  (void *) (array_buf);
    (size2cpy) = __elem->channel_type.nelements * sizeof(IOReportElement);
} while(0)

macroSIMPLEARRAY_UPDATERES

#define SIMPLEARRAY_UPDATERES(array_buf, action, result) do {
    IOReportElement     *__elem;
    int *__nElements = (int *)(result);
    __elem = &(((IOReportElement *)(array_buf))[0]);
    if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
    if (os_add_overflow(*__nElements, __elem->channel_type.nelements, __nElements)) {
	*__nElements = INT_MAX;
    }
    }
} while (0)

macroSIMPLEARRAY_GETCHID

Get the 64-bit channel ID of a SimpleArrayReport. void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
#define SIMPLEARRAY_GETCHID(array_buf) (((IOReportElement *)(array_buf))->channel_id)

macroSIMPLEARRAY_GETCHTYPE

Get the IOReportChannelType of a SimpleArrayReport. void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
#define SIMPLEARRAY_GETCHTYPE(array_buf) (*(uint64_t*)&(((IOReportElement *)(array_buf))->channel_type))

macroSIMPLEARRAY_GETVALUE

Get a value from a SimpleArrayReport. void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT() unsigned idx - index of the value, out of bounds -> kIOReportInvalidValue
#define SIMPLEARRAY_GETVALUE(array_buf, idx) (((idx) > __SA_MAXINDEX(array_buf) || (idx) < 0) ? kIOReportInvalidIntValue :
    ((IOSimpleArrayReportValues*)&(
	((IOReportElement*)(array_buf))[(idx) / IOR_VALUES_PER_ELEMENT].values))
	    ->simple_values[(idx) % IOR_VALUES_PER_ELEMENT])

structIOHistReportInfo

Internal struct for HistogramReport
size 4, align 4
intbucketWidth
IOReportElement[]elemArray of elements

typedefIOHistReportInfo

typedef struct IOHistReportInfo IOHistReportInfo;

macroHISTREPORT_BUFSIZE

Determine the size required for a HistogramReport buffer. int nbuckets - number of buckets in the histogram
#define HISTREPORT_BUFSIZE(nbuckets) (sizeof(IOHistReportInfo) + ((nbuckets) * sizeof(IOReportElement)))

macroHISTREPORT_INIT

Initialize a HistogramReport buffer. Supports only linear scale histogram. uint16_t nbuckets - number of buckets data is combined into uint32_t bucketWidth - size of each bucket void* buffer - ptr to HISTREPORT_BUFSIZE(nbuckets) bytes size_t bufSize - sanity check of buffer's size uint64_t providerID - registry Entry ID of the reporting service uint64_t channelID - ID of this channel, see IOREPORT_MAKEID() IOReportCategories categories - categories of this channel If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT. If that returns, the buffer is left full of '&'.
#define HISTREPORT_INIT(nbuckets, bktSize, buf, bufSize, providerID, channelID, cats) do {
    memset((buf), '&', (bufSize));
    IOHistReportInfo   *__info = (IOHistReportInfo *)(buf);
    IOReportElement         *__elem;
    IOHistogramReportValues *__rep;
    if ((bufSize) >= HISTREPORT_BUFSIZE(nbuckets)) {
	__info->bucketWidth = (bktSize);
	for (uint16_t __no = 0; __no < (nbuckets); __no++) {
	    __elem =  &(__info->elem[__no]);
	    __rep = (IOHistogramReportValues *) &(__elem->values);
	    __elem->provider_id = (providerID);
	    __elem->channel_id = (channelID);
	    __elem->channel_type.report_format = kIOReportFormatHistogram;
	    __elem->channel_type.reserved = 0;
	    __elem->channel_type.categories = (cats);
	    __elem->channel_type.nelements = (nbuckets);
	    __elem->channel_type.element_idx = __no;
	    __elem->timestamp = 0;
	    memset(__rep, '\0', sizeof(IOHistogramReportValues));
	}
    }
    else {
	IOREPORT_ABORT("bufSize is smaller than the required size\n");
    }
} while (0)

macroHISTREPORT_TALLYVALUE

Update histogram with a new value. void* hist_buf - pointer to memory initialized by HISTREPORT_INIT() int64_t value - new value to add to the histogram
#define HISTREPORT_TALLYVALUE(hist_buf, value) do {
    IOHistReportInfo   *__info = (IOHistReportInfo *)(hist_buf);
    IOReportElement         *__elem;
    IOHistogramReportValues *__rep;
    for (unsigned __no = 0; __no < __info->elem[0].channel_type.nelements; __no++) {
	if ((value) <= __info->bucketWidth * (__no+1)) {
	    __elem =  &(__info->elem[__no]);
	    __rep = (IOHistogramReportValues *) &(__elem->values);
	    if (__rep->bucket_hits == 0) {
	        __rep->bucket_min = __rep->bucket_max = (value);
	    }
	    else if ((value) < __rep->bucket_min) {
	        __rep->bucket_min = (value);
	    }
	    else if ((value) > __rep->bucket_max) {
	        __rep->bucket_max = (value);
	    }
	int64_t __sum = 0;
	if (os_add_overflow(__rep->bucket_sum, (value), &__sum)) {
	    __rep->bucket_sum = INT64_MAX;
	} else {
	    __rep->bucket_sum = __sum;
	}
	    __rep->bucket_hits++;
	    break;
	}
    }
} while (0)

macroHISTREPORT_UPDATEPREP

#define HISTREPORT_UPDATEPREP(hist_buf, ptr2cpy, size2cpy) do {
    IOHistReportInfo   *__info = (IOHistReportInfo *)(hist_buf);
    (size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement);
    (ptr2cpy) =  (void *) &__info->elem[0];
} while(0)

macroHISTREPORT_UPDATERES

#define HISTREPORT_UPDATERES(hist_buf, action, result) do {
    IOHistReportInfo   *__info = (IOHistReportInfo *)(hist_buf);
    int *__nElements = (int *)(result);
    if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
	if (os_add_overflow(*__nElements, __info->elem[0].channel_type.nelements, __nElements)) {
	    *__nElements = INT_MAX;
	}
    }
} while (0)

macroHISTREPORT_GETCHID

Get the 64-bit channel ID of a HistogramReport. void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
#define HISTREPORT_GETCHID(hist_buf) (((IOHistReportInfo *)(hist_buf))->elem[0].channel_id)

macroHISTREPORT_GETCHTYPE

Get the IOReportChannelType of a HistogramReport. void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
#define HISTREPORT_GETCHTYPE(hist_buf) (*(uint64_t*)&(((IOHistReportInfo *)(hist_buf))->elem[0].channel_type))