📄 erosimage.cxx
字号:
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 + -