GuC KMD API
/**************************************************************************************** ** Copyright © 2016 Intel® Corporation ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and associated documentation files (the "Software"), ** to deal in the Software without restriction, including without limitation ** the rights to use, copy, modify, merge, publish, distribute, sublicense, ** and/or sell copies of the Software, and to permit persons to whom the ** Software is furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice (including the next ** paragraph) shall be included in all copies or substantial portions of the ** Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ** IN THE SOFTWARE. ** ****************************************************************************************/ /**************************************************************************************** ** File Name : UkGuckmdInterface.h ** ** Description : Definitions for GuC to KMD interface ** ** Environment : GuC ** ** Notes: ** ****************************************************************************************/ #ifndef UK_GUC_KMD_INTEFACE_H #define UK_GUC_KMD_INTEFACE_H #if defined (_MSC_VER) #pragma pack(push, 1) #else #pragma pack(1) #endif #include "types.h" typedef ULONG64 ADDRESS64; typedef ULONG ADDRESS32; //***************************************************************************** // MACRO: KM_BIT_RANGE // PURPOSE: Calculates the number of bits between the startbit and the endbit // and count is inclusive of both bits. The bits are 0 based. //***************************************************************************** #ifndef KM_BIT_RANGE #define KM_BIT_RANGE(endbit, startbit) ((endbit)-(startbit)+1) //***************************************************************************** // MACRO: KM_BIT // PURPOSE: Used for clarity when defining bit structs //***************************************************************************** #define KM_BIT(bit) (1) #endif //*********************************************************************************************** // Struct: Render Power Clock State register definition // PURPOSE: KMD/GuC uses this definition to program Render Power Clock State register in ring context // at Exec List Submit Port time. //*********************************************************************************************** typedef struct _KM_UK_RENDER_PWR_CLK_STATE { union { struct { // 0010: 2 EUs // 0100: 4 EUs // 0110: 6 EUs // 1000 :8 EUs DWORD EUmin : KM_BIT_RANGE(3,0); // Minimum number of EUs to power (per subslice if multiple subslices enabled) DWORD EUmax : KM_BIT_RANGE(7,4); // Maximum number of EUs to power (per subslice if multiple subslices enabled). // To specify an exact number of subslices, set EUmax equal to EUmin // Number of subslices to power: // 001: 1 subslice // 010: 2 subslices // 011: 3 subslices // BXT only! This MBZ for SKL! DWORD SScount : KM_BIT_RANGE(10,8); // sub-slice count // BXT only! This MBZ for SKL! DWORD SScountEn : KM_BIT_RANGE(11,11); // Enable Subslice Count Request (1 = Use SliceCount from this register) DWORD : KM_BIT_RANGE(14,12); // SKL only! This MBZ for BXT! DWORD SliceCount : KM_BIT_RANGE(17,15); // SKL only! This MBZ for BXT! DWORD SCountEn : KM_BIT_RANGE(18,18); DWORD : KM_BIT_RANGE(30,19); // Main trigger: Power Clock State Enable // 0: No specific power state set, no message/wait with PMunit // 1: CSunit sends the contents of this register to PMunit each time it is written, Send contents of this register to PMunit, wait for Ack. DWORD PowerClkStateEn : KM_BIT_RANGE(31,31); }; DWORD Data; }; }KM_UK_RENDER_PWR_CLK_STATE; //***************************************************************************** // Enum: IGFX_ENGINE // PURPOSE: Engine IDs available in the GFX HW //***************************************************************************** typedef enum { // The Enum values are important as some macros and loops depend on them being sequential IGFX_RENDER_ENGINE = 0, IGFX_VIDEO_ENGINE = 1, IGFX_BLITTER_ENGINE = 2, IGFX_VIDEOENHANCE_ENGINE = 3, IGFX_VIDEO_ENGINE2 = 4, IGFX_ABSOLUTE_MAX_ENGINES, IGFX_ENGINE_INVALID = IGFX_ABSOLUTE_MAX_ENGINES }IGFX_ENGINE; //***************************************************************************** // Enum: UK_ENGINES_USED // PURPOSE: A bit flag for each engines used. Used for making some memory optimizations. //***************************************************************************** typedef struct UK_ENGINES_USED_REC { union { struct { // This sequence of engines (i.e bit positions) must match the corresponding IGFX_ENGINE enum value, UCHAR RenderEngine : KM_BIT ( 0 ); UCHAR VideoEngine : KM_BIT ( 1 ); UCHAR BltEngine : KM_BIT ( 2 ); UCHAR VEEngine : KM_BIT ( 3 ); UCHAR VideoEngine2 : KM_BIT ( 4 ); UCHAR : KM_BIT_RANGE (7, 5 ); }; UCHAR Value; }; } IGFX_ENGINES_USED; //***************************************************************************** // Enum: UK_QUEUE_STATUS // PURPOSE: to indicate the status of a Micro Kernel's Work/Submit Queue. // TBD: Define what state means what... //***************************************************************************** typedef enum { UK_QSTATUS_ACTIVE = 1, //Work queue will be serviced if doorbell is owned by app UK_QSTATUS_SUSPENDED , //Work queue will not be serviced. UK_QSTATUS_CMD_ERROR , //Error in work queue UK_QUEUE_STATUS_ENGINE_ID_NOT_USED, UK_QSTATUS_SUSPENDED_FROM_ENGINE_RESET, //Suspended due to engine reset. App must consider all work before WQ tail as in error and resubmit necessary work. UK_QSTATUS_INVALID_STATUS }UK_QUEUE_STATUS; //***************************************************************************** // Enum: UK_CONTEXT_PRIORITY // PURPOSE: To indicate the priority of UK context. //***************************************************************************** typedef enum { UK_CONTEXT_PRIORITY_KMD_HIGH = 0, // KMD priority is only for SKL+ UK_CONTEXT_PRIORITY_HIGH = 1, UK_CONTEXT_PRIORITY_KMD_NORMAL = 2, // KMD priority is only for SKL+ UK_CONTEXT_PRIORITY_NORMAL = 3, UK_CONTEXT_PRIORITY_ABSOLUTE_MAX_COUNT , UK_CONTEXT_PRIORITY_INVALID = UK_CONTEXT_PRIORITY_ABSOLUTE_MAX_COUNT }UK_CONTEXT_PRIORITY; #define UK_BDW_MAX_PRIORITIES (2) #define UK_SKL_MAX_PRIORITIES (4) //***************************************************************************** // Enum: UK_ENGINE_EXECLIST_CONTEXT // PURPOSE: State of the context - this is per engine. //***************************************************************************** typedef struct UK_ENGINE_CONTEXT_STATE_REC { union { struct { UCHAR Submitted : KM_BIT ( 0); UCHAR : KM_BIT_RANGE( 7, 1); }; UCHAR SubmitValue; }; union { struct { UCHAR WaitForDisplayEvent : KM_BIT ( 0); UCHAR WaitForSemaphore : KM_BIT ( 1); UCHAR WaitForFaultFulfill : KM_BIT ( 2); UCHAR CATError : KM_BIT ( 3); UCHAR ReEnqueueToSubmitQueue : KM_BIT ( 4); UCHAR : KM_BIT_RANGE( 7, 5); }; UCHAR WaitValue; }; } UK_ENGINE_CONTEXT_STATE; //***************************************************************************** // Enum: UK_SCHED_INSTRUCTION_TYPE // PURPOSE: These are instructions to the scheduler //***************************************************************************** typedef enum { SCHED_INSTRUCTION_BATCH_BUFFER_START = 0x1, SCHED_INSTRUCTION_GUC_CMD_PSEUDO = 0x2, SCHED_INSTRUCTION_GUC_CMD_KMD = 0x3, // This work item is issued by KMD (Windows mode) SCHED_INSTRUCTION_GUC_CMD_NOOP = 0x4, // Treat data following this WI header as no op (i.e. skip it). uKernel will not read the data. SCHED_INSTRUCTION_INVALID , // This must be the last-1 entry SCHED_INSTRUCTION_MAX = 0xF, // Currently this is the max value }UK_SCHED_INSTRUCTION_TYPE; //***************************************************************************** // Enum: UK_SCHED_WORK_QUEUE_WORKLOAD_TYPE // PURPOSE: Workload type information. //***************************************************************************** typedef enum { SCHED_WORK_QUEUE_GENERAL_WORKLOAD = 0, SCHED_WORK_QUEUE_GPGPU_WORKLOAD, SCHED_WORK_QUEUE_TOUCH_WORKLOAD, SCHED_WORK_QUEUE_MAX_WORKLOADS }UK_SCHED_WORK_QUEUE_WORKLOAD_TYPE; //***************************************************************************** // Enum: UK_SCHED_WORK_QUEUE_ITEM_HEADER // PURPOSE: Header for every work item put in the work queue //***************************************************************************** typedef struct UK_SCHED_WORK_QUEUE_ITEM_HEADER_REC { union { struct { ULONG WorkInstructionType : KM_BIT_RANGE( 7, 0); //UK_SCHED_INSTRUCTION_TYPE ULONG : KM_BIT_RANGE( 9, 8); //MBZ ULONG TargetEngine : KM_BIT_RANGE(13, 10); //IGFX_ENGINE ULONG : KM_BIT_RANGE(15, 14); //MBZ ULONG CommandLengthDwords : KM_BIT_RANGE(26, 16); //Length in number of Dwords following this header ULONG DoNotInsertWCFlushWait : KM_BIT_RANGE(27, 27); ULONG IsPresentWorkload : KM_BIT_RANGE(28, 28); ULONG WorkloadType : KM_BIT_RANGE(31, 29); // Enum UK_SCHED_WORK_QUEUE_WORKLOAD_TYPE //ULONG : KM_BIT_RANGE(31, 30); //Ignored on production build. On debug, UMD can use to put tracking number (16 max) }; ULONG Value; }; }UK_SCHED_WORK_QUEUE_ITEM_HEADER; //INFO: Work Queue Item // // Work Queue Item // V---------------------------------------V // ***************************************** // * * * // * WQ Item Header * Commands * // ***************************************** // Commands are variable length so not included in any structure. #define UK_MAX_WORK_QUEUE_ITEMS (128) //Max size of WI (including header). This is used for security checks. //If a single WI size increases more than this size, we need to evaluate use cases to increase this define #define UK_MAX_WI_SIZE_IN_DW (16) //***************************************************************************** // Struct: UK_KM_APP_DOORBELL_INFO // PURPOSE: Doorbell cacheline description //***************************************************************************** typedef struct UK_KM_APP_DOORBELL_INFO_REC { struct { ULONG DoorBellStatus; // 0 / 1 ULONG Cookie; // Only KMD/uKernel should write 0 here. App should rollover to 1. ULONG Reserved[14]; // Rest of the cache line. }; }UK_KM_APP_DOORBELL_INFO; //***************************************************************************** // Struct: UK_DOORBELL_QW // PURPOSE: Doorbell QW description //***************************************************************************** typedef struct UK_DOORBELL_QW_REC { union { struct { ULONG DoorBellStatus; // 0 / 1 ULONG Cookie; // Only KMD/uKernel should write 0 here. App should rollover to 1. }; ULONG64 QuadPart; }; }UK_DOORBELL_QW; #define KM_DOORBELL_ENABLED (1) #define KM_DOORBELL_DISABLED (0) //***************************************************************************** // Struct: SCHED_CONTEXT_ENGINE_PRESENCE // PURPOSE: Per Context Engine Status //***************************************************************************** typedef struct SCHED_CONTEXT_ENGINE_PRESENCE_STRUCT { union { struct { ULONG IsContextInRcsSubmitQueue : KM_BIT ( 0); ULONG IsContextInVcsSubmitQueue : KM_BIT ( 1); ULONG IsContextInBcsSubmitQueue : KM_BIT ( 2); ULONG IsContextInVecsSubmitQueue : KM_BIT ( 3); ULONG IsContextInVcs2SubmitQueue : KM_BIT ( 4); ULONG : KM_BIT_RANGE(30,5); ULONG : KM_BIT ( 31); //Used to be IsSubmitQueueElementValid }; ULONG SubmitQueuePresenceValue; }; }SCHED_CONTEXT_ENGINE_PRESENCE; //***************************************************************************** // Struct: UK_SCHED_PROCESS_DESCRIPTOR // PURPOSE: A shared structure between app and uKernel communication. //***************************************************************************** typedef struct UK_SCHED_PROCESS_DESCRIPTOR_REC { ULONG ContextId; // Trigger / doorbell address for App - Reserved in uK space ADDRESS64 pDoorbell; // For Read-Write access by App. Ptr to UK_KM_APP_DOORBELL_INFO ULONG HeadOffset; // Byte Offset - App must not write here. ULONG TailOffset; // Byte Offset - uKernel will not write here. ULONG ErrorOffsetByte; ADDRESS64 WQVBaseAddress; // pVirt in app - for use only by application ULONG WQSizeBytes; UK_QUEUE_STATUS WQStatus; // Read by App. Written by uKernel/KMD. SCHED_CONTEXT_ENGINE_PRESENCE ContextEnginePresence; // Read by App. Written by uKernel. A snapshot of context descriptor's copy. Updates only at Context Complete and WI Process complete. UK_CONTEXT_PRIORITY PriorityAssigned; // Read only by app ULONG Reserved[4]; // Reserved //Tracking variables for debug ULONG WorkItemTrackingEnabled; // Status set by KMD, Read only for App. For speed reasons, tracking is enabled for all contexts or none. ULONG AppTotalNumberOfWorkItemsAdded; // App must set to 0 upon return from OpenGPU, before using it. Written only by Application - Total number of Work Items added to WQ so far (all Engines, monotonic increase) ULONG AppReserved2[3]; //uKernel side tracking for debug ULONG TotalWorkItemsParsedByGuC; // Written by uKernel at the time of parsing and successfull removed from WQ (implies ring tail was updated). ULONG TotalWorkItemsCollapsedByGuC; // Written by uKernel if a WI was collapsed if next WI is the same LRCA (optimization applies only to Secure/KMD contexts) ULONG TotalWorkItemsCancelled; // Written by uKernel if a WI was cancelled due to preempt. ULONG IsContextInEngineReset; // Tells if the context is affected in Engine Reset. UMD needs to clear it after taking appropriate Action(TBD). ULONG EngineResetSampledWQTail; // WQ Sampled tail at Engine Reset Time. Valid only if IsContextInEngineReset = TRUE ULONG EngineResetSampledWQTailValid; // Valid from Engine reset until all the affected Work Items are processed. ULONG GuCReserved3[15]; // Reserved }UK_SCHED_PROCESS_DESCRIPTOR; #define KM_MAX_PDP_REGISTERS (4) #define KM_PDP_REGISTER_DWORDS (2) #define MAX_GUC_GPU_CONTEXTS (1024) #define MAX_GUC_BLOCKS_OF_16_GPU_CONTEXTS (64) #define KM_GUC_INVALID_CONTEXT_ID (MAX_GUC_GPU_CONTEXTS) //************************************************************************************** // Struct: KM_UK_POWER_GATING_TRANSPORT_STATE // PURPOSE: Transport current programmed and requested power gating states in shared context //************************************************************************************** typedef struct KM_UK_POWER_GATING_TRANSPORT_STATE_REC { KM_UK_RENDER_PWR_CLK_STATE CurrentState; KM_UK_RENDER_PWR_CLK_STATE RequestedState; }KM_UK_POWER_GATING_TRANSPORT_STATE; //***************************************************************************** // Enum: KM_PAGE_FAULT_MODE // PURPOSE: Page fault mode. Must match "Context Descriptor Format" in BSpec //***************************************************************************** typedef enum KM_PAGE_FAULT_MODE_ENUM { KM_PAGE_FAULT_MODE_FAULT_HANG = 0x0, KM_PAGE_FAULT_MODE_FAULT_WAIT = 0x1, //aka Fault and Halt KM_PAGE_FAULT_MODE_FAULT_STREAM = 0x2, KM_PAGE_FAULT_MODE_FAULT_CONTINUE = 0x3, //SKL+ }KM_PAGE_FAULT_MODE; //***************************************************************************** // Enum: KM_CONTEXT_ADDRESSING_MODE // PURPOSE: Describes Addressing Mode & Legacy Context. Must match "Context Descriptor Format" in BSpec //***************************************************************************** typedef enum KM_CONTEXT_ADDRESSING_MODE_ENUM { KM_CONTEXT_ADDRESSING_MODE_INVALID = 0x0, KM_CONTEXT_ADDRESSING_MODE_LEGACY_NO_64BIT_VA = 0x1, //Legacy & DOESN'T support any SVM features. (32bit PPGGTT) KM_CONTEXT_ADDRESSING_MODE_ADVANCED = 0x2, //Advanced context mode and supports SVM features KM_CONTEXT_ADDRESSING_MODE_LEGACY_WITH_64BIT_VA = 0x3, //Legacy & DOESN'T support any SVM features. (64bit PPGTT) }KM_CONTEXT_ADDRESSING_MODE; //***************************************************************************** // Struct: UK_KM_ADDRESS // PURPOSE: Used to hold ptr to CPU virtual address and Ptr to Ukernel address //***************************************************************************** typedef struct UK_KM_ADDRESS_REC { ADDRESS64 pCpuAddress; //Cpu / big core address (virtual) ADDRESS32 pUkAddress; //uKernel address (gfx) }UK_KM_ADDRESS; //***************************************************************************** // Struct: UK_CONTEXT_ID_MAP // PURPOSE: To represent the context ID structure and execlist/submit queues //***************************************************************************** typedef struct UK_CONTEXT_ID_MAP_REC { union { struct { ULONG ContextIndex : KM_BIT_RANGE( 19, 0); // NOTE: This can be index in the app context pool in direct submission case or LRCA itself in proxy submission case ULONG SubmissionByProxy : KM_BIT_RANGE( 20, 20); // If KMD or other context submitted this context. This means, ContextID is LRCA[31:20] ULONG Reserved : KM_BIT_RANGE( 22, 21); // Required by HW ULONG SWCounter : KM_BIT_RANGE( 28, 23); // Used for tracking IOMMU group resubmits (or if submit by proxy is true, lower 6 bits QWIndex). ULONG EngineId : KM_BIT_RANGE( 31, 29); }; ULONG ContextIdDword; }; }UK_CONTEXT_ID_MAP; #define CONTEXT_ID_MAP_SWCOUNTER_NUM_BITS (6) //***************************************************************************** // Struct: SCHED_CONTEXT_DESCRIPTOR_LD_REC // PURPOSE: The default setting for Context Descriptor Format to be set in UK_ELEMENT_DESC //***************************************************************************** typedef struct SCHED_ELEMENT_DESC_REC { union { struct { ULONG Valid : KM_BIT ( 0); ULONG ForcePDRestore : KM_BIT ( 1); //Force Page Directory ULONG ForceRestore : KM_BIT ( 2); ULONG CtxtAddrMode : KM_BIT_RANGE( 4, 3); //Addressing Mode & Legacy Context (KM_CONTEXT_ADDRESSING_MODE) ULONG L3LLCCoherencySupport : KM_BIT ( 5); ULONG FaultSupportType : KM_BIT_RANGE( 7, 6); //Type: KM_PAGE_FAULT_MODE ULONG Privilege : KM_BIT ( 8); ULONG : KM_BIT_RANGE( 11, 9); ULONG LRCA : KM_BIT_RANGE( 31, 12); }; ULONG Value; }; }SCHED_CONTEXT_DESCRIPTOR_LD; //***************************************************************************** // Struct: UK_ELEMENT_DESC // PURPOSE: The Execution list's element descriptor. Also in Submit Queue //***************************************************************************** typedef struct UK_ELEMENT_DESC_REC { union { SCHED_CONTEXT_DESCRIPTOR_LD ContextDesc; }; union { struct { UK_CONTEXT_ID_MAP ContextId; }; ULONG HighDW; }; }UK_ELEMENT_DESC; // Bit-flags used for storing information about each saved register typedef union KM_MMIO_REGISTER_FLAGS { ULONG FlagsValue; struct { ULONG PowerCycle : KM_BIT_RANGE(0 , 0); //Restore at power cycle ULONG Masked : KM_BIT_RANGE(1 , 1); //Register is masked ULONG EngineReset : KM_BIT_RANGE(2 , 2); //Restore at Engine Reset ULONG SaveDefaultValue : KM_BIT_RANGE(3 , 3); //Save default at init time ULONG SaveCurrentValue : KM_BIT_RANGE(4 , 4); //Save current value just before reset/sleep ULONG : KM_BIT_RANGE(31, 5); //Reserved }; }KM_MMIO_REGISTER_FLAGS; #define KM_REGSET_FLAG_FLAGS_NONE 0x00000000 #define KM_REGSET_FLAG_POWERCYCLE 0x00000001 //(__BIT(0)) #define KM_REGSET_FLAG_MASKED 0x00000002 //(__BIT(1)) #define KM_REGSET_FLAG_ENGINERESET 0x00000004 //(__BIT(2)) #define KM_REGSET_FLAG_SAVE_DEFAULT_VALUE 0x00000008 //(__BIT(3)) #define KM_REGSET_FLAG_SAVE_CURRENT_VALUE 0x00000010 //(__BIT(4)) // Note: this value will need to be increased if any register set exceeds it #define KM_REGSET_MAX_REGISTERS_PER_SET (25) #define KM_MMIO_WHITE_LIST_MAX_OFFSETS 12 typedef struct KM_MMIO_WHITE_LIST_REC { ULONG MmioStart; ULONG Offsets[KM_MMIO_WHITE_LIST_MAX_OFFSETS]; ULONG Count; } KM_MMIO_WHITE_LIST; // Structure used for storing register offset, current value, default value // and flags typedef struct KM_MMIO_REGISTER_REC { ULONG Offset; // Register offset ULONG Value; // Current value KM_MMIO_REGISTER_FLAGS Flags; } KM_MMIO_REGISTER; // Structure describing register set typedef struct KM_MMIO_REGISTER_SET_REC { KM_MMIO_REGISTER Registers[KM_REGSET_MAX_REGISTERS_PER_SET]; BOOL RegisterValuesValid; ULONG NumberOfRegisters; } KM_MMIO_REGISTER_SET; // Structure describing collection of register sets typedef struct KM_MMIO_REGISTER_STATE_REC { KM_MMIO_REGISTER_SET GlobalRegisters; // Registers that are not specific to a node KM_MMIO_REGISTER_SET NodeRegisters[IGFX_ABSOLUTE_MAX_ENGINES]; // Node specific registers KM_MMIO_WHITE_LIST MMIOWhiteList[IGFX_ABSOLUTE_MAX_ENGINES]; // List of MMIO registers that are set as non privileged } KM_MMIO_REGISTER_STATE; #define UK_MAX_GUC_S3_SAVE_SPACE_PAGES (10) //***************************************************************************** // Struct: KM_GUC_ADDITIONAL_DATA_STRUCTS // PURPOSE: Pointers to other data structures used for various operations //***************************************************************************** typedef struct KM_GUC_ADDITIONAL_DATA_STRUCTS_REC { ADDRESS32 GfxAddressMMIORegisterState; //Gfx ptr to KM_MMIO_REGISTER_STATE. Size is IGFX_ABSOLUTE_MAX_ENGINES (Gfx address must be persistent for life of GuC) ADDRESS32 GfxPtrToGuCSStateSaveBuffer; //Max of UK_MAX_GUC_S3_SAVE_SPACE_PAGES (Persistent) ADDRESS32 GfxGoldenContextLRCA; //LRCA addresses of golden contexts; (Persistent) ADDRESS32 GfxSchedulerPolicies; //GFX addresses of SCHED_SCHEDULING_POLICIES; (non-Persistent, may be released after initial load), NULL or valid=0 flag value will cause default policies to be loaded. DWORD Reserved0[2]; DWORD Reserved1; DWORD GoldenContextEngStateSizeInBytes[IGFX_ABSOLUTE_MAX_ENGINES]; DWORD Reserved2[2]; DWORD Reserved3[2]; }KM_GUC_ADDITIONAL_DATA_STRUCTS; #define KM_KBYTES_TO_DWORD_COUNT(a) ((a * 1024) / sizeof(DWORD)) #define KM_SCHED_MAX_SUBMIT_DATA_ENTRIES (64) #define KM_SCHED_MAX_PREMPT_REPORT_ENTRIES (16) //***************************************************************************** // Struct: KM_SCHED_SUBMIT_DATA // PURPOSE: Currently Reserved. (Future: used for extended KMD - GuC Communication) //***************************************************************************** typedef struct KM_SCHED_SUBMIT_DATA_REC { ULONG Reserved[KM_SCHED_MAX_SUBMIT_DATA_ENTRIES]; ULONG MaxSubmitDataEntriesCount; // MBZ - For future use. ULONG SubmitDataFreeIndex; // MBZ }KM_SCHED_SUBMIT_DATA; //***************************************************************************** // Enum: KM_SCHED_CONTEXT_AFFECTED_TYPE // PURPOSE: To indicate how a context was affected when involved in preempt/reset //***************************************************************************** typedef enum KM_SCHED_CONTEXT_AFFECTED_TYPE_ENUM { KM_SCHED_CONTEXT_AFFECTED_NONE = 0x0, KM_SCHED_CONTEXT_AFFECTED_IN_HW_EXECUTION = 0x1, KM_SCHED_CONTEXT_AFFECTED_IN_WORK_QUEUE = 0x2, KM_SCHED_CONTEXT_AFFECTED_IN_SUBMIT_QUEUE = 0x3, }KM_SCHED_CONTEXT_AFFECTED_TYPE; //***************************************************************************** // Enum: KM_SCHED_AC_REPORT_STATUS // PURPOSE: To indicate report status of the context when involved in preempt/reset //***************************************************************************** typedef enum KM_SCHED_AC_REPORT_STATUS_ENUM { KM_SCHED_AC_REPORT_STATUS_UNKNOWN = 0x0, //Unknown / un-acked. KM_SCHED_AC_REPORT_STATUS_REQUEST_ACKED = 0x1, // Got the request to preempt KM_SCHED_AC_REPORT_STATUS_ERROR = 0x2, KM_SCHED_AC_REPORT_STATUS_COMPLETE = 0x4 //Request to preempt was completed by CSB = context complete for preempt context }KM_SCHED_AC_REPORT_STATUS; //KM_SCHED_AC_REPORT_STATUS_REACHED_CS = 0x3, //[Currently not implemented due to perf] Request to preempt was acked by CS HW (idle -> active/switch) // Types of Reset supported by GuC typedef enum UK_KM_RESET_TYPE_ENUM { UK_KM_RESET_TYPE_MEDIA_RESET, UK_KM_RESET_TYPE_WINDOWS_ENGINE_RESET, UK_KM_RESET_TYPE_PRIVATE_ENGINE_RESET, // TODO: find out what is needed for this?? To support this we may need to send UK_KM_RESET_TYPE from KMD UK_KM_RESET_TYPE_GUC_INTERNAL_ENGINE_RESET }UK_KM_RESET_TYPE; //***************************************************************************** // Struct: KM_SCHED_AFFECTED_CONTEXT_REPORT // PURPOSE: Used by GuC to report back on which contexts were affected by // preempt request by KMD //***************************************************************************** typedef struct KM_SCHED_AFFECTED_CONTEXT_REPORT_REC { KM_SCHED_AC_REPORT_STATUS ReportReturnStatus; // KMD must request report in Options (see host->GuC interface doc) // GuC sets this if a report is requested and was able to satisfy the request ULONG64 ArrAffectedPtrExeclistContext[KM_SCHED_MAX_PREMPT_REPORT_ENTRIES]; // Kernel mode virtual address (pExeclistContext, from Backpointer in LRCA) KM_SCHED_CONTEXT_AFFECTED_TYPE ArrAffectedType[KM_SCHED_MAX_PREMPT_REPORT_ENTRIES]; // How the context is affected. ULONG ArrAffectedFenceId[KM_SCHED_MAX_PREMPT_REPORT_ENTRIES]; // This is the submit fence ID as seen by GuC for debug. Should not use for reporting to OS. ULONG AffectExeclistCount; ULONG GuCInternal0; // KMD should not write to this value as long as preemption is in progress with GuC ULONG GuCInternal1; // KMD should not write to this value as long as preemption is in progress with GuC }KM_SCHED_AFFECTED_CONTEXT_REPORT; #define KM_UK_MAX_PREEMPTION_DEBUG_DWORDS 32 //*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // typedef: // SLPM_PER_CTX_STATE_INFO // // Description: // This structure provides per-context storage for SLPM related information. // // *** IMPORTANT *** Keep in sync with slpmosinterface.h and UkGucKmdInterface.h //------------------------------------------------------------------------------*/ typedef struct KM_SLPM_PER_CTX_STATE_INFO_REC { ULONG EvaluationId; // The evaluation id that this context last partipated in. 0 == This is a new context. ULONG GtFreqRequest; // The GT frequency request for this context. Opaque value of type SLPM_GT_FREQ_REQUEST. ULONG GtFreqRequestId; // The GT frequency request ID used by SLPM to decide if a new frequency change needs to be applied. 0 = There is not GT frequency request. ULONG GtConfig; // The recommended GT_CONFIG. ULONG GtFreqLRI; // Encoded GtFreqRequest ready for sending to pcode via LRI. UCHAR AppMinGtFreqBins; // Minimum GT frequency requested by application/KMD. Value is in bins (1 = 50MHz). Default = 0x0. UCHAR AppMaxGtFreqBins; // Maximum GT frequency requested by application/KMD. Value is in bins (1 = 50MHz). Default = 0xFF. UCHAR GtHwMaxFreq; // The maximum GT frequency for the recommended GT_CONFIG. // Last member of this structure. UCHAR ChangeId; // KMD/APP increments this value when a change is made to the data above. SLPM uses this to know if to reread the data in this structure // or if it's safe to use it's internally cached values. // - 0x00 : means that this context is new. // - 0xFF : forces SLPM to read the structure all the time. }KM_SLPM_PER_CTX_STATE_INFO; //***************************************************************************** // Struct: KM_SCHED_SHARED_CONTEXT_DATA_LOCK // PURPOSE: Lock of KM_SCHED_SHARED_CONTEXT_DATA so that clients can access // this data even after the scheduler has submitted for execution. //***************************************************************************** typedef enum KM_SCHED_SHARED_CONTEXT_DATA_CLIENT_ENUM { KM_SCHED_SHARED_CONTEXT_DATA_CLIENT_SLPM = 0, KM_SCHED_SHARED_CONTEXT_DATA_CLIENT_MAX }KM_SCHED_SHARED_CONTEXT_DATA_CLIENT; typedef struct KM_SCHED_SHARED_CONTEXT_DATA_LOCK_DATA { union { ULONG Value; struct { UCHAR Client[KM_SCHED_SHARED_CONTEXT_DATA_CLIENT_MAX]; // The value will be 1 or 0. // UCHAR is used rather than a bitfield // so that there is no need to read // the lock value into the GUC. }; }; }KM_SCHED_SHARED_CONTEXT_DATA_LOCK; //***************************************************************************** // Struct: KM_SCHED_SHARED_CONTEXT_DATA // PURPOSE: Used for extended KMD - GuC Communication. // This is part of HW context allocation //***************************************************************************** typedef struct KM_SCHED_SHARED_CONTEXT_DATA_REC { //Context specific address of dma buffer private data for tracking mid batch preemption ULONG AddOfLastPreemptedPrivateDataLowPart; // CPU address of private data for currently executing preemtable workload. Used to save BB preempt data. ULONG AddOfLastPreemptedPrivateDataHighPart; // If these are non-zero at Preempt Completion time, then this BB was preempted mid-batch or mid-thread ULONG AddOfLastPreemptedPrivateDataHighPartTmp; // Used for WaPipeControlUpperDwordCorruption ULONG :32; // Qword Padding ULONG IsMappedToProxyContext; ULONG ProxyContextID; ULONG EngineResetContextId; ULONG MediaResetCount; // Reserved Space ULONG Reserved[8]; ULONG UkLastContextSwitchReason; ULONG WasReset; ULONG LRCAGfxAddress; // Gfx Address of LRCA used as back pointer ULONG64 pExeclistContext; // Back pointer to ExecList Context (KM_EXECLIST_CONTEXT) KM_SCHED_SUBMIT_DATA SchedSubmitData; // MBZ KM_SCHED_AFFECTED_CONTEXT_REPORT PreemptedContextReport[IGFX_ABSOLUTE_MAX_ENGINES]; // MBZ prior to calling to GuC for this report TODO: Make this allocation per engine's shared area KM_SCHED_AFFECTED_CONTEXT_REPORT EngResetContextReport[IGFX_ABSOLUTE_MAX_ENGINES]; KM_UK_POWER_GATING_TRANSPORT_STATE PowerGatingStates; // SSEU payload to be transported to GuC ULONG ReservedPreemptDebugData[KM_UK_MAX_PREEMPTION_DEBUG_DWORDS]; // The structure is reserved for Intel use ULONG KmIdleContextId; BOOL IsIdleContextValid; KM_SCHED_SHARED_CONTEXT_DATA_LOCK Lock; // This is used to keep track of when clients need to prevent // this data from being destroyed. When not zero, KMD cannot // garabage clean this memory from GTT or system memory. // Fields for SLPM KM_SLPM_PER_CTX_STATE_INFO SlpmPerContextState; }KM_SCHED_SHARED_CONTEXT_DATA; typedef enum UK_SLEEP_STATE_ENTER_STATUS_ENUM { UK_SLEEP_STATE_ENTER_SUCCESS, UK_SLEEP_STATE_ENTER_PREEMPT_TO_IDLE_FAILED, UK_SLEEP_STATE_ENTER_ENG_RESET_FAILED, }UK_SLEEP_STATE_ENTER_STATUS; //***************************************************************************** // Struct: KM_SCHED_WORK_QUEUE_KMD_ELEMENT_INFO // PURPOSE: Work item for submitting KMD workloads into work queue for GuC. //***************************************************************************** typedef struct KM_SCHED_WORK_QUEUE_KMD_ELEMENT_INFO_REC { SCHED_CONTEXT_DESCRIPTOR_LD ElementLowDW; // 1 DW - Execlist context descriptor's lower DW. union { struct { ULONG : KM_BIT_RANGE( 19, 0); ULONG RingTailQWIndex : KM_BIT_RANGE( 30, 20); // QW Aligned, TailValue <= 2048 (addresses 4 pages max) ULONG : KM_BIT_RANGE( 31, 31); }; ULONG Value; } ElementHighDW; } KM_SCHED_WORK_QUEUE_KMD_ELEMENT_INFO; //KMD work Item looks like this: // KMD Work Queue Item ( KM_SCHED_WORK_QUEUE_ITEM) // V------------------------------------------------------------------------------V // ******************************************************************************** // | | KmdSubmitInfo (2 DWs) | | // | WQ Item Header | TailValue | LRCA | ContextDescLD | RsvdDW | // ******************************************************************************** //***************************************************************************** // Struct: KM_SCHED_WORK_QUEUE_ITEM // PURPOSE: Work item for submitting KMD workloads into work queue for GuC. //***************************************************************************** typedef struct KM_SCHED_WORK_QUEUE_ITEM_REC { UK_SCHED_WORK_QUEUE_ITEM_HEADER Header; // 1 DW KM_SCHED_WORK_QUEUE_KMD_ELEMENT_INFO KmdSubmitElementInfo; // 2 DW - Contains Ring Tail and LRCA, ContextDescLD ULONG FenceId; // 1 DW Fence ID from OS (used for debug tracing). Bit 31, says its preempt or not } KM_SCHED_WORK_QUEUE_ITEM; // If we don't have KM_MAX_ELEMENTS_PER_EXEC_LIST defined we are // in non-windows gfx driver environment (like fulsim/GuC code itself...) // So, define these stuctures. #ifndef KM_MAX_ELEMENTS_PER_EXEC_LIST #ifndef __IGFXFMID_H__ //***************************************************************************** // Enum: GTTYPE // PURPOSE: To GT type of the device //***************************************************************************** typedef enum __GTTYPE { GTTYPE_GT1 = 0x0, GTTYPE_GT2, GTTYPE_GT2_FUSED_TO_GT1, GTTYPE_GT2_FUSED_TO_GT1_6, //IVB GTTYPE_GTL, // HSW GTTYPE_GTM, // HSW GTTYPE_GTH, // HSW GTTYPE_GT3, // BDW GTTYPE_GT4, // BDW GTTYPE_GT0, // BDW GTTYPE_GTA, // BXT GTTYPE_GTC, // BXT GTTYPE_UNDEFINED,//Always at the end. }GTTYPE; //***************************************************************************** // Enum: GFXCORE_FAMILY // PURPOSE: Identify the family //***************************************************************************** typedef enum { IGFX_GEN8_CORE = 11, //Gen8 Family IGFX_GEN9_CORE = 12, //Gen9 Family IGFX_GENNEXT_CORE = 13, //GenNext Family GFXCORE_FAMILY_FORCE_ULONG = 0x7fffffff } GFXCORE_FAMILY; //***************************************************************************** // Enum: PRODUCT_FAMILY // PURPOSE: Identify the product //***************************************************************************** typedef enum { IGFX_UNKNOWN = 0, IGFX_BROADWELL = 16, IGFX_CHERRYVIEW = 17, IGFX_SKYLAKE = 18, IGFX_WILLOWVIEW = 19, IGFX_BROXTON = 20, IGFX_GENNEXT = 0x7ffffffe, PRODUCT_FAMILY_FORCE_ULONG = 0x7fffffff } PRODUCT_FAMILY; //***************************************************************************** // Enum: SKU_STEPPING_ID // PURPOSE: Stepping ID for use for use with GuC //***************************************************************************** typedef enum SKU_STEPPING_ID_ENUM { SKU_STEPPING_ID_A0 = 0x0, // Add Ax steppings here SKU_STEPPING_ID_B0 = 0x10, // Add Bx steppings here SKU_STEPPING_ID_C0 = 0x20, // Add Cx stepping here SKU_STEPPING_ID_D0 = 0x30, // Add Dx stepping here SKU_STEPPING_ID_E0 = 0x40 // Add Ex stepping here }SKU_STEPPING_ID; #endif // ifndef __IGFXFMID_H__ /****************************** KM_EXECLIST_RING_CONTEXT_REGISTER - Must Match BSpec ******************************/ #define KM_MAX_ELEMENTS_PER_EXEC_LIST (2) typedef struct { ULONG Offset; ULONG Data; } KM_EXECLIST_RING_CONTEXT_REGISTER; /****************************** KM_EXECLIST_RING_CONTEXT - Must Match BSpec ******************************/ typedef struct KM_EXECLIST_RING_CONTEXT_REC { ULONG Noop; ULONG RingInfoLriHeader; KM_EXECLIST_RING_CONTEXT_REGISTER ContextControl; KM_EXECLIST_RING_CONTEXT_REGISTER RingHead; KM_EXECLIST_RING_CONTEXT_REGISTER RingTail; KM_EXECLIST_RING_CONTEXT_REGISTER RingBufferStart; KM_EXECLIST_RING_CONTEXT_REGISTER RingBufferControl; KM_EXECLIST_RING_CONTEXT_REGISTER BatchBufferCurrentHead_Udw; KM_EXECLIST_RING_CONTEXT_REGISTER BatchBufferCurrentHead; KM_EXECLIST_RING_CONTEXT_REGISTER BatchBufferState; KM_EXECLIST_RING_CONTEXT_REGISTER SecondBatchBufferAddr_Udw; KM_EXECLIST_RING_CONTEXT_REGISTER SecondBatchBufferAddr; KM_EXECLIST_RING_CONTEXT_REGISTER SecondBatchBufferState; KM_EXECLIST_RING_CONTEXT_REGISTER PostRestoreBb; KM_EXECLIST_RING_CONTEXT_REGISTER IndirectContext; KM_EXECLIST_RING_CONTEXT_REGISTER IndirectContextOffset; union { KM_EXECLIST_RING_CONTEXT_REGISTER RingModeCCID; //Only KBL-H ULONG Padding1[2]; //2 Noops }; ULONG Padding2; // 1 Noop ULONG PdpInfoLriHeader; KM_EXECLIST_RING_CONTEXT_REGISTER ContextTimestamp; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp3_UDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp3_LDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp2_UDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp2_LDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp1_UDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp1_LDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp0_UDW; KM_EXECLIST_RING_CONTEXT_REGISTER Pdp0_LDW; ULONG Padding3[13]; ULONG PcRegisterLriHeader; KM_EXECLIST_RING_CONTEXT_REGISTER RcsPwrClkState; ULONG GpGpuCsrBaseAddress[3]; ULONG Padding4[9]; } KM_EXECLIST_HW_RING_CONTEXT; //***************************************************************************** // Enum: KM_RING_STATUS // PURPOSE: To describe status of current ring //***************************************************************************** typedef enum KM_RING_STATUS_REC { RING_NOT_PRESENT, RING_NOT_ALLOCATED, RING_NOT_INITALIZED, RING_AVAILABLE, RING_CURRENTLY_USED, RING_STOPPED, RING_STATUS_UNKOWN, } KM_RING_STATUS; #endif // end: #ifndef KM_MAX_ELEMENTS_PER_EXEC_LIST -- above is for non-KMD environments. //***************************************************************************** // Struct: UK_EXECLIST_RING_BUFFER // PURPOSE: To describe status and access information of current ring buffer for a given EL context //***************************************************************************** typedef struct { KM_RING_STATUS RingStatus; // Status ADDRESS32 pExeclistRingContext; // uKernel Pointer to pExeclistRingContext ADDRESS32 pRingBegin; // uKernel address for RingBegin ADDRESS32 pRingEnd; // uKernel final byte address that is valid for this ring ADDRESS32 pNextFreeLocation; // uKernel address for next location in ring // ULONG CurrentTailPointerValue; // Last value written by software for tracking (just in case HW corrupts the tail in its context) } UK_EXECLIST_RING_BUFFER; typedef struct KM_PP_HWSP_REC { union { struct { DWORD Reserved0[4]; // 4 Reserved DWORDS at the beginning DWORD RingHeadPointer; DWORD Reserved1[11]; DWORD CumulativeContextRunTime; DWORD SubmitInfo; ULONG64 PreemptRequestTimestamp; ULONG64 ContextRestoreCompleteTimestamp; ULONG64 ContextSaveFinishedTimestamp; }; DWORD PpHwSp[KM_KBYTES_TO_DWORD_COUNT(4)]; }; } KM_PP_HWSP; #define KM_EXECLIST_CONTEXT_PPHWSP_SIZE PAGE_SIZE #define KM_EXECLIST_SHARED_DATA_SIZE PAGE_SIZE // Macros to get the offset of elements in the execution list context layout #define KM_EXECLIST_CONTEXT_GET_HHWSP_OFFSET ( KM_EXECLIST_SHARED_DATA_SIZE ) #define KM_EXECLIST_CONTEXT_GET_RING_CONTEXT_OFFSET ( KM_EXECLIST_SHARED_DATA_SIZE + KM_EXECLIST_CONTEXT_PPHWSP_SIZE ) #define KM_EXECLIST_CONTEXT_GET_ENGINE_STATE_OFFSET ( KM_EXECLIST_CONTEXT_GET_RING_CONTEXT_OFFSET + sizeof(KM_EXECLIST_HW_RING_CONTEXT) ) // Offsets in the BSPEC are from the beginning of the LRCA so they don't include the PPHWSP // Engine state doesnt' include the Ring Contxt though, so we will take a context DWORD offset // and remove the Ring Context from it via macro #define KM_CONTEXT_DWORD_OFFSET_TO_ENGINE_STATE_DWORD_OFFSET(Offset) \ (Offset - (sizeof(KM_EXECLIST_HW_RING_CONTEXT) / sizeof(DWORD) )) // Offsets in the BSPEC are from the beginning of the ring context so they don't include the PPHWSP // Engine state doesnt' include the Ring Contxt though, so we will take a context DWORD offset // and remove the Ring Context from it via macro #define KM_CONTEXT_DWORD_OFFSET_TO_ENGINE_STATE_DWORD_OFFSET(Offset) \ (Offset - (sizeof(KM_EXECLIST_HW_RING_CONTEXT) / sizeof(DWORD) )) //***************************************************************************** // Struct: UK_EXECLIST_CONTEXT // PURPOSE: The entire execlist context including software and HW information //***************************************************************************** typedef struct UK_EXECLIST_CONTEXT_REC { UK_ELEMENT_DESC ExecElement; UK_EXECLIST_RING_BUFFER RingBufferObj; UK_ENGINE_CONTEXT_STATE State; // State holds same info as SwitchReason (removed) SHORT PageFaultCount; // Number of pagefaults outstanding (possible negative numbers) SHORT EngineSubmitQueueCount; } UK_EXECLIST_CONTEXT; //***************************************************************************** // Struct: UK_KM_COMMON_CONTEXT_AREA_DESCRIPTOR // PURPOSE: A common area for communication from uKernel OS to Scheduler. //***************************************************************************** typedef struct UK_KM_COMMON_CONTEXT_AREA_DESCRIPTOR_REC { ULONG a; }UK_KM_COMMON_CONTEXT_AREA_DESCRIPTOR; //***************************************************************************** // Struct: UK_KM_CONTEXT_DESCRIPTOR // PURPOSE: Context descriptor for communicating between uKernel and KM Driver //***************************************************************************** typedef struct UK_KM_CONTEXT_DESCRIPTOR_REC { UK_KM_COMMON_CONTEXT_AREA_DESCRIPTOR UkSchedCommonArea; ULONG ContextID; ULONG PASID; IGFX_ENGINES_USED EnginesUsed; UK_KM_ADDRESS DoorbellTriggerAddress; // The doorbell page's trigger cacheline (Ptr to UK_KM_APP_DOORBELL_INFO) ADDRESS64 DoorbellTriggerAddressGPA; USHORT DoorbellID; // Do not modify manually once allocated UK_EXECLIST_CONTEXT ExecListContext[IGFX_ABSOLUTE_MAX_ENGINES]; union { struct { UCHAR IsContextActive : KM_BIT ( 0); // Is this context actively assigned to an app UCHAR IsPendingDoorbell : KM_BIT ( 1); UCHAR IsKMDCreatedContext : KM_BIT ( 2); // KMD Special WorkItems can be processed. UCHAR IsKMDPreemptContext : KM_BIT ( 3); // KMD Context used for preemption. This flag is used for tracking if preemption workload is complete. UCHAR IsContextEngReset : KM_BIT ( 4); // Context was part of engine reset. KMD must take appropriate action (this context will not be resubmitted until this bit is cleared) UCHAR WqProcessingLocked : KM_BIT ( 5); // Set it = 1 to prevent other code paths to do work queue processing as we use sampled values for WQ processing. Allowing multiple code paths to do WQ processing will cause same workload to execute multiple times. UCHAR IsDoorbellForPCHUse : KM_BIT ( 6); // If set to 1 at acquire doorbell time, this doorbell address will be programmed in appropriate XTM register so that PCH can ring the doorbell UCHAR IsContextTerminated : KM_BIT ( 7); // If set 1, the context is terminated by GuC, All the pending work is dropped, its doorbell is evicted and eventually this context will be removed. }; UCHAR BoolValues; }; UK_CONTEXT_PRIORITY Priority; ULONG WQSampledTailOffset; // Sampled and set during doorbell ISR handler ULONG TotalSubmitQueueEnqueues; // Global (across all submit queues) pending enqueues. ADDRESS32 pProcessDescriptor; // pProcessDescriptor is ptr to (UK_SCHED_PROCESS_DESCRIPTOR *) ADDRESS32 pWorkQueueAddress; ULONG WorkQueueSizeBytes; // WQ address & size is here because we do not trust // addresses in UK_SCHED_PROCESS_DESCRIPTOR //With the new Submit Queue Implementation also we do not do duplicate entries in the submit queue //for a context if it is already present in the submit queue. //The flag below are set if a context is present in the submit queue of the engine SCHED_CONTEXT_ENGINE_PRESENCE EnginePresence; // Note that a duplicate copy is in UK_SCHED_PROCESS_DESCRIPTOR is used for letting app know the status. // It is duplicated since app is not trusted that it will not write to that location and // Enginepresence is used in scheduling decisions. IGFX_ENGINES_USED EngineSchedSuspended; // EngineSchedSuspended is used in scheduling decisions. If the bit set, its schedule is suspended for corresponding engine. UCHAR Reserved0[3]; ULONG64 Reserved1[1]; // For GuC Internal use. MBZ at init time. }UK_KM_CONTEXT_DESCRIPTOR, ContextDescriptor; //* ContextDescriptor this is for Fulsim */ //***************************************************************************** // Struct: KM_GUC_CONTEXT_INFO // PURPOSE: Information about the actual contexts stored in the pool //***************************************************************************** typedef struct KM_GUC_POOLED_CONTEXT_INFO_REC { UK_KM_CONTEXT_DESCRIPTOR Context; // UK_KM_CONTEXT_DESCRIPTORs ULONG64 AssignedGuCGPUDesc; // CPU back pointer to the GPU descriptor (KM_GUC_GPU_DESC) to which this context is assigned to. }KM_GUC_POOLED_CONTEXT_INFO; //***************************************************************************** // Struct: KM_GUC_CONTEXT_POOL // PURPOSE: Descriptor record for the pool of UK_KM_CONTEXT_DESCRIPTOR s //***************************************************************************** typedef struct KM_GUC_CONTEXT_POOL_DESC_REC { ULONG64 GMMContextPoolHandle; //Memory Manager's handle to the pool of KM_GUC_POOLED_CONTEXT_INFO ULONG PoolGFXAddressBegin; //GFX Address of the pool of KM_GUC_POOLED_CONTEXT_INFO ULONG64 PoolCPUAddressBegin; //CPU address of the pool of KM_GUC_POOLED_CONTEXT_INFO ULONG AllocatedContextCount; //Total number of Contexts in pool ULONG AssignedContextCount; //Total number of context assigned to some app (contexts in use count) ULONG NextFreeContextIndex; //Next free index in the pool }KM_GUC_CONTEXT_POOL_DESC; //***************************************************************************** // Struct: KM_GUC_LOG_INIT_PARAMS // PURPOSE: Loging Parameters sent via sched_control_data. // Maintained as separate structure to allow debug tools to access logs without // contacting guc (for when Guc is stuck in ISR) //***************************************************************************** typedef struct KM_GUC_LOG_INIT_PARAMS_REC { union { struct { ULONG IsLogBufferValid : KM_BIT_RANGE( 0, 0); //Is logbuffer valid ULONG NotifyOnLogHalfFull : KM_BIT_RANGE( 1, 1); //Raises a GuC to Host interrupt when log buffer is half full. ULONG : KM_BIT_RANGE( 2, 2); ULONG AllocatedCountUnits : KM_BIT_RANGE( 3, 3); // 0 = Log buffer allocation in Pages, 1 = Log buffer allocation in Megabytes ULONG CrashDumpLogAllocatedCount : KM_BIT_RANGE( 5, 4); //No. of units allocated -1 for Crash Dump Log Buffer(MAX 4 Units) ULONG DpcLogAllocatedCount : KM_BIT_RANGE( 8, 6); //No. of units allocated -1 for DPC Log Buffer(MAX 8 Units) ULONG IsrLogAllocatedCount : KM_BIT_RANGE( 11, 9); //No. of units allocated -1 for ISR Log Buffer(MAX 8 Units) ULONG LogBufferGFXAddress : KM_BIT_RANGE( 31, 12); //Page aligned address for log buffer }; ULONG LogDwordValue; }; }KM_GUC_LOG_INIT_PARAMS; //Size must not exceed 1 DWORD //***************************************************************************** // Struct: SCHED_CONTROL_DATA_REC // PURPOSE: Holds the init values of various parameters used by the uKernel //***************************************************************************** typedef struct SCHED_CONTROL_DATA_REC { //Dword 0 union { struct { ULONG NumContextsInPool16Blocks : KM_BIT_RANGE( 11, 0); // Num of Contexts In Pool in blocks of 16, NumContextsInPool16Block = 1 if 16 contexts. 64 if 1024 contexts allocated. ULONG ContextPoolGFXAddressBegin : KM_BIT_RANGE( 31, 12); //Aligned bits [31:12] of the GFX address where the pool begins }; }; //Dword 1 union { ULONG ARATHighRegValue : KM_BIT_RANGE( 31, 0); // The value to be progammed into ARAT (timer) High register, upon uKernel load }; //Dword 2 union { ULONG ARATLowRegValue : KM_BIT_RANGE( 31, 0); // The value to be programmed into ARAT Low register, upon uKernel load. 0-> selects a default value by ukernel }; //Dword 3 //Device details on which the uKernel is loaded. //Specified by the driver to reduce code in uKernel. union { struct { ULONG GfxGtType : KM_BIT_RANGE( 6, 0); //Enum: GTTYPE ULONG GfxCoreFamily : KM_BIT_RANGE(12, 7); //Enum: GFXCORE_FAMILY ULONG usRevId : KM_BIT_RANGE(28, 13); //GFX rev ID. Set 0 unless there is a stepping specific WA to be done in uKernel ULONG : KM_BIT_RANGE(31, 29); }; ULONG DeviceDetailsDword; }; //Dword 4 // Log buffer setup KM_GUC_LOG_INIT_PARAMS LogInitParams; //Dword 5 //Page fault control union { struct { ULONG MinPageFaultsBeforeSwitch : KM_BIT_RANGE (10, 0); //Value should be (num faults - 1.) 0 -> 1 fault, 4 -> 5 faults ULONG : KM_BIT_RANGE (12,11); ULONG MinFaultsServicedBeforeRetry : KM_BIT_RANGE (23,13); //Value should be (num faults - 1.) 0 -> 1 fault, 4 -> 5 faults ULONG : KM_BIT_RANGE (25,24); ULONG : KM_BIT_RANGE (31,29); }; ULONG PageFaultControlDword; }; //Dword 6 //GuC uKernel Specific workarounds that needs to be applied. WA must have a HSD/traceable reference! union { struct { ULONG WaPreSiDummyGuC2HostOnCSInterrupt : KM_BIT ( 0); ULONG WaWorkaround1 : KM_BIT ( 1); ULONG WaDisableDefaultSchedulerPolicy : KM_BIT ( 2); ULONG WauKernelLoadedByDriver : KM_BIT ( 3); ULONG WaDisableDummyAllEngineFaultFix : KM_BIT ( 4); ULONG WaDisableLiteRestoreOptimization : KM_BIT ( 5); ULONG WaEnableMultipleAffectCountWrites : KM_BIT ( 6); ULONG WaReadBackAffectedCountAfterWrite : KM_BIT ( 7); ULONG WaUseGuc2HostFencingForSQFlush : KM_BIT ( 8); ULONG WaReadBackAffectedInfoAfterWrite : KM_BIT ( 9); ULONG WaEnableGoMsgToGAMDuringCPD : KM_BIT ( 10); ULONG WaDisable2ElemSubmission : KM_BIT ( 11); ULONG WaDisableDOPRenderClkGatingAtSubmit : KM_BIT ( 12); ULONG WaDummyWriteBeforeFenceCycle : KM_BIT ( 13); ULONG WaDisableSRAMRestoreDisable : KM_BIT ( 14); ULONG WaEnableGoMsgAckDuringCPD : KM_BIT ( 15); ULONG : KM_BIT_RANGE(31, 16); }; ULONG WorkaroundDW; }; //Dword 7 //GuC uKernel Specific features union { struct { ULONG FtrGuCEnableVCS2Engine : KM_BIT ( 0); // For GT3 configs. ULONG FtrKmdGuCSubmissions : KM_BIT ( 1); ULONG FtrFeature2 : KM_BIT ( 2); ULONG FtrGucPowerGating : KM_BIT ( 3); // For power gating ULONG FtrDisableGuCScheduler : KM_BIT ( 4); // Prevent GuC Scheduler from initializing ULONG FtrEnablePreemptionDataLogging : KM_BIT ( 5); // Enable tracking and logging preemption data ULONG FtrEnableGuCPAVPControl : KM_BIT ( 6); // Enable GuC PAVP Control ULONG FtrEnableGuCSlpm : KM_BIT ( 7); // Enable SLPM in GuC ULONG FtrEnableEngineResetOnPreemptFailure : KM_BIT ( 8); // Enable GuC Internal Reset feature. ULONG FtrNotApplicable : KM_BIT ( 9); ULONG FtrEnableAsyncFWInEngSchedule : KM_BIT ( 10); // For disabling tight poll on engine wake during schedule ULONG : KM_BIT_RANGE(31, 11); }; ULONG FeatureDword; }; //Dword 8 // Logging Verbosity Select and other tracking data control union { struct { ULONG LoggingVerbosity : KM_BIT_RANGE(3, 0); // defines the level of logging in uKernel. 0 -> logging only important events 3 -> logging at every step of execution ULONG LogOutputSelection : KM_BIT_RANGE(5, 4); // For log output to NPK/LogBuffer or both ULONG LoggingDisabled : KM_BIT_RANGE(6, 6); // Flag to indicate logging is enabled or not. Keeping the bit clear as logging enabled for backward comaptibility with Ukernel. ULONG ProfileEnabled : KM_BIT_RANGE(7, 7); // Flag to indicate profile logs are enabled. ULONG EnableWorkQueueItemTracking : KM_BIT_RANGE(8, 8); // This flag enables counting work items seen by each context. This mainly for debug. ULONG AdditionalDataStructsEnabled : KM_BIT_RANGE(9, 9); // Note: Additional data structs is *not* optional for most POR use cases of GuC. ULONG DefaultLoggingDisabled : KM_BIT_RANGE(10, 10); //Enable Logging Critical Messages always ULONG GfxAddressAdditionalDataStructs: KM_BIT_RANGE(31, 11); // Gfx Ptr to KM_GUC_ADDITIONAL_DATA_STRUCTS }; }; //Dword 9 union { struct { ULONG GfxAddressKmSharedData; }; }; }SCHED_CONTROL_DATA; //Enum to determine what mode the scheduler is in. typedef enum UK_SCHEDULER_MODE_REC { UK_SCHEDULER_MODE_NORMAL, //Standard scheduling mode no stalling UK_SCHEDULER_MODE_STALL_PER_PRESENT, //Stalls scheduling on all engines WI's whose header has IsPresentWorkload is to be scheduled UK_SCHEDULER_MODE_STALL_IMMEDIATE, //Stalls scheduling on all engines UK_SCHEDULER_MODE_STALL_IMMEDIATE_PREEMPT_TO_IDLE //Stalls scheduling on all engines and preempts any executing workloads }UK_SCHEDULER_MODE; typedef struct SCHED_SCHEDULING_POLICY_FLAGS_REC { union { struct { ULONG ResetEngineUponPreemptFailure : KM_BIT_RANGE(0, 0); // Should we reset engine when preemption failed within its time quantum ULONG PreemptToIdleOnQuantumExpiry : KM_BIT_RANGE(1, 1); // Should we preempt to idle unconditionaly for the execution quantum expiry. ULONG : KM_BIT_RANGE(31, 2); }; ULONG PolicyDword; }; }SCHED_SCHEDULING_POLICY_FLAGS; typedef struct SCHED_SCHEDULING_POLICY_REC { ULONG ExecutionQuantum; // Time for one workload to execute. (micro seconds) ULONG RSVD1; // MaxQuantumCredits Usage TBD: No. of schedule quantums before this queue has to give up even if it has work. ULONG WaitForPreemptionCompletionTime; // Time to wait for a preemption request to completed before issuing a reset. (micro seconds). ULONG QuantumUponFirstFaultTime; // How much time to allow to run after the first fault is observed. Then preempt afterwards. (micro seconds) SCHED_SCHEDULING_POLICY_FLAGS PolicyFlags; ULONG Rsvd; ULONG Rsvd2; }SCHED_SCHEDULING_POLICY; typedef struct SCHED_SCHEDULING_POLICIES_REC { SCHED_SCHEDULING_POLICY PerSubmitQueuePolicy[UK_CONTEXT_PRIORITY_ABSOLUTE_MAX_COUNT][IGFX_ABSOLUTE_MAX_ENGINES]; ULONG DPCPromoteTime; //In MicroSec. How much time to allow before DPC processing is called back via interrupt (to prevent DPC queue drain starving). Typically 1000s of micro seconds (example only, not granularity). ULONG IsValid; //Must be set to take these new values. ULONG MaxNumWorkItemsPerDpcCall; // Number of WIs to process per call to process single. Process Single could have a large Max Tail value which may keep CS idle. Process MaxNumWorkItemsPerDpcCall WIs and try fast schedule. ULONG Rsvd[19]; //Other global policies that may be used in future }SCHED_SCHEDULING_POLICIES; // Datastructures to keep the status of Logging Buffer. typedef enum UK_LOG_BUFFER_TYPE_ENUM { UK_ISR_LOG_BUFFER, UK_DPC_LOG_BUFFER, UK_CRASH_DUMP_LOG_BUFFER, UK_MAX_LOG_BUFFER, }UK_LOG_BUFFER_TYPE; typedef enum UK_LOG_VERBOSITY_ENUM { UK_LOG_VERBOSITY_LOW = 0x00, UK_LOG_VERBOSITY_MED = 0x01, UK_LOG_VERBOSITY_HIGH = 0x02, UK_LOG_VERBOSITY_ULTRA = 0x03, UK_LOG_VERBOSITY_MAX }UK_LOG_VERBOSITY; //This enum controls the type of logging output. Can be changed dynamically using Host2GuC interface. typedef enum LOGOUTPUT_SELECTION_REC { LOGOUTPUT_LOGBUFFER_ONLY = 0x0, LOGOUTPUT_NPK_ONLY = 0x1, LOGOUTPUT_LOGBUFFER_AND_NPK = 0x2, LOGOUTPUT_MAX }LOGOUTPUT_SELECTION; #define UK_KM_LOG_BUFFER_KMD_VERSION 1 // Filled by KMD except Version and Marker are initialized by uKernel typedef struct UK_KM_SCHED_STATISTICS_REC { ULONG Marker[2]; // Marks the beginning of statistics buffer ULONG Version; ULONG Reserved[5]; ULONG GlobalDoorbellRingCount; ULONG GlobalPreemptRequestCount; }UK_KM_SCHED_STATISTICS; // Filled by KMD except Version and Marker are initialized by uKernel typedef struct UK_KM_LOG_BUFFER_STATE_REC { ULONG Marker[2]; // Marks the beginning of Buffer Flush(set by uKernel at Log Buffer Init) ULONG LogBufRdPtr; // This is the Last Byte Offset Location that was read by KMD. KMD will write to this and uKernel will read this. ULONG LogBufWrPtr; // This is the Byte Offset Location that will be written by uKernel. ULONG LogBufSize; // Log Buffer size (set by KMD) ULONG SampledLogBufWrptr; // This is written by ukernel when it sees the log buffer becoming half full and KMD writes this value in the Log file to avoid stale data. union { struct { ULONG LogBufFlushToFile : KM_BIT_RANGE (0,0); // uKernel sets this when log buffer is half full or when a forced flush has been requested through host2guc. uKernel will send GUC2HOST only if this bit is cleared. This is to avoid unnecessary interrupts from GuC. ULONG BufferFullCount : KM_BIT_RANGE (4,1); // uKernel increments this when log buffer overflows ULONG : KM_BIT_RANGE (31,5); }; ULONG LogBufFlags; }; ULONG Version; }UK_KM_LOG_BUFFER_STATE; //***************************************************************************** // Struct: SCHED_PREEMPT_OPTIONS // PURPOSE: Options for Engine Preempt Host 2 GuC Actions //***************************************************************************** typedef struct SCHED_PREEMPT_OPTIONS_REC { //Dword 0 union { struct { ULONG AttemptScheduleBeforeReturn : KM_BIT ( 0); // After adding the Preempt Context ID to submit queue, attempt to schedule it to Runlist submit port before returning from the call. ULONG : KM_BIT ( 1); // MBZ ULONG PreemptTargetWorkQueueItems : KM_BIT ( 2); // For the target context ID, drop the work items in WQ that are targeted to this engine. ULONG DropSubmitQueueItemsOnPreempt : KM_BIT ( 3); // For the target priority, if flag is set, this flag drops the submit queue. Otherwise, reenqueues them back into submit queue ULONG ReportAffectedContexts : KM_BIT ( 4); // Applicable only of following KMD submissions. Report back the ptr to Execlist contexts in an array ULONG : KM_BIT_RANGE(31 ,5); }; ULONG OptionsDW; }; }SCHED_PREEMPT_OPTIONS; typedef struct SCHED_ENG_RESET_OPTIONS_REC { //Dword 0 union { struct { ULONG Reserved : KM_BIT ( 0); // After adding the Preempt Context ID to submit queue, attempt to schedule it to Runlist submit port before returning from the call. ULONG : KM_BIT ( 1); // MBZ ULONG Reserved1 : KM_BIT ( 2); // For the target context ID, drop the work items in WQ that are targeted to this engine. ULONG reserved2 : KM_BIT ( 3); // For the target priority, if flag is set, this flag drops the submit queue. Otherwise, reenqueues them back into submit queue ULONG ReportAffectedContexts : KM_BIT ( 4); // Applicable only of following KMD submissions. Report back the ptr to Execlist contexts in an array ULONG : KM_BIT_RANGE(31 ,5); }; ULONG OptionsDW; }; }SCHED_ENG_RESET_OPTIONS; /* This Status will be programmed in C1BC - SOFT_SCRATCH_15_REG */ typedef struct UK_GUC_TO_HOST_MESSAGE_RECORD { union { struct { ULONG UkInitDone : KM_BIT_RANGE(0, 0 ); ULONG CrashDumpPosted : KM_BIT_RANGE(1, 1 ); ULONG IommuPageFaulted : KM_BIT_RANGE(2, 2 ); ULONG FlushLogBufferToFile : KM_BIT_RANGE(3, 3 ); ULONG PreemptRequestOldPreemptPending : KM_BIT_RANGE(4, 4 ); // Preempt request was unable to start because an old preempt was already pending. Wait for some time. ULONG PreemptRequestTargetContextBad : KM_BIT_RANGE(5, 5 ); // Input Target context ID was incorrect / null. ULONG PreemptRequestInfoTargetHasWork : KM_BIT_RANGE(6, 6 ); // Information flag that indicates either submit queue has pending work. This is to help debug. ULONG SleepEntryInProgress : KM_BIT_RANGE(7, 7 ); // s3/s4 entry in progress. ULONG GuCInDebugHalt : KM_BIT_RANGE(8, 8 ); // Debug infinite loop is hit inserted in ukernel and is hit. This will halt kmd to carry on debug. ULONG GuCReportEngineResetContextId : KM_BIT_RANGE(9, 9 ); ULONG HuCAuthenticationFailed : KM_BIT_RANGE(10, 10); ULONG Reserved1 : KM_BIT_RANGE(15, 11); ULONG GpaToHpaXlationError : KM_BIT_RANGE(16, 16); ULONG DoorbellIDAllocationError : KM_BIT_RANGE(17, 17); ULONG DoorbellIDAllocationInvalidCtxID : KM_BIT_RANGE(18, 18); ULONG SetBackLightDutyCycle : KM_BIT_RANGE(19, 19); // Revisit later and remove if not needed by dpst/turbo. ULONG ForceWakeTimedOut : KM_BIT_RANGE(20, 20); ULONG ForceWakeTimeOutCounter : KM_BIT_RANGE(22, 21); // Max 4, just as an indication that time out happened multiple times ULONG PreemptRequestProcessDpcError : KM_BIT_RANGE(23, 23); ULONG IommuCatPageFaulted : KM_BIT_RANGE(24, 24); ULONG Reserved3 : KM_BIT_RANGE(28, 25); ULONG DoorbellIDReleaseError : KM_BIT_RANGE(29, 29); ULONG UkException : KM_BIT_RANGE(30, 30); ULONG BootromHalt : KM_BIT_RANGE(31, 31); }; ULONG Dw; }; }UK_GUC_TO_HOST_MESSAGE; // Note trigger is a write only register - it has no backing storage. #define KM_GEN8_REG_GUC_HOST2GUC_INTERRUPT (0xC4C8) #define KM_GEN8_RING_HOST2GUC_INTERRUPT (0x1) #define KM_GEN8_REG_GUC_HOST2GUC_IIR (0xC590) #define KM_GUC_SLEEP_STATE_ENTER_STATUS (0xc1b8) /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ typedef enum { HOST2GUC_ACTION_DEFAULT = 0x0, HOST2GUC_ACTION_REQUEST_INIT_DONE_INTERRUPT = 0x1, HOST2GUC_ACTION_REQUEST_PREEMPTION = 0x2, HOST2GUC_ACTION_REQUEST_ENGINE_RESET = 0x3, HOST2GUC_ACTION_PAUSE_SCHEDULING = 0x4, //Only for Dom0 type KMD HOST2GUC_ACTION_RESUME_SCHEDULING = 0x5, HOST2GUC_ACTION_SAMPLE_FORCEWAKE_FEATURE_REGISTER = 0x6, //SKL+ in case OS changes this register to enable/disable it after GuC init, GuC should resample it HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, HOST2GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE = 0x30, HOST2GUC_ACTION_CACHE_CRASH_DUMP = 0x200, // Cache address from host to send crash dump HOST2GUC_ACTION_DEBUG_RING_DB = 0x300, // For debugging, ring a doorbell via host 2 guc interrupt HOST2GUC_ACTION_PERFORM_GLOBAL_DEBUG_ACTIONS = 0x301, HOST2GUC_ACTION_FORCE_LOGBUFFERFLUSH = 0x302, // Force a flush of the log buffer in its current state by sending guc2host HOST2GUC_ACTION_UK_LOG_VERBOSITY_LOGOUTPUT_SELECT = 0x400, // Select Logging Verbosity (may be raised by kmdebugtools) OR logging output selection HOST2GUC_ACTION_RESET_ENGINE = 0x500, // Host OS calling for reset of a specific command streamer engine HOST2GUC_ACTION_ENTER_S_STATE = 0x501, // S3/S4 state HOST2GUC_ACTION_EXIT_S_STATE = 0x502, // S3/S4 state HOST2GUC_ACTION_PREPARE_FOR_TDR = 0x503, // State before. This is to ensure GuC does not touch TDR registers. HOST2GUC_ACTION_SET_SCHEDULING_MODE = 0x504, // Set scheduling mode. Currently used by DCC/DFPS HOST2GUC_ACTION_PM_TEST_BASE = 0x1000, HOST2GUC_ACTION_PM_TEST_END = 0x2000, // Action for PC: 0x3000-0x3FFF HOST2GUC_ACTION_PC_TURBO_REQUEST = 0x3001, HOST2GUC_ACTION_PC_DPST_REQUEST = 0x3002, HOST2GUC_ACTION_PC_SLPM_REQUEST = 0x3003, // End action for PC HOST2GUC_ACTION_AUTHENTICATE_HUC = 0x4000, HOST2GUC_ACTION_MAX = 0xF0000000 }HOST2GUC_ACTION; #define __MAKE_HOST2GUC_STATUS(a) (HOST2GUC_ACTION_MAX+a) typedef enum { HOST2GUC_STATUS_SUCCESS = __MAKE_HOST2GUC_STATUS(0x0), HOST2GUC_STATUS_ALLOCATE_DOORBELL_FAIL = __MAKE_HOST2GUC_STATUS(0x10), HOST2GUC_STATUS_DEALLOCATE_DOORBELL_FAIL = __MAKE_HOST2GUC_STATUS(0x20), HOST2GUC_STATUS_FULSIM_TEST_FAIL = __MAKE_HOST2GUC_STATUS(0x80), HOST2GUC_STATUS_LOG_ALLOCATION_TOO_SMALL = __MAKE_HOST2GUC_STATUS(0x80), // Not enough space allocated in host for entire log HOST2GUC_STATUS_LOG_HOST_ADDRESS_NOT_VALID = __MAKE_HOST2GUC_STATUS(0x80), // Location not in 48 bits, SRAM specified as type etc HOST2GUC_STATUS_LOG_DMA_FAILED = __MAKE_HOST2GUC_STATUS(0x80), // DMA transfer failed. Upper word will have error code from HW HOST2GUC_STATUS_UNKNOWN_ACTION = __MAKE_HOST2GUC_STATUS(0x100), HOST2GUC_STATUS_GENERIC_FAIL = __MAKE_HOST2GUC_STATUS(0x0000F000) }HOST2GUC_STATUS; #define KM_MAX_NUM_INPUT_DWORDS (14) #define KM_MAX_NUM_OUTPUT_DWORDS (16) //***************************************************************************** // Struct: KM_GUC_HOST_TO_GUC_REQUEST // PURPOSE: Used to pass info for doing a Host 2 Guc call within Driver //***************************************************************************** typedef struct KM_GUC_HOST_TO_GUC_REQUEST_REC { ULONG Rsvd; ULONG64 HwDeviceHandle; //In: HW_DEVICE_EXTENSION as ULONG64 ULONG *pInput; //In: Ptr to array of dwords for input ULONG NumOfInputDwords; //In: No. of Dwords in array ULONG WriteDisableMask; //In: Bitwise mask to disable write to registers for each Input dword. when BIT(x) is set, Input[x] won't be written. ULONG *pOutput; //In/Out: Out of read registers after successful host2guc. Also space must be allocated by caller for this array for the number of Dwords. ULONG NumOfOutputDwords; //In: No. of Dwords to read LONG ReturnStatus; //Out: NTSTATUS of H2G request TODO: Remove this windows specific status. } KM_GUC_HOST_TO_GUC_REQUEST; //***************************************************************************** // // Power Managment Module: SLPC // //***************************************************************************** #ifndef _SLPC_KMD_INTERFACE_H_ #define _SLPC_KMD_INTERFACE_H_ /**************************************************************** OVERVIEW ======== This is the glue between the SLPM core layer and the HAL layer that is provided by the OS under which the core is running (GuC, KMD). It defines the functions that need to be provided by the HAL layer to the SLPM core layer and visa versa. It also defines all structures that are shared between the SLPM core layer and the layer above the HAL (the Host). ****************************************************************/ #ifdef __cplusplus extern "C" { #endif //A way to force compile check in GCC/ICC. // It creates an unique typedef. #ifndef CASSERT #define _impl_PASTE(a,b) a##b #define _impl_CASSERT_LINE(predicate, line, file) typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1]; #define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate,__LINE__, file) #endif #define SLPM_BIT_RANGE(endbit, startbit) ((endbit)-(startbit)+1) #define SLPM_BIT(bit) (1) //--------------------------------------------------------------- //STATUS CODES //--------------------------------------------------------------- typedef enum _SLPM_STATUS { SLPM_STATUS_OK = 0, SLPM_STATUS_ERROR = 1, SLPM_STATUS_ILLEGAL_COMMAND = 2, SLPM_STATUS_INVALID_ARGS = 3, SLPM_STATUS_INVALID_PARAMS = 4, SLPM_STATUS_INVALID_DATA = 5, SLPM_STATUS_OUT_OF_RANGE = 6, SLPM_STATUS_NOT_SUPPORTED = 7, SLPM_STATUS_NOT_IMPLEMENTED = 8, SLPM_STATUS_NO_DATA = 9, SLPM_STATUS_EVENT_NOT_REGISTERED = 10, SLPM_STATUS_REGISTER_LOCKED = 11, SLPM_STATUS_TEMPORARILY_UNAVAILABLE = 12, SLPM_STATUS_VALUE_ALREADY_SET = 13, SLPM_STATUS_VALUE_ALREADY_UNSET = 14, SLPM_STATUS_VALUE_NOT_CHANGED = 15, SLPM_STATUS_MEMIO_ERROR = 16, SLPM_STATUS_EVENT_QUEUED_REQ_DPC = 17, SLPM_STATUS_EVENT_QUEUED_NOREQ_DPC = 18, SLPM_STATUS_NO_EVENT_QUEUED = 19, SLPM_STATUS_OUT_OF_SPACE = 20, SLPM_STATUS_TIMEOUT = 21, SLPM_STATUS_NO_LOCK = 22 } SLPM_STATUS; //--------------------------------------------------------------- //END OF STATUS CODES //--------------------------------------------------------------- //--------------------------------------------------------------- //ALL EVENTS THAT THE HAL WILL SEND TO SLPM CORE. //WHEN PASSING EVENTS TO THE ISR HANDLING INTERFACE (SLPM_PFN_EVENT_ISR) //15 DWORD PAYLOAD CAN BE PASSED IN. FOR EACH EVENT BELOW, ARGUMENTS ARE //DEFINED IN COMMENTS. //--------------------------------------------------------------- typedef enum _SLPM_EVENT_ID { SLPM_KMD_EVENT_RESET = 0, // Args[0] = lsb of SLPM_KMD_SHARED_DATA, Args[1] = msb of SLPM_KMD_SHARED_DATA, [OPTIONAL] Args[2] = Bitfield of SLPM_PROFILE_RESET_FLAGS SLPM_KMD_EVENT_SHUTDOWN = 1, // Args[0] = lsb of SLPM_KMD_SHARED_DATA, Args[1] = msb of SLPM_KMD_SHARED_DATA, [OPTIONAL] Args[2] = Bitfield of SLPM_PROFILE_RESET_FLAGS SLPM_KMD_EVENT_PLATFORM_INFO_CHANGE = 2, // Args[0] = lsb of SLPM_KMD_SHARED_DATA, Args[1] = msb of SLPM_KMD_SHARED_DATA SLPM_KMD_EVENT_DISPLAY_MODE_CHANGE = 3, // Args[0] = SLPM_KMD_DISPLAY_MODE_EVENT_PARAM.GlobalData, Args[1..5] = SLPM_KMD_DISPLAY_MODE_EVENT_PARAM.PerPipeData[1..5].Data, SLPM_KMD_EVENT_FLIP_COMPLETE = 4, // Args[0] = KM_FPS_TRACKING_FLIP_INFO SLPM_KMD_EVENT_QUERY_TASK_STATE = 5, SLPM_KMD_EVENT_PARAMETER_SET = 6, // Args[0] = SLPM_KMD_PARAM_ID, Args[1] = Value SLPM_KMD_EVENT_PARAMETER_UNSET = 7, // Args[0] = SLPM_KMD_PARAM_ID SLPM_END_KMD_EVENTS } SLPM_EVENT_ID; //--------------------------------------------------------------- //END OF EVENTS //--------------------------------------------------------------- //--------------------------------------------------------------- //ALL PARAMS - this is used to start parameter values in an array // and to use a bitfield at the start of the array to // flag the parameters that are set. //--------------------------------------------------------------- typedef enum _SLPM_KMD_PARAM_ID { // Please explicitly define values to reduce chance of mismatch SLPM_KMD_PARAM_TASK_ENABLE_GTPERF = 0, SLPM_KMD_PARAM_TASK_DISABLE_GTPERF = 1, SLPM_KMD_PARAM_TASK_ENABLE_BALANCER = 2, SLPM_KMD_PARAM_TASK_DISABLE_BALANCER = 3, SLPM_KMD_PARAM_TASK_ENABLE_DCC = 4, SLPM_KMD_PARAM_TASK_DISABLE_DCC = 5, SLPM_KMD_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6, // Special values defined in enum SLPM_GT_FREQ_MHZ SLPM_KMD_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7, // Special values defined in enum SLPM_GT_FREQ_MHZ SLPM_KMD_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8, // Special values defined in enum SLPM_GT_FREQ_MHZ SLPM_KMD_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9, // Special values defined in enum SLPM_GT_FREQ_MHZ SLPM_KMD_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10, SLPM_KMD_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11, // This does not need force enable. Freq range will take care of it when this is FALSE SLPM_KMD_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12, SLPM_KMD_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13, SLPM_KMD_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14, SLPM_KMD_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15, SLPM_KMD_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16, SLPM_KMD_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17, SLPM_KMD_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18, SLPM_KMD_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19, // Gaming mode refers to when display flip is exclusively controlled by game context using command streamer flips // Also add new ones at the end. 32 KMD parameters are reserved. SLPM_END_KMD_PARAMS, SLPM_KMD_PARAMS_MAX = 32, } SLPM_KMD_PARAM_ID; CASSERT(SLPM_END_KMD_PARAMS <= SLPM_KMD_PARAMS_MAX, UkGucKmdInterface_h); //--------------------------------------------------------------- //STRUCTURE THAT WILL BE PASSED TO SLPM CORE BOOTSTRAP. IT //CONTAINS THE HAL FUNCTION POINTERS THAT SLPM CORE CAN USE, //CONTEXT DATA THAT NEEDS TO BE PASSED TO THESE FUNCTIONS AND //SHARED DATA STRUCTURES. //--------------------------------------------------------------- typedef enum _SLPM_PLATFORM_SKU { SLPM_PLATFORM_SKU_UNDEFINED = 0, SLPM_PLATFORM_SKU_ULX = 1, SLPM_PLATFORM_SKU_ULT = 2, SLPM_PLATFORM_SKU_T = 3, SLPM_PLATFORM_SKU_MOBL = 4, SLPM_PLATFORM_SKU_DT = 5, SLPM_PLATFORM_SKU_UNKNOWN, SLPM_PLATFORM_SKU_ALL = 7 } SLPM_PLATFORM_SKU; CASSERT(SLPM_PLATFORM_SKU_UNKNOWN <= SLPM_PLATFORM_SKU_ALL, UkGucKmdInterface_h); typedef enum _SLPM_HW_POWERSRC { SLPM_POWERSRC_UNDEFINED = 0, SLPM_POWERSRC_AC = 1, SLPM_POWERSRC_DC = 2, SLPM_POWERSRC_UNKNOWN, SLPM_POWERSRC_ALL = 3 } SLPM_HW_POWERSRC; CASSERT(SLPM_POWERSRC_UNKNOWN <= SLPM_POWERSRC_ALL, UkGucKmdInterface_h); typedef enum _SLPM_HW_POWERPLAN { SLPM_POWERPLAN_UNDEFINED = 0, SLPM_POWERPLAN_BATTERY_SAVER = 1, SLPM_POWERPLAN_BALANCED = 2, SLPM_POWERPLAN_PERFORMANCE = 3, SLPM_POWERPLAN_UNKNOWN, SLPM_POWERPLAN_ALL = 7 } SLPM_HW_POWERPLAN; CASSERT(SLPM_POWERPLAN_UNKNOWN <= SLPM_POWERPLAN_ALL, UkGucKmdInterface_h); //--------------------------------------------------------------- //END OF SHARED HOST-SLPM STRUCTURES //--------------------------------------------------------------- //--------------------------------------------------------------- //STRUCTURES THAT ARE SHARED BETWEEN THE HOST AND SLPM CORE. //THESE STRUCTURES ENABLE THE HOST TO COMMUNICATE DATA //EFFICIENTLY TO THE SLPM. //--------------------------------------------------------------- typedef struct _SLPM_KMD_PLATFORM_INFO { union { ULONG Bitfield1; // SKU info struct { ULONG PlatformSku : SLPM_BIT_RANGE(7, 0); ULONG FusedSliceCnt : SLPM_BIT_RANGE(15, 8); ULONG Reserved : SLPM_BIT_RANGE(23, 16); ULONG PowerPlan : SLPM_BIT_RANGE(29, 24); ULONG PowerSrc : SLPM_BIT_RANGE(31, 30); }; }; union { ULONG Bitfield2; // IA capability info struct { ULONG MaxP0FreqBins : SLPM_BIT_RANGE(7, 0); ULONG P1FreqBins : SLPM_BIT_RANGE(15, 8); ULONG PeFreqBins : SLPM_BIT_RANGE(23, 16); ULONG PnFreqBins : SLPM_BIT_RANGE(31, 24); }; }; ULONG Reserved1; ULONG Reserved2; } SLPM_KMD_PLATFORM_INFO; typedef enum _SLPM_GLOBAL_STATE { SLPM_GLOBAL_STATE_NOT_RUNNING = 0, SLPM_GLOBAL_STATE_INITIALIZING = 1, SLPM_GLOBAL_STATE_RESETING = 2, SLPM_GLOBAL_STATE_RUNNING = 3, SLPM_GLOBAL_STATE_SHUTTING_DOWN = 4, SLPM_GLOBAL_STATE_ERROR = 5 } SLPM_GLOBAL_STATE; typedef struct _SLPM_TASK_STATE_DATA { union { ULONG Bitfield1; struct { // GT Perf data ULONG GtPerfTaskActive : SLPM_BIT(0); ULONG GtPerfIsStallPossible : SLPM_BIT(1); ULONG GtPerfInGamingMode : SLPM_BIT(2); ULONG GtPerfTargetFps : SLPM_BIT_RANGE(10, 3); //8bits to support upto 255FPS // DCC data ULONG DccTaskActive : SLPM_BIT(11); ULONG DccInDccMode : SLPM_BIT(12); ULONG DccInDctMode : SLPM_BIT(13); // Freq Switch data ULONG FreqSwitchActive : SLPM_BIT(14); // IBC/PG1 data ULONG IbcEnabled : SLPM_BIT(15); ULONG IbcActive : SLPM_BIT(16); ULONG PG1Enabled : SLPM_BIT(17); ULONG PG1Active : SLPM_BIT(18); }; }; union { ULONG Bitfield2; struct { ULONG FreqRangeUnsliceMax : SLPM_BIT_RANGE(7, 0); ULONG FreqRangeUnsliceMin : SLPM_BIT_RANGE(15, 8); ULONG FreqRangeSliceMax : SLPM_BIT_RANGE(23, 16); ULONG FreqRangeSliceMin : SLPM_BIT_RANGE(31, 24); }; }; }SLPM_TASK_STATE_DATA; #define SLPM_KMD_MAX_OVERRIDE_PARAMETERS 192 #define SLPM_UNSET_PARAM_SETARRAY(setarray, id) {setarray[(id >> 5)] &= (~(1 << (id % 32)));} #define SLPM_SET_PARAM_SETARRAY(setarray, id) {setarray[(id >> 5)] |= (1 << (id % 32));} #define SLPM_UNSET_PARAM(setarray, valarray, id) {setarray[(id >> 5)] &= (~(1 << (id % 32))); valarray[id] = 0;} #define SLPM_SET_PARAM(setarray, valarray, id, val) {setarray[(id >> 5)] |= (1 << (id % 32)); valarray[id] = val;} #define SLPM_GET_PARAM(setarray, valarray, id) valarray[id] #define SLPM_ISSET_PARAM(setarray, valarray, id) (setarray[(id >> 5)] & (1 << (id % 32))) CASSERT((SLPM_KMD_MAX_OVERRIDE_PARAMETERS & 0x1F) == 0, UkGucKmdInterface_h); typedef struct _SLPM_KMD_SHARED_DATA { ULONG Reserved; ULONG KmdSharedDataSize; // KMD must fill this in with the total size in bytes of this buffer. SLPM_GLOBAL_STATE KmdGlobalState; SLPM_KMD_PLATFORM_INFO KmdPlatformInfo; SLPM_TASK_STATE_DATA KmdTaskStateData; // KMD can override some of the internal parameters that are defined above in enum SLPM_KMD_PARAM_ID. // There is an array for storing the override value and a bitfield array for specifying which // elements of the array have been set. Use the above macros SLPM_UNSET_PARAM and SLPM_SET_PARAM to // update these arrays. ULONG KmdOverrideParametersSetBits[(SLPM_KMD_MAX_OVERRIDE_PARAMETERS + 31) / 32]; ULONG KmdOverrideParametersValues[SLPM_KMD_MAX_OVERRIDE_PARAMETERS]; } SLPM_KMD_SHARED_DATA; //--------------------------------------------------------------- //END OF SHARED HOST-SLPM STRUCTURES //--------------------------------------------------------------- //--------------------------------------------------------------- //STRUCTURES FOR DISPLAY MODE EVENT //--------------------------------------------------------------- #ifndef MAX_INTEL_PIPES #define MAX_INTEL_PIPES 3 #endif #ifndef MAX_PLANE_PER_PIPE #define MAX_PLANE_PER_PIPE 4 #endif #ifndef MAX_NUM_OF_PIPE #define MAX_NUM_OF_PIPE (MAX_INTEL_PIPES + 1) #endif typedef enum SLPM_PLANE_ENUM { SLPM_PLANE_1 = 0, SLPM_PLANE_2 = 1, SLPM_PLANE_3 = 2, SLPM_PLANE_4 = 3 }SLPM_PLANE; // Keep this structure in sync with KM_FPS_TRACKING_FLIP_INFO. typedef struct SLPM_KMD_FPS_TRACKING_FLIP_INFO_REC { union { ULONG Data; struct { ULONG BitwiseTargetPipe : MAX_NUM_OF_PIPE; ULONG PipeAPlane : MAX_PLANE_PER_PIPE; ULONG PipeBPlane : MAX_PLANE_PER_PIPE; ULONG PipeCPlane : MAX_PLANE_PER_PIPE; ULONG PipeTPVPlane : MAX_PLANE_PER_PIPE; //20bits ULONG VbiVsyncOn : 1; ULONG MpoEnabled : 1; ULONG FlipType : 2; //MMIO or DMA //reserved, let complier pack }; }; } SLPM_KMD_FPS_TRACKING_FLIP_INFO; typedef struct KMD_DISPLAY_PIPE_BASIC_INFO_REC { union { ULONG Data; struct { ULONG IsWiDi : 1; ULONG RefreshRate : 7; ULONG VSyncFTUsec : 24; }; }; }KMD_DISPLAY_PIPE_BASIC_INFO; typedef struct SLPM_KMD_DISPLAY_MODE_EVENT_PARAM_REC { struct { KMD_DISPLAY_PIPE_BASIC_INFO PerPipeInfo[MAX_NUM_OF_PIPE]; union { ULONG GlobalData; struct { ULONG BitwiseActivePipes : MAX_NUM_OF_PIPE; // Bitwise ULONG FullscreenPipes : MAX_NUM_OF_PIPE; // Bitwise - Fullscreen is defined as a pipe whose // display surfaces are not owned by the OS composer. ULONG VbiVsyncOnPipes : MAX_NUM_OF_PIPE; // Bitwise - Pipes that have VBI enabled. ULONG NumOfActivePipes : 2; }; }; }; } SLPM_KMD_DISPLAY_MODE_EVENT_PARAM; //--------------------------------------------------------------- //END OF STRUCTURES FOR DISPLAY MODE EVENT //--------------------------------------------------------------- //--------------------------------------------------------------- //RESET/SHUTDOWN EVENT FLAGS //--------------------------------------------------------------- typedef enum _SLPM_KMD_RESET_FLAGS { SLPM_KMD_RESET_FLAG_TDR_OCCURRED = (1 << 0) } SLPM_KMD_RESET_FLAGS; //--------------------------------------------------------------- //END OF RESET/SHUTDOWN EVENT FLAGS //--------------------------------------------------------------- //--------------------------------------------------------------- //STRUCTURE USED TO PASS IN EVENT INPUT DATA //--------------------------------------------------------------- #define SLPM_MAX_EVENT_INPUT_ARGS 7 #define SLPM_MAX_EVENT_OUTPUT_ARGS 1 CASSERT(SLPM_MAX_EVENT_INPUT_ARGS <= 14, UkGucKmdInterface_h); // Host2GuC gives us 15 scratch registers (the first we will use for the event ID). CASSERT(SLPM_MAX_EVENT_INPUT_ARGS >= (MAX_NUM_OF_PIPE + 1), UkGucKmdInterface_h); // SLPM_KMD_EVENT_DISPLAY_MODE_CHANGE requires the most number of arguments CASSERT(SLPM_MAX_EVENT_OUTPUT_ARGS >= 1, UkGucKmdInterface_h); // Host2GuC number of Output Args should be at least 1 CASSERT(SLPM_MAX_EVENT_OUTPUT_ARGS <= 14, UkGucKmdInterface_h); // Host2GuC gives us 15 scratch registers (the first we will use for the event ID). typedef union _SLPM_EVENT_INPUT_HEADER { ULONG HeaderData; struct { ULONG NumArgs : SLPM_BIT_RANGE(7, 0); ULONG EventId : SLPM_BIT_RANGE(15, 8); }; } SLPM_EVENT_INPUT_HEADER; typedef struct _SLPM_EVENT_INPUT { ULONG MessageId; // This is reserved for use when sending requests to GuC. SLPM_EVENT_INPUT_HEADER Header; ULONG Args[SLPM_MAX_EVENT_INPUT_ARGS]; } SLPM_EVENT_INPUT; typedef union _SLPM_EVENT_OUTPUT_HEADER { ULONG HeaderData; struct { ULONG NumArgs : SLPM_BIT_RANGE(7, 0); ULONG EventId : SLPM_BIT_RANGE(15, 8); ULONG Status : SLPM_BIT_RANGE(31, 16); }; } SLPM_EVENT_OUTPUT_HEADER; typedef struct _SLPM_EVENT_OUTPUT { ULONG Error; // This contains the result of the ISR function. SLPM_EVENT_OUTPUT_HEADER Header; ULONG Args[SLPM_MAX_EVENT_OUTPUT_ARGS]; } SLPM_EVENT_OUTPUT; //--------------------------------------------------------------- //EVENT INPUT DATA //--------------------------------------------------------------- #ifdef __cplusplus } #endif #endif //End of '#define _SLPC_KMD_INTERFACE_H_' #if defined (_MSC_VER) #pragma pack(pop) #else #pragma pack() #endif #endif /*_UK_GUCKMDINTEFACE_H_*/
Parent topic: Code Documentation