📄 key.hxx
字号:
#ifndef __KEY_HXX__#define __KEY_HXX__/* * Copyright (C) 1998, 1999, 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. *//* Dependencies: */#include <eros/memory.h>#include <disk/KeyStruct.hxx>#include <kerninc/ObjectHeader.hxx>class Node;struct ObjectHeader;struct DiskKey;/* * Key. A Key is a capability, in the sense of Hydra or the Sigma-7. * EROS is a pure capability system, which means that Keys are the * only namespace known to the system. They are therefore the *only* * way that one can refer to an object within EROS. * * A Key names a Page (see Page.hxx), a Node (see Node.hxx), a Number, * or one of the EROS devices or miscellaneous kernel tools. * * Keys have an on-disk and in-core form. Both are 3 words. A valid * in-core key points to an in-core object. * * Before being used, a Key must be converted to in-core form, but * this is done in a lazy fashion, so many of the Keys that happen to * be in core remain encoded in the on-disk form. A Key that has been * converted for use in its in-core form is said to be "prepared." * * Number, Device, and Miscellaneous keys have the same form on disk * as in core: * * +--------+--------+--------+--------+ * | Data[31:0] | * +--------+--------+--------+--------+ * | Data[63:32] | * +--------+--------+--------+--------+ * |000 Type| Data[87:64] | * +--------+--------+--------+--------+ * * NOTE: Reorder per machine's natural word order for long long * * In the in-core form, the P bit is always set (1). This eliminates * the need to special case the check for Key preparedness for this * class of Keys. * * The Type field encodes only primary keys, and is always 5 bits * wide. In the Number key, the Data slots hold the numeric value. In * Device and Miscellaneous key, they differentiate the called device * or tool. * * The Sanity field is used by the system sanity checker to verify * that the world is sane. It's value should not be examined or * counted on. * * * Page and Node keys (all other cases) are a bit different in core * then they are on disk: * * +--------+--------+--------+--------+ * | Allocation Count | PREPARED IN CORE * +--------+--------+--------+--------+ * | Pointer to ObHeader for object | * +--------+--------+--------+--------+ * |Phh Type|Datauint8_t| OID[47:32] | * +--------+--------+--------+--------+ * * +--------+--------+--------+--------+ * | Allocation Count | ON DISK * +--------+--------+--------+--------+ * | OID[31:0] | * +--------+--------+--------+--------+ * |000 Type|Datauint8_t| OID[47:32] | * +--------+--------+--------+--------+ * * For an interpretation of the fields, see eros/KeyType.hxx. * * The Datauint8_t is an 8 bit value handed to the recipient when the Key * is invoked. It allows the recipient to handle multiple client * classes by providing each client class with a unique Datauint8_t. * * The ObHeader Pointer is an in-core pointer to the object denoted by * the Key. * * The Allocation Count is used to rescind keys to pages and notes. * This is described in the rescind logic for Keys. * */class Key : public KeyBits { /* BOOK: The reason to separate rHazard and wHazard is that it * lets PTE's dangle in the wind, which is sometimes profitable. * This is an optimization we might wish to leave out of the book. */public:#if 0 Key(KeyType kt, uint8_t db); /* This is wrong - need more args. */#endif Key(); #if 0 ~Key();#endif /* The following two calls should NEVER be used, and I occasionally * forget. By including declarations for them here, I suppress * automatic generation by the compiler and guarantee that a link * error will result if you use them. * * The solution is to use NH_Set instead, NOT to insert definitions * for these functions. It makes a HUGE difference in performance * to use NH_Set vs. the general case set! */ Key& operator =(const Key& that); Key(const Key& that); private: void DoPrepare(); public:#ifndef NDEBUG bool IsValid() const;#endif #ifdef NDEBUG void Prepare() { if (IsUnprepared()) DoPrepare(); if ( NeedsPin() ) ok.pObj->TransLock(); }#else void Prepare();#endif /* Prepare a key, which must be of type kt */ bool Prepare(KeyType kt); /* ALL OF THE NH ROUTINES MUST BE CALLED ON NON-HAZARDED KEYS */ /* Unprepare current key with intention to overwrite immediately, so * no need to remember that the key was unprepared. */ void NH_Unchain() { IKS_Unchain(); } /* Called from Node::Unprepare after hazards are cleared. Also used * by Thread unprepare, which is why it is in the key rather than * the node. */ void NH_Unprepare(); /* KS_Set now checks for need to unchain internally. */ void NH_Set(KeyBits& kb) { KS_Set(kb); } /* Purely inlined version: */ void INH_Set(KeyBits& kb) { IKS_Set(kb); } void NH_VoidKey() { KS_VoidKey(); } void NH_RescindKey() { KS_RescindKey(); } OID GetKeyOid() const; ObjectHeader *GetObjectPtr() const; uint32_t GetAllocCount() const; void Print() const; #ifdef OPTION_OB_MOD_CHECK uint32_t CalcCheck();#endif static Key VoidKey;} ;/* Orders on Various Key Types: * * KtNumber: * * KeyType * GetData(small); aslong * GetData(medium); aslonglong * GetData(large); asNumber ;-) (spec'd to return as 16 bytes) * * KtDataPage: * * Return a read-only key to same page (ROpageKey) - impl in * Datauint8_t * Read(start, buf) * DOCNOTE: logically returns entire page, wrapping at the end. * this is bounded by the buffer size in implementation. * Write(start, buf) (not on ROkeys) * DOCNOTE: logically returns entire page, wrapping at the end. * this is bounded by the buffer size in implementation. * Clear() - very fast, but don't play poker with Norm. Also, don't * tell the marketeers, who will subsequently tell the public * that EROS can clear any size page in one instruction on any * architectrue. * * KtNode: * get(n,nr) - fetch key in slot N into domain's node register nr. * swap(n,nr) - swap key in slot N with domain's node register nr. * Don't have to accept the responding key, so this subsumes * set(). * LIBNOTE: should have a set() in the access library. Blech. * * asMeter() - obvious conversions (Datauint8_t always 0) * asSegment(Datauint8_t) * asDomain(Datauint8_t) * asTimer(Datauint8_t) * asNode(Datauint8_t) * asFetch(Datauint8_t) * asSensory(Datauint8_t) FIX - norm thinks there's a virtualization * issue buried here. * datauint8_t() - return the data byte in the return code. (?) Maybe * should be in register-string * clear() - c.f. page clear. Same problem with marketeers. * numerate(start, buf) - place a number key in the node. In the old * logic, you could create multiple number keys in sequence, * which was useful. We do not do that for now. * * KtMeter: * no protocol outside the Kernel * might have stuff for key cacheing. * * KtSegment: * * getROSegment() - does this require dynamic allocation? * read() * write() * * send message to keeper. standard ops on keeper are: * * KtDomain: * Bill suggested dividing this into MI/MD parts. * * Machine Independent: * * SetAddressSlot(KeyReg): - alternative: set both. Option: * give new PC. * SetMeterSlot(KeyReg): * SetKeeperSlot(KeyReg): * SetSymbolSlot(): * * GetAddressSlots(KeyReg): * GetMeterSlot(KeyReg): * GetKeeperSlot(KeyReg): * GetSymbolSlot: * * GetStartKey(Datauint8_t): * Reset() - makes the domain available * Stop() => (ResumeKey,GeneralRegs) * * FetchKeyReg(nkr): * SwapKeyReg(nkr): * * GetDomainInfo() - returns general information about the Domain * implementation. * * SetPC(): * GetPC(): * * SingleStep() - step a single instruction, may fail. Arch defined * on delay slots. * * NOTE: canNOT get the brand or the general registers nodes. * * Machine Dependent: * * Get{General,Float}Registers(): * Set{General,Float}Registers(): * * GetTrapCode(): * SetTrapCode(): * * KtTimer: * * SetInterval(interval) * SleepFor(interval) - sets interval too * Sleep() - useful for rendevous * * KtStart, KtResume: * * Sends message to the domain itself. * * KtFetch: * get(n,nr) - fetch key in slot N into domain's node register nr. * swap(n,nr): * asMeter(): * asSegment(Datauint8_t): * asDomain(Datauint8_t): * asTimer(Datauint8_t): * asNode(Datauint8_t): * these always fail in kernel. Should this be accesViolation or * badOrderCode? * * asFetch(Datauint8_t) - see Node protocol? What current designs does * this break? * asSensory(Datauint8_t) - if I can get a fetch key, I can get a sense * key. * * datauint8_t() - return the data byte in the return code. (?) Maybe * should be in register-string * clear(): * numerate(start, buf): * - fails, either accessViolation or invalidOrder. * * KtRange: * Range key argument CDAs are expressed as offsets relative to * the start of the range controlled by the range key. * getPageKey(relative CDA) - policy issue here. Should bank be * cognizant of disk partitions? * rescindPageKey(relative CDA) * makeSubRangeKey(relative start, count) - NEW and IMPROVED! Well, * new at least. * validCDA(relative CDA) * maxCDAQuery(buf) * * KtHook: * No protocol - just a kernel tool * * KtDevice: * Block: * read() * write() * seek() * reset() * init() * control() * size() * shutdown() * * Disk * Screen * WallClock * OPTION_SCSI[0..7] - multimaster; where does this belong? * * Asynch: * read() * write() * ?seek() * reset() * init() * control() * size() * shutdown() * * Keyboard * Mouse * Serial * Parallel * OPTION_SCSI[0..7] * * ?WallClock * ?DiskPackManager - manages removable media * * KtMisc: * DomainCreator * Returner * Discrim * DataCreater * DeviceCreator - creator/rescinder of device keys * Journaler * Checkpointer * Shutdown/Reboot * ErrorKey - used by error log daemon * ?ItimerCreator - Wall banging issue * ?OPTION_SCSIKeyCreator - Avoid this if can be done dynamically. Lets me * tell the kernel about the ones it can't decipher. * * Tool specific * */#endif /* __KEY_HXX__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -