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