Ejemplo n.º 1
0
//Operations of Console object.
static VOID ConPrintStr(const char* pszStr)
{
	DWORD   dwWriteSize = 0;
	DWORD   i;

	//Low level output should be used if in context or in system initialization phase.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		dwWriteSize   = strlen(pszStr);
		for(i = 0;i < dwWriteSize;i ++)
		{
			__LL_Output(pszStr[i]);
		}
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		strlen(pszStr),
		(LPVOID)pszStr,
		&dwWriteSize);
	return;
}
Ejemplo n.º 2
0
static VOID ConGotoHome(void)
{
	DWORD   dwWriteSize = 0;
	CHAR    chTarg      = '\r';

	//Low level output operation should be used when in interrupt context or in process
	//of OS initialization.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		__LL_Output(chTarg);
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		1,
		(LPVOID)&chTarg,
		&dwWriteSize);
	return;
}
Ejemplo n.º 3
0
void up_release_pending(void)
{
  FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head;

  slldbg("From TCB=%p\n", rtcb);

  /* Merge the g_pendingtasks list into the g_readytorun task list */

  /* sched_lock(); */
  if (sched_mergepending())
    {
      /* The currently active task has changed!  We will need to
       * switch contexts.  First check if we are operating in
       * interrupt context:
       */

      if (IN_INTERRUPT())
        {
          /* Yes, then we have to do things differently.
           * Just copy the current context into the OLD rtcb.
           */

           SAVE_IRQCONTEXT(rtcb);

          /* Restore the exception context of the rtcb at the (new) head
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;
          slldbg("New Active Task TCB=%p\n", rtcb);

          /* Then setup so that the context will be performed on exit
           * from the interrupt.
           */

          SET_IRQCONTEXT(rtcb);
        }

      /* Copy the exception context into the TCB of the task that
       * was currently active. if SAVE_USERCONTEXT returns a non-zero
       * value, then this is really the previously running task
       * restarting!
       */

      else if (!SAVE_USERCONTEXT(rtcb))
        {
          /* Restore the exception context of the rtcb at the (new) head
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;
          slldbg("New Active Task TCB=%p\n", rtcb);

          /* Then switch contexts */

          RESTORE_USERCONTEXT(rtcb);
        }
    }
}
Ejemplo n.º 4
0
static VOID ConClearScreen(void)
{
	//Adopt low level output operation if in interrupt context or in process
	//of system initialization.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		return;
	}
	if(!Console.bInitialized)
	{
		return;
	}
	return;
}
Ejemplo n.º 5
0
// returns nonzero if handled
int
phantom_check_user_trap( struct trap_state *ts )
{
    // In interrupt? Surely this is a kernel problem, don't
    // deliver to curr thread!
    if(IN_INTERRUPT())
        return 0;

    // TODO move to some arch func?
#if ARCH_ia32
    if( ts->cs == KERNEL_CS )
    {
        //printf("kernel CS in trap\n");
        return 0;
    }
#endif

    phantom_thread_t *t = GET_CURRENT_THREAD();
    int tid = t->tid;

    if(t->thread_flags & THREAD_FLAG_USER)
    {
        // Try thread trap handler first. If it returns zero - trap
        // is supposed to be handled
        if(t->trap_handler)
        {
            int sig_no = trap2signo(ts);
            if( 0 == ( t->trap_handler( sig_no, ts ) ) )
                return 1;
        }

#ifdef ARCH_ia32
        if(ts->trapno == T_PAGE_FAULT)
            printf("Page fault addr %p\n", (void *)arch_get_fault_address() );
#endif
        printf("Usermode thread %d killed due to unexpected trap %d, eip %p\n", tid, ts->trapno, (void *)(ts->TS_PROGRAM_COUNTER) );
        t_kill_thread( tid );
        // Will panic below if returned
        printf("Usermode trap panic in thread %d\n", tid);
        trap_panic(ts);
    }
    printf("? trap not from kernel CS, and thread has no THREAD_FLAG_USER, tid %d\n", tid);
    // Not user mode, return

    return 0;
}
Ejemplo n.º 6
0
/* Show out bug information. */
VOID __BUG(LPSTR lpszFileName,DWORD dwLineNum)
{
	DWORD   dwFlags;
	unsigned int processor_id = __CURRENT_PROCESSOR_ID;
	__KERNEL_THREAD_OBJECT* pKernelThread = __CURRENT_KERNEL_THREAD;
	
	/* Show general bug info. */
	_hx_printk("\r\nBUG encountered[curr_processor = %d].\r\n",processor_id);
	_hx_printk("File name : %s\r\nCode Lines : %d\r\n",lpszFileName,dwLineNum);
	/* Show out specific information according current execution context. */
	if (IN_INTERRUPT())
	{
		/* Show interrupt related information. */
		_hx_printk("In interrupt context,vector:%d.\r\n", System.ucCurrInt[processor_id]);
		/* Show out interrupted kernel thread information. */
		if (pKernelThread)
		{
			_hx_printk("Interrupted kernel thread:%s\r\n", pKernelThread->KernelThreadName);
		}
	}
	else if (IN_SYSINITIALIZATION())
	{
		/* In process of system initialization. */
		_hx_printf("In process of system initialization.\r\n");
	}
	else
	{
		/* In normal thread context. */
		_hx_printf("Current kthread: %s\r\n",
			__CURRENT_KERNEL_THREAD->KernelThreadName);
	}
	/* Current CPU dive into a halt state. */
	__DISABLE_LOCAL_INTERRUPT(dwFlags);
	while (TRUE)
	{
		/* Enter halt state to save energy. */
		HaltSystem();
	}
	__RESTORE_LOCAL_INTERRUPT(dwFlags);
}
Ejemplo n.º 7
0
static VOID ConGotoPrev(void)
{
	DWORD   dwWriteSize = 0;
	CHAR    chTarg      = VK_BACKSPACE;

	//Interrupt context or OS initialization phase.
	if(IN_INTERRUPT())
	{
		__LL_Output(chTarg);
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		1,
		(LPVOID)&chTarg,
		&dwWriteSize);
	return;
}
Ejemplo n.º 8
0
static VOID ConChangeLine(void)
{
	DWORD   dwWriteSize = 0;
	CHAR    chTarg      = '\n';

	//Interrupt context or OS initialization phase output.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		__LL_Output(chTarg);
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		1,
		(LPVOID)&chTarg,
		&dwWriteSize);
	return;
}
Ejemplo n.º 9
0
void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
{
  FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head;
  bool switch_needed;

  /* Verify that the context switch can be performed */

  ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
         (tcb->task_state <= LAST_READY_TO_RUN_STATE));

  /* dbg("Blocking TCB=%p\n", tcb); */

  /* Remove the tcb task from the ready-to-run list.  If we
   * are blocking the task at the head of the task list (the
   * most likely case), then a context switch to the next
   * ready-to-run task is needed. In this case, it should
   * also be true that rtcb == tcb.
   */

  switch_needed = sched_removereadytorun(tcb);

  /* Add the task to the specified blocked task list */

  sched_addblocked(tcb, (tstate_t)task_state);

  /* If there are any pending tasks, then add them to the g_readytorun
   * task list now
   */

  if (g_pendingtasks.head)
    {
      switch_needed |= sched_mergepending();
    }

  /* Now, perform the context switch if one is needed */

  if (switch_needed)
    {
      /* Are we in an interrupt handler? */

      if (IN_INTERRUPT())
        {
          /* Yes, then we have to do things differently.
           * Just copy the current registers into the OLD rtcb.
           */

          SAVE_IRQCONTEXT(rtcb);

          /* Restore the exception context of the rtcb at the (new) head 
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;
          /* dbg("New Active Task TCB=%p\n", rtcb); */

          /* Then setup so that the context will be performed on exit
           * from the interrupt.
           */

          SET_IRQCONTEXT(rtcb);
        }

      /* Copy the user C context into the TCB at the (old) head of the
       * g_readytorun Task list. if SAVE_USERCONTEXT returns a non-zero
       * value, then this is really the previously running task restarting!
       */

      else if (!SAVE_USERCONTEXT(rtcb))
        {
          /* Restore the exception context of the rtcb at the (new) head 
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;
          /* dbg("New Active Task TCB=%p\n", rtcb); */

          /* Then switch contexts */

          RESTORE_USERCONTEXT(rtcb);
        }
    }
}
Ejemplo n.º 10
0
void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state)
{
  FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head;
  bool switch_needed;

  /* Verify that the context switch can be performed */

  ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
         (tcb->task_state <= LAST_READY_TO_RUN_STATE));

  /* dbg("Blocking TCB=%p\n", tcb); */

  /* Remove the tcb task from the ready-to-run list.  If we
   * are blocking the task at the head of the task list (the
   * most likely case), then a context switch to the next
   * ready-to-run task is needed. In this case, it should
   * also be true that rtcb == tcb.
   */

  switch_needed = sched_removereadytorun(tcb);

  /* Add the task to the specified blocked task list */

  sched_addblocked(tcb, (tstate_t)task_state);

  /* If there are any pending tasks, then add them to the g_readytorun
   * task list now
   */

  if (g_pendingtasks.head)
    {
      switch_needed |= sched_mergepending();
    }

  /* Now, perform the context switch if one is needed */

  if (switch_needed)
    {
      /* Update scheduler parameters */

      sched_suspend_scheduler(rtcb);

      /* Are we in an interrupt handler? */

      if (IN_INTERRUPT())
        {
          /* Yes, then we have to do things differently.
           * Just copy the current registers into the OLD rtcb.
           */

          SAVE_IRQCONTEXT(rtcb);

          /* Restore the exception context of the rtcb at the (new) head
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;

          /* Reset scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then setup so that the context will be performed on exit
           * from the interrupt.  Any necessary address environment
           * changes will be made when the interrupt returns.
           */

          SET_IRQCONTEXT(rtcb);
        }

      /* Copy the user C context into the TCB at the (old) head of the
       * g_readytorun Task list. if SAVE_USERCONTEXT returns a non-zero
       * value, then this is really the previously running task restarting!
       */

      else if (!SAVE_USERCONTEXT(rtcb))
        {
          /* Restore the exception context of the rtcb at the (new) head
           * of the g_readytorun task list.
           */

          rtcb = (FAR struct tcb_s*)g_readytorun.head;

#ifdef CONFIG_ARCH_ADDRENV
         /* Make sure that the address environment for the previously
          * running task is closed down gracefully (data caches dump,
          * MMU flushed) and set up the address environment for the new
          * thread at the head of the ready-to-run list.
          */

         (void)group_addrenv(rtcb);
#endif
          /* Reset scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then switch contexts */

          RESTORE_USERCONTEXT(rtcb);
        }
    }
}
Ejemplo n.º 11
0
void up_unblock_task(FAR struct tcb_s *tcb)
{
  FAR struct tcb_s *rtcb = this_task();

  /* Verify that the context switch can be performed */

  ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
         (tcb->task_state <= LAST_BLOCKED_STATE));

  /* _info("Unblocking TCB=%p\n", tcb); */

  /* Remove the task from the blocked task list */

  sched_removeblocked(tcb);

  /* Add the task in the correct location in the prioritized
   * ready-to-run task list
   */

  if (sched_addreadytorun(tcb))
    {
      /* The currently active task has changed! We need to do
       * a context switch to the new task.
       */

      /* Update scheduler parameters */

      sched_suspend_scheduler(rtcb);

      /* Are we in an interrupt handler? */

      if (IN_INTERRUPT())
        {
          /* Yes, then we have to do things differently.
           * Just copy the current context into the OLD rtcb.
           */

          SAVE_IRQCONTEXT(rtcb);

          /* Restore the exception context of the rtcb at the (new) head
           * of the ready-to-run task list.
           */

          rtcb = this_task();

          /* Update scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then setup so that the context will be performed on exit
           * from the interrupt.  Any necessary address environment
           * changes will be made when the interrupt returns.
           */

          SET_IRQCONTEXT(rtcb);
        }

      /* We are not in an interrupt handler.  Copy the user C context
       * into the TCB of the task that was previously active.  if
       * SAVE_USERCONTEXT returns a non-zero value, then this is really the
       * previously running task restarting!
       */

      else if (!SAVE_USERCONTEXT(rtcb))
        {
          /* Restore the exception context of the new task that is ready to
           * run (probably tcb).  This is the new rtcb at the head of the
           * ready-to-run task list.
           */

          rtcb = this_task();

#ifdef CONFIG_ARCH_ADDRENV
         /* Make sure that the address environment for the previously
          * running task is closed down gracefully (data caches dump,
          * MMU flushed) and set up the address environment for the new
          * thread at the head of the ready-to-run list.
          */

         (void)group_addrenv(rtcb);
#endif
          /* Update scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then switch contexts */

          RESTORE_USERCONTEXT(rtcb);
        }
    }
}
Ejemplo n.º 12
0
void up_release_pending(void)
{
  FAR struct tcb_s *rtcb = this_task();

  slldbg("From TCB=%p\n", rtcb);

  /* Merge the g_pendingtasks list into the ready-to-run task list */

  /* sched_lock(); */
  if (sched_mergepending())
    {
      /* The currently active task has changed!  We will need to switch
       * contexts.
       *
       * Update scheduler parameters.
       */

      sched_suspend_scheduler(rtcb);

      /* Are we operating in interrupt context? */

      if (IN_INTERRUPT())
        {
          /* Yes, then we have to do things differently.
           * Just copy the current context into the OLD rtcb.
           */

           SAVE_IRQCONTEXT(rtcb);

          /* Restore the exception context of the rtcb at the (new) head
           * of the ready-to-run task list.
           */

          rtcb = this_task();

          /* Update scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then setup so that the context will be performed on exit
           * from the interrupt.  Any necessary address environment
           * changes will be made when the interrupt returns.
           */

          SET_IRQCONTEXT(rtcb);
        }

      /* Copy the exception context into the TCB of the task that
       * was currently active. if SAVE_USERCONTEXT returns a non-zero
       * value, then this is really the previously running task
       * restarting!
       */

      else if (!SAVE_USERCONTEXT(rtcb))
        {
          /* Restore the exception context of the rtcb at the (new) head
           * of the ready-to-run task list.
           */

          rtcb = this_task();

#ifdef CONFIG_ARCH_ADDRENV
          /* Make sure that the address environment for the previously
           * running task is closed down gracefully (data caches dump,
           * MMU flushed) and set up the address environment for the new
           * thread at the head of the ready-to-run list.
           */

          (void)group_addrenv(rtcb);
#endif
          /* Update scheduler parameters */

          sched_resume_scheduler(rtcb);

          /* Then switch contexts */

          RESTORE_USERCONTEXT(rtcb);
        }
    }
}
Ejemplo n.º 13
0
void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
  dbg("tcb=0x%p sigdeliver=0x%04x\n", tcb, (uint16_t)sigdeliver);

  /* Refuse to handle nested signal actions */

  if (tcb->xcp.sigdeliver == NULL)
    {
      irqstate_t flags;

      /* Make sure that interrupts are disabled */

      flags = irqsave();

      /* First, handle some special cases when the signal is being delivered
       * to the currently executing task.
       */

      if (tcb == (FAR struct tcb_s*)g_readytorun.head)
        {
          /* CASE 1:  We are not in an interrupt handler and a task is
           * signalling itself for some reason.
           */

          if (!IN_INTERRUPT())
            {
              /* In this case just deliver the signal now. */

              sigdeliver(tcb);
            }

          /* CASE 2:  We are in an interrupt handler AND the interrupted task
           * is the same as the one that must receive the signal, then we
           * will have to modify the return state as well as the state in
           * the TCB.
           */

          else
            {
              /* Set up to vector to the trampoline with interrupts disabled. */

              z80_sigsetup(tcb, sigdeliver, IRQ_STATE());

              /* And make sure that the saved context in the TCB
               * is the same as the interrupt return context.
               */

              SAVE_IRQCONTEXT(tcb);
            }
        }

      /* Otherwise, we are (1) signaling a task is not running from an interrupt
       * handler or (2) we are not in an interrupt handler and the running task
       * is signalling some non-running task.
       */

      else
        {
          /* Set up to vector to the trampoline with interrupts disabled. */

          z80_sigsetup(tcb, sigdeliver, tcb->xcp.regs);
        }

      irqrestore(flags);
    }
}
Ejemplo n.º 14
0
void up_reprioritize_rtr(FAR _TCB *tcb, uint8_t priority)
{
  /* Verify that the caller is sane */

  if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
      tcb->task_state > LAST_READY_TO_RUN_STATE ||
      priority < SCHED_PRIORITY_MIN || 
      priority > SCHED_PRIORITY_MAX)
    {
       PANIC(OSERR_BADREPRIORITIZESTATE);
    }
  else
    {
      FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
      bool switch_needed;

      slldbg("TCB=%p PRI=%d\n", tcb, priority);

      /* Remove the tcb task from the ready-to-run list.
       * sched_removereadytorun will return true if we just
       * remove the head of the ready to run list.
       */

      switch_needed = sched_removereadytorun(tcb);

      /* Setup up the new task priority */

      tcb->sched_priority = (uint8_t)priority;

      /* Return the task to the specified blocked task list.
       * sched_addreadytorun will return true if the task was
       * added to the new list.  We will need to perform a context
       * switch only if the EXCLUSIVE or of the two calls is non-zero
       * (i.e., one and only one the calls changes the head of the
       * ready-to-run list).
       */

      switch_needed ^= sched_addreadytorun(tcb);

      /* Now, perform the context switch if one is needed */

      if (switch_needed)
        {
          /* If we are going to do a context switch, then now is the right
           * time to add any pending tasks back into the ready-to-run list.
           * task list now
           */

          if (g_pendingtasks.head)
            {
              sched_mergepending();
            }

          /* Are we in an interrupt handler? */

          if (IN_INTERRUPT())
            {
              /* Yes, then we have to do things differently.
               * Just copy the current context into the OLD rtcb.
               */

               SAVE_IRQCONTEXT(rtcb);

              /* Restore the exception context of the rtcb at the (new) head 
               * of the g_readytorun task list.
               */

              rtcb = (FAR _TCB*)g_readytorun.head;
              slldbg("New Active Task TCB=%p\n", rtcb);

              /* Then setup so that the context will be performed on exit
               * from the interrupt.
               */

               SET_IRQCONTEXT(rtcb);
            }

          /* Copy the exception context into the TCB at the (old) head of the
           * g_readytorun Task list. if SAVE_USERCONTEXT returns a non-zero
           * value, then this is really the previously running task restarting!
           */

          else if (!SAVE_USERCONTEXT(rtcb))
            {
              /* Restore the exception context of the rtcb at the (new) head 
               * of the g_readytorun task list.
               */

              rtcb = (FAR _TCB*)g_readytorun.head;
              slldbg("New Active Task TCB=%p\n", rtcb);

              /* Then switch contexts */

              RESTORE_USERCONTEXT(rtcb);
            }
        }
    }
}