⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipctrap.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* This file contains the functions that are called in the IPC path, * in an attempt (probably vain) to minimize I-TLB misses. *//* Define this so that all of the functions that are called from the * IPC path will be exposed by their respective header files to be * inlined:  */#if !defined(NDEBUG) && !defined(OPTION_DDB)#define IPC_INTERRUPT_SUPPRESS#endif#define IPC_INLINES#include <kerninc/kernel.hxx>#include <kerninc/Check.hxx>#include <kerninc/Machine.hxx>#include <kerninc/IRQ.hxx>#include <kerninc/Thread.hxx>#include <kerninc/util.h>#include <kerninc/Debug.hxx>#include <kerninc/SysTimer.hxx>#include <kerninc/Process.hxx>#include <eros/SysTraceKey.h>#include <eros/i486/io.h>#include "lostart.hxx"#include "IDT.hxx"#include "GDT.hxx"/* #define TIMING_DEBUG */extern "C" {  extern uint32_t InterruptStackTop;  extern uint32_t InterruptStackBottom;  extern uint32_t InterruptStackLimit;  extern int _start;  extern int etext;}/* Declared in IPC-vars.cxx */#if 0extern void Invoke();#endif/* Called from the interrupt entry point with interrupts disabled.   The interrupt handler assembly code has also incremented   DisableDepth, so we are running as though we had already called   IRQ::DISABLE().  Do any processing that must be done with   interrupts disabled here and then call IRQ::ENABLE() to allow   nested interrupts (when we get that working).   The saveArea pointer is passed in solely for use by the kernel   debugger in back-walking the stack.   */voidIDT::OnKeyInvocationTrap(fixregs_t * /* saveArea */){#ifndef NDEBUG  uint32_t vecNumber = ((Process*) Thread::CurContext())->fixRegs.ExceptNo;  assert (vecNumber == IntVec::InvokeKey);#endif  KernStats.nInter++;        assert ( (GetFlags() & MASK_EFLAGS_Interrupt) == 0 );  assert( IRQ::DISABLE_DEPTH() == 1 );#ifndef IPC_INTERRUPT_SUPPRESS  /* We have now done all of the processing that must be done with   * interrupts disabled.  Re-enable interrupts here:   */  IRQ::ENABLE();    assert( IRQ::DISABLE_DEPTH() == 0 );#endif  assert ( Thread::Current() );#ifndef NDEBUG  if (dbg_inttrap)    Debugger();#endif#ifdef DBG_WILD_PTR  if (dbg_wild_ptr)    Check::Consistency("Before Invoke");#endif  {    Process* sndContext = (Process*) Thread::CurContext();    /* If IPC block validation is running in the IPC assembly path,       that path may have set a fault code, in which case we need to       bypass the actual invocation and let the thread scheduler       invoke the domain keeper. */    if (sndContext->faultCode == FC_NoFault)      sndContext->DoKeyInvocation();  }  #ifdef DBG_WILD_PTR  if (dbg_wild_ptr)    Check::Consistency("After Invoke()");#endif#ifndef IPC_INTERRUPT_SUPPRESS  assert( IRQ::DISABLE_DEPTH() == 0 );  /* On return from Invoke() we might NOT have a current thread   * because the invocation may have been a return to a kernel key.   * assert ( Thread::Current() );   */  IRQ::DISABLE();  assert( IRQ::DISABLE_DEPTH() == 1 );#endif      /*    * If the thread is yielding voluntarily, it MUST be rescheduled.   *    * If the current thread is a user thread, it is possible that   * having completed the invocation means that the current thread   * needs to be reprepared, or that the thread has faulted. If the   * thread has faulted, it has not yielded, as we need to know in   * order to migrate the thread to the keeper.   *    * It is also possible that in attempting to reprepare the current   * thread, we will discover that the thread has DIED.  This can   * happen if a domain rescinds itself, or if it returns to a kernel   * key.   *    * Rather than try to deal with all of this in multiple places, we   * unconditionally call Thread::Resched().  If appropriate,   * Thread::Resched() will simply return the current thread in   * prepared form, and we will return to it.  If the thread should   * yield unconditionally, we tell Thread::Resched() so.   *    */    assert ( (GetFlags() & MASK_EFLAGS_Interrupt) == 0 );  assert( IRQ::DISABLE_DEPTH() == 1 );    Thread::Reschedule();  /* We succeeded (wonder of wonders) -- release pinned resources. */  ObjectHeader::ReleasePinnedObjects();  /* After calling Reschedule we should at least have the idle thread. */    assert ( Thread::Current() );  /* We are about to do a return from interrupt, which path must not   * be interrupted.  Disable interrupts prior to return:   */  assert ( (GetFlags() & MASK_EFLAGS_Interrupt) == 0 );  assert( IRQ::DISABLE_DEPTH() == 1 );  /* Otherwise resume some thread.  Note that we may be returning to a   * non-user thread here.   */  Thread::Current()->Resume();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -