1/*
2 * Copyright (c) 2012-2014 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _IOREPORT_TYPES_H_
30#define _IOREPORT_TYPES_H_
31
32#include <stdint.h>
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#define IOR_VALUES_PER_ELEMENT 4
39
40/*! @const kIOReportInvalidValue
41 * @const kIOReportInvalidIntValue
42 * @abstract cardinal value used to indicate data errors
43 *
44 * @discussion
45 * kIOReportInvalidValue and kIOReportInvalidIntValue have the
46 * same bit pattern so that clients checking for one or the other
47 * don't have to worry about getting the signedness right.
48 */
49#define kIOReportInvalidIntValue INT64_MIN
50#define kIOReportInvalidValue (uint64_t)kIOReportInvalidIntValue
51
52/*! @typedef IOReportCategories
53 * @abstract encapsulate important, multi-purpose "tags" for channels
54 *
55 * @discussion
56 * IOReportCategories is the type for the .categories field of
57 * IOReportChanelType. These categories are inteded to empower a
58 * limited number of clients to retrieve a broad range of channels
59 * without knowing much about them. They can be OR'd together as
60 * needed. Groups and subgroups are a more extensible mechanism
61 * for aggregating channels produced by different drivers.
62 */
63typedef uint16_t IOReportCategories;
64#define kIOReportCategoryPower (1 << 1) // and energy
65#define kIOReportCategoryTraffic (1 << 2) // I/O at any level
66#define kIOReportCategoryPerformance (1 << 3) // e.g. cycles/byte
67#define kIOReportCategoryPeripheral (1 << 4) // not built-in
68
69#define kIOReportCategoryField (1 << 8) // consider logging
70
71// future categories TBD
72#define kIOReportCategoryDebug (1 << 15)
73#define kIOReportInvalidCategory UINT16_MAX
74
75
76// IOReportChannelType.report_format
77typedef uint8_t IOReportFormat;
78enum {
79 kIOReportInvalidFormat = 0,
80 kIOReportFormatSimple = 1,
81 kIOReportFormatState = 2,
82 kIOReportFormatHistogram = 3,
83 kIOReportFormatSimpleArray = 4
84};
85
86// simple report values
87typedef struct {
88 int64_t simple_value;
89 uint64_t reserved1;
90 uint64_t reserved2;
91 uint64_t reserved3;
92} __attribute((packed)) IOSimpleReportValues;
93
94// simple value array
95typedef struct {
96 int64_t simple_values[IOR_VALUES_PER_ELEMENT];
97} __attribute((packed)) IOSimpleArrayReportValues;
98
99// state report values
100typedef struct {
101 uint64_t state_id; // 0..N-1 or 8-char code (see MAKEID())
102 uint64_t intransitions; // number of transitions into this state
103 uint64_t upticks; // ticks spent in state (local timebase)
104 uint64_t last_intransition;// ticks at last in-transition
105} __attribute((packed)) IOStateReportValues;
106
107// histogram report values
108typedef struct {
109 uint64_t bucket_hits;
110 int64_t bucket_min;
111 int64_t bucket_max;
112 int64_t bucket_sum;
113} __attribute((packed)) IOHistogramReportValues;
114
115
116
117// configuration actions generally change future behavior
118typedef uint32_t IOReportConfigureAction;
119enum {
120 // basics (in common operational order)
121 kIOReportEnable = 0x01,
122 kIOReportGetDimensions = 0x02,
123 kIOReportDisable = 0x00,
124
125 // Enable/disable modifiers
126 kIOReportNotifyHubOnChange = 0x10, // triggered polling
127
128 kIOReportTraceOnChange = 0x20 // kdebug.h tracing
129};
130
131// update actions should not have observable side effects
132typedef uint32_t IOReportUpdateAction;
133enum {
134 kIOReportCopyChannelData = 1,
135 kIOReportTraceChannelData = 2
136};
137
138typedef struct {
139 uint8_t report_format; // Histogram, StateResidency, etc.
140 uint8_t reserved; // must be zero
141 uint16_t categories; // power, traffic, etc (omnibus obs.)
142 uint16_t nelements; // internal size of channel
143
144 // only meaningful in the data pipeline
145 int16_t element_idx; // 0..nelements-1
146 // -1..-(nelements) = invalid (13127884)
147} __attribute((packed)) IOReportChannelType;
148
149/*!
150 * @define IOREPORT_MAKECHID
151 * @abstract convert up to 8 printable characters into a 64-bit channel ID
152 * @param <char0..char7> - printable chars to be packed into a channel ID
153 * @result a 64-bit channel ID with an implicit ASCII name
154 * @discussion A simple example:
155 * IOREPORT_MAKECHID('H', 'i', ' ', 'w', 'o', 'r', 'l', 'd');
156 * will evaluate to 0x686920776f726c64. Any NUL bytes are
157 * ignored (by libIOReport) for naming purposes, but will
158 * appear in the channel ID. Using a non-NUL non-printable
159 * character will disable the implicit name. Putting NUL
160 * bytes first eliminates trailing zeros when the channel
161 * ID is printed as hex. For example:
162 * IORERPORT_MAKECHID('\0','\0','n','x','f','e','r','s');
163 * To see the text, use xxd -r -p # not -rp; see 12976241
164 */
165#define __IOR_lshiftchr(c, chshift) ((uint64_t)(c) << (8*(chshift)))
166#define IOREPORT_MAKEID(A, B, C, D, E, F, G, H) \
167 (__IOR_lshiftchr(A, 7) | __IOR_lshiftchr(B, 6) | __IOR_lshiftchr(C, 5) \
168 | __IOR_lshiftchr(D, 4) | __IOR_lshiftchr(E, 3) | __IOR_lshiftchr(F, 2) \
169 | __IOR_lshiftchr(G, 1) | __IOR_lshiftchr(H, 0))
170
171typedef struct {
172 uint64_t channel_id;
173 IOReportChannelType channel_type;
174} IOReportChannel;
175
176typedef struct {
177 uint32_t nchannels;
178 IOReportChannel channels[];
179} IOReportChannelList;
180
181typedef struct {
182 uint64_t provider_id;
183 IOReportChannel channel;
184} IOReportInterest;
185
186typedef struct {
187 uint32_t ninterests;
188 IOReportInterest interests[];
189} IOReportInterestList;
190
191typedef struct {
192 uint64_t v[IOR_VALUES_PER_ELEMENT];
193} __attribute((packed)) IOReportElementValues;
194
195typedef struct {
196 uint64_t provider_id;
197 uint64_t channel_id;
198 IOReportChannelType channel_type;
199 uint64_t timestamp;// mach_absolute_time()
200 IOReportElementValues values;
201} __attribute((packed)) IOReportElement;
202
203
204
205/*
206 * IOReporting unit type and constants
207 */
208
209// 1. Mechanism
210
211// Assume encoded units could be stored in binary format: don't
212// change existing values.
213
214typedef uint64_t IOReportUnit;
215typedef uint64_t IOReportUnits; // deprecated typo, please switch
216#define __IOR_MAKEUNIT(quantity, scale) \
217 (((IOReportUnit)quantity << 56) | (uint64_t)scale)
218#define IOREPORT_GETUNIT_QUANTITY(unit) \
219 ((IOReportQuantity)((uint64_t)unit >> 56) & 0xff)
220#define IOREPORT_GETUNIT_SCALE(unit) \
221 ((IOReportScaleFactor)unit & 0x00ffffffffffffff)
222
223// 8b quantity ID | 32b const val + 8b*2^10 + 8b*2^n | 8b cardinal | 8b unused
224typedef uint8_t IOReportQuantity; // SI "quantity" is what's measured
225typedef uint64_t IOReportScaleFactor;
226
227// See <http://en.wikipedia.org/wiki/SI_base_unit> for a list
228// of quantities and their symbols.
229enum {
230 // used by state reports, etc
231 kIOReportQuantityUndefined = 0,
232
233 kIOReportQuantityTime = 1,// Seconds
234 kIOReportQuantityPower = 2,// Watts
235 kIOReportQuantityEnergy = 3,// Joules
236 kIOReportQuantityCurrent = 4,// Amperes
237 kIOReportQuantityVoltage = 5,// Volts
238 kIOReportQuantityCapacitance = 6,// Farad
239 kIOReportQuantityInductance = 7,// Henry
240 kIOReportQuantityFrequency = 8,// Hertz
241 kIOReportQuantityData = 9,// bits/bytes (see scale)
242 kIOReportQuantityTemperature = 10,// Celsius (not Kelvin :)
243
244 kIOReportQuantityEventCount = 100,
245 kIOReportQuantityPacketCount = 101,
246 kIOReportQuantityCPUInstrs = 102
247};
248
249
250/* A number of units end up with both IEC (2^n) and SI (10^n) scale factors.
251 * For example, the "MB" of a 1.44 MB floppy or a 1024MHz clock. We
252 * thus support separate 2^n and 10^n factors. The exponent encoding
253 * scheme is modeled loosely on single-precision IEEE 754.
254 */
255#define kIOReportScaleConstMask 0x000000007fffffff // constant ("uint31")
256#define kIOReportScaleOneOver (1LL << 31) // 1/constant
257#define kIOReportExpBase (-127) // support base^(-n)
258#define kIOReportExpZeroOffset -(kIOReportExpBase) // max exponent = 128
259#define kIOReportScaleSIShift 32 // * 10^n
260#define kIOReportScaleSIMask 0x000000ff00000000
261#define kIOReportScaleIECShift 40 // * 2^n
262#define kIOReportScaleIECMask 0x0000ff0000000000
263#define kIOReportCardinalShift 48 // placeholders
264#define kIOReportCardinalMask 0x00ff000000000000
265
266
267/*
268 * Scales are described as a factor times unity:
269 * 1ms = kIOReportScaleMilli * s
270 *
271 * A value expressed in a scaled unit can be scaled to unity via
272 * multiplication by the constant:
273 * 100ms * kIOReportScaleMilli [1e-3] = 0.1s.
274 */
275
276// SI / decimal
277#define kIOReportScalePico ((-12LL + kIOReportExpZeroOffset) \
278 << kIOReportScaleSIShift)
279#define kIOReportScaleNano ((-9LL + kIOReportExpZeroOffset) \
280 << kIOReportScaleSIShift)
281#define kIOReportScaleMicro ((-6LL + kIOReportExpZeroOffset) \
282 << kIOReportScaleSIShift)
283#define kIOReportScaleMilli ((-3LL + kIOReportExpZeroOffset) \
284 << kIOReportScaleSIShift)
285#define kIOReportScaleUnity 0 // 10^0 = 2^0 = 1
286// unity = 0 is a special case for which we give up exp = -127
287#define kIOReportScaleKilo ((3LL + kIOReportExpZeroOffset) \
288 << kIOReportScaleSIShift)
289#define kIOReportScaleMega ((6LL + kIOReportExpZeroOffset) \
290 << kIOReportScaleSIShift)
291#define kIOReportScaleGiga ((9LL + kIOReportExpZeroOffset) \
292 << kIOReportScaleSIShift)
293#define kIOReportScaleTera ((12LL + kIOReportExpZeroOffset) \
294 << kIOReportScaleSIShift)
295
296// IEC / computer / binary
297// It's not clear we'll ever use 2^(-n), but 1..2^~120 should suffice.
298#define kIOReportScaleBits kIOReportScaleUnity
299#define kIOReportScaleBytes ((3LL + kIOReportExpZeroOffset) \
300 << kIOReportScaleIECShift)
301// (bytes have to be added to the exponents up front, can't just OR in)
302#define kIOReportScaleKibi ((10LL + kIOReportExpZeroOffset) \
303 << kIOReportScaleIECShift)
304#define kIOReportScaleKiBytes ((13LL + kIOReportExpZeroOffset) \
305 << kIOReportScaleIECShift)
306#define kIOReportScaleMebi ((20LL + kIOReportExpZeroOffset) \
307 << kIOReportScaleIECShift)
308#define kIOReportScaleMiBytes ((23LL + kIOReportExpZeroOffset) \
309 << kIOReportScaleIECShift)
310#define kIOReportScaleGibi ((30LL + kIOReportExpZeroOffset) \
311 << kIOReportScaleIECShift)
312#define kIOReportScaleGiBytes ((33LL + kIOReportExpZeroOffset) \
313 << kIOReportScaleIECShift)
314#define kIOReportScaleTebi ((40LL + kIOReportExpZeroOffset) \
315 << kIOReportScaleIECShift)
316#define kIOReportScaleTiBytes ((43LL + kIOReportExpZeroOffset) \
317 << kIOReportScaleIECShift)
318// can't encode more than 2^125 (keeping bits & bytes inside -126..128)
319// Also, IOReportScaleValue() is currently limited internally by uint64_t.
320
321
322// Cardinal values, to be filled in appropriately.
323// Add values in increasing order.
324#define kIOReportScaleMachHWTicks (1LL << kIOReportCardinalShift)
325#define kIOReportScaleHWPageSize (2LL << kIOReportCardinalShift)
326
327// page scales: 2 pages * 4ikB/page = 8096 bytes
328#define kIOReportScale4KiB (4 | kIOReportScaleKiBytes)
329#define kIOReportScale8KiB (8 | kIOReportScaleKiBytes)
330#define kIOReportScale16KiB (16 | kIOReportScaleKiBytes)
331
332// Clock frequency scales (units add seconds).
333// 1 GHz ticks are 1 ns: 1000 ticks * 1e-6 = 1e-3s
334// This '1' is a no-op for scaling, but allows a custom label.
335#define kIOReportScale1GHz (1 | kIOReportScaleNano)
336// 24MHz ticks are 1/24 of a microsecond: (1/24 * kIOReportScaleMicro [1e-6])s
337// So for example, 240 24Mticks * 1/24 * 1e-6 = .00001s [1e-5]s
338#define kIOReportScale24MHz (kIOReportScaleOneOver|24 |kIOReportScaleMicro)
339
340// --- END: units mechanism
341
342
343// 2. Unit constants
344#define kIOReportUnitNone __IOR_MAKEUNIT(kIOReportQuantityUndefined, \
345 kIOReportScaleUnity)
346
347#define kIOReportUnit_s __IOR_MAKEUNIT(kIOReportQuantityTime, \
348 kIOReportScaleUnity)
349#define kIOReportUnit_ms __IOR_MAKEUNIT(kIOReportQuantityTime, \
350 kIOReportScaleMilli)
351#define kIOReportUnit_us __IOR_MAKEUNIT(kIOReportQuantityTime, \
352 kIOReportScaleMicro)
353#define kIOReportUnit_ns __IOR_MAKEUNIT(kIOReportQuantityTime, \
354 kIOReportScaleNano)
355
356#define kIOReportUnit_J __IOR_MAKEUNIT(kIOReportQuantityEnergy, \
357 kIOReportScaleUnity)
358#define kIOReportUnit_mJ __IOR_MAKEUNIT(kIOReportQuantityEnergy, \
359 kIOReportScaleMilli)
360#define kIOReportUnit_uJ __IOR_MAKEUNIT(kIOReportQuantityEnergy, \
361 kIOReportScaleMicro)
362#define kIOReportUnit_nJ __IOR_MAKEUNIT(kIOReportQuantityEnergy, \
363 kIOReportScaleNano)
364#define kIOReportUnit_pJ __IOR_MAKEUNIT(kIOReportQuantityEnergy, \
365 kIOReportScalePico)
366
367#define kIOReportUnitHWTicks __IOR_MAKEUNIT(kIOReportQuantityTime, \
368 kIOReportScaleMachHWTicks)
369#define kIOReportUnit24MHzTicks __IOR_MAKEUNIT(kIOReportQuantityTime, \
370 kIOReportScale24MHz)
371#define kIOReportUnit1GHzTicks __IOR_MAKEUNIT(kIOReportQuantityTime, \
372 kIOReportScale1GHz)
373
374#define kIOReportUnitBits __IOR_MAKEUNIT(kIOReportQuantityData, \
375 kIOReportScaleBits)
376#define kIOReportUnitBytes __IOR_MAKEUNIT(kIOReportQuantityData, \
377 kIOReportScaleBytes)
378#define kIOReportUnit_KiB __IOR_MAKEUNIT(kIOReportQuantityData, \
379 kIOReportScaleKiBytes)
380#define kIOReportUnit_MiB __IOR_MAKEUNIT(kIOReportQuantityData, \
381 kIOReportScaleMiBytes)
382#define kIOReportUnit_GiB __IOR_MAKEUNIT(kIOReportQuantityData, \
383 kIOReportScaleGiBytes)
384#define kIOReportUnit_TiB __IOR_MAKEUNIT(kIOReportQuantityData, \
385 kIOReportScaleTiBytes)
386
387#define kIOReportUnitEvents __IOR_MAKEUNIT(kIOReportQuantityEventCount, \
388 kIOReportScaleUnity)
389
390#define kIOReportUnitPackets __IOR_MAKEUNIT(kIOReportQuantityPacketCount, \
391 kIOReportScaleUnity)
392
393#define kIOReportUnitInstrs __IOR_MAKEUNIT(kIOReportQuantityCPUInstrs, \
394 kIOReportScaleUnity)
395#define kIOReportUnit_KI __IOR_MAKEUNIT(kIOReportQuantityCPUInstrs, \
396 kIOReportScaleKilo)
397#define kIOReportUnit_MI __IOR_MAKEUNIT(kIOReportQuantityCPUInstrs, \
398 kIOReportScaleMega)
399#define kIOReportUnit_GI __IOR_MAKEUNIT(kIOReportQuantityCPUInstrs, \
400 kIOReportScaleGiga)
401
402// Please file bugs (xnu | IOReporting) for additional units.
403
404// --- END: unit constants
405
406
407#ifdef __cplusplus
408}
409#endif
410
411#endif // _IOREPORT_TYPES_H_
412