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