BOOT_CODE static bool_t create_untypeds_for_region( cap_t root_cnode_cap, region_t reg, slot_pos_t first_untyped_slot ) { uint32_t align_bits; uint32_t size_bits; while (!is_reg_empty(reg)) { /* Determine the maximum size of the region */ size_bits = WORD_BITS - 1 - boot_clz(reg.end - reg.start); /* Determine the alignment of the region */ align_bits = boot_ctz(reg.start); /* Reduce size bits to align if needed */ if (align_bits < size_bits) { size_bits = align_bits; } assert(size_bits >= WORD_BITS / 8); if (!provide_untyped_cap(root_cnode_cap, reg.start, size_bits, first_untyped_slot)) { return false; } reg.start += BIT(size_bits); } return true; }
BOOT_CODE bool_t create_untypeds_for_region( cap_t root_cnode_cap, bool_t deviceMemory, region_t reg, slot_pos_t first_untyped_slot ) { uint32_t align_bits; uint32_t size_bits; while (!is_reg_empty(reg)) { /* Due to a limitation on the mdb we cannot give out an untyped to the * the start of the kernel region. The reason for this is that cte pointers * in mdb nodes are stored with the high bits masked out. To recreate a cte pointer * we then need to put the high bits back in after reading it out. HOWEVER, we * still need a way to store and identify a NULL pointer. This means reserving * the bottom address as the 'null' address so that no one creates an cnode * there resulting in a 'null' (yet valid) cte */ if (!deviceMemory && reg.start == kernelBase) { reg.start += BIT(PAGE_BITS); } /* Determine the maximum size of the region */ size_bits = WORD_BITS - 1 - boot_clz(reg.end - reg.start); /* Determine the alignment of the region */ align_bits = boot_ctz(reg.start); /* Reduce size bits to align if needed */ if (align_bits < size_bits) { size_bits = align_bits; } assert(size_bits >= WORD_BITS / 8); if (!provide_untyped_cap(root_cnode_cap, deviceMemory, reg.start, size_bits, first_untyped_slot)) { return false; } reg.start += BIT(size_bits); } return true; }