1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for more
24 * This file defines the DiagChannel protocol. This protocol is used to aid in
25 * preserving event data sent by external applications. This protocol provides
26 * a region for event data to reside in. This data will eventually be sent to
27 * the Boot Partition where it will be committed to memory and/or disk. This
28 * file contains platform-independent data that can be built using any
29 * Supervisor build environment (Windows, Linux, EFI).
33 #ifndef _DIAG_CHANNEL_H_
34 #define _DIAG_CHANNEL_H_
36 #include <linux/uuid.h>
39 /* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */
40 #define ULTRA_DIAG_CHANNEL_PROTOCOL_GUID \
41 UUID_LE(0xeea7a573, 0xdb82, 0x447c, \
42 0x87, 0x16, 0xef, 0xbe, 0xaa, 0xae, 0x48, 0x58)
44 static const uuid_le UltraDiagChannelProtocolGuid =
45 ULTRA_DIAG_CHANNEL_PROTOCOL_GUID;
47 /* {E850F968-3263-4484-8CA5-2A35D087A5A8} */
48 #define ULTRA_DIAG_ROOT_CHANNEL_PROTOCOL_GUID \
49 UUID_LE(0xe850f968, 0x3263, 0x4484, \
50 0x8c, 0xa5, 0x2a, 0x35, 0xd0, 0x87, 0xa5, 0xa8)
52 #define ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
54 /* Must increment this whenever you insert or delete fields within this channel
55 * struct. Also increment whenever you change the meaning of fields within this
56 * channel struct so as to break pre-existing software. Note that you can
57 * usually add fields to the END of the channel struct withOUT needing to
59 #define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2
61 #define ULTRA_DIAG_CHANNEL_OK_CLIENT(pChannel, logCtx) \
62 (ULTRA_check_channel_client(pChannel, \
63 UltraDiagChannelProtocolGuid, \
65 sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \
66 ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \
67 ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE, \
68 __FILE__, __LINE__, logCtx))
69 #define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes, logCtx) \
70 (ULTRA_check_channel_server(UltraDiagChannelProtocolGuid, \
72 sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \
73 actualBytes, __FILE__, __LINE__, logCtx))
74 #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */
75 #define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info
76 * accompanying event... */
77 #define MAX_SUBSYSTEMS 64 /* Maximum number of subsystems allowed in
79 #define LOW_SUBSYSTEMS 32 /* Half of MAX_SUBSYSTEMS to allow 64-bit
81 #define SUBSYSTEM_DEBUG 0 /* Standard subsystem for debug events */
82 #define SUBSYSTEM_DEFAULT 1 /* Default subsystem for legacy calls to
85 /* few useful subsystem mask values */
86 #define SUBSYSTEM_MASK_DEBUG 0x01 /* Standard subsystem for debug
88 #define SUBSYSTEM_MASK_DEFAULT 0x02 /* Default subsystem for legacy calls to
91 /* Event parameter "Severity" is overloaded with Cause in byte 2 and Severity in
92 * byte 0, bytes 1 and 3 are reserved */
93 #define SEVERITY_MASK 0x0FF /* mask out all but the Severity in byte 0 */
94 #define CAUSE_MASK 0x0FF0000 /* mask out all but the cause in byte 2 */
95 #define CAUSE_SHIFT_AMT 16 /* shift 2 bytes to place it in byte 2 */
97 /* SubsystemSeverityFilter */
98 #define SEVERITY_FILTER_MASK 0x0F /* mask out the Cause half, SeverityFilter is
99 * in the lower nibble */
100 #define CAUSE_FILTER_MASK 0xF0 /* mask out the Severity half, CauseFilter is in
101 * the upper nibble */
102 #define CAUSE_FILTER_SHIFT_AMT 4 /* shift amount to place it in lower or upper
105 /* Copied from EFI's EFI_TIME struct in efidef.h. EFI headers are not allowed
106 * in some of the Supervisor areas, such as Monitor, so it has been "ported" here
107 * for use in diagnostic event timestamps... */
108 typedef struct _DIAG_EFI_TIME {
109 u16 Year; /* 1998 - 20XX */
110 u8 Month; /* 1 - 12 */
112 u8 Hour; /* 0 - 23 */
113 u8 Minute; /* 0 - 59 */
114 u8 Second; /* 0 - 59 */
116 u32 Nanosecond; /* 0 - 999, 999, 999 */
117 s16 TimeZone; /* -1440 to 1440 or 2047 */
123 ULTRA_COMPONENT_GUEST = 0,
124 ULTRA_COMPONENT_MONITOR = 0x01,
125 ULTRA_COMPONENT_CCM = 0x02, /* Common Control module */
126 /* RESERVED 0x03 - 0x7 */
128 /* Ultravisor Components */
129 ULTRA_COMPONENT_BOOT = 0x08,
130 ULTRA_COMPONENT_IDLE = 0x09,
131 ULTRA_COMPONENT_CONTROL = 0x0A,
132 ULTRA_COMPONENT_LOGGER = 0x0B,
133 ULTRA_COMPONENT_ACPI = 0X0C,
134 /* RESERVED 0x0D - 0x0F */
136 /* sPAR Components */
137 ULTRA_COMPONENT_COMMAND = 0x10,
138 ULTRA_COMPONENT_IODRIVER = 0x11,
139 ULTRA_COMPONENT_CONSOLE = 0x12,
140 ULTRA_COMPONENT_OPERATIONS = 0x13,
141 ULTRA_COMPONENT_MANAGEMENT = 0x14,
142 ULTRA_COMPONENT_DIAG = 0x15,
143 ULTRA_COMPONENT_HWDIAG = 0x16,
144 ULTRA_COMPONENT_PSERVICES = 0x17,
145 ULTRA_COMPONENT_PDIAG = 0x18
146 /* RESERVED 0x18 - 0x1F */
147 } ULTRA_COMPONENT_TYPES;
149 /* Structure: DIAG_CHANNEL_EVENT Purpose: Contains attributes that make up an
150 * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of
151 * the diagnostic event to write to memory. Severity: Severity of the event
152 * (Error, Info, etc). ModuleName: Module/file name where event originated.
153 * LineNumber: Line number in module name where event originated. Timestamp:
154 * Date/time when event was received by ReportEvent, and written to DiagChannel.
155 * Reserved: Padding to align structure on a 64-byte cache line boundary.
156 * AdditionalInfo: Array of characters for additional event info (may be
158 typedef struct _DIAG_CHANNEL_EVENT {
161 u8 ModuleName[MAX_MODULE_NAME_SIZE];
163 DIAG_EFI_TIME Timestamp; /* Size = 16 bytes */
164 u32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are
166 u16 VirtualProcessorNumber;
167 u16 LogicalProcessorNumber;
168 u8 ComponentType; /* ULTRA_COMPONENT_TYPES */
170 u16 Reserved0; /* pad to u64 alignment */
171 u32 BlockNumber; /* filled in by DiagSwitch as pool blocks are
174 u32 EventNumber; /* filled in by DiagSwitch as pool blocks are
178 /* The BlockNumber and EventNumber fields are set only by DiagSwitch
179 * and referenced only by WinDiagDisplay formatting tool as
180 * additional diagnostic information. Other tools including
181 * WinDiagDisplay currently ignore these 'Reserved' bytes. */
183 u8 AdditionalInfo[MAX_ADDITIONAL_INFO_SIZE];
185 /* NOTE: Changesto DIAG_CHANNEL_EVENT generally need to be reflected in
188 * GuestLinux/visordiag_early/supervisor_diagchannel.h *
189 * - for WinDiagDisplay at
190 * EFI/Ultra/Tools/WinDiagDisplay/WinDiagDisplay/diagstruct.h */
191 } DIAG_CHANNEL_EVENT;
193 /* Levels of severity for diagnostic events, in order from lowest severity to
194 * highest (i.e. fatal errors are the most severe, and should always be logged,
195 * but info events rarely need to be logged except during debugging). The values
196 * DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid severity
197 * values. They exist merely to dilineate the list, so that future additions
198 * won't require changes to the driver (i.e. when checking for out-of-range
199 * severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE and
200 * DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events but
201 * they are valid for controlling the amount of event data. This enum is also
202 * defined in DotNet\sParFramework\ControlFramework\ControlFramework.cs. If a
203 * change is made to this enum, they should also be reflected in that file. */
204 typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0,
205 DIAG_SEVERITY_OVERRIDE = DIAG_SEVERITY_ENUM_BEGIN,
206 DIAG_SEVERITY_VERBOSE = DIAG_SEVERITY_OVERRIDE, /* 0 */
207 DIAG_SEVERITY_INFO = DIAG_SEVERITY_VERBOSE + 1, /* 1 */
208 DIAG_SEVERITY_WARNING = DIAG_SEVERITY_INFO + 1, /* 2 */
209 DIAG_SEVERITY_ERR = DIAG_SEVERITY_WARNING + 1, /* 3 */
210 DIAG_SEVERITY_PRINT = DIAG_SEVERITY_ERR + 1, /* 4 */
211 DIAG_SEVERITY_SHUTOFF = DIAG_SEVERITY_PRINT + 1, /* 5 */
212 DIAG_SEVERITY_ENUM_END = DIAG_SEVERITY_SHUTOFF, /* 5 */
213 DIAG_SEVERITY_NONFATAL_ERR = DIAG_SEVERITY_ERR,
214 DIAG_SEVERITY_FATAL_ERR = DIAG_SEVERITY_PRINT
219 * Levels of cause for diagnostic events, in order from least to greatest cause
220 * Internal errors are most urgent since ideally they should never exist
221 * Invalid requests are preventable by avoiding invalid inputs
222 * Operations errors depend on environmental factors which may impact which
223 * requests are possible
224 * Manifest provides intermediate value to capture firmware and configuration
225 * version information
226 * Trace provides suplimental debug information in release firmware
227 * Unknown Log captures unclasified LogEvent calls.
228 * Debug is the least urgent since it provides suplimental debug information only
230 * Unknown Debug captures unclassified DebugEvent calls.
231 * This enum is also defined in
232 * DotNet\sParFramework\ControlFramework\ControlFramework.cs.
233 * If a change is made to this enum, they should also be reflected in that
238 /* A cause value "DIAG_CAUSE_FILE_XFER" together with a severity value of
239 * "DIAG_SEVERITY_PRINT" (=4), is used for transferring text or binary file to
240 * the Diag partition. This cause-severity combination will be used by Logger
241 * DiagSwitch to segregate events into block types. The files are transferred in
242 * 256 byte chunks maximum, in the AdditionalInfo field of the DIAG_CHANNEL_EVENT
243 * structure. In the file transfer mode, some event fields will have different
244 * meaning: EventId specifies the file offset, severity specifies the block type,
245 * ModuleName specifies the filename, LineNumber specifies the number of valid
246 * data bytes in an event and AdditionalInfo contains up to 256 bytes of data. */
248 /* The Diag DiagWriter appends event blocks to events.raw as today, and for data
249 * blocks uses DIAG_CHANNEL_EVENT
250 * PartitionNumber to extract and append 'AdditionalInfo' to filename (specified
253 /* The Dell PDiag uses this new mechanism to stash DSET .zip onto the
254 * 'diagnostic' virtual disk. */
256 DIAG_CAUSE_UNKNOWN = 0,
257 DIAG_CAUSE_UNKNOWN_DEBUG = DIAG_CAUSE_UNKNOWN + 1, /* 1 */
258 DIAG_CAUSE_DEBUG = DIAG_CAUSE_UNKNOWN_DEBUG + 1, /* 2 */
259 DIAG_CAUSE_UNKNOWN_LOG = DIAG_CAUSE_DEBUG + 1, /* 3 */
260 DIAG_CAUSE_TRACE = DIAG_CAUSE_UNKNOWN_LOG + 1, /* 4 */
261 DIAG_CAUSE_MANIFEST = DIAG_CAUSE_TRACE + 1, /* 5 */
262 DIAG_CAUSE_OPERATIONS_ERROR = DIAG_CAUSE_MANIFEST + 1, /* 6 */
263 DIAG_CAUSE_INVALID_REQUEST = DIAG_CAUSE_OPERATIONS_ERROR + 1, /* 7 */
264 DIAG_CAUSE_INTERNAL_ERROR = DIAG_CAUSE_INVALID_REQUEST + 1, /* 8 */
265 DIAG_CAUSE_FILE_XFER = DIAG_CAUSE_INTERNAL_ERROR + 1, /* 9 */
266 DIAG_CAUSE_ENUM_END = DIAG_CAUSE_FILE_XFER /* 9 */
269 /* Event Cause category defined into the byte 2 of Severity */
270 #define CAUSE_DEBUG (DIAG_CAUSE_DEBUG << CAUSE_SHIFT_AMT)
271 #define CAUSE_TRACE (DIAG_CAUSE_TRACE << CAUSE_SHIFT_AMT)
272 #define CAUSE_MANIFEST (DIAG_CAUSE_MANIFEST << CAUSE_SHIFT_AMT)
273 #define CAUSE_OPERATIONS_ERROR (DIAG_CAUSE_OPERATIONS_ERROR << CAUSE_SHIFT_AMT)
274 #define CAUSE_INVALID_REQUEST (DIAG_CAUSE_INVALID_REQUEST << CAUSE_SHIFT_AMT)
275 #define CAUSE_INTERNAL_ERROR (DIAG_CAUSE_INTERNAL_ERROR << CAUSE_SHIFT_AMT)
276 #define CAUSE_FILE_XFER (DIAG_CAUSE_FILE_XFER << CAUSE_SHIFT_AMT)
277 #define CAUSE_ENUM_END CAUSE_FILE_XFER
279 /* Combine Cause and Severity categories into one */
280 #define CAUSE_DEBUG_SEVERITY_VERBOSE \
281 (CAUSE_DEBUG | DIAG_SEVERITY_VERBOSE)
282 #define CAUSE_TRACE_SEVERITY_VERBOSE \
283 (CAUSE_TRACE | DIAG_SEVERITY_VERBOSE)
284 #define CAUSE_MANIFEST_SEVERITY_VERBOSE\
285 (CAUSE_MANIFEST | DIAG_SEVERITY_VERBOSE)
286 #define CAUSE_OPERATIONS_SEVERITY_VERBOSE \
287 (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_VERBOSE)
288 #define CAUSE_INVALID_SEVERITY_VERBOSE \
289 (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_VERBOSE)
290 #define CAUSE_INTERNAL_SEVERITY_VERBOSE \
291 (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_VERBOSE)
293 #define CAUSE_DEBUG_SEVERITY_INFO \
294 (CAUSE_DEBUG | DIAG_SEVERITY_INFO)
295 #define CAUSE_TRACE_SEVERITY_INFO \
296 (CAUSE_TRACE | DIAG_SEVERITY_INFO)
297 #define CAUSE_MANIFEST_SEVERITY_INFO \
298 (CAUSE_MANIFEST | DIAG_SEVERITY_INFO)
299 #define CAUSE_OPERATIONS_SEVERITY_INFO \
300 (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_INFO)
301 #define CAUSE_INVALID_SEVERITY_INFO \
302 (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_INFO)
303 #define CAUSE_INTERNAL_SEVERITY_INFO \
304 (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_INFO)
306 #define CAUSE_DEBUG_SEVERITY_WARN \
307 (CAUSE_DEBUG | DIAG_SEVERITY_WARNING)
308 #define CAUSE_TRACE_SEVERITY_WARN \
309 (CAUSE_TRACE | DIAG_SEVERITY_WARNING)
310 #define CAUSE_MANIFEST_SEVERITY_WARN \
311 (CAUSE_MANIFEST | DIAG_SEVERITY_WARNING)
312 #define CAUSE_OPERATIONS_SEVERITY_WARN \
313 (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_WARNING)
314 #define CAUSE_INVALID_SEVERITY_WARN \
315 (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_WARNING)
316 #define CAUSE_INTERNAL_SEVERITY_WARN \
317 (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_WARNING)
319 #define CAUSE_DEBUG_SEVERITY_ERR \
320 (CAUSE_DEBUG | DIAG_SEVERITY_ERR)
321 #define CAUSE_TRACE_SEVERITY_ERR \
322 (CAUSE_TRACE | DIAG_SEVERITY_ERR)
323 #define CAUSE_MANIFEST_SEVERITY_ERR \
324 (CAUSE_MANIFEST | DIAG_SEVERITY_ERR)
325 #define CAUSE_OPERATIONS_SEVERITY_ERR \
326 (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_ERR)
327 #define CAUSE_INVALID_SEVERITY_ERR \
328 (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_ERR)
329 #define CAUSE_INTERNAL_SEVERITY_ERR \
330 (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_ERR)
332 #define CAUSE_DEBUG_SEVERITY_PRINT \
333 (CAUSE_DEBUG | DIAG_SEVERITY_PRINT)
334 #define CAUSE_TRACE_SEVERITY_PRINT \
335 (CAUSE_TRACE | DIAG_SEVERITY_PRINT)
336 #define CAUSE_MANIFEST_SEVERITY_PRINT \
337 (CAUSE_MANIFEST | DIAG_SEVERITY_PRINT)
338 #define CAUSE_OPERATIONS_SEVERITY_PRINT \
339 (CAUSE_OPERATIONS_ERROR | DIAG_SEVERITY_PRINT)
340 #define CAUSE_INVALID_SEVERITY_PRINT \
341 (CAUSE_INVALID_REQUEST | DIAG_SEVERITY_PRINT)
342 #define CAUSE_INTERNAL_SEVERITY_PRINT \
343 (CAUSE_INTERNAL_ERROR | DIAG_SEVERITY_PRINT)
344 #define CAUSE_FILE_XFER_SEVERITY_PRINT \
345 (CAUSE_FILE_XFER | DIAG_SEVERITY_PRINT)
347 /* Structure: DIAG_CHANNEL_PROTOCOL_HEADER
349 * Purpose: Contains attributes that make up the header specific to the
354 * DiagLock: Diag Channel spinlock.
356 *IsChannelInitialized: 1 iff SignalInit was called for this channel; otherwise
357 * 0, and assume the channel is not ready for use yet.
359 * Reserved: Padding to align the fields in this structure.
361 *SubsystemSeverityFilter: Level of severity on a subsystem basis that controls
362 * whether events are logged. Any event's severity for a
363 * particular subsystem below this level will be discarded.
365 typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER {
366 volatile u32 DiagLock;
367 u8 IsChannelInitialized;
369 u8 SubsystemSeverityFilter[64];
370 } DIAG_CHANNEL_PROTOCOL_HEADER;
372 /* The Diagram for the Diagnostic Channel: */
373 /* ----------------------- */
374 /* | Channel Header | Defined by ULTRA_CHANNEL_PROTOCOL */
375 /* ----------------------- */
376 /* | Signal Queue Header | Defined by SIGNAL_QUEUE_HEADER */
377 /* ----------------------- */
378 /* | DiagChannel Header | Defined by DIAG_CHANNEL_PROTOCOL_HEADER */
379 /* ----------------------- */
380 /* | Channel Event Info | Defined by (DIAG_CHANNEL_EVENT * MAX_EVENTS) */
381 /* ----------------------- */
382 /* | Reserved | Reserved (pad out to 4MB) */
383 /* ----------------------- */
385 /* Offsets/sizes for diagnostic channel attributes... */
386 #define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(ULTRA_CHANNEL_PROTOCOL))
387 #define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(SIGNAL_QUEUE_HEADER))
388 #define DIAG_CH_PROTOCOL_HEADER_OFFSET \
389 (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE)
390 #define DIAG_CH_PROTOCOL_HEADER_SIZE (sizeof(DIAG_CHANNEL_PROTOCOL_HEADER))
391 #define DIAG_CH_EVENT_OFFSET \
392 (DIAG_CH_PROTOCOL_HEADER_OFFSET + DIAG_CH_PROTOCOL_HEADER_SIZE)
393 #define DIAG_CH_SIZE (4096 * 1024)
395 /* For Control and Idle Partitions with larger (8 MB) diagnostic(root)
397 #define DIAG_CH_LRG_SIZE (2 * DIAG_CH_SIZE) /* 8 MB */
400 * Structure: ULTRA_DIAG_CHANNEL_PROTOCOL
402 * Purpose: Contains attributes that make up the DIAG_CHANNEL memory.
406 * CommonChannelHeader: Header info common to all channels.
408 * QueueHeader: Queue header common to all channels - used to determine where to
411 * DiagChannelHeader: Diagnostic channel header info (see
412 * DIAG_CHANNEL_PROTOCOL_HEADER comments).
414 * Events: Area where diagnostic events (up to MAX_EVENTS) are written.
416 *Reserved: Reserved area to allow for correct channel size padding.
418 typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL {
419 ULTRA_CHANNEL_PROTOCOL CommonChannelHeader;
420 SIGNAL_QUEUE_HEADER QueueHeader;
421 DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader;
422 DIAG_CHANNEL_EVENT Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) /
423 sizeof(DIAG_CHANNEL_EVENT)];
425 ULTRA_DIAG_CHANNEL_PROTOCOL;