boot: fail boot if region configuration is invalid
Also make the output more verbose in case of errors, which is helpful when porting the kernel to new platforms. Signed-off-by: Axel Heider <axelheider@gmx.de>
This commit is contained in:
parent
adbd374370
commit
938c1c9557
5 changed files with 74 additions and 33 deletions
|
|
@ -47,9 +47,9 @@ static inline bool_t is_reg_empty(region_t reg)
|
|||
return reg.start == reg.end;
|
||||
}
|
||||
|
||||
void init_freemem(word_t n_available, const p_region_t *available,
|
||||
word_t n_reserved, const region_t *reserved,
|
||||
v_region_t it_v_reg, word_t extra_bi_size_bits);
|
||||
bool_t init_freemem(word_t n_available, const p_region_t *available,
|
||||
word_t n_reserved, const region_t *reserved,
|
||||
v_region_t it_v_reg, word_t extra_bi_size_bits);
|
||||
bool_t reserve_region(p_region_t reg);
|
||||
bool_t insert_region(region_t reg);
|
||||
void write_slot(slot_ptr_t slot_ptr, cap_t cap);
|
||||
|
|
|
|||
|
|
@ -42,8 +42,10 @@ BOOT_BSS static volatile int node_boot_lock;
|
|||
#define MAX_RESERVED (ARCH_RESERVED + MODE_RESERVED)
|
||||
BOOT_BSS static region_t reserved[MAX_RESERVED];
|
||||
|
||||
BOOT_CODE static void arch_init_freemem(p_region_t ui_p_reg, p_region_t dtb_p_reg, v_region_t it_v_reg,
|
||||
word_t extra_bi_size_bits)
|
||||
BOOT_CODE static bool_t arch_init_freemem(p_region_t ui_p_reg,
|
||||
p_region_t dtb_p_reg,
|
||||
v_region_t it_v_reg,
|
||||
word_t extra_bi_size_bits)
|
||||
{
|
||||
reserved[0].start = KERNEL_ELF_BASE;
|
||||
reserved[0].end = (pptr_t)ki_end;
|
||||
|
|
@ -57,8 +59,8 @@ BOOT_CODE static void arch_init_freemem(p_region_t ui_p_reg, p_region_t dtb_p_re
|
|||
}
|
||||
|
||||
if (MODE_RESERVED > 1) {
|
||||
printf("MODE_RESERVED > 1 unsupported!\n");
|
||||
halt();
|
||||
printf("ERROR: MODE_RESERVED > 1 unsupported!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui_p_reg.start < PADDR_TOP) {
|
||||
|
|
@ -86,7 +88,8 @@ BOOT_CODE static void arch_init_freemem(p_region_t ui_p_reg, p_region_t dtb_p_re
|
|||
index++;
|
||||
}
|
||||
|
||||
init_freemem(get_num_avail_p_regs(), get_avail_p_regs(), index, reserved, it_v_reg, extra_bi_size_bits);
|
||||
return init_freemem(get_num_avail_p_regs(), get_avail_p_regs(), index,
|
||||
reserved, it_v_reg, extra_bi_size_bits);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -380,7 +383,10 @@ static BOOT_CODE bool_t try_init_kernel(
|
|||
/* initialise the platform */
|
||||
init_plat();
|
||||
|
||||
arch_init_freemem(ui_p_reg, dtb_p_reg, it_v_reg, extra_bi_size_bits);
|
||||
if (!arch_init_freemem(ui_p_reg, dtb_p_reg, it_v_reg, extra_bi_size_bits)) {
|
||||
printf("ERROR: free memory management initialization failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create the root cnode */
|
||||
root_cnode_cap = create_root_cnode();
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@ BOOT_CODE cap_t create_mapped_it_frame_cap(cap_t pd_cap, pptr_t pptr, vptr_t vpt
|
|||
return cap;
|
||||
}
|
||||
|
||||
BOOT_CODE static void arch_init_freemem(region_t ui_reg, v_region_t ui_v_reg,
|
||||
region_t dtb_reg, word_t extra_bi_size_bits)
|
||||
BOOT_CODE static bool_t arch_init_freemem(region_t ui_reg, v_region_t ui_v_reg,
|
||||
region_t dtb_reg,
|
||||
word_t extra_bi_size_bits)
|
||||
{
|
||||
// This looks a bit awkward as our symbols are a reference in the kernel image window, but
|
||||
// we want to do all allocations in terms of the main kernel window, so we do some translation
|
||||
|
|
@ -94,8 +95,8 @@ BOOT_CODE static void arch_init_freemem(region_t ui_reg, v_region_t ui_v_reg,
|
|||
res_reg[index].end = ui_reg.end;
|
||||
index += 1;
|
||||
|
||||
init_freemem(get_num_avail_p_regs(), get_avail_p_regs(), index, res_reg, ui_v_reg,
|
||||
extra_bi_size_bits);
|
||||
return init_freemem(get_num_avail_p_regs(), get_avail_p_regs(), index,
|
||||
res_reg, ui_v_reg, extra_bi_size_bits);
|
||||
}
|
||||
|
||||
BOOT_CODE static void init_irqs(cap_t root_cnode_cap)
|
||||
|
|
@ -257,7 +258,10 @@ static BOOT_CODE bool_t try_init_kernel(
|
|||
init_plat();
|
||||
|
||||
/* make the free memory available to alloc_region() */
|
||||
arch_init_freemem(ui_reg, it_v_reg, dtb_reg, extra_bi_size_bits);
|
||||
if (!arch_init_freemem(ui_reg, it_v_reg, dtb_reg, extra_bi_size_bits)) {
|
||||
printf("ERROR: free memory management initialization failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create the root cnode */
|
||||
root_cnode_cap = create_root_cnode();
|
||||
|
|
|
|||
|
|
@ -85,12 +85,14 @@ BOOT_CODE static bool_t create_untypeds(
|
|||
return true;
|
||||
}
|
||||
|
||||
BOOT_CODE static void arch_init_freemem(p_region_t ui_p_reg, v_region_t v_reg,
|
||||
mem_p_regs_t *mem_p_regs, word_t extra_bi_size_bits)
|
||||
BOOT_CODE static bool_t arch_init_freemem(p_region_t ui_p_reg, v_region_t v_reg,
|
||||
mem_p_regs_t *mem_p_regs,
|
||||
word_t extra_bi_size_bits)
|
||||
{
|
||||
ui_p_reg.start = 0;
|
||||
reserved[0] = paddr_to_pptr_reg(ui_p_reg);
|
||||
init_freemem(mem_p_regs->count, mem_p_regs->list, MAX_RESERVED, reserved, v_reg, extra_bi_size_bits);
|
||||
return init_freemem(mem_p_regs->count, mem_p_regs->list, MAX_RESERVED,
|
||||
reserved, v_reg, extra_bi_size_bits);
|
||||
}
|
||||
|
||||
/* This function initialises a node's kernel state. It does NOT initialise the CPU. */
|
||||
|
|
@ -164,7 +166,10 @@ BOOT_CODE bool_t init_sys_state(
|
|||
}
|
||||
#endif /* CONFIG_IOMMU */
|
||||
|
||||
arch_init_freemem(ui_info.p_reg, it_v_reg, mem_p_regs, extra_bi_size_bits);
|
||||
if (!arch_init_freemem(ui_info.p_reg, it_v_reg, mem_p_regs, extra_bi_size_bits)) {
|
||||
printf("ERROR: free memory management initialization failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create the root cnode */
|
||||
root_cnode_cap = create_root_cnode();
|
||||
|
|
|
|||
|
|
@ -699,29 +699,53 @@ BOOT_BSS static region_t avail_reg[MAX_NUM_FREEMEM_REG];
|
|||
* Dynamically initialise the available memory on the platform.
|
||||
* A region represents an area of memory.
|
||||
*/
|
||||
BOOT_CODE void init_freemem(word_t n_available, const p_region_t *available,
|
||||
word_t n_reserved, const region_t *reserved,
|
||||
v_region_t it_v_reg, word_t extra_bi_size_bits)
|
||||
BOOT_CODE bool_t init_freemem(word_t n_available, const p_region_t *available,
|
||||
word_t n_reserved, const region_t *reserved,
|
||||
v_region_t it_v_reg, word_t extra_bi_size_bits)
|
||||
{
|
||||
/* The system configuration is broken if no region is available */
|
||||
if (0 == n_available) {
|
||||
printf("ERROR: no memory regions available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Force ordering and exclusivity of reserved regions */
|
||||
for (word_t i = 0; i < n_reserved; i++) {
|
||||
UNUSED const region_t *r = &reserved[i];
|
||||
const region_t *r = &reserved[i];
|
||||
|
||||
/* Reserved regions must be sane, the size is allowed to be zero */
|
||||
assert(r->start <= r->end);
|
||||
if (i > 0) {
|
||||
/* regions must be ordered and must not overlap */
|
||||
assert(r->start >= reserved[i - 1].end);
|
||||
if (r->start > r->end) {
|
||||
printf("ERROR: reserved region %"SEL4_PRIu_word" has start > end\n", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* regions must be ordered and must not overlap */
|
||||
if ((i > 0) && (r->start < reserved[i - 1].end)) {
|
||||
printf("ERROR: reserved region %"SEL4_PRIu_word" in wrong order\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Force ordering and exclusivity of available regions */
|
||||
for (word_t i = 0; i < n_available; i++) {
|
||||
UNUSED const p_region_t *r = &available[i];
|
||||
/* Available regions must be sane and have a size greater zero */
|
||||
assert(r->start < r->end);
|
||||
if (i > 0) {
|
||||
/* regions must be ordered and must not overlap */
|
||||
assert(r->start >= available[i - 1].end);
|
||||
const p_region_t *r = &available[i];
|
||||
|
||||
/* Available regions must be sane */
|
||||
if (r->start > r->end) {
|
||||
printf("ERROR: memory region %"SEL4_PRIu_word" has start > end\n", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Available regions can't be empty */
|
||||
if (r->start == r->end) {
|
||||
printf("ERROR: memory region %"SEL4_PRIu_word" empty\n", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* regions must be ordered and must not overlap */
|
||||
if ((i > 0) && (r->start < available[i - 1].end)) {
|
||||
printf("ERROR: memory region %"SEL4_PRIu_word" in wrong order\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -797,7 +821,7 @@ BOOT_CODE void init_freemem(word_t n_available, const p_region_t *available,
|
|||
word_t i = MAX_NUM_FREEMEM_REG - 1;
|
||||
if (!is_reg_empty(ndks_boot.freemem[i])) {
|
||||
printf("Insufficient MAX_NUM_FREEMEM_REG\n");
|
||||
halt();
|
||||
return false;
|
||||
}
|
||||
/* skip any empty regions */
|
||||
for (; is_reg_empty(ndks_boot.freemem[i]) && i >= 0; i--);
|
||||
|
|
@ -821,4 +845,6 @@ BOOT_CODE void init_freemem(word_t n_available, const p_region_t *available,
|
|||
ndks_boot.freemem[next] = ndks_boot.freemem[i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue