📄 keystruct.hxx
字号:
#ifndef __KEYTYPE_HXX__#define __KEYTYPE_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. */#include <disk/ErosTypes.h>#include <disk/KeyRing.hxx>#include <eros/StdKeyType.h>#include <eros/Key.h>/* * KeyType - the major key types supported in EROS. Keys also have a subtype * For example, the Process Tool is KtMisc, KsProcTool. * */#define PRIMARY_KEY_TYPES 32#define PRIMARY_KEY_TYPE_BITS 5/* If these numbers change, the dispatch table in kerninc/Invoke.cxx * must be changed as well. Key preparation is a very frequent * operation in the kernel, so these numbers are ordered in such a way * as to take advantage of a representation pun. Key types having a * prepared form appear starting at zero. In the actual key data * structure, the first byte of the key is layed out as: * * (bit 7) hazard[2] :: prepared :: keytype[5] (bit 0) * * Both the hazard field and the prepared field are 0 on an unprepared * key. This allows a combined test on the byte value to determine * which keys need to be prepared and which keys need to be * validated. If the byte value is <= LAST_OBJECT_KEYTYPE, then the * key is NOT prepared and needs to be. If the key is prepared, it * needs to be validated. */#define LAST_GATE_KEYTYPE KT_Resume#define LAST_OBJECT_KEYTYPE KT_Page#define FIRST_MISC_KEYTYPE KT_KeyBits#define LAST_KEYTYPE KT_MISC+1typedef unsigned KeyType;/* Subtypes of resume key: */#define KsitResume 0 /* normal resume key */#define KsitFault 1 /* fault key -- cannot convey message */struct Prio { enum Priority { Inactive = -2, KernIdle = -1, UserIdle = 0, Normal = 8, High = 15 };} ;#ifndef KT_Wrapperstruct BLSS { enum { bit32 = 7, bit28 = 6, bit24 = 5, bit20 = 4, bit16 = 3, bit12 = 2, RedSeg = 1, };};#endif/* The ObjectHeader pointer declaration is unused in the on-disk * key format, but including it here is harmless and simplifies * the declarations in Key.hxx. */class ObjectTable;#if 0/************************************************************* * * NEW KEY TYPE BYTE ORGANIZATION (STILL EXPERIMENTAL): * * 7 6 2 1 0 * +-+-----------+---+---+ * |P| type |RHz|Whz| * +-+-----------+---+---+ * * P == 1 ==> prepared in this design, only object keys are * prepared. * * RATIONALE: * * 1. Key type comparison requires a mask operation in most * cases anyway, but since the comparison is to a constant * the shift operation should be resolvable at compile time. * * 2. Key types requiring preparation (object types) can be * tested for with a single less-than operation. * * 3. Key types requiring pin can be tested for with a simple * bit test. * * This rearrangement is in fact a precursor to the pin logic * change. * * One problem with this rearrangement is that it destroys the * bit pun in the keyring. That doesn't appear to be critical, * though. *************************************************************/#define KHAZARD_WRITE 0x1u#define KHAZARD_READ 0x2u#define PREPARED_KT_BIT __U(0x80)#define KHAZARD_BITS __U(0x3)#define KEYTYPE_BITS __U(0x7c) #define KEYTYPE_NEEDS_PREPARE(x) (x < ((LAST_OBJECT_KEYTYPE+1))) /* #define PREPARABLE_TYPE(x) ( ((x) & KEYTYPE_BITS) <= LAST_PREPARED_KEYTYPE ) */#define UNPREPARED_KT(x) ((uint8_t)(x) & ~PREPARED_KT_BIT)#define PREPARED_KT(x) ((uint8_t)(x) | PREPARED_KT_BIT)/* #define PREPPED_TYPE(ty) ((ty <= LAST_PREPARED_KEYTYPE) ? (ty | 0x2u) : ty) */#else#define KFL_PREPARED __U(0x80)#define KFL_RHAZARD __U(0x40)#define KFL_WHAZARD __U(0x20)#define KFL_HAZARD_BITS __U(0x60)#define KFL_ALL_FLAG_BITS __U(0xe0)#if 0#define PREPARED_KT_BIT __U(0x80)#define KEYTYPE_BITS __U(0x7f)#define KEYTYPE_IS_PREPPED(x) (x >= (LAST_OBJECT_KEYTYPE+1))#define UNPREPARED_KT(x) ((uint8_t)(x) & ~PREPARED_KT_BIT)#define PREPARED_KT(x) ((uint8_t)(x) | PREPARED_KT_BIT)#endif#endifstruct KeyBits {#ifdef BITFIELD_PACK_LOW uint8_t keyType; uint8_t keyFlags; uint16_t keyData;#else#error "verify bitfield layout" #endif /* ACCESSORS AND MUTATORS RELATING TO SEGMODE KEYS: */ uint32_t GetBlss() const { return keyData & SEGMODE_BLSS_MASK; } void SetBlss(uint32_t blss) { keyData = (keyData & ~SEGMODE_BLSS_MASK) | blss; } bool IsHazard() const { return (keyFlags & KFL_HAZARD_BITS); } void UnHazard() { keyFlags &= ~KFL_HAZARD_BITS; } void SetPrepared() { keyFlags |= KFL_PREPARED; } void SetUnprepared() { keyFlags &= ~KFL_PREPARED; } void SetRdHazard() { keyFlags |= KFL_RHAZARD; } void SetWrHazard() { keyFlags |= KFL_WHAZARD; } void SetRwHazard() { keyFlags |= KFL_RHAZARD|KFL_WHAZARD; } bool IsRdHazard() { return (keyFlags & KFL_RHAZARD); } bool IsWrHazard() { return (keyFlags & KFL_WHAZARD); } KeyType GetType() const { return (KeyType) keyType; } void InitType(uint8_t t) { keyType = (KeyType)t; /* not hazard, not prepared */ keyFlags = 0; keyData = 0; } void SetType(KeyType kt) { keyType = kt; } bool IsType(uint8_t t) const { return (GetType() == t); } bool IsNoCall() const { return (keyData & (SEGMODE_NC|SEGMODE_WEAK)) ? true : false; } void SetNoCall() { keyData |= SEGMODE_NC; } bool IsReadOnly() const { return (keyData & SEGMODE_RO) ? true : false; } bool IsWeak() const { return (keyData & SEGMODE_WEAK) ? true : false; } void SetWeak() { keyData |= SEGMODE_WEAK; } bool IsPrepared() const { if (keyFlags & KFL_PREPARED) return true; return false; } bool IsUnprepared() const { if ((keyFlags & KFL_PREPARED) == 0) return true; return false; } bool IsPreparedResumeKey() const { /* Resume keys are never hazarded... */ return (IsType(KT_Resume) && IsPrepared()) ? true : false; } void SetReadOnly() { keyData |= SEGMODE_RO; } #ifndef KT_Wrapper bool IsRedSegmentKey() const { return ((keyData & SEGMODE_BLSS_MASK) == BLSS::RedSeg) ? true : false; }#endif bool IsGateKey() const { return (GetType() <= LAST_GATE_KEYTYPE) ? true : false; } bool IsObjectKey() const { return (GetType() <= LAST_OBJECT_KEYTYPE) ? true : false; } bool NeedsPrepare() const { return IsUnprepared(); } bool IsPreparedObjectKey() const { return (IsObjectKey() && IsPrepared()) ? true : false; } bool NeedsPin() const { return (IsObjectKey() && !IsGateKey()) ? true : false; } bool IsMiscKey() const { return (GetType() >= FIRST_MISC_KEYTYPE) ? true : false; } bool IsNodeKeyType() const; bool IsSegKeyType() const { return (IsType(KT_Node) ||#ifdef KT_Wrapper IsType(KT_Wrapper) ||#endif IsType(KT_Segment)); } bool IsDataPageType() const { return (IsType(KT_Page) || IsType(KT_TimePage)); } bool IsSegModeType() const { return (IsSegKeyType() || IsDataPageType()); } /* EVERYTHING ABOVE HERE IS GENERIC TO ALL KEYS. Structures below * this point should describe the layout of a particular key type * and should occupy exactly three words. */ union { struct { ObCount count; OID oid; } unprep; /* Changes to this substructure must be coordinated with * KeyRing.hxx! */ struct { KeyRing *next; KeyRing *prev; struct ObjectHeader *pObj; } ok; struct { KeyRing *next; KeyRing *prev; struct Process *pContext; } gk; struct { /* NUMBER KEYS */ uint32_t value[3]; } nk; /* Priority keys use the keyData field, but no other fields. */ /* Miscellaneous Keys have no substructure, but use the 'keyData' * field. */ /* Device Keys (currently) have no substructure, but use the * 'keyData' field. */ /* It is currently true that oidLo and oidHi in range keys and * object keys overlap, but not important that they do so. */ struct { /* RANGE KEYS */ uint32_t count; OID oid; } rk; struct { /* DEVICE KEYS */ uint16_t devClass; uint16_t devNdx; uint32_t devUnit; } dk; struct { /* QUEUE MISC KEY */ uint32_t releaseCount; uint32_t value[2]; /* This is a horrible representation pun, user here solely to * avoid the need to publish the link structure outside the kernel */ class ThreadPile& AsThreadPile() { return * ((ThreadPile *) &value[0]); } } semaMiscKey; } ; /* IsVoidKey does not check for a rescinded key, only that the current representation is void. */ bool IsVoidKey() const { return IsType(KT_Void); }#ifndef KT_Wrapper#ifdef NEW_SEGMENT_LOGIC bool IsValidFormatKey() const { if ( ( IsType(KT_Number)) && ( REDSEG_GET_BLSS(nk) > EROS_PAGE_BLSS ) && ( REDSEG_GET_INITIAL_SLOTS(nk) <= REDSEG_GET_RESERVED_SLOTS(nk) ) && ( REDSEG_GET_INITIAL_SLOTS(nk) < EROS_NODE_SLOT_MASK ) && ( REDSEG_GET_RESERVED_SLOTS(nk) <= EROS_NODE_SLOT_MASK ) ) return true; return false; }#else bool IsValidFormatKey() const { if ( ( IsType(KT_Number)) && ( REDSEG_GET_BLSS(nk) > EROS_PAGE_BLSS ) && ( (nk.value[0] & 0xc0) == 0 ) && ( REDSEG_GET_INITIAL_SLOTS(nk) < EROS_NODE_SLOT_MASK ) && ( REDSEG_GET_RESERVED_SLOTS(nk) <= EROS_NODE_SLOT_MASK ) ) return true; return false; }#endif#endif #ifdef __KERNEL__ inline void KeyBits::IKS_Unchain();#endif void KS_SetNumberKey(uint32_t hi, uint32_t mid, uint32_t lo); inline void KS_VoidInitKey(); void KS_VoidKey(); void KS_RescindKey() { KS_VoidKey(); } void KS_Set(KeyBits& kb);#ifdef __KERNEL__ inline void IKS_VoidKey(); inline void IKS_Set(KeyBits& kb);#endif} ;#ifdef __KERNEL__inline voidKeyBits::IKS_Unchain(){ if ( IsPreparedObjectKey() ) { ok.next->prev = ok.prev; ok.prev->next = ok.next; }}#endifinline voidKeyBits::KS_VoidInitKey(){ /* Overwrite with void without first checking anything at all! */ InitType(KT_Void); nk.value[2] = 0; nk.value[1] = 0; nk.value[0] = 0;}#ifdef __KERNEL__inline voidKeyBits::IKS_VoidKey(){#ifdef __KERNEL__ IKS_Unchain();#endif KS_VoidInitKey();}inline voidKeyBits::IKS_Set(KeyBits& kb){ /* Skip copy if src == dest (surprisingly often!) */ if (&kb == (KeyBits*) this) return; #ifdef __KERNEL__ IKS_Unchain();#endif keyType = kb.keyType; keyFlags = kb.keyFlags & ~KFL_HAZARD_BITS; keyData = kb.keyData; nk.value[0] = kb.nk.value[0]; nk.value[1] = kb.nk.value[1]; nk.value[2] = kb.nk.value[2]; /* Update the linkages if destination is now prepared: */ if ( IsPreparedObjectKey() ) { ok.prev->next = (KeyRing*) this; ok.next = (KeyRing*) &kb; kb.ok.prev = (KeyRing*) this; }}#endif#endif /* __KEYTYPE_HXX__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -