Hi Matt,
Thanks for your email.
Let me try to answer your question because of the designer of the TF-M interrupt handling is on leave now.
First, you are right about this: "If the interrupted partition is the same as the handler partition, interrupted_ctx_stack_frame_t and handler_ctx_stack_frame_t should be pushed at different location."
Let's start from an example, there are 3 SPs with different interrupt priority, SP1 < SP2 < SP3. And there is one scenario like this:
* SP1 is running, SP2 interrupt SP1. Current, the interrupted partition is SP1, and the handler partition is SP2.
As the below code show in tfm_spm_partition_push_handler_ctx(), the stack pointer will be moved upper as below:
SP2 stack pointer --->
Caller_partition_indx(handler)
Partition_sate(handler)
* SP2 starts to run, and it is interrupted by SP3. Current, the interrupted partition is SP2, and the handler partition is SP3.
As the code shown in tfm_spm_partition_push_interrupted_ctx(), it uses the current stack member directly without moving its pointer.
SP2 stack pointer --->
Partition_state(interrupted)
Caller_partition_indx(handler)
Partition_sate(handler) And after SP2 is interrupted by SP3, its partition status will be changed to "SPM_PARTITION_STATE_SUSPENDED". So that this partition will not be interrupted by others anymore unless it comes back to running state. Which means it does not need more stack anymore.
We can consider that after one SP is interrupted by others, there is no more stack is needed for it before it comes back to running status.
So I think it should be ok in the current design for the interrupt in the library model.
I am not sure if this can solve your confuse. Please feel free to give feedback. We can discuss more about it.
Thanks, Edison
From: TF-M tf-m-bounces@lists.trustedfirmware.org On Behalf Of lg via TF-M Sent: Monday, December 16, 2019 1:08 PM To: tf-m@lists.trustedfirmware.org Subject: [TF-M] irq handling in library mode
Hi TFM experts,
I have a question about the code logic of irq handling in library mode, code blocks in spm_api_func.c are as follows:
void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx) { struct spm_partition_runtime_data_t *runtime_data = &g_spm_partition_db.partitions[partition_idx].runtime_data; struct interrupted_ctx_stack_frame_t *stack_frame = (struct interrupted_ctx_stack_frame_t *)runtime_data->ctx_stack_ptr;
stack_frame->partition_state = runtime_data->partition_state; }
void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx) { struct spm_partition_runtime_data_t *runtime_data = &g_spm_partition_db.partitions[partition_idx].runtime_data; struct handler_ctx_stack_frame_t *stack_frame = (struct handler_ctx_stack_frame_t *) runtime_data->ctx_stack_ptr;
stack_frame->partition_state = runtime_data->partition_state; stack_frame->caller_partition_idx = runtime_data->caller_partition_idx;
runtime_data->ctx_stack_ptr += sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t); }
My question is why there is not the following such code logic at the end of function tfm_spm_partition_push_interrupted_ctx. runtime_data->ctx_stack_ptr += sizeof(struct interrupted_ctx_stack_frame_t ) / sizeof(uint32_t);
If the interrupted partition is the same as the handler partition, interrupted_ctx_stack_frame_t and handler_ctx_stack_frame_t should be pushed at different location.
And when pop the stack frame after handling irq, there is the following code logic in tfm_spm_partition_pop_handler_ctx runtime_data->ctx_stack_ptr -= sizeof(struct handler_ctx_stack_frame_t) / sizeof(uint32_t);
I think the same logic of changing ctx_stack_ptr should be added the begining of the function tfm_spm_partition_pop_interrupted_ctx like the above code logic in tfm_spm_partition_pop_handler_ctx. runtime_data->ctx_stack_ptr -= sizeof(struct interrupted_ctx_stack_frame_t ) / sizeof(uint32_t);
Please help to check.
Thanks, Matt