|  | // Copyright CHERIoT Contributors. | 
|  | // SPDX-License-Identifier: MIT | 
|  |  | 
|  | #pragma once | 
|  | #include <compartment-macros.h> | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | struct Timeout; | 
|  |  | 
|  | /** | 
|  | * The complete set of architectural permissions. | 
|  | */ | 
|  | enum CHERIPermission | 
|  | { | 
|  | /** | 
|  | * Capability refers to global memory (this capability may be stored | 
|  | * anywhere). | 
|  | */ | 
|  | CheriPermissionGlobal = 0, | 
|  | /** | 
|  | * Global capabilities can be loaded through this capability.  Without | 
|  | *  this permission, any capability loaded via this capability will | 
|  | *  have `Global` and `LoadGlobal` removed. | 
|  | */ | 
|  | CheriPermissionLoadGlobal = 1, | 
|  | /** | 
|  | * Capability may be used to store.  Any store via a capability without | 
|  | * this permission will trap. | 
|  | */ | 
|  | CheriPermissionStore = 2, | 
|  | /** | 
|  | * Capabilities with store permission may be loaded through this | 
|  | * capability.  Without this, any loaded capability will have | 
|  | * `LoadMutable` and `Store` removed. | 
|  | */ | 
|  | CheriPermissionLoadMutable = 3, | 
|  | /** | 
|  | * This capability may be used to store capabilities that do not have | 
|  | * `Global` permission. | 
|  | */ | 
|  | CheriPermissionStoreLocal = 4, | 
|  | /** | 
|  | * This capability can be used to load. | 
|  | */ | 
|  | CheriPermissionLoad = 5, | 
|  | /** | 
|  | * Any load and store permissions on this capability convey the right to | 
|  | * load or store capabilities in addition to data. | 
|  | */ | 
|  | CheriPermissionLoadStoreCapability = 6, | 
|  | /** | 
|  | * If installed as the program counter capability, running code may | 
|  | * access privileged system registers. | 
|  | */ | 
|  | CheriPermissionAccessSystemRegisters = 7, | 
|  | /** | 
|  | * This capability may be used as a jump target and used to execute | 
|  | * instructions. | 
|  | */ | 
|  | CheriPermissionExecute = 8, | 
|  | /** | 
|  | * This capability may be used to unseal other capabilities.  The | 
|  | * 'address' range is in the sealing type namespace and not in the | 
|  | * memory namespace. | 
|  | */ | 
|  | CheriPermissionUnseal = 9, | 
|  | /** | 
|  | * This capability may be used to seal other capabilities.  The | 
|  | * 'address' range is in the sealing type namespace and not in the | 
|  | * memory namespace. | 
|  | */ | 
|  | CheriPermissionSeal = 10, | 
|  | /** | 
|  | * Software defined permission bit, no architectural meaning. | 
|  | */ | 
|  | CheriPermissionUser0 = 11 | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * The codes used in the cause field of the mtval CSR when the processor | 
|  | * takes a CHERI exception. | 
|  | */ | 
|  | enum CHERICauseCode | 
|  | { | 
|  | /** | 
|  | * No exception. This value is passed to the error handler after a | 
|  | * forced unwind in a called compartment. | 
|  | */ | 
|  | CheriCauseCodeNone = 0, | 
|  | /** | 
|  | * Attempted to use a capability outside its bounds. | 
|  | */ | 
|  | CheriCauseCodeBoundsViolation = 1, | 
|  | /** | 
|  | * Attempted to use an untagged capability to authorize something. | 
|  | */ | 
|  | CheriCauseCodeTagViolation = 2, | 
|  | /** | 
|  | * Attempted to use a sealed capability to authorize something. | 
|  | */ | 
|  | CheriCauseCodeSealViolation = 3, | 
|  | /** | 
|  | * Attempted to jump to a capability without `Permission::Execute`. | 
|  | */ | 
|  | CheriCauseCodePermitExecuteViolation = 0x11, | 
|  | /** | 
|  | * Attempted to load via a capability without `Permission::Load`. | 
|  | */ | 
|  | CheriCauseCodePermitLoadViolation = 0x12, | 
|  | /** | 
|  | * Attempted to store via a capability without `Permission::Store`. | 
|  | */ | 
|  | CheriCauseCodePermitStoreViolation = 0x13, | 
|  | /** | 
|  | * Attempted to store a tagged capability via a capability without | 
|  | * `Permission::LoadStoreCapability`. | 
|  | */ | 
|  | CheriCauseCodePermitStoreCapabilityViolation = 0x15, | 
|  | /** | 
|  | * Attempted to store a tagged capability without `Permission::Global` | 
|  | * via capability without `Permission::StoreLocal`. | 
|  | */ | 
|  | CheriCauseCodePermitStoreLocalCapabilityViolation = 0x16, | 
|  | /** | 
|  | * Attempted to access a restricted CSR or SCR with PCC without | 
|  | * `Permission::AccessSystemRegisters`. | 
|  | */ | 
|  | CheriCauseCodePermitAccessSystemRegistersViolation = 0x18, | 
|  | /** | 
|  | * Used to represent a value that has no valid meaning in hardware. | 
|  | */ | 
|  | CheriCauseCodeInvalid = -1 | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Register numbers as reported in cap idx field of  `mtval` CSR when | 
|  | * a CHERI exception is taken. Values less than 32 refer to general | 
|  | * purpose registers and others to SCRs (of these, only PCC can actually | 
|  | * cause an exception). | 
|  | */ | 
|  | enum CHERIRegisterNumber | 
|  | { | 
|  | /** | 
|  | * The zero register, which always contains the `NULL` capability. | 
|  | */ | 
|  | CheriRegisterNumberCzr = 0x0, | 
|  | /** | 
|  | * `$c1` / `$cra` used by the ABI as the return address. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCra = 0x1, | 
|  | /** | 
|  | * `$c2` / `$csp` used by the ABI as the stack pointer. | 
|  | * Preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCsp = 0x2, | 
|  | /** | 
|  | * `$c3` / `$cgp` used by the ABI as the global pointer. | 
|  | * Not allocatable by the compiler, set by the switcher on compartment | 
|  | * entry. | 
|  | */ | 
|  | CheriRegisterNumberCgp = 0x3, | 
|  | /** | 
|  | * `$c4` / `$ctp` used by the ABI as the thread pointer. | 
|  | * Currently unused by the compiler. | 
|  | * Not preserved across compartment calls. | 
|  | */ | 
|  | CheriRegisterNumberCtp = 0x4, | 
|  | /** | 
|  | * `$c5` / `$ct0` used by the ABI as temporary register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCT0 = 0x5, | 
|  | /** | 
|  | * `$c6` / `$ct1` used by the ABI as temporary register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCT1 = 0x6, | 
|  | /** | 
|  | * `$c7` / `$ct2` used by the ABI as temporary register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCT2 = 0x7, | 
|  | /** | 
|  | * `$c8` / `$cs0` used by the ABI as a callee-saved register. | 
|  | * Preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCS0 = 0x8, | 
|  | /** | 
|  | * `$c9` / `$cs1` used by the ABI as a callee-saved register. | 
|  | * Preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCS1 = 0x9, | 
|  | /** | 
|  | * `$c10` / `$ca0` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA0 = 0xa, | 
|  | /** | 
|  | * `$c11` / `$ca1` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA1 = 0xb, | 
|  | /** | 
|  | * `$c12` / `$ca2` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA2 = 0xc, | 
|  | /** | 
|  | * `$c13` / `$ca3` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA3 = 0xd, | 
|  | /** | 
|  | * `$c14` / `$ca4` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA4 = 0xe, | 
|  | /** | 
|  | * `$c15` / `$ca5` used by the ABI as an argument register. | 
|  | * Not preserved across calls. | 
|  | */ | 
|  | CheriRegisterNumberCA5 = 0xf, | 
|  | /** | 
|  | * The Program Counter Capability. | 
|  | * | 
|  | * Special capability register used to authorize instruction fetch. The | 
|  | * address is that of the faulting instruction. Also used for accessing | 
|  | * read-only globals. | 
|  | */ | 
|  | CheriRegisterNumberPcc = 0x20, | 
|  | /** | 
|  | * Machine-mode Trap Code Capability. | 
|  | * | 
|  | * Special capability register that | 
|  | * is installed in PCC when the CPU takes a trap. The address has the | 
|  | * same semantics as the RISC-V `mtvec` CSR. Only accessible when PCC | 
|  | * has the AccessSystemRegisters permission. | 
|  | */ | 
|  | CheriRegisterNumberMtcc = 0x3c, | 
|  | /** | 
|  | * Machine-mode Tusted Data Capability. | 
|  | * | 
|  | * Special capability register that contains the memory root capability | 
|  | * on boot. Only accessible when PCC has the AccessSystemRegisters | 
|  | * permission.  Use by the RTOS to store a capability to the trusted | 
|  | * stack. | 
|  | */ | 
|  | CheriRegisterNumberMtdc = 0x3d, | 
|  | /** | 
|  | * Machine-mode Scratch Capability. Special capabiltiy register that | 
|  | * contains the sealing root capability on boot. Only accessible when | 
|  | * PCC has the AccessSystemRegisters permission. | 
|  | */ | 
|  | CheriRegisterNumberMScratchC = 0x3e, | 
|  | /** | 
|  | * Machine-mode Exception Program Counter Capability. Special capability | 
|  | * register that contains the PCC of the faulting instruction on trap. | 
|  | * The address has the same semantics as the RISC-V `mepc` CSR. Only | 
|  | * accessible when PCC has the AccessSystemRegisters permission. | 
|  | */ | 
|  | CheriRegisterNumberMepcc = 0x3f, | 
|  | /** | 
|  | * Indicates a value that is not used by the hardware to refer to a | 
|  | * register. | 
|  | */ | 
|  | CheriRegisterNumberInvalid = -1 | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Sealing types. | 
|  | */ | 
|  | enum CHERISealingType | 
|  | { | 
|  | /** | 
|  | * 0 represents unsealed. | 
|  | */ | 
|  | CheriSealTypeUnsealed = 0, | 
|  |  | 
|  | /** | 
|  | * Sentry that inherits interrupt status. | 
|  | */ | 
|  | CheriSealTypeSentryInheriting, | 
|  |  | 
|  | /** | 
|  | * Sentry that disables interrupts on calls. | 
|  | */ | 
|  | CheriSealTypeSentryDisabling, | 
|  |  | 
|  | /** | 
|  | * Sentry that enables interrupts on calls. | 
|  | */ | 
|  | CheriSealTypeSentryEnabling, | 
|  |  | 
|  | /** | 
|  | * Return sentry that disables interrupts on return | 
|  | */ | 
|  | CheriSealTypeReturnSentryDisabling, | 
|  |  | 
|  | /** | 
|  | * Return sentry that enables interrupts on return | 
|  | */ | 
|  | CheriSealTypeReturnSentryEnabling, | 
|  |  | 
|  | /** | 
|  | * Marker for the first sealing type that's valid for data capabilities. | 
|  | */ | 
|  | CheriSealTypeFirstDataSealingType = 9, | 
|  |  | 
|  | /** | 
|  | * The sealing type used for sealed export table entries. | 
|  | * | 
|  | * This is RTOS- and not CHERIoT-specific. | 
|  | */ | 
|  | CheriSealTypeSealedImportTableEntries = CheriSealTypeFirstDataSealingType, | 
|  |  | 
|  | /** | 
|  | * The compartment switcher has a sealing type for the trusted stack. | 
|  | * | 
|  | * This must be the second data sealing type so that we can also permit | 
|  | * the switcher to unseal sentries and export table entries. | 
|  | * | 
|  | * This is RTOS- and not CHERIoT-specific. | 
|  | */ | 
|  | CheriSealTypeSealedTrustedStacks, | 
|  |  | 
|  | /** | 
|  | * The allocator has a sealing type for the software sealing mechanism | 
|  | * with dynamically allocated objects. | 
|  | * | 
|  | * This is RTOS- and not CHERIoT-specific. | 
|  | */ | 
|  | CheriSealTypeAllocator, | 
|  |  | 
|  | /** | 
|  | * The loader reserves a sealing type for the software sealing | 
|  | * mechanism.  The permit-unseal capability for this is destroyed after | 
|  | * the loader has run, which guarantees that anything sealed with this | 
|  | * type was present in the original firmware image.  The token library | 
|  | * has the only permit-unseal capability for this type. | 
|  | * | 
|  | * This is RTOS- and not CHERIoT-specific. | 
|  | */ | 
|  | CheriSealTypeStaticToken, | 
|  |  | 
|  | /** | 
|  | * The first sealing key that is reserved for use by the allocator's | 
|  | * software sealing mechanism and used for static sealing types, | 
|  | * | 
|  | * Architecturally, this is the smallest non-interpreted sealing type. | 
|  | */ | 
|  | CheriSealTypeFirstStaticSoftware = 16, | 
|  |  | 
|  | /** | 
|  | * The first sealing key in the space that the allocator will | 
|  | * dynamically allocate for sealing types. | 
|  | * | 
|  | * This is RTOS- and not CHERIoT-specific. | 
|  | */ | 
|  | CheriSealTypeFirstDynamicSoftware = 0x1000000 | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Checks that `ptr` is valid, unsealed, has at least `rawPermissions`, and has | 
|  | * at least `space` bytes after the current offset. | 
|  | * | 
|  | * If the permissions do not include Global and `checkStackNeeded` is `false`, | 
|  | * then this will also check that the capability does not point to the current | 
|  | * thread's stack. | 
|  | * | 
|  | * To reduce code size, this function is provided as part of the compartment | 
|  | * helper library. | 
|  | */ | 
|  | bool __cheri_libcall check_pointer(const void *ptr, | 
|  | size_t      space, | 
|  | uint32_t    rawPermissions, | 
|  | bool        checkStackNeeded); | 
|  |  | 
|  | /** | 
|  | * Check that the argument is a valid pointer to a `Timeout` structure.  This | 
|  | * must have read/write permissions, be unsealed, and must not be a heap | 
|  | * address. | 
|  | */ | 
|  | bool __cheri_libcall check_timeout_pointer(const struct Timeout *timeout); |