Exemplo n.º 1
0
void sys_ipc(uint32_t *param1)
{
	/* TODO: Checking of recv-mask */
	tcb_t *to_thr = NULL;
	l4_thread_t to_tid = param1[REG_R0], from_tid = param1[REG_R1];

	if (to_tid != L4_NILTHREAD) {
		to_thr = thread_by_globalid(to_tid);

		if (to_tid == TID_TO_GLOBALID(THREAD_LOG)) {
			user_log(caller);
			caller->state = T_RUNNABLE;
		} else if ((to_thr && to_thr->state == T_RECV_BLOCKED)
		           || to_tid == caller->t_globalid) {
			/* To thread who is waiting for us or sends to myself */
			do_ipc(caller, to_thr);
		} else if (to_thr && to_thr->state == T_INACTIVE &&
		           GLOBALID_TO_TID(to_thr->utcb->t_pager) == GLOBALID_TO_TID(caller->t_globalid)) {
			if (ipc_read_mr(caller, 0) == 0x00000003) {
				/* thread start protocol */

				memptr_t sp = ipc_read_mr(caller, 2);
				size_t stack_size = ipc_read_mr(caller, 3);

				dbg_printf(DL_IPC, "IPC: %t thread start\n", to_tid);

				to_thr->stack_base = sp - stack_size;
				to_thr->stack_size = stack_size;

				thread_init_ctx((void *) sp, (void *) ipc_read_mr(caller, 1), to_thr);
				caller->state = T_RUNNABLE;

				/* Start thread */
				to_thr->state = T_RUNNABLE;
			} else {
				do_ipc(caller, to_thr);
				to_thr->state = T_INACTIVE;
			}
		} else  {
			/* No waiting, block myself */
			caller->state = T_SEND_BLOCKED;
			caller->utcb->intended_receiver = to_tid;

			dbg_printf(DL_IPC, "IPC: %t sending\n", caller->t_globalid);

			return;
		}
	}

	if (from_tid != L4_NILTHREAD) {
		/* Only receive phases, simply lock myself */
		caller->state = T_RECV_BLOCKED;
		caller->ipc_from = from_tid;

		dbg_printf(DL_IPC, "IPC: %t receiving\n", caller->t_globalid);
	}
}
Exemplo n.º 2
0
void sys_ipc(uint32_t* param1) {
	/*TODO: Checking of recv-mask*/
	tcb_t *to_thr = NULL;
	l4_thread_t to_tid = param1[REG_R0], from_tid = param1[REG_R1];

	if(to_tid != L4_NILTHREAD) {
		to_thr =  thread_by_globalid(to_tid);

		if((to_thr && to_thr->state == T_RECV_BLOCKED)
				|| to_tid == caller->t_globalid ) {
			/* To thread who waiting us or send myself*/
			do_ipc(caller, to_thr);
		}
		else if(to_thr && to_thr->state == T_INACTIVE &&
				GLOBALID_TO_TID(to_thr->utcb->t_pager) == GLOBALID_TO_TID(caller->t_globalid)) {
			/* That is thread start protocol */

			dbg_printf(DL_IPC, "IPC: %t thread start\n", to_tid);

			thread_init_ctx((void*) ipc_read_mr(caller, 2),
							(void*) ipc_read_mr(caller, 1), to_thr);
			caller->state = T_RUNNABLE;

			/*Start thread*/
			to_thr->state = T_RUNNABLE;
		}
		else  {
			/*No waiting, block myself*/
			caller->state = T_SEND_BLOCKED;
			caller->utcb->intended_receiver = to_tid;

			dbg_printf(DL_IPC, "IPC: %t sending\n", caller->t_globalid);
		}
	}

	if(from_tid != L4_NILTHREAD) {
		/*Only receive phases, simply lock myself*/
		caller->state = T_RECV_BLOCKED;
		caller->ipc_from = from_tid;

		dbg_printf(DL_IPC, "IPC: %t receiving\n", caller->t_globalid);
	}
}
Exemplo n.º 3
0
void sys_ipc(uint32_t *param1)
{
	/* TODO: Checking of recv-mask */
	tcb_t *to_thr = NULL;
	l4_thread_t to_tid = param1[REG_R0], from_tid = param1[REG_R1];
	uint32_t timeout = param1[REG_R2];

	if (to_tid == L4_NILTHREAD &&
		from_tid == L4_NILTHREAD) {
		caller->state = T_INACTIVE;
		if (timeout)
			sys_ipc_timeout(timeout);
		return;
	}

	if (to_tid != L4_NILTHREAD) {
		to_thr = thread_by_globalid(to_tid);

		if (to_tid == TID_TO_GLOBALID(THREAD_LOG)) {
			user_log(caller);
			caller->state = T_RUNNABLE;
			return;
		} else if (to_tid == TID_TO_GLOBALID(THREAD_IRQ_REQUEST)) {
			user_interrupt_config(caller);
			caller->state = T_RUNNABLE;
			return;
		} else if ((to_thr && to_thr->state == T_RECV_BLOCKED)
		           || to_tid == caller->t_globalid) {
			/* To thread who is waiting for us or sends to myself */
			do_ipc(caller, to_thr);
			return;
		} else if (to_thr && to_thr->state == T_INACTIVE &&
		           GLOBALID_TO_TID(to_thr->utcb->t_pager) == GLOBALID_TO_TID(caller->t_globalid)) {
			if (ipc_read_mr(caller, 0) == 0x00000005) {
				/* mr1: thread func, mr2: stack addr, mr3: stack size*/
				/* mr4: thread entry, mr5: thread args */
				/* thread start protocol */

				memptr_t sp = ipc_read_mr(caller, 2);
				size_t stack_size = ipc_read_mr(caller, 3);
				uint32_t regs[4];	/* r0, r1, r2, r3 */

				dbg_printf(DL_IPC, "IPC: %t thread start\n", to_tid);

				to_thr->stack_base = sp - stack_size;
				to_thr->stack_size = stack_size;

				regs[REG_R0] = (uint32_t)&kip;
				regs[REG_R1] = (uint32_t)to_thr->utcb;
				regs[REG_R2] = ipc_read_mr(caller, 4);
				regs[REG_R3] = ipc_read_mr(caller, 5);
				thread_init_ctx((void *) sp, (void *) ipc_read_mr(caller, 1),
				                regs, to_thr);

				caller->state = T_RUNNABLE;

				/* Start thread */
				to_thr->state = T_RUNNABLE;

				return;
			} else {
				do_ipc(caller, to_thr);
				to_thr->state = T_INACTIVE;

				return;
			}
		} else  {
			/* No waiting, block myself */
			caller->state = T_SEND_BLOCKED;
			caller->utcb->intended_receiver = to_tid;
			dbg_printf(DL_IPC, "IPC: %t sending\n", caller->t_globalid);

			if (timeout)
				sys_ipc_timeout(timeout);

			return;
		}
	}

	if (from_tid != L4_NILTHREAD) {
		tcb_t *thr = NULL;

		if (from_tid == L4_ANYTHREAD) {
			int i;
			/* Find out if there is any sending thread waiting for caller */
			for (i = 1; i < thread_count; ++i) {
				thr = thread_map[i];
				if (thr->state == T_SEND_BLOCKED &&
				    thr->utcb->intended_receiver == caller->t_globalid) {
					do_ipc(thr, caller);
					return;
				}
			}
		} else if (from_tid != TID_TO_GLOBALID(THREAD_INTERRUPT)) {
			thr = thread_by_globalid(from_tid);

			if (thr->state == T_SEND_BLOCKED &&
			    thr->utcb->intended_receiver == caller->t_globalid) {
				do_ipc(thr, caller);
				return;
			}
		}

		/* Only receive phases, simply lock myself */
		caller->state = T_RECV_BLOCKED;
		caller->ipc_from = from_tid;

		if (from_tid == TID_TO_GLOBALID(THREAD_INTERRUPT)) {
			/* Threaded interrupt is ready */
			user_interrupt_handler_update(caller);
		}

		if (timeout)
			sys_ipc_timeout(timeout);

		dbg_printf(DL_IPC, "IPC: %t receiving\n", caller->t_globalid);

		return;
	}

	caller->state = T_SEND_BLOCKED;
}