1use crate::vmx;
7use bitfield_struct::bitfield;
8use open_enum::open_enum;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13
14pub const TDX_SHARED_GPA_BOUNDARY_BITS: u8 = 47;
15pub const TDX_SHARED_GPA_BOUNDARY_ADDRESS_BIT: u64 = 1 << TDX_SHARED_GPA_BOUNDARY_BITS;
16pub const RESET_VECTOR_PAGE: u64 = 0xfffff000;
17
18open_enum! {
19 pub enum TdCallLeaf: u64 {
22 VP_VMCALL = 0,
23 VP_INFO = 1,
24 MR_RTMR_EXTEND = 2,
25 VP_VEINFO_GET = 3,
26 MR_REPORT = 4,
27 VP_CPUIDVE_SET = 5,
28 MEM_PAGE_ACCEPT = 6,
29 VM_RD = 7,
30 VM_WR = 8,
31 VP_RD = 9,
32 VP_WR = 10,
33 MEM_PAGE_ATTR_RD = 23,
34 MEM_PAGE_ATTR_WR = 24,
35 VP_ENTER = 25,
36 VP_INVGLA = 27,
37 }
38}
39
40#[repr(u8)]
42#[derive(Clone, Copy, Debug, PartialEq, Eq)]
43pub enum TdgMemPageLevel {
44 Size4k = 0,
45 Size2Mb = 1,
46 Size1Gb = 2,
47}
48
49impl TdgMemPageLevel {
50 const fn from_bits(value: u64) -> Self {
51 match value {
52 0 => Self::Size4k,
53 1 => Self::Size2Mb,
54 2 => Self::Size1Gb,
55 _ => panic!("invalid TdgMemPageLevel value"),
56 }
57 }
58
59 const fn into_bits(self) -> u64 {
60 self as u64
61 }
62}
63
64#[bitfield(u16)]
66#[derive(PartialEq, Eq)]
67pub struct GpaVmAttributes {
68 pub read: bool,
69 pub write: bool,
70 pub kernel_execute: bool,
71 pub user_execute: bool,
72 #[bits(3)]
73 reserved: u8,
74 suppress_ve: bool,
75 #[bits(7)]
76 reserved2: u8,
77 pub valid: bool,
78}
79
80impl GpaVmAttributes {
82 pub const FULL_ACCESS: Self = Self::new()
83 .with_read(true)
84 .with_write(true)
85 .with_kernel_execute(true)
86 .with_user_execute(true)
87 .with_valid(true);
88}
89
90#[bitfield(u16)]
92pub struct GpaVmAttributesMask {
93 pub read: bool,
94 pub write: bool,
95 pub kernel_execute: bool,
96 pub user_execute: bool,
97 #[bits(3)]
98 reserved: u8,
99 pub suppress_ve: bool,
100 #[bits(7)]
101 reserved2: u8,
102 pub inv_ept: bool,
104}
105
106impl GpaVmAttributesMask {
107 pub const ALL_CHANGED: Self = Self::new()
108 .with_read(true)
109 .with_write(true)
110 .with_kernel_execute(true)
111 .with_user_execute(true);
112}
113
114#[bitfield(u64)]
117#[derive(PartialEq, Eq)]
118pub struct TdgMemPageGpaAttr {
119 #[bits(16)]
121 pub l1: GpaVmAttributes,
122 #[bits(16)]
124 pub l2_vm1: GpaVmAttributes,
125 #[bits(16)]
127 pub l2_vm2: GpaVmAttributes,
128 #[bits(16)]
129 pub l2_vm3: GpaVmAttributes,
130}
131
132#[bitfield(u64)]
133pub struct TdgMemPageAcceptRcx {
134 #[bits(3)]
135 pub level: TdgMemPageLevel,
136 #[bits(9)]
137 pub reserved: u64,
138 #[bits(40)]
140 pub gpa_page_number: u64,
141 #[bits(12)]
142 pub reserved2: u64,
143}
144
145#[bitfield(u64)]
146pub struct TdgMemPageAttrGpaMappingReadRcxResult {
147 #[bits(3)]
148 pub level: TdgMemPageLevel,
149 #[bits(9)]
150 pub reserved: u64,
151 #[bits(40)]
153 pub gpa_page_number: u64,
154 #[bits(10)]
155 pub reserved2: u64,
156 #[bits(1)]
159 pub pending: u8,
160 #[bits(1)]
161 pub reserved3: u64,
162}
163
164#[bitfield(u64)]
166#[derive(PartialEq, Eq)]
167pub struct TdgMemPageAttrWriteRcx {
168 #[bits(3)]
169 pub level: TdgMemPageLevel,
170 #[bits(9)]
171 pub reserved: u64,
172 #[bits(40)]
174 pub gpa_page_number: u64,
175 #[bits(12)]
176 pub reserved2: u64,
177}
178
179#[bitfield(u64)]
181pub struct TdgMemPageAttrWriteR8 {
182 #[bits(16)]
183 pub reserved: u64,
184 #[bits(16)]
186 pub l2_vm1: GpaVmAttributesMask,
187 #[bits(16)]
189 pub l2_vm2: GpaVmAttributesMask,
190 #[bits(16)]
192 pub l2_vm3: GpaVmAttributesMask,
193}
194
195#[repr(u64)]
198pub enum TdVmCallSubFunction {
199 IoInstr = 0x1e,
200 RdMsr = 0x1f,
201 WrMsr = 0x20,
202 MapGpa = 0x10001,
203}
204
205open_enum! {
206 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
208 pub enum TdCallResultCode: u32 {
209 SUCCESS = 0x00000000,
210 NON_RECOVERABLE_VCPU = 0x40000001,
211 NON_RECOVERABLE_TD = 0x60000002,
212 INTERRUPTED_RESUMABLE = 0x80000003,
213 INTERRUPTED_RESTARTABLE = 0x80000004,
214 NON_RECOVERABLE_TD_NON_ACCESSIBLE = 0x60000005,
215 INVALID_RESUMPTION = 0xC0000006,
216 NON_RECOVERABLE_TD_WRONG_APIC_MODE = 0xE0000007,
217 CROSS_TD_FAULT = 0x80000008,
218 CROSS_TD_TRAP = 0x90000009,
219 NON_RECOVERABLE_TD_CORRUPTED_MD = 0x6000000A,
220 OPERAND_INVALID = 0xC0000100,
221 OPERAND_ADDR_RANGE_ERROR = 0xC0000101,
222 OPERAND_BUSY = 0x80000200,
223 PREVIOUS_TLB_EPOCH_BUSY = 0x80000201,
224 SYS_BUSY = 0x80000202,
225 RND_NO_ENTROPY = 0x80000203,
226 OPERAND_BUSY_HOST_PRIORITY = 0x80000204,
227 HOST_PRIORITY_BUSY_TIMEOUT = 0x90000205,
228 PAGE_METADATA_INCORRECT = 0xC0000300,
229 PAGE_ALREADY_FREE = 0x00000301,
230 PAGE_NOT_OWNED_BY_TD = 0xC0000302,
231 PAGE_NOT_FREE = 0xC0000303,
232 TD_ASSOCIATED_PAGES_EXIST = 0xC0000400,
233 SYS_INIT_NOT_PENDING = 0xC0000500,
234 SYS_LP_INIT_NOT_DONE = 0xC0000502,
235 SYS_LP_INIT_DONE = 0xC0000503,
236 SYS_NOT_READY = 0xC0000505,
237 SYS_SHUTDOWN = 0xC0000506,
238 SYS_KEY_CONFIG_NOT_PENDING = 0xC0000507,
239 SYS_STATE_INCORRECT = 0xC0000508,
240 SYS_INVALID_HANDOFF = 0xC0000509,
241 SYS_INCOMPATIBLE_SIGSTRUCT = 0xC000050A,
242 SYS_LP_INIT_NOT_PENDING = 0xC000050B,
243 SYS_CONFIG_NOT_PENDING = 0xC000050C,
244 INCOMPATIBLE_SEAM_CAPABILITIES = 0xC000050D,
245 TD_FATAL = 0xE0000604,
246 TD_NON_DEBUG = 0xC0000605,
247 TDCS_NOT_ALLOCATED = 0xC0000606,
248 LIFECYCLE_STATE_INCORRECT = 0xC0000607,
249 OP_STATE_INCORRECT = 0xC0000608,
250 NO_VCPUS = 0xC0000609,
251 TDCX_NUM_INCORRECT = 0xC0000610,
252 VCPU_STATE_INCORRECT = 0xC0000700,
253 VCPU_ASSOCIATED = 0x80000701,
254 VCPU_NOT_ASSOCIATED = 0x80000702,
255 NO_VALID_VE_INFO = 0xC0000704,
256 MAX_VCPUS_EXCEEDED = 0xC0000705,
257 TSC_ROLLBACK = 0xC0000706,
258 TD_VMCS_FIELD_NOT_INITIALIZED = 0xC0000730,
259 MCS_FIELD_ERROR = 0xC0000731,
260 KEY_GENERATION_FAILED = 0x80000800,
261 TD_KEYS_NOT_CONFIGURED = 0x80000810,
262 KEY_STATE_INCORRECT = 0xC0000811,
263 KEY_CONFIGURED = 0x00000815,
264 WBCACHE_NOT_COMPLETE = 0x80000817,
265 HKID_NOT_FREE = 0xC0000820,
266 NO_HKID_READY_TO_WBCACHE = 0x00000821,
267 WBCACHE_RESUME_ERROR = 0xC0000823,
268 FLUSHVP_NOT_DONE = 0x80000824,
269 NUM_ACTIVATED_HKIDS_NOT_SUPPORTED = 0xC0000825,
270 INCORRECT_CPUID_VALUE = 0xC0000900,
271 LIMIT_CPUID_MAXVAL_SET = 0xC0000901,
272 INCONSISTENT_CPUID_FIELD = 0xC0000902,
273 CPUID_MAX_SUBLEAVES_UNRECOGNIZED = 0xC0000903,
274 CPUID_LEAF_1F_FORMAT_UNRECOGNIZED = 0xC0000904,
275 INVALID_WBINVD_SCOPE = 0xC0000905,
276 INVALID_PKG_ID = 0xC0000906,
277 ENABLE_MONITOR_FSM_NOT_SET = 0xC0000907,
278 CPUID_LEAF_NOT_SUPPORTED = 0xC0000908,
279 SMRR_NOT_LOCKED = 0xC0000910,
280 INVALID_SMRR_CONFIGURATION = 0xC0000911,
281 SMRR_OVERLAPS_CMR = 0xC0000912,
282 SMRR_LOCK_NOT_SUPPORTED = 0xC0000913,
283 SMRR_NOT_SUPPORTED = 0xC0000914,
284 INCONSISTENT_MSR = 0xC0000920,
285 INCORRECT_MSR_VALUE = 0xC0000921,
286 SEAMREPORT_NOT_AVAILABLE = 0xC0000930,
287 SEAMDB_GETREF_NOT_AVAILABLE = 0xC0000931,
288 SEAMDB_REPORT_NOT_AVAILABLE = 0xC0000932,
289 SEAMVERIFYREPORT_NOT_AVAILABLE = 0xC0000933,
290 INVALID_TDMR = 0xC0000A00,
291 NON_ORDERED_TDMR = 0xC0000A01,
292 TDMR_OUTSIDE_CMRS = 0xC0000A02,
293 TDMR_ALREADY_INITIALIZED = 0x00000A03,
294 INVALID_PAMT = 0xC0000A10,
295 PAMT_OUTSIDE_CMRS = 0xC0000A11,
296 PAMT_OVERLAP = 0xC0000A12,
297 INVALID_RESERVED_IN_TDMR = 0xC0000A20,
298 NON_ORDERED_RESERVED_IN_TDMR = 0xC0000A21,
299 CMR_LIST_INVALID = 0xC0000A22,
300 EPT_WALK_FAILED = 0xC0000B00,
301 EPT_ENTRY_FREE = 0xC0000B01,
302 EPT_ENTRY_NOT_FREE = 0xC0000B02,
303 EPT_ENTRY_NOT_PRESENT = 0xC0000B03,
304 EPT_ENTRY_NOT_LEAF = 0xC0000B04,
305 EPT_ENTRY_LEAF = 0xC0000B05,
306 GPA_RANGE_NOT_BLOCKED = 0xC0000B06,
307 GPA_RANGE_ALREADY_BLOCKED = 0x00000B07,
308 TLB_TRACKING_NOT_DONE = 0xC0000B08,
309 EPT_INVALID_PROMOTE_CONDITIONS = 0xC0000B09,
310 PAGE_ALREADY_ACCEPTED = 0x00000B0A,
311 PAGE_SIZE_MISMATCH = 0xC0000B0B,
312 GPA_RANGE_BLOCKED = 0xC0000B0C,
313 EPT_ENTRY_STATE_INCORRECT = 0xC0000B0D,
314 EPT_PAGE_NOT_FREE = 0xC0000B0E,
315 L2_SEPT_WALK_FAILED = 0xC0000B0F,
316 L2_SEPT_ENTRY_NOT_FREE = 0xC0000B10,
317 PAGE_ATTR_INVALID = 0xC0000B11,
318 L2_SEPT_PAGE_NOT_PROVIDED = 0xC0000B12,
319 METADATA_FIELD_ID_INCORRECT = 0xC0000C00,
320 METADATA_FIELD_NOT_WRITABLE = 0xC0000C01,
321 METADATA_FIELD_NOT_READABLE = 0xC0000C02,
322 METADATA_FIELD_VALUE_NOT_VALID = 0xC0000C03,
323 METADATA_LIST_OVERFLOW = 0xC0000C04,
324 INVALID_METADATA_LIST_HEADER = 0xC0000C05,
325 REQUIRED_METADATA_FIELD_MISSING = 0xC0000C06,
326 METADATA_ELEMENT_SIZE_INCORRECT = 0xC0000C07,
327 METADATA_LAST_ELEMENT_INCORRECT = 0xC0000C08,
328 METADATA_FIELD_CURRENTLY_NOT_WRITABLE = 0xC0000C09,
329 METADATA_WR_MASK_NOT_VALID = 0xC0000C0A,
330 METADATA_FIRST_FIELD_ID_IN_CONTEXT = 0x00000C0B,
331 METADATA_FIELD_SKIP = 0x00000C0C,
332 SERVTD_ALREADY_BOUND_FOR_TYPE = 0xC0000D00,
333 SERVTD_TYPE_MISMATCH = 0xC0000D01,
334 SERVTD_ATTR_MISMATCH = 0xC0000D02,
335 SERVTD_INFO_HASH_MISMATCH = 0xC0000D03,
336 SERVTD_UUID_MISMATCH = 0xC0000D04,
337 SERVTD_NOT_BOUND = 0xC0000D05,
338 SERVTD_BOUND = 0xC0000D06,
339 TARGET_UUID_MISMATCH = 0xC0000D07,
340 TARGET_UUID_UPDATED = 0xC0000D08,
341 INVALID_MBMD = 0xC0000E00,
342 INCORRECT_MBMD_MAC = 0xC0000E01,
343 NOT_WRITE_BLOCKED = 0xC0000E02,
344 ALREADY_WRITE_BLOCKED = 0x00000E03,
345 NOT_EXPORTED = 0xC0000E04,
346 MIGRATION_STREAM_STATE_INCORRECT = 0xC0000E05,
347 MAX_MIGS_NUM_EXCEEDED = 0xC0000E06,
348 EXPORTED_DIRTY_PAGES_REMAIN = 0xC0000E07,
349 MIGRATION_DECRYPTION_KEY_NOT_SET = 0xC0000E08,
350 TD_NOT_MIGRATABLE = 0xC0000E09,
351 PREVIOUS_EXPORT_CLEANUP_INCOMPLETE = 0xC0000E0A,
352 NUM_MIGS_HIGHER_THAN_CREATED = 0xC0000E0B,
353 IMPORT_MISMATCH = 0xC0000E0C,
354 MIGRATION_EPOCH_OVERFLOW = 0xC0000E0D,
355 MAX_EXPORTS_EXCEEDED = 0xC0000E0E,
356 INVALID_PAGE_MAC = 0xC0000E0F,
357 MIGRATED_IN_CURRENT_EPOCH = 0xC0000E10,
358 DISALLOWED_IMPORT_OVER_REMOVED = 0xC0000E11,
359 SOME_VCPUS_NOT_MIGRATED = 0xC0000E12,
360 ALL_VCPUS_IMPORTED = 0xC0000E13,
361 MIN_MIGS_NOT_CREATED = 0xC0000E14,
362 VCPU_ALREADY_EXPORTED = 0xC0000E15,
363 INVALID_MIGRATION_DECRYPTION_KEY = 0xC0000E16,
364 INVALID_CPUSVN = 0xC0001000,
365 INVALID_REPORTMACSTRUCT = 0xC0001001,
366 L2_EXIT_HOST_ROUTED_ASYNC = 0x00001100,
367 L2_EXIT_HOST_ROUTED_TDVMCALL = 0x00001101,
368 L2_EXIT_PENDING_INTERRUPT = 0x00001102,
369 PENDING_INTERRUPT = 0x00001120,
370 TD_EXIT_BEFORE_L2_ENTRY = 0x00001140,
371 TD_EXIT_ON_L2_VM_EXIT = 0x00001141,
372 TD_EXIT_ON_L2_TO_L1 = 0x00001142,
373 GLA_NOT_CANONICAL = 0xC0001160,
374 }
375}
376
377impl TdCallResultCode {
378 const fn from_bits(value: u64) -> Self {
379 Self(value as u32)
380 }
381
382 const fn into_bits(self) -> u64 {
383 self.0 as u64
384 }
385}
386
387#[bitfield(u64)]
389pub struct TdCallResult {
390 pub details: u32,
391 #[bits(32)]
392 pub code: TdCallResultCode,
393}
394
395open_enum! {
396 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
398 pub enum TdVmCallR10Result: u64 {
399 SUCCESS = 0,
400 RETRY = 1,
401 OPERAND_INVALID = 0x80000000_00000000,
402 GPA_INUSE = 0x80000000_00000001,
403 ALIGN_ERROR = 0x80000000_00000002,
404 }
405}
406
407#[repr(u64)]
409#[derive(Debug)]
410pub enum FieldSize {
411 Invalid = 0,
412 Size16Bit = 1,
413 Size32Bit = 2,
414 Size64Bit = 3,
415}
416
417impl FieldSize {
418 const fn from_bits(value: u64) -> Self {
419 match value {
420 0 => FieldSize::Invalid,
421 1 => FieldSize::Size16Bit,
422 2 => FieldSize::Size32Bit,
423 3 => FieldSize::Size64Bit,
424 _ => panic!("Invalid field size"),
425 }
426 }
427
428 const fn into_bits(self) -> u64 {
429 self as u64
430 }
431}
432
433open_enum! {
434 pub enum TdVpsClassCode: u8 {
435 TD_VMCS = 0,
436 VAPIC = 1,
437 VE_INFO = 2,
438 GUEST_GPR_STATE = 16,
439 GUEST_STATE = 17,
440 GUEST_EXT_STATE = 18,
441 GUEST_MSR_STATE = 19,
442 MANAGEMENT = 32,
443 CPUID_CONTROL = 33,
444 EPT_VIOLATION_LOG = 34,
445 VMCS_1 = 36,
446 MSR_BITMAPS_1 = 37,
447 MSR_BITMAPS_SHADOW_1 = 38,
448 VMCS_2 = 44,
449 MSR_BITMAPS_2 = 45,
450 MSR_BITMAPS_SHADOW_2 = 46,
451 VMCS_3 = 52,
452 }
453}
454
455open_enum! {
456 pub enum TdxContextCode: u8 {
457 PLATFORM = 0,
458 TD = 1,
459 TD_VCPU = 2,
460 }
461}
462
463impl TdxContextCode {
464 const fn from_bits(value: u64) -> Self {
465 Self(value as u8)
466 }
467 const fn into_bits(self) -> u64 {
468 self.0 as u64
469 }
470}
471
472pub const TDX_FIELD_CODE_L2_CTLS_VM1: TdxExtendedFieldCode =
473 TdxExtendedFieldCode(0xA020000300000051);
474pub const TDX_FIELD_CODE_L2_CTLS_VM2: TdxExtendedFieldCode =
475 TdxExtendedFieldCode(0xA020000300000051);
476
477#[bitfield(u64)]
479pub struct TdxExtendedFieldCode {
480 #[bits(24)]
481 pub field_code: u32,
482 #[bits(8)]
483 _reserved0: u64,
484 #[bits(2)]
485 pub field_size: FieldSize,
486 #[bits(4)]
487 pub last_element: u8,
488 #[bits(9)]
489 pub last_field: u16,
490 #[bits(3)]
491 _reserved1: u64,
492 pub increment_size: bool,
493 pub write_mask_valid: bool,
494 #[bits(3)]
495 pub context_code: TdxContextCode,
496 #[bits(1)]
497 _reserved2: u64,
498 #[bits(6)]
499 pub class_code: u8,
500 #[bits(1)]
501 _reserved3: u64,
502 pub non_arch: bool,
503}
504
505#[bitfield(u64)]
507pub struct TdxInstructionInfo {
508 pub info: u32,
509 pub length: u32,
510}
511
512#[bitfield(u64)]
513pub struct TdxL2Ctls {
514 pub enable_shared_ept: bool,
515 pub enable_tdvmcall: bool,
516 #[bits(62)]
517 pub reserved: u64,
518}
519
520#[bitfield(u64)]
521pub struct TdxVpEnterRaxResult {
522 #[bits(32)]
524 pub vmx_exit: vmx::VmxExit,
525 #[bits(32)]
527 pub tdx_exit: TdCallResultCode,
528}
529
530#[bitfield(u64)]
531pub struct TdxExtendedExitQualification {
532 #[bits(4)]
533 pub ty: TdxExtendedExitQualificationType,
534 #[bits(60)]
535 _reserved: u64,
536}
537
538open_enum! {
539 pub enum TdxExtendedExitQualificationType: u8 {
540 NONE = 0,
541 PENDING_EPT_VIOLATION = 6,
542 }
543}
544
545impl TdxExtendedExitQualificationType {
546 const fn from_bits(value: u64) -> Self {
547 Self(value as u8)
548 }
549
550 const fn into_bits(self) -> u64 {
551 self.0 as u64
552 }
553}
554
555#[repr(C)]
558#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
559pub struct TdxL2EnterGuestState {
560 pub gps: [u64; 16],
562 pub rflags: u64,
563 pub rip: u64,
564 pub ssp: u64,
565 pub rvi: u8, pub svi: u8, pub reserved: [u8; 6],
568}
569
570pub enum TdxGp {}
571impl TdxGp {
572 pub const RAX: usize = 0;
573 pub const RCX: usize = 1;
574 pub const RDX: usize = 2;
575 pub const RBX: usize = 3;
576 pub const RSP: usize = 4;
577 pub const RBP: usize = 5;
578 pub const RSI: usize = 6;
579 pub const RDI: usize = 7;
580 pub const R8: usize = 8;
581 pub const R9: usize = 9;
582 pub const R10: usize = 10;
583 pub const R11: usize = 11;
584 pub const R12: usize = 12;
585 pub const R13: usize = 13;
586 pub const R14: usize = 14;
587 pub const R15: usize = 15;
588}
589
590#[bitfield(u64)]
591pub struct TdxGlaListInfo {
592 #[bits(9)]
593 pub first_entry: u64,
594 #[bits(3)]
595 _reserved_z0: u64,
596 #[bits(40)]
597 pub list_gpa: u64,
598 #[bits(10)]
599 pub num_entries: u64,
600 #[bits(2)]
601 _reserved_z1: u64,
602}
603
604#[bitfield(u64)]
605pub struct TdGlaVmAndFlags {
606 pub list: bool,
607 #[bits(51)]
608 _reserved_z0: u64,
609 #[bits(2)]
610 pub vm_index: u64,
611 #[bits(10)]
612 _reserved_z1: u64,
613}
614
615#[bitfield(u64)]
616#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
617pub struct TdxVmFlags {
618 #[bits(2)]
619 pub invd_translations: u8,
620
621 #[bits(50)]
622 _reserved: u64,
623
624 #[bits(2)]
626 pub vm_index: u8,
627
628 #[bits(10)]
629 _reserved_2: u64,
630}
631
632pub const TDX_VP_ENTER_INVD_INVEPT: u8 = 1;
633pub const TDX_VP_ENTER_INVD_INVVPID: u8 = 2;
634pub const TDX_VP_ENTER_INVD_INVVPID_NON_GLOBAL: u8 = 3;