diff --git a/os/src/loader.rs b/os/src/loader.rs index af9e508d7..8c711f175 100644 --- a/os/src/loader.rs +++ b/os/src/loader.rs @@ -70,10 +70,6 @@ pub fn load_apps() { let num_app_ptr = _num_app as usize as *const usize; let num_app = get_num_app(); let app_start = unsafe { core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1) }; - // clear i-cache first - unsafe { - asm!("fence.i"); - } // load apps for i in 0..num_app { let base_i = get_base_i(i); @@ -87,6 +83,15 @@ pub fn load_apps() { let dst = unsafe { core::slice::from_raw_parts_mut(base_i as *mut u8, src.len()) }; dst.copy_from_slice(src); } + // Memory fence about fetching the instruction memory + // It is guaranteed that a subsequent instruction fetch must + // observes all previous writes to the instruction memory. + // Therefore, fence.i must be executed after we have loaded + // the code of the next app into the instruction memory. + // See also: riscv non-priv spec chapter 3, 'Zifencei' extension. + unsafe { + asm!("fence.i"); + } } /// get app info with entry and sp and save `TrapContext` in kernel stack