lib/machine/src/instance/types.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const core = @import("machine_instance_core");
2 const os = @import("os");
3 const admission = @import("../admission/root.zig");
4 const checkpoint = @import("../checkpoint/root.zig");
5 const profile = @import("../profile/root.zig");
6 const receipt = @import("receipt/root.zig");
7
8 pub const BackendAvailability = core.backend.BackendAvailability;
9 pub const BackendStage = core.backend.BackendStage;
10 pub const Unavailable = core.backend.Unavailable;
11 pub const EventBatch = receipt.EventBatch;
12 pub const ExecutionFingerprint = receipt.ExecutionFingerprint;
13 pub const K0State = receipt.K0State;
14 pub const QuiescenceReceipt = receipt.QuiescenceReceipt;
15 pub const SettledTransport = receipt.SettledTransport;
16 pub const event_batch_max = receipt.event_batch_max;
17
18 /// Gathers everything one cold start of a K0 guest needs into one value, so a
19 /// caller supplies all of this at once and knows how long to keep the image and
20 /// the manifest around. The profile inside it decides which backend runs and
21 /// under which execution rules. The caller keeps ownership of both slices and
22 /// may free them once `Instance.init` has returned.
23 pub const Input = struct {
24 profile: profile.Profile,
25 elf: []const u8,
26 execution_manifest: []const u8,
27 expected_execution_fingerprint: ExecutionFingerprint,
28 fence: os.abi.ActivationFence,
29 initial_time_tick: u64,
30 entropy_generation: u64,
31 terminal_offset: u64,
32 effect_frontier: u64,
33 block_root: os.abi.Digest,
34 source_root: os.abi.Digest,
35 input_frontier: u64,
36 terminal_input_offset: u64,
37 outstanding_effect: ?admission.EffectRequest,
38 };
39
40 /// Gathers everything needed to bring a checkpoint back into RAM the caller
41 /// owns, so a caller supplies all of this at once for a restore. The checkpoint
42 /// source and the manifest stay the caller's, borrowed only for the length of
43 /// the `Instance.restore` call.
44 pub const RestoreInput = struct {
45 checkpoint: checkpoint.Source,
46 expected_root: checkpoint.Root,
47 profile: profile.Profile,
48 execution_manifest: []const u8,
49 fence: os.abi.ActivationFence,
50 };
51
52 /// Gathers everything needed for a portable restore whose pages come from an
53 /// immutable root provider, so the caller supplies a provider and branch
54 /// storage. The provider and the branch storage arrive as their own arguments
55 /// to `Instance.restoreShared`. The instance holds the memory behind both until
56 /// `deinit`.
57 pub const SharedRestoreInput = struct {
58 expected_root: checkpoint.roots.ManifestRoot,
59 profile: profile.Profile,
60 execution_manifest: []const u8,
61 fence: os.abi.ActivationFence,
62 };
63
64 /// Holds one yield code read off the fixed machine doorbell port, so a caller
65 /// receives the value a guest yield carries.
66 pub const Doorbell = struct { code: os.abi.channel.DoorbellCode };
67
68 /// Represents the stage of one lifecycle as a caller can observe it, so the
69 /// caller knows which lifecycle calls are legal at this moment. A lifecycle
70 /// call takes some stages and answers with a protocol error in the rest.
71 pub const RunPhase = enum(u8) {
72 closed,
73 booting,
74 draining_activation,
75 awaiting_input,
76 input_delivered,
77 draining_input,
78 awaiting_acknowledgement,
79 awaiting_reactivation,
80 capturing_checkpoint,
81 completing_io,
82 failed,
83 };
84
85 /// Records where a terminal execution fault came from, so a fault that ends a
86 /// run states its source. The eight sources are device, exception, entry,
87 /// memory, hypercall, debug, system, and backend.
88 pub const FaultKind = enum(u8) {
89 device,
90 exception,
91 entry,
92 memory,
93 hypercall,
94 debug,
95 system,
96 backend,
97 };
98
99 /// Presents one terminal fault in a single shape across backends, so a caller
100 /// reads the details once a run has ended in a fault. The code and address
101 /// fields hold whatever the backend reported for that kind of fault.
102 pub const Fault = struct {
103 kind: FaultKind,
104 code: u64,
105 address: u64,
106 };
107
108 /// Reports one execution boundary in the form a caller sees, so every `run`
109 /// answers with this value and the answer decides whether the lifecycle goes
110 /// on. A ready or quiescent yield moves the lifecycle to its next stage. A
111 /// halt, a shutdown, a fault, and every other yield code end execution for that
112 /// lifecycle.
113 pub const Exit = union(enum) {
114 doorbell: Doorbell,
115 halted,
116 shutdown,
117 fault: Fault,
118 };