1 /*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7 #pragma once
8 #include <bootinfo.h>
9 #include <arch/bootinfo.h>
10
11 /*
12 * Resolve naming differences between the abstract specifications
13 * of the bootstrapping phase and the runtime phase of the kernel.
14 */
15 typedef cte_t slot_t;
16 typedef cte_t *slot_ptr_t;
17 #define SLOT_PTR(pptr, pos) (((slot_ptr_t)(pptr)) + (pos))
18 #define pptr_of_cap (pptr_t)cap_get_capPtr
19
20 /* (node-local) state accessed only during bootstrapping */
21
22 typedef struct ndks_boot {
23 p_region_t reserved[MAX_NUM_RESV_REG];
24 word_t resv_count;
25 region_t freemem[MAX_NUM_FREEMEM_REG];
26 seL4_BootInfo *bi_frame;
27 seL4_SlotPos slot_pos_cur;
28 } ndks_boot_t;
29
30 extern ndks_boot_t ndks_boot;
31
32 /* function prototypes */
33
is_reg_empty(region_t reg)34 static inline bool_t is_reg_empty(region_t reg)
35 {
36 return reg.start == reg.end;
37 }
38
39 bool_t init_freemem(word_t n_available, const p_region_t *available,
40 word_t n_reserved, const region_t *reserved,
41 v_region_t it_v_reg, word_t extra_bi_size_bits);
42 bool_t reserve_region(p_region_t reg);
43 void write_slot(slot_ptr_t slot_ptr, cap_t cap);
44 cap_t create_root_cnode(void);
45 bool_t provide_cap(cap_t root_cnode_cap, cap_t cap);
46 cap_t create_it_asid_pool(cap_t root_cnode_cap);
47 void write_it_pd_pts(cap_t root_cnode_cap, cap_t it_pd_cap);
48 bool_t create_idle_thread(void);
49 bool_t create_untypeds(cap_t root_cnode_cap, region_t boot_mem_reuse_reg);
50 void bi_finalise(void);
51 void create_domain_cap(cap_t root_cnode_cap);
52
53 cap_t create_ipcbuf_frame_cap(cap_t root_cnode_cap, cap_t pd_cap, vptr_t vptr);
54 word_t calculate_extra_bi_size_bits(word_t extra_size);
55 void populate_bi_frame(node_id_t node_id, word_t num_nodes, vptr_t ipcbuf_vptr,
56 word_t extra_bi_size_bits);
57 void create_bi_frame_cap(cap_t root_cnode_cap, cap_t pd_cap, vptr_t vptr);
58
59 #ifdef CONFIG_KERNEL_MCS
60 bool_t init_sched_control(cap_t root_cnode_cap, word_t num_nodes);
61 #endif
62
63 typedef struct create_frames_of_region_ret {
64 seL4_SlotRegion region;
65 bool_t success;
66 } create_frames_of_region_ret_t;
67
68 create_frames_of_region_ret_t
69 create_frames_of_region(
70 cap_t root_cnode_cap,
71 cap_t pd_cap,
72 region_t reg,
73 bool_t do_map,
74 sword_t pv_offset
75 );
76
77 cap_t
78 create_it_pd_pts(
79 cap_t root_cnode_cap,
80 v_region_t ui_v_reg,
81 vptr_t ipcbuf_vptr,
82 vptr_t bi_frame_vptr
83 );
84
85 tcb_t *
86 create_initial_thread(
87 cap_t root_cnode_cap,
88 cap_t it_pd_cap,
89 vptr_t ui_v_entry,
90 vptr_t bi_frame_vptr,
91 vptr_t ipcbuf_vptr,
92 cap_t ipcbuf_cap
93 );
94
95 void init_core_state(tcb_t *scheduler_action);
96
97 /* state tracking the memory allocated for root server objects */
98 typedef struct {
99 pptr_t cnode;
100 pptr_t vspace;
101 pptr_t asid_pool;
102 pptr_t ipc_buf;
103 pptr_t boot_info;
104 pptr_t extra_bi;
105 pptr_t tcb;
106 #ifdef CONFIG_KERNEL_MCS
107 pptr_t sc;
108 #endif
109 region_t paging;
110 } rootserver_mem_t;
111
112 extern rootserver_mem_t rootserver;
113
114 /* get the number of paging structures required to cover it_v_reg, with
115 * the paging structure covering `bits` of the address range - for a 4k page
116 * `bits` would be 12 */
get_n_paging(v_region_t v_reg,word_t bits)117 static inline BOOT_CODE word_t get_n_paging(v_region_t v_reg, word_t bits)
118 {
119 vptr_t start = ROUND_DOWN(v_reg.start, bits);
120 vptr_t end = ROUND_UP(v_reg.end, bits);
121 return (end - start) / BIT(bits);
122 }
123
124 /* allocate a page table sized structure from rootserver.paging */
it_alloc_paging(void)125 static inline BOOT_CODE pptr_t it_alloc_paging(void)
126 {
127 pptr_t allocated = rootserver.paging.start;
128 rootserver.paging.start += BIT(seL4_PageTableBits);
129 assert(rootserver.paging.start <= rootserver.paging.end);
130 return allocated;
131 }
132
133 /* return the amount of paging structures required to cover v_reg */
134 word_t arch_get_n_paging(v_region_t it_veg);
135