@@ -210,6 +210,14 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct
210210 hwctx -> fw_ctx_id = resp .context_id ;
211211 WARN_ONCE (hwctx -> fw_ctx_id == -1 , "Unexpected context id" );
212212
213+ if (ndev -> force_preempt_enabled ) {
214+ ret = aie2_runtime_cfg (ndev , AIE2_RT_CFG_FORCE_PREEMPT , & hwctx -> fw_ctx_id );
215+ if (ret ) {
216+ XDNA_ERR (xdna , "failed to enable force preempt %d" , ret );
217+ return ret ;
218+ }
219+ }
220+
213221 cq_pair = & resp .cq_pair [0 ];
214222 x2i .mb_head_ptr_reg = AIE2_MBOX_OFF (ndev , cq_pair -> x2i_q .head_addr );
215223 x2i .mb_tail_ptr_reg = AIE2_MBOX_OFF (ndev , cq_pair -> x2i_q .tail_addr );
@@ -601,6 +609,11 @@ aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
601609 return 0 ;
602610}
603611
612+ static int aie2_cmdlist_unsupp (struct amdxdna_gem_obj * cmd_bo , void * slot , size_t * size )
613+ {
614+ return - EOPNOTSUPP ;
615+ }
616+
604617static u32 aie2_get_chain_msg_op (u32 cmd_op )
605618{
606619 switch (cmd_op ) {
@@ -621,6 +634,8 @@ static struct aie2_exec_msg_ops legacy_exec_message_ops = {
621634 .init_chain_req = aie2_init_exec_chain_req ,
622635 .fill_cf_slot = aie2_cmdlist_fill_cf ,
623636 .fill_dpu_slot = aie2_cmdlist_fill_dpu ,
637+ .fill_preempt_slot = aie2_cmdlist_unsupp ,
638+ .fill_elf_slot = aie2_cmdlist_unsupp ,
624639 .get_chain_msg_op = aie2_get_chain_msg_op ,
625640};
626641
@@ -680,6 +695,74 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
680695 return 0 ;
681696}
682697
698+ static int
699+ aie2_cmdlist_fill_npu_preempt (struct amdxdna_gem_obj * cmd_bo , void * slot , size_t * size )
700+ {
701+ struct cmd_chain_slot_npu * npu_slot = slot ;
702+ struct amdxdna_cmd_preempt_data * pd ;
703+ u32 cmd_len ;
704+ u32 arg_sz ;
705+
706+ pd = amdxdna_cmd_get_payload (cmd_bo , & cmd_len );
707+ arg_sz = cmd_len - sizeof (* pd );
708+ if (cmd_len < sizeof (* pd ) || arg_sz > MAX_NPU_ARGS_SIZE )
709+ return - EINVAL ;
710+
711+ if (* size < sizeof (* npu_slot ) + arg_sz )
712+ return - EINVAL ;
713+
714+ npu_slot -> cu_idx = amdxdna_cmd_get_cu_idx (cmd_bo );
715+ if (npu_slot -> cu_idx == INVALID_CU_IDX )
716+ return - EINVAL ;
717+
718+ memset (npu_slot , 0 , sizeof (* npu_slot ));
719+ npu_slot -> type = EXEC_NPU_TYPE_PREEMPT ;
720+ npu_slot -> inst_buf_addr = pd -> inst_buf ;
721+ npu_slot -> save_buf_addr = pd -> save_buf ;
722+ npu_slot -> restore_buf_addr = pd -> restore_buf ;
723+ npu_slot -> inst_size = pd -> inst_size ;
724+ npu_slot -> save_size = pd -> save_size ;
725+ npu_slot -> restore_size = pd -> restore_size ;
726+ npu_slot -> inst_prop_cnt = pd -> inst_prop_cnt ;
727+ npu_slot -> arg_cnt = arg_sz / sizeof (u32 );
728+ memcpy (npu_slot -> args , pd -> prop_args , arg_sz );
729+
730+ * size = sizeof (* npu_slot ) + arg_sz ;
731+ return 0 ;
732+ }
733+
734+ static int
735+ aie2_cmdlist_fill_npu_elf (struct amdxdna_gem_obj * cmd_bo , void * slot , size_t * size )
736+ {
737+ struct cmd_chain_slot_npu * npu_slot = slot ;
738+ struct amdxdna_cmd_preempt_data * pd ;
739+ u32 cmd_len ;
740+ u32 arg_sz ;
741+
742+ pd = amdxdna_cmd_get_payload (cmd_bo , & cmd_len );
743+ arg_sz = cmd_len - sizeof (* pd );
744+ if (cmd_len < sizeof (* pd ) || arg_sz > MAX_NPU_ARGS_SIZE )
745+ return - EINVAL ;
746+
747+ if (* size < sizeof (* npu_slot ) + arg_sz )
748+ return - EINVAL ;
749+
750+ memset (npu_slot , 0 , sizeof (* npu_slot ));
751+ npu_slot -> type = EXEC_NPU_TYPE_ELF ;
752+ npu_slot -> inst_buf_addr = pd -> inst_buf ;
753+ npu_slot -> save_buf_addr = pd -> save_buf ;
754+ npu_slot -> restore_buf_addr = pd -> restore_buf ;
755+ npu_slot -> inst_size = pd -> inst_size ;
756+ npu_slot -> save_size = pd -> save_size ;
757+ npu_slot -> restore_size = pd -> restore_size ;
758+ npu_slot -> inst_prop_cnt = pd -> inst_prop_cnt ;
759+ npu_slot -> arg_cnt = 1 ;
760+ npu_slot -> args [0 ] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN ;
761+
762+ * size = struct_size (npu_slot , args , npu_slot -> arg_cnt );
763+ return 0 ;
764+ }
765+
683766static u32 aie2_get_npu_chain_msg_op (u32 cmd_op )
684767{
685768 return MSG_OP_CHAIN_EXEC_NPU ;
@@ -691,6 +774,8 @@ static struct aie2_exec_msg_ops npu_exec_message_ops = {
691774 .init_chain_req = aie2_init_npu_chain_req ,
692775 .fill_cf_slot = aie2_cmdlist_fill_npu_cf ,
693776 .fill_dpu_slot = aie2_cmdlist_fill_npu_dpu ,
777+ .fill_preempt_slot = aie2_cmdlist_fill_npu_preempt ,
778+ .fill_elf_slot = aie2_cmdlist_fill_npu_elf ,
694779 .get_chain_msg_op = aie2_get_npu_chain_msg_op ,
695780};
696781
@@ -749,6 +834,16 @@ aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo,
749834 case ERT_START_NPU :
750835 ret = EXEC_MSG_OPS (xdna )-> fill_dpu_slot (cmd_abo , slot , size );
751836 break ;
837+ case ERT_START_NPU_PREEMPT :
838+ if (!AIE2_FEATURE_ON (xdna -> dev_handle , AIE2_PREEMPT ))
839+ return - EOPNOTSUPP ;
840+ ret = EXEC_MSG_OPS (xdna )-> fill_preempt_slot (cmd_abo , slot , size );
841+ break ;
842+ case ERT_START_NPU_PREEMPT_ELF :
843+ if (!AIE2_FEATURE_ON (xdna -> dev_handle , AIE2_PREEMPT ))
844+ return - EOPNOTSUPP ;
845+ ret = EXEC_MSG_OPS (xdna )-> fill_elf_slot (cmd_abo , slot , size );
846+ break ;
752847 default :
753848 XDNA_INFO (xdna , "Unsupported op %d" , op );
754849 ret = - EOPNOTSUPP ;
0 commit comments