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

📄 usercontext.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 3 页
字号:
Process::ValidateRegValues(){  if (processFlags & PF_Faulted)    return;    uint32_t code = 0;  uint32_t info = 0;  fixreg_t iopl = (fixRegs.EFLAGS & MASK_EFLAGS_IOPL) >> SHIFT_EFLAGS_IOPL;  /* FIX: This is no longer correct, as a valid user-mode application   * can now carry PrivDomainCode and PrivDomainData in some cases. */  uint32_t wantCode =    isUserContext ? Selector::DomainCode : Selector::KProcCode;  uint32_t wantData =    isUserContext ? Selector::DomainData : Selector::KProcData;  /* FIX: The whole segment register check needs to be MUCH more   * specific. There are only a few allowable values, and they should   * be explicitly tested here.   */#define validate(seg, want) \  do { \    if ( ((seg) != Selector::Null) && ((seg) != (want)) ) {   \      code = FC_RegValue;               \      info = (seg);                     \      goto fault;                       \    }                                   \  } while (0)          validate(fixRegs.CS, wantCode);  /* Strictly speaking, it's okay for a user program to place the code   * segment value in a data segment register, so long as read-only   * access is sufficient. Fix this when somebody complains someday. */  validate(fixRegs.DS, wantData);  validate(fixRegs.ES, wantData);  validate(fixRegs.FS, wantData);  validate(fixRegs.GS, wantData);  validate(fixRegs.SS, wantData);  #undef validate    if ( (fixRegs.EFLAGS & MASK_EFLAGS_Interrupt) == 0 ) {    /* interrupts must be enabled, various others not: */    code = FC_RegValue;  }  else if ( fixRegs.EFLAGS & MASK_EFLAGS_Nested ) {    code = FC_RegValue;  }  else if ( iopl != 0 && !HasDevicePriveleges() ) {    code = FC_RegValue;  }#ifdef EROS_HAVE_FPU  /* Check for pending floating point exceptions too. If an unmasked     exception is pending, invoke the process keeper.     The bits in the control words are 'mask if set', while the bits     in the status words are 'raise if set'.  The and-not logic is     therefore what we want: */  else if (fpuRegs.f_status & ~(fpuRegs.f_ctrl & FPSTATUS_EXCEPTIONS)) {    code = FC_FloatingPointError;    info = fpuRegs.f_cs;  }  /* The floating point %f_cs, %f_ip, %f_ds, and %f_dp registers     record the location of the last operation.  They are output only,     and need not be checked. */#endif   fault:  if (code)    SetFault(code, info, true);  #if 0  if (faultCode)    printf("Bad register values\n");#endif  return;}/* Both loads the register values and validates that the process root * is well-formed. */voidProcess::LoadFixRegs(){  assert(hazards & hz::DomRoot);  assert(procRoot);  procRoot->MakeObjectDirty();#ifdef ProcAltMsgBuf#error "Type checks need revision"#endif    /* Ensure slots containing fixed regs are number keys. */  for (uint32_t k = ProcFirstRootRegSlot; k <= ProcLastRootRegSlot; k++) {    if ( (*procRoot)[k].IsType(KT_Number) == false ) {      SetMalformed();      return;    }    assert ( (*procRoot)[k].IsHazard() == false );  }  stats.pfCount = 0;#if 1  uint8_t *rootkey0 = (uint8_t *) & ((*procRoot)[0]);  LOAD_FIX_REGS;#else    DomRegLayout* pDomRegs = (DomRegLayout*) & ((*procRoot)[0]);  faultCode = pDomRegs->faultCode;  faultInfo = pDomRegs->faultInfo;  runState = pDomRegs->runState;  processFlags = pDomRegs->flags;    if (faultCode)    printf("Fault code already set\n");    fixRegs.EDX = pDomRegs->edx;  fixRegs.EDI = pDomRegs->edi;  fixRegs.DS = pDomRegs->ds;  fixRegs.ECX = pDomRegs->ecx;  fixRegs.ESI = pDomRegs->esi;  fixRegs.ES = pDomRegs->es;  fixRegs.EAX = pDomRegs->eax;  fixRegs.EBX = pDomRegs->ebx;  fixRegs.SS = pDomRegs->ss;  fixRegs.EIP = pDomRegs->eip;  fixRegs.ESP = pDomRegs->esp;  fixRegs.CS = pDomRegs->cs;  fixRegs.EFLAGS = pDomRegs->eflags;  fixRegs.EBP = pDomRegs->ebp;  fixRegs.FS = pDomRegs->fs;  fixRegs.GS = pDomRegs->gs;  fixRegs.sndPtr = pDomRegs->sndPtr;  fixRegs.sndLen = pDomRegs->sndLen;  fixRegs.rcvPtr = pDomRegs->rcvPtr;  fixRegs.invType = pDomRegs->invType;      stats.evtCounter0 = pDomRegs->hiEvtCount;  stats.evtCounter0 <<= 32;  stats.evtCounter0 |= pDomRegs->loEvtCount;  stats.evtCounter1 = 0;#endif    fixRegs.ReloadUnits = 0;    for (uint32_t k = ProcFirstRootRegSlot; k <= ProcLastRootRegSlot; k++)    (*procRoot)[k].SetRwHazard();  hazards &= ~hz::DomRoot;#if 0  dprintf(true, "Process root oid=0x%x to ctxt 0x%08x, eip 0x%08x hz 0x%08x\n",		  (uint32_t) procRoot->oid, this, fixRegs.EIP, hazards);#endif}#ifdef EROS_HAVE_FPU/* This version requires no annex node. */voidProcess::LoadFloatRegs(){  assert (hazards & hz::FloatRegs);  assert (procRoot);  assert (procRoot->IsDirty());    uint8_t *rootkey0 = (uint8_t *) & ((*procRoot)[0]);  LOAD_FLOAT_REGS;  hazards &= ~hz::FloatRegs;}#endifvoidProcess::LoadKeyRegs(){  assert (hazards & hz::KeyRegs);  assert (procRoot->slot[ProcGenKeys].IsHazard() == false);  if (procRoot->slot[ProcGenKeys].IsType(KT_Node) == false) {    SetMalformed();    return;  }  #if 0  {    Key& k = procRoot->slot[ProcGenKeys];    printf("Preparing nd oid 0x%08x%08x\n",		   (uint32_t) (k.GetKeyOid() >> 32),		   (uint32_t) (k.GetKeyOid()));  }#endif		   procRoot->slot[ProcGenKeys].Prepare();  Node *kn = (Node *) procRoot->slot[ProcGenKeys].GetObjectPtr();  assertex(kn,kn->IsUserPinned());    assert ( kn->Validate() );  kn->Unprepare(false);  if (kn->obType != ObType::NtUnprepared || kn == procRoot) {    SetMalformed();    return;  }  kn->MakeObjectDirty();  for (uint32_t k = 0; k < EROS_NODE_SIZE; k++) {    if ( (*kn)[k].IsHazard() )      dprintf(true, "Key register slot %d is hazarded in node 0x%08x%08x\n",		      k,		      (uint32_t) (kn->ob.oid >> 32), (uint32_t) kn->ob.oid);#ifndef NDEBUG    /* We know that the context structure key registers are unhazarded     * and unprepared by virtue of the fact that they are unloaded,     * but check here just in case:     */    if ( keyReg[k].IsHazard() )      dprintf(true, "Key register %d is hazarded in Process 0x%08x\n",		      k, this);    if ( keyReg[k].IsUnprepared() == false )      dprintf(true, "Key register %d is prepared in Process 0x%08x\n",		      k, this);#endif    if (k == 0)      keyReg[0].NH_VoidKey();	/* key register 0 is always void */    else      keyReg[k].NH_Set(kn->slot[k]);    (*kn)[k].SetRwHazard();  }    /* Node is now known to be valid... */  kn->context = this;  kn->obType = ObType::NtKeyRegs;  keysNode = kn;  procRoot->slot[ProcGenKeys].SetWrHazard();  assert(keysNode);  hazards &= ~hz::KeyRegs;}voidProcess::FlushFixRegs(){  assert((hazards & hz::DomRoot) == 0);    assert(procRoot);  assert(procRoot->IsDirty());  assert(isUserContext);#ifdef ProcAltMsgBuf#error "Type checks need revision"#endif    for (uint32_t k = ProcFirstRootRegSlot; k <= ProcLastRootRegSlot; k++) {    assert ( (*procRoot)[k].IsRdHazard() );    assert ( (*procRoot)[k].IsWrHazard() );    (*procRoot)[k].UnHazard();  }#if 1  uint8_t *rootkey0 = (uint8_t *) & ((*procRoot)[0]);  UNLOAD_FIX_REGS;  /* ISSUE: If this process has IOPL privileges, it is not clear that   * we should ever be recording them back to the domain root, as this   * makes them fairly well permanent. */  #else  DomRegLayout* pDomRegs = (DomRegLayout*) & ((*procRoot)[0]);  pDomRegs->faultCode = faultCode;  pDomRegs->faultInfo = faultInfo;  pDomRegs->runState = runState;  pDomRegs->flags = processFlags;    pDomRegs->edx = fixRegs.EDX;  pDomRegs->edi = fixRegs.EDI;  pDomRegs->ds = fixRegs.DS;  pDomRegs->ecx = fixRegs.ECX;  pDomRegs->esi = fixRegs.ESI;  pDomRegs->es = fixRegs.ES;  pDomRegs->eax = fixRegs.EAX;  pDomRegs->ebx = fixRegs.EBX;  pDomRegs->ss = fixRegs.SS;  pDomRegs->eip = fixRegs.EIP;  pDomRegs->esp = fixRegs.ESP;  pDomRegs->cs = fixRegs.CS;  pDomRegs->eflags = fixRegs.EFLAGS;  pDomRegs->ebp = fixRegs.EBP;  pDomRegs->fs = fixRegs.FS;  pDomRegs->gs = fixRegs.GS;  pDomRegs->sndPtr = fixRegs.sndPtr;  pDomRegs->sndLen = fixRegs.sndLen;  pDomRegs->rcvPtr = fixRegs.rcvPtr;  pDomRegs->invType = fixRegs.invType;  pDomRegs->loEvtCount = stats.evtCounter0;  pDomRegs->hiEvtCount = stats.evtCounter0 >> 32;#endif    (*procRoot)[ProcSched].UnHazard();  hazards |= (hz::DomRoot | hz::Schedule);  saveArea = 0;}#ifdef EROS_HAVE_FPUvoidProcess::SaveFPU(){  assert(fpuOwner == this);  Machine::EnableFPU();  __asm__ __volatile__("fnsave %0\n\t" : "=m" (fpuRegs));  fpuOwner = 0;  Machine::DisableFPU();}#ifdef EROS_HAVE_FPUvoidProcess::LoadFPU(){  /* FPU is unloaded, or is owned by some other process.  Unload   * that, and load the current process's FPU state in it's place.   */  if (fpuOwner)    Process::fpuOwner->SaveFPU();  assert(fpuOwner == 0);  Machine::EnableFPU();  __asm__ __volatile__("frstor %0\n\t"		       : /* no outputs */		       : "m" (fpuRegs));  fpuOwner = this;  Machine::DisableFPU();  hazards &= ~hz::NumericsUnit;}#endif/* This version requires no annex node. */voidProcess::FlushFloatRegs(){  assert ((hazards & hz::FloatRegs) == 0);  assert (procRoot);  assert (procRoot->IsDirty());  uint8_t *rootkey0 = (uint8_t *) & ((*procRoot)[0]);  UNLOAD_FLOAT_REGS;  hazards |= hz::FloatRegs;  saveArea = 0;}#endifvoidProcess::FlushKeyRegs(){  assert (keysNode);  assert ((hazards & hz::KeyRegs) == 0);  assert(procRoot);  assert (keysNode->IsDirty());  assert ( keysNode->Validate() );#if 0  printf("Flushing key regs on ctxt=0x%08x\n", this);  if (inv.IsActive() && inv.invokee == this)    dprintf(true,"THAT WAS INVOKEE!\n");#endif  for (uint32_t k = 0; k < EROS_NODE_SIZE; k++) {    keysNode->slot[k].UnHazard();    keysNode->slot[k].NH_Set(keyReg[k]);    /* Not hazarded because key register */    keyReg[k].NH_VoidKey();    /* We know that the context structure key registers are unhazarded     * and unlinked by virtue of the fact that they are unloaded.     */  }  keysNode->context = 0;  keysNode->obType = ObType::NtUnprepared;  keysNode = 0;  hazards |= hz::KeyRegs;  procRoot->slot[ProcGenKeys].UnHazard();  saveArea = 0;}/* Rewrite the process key back to our current thread.  Note that * the thread's process key is not reliable unless this unload has * been performed. */voidProcess::SyncThread(){  assert(curThread);  assert(procRoot);  assert (curThread->context == this);    Key& procKey = curThread->processKey;  assert (procKey.IsHazard() == false);  /* Not hazarded because thread key */  if (procKey.IsPrepared())    procKey.NH_Unprepare();  procKey.InitType(KT_Process);  procKey.unprep.oid = procRoot->ob.oid;  procKey.unprep.count = procRoot->ob.allocCount; }voidProcess::Unload(){  /* It might already be unloaded: */  if (procRoot == 0)    return;  #if 0  {    const char *descrip = "other";    bool shouldStop = false;        if (this == Thread::Current()->context)      descrip = "current";    if (inv.IsActive() && this == inv.invokee) {      descrip = "invokee";      shouldStop = true;    }       dprintf(shouldStop, "Unloading %s ctxt 0x%08x\n", descrip, this);  }#endif    #if 0  if (hazards & hz::DomRoot)    dprintf(false, "Calling Context::Unload() on 0x%08x, eip=???\n", this);  else    dprintf(false, "Calling Context::Unload() on 0x%08x, eip=0x%08x\n",		   this, fixRegs.EIP);#endif#if defined(DBG_WILD_PTR)

⌨️ 快捷键说明

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