1d7b84ddcSIra Weiny /* 2d7b84ddcSIra Weiny * QEMU CXL Events 3d7b84ddcSIra Weiny * 4d7b84ddcSIra Weiny * Copyright (c) 2022 Intel 5d7b84ddcSIra Weiny * 6d7b84ddcSIra Weiny * This work is licensed under the terms of the GNU GPL, version 2. See the 7d7b84ddcSIra Weiny * COPYING file in the top-level directory. 8d7b84ddcSIra Weiny */ 9d7b84ddcSIra Weiny 10d7b84ddcSIra Weiny #ifndef CXL_EVENTS_H 11d7b84ddcSIra Weiny #define CXL_EVENTS_H 12d7b84ddcSIra Weiny 1322d7e3beSIra Weiny #include "qemu/uuid.h" 1422d7e3beSIra Weiny 15d7b84ddcSIra Weiny /* 168700ee15SJonathan Cameron * CXL r3.1 section 8.2.9.2.2: Get Event Records (Opcode 0100h); Table 8-52 17d7b84ddcSIra Weiny * 18d7b84ddcSIra Weiny * Define these as the bit position for the event status register for ease of 19d7b84ddcSIra Weiny * setting the status. 20d7b84ddcSIra Weiny */ 21d7b84ddcSIra Weiny typedef enum CXLEventLogType { 22d7b84ddcSIra Weiny CXL_EVENT_TYPE_INFO = 0, 23d7b84ddcSIra Weiny CXL_EVENT_TYPE_WARN = 1, 24d7b84ddcSIra Weiny CXL_EVENT_TYPE_FAIL = 2, 25d7b84ddcSIra Weiny CXL_EVENT_TYPE_FATAL = 3, 26d7b84ddcSIra Weiny CXL_EVENT_TYPE_DYNAMIC_CAP = 4, 27d7b84ddcSIra Weiny CXL_EVENT_TYPE_MAX 28d7b84ddcSIra Weiny } CXLEventLogType; 29d7b84ddcSIra Weiny 3022d7e3beSIra Weiny /* 3122d7e3beSIra Weiny * Common Event Record Format 328700ee15SJonathan Cameron * CXL r3.1 section 8.2.9.2.1: Event Records; Table 8-43 3322d7e3beSIra Weiny */ 3422d7e3beSIra Weiny #define CXL_EVENT_REC_HDR_RES_LEN 0xf 3522d7e3beSIra Weiny typedef struct CXLEventRecordHdr { 3622d7e3beSIra Weiny QemuUUID id; 3722d7e3beSIra Weiny uint8_t length; 3822d7e3beSIra Weiny uint8_t flags[3]; 3922d7e3beSIra Weiny uint16_t handle; 4022d7e3beSIra Weiny uint16_t related_handle; 4122d7e3beSIra Weiny uint64_t timestamp; 4222d7e3beSIra Weiny uint8_t maint_op_class; 4322d7e3beSIra Weiny uint8_t reserved[CXL_EVENT_REC_HDR_RES_LEN]; 4422d7e3beSIra Weiny } QEMU_PACKED CXLEventRecordHdr; 4522d7e3beSIra Weiny 4622d7e3beSIra Weiny #define CXL_EVENT_RECORD_DATA_LENGTH 0x50 4722d7e3beSIra Weiny typedef struct CXLEventRecordRaw { 4822d7e3beSIra Weiny CXLEventRecordHdr hdr; 4922d7e3beSIra Weiny uint8_t data[CXL_EVENT_RECORD_DATA_LENGTH]; 5022d7e3beSIra Weiny } QEMU_PACKED CXLEventRecordRaw; 5122d7e3beSIra Weiny #define CXL_EVENT_RECORD_SIZE (sizeof(CXLEventRecordRaw)) 5222d7e3beSIra Weiny 5322d7e3beSIra Weiny /* 5422d7e3beSIra Weiny * Get Event Records output payload 558700ee15SJonathan Cameron * CXL r3.1 section 8.2.9.2.2; Table 8-53 5622d7e3beSIra Weiny */ 5722d7e3beSIra Weiny #define CXL_GET_EVENT_FLAG_OVERFLOW BIT(0) 5822d7e3beSIra Weiny #define CXL_GET_EVENT_FLAG_MORE_RECORDS BIT(1) 5922d7e3beSIra Weiny typedef struct CXLGetEventPayload { 6022d7e3beSIra Weiny uint8_t flags; 6122d7e3beSIra Weiny uint8_t reserved1; 6222d7e3beSIra Weiny uint16_t overflow_err_count; 6322d7e3beSIra Weiny uint64_t first_overflow_timestamp; 6422d7e3beSIra Weiny uint64_t last_overflow_timestamp; 6522d7e3beSIra Weiny uint16_t record_count; 6622d7e3beSIra Weiny uint8_t reserved2[0xa]; 6722d7e3beSIra Weiny CXLEventRecordRaw records[]; 6822d7e3beSIra Weiny } QEMU_PACKED CXLGetEventPayload; 6922d7e3beSIra Weiny #define CXL_EVENT_PAYLOAD_HDR_SIZE (sizeof(CXLGetEventPayload)) 7022d7e3beSIra Weiny 7122d7e3beSIra Weiny /* 7222d7e3beSIra Weiny * Clear Event Records input payload 738700ee15SJonathan Cameron * CXL r3.1 section 8.2.9.2.3; Table 8-54 7422d7e3beSIra Weiny */ 7522d7e3beSIra Weiny typedef struct CXLClearEventPayload { 7622d7e3beSIra Weiny uint8_t event_log; /* CXLEventLogType */ 7722d7e3beSIra Weiny uint8_t clear_flags; 7822d7e3beSIra Weiny uint8_t nr_recs; 7922d7e3beSIra Weiny uint8_t reserved[3]; 8022d7e3beSIra Weiny uint16_t handle[]; 8122d7e3beSIra Weiny } CXLClearEventPayload; 8222d7e3beSIra Weiny 838700ee15SJonathan Cameron /* 846676bb97SIra Weiny * Event Interrupt Policy 856676bb97SIra Weiny * 868700ee15SJonathan Cameron * CXL r3.1 section 8.2.9.2.4; Table 8-55 876676bb97SIra Weiny */ 886676bb97SIra Weiny typedef enum CXLEventIntMode { 896676bb97SIra Weiny CXL_INT_NONE = 0x00, 906676bb97SIra Weiny CXL_INT_MSI_MSIX = 0x01, 916676bb97SIra Weiny CXL_INT_FW = 0x02, 926676bb97SIra Weiny CXL_INT_RES = 0x03, 936676bb97SIra Weiny } CXLEventIntMode; 946676bb97SIra Weiny #define CXL_EVENT_INT_MODE_MASK 0x3 95b342489aSJonathan Cameron #define CXL_EVENT_INT_SETTING(vector) \ 96b342489aSJonathan Cameron ((((uint8_t)vector & 0xf) << 4) | CXL_INT_MSI_MSIX) 976676bb97SIra Weiny typedef struct CXLEventInterruptPolicy { 986676bb97SIra Weiny uint8_t info_settings; 996676bb97SIra Weiny uint8_t warn_settings; 1006676bb97SIra Weiny uint8_t failure_settings; 1016676bb97SIra Weiny uint8_t fatal_settings; 1026676bb97SIra Weiny uint8_t dyn_cap_settings; 1036676bb97SIra Weiny } QEMU_PACKED CXLEventInterruptPolicy; 1046676bb97SIra Weiny /* DCD is optional but other fields are not */ 1056676bb97SIra Weiny #define CXL_EVENT_INT_SETTING_MIN_LEN 4 1066676bb97SIra Weiny 107ea9b6d64SIra Weiny /* 108ea9b6d64SIra Weiny * General Media Event Record 1098700ee15SJonathan Cameron * CXL r3.1 Section 8.2.9.2.1.1; Table 8-45 110ea9b6d64SIra Weiny */ 111ea9b6d64SIra Weiny #define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10 112ea9b6d64SIra Weiny #define CXL_EVENT_GEN_MED_RES_SIZE 0x2e 113ea9b6d64SIra Weiny typedef struct CXLEventGenMedia { 114ea9b6d64SIra Weiny CXLEventRecordHdr hdr; 115ea9b6d64SIra Weiny uint64_t phys_addr; 116ea9b6d64SIra Weiny uint8_t descriptor; 117ea9b6d64SIra Weiny uint8_t type; 118ea9b6d64SIra Weiny uint8_t transaction_type; 119ea9b6d64SIra Weiny uint16_t validity_flags; 120ea9b6d64SIra Weiny uint8_t channel; 121ea9b6d64SIra Weiny uint8_t rank; 122ea9b6d64SIra Weiny uint8_t device[3]; 123ea9b6d64SIra Weiny uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE]; 124ea9b6d64SIra Weiny uint8_t reserved[CXL_EVENT_GEN_MED_RES_SIZE]; 125ea9b6d64SIra Weiny } QEMU_PACKED CXLEventGenMedia; 126ea9b6d64SIra Weiny 127b90a324eSJonathan Cameron /* 128b90a324eSJonathan Cameron * DRAM Event Record 1298700ee15SJonathan Cameron * CXL r3.1 Section 8.2.9.2.1.2: Table 8-46 130b90a324eSJonathan Cameron * All fields little endian. 131b90a324eSJonathan Cameron */ 132b90a324eSJonathan Cameron typedef struct CXLEventDram { 133b90a324eSJonathan Cameron CXLEventRecordHdr hdr; 134b90a324eSJonathan Cameron uint64_t phys_addr; 135b90a324eSJonathan Cameron uint8_t descriptor; 136b90a324eSJonathan Cameron uint8_t type; 137b90a324eSJonathan Cameron uint8_t transaction_type; 138b90a324eSJonathan Cameron uint16_t validity_flags; 139b90a324eSJonathan Cameron uint8_t channel; 140b90a324eSJonathan Cameron uint8_t rank; 141b90a324eSJonathan Cameron uint8_t nibble_mask[3]; 142b90a324eSJonathan Cameron uint8_t bank_group; 143b90a324eSJonathan Cameron uint8_t bank; 144b90a324eSJonathan Cameron uint8_t row[3]; 145b90a324eSJonathan Cameron uint16_t column; 146b90a324eSJonathan Cameron uint64_t correction_mask[4]; 147b90a324eSJonathan Cameron uint8_t reserved[0x17]; 148b90a324eSJonathan Cameron } QEMU_PACKED CXLEventDram; 149b90a324eSJonathan Cameron 150bafe0308SJonathan Cameron /* 151bafe0308SJonathan Cameron * Memory Module Event Record 1528700ee15SJonathan Cameron * CXL r3.1 Section 8.2.9.2.1.3: Table 8-47 153bafe0308SJonathan Cameron * All fields little endian. 154bafe0308SJonathan Cameron */ 155bafe0308SJonathan Cameron typedef struct CXLEventMemoryModule { 156bafe0308SJonathan Cameron CXLEventRecordHdr hdr; 157bafe0308SJonathan Cameron uint8_t type; 158bafe0308SJonathan Cameron uint8_t health_status; 159bafe0308SJonathan Cameron uint8_t media_status; 160bafe0308SJonathan Cameron uint8_t additional_status; 161bafe0308SJonathan Cameron uint8_t life_used; 162bafe0308SJonathan Cameron int16_t temperature; 163bafe0308SJonathan Cameron uint32_t dirty_shutdown_count; 164bafe0308SJonathan Cameron uint32_t corrected_volatile_error_count; 165bafe0308SJonathan Cameron uint32_t corrected_persistent_error_count; 166bafe0308SJonathan Cameron uint8_t reserved[0x3d]; 167bafe0308SJonathan Cameron } QEMU_PACKED CXLEventMemoryModule; 168bafe0308SJonathan Cameron 169*d0b9b28aSFan Ni /* 170*d0b9b28aSFan Ni * CXL r3.1 section Table 8-50: Dynamic Capacity Event Record 171*d0b9b28aSFan Ni * All fields little endian. 172*d0b9b28aSFan Ni */ 173*d0b9b28aSFan Ni typedef struct CXLEventDynamicCapacity { 174*d0b9b28aSFan Ni CXLEventRecordHdr hdr; 175*d0b9b28aSFan Ni uint8_t type; 176*d0b9b28aSFan Ni uint8_t validity_flags; 177*d0b9b28aSFan Ni uint16_t host_id; 178*d0b9b28aSFan Ni uint8_t updated_region_id; 179*d0b9b28aSFan Ni uint8_t flags; 180*d0b9b28aSFan Ni uint8_t reserved2[2]; 181*d0b9b28aSFan Ni uint8_t dynamic_capacity_extent[0x28]; /* defined in cxl_device.h */ 182*d0b9b28aSFan Ni uint8_t reserved[0x18]; 183*d0b9b28aSFan Ni uint32_t extents_avail; 184*d0b9b28aSFan Ni uint32_t tags_avail; 185*d0b9b28aSFan Ni } QEMU_PACKED CXLEventDynamicCapacity; 186*d0b9b28aSFan Ni 187d7b84ddcSIra Weiny #endif /* CXL_EVENTS_H */ 188