1 // Copyright 2017 The Fuchsia Authors 2 // 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file or at 5 // https://opensource.org/licenses/MIT 6 7 #pragma once 8 9 #define MEMMOV_OPS_DST_OFFSET (0) 10 #define MEMMOV_OPS_SRC_OFFSET (8) 11 #define MEMMOV_OPS_LEN_OFFSET (16) 12 13 #ifndef __ASSEMBLER__ 14 15 #include <zircon/compiler.h> 16 #include <fbl/ref_ptr.h> 17 #include <vm/vm_object.h> 18 #include <zircon/types.h> 19 #include <stddef.h> 20 #include <stdint.h> 21 22 // Warning: The geometry of this struct is depended upon by the mexec assembly 23 // function. Do not modify without also updating mexec.S. 24 typedef struct __PACKED { 25 void* dst; 26 void* src; 27 size_t len; 28 } memmov_ops_t; 29 30 // Implemented in assembly. Copies the new kernel into place and branches to it. 31 typedef void (*mexec_asm_func)(uint64_t arg0, uint64_t arg1, uint64_t arg2, 32 uint64_t aux, memmov_ops_t* ops, 33 void* new_kernel_addr); 34 35 // Save the crashlog for propagation to the next kernel. 36 void mexec_stash_crashlog(fbl::RefPtr<VmObject> vmo); 37 38 /* Allow the platform to patch the zbi structure with any platform specific 39 * data that might be necessary for the kernel that mexec is chain-loading. 40 */ 41 zx_status_t platform_mexec_patch_zbi(uint8_t* bootdata, const size_t len); 42 43 /* This function is called at the beginning of mexec. Interrupts are not yet 44 * disabled, but only one CPU is running. 45 */ 46 void platform_mexec_prep(uintptr_t new_bootimage_addr, size_t new_bootimage_len); 47 48 /* Ask the platform to mexec into the next kernel. 49 * This function is called after platform_mexec_prep(), with interrupts disabled. 50 */ 51 void platform_mexec(mexec_asm_func mexec_assembly, memmov_ops_t* ops, 52 uintptr_t new_bootimage_addr, size_t new_bootimage_len, 53 uintptr_t entry64_addr); 54 55 static_assert(__offsetof(memmov_ops_t, dst) == MEMMOV_OPS_DST_OFFSET, ""); 56 static_assert(__offsetof(memmov_ops_t, src) == MEMMOV_OPS_SRC_OFFSET, ""); 57 static_assert(__offsetof(memmov_ops_t, len) == MEMMOV_OPS_LEN_OFFSET, ""); 58 59 #endif // __ASSEMBLER__ 60