@@ -19,6 +19,7 @@ use microkit_tool::elf::ElfFile;
1919use microkit_tool:: loader:: Loader ;
2020use microkit_tool:: report:: write_report;
2121use microkit_tool:: sdf:: { parse, SysMemoryRegion , SysMemoryRegionPaddr } ;
22+ use microkit_tool:: sdk:: Sdk ;
2223use microkit_tool:: sel4:: {
2324 emulate_kernel_boot, emulate_kernel_boot_partial, Arch , Config , PlatformConfig ,
2425 RiscvVirtualMemory ,
@@ -82,54 +83,31 @@ impl ImageOutputType {
8283 }
8384}
8485
85- fn main ( ) -> Result < ( ) , String > {
86- let exe_path = std:: env:: current_exe ( ) . unwrap ( ) ;
87- let sdk_env = std:: env:: var ( "MICROKIT_SDK" ) ;
88- let sdk_dir = match sdk_env {
89- Ok ( ref value) => Path :: new ( value) ,
90- Err ( err) => match err {
91- // If there is no MICROKIT_SDK explicitly set, use the one that the binary is in.
92- std:: env:: VarError :: NotPresent => exe_path. parent ( ) . unwrap ( ) . parent ( ) . unwrap ( ) ,
93- _ => {
94- return Err ( format ! (
95- "Could not read MICROKIT_SDK environment variable: {err}"
96- ) )
97- }
98- } ,
99- } ;
100-
101- if !sdk_dir. exists ( ) {
102- eprintln ! (
103- "Error: SDK directory '{}' does not exist." ,
104- sdk_dir. display( )
105- ) ;
106- std:: process:: exit ( 1 ) ;
107- }
108-
109- let boards_path = sdk_dir. join ( "board" ) ;
110- if !boards_path. exists ( ) || !boards_path. is_dir ( ) {
86+ fn bail_if_not_exists ( description : & ' static str , path : & Path ) -> Result < ( ) , String > {
87+ if !path. exists ( ) {
11188 eprintln ! (
112- "Error: SDK directory '{}' does not have a 'board' sub-directory. " ,
113- sdk_dir . display( )
89+ "microkit: error: {description} '{}' does not exist " ,
90+ path . display( )
11491 ) ;
11592 std:: process:: exit ( 1 ) ;
11693 }
94+ Ok ( ( ) )
95+ }
11796
118- let mut available_boards = Vec :: new ( ) ;
119- for p in fs :: read_dir ( & boards_path ) . unwrap ( ) {
120- let path_buf = p . unwrap ( ) . path ( ) ;
121- let path = path_buf . as_path ( ) ;
122- if path . is_dir ( ) {
123- available_boards . push ( path . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ) ;
97+ fn main ( ) -> Result < ( ) , String > {
98+ let sdk = match Sdk :: discover ( ) {
99+ Ok ( discovered_info ) => discovered_info ,
100+ Err ( err ) => {
101+ eprintln ! ( "microkit: error: {err}" ) ;
102+ std :: process :: exit ( 1 ) ;
124103 }
125- }
126- available_boards. sort ( ) ;
104+ } ;
127105
128106 let env_args: Vec < _ > = std:: env:: args ( ) . collect ( ) ;
129- let mut args = match Args :: parse ( & env_args, & available_boards ) {
130- Ok ( result ) => result ,
107+ let mut args = match Args :: parse ( & env_args, & sdk ) {
108+ Ok ( parsed_arguments ) => parsed_arguments ,
131109 Err ( ArgsError :: HelpWanted ) => {
132- argparse:: print_help ( & available_boards ) ;
110+ argparse:: print_help ( & sdk ) ;
133111 std:: process:: exit ( 0 ) ;
134112 }
135113 Err ( err) => {
@@ -146,113 +124,32 @@ fn main() -> Result<(), String> {
146124 } ;
147125 args. search_paths . push ( std:: env:: current_dir ( ) . unwrap ( ) ) ;
148126
149- let board_path = boards_path. join ( & args. board ) ;
150- if !board_path. exists ( ) {
151- eprintln ! (
152- "Error: board path '{}' does not exist." ,
153- board_path. display( )
154- ) ;
155- std:: process:: exit ( 1 ) ;
156- }
157-
158- let mut available_configs = Vec :: new ( ) ;
159- for p in fs:: read_dir ( board_path) . unwrap ( ) {
160- let path_buf = p. unwrap ( ) . path ( ) ;
161- let path = path_buf. as_path ( ) ;
162-
163- if path. file_name ( ) . unwrap ( ) == "example" {
164- continue ;
165- }
166-
167- if path. is_dir ( ) {
168- available_configs. push ( path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ) ;
169- }
170- }
127+ // NB safe unwrap: argparse would already have bailed if the config did not
128+ // exist.
129+ let current_config = sdk. select ( & args. board , & args. config ) . unwrap ( ) ;
171130
172- if !available_configs. contains ( & args. config . to_string ( ) ) {
173- eprintln ! (
174- "microkit: error: argument --config: invalid choice: '{}' (choose from: {})" ,
175- args. config,
176- available_configs. join( ", " )
177- )
178- }
179-
180- let elf_path = sdk_dir
181- . join ( "board" )
182- . join ( & args. board )
183- . join ( & args. config )
184- . join ( "elf" ) ;
131+ // the real work begins here
132+ let elf_path = current_config. config_dir . join ( "elf" ) ;
185133 let loader_elf_path = elf_path. join ( "loader.elf" ) ;
186134 let kernel_elf_path = match args. override_kernel {
187135 Some ( ref path) => path,
188136 None => & elf_path. join ( "sel4.elf" ) ,
189137 } ;
190138 let monitor_elf_path = elf_path. join ( "monitor.elf" ) ;
191139 let capdl_init_elf_path = elf_path. join ( "initialiser.elf" ) ;
192-
193- let kernel_config_path = sdk_dir
194- . join ( "board" )
195- . join ( & args. board )
196- . join ( & args. config )
140+ let kernel_config_path = current_config
141+ . config_dir
197142 . join ( "include/kernel/gen_config.json" ) ;
198-
199- let invocations_all_path = sdk_dir
200- . join ( "board" )
201- . join ( & args. board )
202- . join ( & args. config )
203- . join ( "invocations_all.json" ) ;
204-
205- if !elf_path. exists ( ) {
206- eprintln ! (
207- "Error: board ELF directory '{}' does not exist" ,
208- elf_path. display( )
209- ) ;
210- std:: process:: exit ( 1 ) ;
211- }
212- if !kernel_elf_path. exists ( ) {
213- eprintln ! (
214- "Error: kernel ELF '{}' does not exist" ,
215- kernel_elf_path. display( )
216- ) ;
217- std:: process:: exit ( 1 ) ;
218- }
219- if !monitor_elf_path. exists ( ) {
220- eprintln ! (
221- "Error: monitor ELF '{}' does not exist" ,
222- monitor_elf_path. display( )
223- ) ;
224- std:: process:: exit ( 1 ) ;
225- }
226- if !capdl_init_elf_path. exists ( ) {
227- eprintln ! (
228- "Error: CapDL initialiser ELF '{}' does not exist" ,
229- capdl_init_elf_path. display( )
230- ) ;
231- std:: process:: exit ( 1 ) ;
232- }
233- if !kernel_config_path. exists ( ) {
234- eprintln ! (
235- "Error: kernel configuration file '{}' does not exist" ,
236- kernel_config_path. display( )
237- ) ;
238- std:: process:: exit ( 1 ) ;
239- }
240- if !invocations_all_path. exists ( ) {
241- eprintln ! (
242- "Error: invocations JSON file '{}' does not exist" ,
243- invocations_all_path. display( )
244- ) ;
245- std:: process:: exit ( 1 ) ;
246- }
143+ let invocations_all_path = current_config. config_dir . join ( "invocations_all.json" ) ;
144+ bail_if_not_exists ( "board ELF directory" , & elf_path) ?;
145+ bail_if_not_exists ( "kernel ELF" , kernel_elf_path) ?;
146+ bail_if_not_exists ( "monitor ELF" , & monitor_elf_path) ?;
147+ bail_if_not_exists ( "CapDL initialiser ELF" , & capdl_init_elf_path) ?;
148+ bail_if_not_exists ( "kernel configuration file" , & kernel_config_path) ?;
149+ bail_if_not_exists ( "invocations JSON file" , & invocations_all_path) ?;
247150
248151 let system_path = & args. sdf_path ;
249- if !system_path. exists ( ) {
250- eprintln ! (
251- "Error: system description file '{}' does not exist" ,
252- system_path. display( )
253- ) ;
254- std:: process:: exit ( 1 ) ;
255- }
152+ bail_if_not_exists ( "system description file" , system_path) ?;
256153
257154 let xml: String = fs:: read_to_string ( system_path) . unwrap ( ) ;
258155
@@ -287,23 +184,10 @@ fn main() -> Result<(), String> {
287184 let ( device_regions, normal_regions) = match arch {
288185 Arch :: X86_64 => ( None , None ) ,
289186 _ => {
290- let kernel_platform_config_path = sdk_dir
291- . join ( "board" )
292- . join ( & args. board )
293- . join ( & args. config )
294- . join ( "platform_gen.json" ) ;
295-
296- if !kernel_platform_config_path. exists ( ) {
297- eprintln ! (
298- "Error: kernel platform configuration file '{}' does not exist" ,
299- kernel_platform_config_path. display( )
300- ) ;
301- std:: process:: exit ( 1 ) ;
302- }
303-
187+ let platform_gen_path = current_config. config_dir . join ( "platform_gen.json" ) ;
188+ bail_if_not_exists ( "kernel platform configuration file" , & platform_gen_path) ?;
304189 let kernel_platform_config: PlatformConfig =
305- serde_json:: from_str ( & fs:: read_to_string ( kernel_platform_config_path) . unwrap ( ) )
306- . unwrap ( ) ;
190+ serde_json:: from_str ( & fs:: read_to_string ( platform_gen_path) . unwrap ( ) ) . unwrap ( ) ;
307191
308192 (
309193 Some ( kernel_platform_config. devices ) ,
@@ -313,19 +197,8 @@ fn main() -> Result<(), String> {
313197 } ;
314198
315199 let object_sizes = {
316- let object_sizes_path = sdk_dir
317- . join ( "board" )
318- . join ( args. board )
319- . join ( & args. config )
320- . join ( "object_sizes.json" ) ;
321-
322- if !object_sizes_path. exists ( ) {
323- eprintln ! (
324- "Error: object sizes file '{}' does not exist" ,
325- object_sizes_path. display( )
326- ) ;
327- std:: process:: exit ( 1 ) ;
328- }
200+ let object_sizes_path = current_config. config_dir . join ( "object_sizes.json" ) ;
201+ bail_if_not_exists ( "kernel object sizes file" , & object_sizes_path) ?;
329202
330203 serde_json:: from_str ( & fs:: read_to_string ( object_sizes_path) . unwrap ( ) ) . unwrap ( )
331204 } ;
0 commit comments