blob: 08f976f4a5c182394f98680967d3e48e024e703f [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2018
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*****************************************************************************
37*
38* Filename:
39* ---------
40* mer_kernel_task.h
41*
42* Project:
43* --------
44* MERTOS
45*
46* Description:
47* ------------
48* Declare task related API header.
49*
50* Author:
51* -------
52 * -------
53*
54*****************************************************************************/
55#ifndef _MER_KERNEL_TASK_H_
56#define _MER_KERNEL_TASK_H_
57
58#include "mer_kernel_config_public.h"
59#include "mer_kernel_scheduler.h"
60#include "mer_service_task.h"
61#include "mer_kernel_switch_target.h"
62#include "mer_kernel_lock_target.h"
63#include "mer_config_public.h"
64#include <stddef.h>
65
66///////////////////////////////////////////////////////////////////////////////
67// Porting variable
68///////////////////////////////////////////////////////////////////////////////
69typedef mer_service_task_cb mer_kernel_task_cb;
70
71/* Make sure the sp is the first element in the control block */
72MER_CASSERT(offsetof(mer_kernel_task_cb, stack_ptr) == 0);
73
74/* Make sure the offset of stack_end in the control block matches with ASM */
75#if defined(__MD97__) || defined(__MD97P__)
76#include "mer_kernel_switch_target_shaolin.inc"
77MER_CASSERT(offsetof(mer_kernel_task_cb, last_execution_vpe) == MER_KERNEL_SWITCH_LAST_EXE_VPE_OFFSET);
78#endif /* defined(__MD97__) || defined(__MD97P__) */
79
80
81///////////////////////////////////////////////////////////////////////////////
82// Macro
83///////////////////////////////////////////////////////////////////////////////
84#define MER_KERNEL_TASK_LEVEL_BIT 31
85#define MER_KERNEL_TASK_LEVEL_MASK (1 << MER_KERNEL_TASK_LEVEL_BIT)
86#define MER_KERNEL_TASK_APPEND_PRIORITY(task_id) ((1 << MER_KERNEL_TASK_LEVEL_BIT) | (task_id))
87#define MER_KERNEL_TASK_REMOVE_PRIORITY(task_id) ((~(1 << MER_KERNEL_TASK_LEVEL_BIT)) & (task_id))
88#define MER_KERNEL_TASK_NUM mer_kernel_task_num
89#define MER_KERNEL_TASK_MASK_NUM mer_kernel_task_mask_num
90#define MER_KERNEL_TASK_TOP_MASK_NUM mer_kernel_task_top_mask_num
91
92/* context means it is either preempted by ISR or running */
93/* For task, it is either bit 31 or bit 29 */
94#define MER_KERNEL_TASK_CONTEXT_MASK (MER_KERNEL_TASK_LEVEL_MASK | (1 << (MER_KERNEL_TASK_LEVEL_BIT-2)))
95
96
97///////////////////////////////////////////////////////////////////////////////
98// Enum
99///////////////////////////////////////////////////////////////////////////////
100
101
102
103///////////////////////////////////////////////////////////////////////////////
104// Structure
105///////////////////////////////////////////////////////////////////////////////
106typedef struct {
107 mer_uint32 *mask;
108} mer_kernel_task_top_mask;
109
110typedef struct {
111 mer_uint32 *mask;
112} mer_kernel_task_mask;
113
114typedef mer_uint32 mer_kernel_task_id;
115///////////////////////////////////////////////////////////////////////////////
116// External variable
117///////////////////////////////////////////////////////////////////////////////
118
119extern mer_kernel_task_cb mer_kernel_task_info_table[];
120extern mer_uint8 mer_kernel_task_dummy_stack[];
121
122extern mer_kernel_task_top_mask mer_kernel_task_top_ready_mask[MIPS_HW_VPE_NUM];
123extern mer_kernel_task_mask mer_kernel_task_ready_mask[MIPS_HW_VPE_NUM];
124
125extern mer_uint32 mer_kernel_task_info_table_begin;
126extern mer_uint32 mer_kernel_task_info_table_end;
127
128extern mer_uint32 mer_kernel_task_idle_priority_begin;
129
130extern const mer_uint32 mer_kernel_task_num;
131extern const mer_uint32 mer_kernel_task_mask_num;
132extern const mer_uint32 mer_kernel_task_top_mask_num;
133
134///////////////////////////////////////////////////////////////////////////////
135// External functions
136///////////////////////////////////////////////////////////////////////////////
137void mer_kernel_task_remove(mer_kernel_task_id);
138void mer_kernel_task_insert(mer_kernel_task_id);
139void mer_kernel_task_set_running_state(mer_kernel_task_id task_id);
140void mer_kernel_task_update_ready_job(mer_uint32 vpe_id);
141void mer_kernel_task_suspend(mer_kernel_task_id task_id, mer_service_task_state suspend_reason);
142void mer_kernel_task_resume(mer_kernel_task_cb* cb, mer_service_task_state suspend_reason);
143void mer_kernel_task_initialization();
144void mer_kernel_task_default_main();
145void mer_kernel_task_set_priority(mer_kernel_task_id source, mer_kernel_task_id target_priority);
146void mer_kernel_task_change_current_affinity(mer_uint32 affinity_mask);
147void mer_kernel_task_set_affinity_to_current_vpe();
148void mer_kernel_task_resume_and_return(mer_kernel_task_cb* cb, mer_service_task_state suspend_reason);
149
150#if defined(__MER_CONFIG_USE_DYNAMIC_ALLOCATION__)
151void mer_kernel_task_stack_allocation();
152#endif /* __MER_CONFIG_USE_DYNAMIC_ALLOCATION__ */
153
154///////////////////////////////////////////////////////////////////////////////
155// Static inline functions
156///////////////////////////////////////////////////////////////////////////////
157/**
158 * Return the task priority by cb
159 * Note that this function assume the schedule lock is taken
160 *
161 * Time complexity O(1)
162 *
163 * @param[out] The task priority
164 * @param[in] cb
165 *
166 */
167static inline mer_kernel_task_id mer_kernel_task_get_priority(mer_kernel_task_cb *cb){
168
169 return cb->priority;
170}
171
172/**
173 * Return the inheritor task index by cb
174 * Note that this function assume the schedule lock is taken
175 *
176 * Time complexity O(1)
177 *
178 * @param[out] The inheritor task index
179 * @param[in] cb
180 *
181 */
182static inline mer_kernel_task_id mer_kernel_task_get_inheritor_task_index(mer_kernel_task_cb *cb){
183
184 return cb->inheritor_task_index;
185}
186
187/**
188 * Return the task index with cb pointer
189 *
190 *
191 * Time complexity O(1)
192 *
193 * @param[out] Index of input cb pointer
194 * @param[in] The task pointer
195 *
196 */
197static inline mer_uint32 mer_kernel_task_get_index(mer_kernel_task_cb *cb){
198
199 //return (mer_uint32)(cb - mer_kernel_task_info_table);
200 return (mer_uint32) cb->job_index;
201}
202
203/**
204 * Return the current running task priority
205 * Note that this function assume the schedule lock is taken
206 *
207 * If we have private memory, no need lock anymore
208 *
209 * Time complexity O(1)
210 *
211 * @param[out] The current task id
212 * @param[in] vpe_id
213 *
214 */
215static inline mer_kernel_task_id mer_kernel_task_get_current_priority(){
216#if defined(__MER_KERNEL_USE_MIPS_CP0_CONTEXT_REG__)
217 mer_kernel_task_cb *cb = (mer_kernel_task_cb *)(MER_KERNEL_GET_CURRENT_CONTROL_BLOCK());
218 return cb->priority;
219#else
220 mer_uint32 current_vpe = mer_kernel_utility_get_current_vpe_id();
221 return MER_KERNEL_TASK_REMOVE_PRIORITY(mer_kernel_scheduler_running_job[current_vpe].priority);
222#endif
223}
224/**
225 * Return the current running task index
226 * Note that this function assume the schedule lock is taken
227 *
228 * If we have private memory, no need lock anymore
229 *
230 * Time complexity O(1)
231 *
232 * @param[out] The current task id
233 * @param[in] vpe_id
234 *
235 */
236__attribute__((always_inline)) static inline mer_kernel_task_id mer_kernel_task_get_current_index(){
237
238#if defined(__MER_KERNEL_USE_MIPS_CP0_CONTEXT_REG__)
239 mer_kernel_task_cb *cb = (mer_kernel_task_cb *)(MER_KERNEL_GET_CURRENT_CONTROL_BLOCK());
240 return mer_kernel_task_get_index(cb);
241#else
242 mer_uint32 current_vpe = mer_kernel_utility_get_current_vpe_id();
243 return mer_kernel_scheduler_running_job[current_vpe].job_index;
244#endif /* __MER_KERNEL_USE_MIPS_CP0_CONTEXT_REG__ */
245}
246
247/**
248 * Return the current running task cb pointer
249 * Note that this function assume the schedule lock is taken
250 *
251 * If we have private memory, no need lock anymore
252 *
253 * Time complexity O(1)
254 *
255 * @param[out] cb pointer
256 * @param[in] vpe_id
257 *
258 */
259static inline mer_kernel_task_cb * mer_kernel_task_get_current_cb(){
260#if defined(__MER_KERNEL_USE_MIPS_CP0_CONTEXT_REG__)
261 return (mer_kernel_task_cb *)(MER_KERNEL_GET_CURRENT_CONTROL_BLOCK());
262#else
263 mer_uint32 current_vpe = mer_kernel_utility_get_current_vpe_id();
264 mer_uint32 job_index = mer_kernel_scheduler_running_job[current_vpe].job_index;
265 return &mer_kernel_task_info_table[job_index];
266#endif /* __MER_KERNEL_USE_MIPS_CP0_CONTEXT_REG__ */
267}
268
269/**
270 * Return the state of specified task control block
271 *
272 *
273 * Time complexity O(1)
274 *
275 * @param[out] State of input cb pointer
276 * @param[in] The task pointer
277 *
278 */
279static inline mer_service_task_state mer_kernel_task_get_state(mer_kernel_task_cb *cb){
280
281 return cb->state;
282}
283
284#endif /* _MER_KERNEL_TASK_H_ */
285