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

📄 erosimage.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 3 页
字号:
  if (wasSeg)    newSegRoot.SetType(KT_Segment);  #ifdef KT_Wrapper  if ( segRoot.IsType(KT_Wrapper) )    return segRoot;#else  if ( segRoot.IsRedSegmentKey() )    return segRoot;#endif  return newSegRoot;}DiskKeyErosImage::DoAddSubsegToBlackSegment(const DiskKey& segRoot,				     uint64_t segOffset,				     const DiskKey& segKey){  /* segOffsetBLSS holds the BLSS of the smallest segment that could   * conceivably contain segOffset.   */  uint32_t segOffsetBLSS = LSS::BiasedLSS(segOffset);  uint32_t rootBLSS = GetAnyBlss(segRoot);  uint32_t segBLSS = segKey.GetBlss();  #if 0  Diag::debug(2, "pageAddr=0x%04x%08x%08x\n",	   pageAddr.hi, pageAddr.mid, pageAddr.lo);#endif#ifdef KT_Wrapper  if ( segRoot.IsType(KT_Wrapper) || segRoot.IsType(KT_Segment) )    Diag::fatal(4, "AddPageToSegment: Cannot traverse subsegment\n");#else  if ( segRoot.IsRedSegmentKey() || segRoot.IsType(KT_Segment) )    Diag::fatal(4, "AddPageToSegment: Cannot traverse subsegment\n");#endif  if (rootBLSS < segOffsetBLSS) {    /* Inserting a segment whose offset BLSS is too large - need to     * grow a new root.     */    DiskKey newRoot = AddNode();    newRoot.SetBlss(segOffsetBLSS);    SetNodeSlot(newRoot, 0, segRoot);        return DoAddSubsegToBlackSegment(newRoot, segOffset, segKey);  }  if (rootBLSS > segOffsetBLSS && rootBLSS > segBLSS) {    uint32_t slot = LSS::SlotNdx(segOffset, segOffsetBLSS);    DiskKey subSeg = GetNodeSlot(segRoot, slot);	    DiskKey newSlotKey = DoAddSubsegToBlackSegment(subSeg, segOffset, segKey);    SetNodeSlot(segRoot, slot, newSlotKey);          return segRoot;  }  /* The new segment might replace the current segment: */  if ( rootBLSS <= segBLSS )    return segKey;	   /* segment key goes somewhere beneath current tree: */  uint32_t slot = LSS::SlotNdx(segOffset, segOffsetBLSS);  segOffsetBLSS--;  uint64_t subSegOffset = segOffset;  subSegOffset &= LSS::Mask(segOffsetBLSS);  DiskKey subSeg = GetNodeSlot(segRoot, slot);  DiskKey newSubSeg = DoAddSubsegToBlackSegment(subSeg, subSegOffset, segKey);  SetNodeSlot(segRoot, slot, newSubSeg);  return segRoot;}DiskKeyErosImage::AddSubsegToSegment(const DiskKey& segRoot,			      uint64_t segOffset,			      const DiskKey& segKey){  ValidateSegKey(this, segKey);  if (segKey.IsType(KT_Node) == false &&      segKey.IsType(KT_Segment) == false &&      segKey.IsType(KT_Page) == false)    Diag::fatal(4, "AddSubsegToSegment: added subseg must be segment, "		"segtree, or page\n");#if 0  if (segKey.IsSegModeType() == false)    Diag::fatal(4, "AddSubsegToSegment expects segment key\n");#endif  DiskKey rootKey;  PrepareToAddObjectToSegment(this, segRoot, segOffset, segKey,                              rootKey /* output */ );  if (rootKey.IsType(KT_Segment))    rootKey.SetType(KT_Node);    DiskKey newSegRoot = DoAddSubsegToBlackSegment(rootKey, segOffset, segKey);#ifdef KT_Wrapper  if ( segRoot.IsType(KT_Wrapper) )    return segRoot;#else  if ( segRoot.IsRedSegmentKey() )    return segRoot;#endif  return newSegRoot;}boolErosImage::DoGetPageInSegment(const DiskKey& segRoot,			      uint64_t segOffset,			      DiskKey& pageKey){  /* pageSegLSS holds the LSS of the smallest segment that could   * conceivably contain pageAddr.   */  uint32_t segOffsetBLSS = LSS::BiasedLSS(segOffset);  uint32_t rootBLSS = GetAnyBlss(segRoot);    if (segOffsetBLSS > rootBLSS)    return false;  if (segOffsetBLSS < rootBLSS) {    DiskKey subSeg = GetNodeSlot(segRoot, 0);    return DoGetPageInSegment(subSeg, segOffset, pageKey);  }  /* Handle single page or empty segments: */  if (segOffsetBLSS == rootBLSS && segOffsetBLSS == EROS_PAGE_BLSS) {    pageKey = segRoot;    return (segRoot.IsType(KT_Page)) ? true : false;  }  /* segOffsetBlss == rootBLSS, not a page:   * page key goes somewhere beneath current tree:   */  uint32_t slot = LSS::SlotNdx(segOffset, segOffsetBLSS);  segOffsetBLSS--;  uint64_t subSegOffset = segOffset;  subSegOffset &= LSS::Mask(segOffsetBLSS);  DiskKey subSeg = GetNodeSlot(segRoot, slot);  return DoGetPageInSegment(subSeg, subSegOffset, pageKey);}boolErosImage::GetPageInSegment(const DiskKey& segRoot,			    uint64_t segOffset,			    DiskKey& pageKey){  ValidateSegKey(this, segRoot);  return DoGetPageInSegment(segRoot, segOffset, pageKey);}voidErosImage::SetPageWord(DiskKey& pageKey, uint32_t offset,		       uint32_t value){  if (pageKey.IsType(KT_Page) == false)    Diag::fatal(5, "ErosImage::SetPageWord requires page key!\n");    if (offset % 4)    Diag::fatal(5, "ErosImage::SetPageWord offset must be word address!\n");      /* Okay, here's the tricky part.  It's quite possible that the page   * key we were handed was a zero page key.  If so, we fabricate a   * new (nonzero) page to replace it and change all of the existing   * keys to this page to point to the new page:   */  if (pageKey.IsPrepared()) {    uint8_t buf[EROS_PAGE_SIZE];    memset(buf, 0, EROS_PAGE_SIZE);        DiskKey newPage = AddDataPage(buf);    /* Relocate all of the keys in the image to reflect the removal of     * this zero page.     */    for (uint32_t nodeNdx = 0; nodeNdx < nNodes; nodeNdx++) {      for (uint32_t keyNdx = 0; keyNdx < EROS_NODE_SIZE; keyNdx++) {	DiskKey& key = nodeImages[nodeNdx][keyNdx];	if (key.IsType(KT_Page) == false || key.IsPrepared() == false)	  continue;		/* It's a zero page key.  May need relocation:  */	if (key.unprep.oid == pageKey.unprep.oid) {	  /* This is a key to the old (zero) page.  Do an in-place	   * swap for the new key, leaving all old attributes untouched.	   */	  key.unprep.oid = newPage.unprep.oid;	}	if (key.unprep.oid > pageKey.unprep.oid) {	  /* This is a key to a zero page that is AFTER the one we are	   * removing. Decrement it's oidLo by 1:	   */	  key.unprep.oid = key.unprep.oid-1;	}      }    }    for (uint32_t dirNdx = 0; dirNdx < nDirEnt; dirNdx++) {	DiskKey& key = dir[dirNdx].key;	if (key.IsType(KT_Page) == false || key.IsPrepared() == false)	  continue;		/* It's a zero page key.  May need relocation:  */	if (key.unprep.oid == pageKey.unprep.oid) {	  /* This is a key to the old (zero) page.  Do an in-place	   * swap for the new key, leaving all old attributes untouched.	   */	  key.unprep.oid = newPage.unprep.oid;	}	if (key.unprep.oid > pageKey.unprep.oid) {	  /* This is a key to a zero page that is AFTER the one we are	   * removing. Decrement it's oidLo by 1:	   */	  key.unprep.oid = key.unprep.oid-1;	}    }        /* We have replaced a zero page with a nonZero page, and removed     * all references to the old zero page, relocating accordingly.     * We now have one less zero page:     */    nZeroPages--;    /* Finally, we need to relocate the page key we were handed too! */    pageKey.unprep.oid = newPage.unprep.oid;  }    uint32_t pageNdx = pageKey.unprep.oid;  uint8_t *pageContent = &pageImages[pageNdx*EROS_PAGE_SIZE];  *((uint32_t *) &pageContent[offset]) = value;}voidErosImage::PrintNode(const DiskKey& nodeKey){  for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) {    DiskKey key = GetNodeSlot(nodeKey, i);    if (key.IsVoidKey())      continue;        Diag::printf("  [%2d] ", i);    PrintDiskKey(key);    Diag::printf("\n");  }}voidErosImage::PrintPage(const DiskKey& pageKey){  if (pageKey.IsPrepared()) {    Diag::printf("Page OID=");    Diag::print(pageKey.unprep.oid);    Diag::printf(" flags=Z (zero page)\n");  }  else {    Diag::printf("Page OID=");    Diag::print(pageKey.unprep.oid);    Diag::printf("\n");    uint8_t *bufp = &pageImages[((uint32_t)pageKey.unprep.oid) * EROS_PAGE_SIZE];    for (int i = 0; i < 8; i++) {      Diag::printf("    ");      for (int j = 0; j < 16; j++) {	Diag::printf("%02x", *bufp);	bufp++;      }      Diag::printf("\n");    }    Diag::printf("...\n");  }  Diag::printf("\n");}/* Given a node key, pretend it's a domain and print it out: */voidErosImage::PrintDomain(const DiskKey& domRoot){  if (domRoot.IsNodeKeyType() == false)    Diag::fatal(4, "Non-node key passed to PrintDomain\n");  DiskKey genKeys = GetNodeSlot(domRoot, ProcGenKeys);  Diag::printf("Domain root:\n");  for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) {    Diag::printf("  [%2d] ", i);    DiskKey key = GetNodeSlot(domRoot, i);        PrintDiskKey(key);    /* keeper key must be start key: */    if (i == ProcKeeper &&	key.IsType(KT_Start) == false &&	! key.IsVoidKey() )      Diag::printf(" (malformed)");    /* address space key must be segmode key: */    if (i == ProcAddrSpace &&	key.IsType(KT_Segment) == false &&	key.IsType(KT_Node) == false &&	key.IsType(KT_Page) == false)      Diag::printf(" (malformed)");          if (i == ProcGenKeys && !key.IsNodeKeyType())      Diag::printf(" (malformed)");        Diag::printf("\n");  }  if (genKeys.IsNodeKeyType()) {    Diag::printf("General Keys:\n");    for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) {      Diag::printf("  [%2d] ", i);      DiskKey key = GetNodeSlot(genKeys, i);          PrintDiskKey(key);      Diag::printf("\n");    }  }}voidErosImage::PrintSegment(const DiskKey& segKey){  DoPrintSegment(0, segKey, 0, 0, false);}voidErosImage::DoPrintSegment(uint32_t slot, const DiskKey& segKey,			  uint32_t indent, const char *annotation,			  bool startKeyOK){  /* Only print top-level void keys: */  if (indent && segKey.IsVoidKey())    return;  for (uint32_t i = 0; i < indent; i++)     Diag::printf("  ");  switch(segKey.GetType()) {  case KT_Node:  case KT_Segment:    Diag::printf("[%2d] :", slot);    PrintDiskKey(segKey);    if (annotation)      Diag::printf(" (%s)", annotation);    Diag::printf("\n");#ifdef KT_Wrapper    if ( segKey.IsType(KT_Wrapper) ) {      DiskKey fmtKey = GetNodeSlot(segKey, WrapperFormat);      if (fmtKey.IsType(KT_Number) == false) {	for (int i = 0; i < WrapperFormat; i++) {	  DiskKey key = GetNodeSlot(segKey, i);	  DoPrintSegment(i, key, indent+1, 0, false);	}	DoPrintSegment(WrapperFormat, fmtKey, indent+1, "format, malformed", 0);	return;      }      /* Have valid format key and valid kpr/bg slots: */      for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) {	char *annotation = 0;	bool startKeyOK = false;		DiskKey key = GetNodeSlot(segKey, i);	if (i == WrapperFormat) {	  annotation = "format";	}	else if (i == WrapperBackground &&		 (fmtKey.nk.value[0] & WRAPPER_BACKGROUND)) {	  annotation = "background";	}	else if (i == WrapperSpace) {	  annotation = "space";	}	else if (i == WrapperKeeper &&		 (fmtKey.nk.value[0] & WRAPPER_KEEPER)) {	  annotation = "keeper";	  startKeyOK = true;	}		DoPrintSegment(i, key, indent+1, annotation, startKeyOK);      }    }#else    if ( segKey.IsRedSegmentKey() ) {      DiskKey fmtKey = GetNodeSlot(segKey, RedSegFormat);      uint32_t initialSlots = EROS_NODE_SIZE - 3;      uint32_t bgslot = RedSegBackground;      uint32_t kprslot = RedSegKeeper;            bool goodFormatKey = fmtKey.IsValidFormatKey();      if (goodFormatKey) {	initialSlots = REDSEG_GET_INITIAL_SLOTS(fmtKey.nk);	bgslot = REDSEG_GET_BG_SLOT(fmtKey.nk);	kprslot = REDSEG_GET_KPR_SLOT(fmtKey.nk);      }      if (goodFormatKey == false) {	for (int i = 0; i < RedSegFormat; i++) {	  DiskKey key = GetNodeSlot(segKey, i);	  DoPrintSegment(i, key, indent+1, 0, false);	}	DoPrintSegment(RedSegFormat, fmtKey, indent+1, "format, malformed", 0);	return;      }      /* Have valid format key and valid kpr/bg slots: */            for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) {	char *annotation = 0;	bool startKeyOK = false;		DiskKey key = GetNodeSlot(segKey, i);	if (i == RedSegFormat)	  annotation = "format";	else if (i == bgslot)	  annotation = "background";	else if (i == kprslot) {	  annotation = "keeper";	  startKeyOK = true;	}		DoPrintSegment(i, key, indent+1, annotation, startKeyOK);      }    }#endif    else {      for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) {	DiskKey key = GetNodeSlot(segKey, i);	DoPrintSegment(i, key, indent+1, 0, false);      }    }    break;  case KT_Page:  case KT_Number:    Diag::printf("[%2d] ", slot);    PrintDiskKey(segKey);    if ((segKey.nk.value[0] & 3) == 3)      Diag::printf(" (background window)");    if (annotation)      Diag::printf(" (%s)", annotation);    Diag::printf("\n");    break;  case KT_Start:  case KT_Resume:    {      if (startKeyOK) {	Diag::printf("[%2d] ", slot);	PrintDiskKey(segKey);	if (annotation)	  Diag::printf(" (%s)", annotation);	Diag::printf("\n");	break;      }      /* fall through */    }  default:    Diag::printf("[%2d] ", slot);    PrintDiskKey(segKey);    if (annotation)      Diag::printf(" (%s, malformed)\n", annotation);    else      Diag::printf("(malformed)\n");  }}voidErosImage::SetProcessState(const DiskKey& procRoot, uint8_t state){  DiskKey key = GetNodeSlot(procRoot, ProcTrapCode);  key.nk.value[2] &= key.nk.value[2] & 0xffffff00;  key.nk.value[2] |= state;  SetNodeSlot(procRoot, ProcTrapCode, key);}	  uint8_tErosImage::GetProcessState(const DiskKey& procRoot){  DiskKey key = GetNodeSlot(procRoot, ProcTrapCode);  uint32_t state = key.nk.value[2] & 0xffu;  return state;}	  DiskKeyErosImage::AddProcess(){  DiskKey rootKey = AddNode();  DiskKey keyregsKey = AddNode();  SetNodeSlot(rootKey, ProcGenKeys, keyregsKey);  /* Domain is initially available: */  SetProcessState(rootKey, RS_Available);  return rootKey;}voidErosImage::ClearNode(const DiskKey &nodeKey){  for (uint32_t i = 0; i < EROS_NODE_SIZE; i++)    SetNodeSlot(nodeKey, i, VoidDiskKey());}

⌨️ 快捷键说明

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