optee_os/core/arch/arm/kernel/RT_TEE_Scheduler.c
// this function will examine the current priority queue and execute
this function will examine the current priority queue and execute
this function will examine the current priority queue and execute
static void schedule_world(int coreNum)
{
	set_next_timer_flag[coreNum] = 0;
	#ifdef IDLE_SCHEDULER
	if(rt_world_cores[SECURE_STATE][coreNum].has_nothing_to_run){
		rt_world_cores[SECURE_STATE][coreNum].has_nothing_to_run = 0;
		idle_scheduler_set_next_timer();
		return_to_normal_world();
	}
	execute_secure_world(coreNum);
	#endif
	#ifdef HIERARCHICAL_SCHEDULER
	if (rt_world_cores[SECURE_STATE][coreNum].has_nothing_to_run)
	{		
			if(rt_world_cores[SECURE_STATE][coreNum].runq_status == RUNQ_RUNNABLE)
			{	
				total_have_nothing_to_run += 1;
				rt_world_cores[SECURE_STATE][coreNum].runq_status = RUNQ_NOTHING_TO_RUN;
				set_has_nothing_to_run_timer(coreNum, rt_world_cores[SECURE_STATE][coreNum].nextEarliestJobRelease);
				rt_world_cores[NONSECURE_STATE][coreNum].runq_status = RUNQ_RUNNING;
				rt_world_cores[NONSECURE_STATE][coreNum].last_start = getCurrentTime_micro();
				return_to_normal_world();
			}
			else if( rt_world_cores[SECURE_STATE][coreNum].runq_status == RUNQ_NOTHING_TO_RUN && 
				rt_world_cores[SECURE_STATE][coreNum].nextEarliestJobRelease <= getCurrentTime_micro())
			{
				rt_world_cores[SECURE_STATE][coreNum].runq_status = RUNQ_RUNNABLE;
				rt_world_cores[SECURE_STATE][coreNum].has_nothing_to_run = false;
			}
			else if (rt_world_cores[SECURE_STATE][coreNum].runq_status == RUNQ_NOTHING_TO_RUN && 
				rt_world_cores[SECURE_STATE][coreNum].nextEarliestJobRelease > getCurrentTime_micro())
			{
				set_has_nothing_to_run_timer(coreNum, rt_world_cores[SECURE_STATE][coreNum].nextEarliestJobRelease);
				rt_world_cores[NONSECURE_STATE][coreNum].runq_status = RUNQ_RUNNING;
				rt_world_cores[NONSECURE_STATE][coreNum].last_start = getCurrentTime_micro();
				return_to_normal_world();
			}
			else
			{
				IMSG("Something very bad happen --- debug me!!!");
			}
	}
   if((rt_world_cores[SECURE_STATE][coreNum].runq_status    == RUNQ_RUNNABLE &&
       rt_world_cores[NONSECURE_STATE][coreNum].runq_status  == RUNQ_OUT_OF_BUDGET )
        ||
       (rt_world_cores[SECURE_STATE][coreNum].runq_status    == RUNQ_OUT_OF_BUDGET &&
       rt_world_cores[NONSECURE_STATE][coreNum].runq_status  == RUNQ_RUNNABLE )
       )
    {
        if(rt_world_cores[SECURE_STATE][coreNum].runq_status == RUNQ_RUNNABLE)
        	execute_secure_world(coreNum);  	
        else
        	execute_normal_world(coreNum);
    }
    else if(rt_world_cores[SECURE_STATE][coreNum].runq_status     == RUNQ_OUT_OF_BUDGET &&
            rt_world_cores[NONSECURE_STATE][coreNum].runq_status  == RUNQ_OUT_OF_BUDGET )
    {
        do_idle_processing(IDLE_PROCESSING_YIELD);
    }
    else
    {
        if(rt_world_cores[SECURE_STATE][coreNum].priority <= 
           rt_world_cores[NONSECURE_STATE][coreNum].priority)
        {
            execute_secure_world(coreNum);
        }
        else
        {
            execute_normal_world(coreNum);
        }
    }
    #endif
}
static void schedule_world ( int coreNum ) { set_next_timer_flag [ coreNum ] = 0 ; #ifdef IDLE_SCHEDULER if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . has_nothing_to_run ) { rt_world_cores [ SECURE_STATE ] [ coreNum ] . has_nothing_to_run = 0 ; idle_scheduler_set_next_timer ( ) ; return_to_normal_world ( ) ; } execute_secure_world ( coreNum ) ; #endif #ifdef HIERARCHICAL_SCHEDULER if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . has_nothing_to_run ) { if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_RUNNABLE ) { total_have_nothing_to_run += 1 ; rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status = RUNQ_NOTHING_TO_RUN ; set_has_nothing_to_run_timer ( coreNum , rt_world_cores [ SECURE_STATE ] [ coreNum ] . nextEarliestJobRelease ) ; rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . runq_status = RUNQ_RUNNING ; rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . last_start = getCurrentTime_micro ( ) ; return_to_normal_world ( ) ; } else if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_NOTHING_TO_RUN && rt_world_cores [ SECURE_STATE ] [ coreNum ] . nextEarliestJobRelease <= getCurrentTime_micro ( ) ) { rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status = RUNQ_RUNNABLE ; rt_world_cores [ SECURE_STATE ] [ coreNum ] . has_nothing_to_run = false ; } else if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_NOTHING_TO_RUN && rt_world_cores [ SECURE_STATE ] [ coreNum ] . nextEarliestJobRelease > getCurrentTime_micro ( ) ) { set_has_nothing_to_run_timer ( coreNum , rt_world_cores [ SECURE_STATE ] [ coreNum ] . nextEarliestJobRelease ) ; rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . runq_status = RUNQ_RUNNING ; rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . last_start = getCurrentTime_micro ( ) ; return_to_normal_world ( ) ; } else { IMSG ( " " ) ; } } if ( ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_RUNNABLE && rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . runq_status == RUNQ_OUT_OF_BUDGET ) || ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_OUT_OF_BUDGET && rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . runq_status == RUNQ_RUNNABLE ) ) { if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_RUNNABLE ) execute_secure_world ( coreNum ) ; else execute_normal_world ( coreNum ) ; } else if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . runq_status == RUNQ_OUT_OF_BUDGET && rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . runq_status == RUNQ_OUT_OF_BUDGET ) { do_idle_processing ( IDLE_PROCESSING_YIELD ) ; } else { if ( rt_world_cores [ SECURE_STATE ] [ coreNum ] . priority <= rt_world_cores [ NONSECURE_STATE ] [ coreNum ] . priority ) { execute_secure_world ( coreNum ) ; } else { execute_normal_world ( coreNum ) ; } } #endif }
this function will examine the current priority queue and execute
this function will examine the current priority queue and execute
//Idle Scheduler //return to normal world when secure world is idle //return from secure world first time after setting has_nothing_to_run, first burn normal world budgets, when it burn out, we can let it continue to run //first set timer to  //min(nearest secure task release,  //normal world budget(burn first and continue, no need to care about),secure world budget(X not used), // normal world deadline, secure world deadline) //no matter whether nw has budget //resume secure world after secure world release their jobs //normal world replenishent, when secure world get replenishened, it will become RUNQ_RUNNABLE (has bedget) //normal world become out of budget will also come into this branch (no budget) // check if both world are runnable, then run the one with higher priority  // when there is only one thing that needs to run, we will just run it //both worlds cannot run //return to normal world //both worlds can run // when both wants to run, we need to check which one has higher priority // otherwise, we will give the execution to normal world by default