@@ -31,9 +31,6 @@ use crate::{
3131 util:: { ranges_overlap, round_down, round_up} ,
3232} ;
3333
34- // Corresponds to the IPC buffer symbol in libmicrokit and the monitor
35- const SYMBOL_IPC_BUFFER : & str = "__sel4_ipc_buffer_obj" ;
36-
3734const FAULT_BADGE : u64 = 1 << 62 ;
3835const PPC_BADGE : u64 = 1 << 63 ;
3936
@@ -295,47 +292,11 @@ impl CapDLSpecContainer {
295292 }
296293 }
297294
298- // Create and map the IPC buffer for this ELF
299- let ipcbuf_frame_obj_id = capdl_util_make_frame_obj (
300- self ,
301- Fill {
302- entries : [ ] . to_vec ( ) ,
303- } ,
304- & format ! ( "ipcbuf_{pd_name}" ) ,
305- None ,
306- PageSize :: Small . fixed_size_bits ( sel4_config) as u8 ,
307- ) ;
308- let ipcbuf_frame_cap =
309- capdl_util_make_frame_cap ( ipcbuf_frame_obj_id, true , true , false , true ) ;
310- // We need to clone the IPC buf cap because in addition to mapping the frame into the VSpace, we need to bind
311- // this frame to the TCB as well.
312- let ipcbuf_frame_cap_for_tcb = ipcbuf_frame_cap. clone ( ) ;
313- let ipcbuf_vaddr = elf
314- . find_symbol ( SYMBOL_IPC_BUFFER )
315- . unwrap_or_else ( |_| panic ! ( "Could not find {SYMBOL_IPC_BUFFER}" ) )
316- . 0 ;
317- match map_page (
318- self ,
319- sel4_config,
320- pd_name,
321- vspace_obj_id,
322- ipcbuf_frame_cap,
323- PageSize :: Small as u64 ,
324- ipcbuf_vaddr,
325- ) {
326- Ok ( _) => { }
327- Err ( map_err_reason) => {
328- return Err ( format ! (
329- "build_capdl_spec(): failed to map ipc buffer frame to {pd_name} because: {map_err_reason}"
330- ) )
331- }
332- } ;
333-
334295 let tcb_name = format ! ( "tcb_{pd_name}" ) ;
335296 let entry_point = elf. entry ;
336297
337298 let tcb_extra_info = object:: TcbExtraInfo {
338- ipc_buffer_addr : ipcbuf_vaddr . into ( ) ,
299+ ipc_buffer_addr : 0 . into ( ) ,
339300 affinity : Word ( pd_cpu. 0 . into ( ) ) ,
340301 prio : 0 ,
341302 max_prio : 0 ,
@@ -350,11 +311,7 @@ impl CapDLSpecContainer {
350311
351312 let tcb_inner_obj = object:: Tcb {
352313 // Bind the VSpace into the TCB
353- slots : [
354- capdl_util_make_cte ( TcbBoundSlot :: VSpace as u32 , vspace_cap) ,
355- capdl_util_make_cte ( TcbBoundSlot :: IpcBuffer as u32 , ipcbuf_frame_cap_for_tcb) ,
356- ]
357- . to_vec ( ) ,
314+ slots : vec ! [ capdl_util_make_cte( TcbBoundSlot :: VSpace as u32 , vspace_cap) ] ,
358315 extra : Box :: new ( tcb_extra_info) ,
359316 } ;
360317
@@ -488,6 +445,27 @@ pub fn build_capdl_spec(
488445 )
489446 . unwrap ( ) ;
490447
448+ // Create monitor IPC Bufffer
449+ let mon_ipcbuf_frame_obj_id = capdl_util_make_frame_obj (
450+ & mut spec_container,
451+ Fill { entries : vec ! [ ] } ,
452+ & format ! ( "ipcbuf_{MONITOR_PD_NAME}" ) ,
453+ None ,
454+ PageSize :: Small . fixed_size_bits ( kernel_config) as u8 ,
455+ ) ;
456+ let mon_ipcbuf_frame_cap =
457+ capdl_util_make_frame_cap ( mon_ipcbuf_frame_obj_id, true , true , false , true ) ;
458+ map_page (
459+ & mut spec_container,
460+ kernel_config,
461+ MONITOR_PD_NAME ,
462+ mon_vspace_obj_id,
463+ mon_ipcbuf_frame_cap. clone ( ) ,
464+ PageSize :: Small as u64 ,
465+ kernel_config. pd_ipc_buffer ( ) ,
466+ )
467+ . expect ( "should be able to map the IPC buffer as we checked overlaps" ) ;
468+
491469 // At this point, all of the required objects for the monitor have been created and its caps inserted into
492470 // the correct slot in the CSpace. We need to bind those objects into the TCB for the monitor to use them.
493471 // In addition, `add_elf_to_spec()` doesn't fill most the details in the TCB.
@@ -497,6 +475,7 @@ pub fn build_capdl_spec(
497475 . unwrap ( )
498476 . object
499477 {
478+ monitor_tcb. extra . ipc_buffer_addr = Word ( kernel_config. pd_ipc_buffer ( ) ) ;
500479 // Special case, monitor has its stack statically allocated.
501480 monitor_tcb. extra . sp = Word ( kernel_config. pd_stack_top ( ) ) ;
502481 // While there is nothing stopping us from running the monitor at the highest priority alongside the
@@ -505,6 +484,11 @@ pub fn build_capdl_spec(
505484 monitor_tcb. extra . max_prio = MONITOR_PRIORITY ;
506485 monitor_tcb. extra . resume = true ;
507486
487+ monitor_tcb. slots . push ( capdl_util_make_cte (
488+ TcbBoundSlot :: IpcBuffer as u32 ,
489+ mon_ipcbuf_frame_cap,
490+ ) ) ;
491+
508492 monitor_tcb. slots . push ( capdl_util_make_cte (
509493 TcbBoundSlot :: CSpace as u32 ,
510494 mon_cnode_cap,
@@ -638,17 +622,27 @@ pub fn build_capdl_spec(
638622 // We perform this check here, otherwise the tool will panic with quite cryptic page-table related errors.
639623 let mr_vaddr_range = map. vaddr ..( map. vaddr + ( page_size_bytes * frames. len ( ) as u64 ) ) ;
640624
641- let pd_stack_range =
642- kernel_config. pd_stack_bottom ( pd. stack_size ) ..kernel_config. pd_stack_top ( ) ;
643- if ranges_overlap ( & mr_vaddr_range, & pd_stack_range) {
644- return Err ( format ! ( "ERROR: mapping MR '{}' to PD '{}' with vaddr [0x{:x}..0x{:x}) will overlap with the stack at [0x{:x}..0x{:x})" , map. mr, pd. name, mr_vaddr_range. start, mr_vaddr_range. end, pd_stack_range. start, pd_stack_range. end) ) ;
625+ let pd_reserved_range =
626+ kernel_config. pd_map_max_vaddr ( pd. stack_size ) ..kernel_config. user_top ( ) ;
627+ if ranges_overlap ( & mr_vaddr_range, & pd_reserved_range) {
628+ return Err (
629+ format ! (
630+ "ERROR: mapping MR '{}' to PD '{}' with vaddr [0x{:x}..0x{:x}) will overlap with the PD reserved range at [0x{:x}..0x{:x})" ,
631+ map. mr, pd. name, mr_vaddr_range. start, mr_vaddr_range. end, pd_reserved_range. start, pd_reserved_range. end,
632+ )
633+ ) ;
645634 }
646635
647636 for elf_seg in elf_obj. loadable_segments ( ) . iter ( ) {
648637 let elf_seg_vaddr_range = elf_seg. virt_addr
649638 ..elf_seg. virt_addr + round_up ( elf_seg. mem_size ( ) , PageSize :: Small as u64 ) ;
650639 if ranges_overlap ( & mr_vaddr_range, & elf_seg_vaddr_range) {
651- return Err ( format ! ( "ERROR: mapping MR '{}' to PD '{}' with vaddr [0x{:x}..0x{:x}) will overlap with an ELF segment at [0x{:x}..0x{:x})" , map. mr, pd. name, mr_vaddr_range. start, mr_vaddr_range. end, elf_seg_vaddr_range. start, elf_seg_vaddr_range. end) ) ;
640+ return Err (
641+ format ! (
642+ "ERROR: mapping MR '{}' to PD '{}' with vaddr [0x{:x}..0x{:x}) will overlap with an ELF segment at [0x{:x}..0x{:x})" ,
643+ map. mr, pd. name, mr_vaddr_range. start, mr_vaddr_range. end, elf_seg_vaddr_range. start, elf_seg_vaddr_range. end,
644+ )
645+ ) ;
652646 }
653647 }
654648
@@ -663,7 +657,32 @@ pub fn build_capdl_spec(
663657 ) ;
664658 }
665659
666- // Step 3-3: Create and map in the stack (bottom up)
660+ // Step 3-3a: Create and map in the IPC buffer
661+ let ipcbuf_frame_obj_id = capdl_util_make_frame_obj (
662+ & mut spec_container,
663+ Fill { entries : vec ! [ ] } ,
664+ & format ! ( "ipcbuf_{}" , pd. name) ,
665+ None ,
666+ PageSize :: Small . fixed_size_bits ( kernel_config) as u8 ,
667+ ) ;
668+ let ipcbuf_frame_cap =
669+ capdl_util_make_frame_cap ( ipcbuf_frame_obj_id, true , true , false , true ) ;
670+ map_page (
671+ & mut spec_container,
672+ kernel_config,
673+ & pd. name ,
674+ pd_vspace_obj_id,
675+ ipcbuf_frame_cap. clone ( ) ,
676+ PageSize :: Small as u64 ,
677+ kernel_config. pd_ipc_buffer ( ) ,
678+ )
679+ . expect ( "should be able to map the IPC buffer as we checked overlaps" ) ;
680+ caps_to_bind_to_tcb. push ( capdl_util_make_cte (
681+ TcbBoundSlot :: IpcBuffer as u32 ,
682+ ipcbuf_frame_cap,
683+ ) ) ;
684+
685+ // Step 3-3b: Create and map in the stack (bottom up)
667686 let mut cur_stack_vaddr = kernel_config. pd_stack_bottom ( pd. stack_size ) ;
668687 pd_stack_bottoms. push ( cur_stack_vaddr) ;
669688 let num_stack_frames = pd. stack_size / PageSize :: Small as u64 ;
@@ -1027,6 +1046,7 @@ pub fn build_capdl_spec(
10271046 . unwrap ( )
10281047 . object
10291048 {
1049+ pd_tcb. extra . ipc_buffer_addr = Word ( kernel_config. pd_ipc_buffer ( ) ) ;
10301050 pd_tcb. extra . sp = Word ( kernel_config. pd_stack_top ( ) ) ;
10311051 pd_tcb. extra . master_fault_ep = None ; // Not used on MCS kernel.
10321052 pd_tcb. extra . prio = pd. priority ;
0 commit comments