[wip] Untyped cap
This commit is contained in:
		
							parent
							
								
									fc6fa7105a
								
							
						
					
					
						commit
						eb0aed1730
					
				|  | @ -41,14 +41,81 @@ register_bitfields! { | |||
|             value = 0 | ||||
|         ] | ||||
|     ], | ||||
|     // The combination of freeIndex and blockSize must match up with the
 | ||||
|     // definitions of MIN_SIZE_BITS and MAX_SIZE_BITS
 | ||||
|     // -- https://github.com/seL4/seL4/blob/master/include/object/structures_32.bf#L18
 | ||||
|     //
 | ||||
|     // /* It is assumed that every untyped is within seL4_MinUntypedBits and seL4_MaxUntypedBits
 | ||||
|     //  * (inclusive). This means that every untyped stored as seL4_MinUntypedBits
 | ||||
|     //  * subtracted from its size before it is stored in capBlockSize, and
 | ||||
|     //  * capFreeIndex counts in chunks of size 2^seL4_MinUntypedBits. The seL4_MaxUntypedBits
 | ||||
|     //  * is the minimal untyped that can be stored when considering both how
 | ||||
|     //  * many bits of capBlockSize there are, and the largest offset that can
 | ||||
|     //  * be stored in capFreeIndex */
 | ||||
|     // +#define MAX_FREE_INDEX(sizeBits) (BIT( (sizeBits) - seL4_MinUntypedBits ))
 | ||||
|     // +#define FREE_INDEX_TO_OFFSET(freeIndex) ((freeIndex)<<seL4_MinUntypedBits)
 | ||||
|     // #define GET_FREE_REF(base,freeIndex) ((word_t)(((word_t)(base)) + FREE_INDEX_TO_OFFSET(freeIndex)))
 | ||||
|     // #define GET_FREE_INDEX(base,free) (((word_t)(free) - (word_t)(base))>>seL4_MinUntypedBits)
 | ||||
|     // #define GET_OFFSET_FREE_PTR(base, offset) ((void *)(((word_t)(base)) + (offset)))
 | ||||
|     // +#define OFFSET_TO_FREE_INDEX(offset) ((offset)>>seL4_MinUntypedBits)
 | ||||
|     //
 | ||||
|     // exception_t decodeUntypedInvocation(word_t invLabel, word_t length,
 | ||||
|     //                                     cte_t *slot, cap_t cap,
 | ||||
|     //                                     extra_caps_t excaps, bool_t call,
 | ||||
|     //                                     word_t *buffer);
 | ||||
|     // exception_t invokeUntyped_Retype(cte_t *srcSlot, bool_t reset,
 | ||||
|     //                                  void *retypeBase, object_t newType,
 | ||||
|     //                                  word_t userSize, slot_range_t destSlots,
 | ||||
|     //                                  bool_t deviceMemory);
 | ||||
|     // // -- https://github.com/seL4/seL4/blob/master/src/object/untyped.c#L276
 | ||||
|     // -- https://github.com/seL4/seL4/blob/master/include/object/untyped.h
 | ||||
|     //
 | ||||
|     // /* Untyped size limits */
 | ||||
|     // #define seL4_MinUntypedBits 4
 | ||||
|     // #define seL4_MaxUntypedBits 47
 | ||||
|     // -- https://github.com/seL4/seL4/blob/master/libsel4/sel4_arch_include/aarch64/sel4/sel4_arch/constants.h#L234
 | ||||
|     //
 | ||||
|     // /*
 | ||||
|     //  * Determine where in the Untyped region we should start allocating new
 | ||||
|     //  * objects.
 | ||||
|     //  *
 | ||||
|     //  * If we have no children, we can start allocating from the beginning of
 | ||||
|     //  * our untyped, regardless of what the "free" value in the cap states.
 | ||||
|     //  * (This may happen if all of the objects beneath us got deleted).
 | ||||
|     //  *
 | ||||
|     //  * If we have children, we just keep allocating from the "free" value
 | ||||
|     //  * recorded in the cap.
 | ||||
|     //  */
 | ||||
|     // -- https://github.com/seL4/seL4/blob/master/src/object/untyped.c#L175
 | ||||
|     // /*
 | ||||
|     //  * Determine the maximum number of objects we can create, and return an
 | ||||
|     //  * error if we don't have enough space.
 | ||||
|     //  *
 | ||||
|     //  * We don't need to worry about alignment in this case, because if anything
 | ||||
|     //  * fits, it will also fit aligned up (by packing it on the right hand side
 | ||||
|     //  * of the untyped).
 | ||||
|     //  */
 | ||||
|     // -- https://github.com/seL4/seL4/blob/master/src/object/untyped.c#L196
 | ||||
| 
 | ||||
|     UntypedCap [ | ||||
|         FreeIndex OFFSET(0) NUMBITS(48) [], | ||||
|         /// Index of the first unoccupied byte within this Untyped.
 | ||||
|         /// This index is limited between MIN_UNTYPED_BITS and max bits number in BlockSizePower.
 | ||||
|         /// To occupy less bits, the free index is shifted right by MIN_UNTYPED_BITS.
 | ||||
|         ///
 | ||||
|         /// Free index is used only if this untyped has children, which may be occupying only
 | ||||
|         /// part of its space.
 | ||||
|         /// This means an Untyped can be retyped multiple times as long as there is
 | ||||
|         /// free space left in it.
 | ||||
|         FreeIndexShifted OFFSET(0) NUMBITS(48) [], | ||||
|         /// Device mapped untypeds cannot be touched by the kernel.
 | ||||
|         IsDevice OFFSET(57) NUMBITS(1) [], | ||||
|         BlockSize OFFSET(58) NUMBITS(6) [], | ||||
|         /// Untyped is 2**BlockSizePower bytes in size
 | ||||
|         BlockSizePower OFFSET(58) NUMBITS(6) [], | ||||
|         Type OFFSET(64) NUMBITS(5) [ | ||||
|             value = 2 | ||||
|         ], | ||||
|         Ptr OFFSET(80) NUMBITS(48) [] | ||||
|         /// Physical address of untyped.
 | ||||
|         Ptr OFFSET(80) NUMBITS(48) [], | ||||
|     ], | ||||
|     EndpointCap [ | ||||
|         Badge OFFSET(0) NUMBITS(64) [], | ||||
|  | @ -306,6 +373,51 @@ capdefs! { | |||
|     AsidControl, AsidPool | ||||
| } | ||||
| 
 | ||||
| // @todo retyping a device capability requires specifying memory base exactly, can't just pick next frame?
 | ||||
| 
 | ||||
| /// Capability to a block of untyped memory.
 | ||||
| /// Can be retyped into more usable types.
 | ||||
| impl UntypedCapability { | ||||
|     const MIN_BITS: usize = 4; | ||||
|     const MAX_BITS: usize = 47; | ||||
| 
 | ||||
|     pub fn is_device(&self) -> bool { | ||||
|         self.0.read(UntypedCap::IsDevice) == 1 | ||||
|     } | ||||
|     // BlockSize OFFSET(58) NUMBITS(6) [],
 | ||||
|     pub fn block_size(&self) -> usize { | ||||
|         1 << self.0.read(UntypedCap::BlockSizePower) | ||||
|     } | ||||
|     // FreeIndex OFFSET(0) NUMBITS(48) [],
 | ||||
|     pub fn free_area_offset(&self) -> usize { | ||||
|         use core::convert::TryInto; | ||||
|         Self::free_index_to_offset( | ||||
|             self.0 | ||||
|                 .read(UntypedCap::FreeIndexShifted) | ||||
|                 .try_into() | ||||
|                 .unwrap(), | ||||
|         ) | ||||
|     } | ||||
|     // Ptr OFFSET(80) NUMBITS(48) []
 | ||||
| 
 | ||||
|     // #define MAX_FREE_INDEX(sizeBits) (BIT( (sizeBits) - seL4_MinUntypedBits ))
 | ||||
|     pub fn max_free_index_from_bits(size_bits: usize) -> usize { | ||||
|         assert!(size_bits >= Self::MIN_BITS); | ||||
|         assert!(size_bits <= Self::MAX_BITS); | ||||
|         1 << (size_bits - Self::MIN_BITS) | ||||
|     } | ||||
| 
 | ||||
|     // #define FREE_INDEX_TO_OFFSET(freeIndex) ((freeIndex)<<seL4_MinUntypedBits)
 | ||||
|     fn free_index_to_offset(index: usize) -> usize { | ||||
|         index << Self::MIN_BITS | ||||
|     } | ||||
| 
 | ||||
|     // #define OFFSET_TO_FREE_INDEX(offset) ((offset)>>seL4_MinUntypedBits)
 | ||||
|     fn offset_to_free_index(offset: usize) -> usize { | ||||
|         offset >> Self::MIN_BITS | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // * Capability slots: 16 bytes of memory per slot (exactly one capability). --?
 | ||||
| // CapNode describes `a given number of capability slots` with `a given guard`
 | ||||
| // of `a given guard size` bits.
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue