Пример #1
0
void thinkos_ev_wait_svc(int32_t * arg)
{
	unsigned int wq = arg[0];
	unsigned int no = wq - THINKOS_EVENT_BASE;
	int self = thinkos_rt.active;
	unsigned int ev;

#if THINKOS_ENABLE_ARG_CHECK

	if (no >= THINKOS_EVENT_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not an event set!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_EVENT_ALLOC
	if (__bit_mem_rd(&thinkos_rt.ev_alloc, no) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid event set %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	cm3_cpsid_i();

	/* check for any pending unmasked event */
	if ((ev = __clz(__rbit(thinkos_rt.ev[no].pend & 
						   thinkos_rt.ev[no].mask))) < 32) {
		DCC_LOG2(LOG_MSG, "set=0x%08x msk=0x%08x", 
				 thinkos_rt.ev[no].pend, thinkos_rt.ev[no].mask);
		__bit_mem_wr(&thinkos_rt.ev[no].pend, ev, 0);  
		DCC_LOG2(LOG_INFO, "pending event %d.%d!", wq, ev);
		arg[0] = ev;
		cm3_cpsie_i();
		return;
	} 

	/* insert into the wait queue */
	__thinkos_wq_insert(wq, self);

	/* wait for event */
	/* remove from the ready wait queue */
	__bit_mem_wr(&thinkos_rt.wq_ready, thinkos_rt.active, 0);  
#if THINKOS_ENABLE_TIMESHARE
	/* if the ready queue is empty, collect
	 the threads from the CPU wait queue */
	if (thinkos_rt.wq_ready == 0) {
		thinkos_rt.wq_ready = thinkos_rt.wq_tmshare;
		thinkos_rt.wq_tmshare = 0;
	}
#endif

	cm3_cpsie_i();

	DCC_LOG2(LOG_INFO, "<%d> waiting for event %d.xx ...", self, wq);

	/* signal the scheduler ... */
	__thinkos_defer_sched();

}
Пример #2
0
void thinkos_sem_wait_svc(int32_t * arg)
{	
	unsigned int wq = arg[0];
	unsigned int sem = wq - THINKOS_SEM_BASE;
	int self = thinkos_rt.active;

#if THINKOS_ENABLE_ARG_CHECK
	if (sem >= THINKOS_SEMAPHORE_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not a semaphore!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_SEM_ALLOC
	if (__bit_mem_rd(thinkos_rt.sem_alloc, sem) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid semaphore %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	arg[0] = 0;

	/* avoid possible race condition on sem_val */
	/* this is only necessary in case we use the __uthread_sem_post() call
	   inside interrupt handlers */
	/* TODO: study the possibility of using exclusive access instead of 
	   disabling interrupts. */
	cm3_cpsid_i();

	if (thinkos_rt.sem_val[sem] > 0) {
		thinkos_rt.sem_val[sem]--;
		/* reenable interrupts ... */
		cm3_cpsie_i();
		return;
	} 
	
	/* insert into the semaphore wait queue */
	__thinkos_wq_insert(wq, self);
	DCC_LOG2(LOG_INFO, "<%d> waiting on semaphore %d...", self, wq);
	/* wait for event */
	/* remove from the ready wait queue */
	__bit_mem_wr(&thinkos_rt.wq_ready, self, 0);  
#if THINKOS_ENABLE_TIMESHARE
	/* if the ready queue is empty, collect
	   the threads from the CPU wait queue */
	if (thinkos_rt.wq_ready == 0) {
		thinkos_rt.wq_ready = thinkos_rt.wq_tmshare;
		thinkos_rt.wq_tmshare = 0;
	}
#endif
	/* reenable interrupts ... */
	cm3_cpsie_i();

	/* signal the scheduler ... */
	__thinkos_defer_sched();
}
Пример #3
0
void isink_test(void)
{
	unsigned int pre;
	unsigned int pulse;
	int mode;

	pre = 500;
	pulse = 1000;

	/* disable interrupts */	
	cm3_cpsid_i();
	for (mode = 0; mode < 26; ++mode) {
		isink_io_cfg(mode);
		isink_pulse(pre, pulse);
		udelay(pulse + 500);
	}
	cm3_cpsie_i();

	isink_drv.mode = -1;
}
Пример #4
0
void cm3_udelay_calibrate(void)
{
	struct cm3_systick * systick = CM3_SYSTICK;
	uint32_t ticks1ms;
	uint32_t rvr;
	uint32_t csr;

	cm3_cpsid_i();
	rvr = systick->rvr;
	csr = systick->csr;

	systick->rvr = 0x00ffffff;
	systick->csr = SYSTICK_CSR_ENABLE;
	ticks1ms = cm3_systick_load_1ms << 8;

	udelay_calibrate(ticks1ms, cm3_get_ticks);

	systick->rvr = rvr;
	systick->csr = csr;

	cm3_cpsie_i();
}
Пример #5
0
void thinkos_sem_post_svc(int32_t * arg)
{	
	unsigned int wq = arg[0];
	unsigned int sem = wq - THINKOS_SEM_BASE;
	int th;

#if THINKOS_ENABLE_ARG_CHECK
	if (sem >= THINKOS_SEMAPHORE_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not a semaphore!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_SEM_ALLOC
	if (__bit_mem_rd(thinkos_rt.sem_alloc, sem) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid semaphore %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	arg[0] = 0;

	cm3_cpsid_i();
	if ((th = __thinkos_wq_head(wq)) == THINKOS_THREAD_NULL) {
		/* no threads waiting on the semaphore, increment. */ 
		thinkos_rt.sem_val[sem]++;
	} else {
		/* wakeup from the sem wait queue */
		__thinkos_wakeup(wq, th);
		DCC_LOG2(LOG_INFO, "<%d> wakeup from sem %d ", th, wq);
		/* signal the scheduler ... */
		__thinkos_defer_sched();
	}

	cm3_cpsie_i();

}
Пример #6
0
void thinkos_sem_trywait_svc(int32_t * arg)
{	
	unsigned int wq = arg[0];
	unsigned int sem = wq - THINKOS_SEM_BASE;

#if THINKOS_ENABLE_ARG_CHECK
	if (sem >= THINKOS_SEMAPHORE_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not a semaphore!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_SEM_ALLOC
	if (__bit_mem_rd(thinkos_rt.sem_alloc, sem) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid semaphore %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	/* avoid possible race condition on sem_val */
	/* this is only necessary in case we use the __uthread_sem_post() call
	   inside interrupt handlers */
	/* TODO: study the possibility of using exclusive access instead of 
	   disabling interrupts. */
	cm3_cpsid_i();

	if (thinkos_rt.sem_val[sem] > 0) {
		thinkos_rt.sem_val[sem]--;
		arg[0] = 0;
	} else {
		arg[0] = THINKOS_EAGAIN;
	}

	cm3_cpsie_i();
}
Пример #7
0
void thinkos_ev_unmask_svc(int32_t * arg)
{
	unsigned int wq = arg[0];
	uint32_t mask = arg[1];
	unsigned int no = wq - THINKOS_EVENT_BASE;
	unsigned int ev;
	int th;

#if THINKOS_ENABLE_ARG_CHECK
	if (no >= THINKOS_EVENT_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not an event set!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_EVENT_ALLOC
	if (__bit_mem_rd(&thinkos_rt.ev_alloc, no) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid event set %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	cm3_cpsid_i();

	/* unmask the events on the mask bitmap */
	thinkos_rt.ev[no].mask |= mask;

	/* wake up the first unmasked thread if any. */
	if ((ev = __clz(__rbit(thinkos_rt.ev[no].pend & mask))) < 32) {
		if ((th = __thinkos_wq_head(wq)) != THINKOS_THREAD_NULL) {
			/* a pending event was unmaksed and there is a thread waiting on 
			   the queue, clear the event pending flag and 
			   wakes up the thread. */
			__bit_mem_wr(&thinkos_rt.ev[no].pend, ev, 0);  
			/* wakeup from the event wait queue, set the return of
			   the thread to the event */
			__thinkos_wakeup_return(wq, th, ev);
			DCC_LOG3(LOG_TRACE, "<%d> waked up with event %d.%d", th, wq, ev);
			/* signal the scheduler ... */
			__thinkos_defer_sched();
		} else {
			/* no threads waiting */
			cm3_cpsie_i();
			return;
		}
	}

	/* wake up as many other threads as possible */
	while ((ev = __clz(__rbit(thinkos_rt.ev[no].pend & mask))) < 32) {
		if ((th = __thinkos_wq_head(wq)) != THINKOS_THREAD_NULL) {
			/* a pending event was unmaksed and there is a thread waiting on 
			   the queue, clear the event pending flag and 
			   wakes up the thread. */
			__bit_mem_wr(&thinkos_rt.ev[no].pend, ev, 0);  
			/* wakeup from the event wait queue, set the return of
			   the thread to the event */
			__thinkos_wakeup_return(wq, th, ev);
			DCC_LOG3(LOG_TRACE, "<%d> waked up with event %d.%d", th, wq, ev);
		} else {
			/* no more threads waiting */
			break;
		}
	}

	cm3_cpsie_i();
}
Пример #8
0
void thinkos_ev_timedwait_svc(int32_t * arg)
{
	unsigned int wq = arg[0];
	uint32_t ms = (uint32_t)arg[1];
	unsigned int no = wq - THINKOS_EVENT_BASE;
	int self = thinkos_rt.active;
	unsigned int ev;

#if THINKOS_ENABLE_ARG_CHECK

	if (no >= THINKOS_EVENT_MAX) {
		DCC_LOG1(LOG_ERROR, "object %d is not an event set!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#if THINKOS_ENABLE_EVENT_ALLOC
	if (__bit_mem_rd(&thinkos_rt.ev_alloc, no) == 0) {
		DCC_LOG1(LOG_ERROR, "invalid event set %d!", wq);
		arg[0] = THINKOS_EINVAL;
		return;
	}
#endif
#endif

	cm3_cpsid_i();

	/* check for any pending unmasked event */
	if ((ev = __clz(__rbit(thinkos_rt.ev[no].pend & 
						   thinkos_rt.ev[no].mask))) < 32) {
		__bit_mem_wr(&thinkos_rt.ev[no].pend, ev, 0);  
		arg[0] = ev;
		cm3_cpsie_i();
		return;
	} 

	/* insert into the mutex wait queue */
	__thinkos_tmdwq_insert(wq, self, ms);

	/* wait for event */
	/* remove from the ready wait queue */
	__bit_mem_wr(&thinkos_rt.wq_ready, thinkos_rt.active, 0);  
#if THINKOS_ENABLE_TIMESHARE
	/* if the ready queue is empty, collect
	 the threads from the CPU wait queue */
	if (thinkos_rt.wq_ready == 0) {
		thinkos_rt.wq_ready = thinkos_rt.wq_tmshare;
		thinkos_rt.wq_tmshare = 0;
	}
#endif
	/* Set the default return value to timeout. The
	   ev_rise() call will change it to the active event */
	arg[0] = THINKOS_ETIMEDOUT;

	cm3_cpsie_i();

	DCC_LOG2(LOG_INFO, "<%d> waiting for event %d...", self, wq);

	/* signal the scheduler ... */
	__thinkos_defer_sched();

}