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.
24typedef 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.
31typedef 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.
36void 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 */
41zx_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 */
46void 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 */
51void 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
55static_assert(__offsetof(memmov_ops_t, dst) == MEMMOV_OPS_DST_OFFSET, "");
56static_assert(__offsetof(memmov_ops_t, src) == MEMMOV_OPS_SRC_OFFSET, "");
57static_assert(__offsetof(memmov_ops_t, len) == MEMMOV_OPS_LEN_OFFSET, "");
58
59#endif // __ASSEMBLER__
60