1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION 2 * All rights reserved. 3 * 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. 8 * 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 13 * details. 14 */ 15 16 /*++ 17 * 18 * Module Name: 19 * 20 * diagchannel.h 21 * 22 * Abstract: 23 * 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). 30 * 31 */ 32 33 #ifndef _DIAG_CHANNEL_H_ 34 #define _DIAG_CHANNEL_H_ 35 36 #include <linux/uuid.h> 37 #include "channel.h" 38 39 /* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */ 40 #define SPAR_DIAG_CHANNEL_PROTOCOL_UUID \ 41 UUID_LE(0xeea7a573, 0xdb82, 0x447c, \ 42 0x87, 0x16, 0xef, 0xbe, 0xaa, 0xae, 0x48, 0x58) 43 44 static const uuid_le spar_diag_channel_protocol_uuid = 45 SPAR_DIAG_CHANNEL_PROTOCOL_UUID; 46 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) 51 52 #define ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE 53 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 58 * increment this. */ 59 #define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2 60 61 #define SPAR_DIAG_CHANNEL_OK_CLIENT(ch)\ 62 (spar_check_channel_client(ch,\ 63 spar_diag_channel_protocol_uuid,\ 64 "diag",\ 65 sizeof(struct spar_diag_channel_protocol),\ 66 ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ 67 ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) 68 69 #define SPAR_DIAG_CHANNEL_OK_SERVER(bytes)\ 70 (spar_check_channel_server(spar_diag_channel_protocol_uuid,\ 71 "diag",\ 72 sizeof(struct spar_diag_channel_protocol),\ 73 bytes)) 74 75 #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ 76 #define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info 77 * accompanying event... */ 78 #define MAX_SUBSYSTEMS 64 /* Maximum number of subsystems allowed in 79 * DiagChannel... */ 80 #define LOW_SUBSYSTEMS 32 /* Half of MAX_SUBSYSTEMS to allow 64-bit 81 * math */ 82 #define SUBSYSTEM_DEBUG 0 /* Standard subsystem for debug events */ 83 #define SUBSYSTEM_DEFAULT 1 /* Default subsystem for legacy calls to 84 * ReportEvent */ 85 86 /* few useful subsystem mask values */ 87 #define SUBSYSTEM_MASK_DEBUG 0x01 /* Standard subsystem for debug 88 * events */ 89 #define SUBSYSTEM_MASK_DEFAULT 0x02 /* Default subsystem for legacy calls to 90 * ReportEvents */ 91 92 /* Event parameter "Severity" is overloaded with Cause in byte 2 and Severity in 93 * byte 0, bytes 1 and 3 are reserved */ 94 #define SEVERITY_MASK 0x0FF /* mask out all but the Severity in byte 0 */ 95 #define CAUSE_MASK 0x0FF0000 /* mask out all but the cause in byte 2 */ 96 #define CAUSE_SHIFT_AMT 16 /* shift 2 bytes to place it in byte 2 */ 97 98 /* SubsystemSeverityFilter */ 99 #define SEVERITY_FILTER_MASK 0x0F /* mask out the Cause half, SeverityFilter is 100 * in the lower nibble */ 101 #define CAUSE_FILTER_MASK 0xF0 /* mask out the Severity half, CauseFilter is in 102 * the upper nibble */ 103 #define CAUSE_FILTER_SHIFT_AMT 4 /* shift amount to place it in lower or upper 104 * nibble */ 105 106 /* Copied from EFI's EFI_TIME struct in efidef.h. EFI headers are not allowed 107 * in some of the Supervisor areas, such as Monitor, so it has been "ported" here 108 * for use in diagnostic event timestamps... */ 109 struct diag_efi_time { 110 u16 year; /* 1998 - 20XX */ 111 u8 month; /* 1 - 12 */ 112 u8 day; /* 1 - 31 */ 113 u8 hour; /* 0 - 23 */ 114 u8 minute; /* 0 - 59 */ 115 u8 second; /* 0 - 59 */ 116 u8 pad1; 117 u32 nanosecond; /* 0 - 999, 999, 999 */ 118 s16 timezone; /* -1440 to 1440 or 2047 */ 119 u8 daylight; 120 u8 pad2; 121 }; 122 123 enum spar_component_types { 124 ULTRA_COMPONENT_GUEST = 0, 125 ULTRA_COMPONENT_MONITOR = 0x01, 126 ULTRA_COMPONENT_CCM = 0x02, /* Common Control module */ 127 /* RESERVED 0x03 - 0x7 */ 128 129 /* Ultravisor Components */ 130 ULTRA_COMPONENT_BOOT = 0x08, 131 ULTRA_COMPONENT_IDLE = 0x09, 132 ULTRA_COMPONENT_CONTROL = 0x0A, 133 ULTRA_COMPONENT_LOGGER = 0x0B, 134 ULTRA_COMPONENT_ACPI = 0X0C, 135 /* RESERVED 0x0D - 0x0F */ 136 137 /* sPAR Components */ 138 ULTRA_COMPONENT_COMMAND = 0x10, 139 ULTRA_COMPONENT_IODRIVER = 0x11, 140 ULTRA_COMPONENT_CONSOLE = 0x12, 141 ULTRA_COMPONENT_OPERATIONS = 0x13, 142 ULTRA_COMPONENT_MANAGEMENT = 0x14, 143 ULTRA_COMPONENT_DIAG = 0x15, 144 ULTRA_COMPONENT_HWDIAG = 0x16, 145 ULTRA_COMPONENT_PSERVICES = 0x17, 146 ULTRA_COMPONENT_PDIAG = 0x18 147 /* RESERVED 0x18 - 0x1F */ 148 }; 149 150 /* Structure: diag_channel_event Purpose: Contains attributes that make up an 151 * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of 152 * the diagnostic event to write to memory. Severity: Severity of the event 153 * (Error, Info, etc). ModuleName: Module/file name where event originated. 154 * LineNumber: Line number in module name where event originated. Timestamp: 155 * Date/time when event was received by ReportEvent, and written to DiagChannel. 156 * Reserved: Padding to align structure on a 64-byte cache line boundary. 157 * AdditionalInfo: Array of characters for additional event info (may be 158 * empty). */ 159 struct diag_channel_event { 160 u32 event_id; 161 u32 severity; 162 u8 module_name[MAX_MODULE_NAME_SIZE]; 163 u32 line_number; 164 struct diag_efi_time timestamp; /* Size = 16 bytes */ 165 u32 partition_number; /* Filled in by Diag Switch as pool blocks are 166 * filled */ 167 u16 vcpu_number; 168 u16 lcpu_number; 169 u8 component_type; /* ULTRA_COMPONENT_TYPES */ 170 u8 subsystem; 171 u16 reserved0; /* pad to u64 alignment */ 172 u32 block_no; /* filled in by DiagSwitch as pool blocks are 173 * filled */ 174 u32 block_no_high; 175 u32 event_no; /* filled in by DiagSwitch as pool blocks are 176 * filled */ 177 u32 event_no_high; 178 179 /* The block_no and event_no fields are set only by DiagSwitch 180 * and referenced only by WinDiagDisplay formatting tool as 181 * additional diagnostic information. Other tools including 182 * WinDiagDisplay currently ignore these 'Reserved' bytes. */ 183 u8 reserved[8]; 184 u8 additional_info[MAX_ADDITIONAL_INFO_SIZE]; 185 186 /* NOTE: Changes to diag_channel_event generally need to be reflected in 187 * existing copies * 188 * - for AppOS at 189 * GuestLinux/visordiag_early/supervisor_diagchannel.h * 190 * - for WinDiagDisplay at 191 * EFI/Ultra/Tools/WinDiagDisplay/WinDiagDisplay/diagstruct.h */ 192 }; 193 194 /* Levels of severity for diagnostic events, in order from lowest severity to 195 * highest (i.e. fatal errors are the most severe, and should always be logged, 196 * but info events rarely need to be logged except during debugging). The values 197 * DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid severity 198 * values. They exist merely to dilineate the list, so that future additions 199 * won't require changes to the driver (i.e. when checking for out-of-range 200 * severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE and 201 * DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events but 202 * they are valid for controlling the amount of event data. This enum is also 203 * defined in DotNet\sParFramework\ControlFramework\ControlFramework.cs. If a 204 * change is made to this enum, they should also be reflected in that file. */ 205 enum diag_severity { 206 DIAG_SEVERITY_ENUM_BEGIN = 0, 207 DIAG_SEVERITY_OVERRIDE = DIAG_SEVERITY_ENUM_BEGIN, 208 DIAG_SEVERITY_VERBOSE = DIAG_SEVERITY_OVERRIDE, /* 0 */ 209 DIAG_SEVERITY_INFO = DIAG_SEVERITY_VERBOSE + 1, /* 1 */ 210 DIAG_SEVERITY_WARNING = DIAG_SEVERITY_INFO + 1, /* 2 */ 211 DIAG_SEVERITY_ERR = DIAG_SEVERITY_WARNING + 1, /* 3 */ 212 DIAG_SEVERITY_PRINT = DIAG_SEVERITY_ERR + 1, /* 4 */ 213 DIAG_SEVERITY_SHUTOFF = DIAG_SEVERITY_PRINT + 1, /* 5 */ 214 DIAG_SEVERITY_ENUM_END = DIAG_SEVERITY_SHUTOFF, /* 5 */ 215 DIAG_SEVERITY_NONFATAL_ERR = DIAG_SEVERITY_ERR, 216 DIAG_SEVERITY_FATAL_ERR = DIAG_SEVERITY_PRINT 217 }; 218 219 /* Event Cause enums 220 * 221 * Levels of cause for diagnostic events, in order from least to greatest cause 222 * Internal errors are most urgent since ideally they should never exist 223 * Invalid requests are preventable by avoiding invalid inputs 224 * Operations errors depend on environmental factors which may impact which 225 * requests are possible 226 * Manifest provides intermediate value to capture firmware and configuration 227 * version information 228 * Trace provides suplimental debug information in release firmware 229 * Unknown Log captures unclasified LogEvent calls. 230 * Debug is the least urgent since it provides suplimental debug information only 231 * in debug firmware 232 * Unknown Debug captures unclassified DebugEvent calls. 233 * This enum is also defined in 234 * DotNet\sParFramework\ControlFramework\ControlFramework.cs. 235 * If a change is made to this enum, they should also be reflected in that 236 * file. */ 237 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. */ 247 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 251 * by ModuleName). */ 252 253 /* The Dell PDiag uses this new mechanism to stash DSET .zip onto the 254 * 'diagnostic' virtual disk. */ 255 enum diag_cause { 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 */ 267 }; 268 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 278 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) 292 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) 305 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) 318 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) 331 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) 346 347 /* Structure: diag_channel_protocol_header 348 * 349 * Purpose: Contains attributes that make up the header specific to the 350 * DIAG_CHANNEL area. 351 * 352 * Attributes: 353 * 354 * DiagLock: Diag Channel spinlock. 355 * 356 *IsChannelInitialized: 1 iff SignalInit was called for this channel; otherwise 357 * 0, and assume the channel is not ready for use yet. 358 * 359 * Reserved: Padding to align the fields in this structure. 360 * 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. 364 */ 365 struct diag_channel_protocol_header { 366 u32 diag_lock; 367 u8 channel_initialized; 368 u8 reserved[3]; 369 u8 subsystem_severity_filter[64]; 370 }; 371 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 /* ----------------------- */ 384 385 /* Offsets/sizes for diagnostic channel attributes... */ 386 #define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(struct channel_header)) 387 #define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(struct 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 \ 391 (sizeof(struct diag_channel_protocol_header)) 392 #define DIAG_CH_EVENT_OFFSET \ 393 (DIAG_CH_PROTOCOL_HEADER_OFFSET + DIAG_CH_PROTOCOL_HEADER_SIZE) 394 #define DIAG_CH_SIZE (4096 * 1024) 395 396 /* For Control and Idle Partitions with larger (8 MB) diagnostic(root) 397 * channels */ 398 #define DIAG_CH_LRG_SIZE (2 * DIAG_CH_SIZE) /* 8 MB */ 399 400 /* 401 * Structure: spar_diag_channel_protocol 402 * 403 * Purpose: Contains attributes that make up the DIAG_CHANNEL memory. 404 * 405 * Attributes: 406 * 407 * CommonChannelHeader: Header info common to all channels. 408 * 409 * QueueHeader: Queue header common to all channels - used to determine where to 410 * store event. 411 * 412 * DiagChannelHeader: Diagnostic channel header info (see 413 * diag_channel_protocol_header comments). 414 * 415 * Events: Area where diagnostic events (up to MAX_EVENTS) are written. 416 * 417 *Reserved: Reserved area to allow for correct channel size padding. 418 */ 419 struct spar_diag_channel_protocol { 420 struct channel_header common_channel_header; 421 struct signal_queue_header queue_header; 422 struct diag_channel_protocol_header diag_channel_header; 423 struct diag_channel_event events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / 424 sizeof(struct diag_channel_event)]; 425 }; 426 427 #endif 428