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 };