Пример #1
0
void syscall_DriverStandardCall(const _OS_Syscall_Args * param_info, const void * arg, void * ret)
{
    const UINT32 * uint_args = (const UINT32 *)arg;
	UINT32 * uint_ret = (UINT32 *)ret;
	OS_Return result = SYSCALL_ARGUMENT_ERROR;
	
	Klog32(KLOG_SYSCALL, "Syscall SubId - ", param_info->sub_id);
	
	switch(param_info->sub_id)
	{
    case SUBCALL_DRIVER_LOOKUP:
        if((param_info->arg_count >= 1) && (param_info->ret_count >= 2))
        {
        	result = _OS_DriverLookup((const INT8 *)uint_args[0], (OS_Driver_t *)(uint_ret+1));
        }
        break;
        
    case SUBCALL_DRIVER_OPEN:
        if(param_info->arg_count >= 2)
        {
        	result = _OS_DriverOpen((OS_Driver_t) uint_args[0], (OS_DriverAccessMode) uint_args[1]);
        }
        break;
            
    case SUBCALL_DRIVER_CLOSE:
        if(param_info->arg_count >= 1)
        {
        	result = _OS_DriverClose((OS_Driver_t) uint_args[0]);
        }
        break;
            
    case SUBCALL_DRIVER_READ:
        if((param_info->arg_count >= 4) && (param_info->ret_count >= 2))
        {
        	uint_ret[1] = uint_args[2];
        	result = _OS_DriverRead((OS_Driver_t) uint_args[0], (void *) uint_args[1], 
        							&uint_ret[1], (BOOL) uint_args[3]);
        }
        break;
        
    case SUBCALL_DRIVER_WRITE:
        if((param_info->arg_count >= 4) && (param_info->ret_count >= 2))
        {
        	uint_ret[1] = uint_args[2];
        	result = _OS_DriverWrite((OS_Driver_t) uint_args[0], (const void *) uint_args[1], 
        							&uint_ret[1], (BOOL) uint_args[3]);
        }
        break;
        
    case SUBCALL_DRIVER_CONFIGURE:
    
        break;
	}
	
	if(uint_ret) uint_ret[0] = result;
}
Пример #2
0
///////////////////////////////////////////////////////////////////////////////
// Kernel Side of the Syscall function
///////////////////////////////////////////////////////////////////////////////
void _OS_KernelSyscall(const _OS_Syscall_Args * param_info, const void * arg, void * ret)
{	
	if(!param_info || (param_info->id >= SYSCALL_MAX_COUNT) || !_syscall_handlers[param_info->id])
	{
		KlogStr(KLOG_WARNING, "Error occurred in Kernel function %s", __FUNCTION__);
		if(ret) ((UINT32 *)ret)[0] = SYSCALL_ARGUMENT_ERROR;
		return;
	}
	
	Klog32(KLOG_SYSCALL, "Syscall Id - ", param_info->id);
	
	// Note down the return pointer which may be needed to update the output parameters
	if(g_current_task) g_current_task->syscall_result = (UINT32 *)ret;
	_syscall_handlers[param_info->id](param_info, arg, ret);
}
Пример #3
0
OS_Return _OS_SemWait(OS_Sem_t sem)
{
	OS_Return status;
	
#if OS_ENABLE_CPU_STATS==1
    g_sched_starting_counter_value = _OS_Timer_GetCount(PERIODIC_TIMER);
#endif	

	if((status = assert_open(sem)) != SUCCESS) {
		goto exit;
	}

	// Get the Semaphore object
	OS_SemaphoreCB * semobj = (OS_SemaphoreCB *)&g_semaphore_pool[sem];

	// Make sure that the current process owns the Semaphore.
	if(semobj->owner != (OS_Process *) g_current_process)
	{
		status = RESOURCE_NOT_OWNED;
		goto exit;
	}

    // Get the task execution time
    UINT32 budget_spent = _OS_Timer_GetTimeElapsed_us(BUDGET_TIMER);
    g_current_task->accumulated_budget += budget_spent;
	
	if(IS_PERIODIC_TASK(g_current_task->attributes))
	{
	    // Adjust the remaining  budget for the current task
	    ASSERT(budget_spent <= ((OS_PeriodicTask *)g_current_task)->remaining_budget);
	    ((OS_PeriodicTask *)g_current_task)->remaining_budget -= budget_spent;		
	}

	// If the semaphore count is 0, then block the thread
	if(semobj->count == 0)
	{
		// Block the thread			
		if(IS_PERIODIC_TASK(g_current_task->attributes))
		{
			// Delete the current task from ready tasks queue
			_OS_QueueDelete(&g_ready_q, (void*)g_current_task); 
			
			// Add the current task to the semaphore's blocked queue for periodic tasks
			_OS_QueueInsert(&semobj->periodic_task_queue, (void*)g_current_task, 
				((OS_PeriodicTask *)g_current_task)->alarm_time); 
		}
		else
		{
			// Delete the current task from ready tasks queue
			_OS_QueueDelete(&g_ap_ready_q, (void*)g_current_task); 
			
			// Add the current task to the semaphore's blocked queue for aperiodic tasks
			_OS_QueueInsert(&semobj->aperiodic_task_queue, (void*)g_current_task, 
				((OS_AperiodicTask *)g_current_task)->priority);
		}
		
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore :- ", semobj->count);				
	}	
	else
	{
		// Decrement the semaphore count in order to acquire it
		semobj->count--;
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore - ", semobj->count);		
		
		// The return path for this function is through _OS_Schedule, so it is important to
		// update the result in the syscall_result
		if(g_current_task->syscall_result) 
			g_current_task->syscall_result[0] = SUCCESS;		
	}	
	
	_OS_Schedule();
	
exit:
	return status;
}
Пример #4
0
OS_Return _OS_SemPost(OS_Sem_t sem)
{
	OS_GenericTask* task = NULL;
	OS_Return status;
	UINT64 key = 0;
	
#if OS_ENABLE_CPU_STATS==1
    g_sched_starting_counter_value = _OS_Timer_GetCount(PERIODIC_TIMER);
#endif

	if((status = assert_open(sem)) != SUCCESS) {
		goto exit;
	}
	
	// Get the Semaphore object
	OS_SemaphoreCB * semobj = (OS_SemaphoreCB *)&g_semaphore_pool[sem];
	
	// Make sure that the current process owns the Semaphore.
	if(semobj->owner != (OS_Process *) g_current_process)
	{
		status = RESOURCE_NOT_OWNED;
		goto exit;
	}
	
    // Get the task execution time
    UINT32 budget_spent = _OS_Timer_GetTimeElapsed_us(BUDGET_TIMER);
    g_current_task->accumulated_budget += budget_spent;
	
	if(IS_PERIODIC_TASK(g_current_task->attributes))
	{
	    // Adjust the remaining  budget for the current task
	    ASSERT(budget_spent <= ((OS_PeriodicTask *)g_current_task)->remaining_budget);
	    ((OS_PeriodicTask *)g_current_task)->remaining_budget -= budget_spent;		
	}

	if(semobj->count == 0)
	{
		// Unblock a waiting task. First check the periodic queue
		_OS_QueueGet(&semobj->periodic_task_queue, (void**)&task, &key);
		if(task)
		{
			// Place this task in the periodic task ready queue
			_OS_QueueInsert(&g_ready_q,(void*)task, key);
		}
		else 
		{
			// Now check the Aperiodic queue
			_OS_QueueGet(&semobj->aperiodic_task_queue, (void**)&task, &key);
			if(task)
			{
				// Insert this task into Aperiodic task queue
				_OS_QueueInsert(&g_ap_ready_q,(void*)task,key);
			}
		}
	}
	
	if(task)
	{
		// If a task is getting ready, then there is no need to increment the semaphore count
		// The return path for this function is through _OS_Schedule, so it is important to
		// update the result in the syscall_result
		if(task->syscall_result) 
			task->syscall_result[0] = SUCCESS;
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore :+ ", semobj->count);		
	}
	else
	{
		// Increment the resource count
		semobj->count++;	
		Klog32(KLOG_SEMAPHORE_DEBUG, "Semaphore + ", semobj->count);		
	}
		
	_OS_Schedule();	
	
exit:
	return status;
}