📄 kern_physpagesource.cxx
字号:
/* * Copyright (C) 2001, 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. *//* ObjectRange driver for preloaded ram ranges */#include <kerninc/kernel.hxx>#include <kerninc/Thread.hxx>#include <kerninc/Machine.hxx>#include <kerninc/util.h>#include <kerninc/ObjectCache.hxx>#include <kerninc/ObjectSource.hxx>#include <kerninc/PhysMem.hxx>#include <eros/Device.h>#include <disk/PagePot.hxx>#include <disk/DiskNode.hxx>#include <kerninc/BootInfo.h>/* We simulate physical page allocation counters using a single * universal allocation counter that is bumped for each new * allocation. Since the physical page ObjectHeader is pinned, the * only time this will get checked is when an old key is prepared * following revocation of the underlying physical page. * * Note that there is a serious potential security hole here if a * physical page key is EVER stored into a persistent node, because * the user might well get lucky on the allocation count. */static ObCount PhysPageAllocCount = 0u;/* The current implementation isn't quite kosher, as the current * implementation is built to assume a preloaded ramdisk, and the * ramdisk boot sector is inherently machine dependent. At some point * in the (near) future, I am going to implement the range preload * flag, and the need for this hack will go away. */#include <disk/LowVolume.hxx>/* It might appear that this is wrong, because we do not know at the * time this constructor runs how many allocatable physical pages * there will be. Actually, we can't ever really know how many * physically allocatable pages are in a given region, because the * kernel may yet do dynamic memory allocations for itself (e.g. to * allocate core table entries when it is informed of physical memory * on cards. * * The good news, such as it is, is that we actually can know the * right answer when the time comes to (de)allocate the actual pages. */PhysPageSource::PhysPageSource(PmemInfo *argPmi) : ObjectSource("physpage", OID_RESERVED_PHYSRANGE + ((argPmi->base / EROS_PAGE_SIZE) * EROS_OBJECTS_PER_FRAME), OID_RESERVED_PHYSRANGE + ((argPmi->bound / EROS_PAGE_SIZE) * EROS_OBJECTS_PER_FRAME)){ pmi = argPmi;}static inline boolValidPhysPage(PmemInfo *pmi, kpa_t pgFrame){ if (pgFrame < pmi->basepa) return false; kpa_t relFrameNdx = (pgFrame - pmi->basepa) / EROS_PAGE_SIZE; if (relFrameNdx >= pmi->nPages) return false; return true;}ObjectHeader *PhysPageSource::GetObject(OID oid, ObType::Type obType, ObCount count, bool useCount){ kpa_t pgFrame = (oid - OID_RESERVED_PHYSRANGE) / EROS_OBJECTS_PER_FRAME; pgFrame *= EROS_PAGE_SIZE; if (!ValidPhysPage(pmi, pgFrame)) { dprintf(true, "OID 0x%08x%08x invalid\n", (unsigned long) (oid >> 32), (unsigned long) (oid)); return 0; } ObjectHeader *pObj = ObjectCache::PhysPageToObHdr(pgFrame); if (pObj == 0) { dprintf(true, "PhysPageSource::GetObject(): No header!\n"); return pObj; }#ifndef NDEBUG kpa_t relFrameNdx = (pgFrame - pmi->basepa) / EROS_PAGE_SIZE; assert(pObj == &pmi->firstObHdr[relFrameNdx]);#endif ObjectCache::EvictFrame(pObj); pObj->ob.oid = oid; pObj->ob.allocCount = PhysPageAllocCount; pObj->age = Age::NewBorn; pObj->SetFlags(OFLG_CURRENT|OFLG_DISKCAPS); assert (pObj->GetFlags(OFLG_CKPT|OFLG_DIRTY|OFLG_REDIRTY|OFLG_IO) == 0); pObj->ob.ioCount = 0; if (pmi->type == MI_DEVICEMEM) { pObj->obType = ObType::PtDevicePage; /* Do not bother with calculating the checksum value, as device * memory is always considered dirty. */ pObj->SetFlags(OFLG_DIRTY); } else { pObj->obType = ObType::PtDataPage;#ifdef OPTION_OB_MOD_CHECK pObj->ob.check = pObj->CalcCheck();#endif } pObj->ResetKeyRing(); pObj->Intern(); printf("PhysPageSource::GetObject() untested!\n"); return pObj;}boolPhysPageSource::Invalidate(ObjectHeader *pObj){ if (pObj->obType == ObType::PtDevicePage) { fatal("PhysPageSource::Invalidate(PtDevicePage) is nonsense\n"); } else { assert(pObj->obType == ObType::PtDataPage); kpa_t pgFrame = pObj->pageAddr; if (!ValidPhysPage(pmi, pgFrame)) return false; /* Okay, now this is a real nuisance. Free the frame and bump the * global physical frame allocation count. */ assert(pObj->kr.IsEmpty()); assert(pObj->products == 0); pObj->Unintern(); pObj->ClearFlags(OFLG_DIRTY); /* FIX: What about transaction lock? */ ObjectCache::ReleaseFrame(pObj); PhysPageAllocCount ++; fatal("PhysPageSource::Invalidate() unimplemented\n"); } return false;}boolPhysPageSource::Detach(){ fatal("PhysPageSource::Detach() unimplemented\n"); return false;}boolPhysPageSource::WriteBack(ObjectHeader *, bool){ fatal("PhysPageSource::WriteBack() unimplemented\n"); return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -