From 23243ba966d1f5ba48e9cf3c0f8622e2c884b5da Mon Sep 17 00:00:00 2001 From: Shane Xiao Date: Fri, 13 Sep 2024 15:55:48 +0800 Subject: [PATCH] wsl/hsakmt: Add pm4 WRITE_DATA packet This patch adds WRITE_DATA packet, which will be used in no PCIe atomic platform. Signed-off-by: Shane Xiao Reviewed-by: Aaron Liu Reviewed-by: Longlong Yao Reviewed-by: Flora Cui Part-of: --- inc/pm4_cmds.h | 28 +++++++++++++++++++++++++++- inc/wddm/cmd_util.h | 5 +++++ wddm/cmd_util.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/inc/pm4_cmds.h b/inc/pm4_cmds.h index 82edddc8dd..d9e60fc086 100644 --- a/inc/pm4_cmds.h +++ b/inc/pm4_cmds.h @@ -37,6 +37,7 @@ union PM4_MEC_TYPE_3_HEADER { #define IT_DISPATCH_DIRECT 0x15 #define IT_ATOMIC_MEM 0x1E +#define IT_WRITE_DATA 0x37 #define IT_INDIRECT_BUFFER 0x3F #define IT_COPY_DATA 0x40 #define IT_EVENT_WRITE 0x46 @@ -238,6 +239,7 @@ struct PM4_MEC_WRITE_DATA { uint32_t ordinal3; }; uint32_t dst_mem_addr_hi; + uint64_t write_data_value; }; #define PERSISTENT_SPACE_START 0x00002c00 @@ -484,7 +486,6 @@ struct AtomicTemplate { /// location accessible to Gpu struct WriteDataTemplate { PM4_MEC_WRITE_DATA write_data; - uint64_t write_data_value; }; // ---------------------------------- MEC_COPY_DATA_src_sel_enum ---------------------------------- @@ -548,6 +549,31 @@ enum MEC_COPY_DATA_pq_exe_status_enum { pq_exe_status__mec_copy_data__phase_update = 1, }; +// ------------------------------- MEC_WRITE_DATA_dst_sel_enum ------------------------------- +enum MEC_WRITE_DATA_dst_sel_enum { + dst_sel__mec_write_data__mem_mapped_register = 0, + dst_sel__mec_write_data__tc_l2 = 2, + dst_sel__mec_write_data__gds = 3, + dst_sel__mec_write_data__memory = 5, + dst_sel__mec_write_data__memory_mapped_adc_persistent_state = 6 }; + +// ------------------------------- MEC_WRITE_DATA_addr_incr_enum ------------------------------- +enum MEC_WRITE_DATA_addr_incr_enum { + addr_incr__mec_write_data__increment_address = 0, + addr_incr__mec_write_data__do_not_increment_address = 1 }; + +// ------------------------------- MEC_WRITE_DATA_wr_confirm_enum ------------------------------- +enum MEC_WRITE_DATA_wr_confirm_enum { + wr_confirm__mec_write_data__do_not_wait_for_write_confirmation = 0, + wr_confirm__mec_write_data__wait_for_write_confirmation = 1 }; + +// ------------------------------- MEC_WRITE_DATA_cache_policy_enum ------------------------------- +enum MEC_WRITE_DATA_cache_policy_enum { + cache_policy__mec_write_data__lru = 0, + cache_policy__mec_write_data__stream = 1, + cache_policy__mec_write_data__noa = 2, + cache_policy__mec_write_data__bypass = 3 }; + typedef struct PM4_MEC_COPY_DATA { union { PM4_MEC_TYPE_3_HEADER header; /// header diff --git a/inc/wddm/cmd_util.h b/inc/wddm/cmd_util.h index 03a047888e..df92e7c233 100644 --- a/inc/wddm/cmd_util.h +++ b/inc/wddm/cmd_util.h @@ -48,6 +48,11 @@ public: uint32_t eventIndex = event_index__mec_event_write__cs_partial_flush, uint32_t eventType = CS_PARTIAL_FLUSH); + size_t BuildWriteData64Command( + void *pBuffer, + uint64_t* write_addr, + uint64_t write_value); + size_t BuildAcquireMem( uint8_t major, void *pBuffer); diff --git a/wddm/cmd_util.cpp b/wddm/cmd_util.cpp index bfd29049d6..d977eac731 100644 --- a/wddm/cmd_util.cpp +++ b/wddm/cmd_util.cpp @@ -53,6 +53,41 @@ size_t CmdUtil::BuildBarrier( return sizeof(barrier); } +/** + * Builds a WRITE_DATA packet. + * Writes two DWORDs into the GPU memory address "write_addr" + */ + +size_t CmdUtil::BuildWriteData64Command( + void* pBuffer, + uint64_t* write_addr, + uint64_t write_value) { + WriteDataTemplate command = {0}; + GenerateCmdHeader(&command.write_data, IT_WRITE_DATA); + + // Encode the user specified address to write to + uint64_t addr = uintptr_t(write_addr); + assert(!(addr & 0x3) && "WriteData address must be 4 byte aligned"); + + // Set the bit to confirm the write operation and cache policy + command.write_data.bitfields2.wr_confirm = wr_confirm__mec_write_data__wait_for_write_confirmation; + command.write_data.bitfields2.cache_policy = cache_policy__mec_write_data__bypass; + + // Specify the command to increment address if writing more than one DWord + command.write_data.bitfields2.addr_incr = addr_incr__mec_write_data__increment_address; + // Specify the class to which the write destination belongs + command.write_data.bitfields2.dst_sel = dst_sel__mec_write_data__memory; + + command.write_data.bitfields3c.dst_mem_addr_lo = (PtrLow32(write_addr) >> 2); + command.write_data.dst_mem_addr_hi = PtrHigh32(write_addr); + + // Specify the value to write + command.write_data.write_data_value = write_value; + + memcpy(pBuffer, &command, sizeof(command)); + return sizeof(command); +} + /* * Builds a ACQUIRE_MEM packet. * Users can submit this command to