| /* |
| * Copyright 2024 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef SW_DEVICE_LIB_TESTING_TEST_ROM_CHERIOT_BAREMETAL_H_ |
| #define SW_DEVICE_LIB_TESTING_TEST_ROM_CHERIOT_BAREMETAL_H_ |
| |
| // XXX just make this a noop? |
| #ifndef __CHERIOT_BAREMETAL__ |
| #error "This file is only useful when compiling for baremetal" |
| #endif |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #define CHERI_PERM_GLOBAL (1U << 0) |
| #define CHERI_PERM_LOAD_GLOBAL (1U << 1) |
| #define CHERI_PERM_STORE (1U << 2) |
| #define CHERI_PERM_LOAD_MUTABLE (1U << 3) |
| #define CHERI_PERM_STORE_LOCAL (1U << 4) |
| #define CHERI_PERM_LOAD (1U << 5) |
| #define CHERI_PERM_LOAD_STORE_CAP (1U << 6) |
| #define CHERI_PERM_ACCESS_SYS (1U << 7) |
| #define CHERI_PERM_EXECUTE (1U << 8) |
| #define CHERI_PERM_UNSEAL (1U << 9) |
| #define CHERI_PERM_SEAL (1U << 10) |
| #define CHERI_PERM_USER0 (1U << 11) |
| |
| #define cgetlen(foo) __builtin_cheri_length_get(foo) |
| #define cgetperms(foo) __builtin_cheri_perms_get(foo) |
| #define cgettype(foo) __builtin_cheri_type_get(foo) |
| #define cgettag(foo) __builtin_cheri_tag_get(foo) |
| #define cgetoffset(foo) __builtin_cheri_offset_get(foo) |
| #define csetoffset(a, b) __builtin_cheri_offset_set((a), (b)) |
| #define cincoffset(a, b) __builtin_cheri_offset_increment((a), (b)) |
| #define cgetaddr(a) __builtin_cheri_address_get(a) |
| #define csetaddr(a, b) __builtin_cheri_address_set((a), (b)) |
| #define cgetbase(foo) __builtin_cheri_base_get(foo) |
| #define candperms(a, b) __builtin_cheri_perms_and((a), (b)) |
| #define cseal(a, b) __builtin_cheri_seal((a), (b)) |
| #define cunseal(a, b) __builtin_cheri_unseal((a), (b)) |
| #define csetbounds(a, b) __builtin_cheri_bounds_set((a), (b)) |
| #define csetboundsext(a, b) __builtin_cheri_bounds_set_exact((a), (b)) |
| #define ccheckperms(a, b) __builtin_cheri_perms_check((a), (b)) |
| #define cchecktype(a, b) __builtin_cheri_type_check((a), (b)) |
| #define cbuildcap(a, b) __builtin_cheri_cap_build((a), (b)) |
| #define ccopytype(a, b) __builtin_cheri_cap_type_copy((a), (b)) |
| #define ccseal(a, b) __builtin_cheri_conditional_seal((a), (b)) |
| #define cequalexact(a, b) __builtin_cheri_equal_exact((a), (b)) |
| |
| // Derives a capability from the root cap for doing MMIO to a |
| // device at a fixed address. |
| static inline uintptr_t cderivecap(const uintptr_t root_cap, |
| const uint32_t paddr, |
| const size_t size_bytes, |
| const uint32_t perms) { |
| return candperms( |
| csetbounds( |
| csetaddr(root_cap, paddr), |
| size_bytes), |
| perms); |
| } |
| |
| // Constructs a capability for invoking a function at the specified |
| // address using mtcc. This is intended only for passing control to |
| // the next stage firmware. |
| static inline uintptr_t cderivepcc(const uintptr_t paddr) { |
| volatile uintptr_t ret; |
| uint32_t paddr_temp; |
| __asm( |
| "cgetaddr %1, %2\n" |
| "cspecialr %0, mtcc\n" |
| "csetaddr %0, %0, %1\n" |
| : "=C"(ret), "=&r"(paddr_temp) |
| : "C"(paddr)); |
| return ret; |
| } |
| |
| #endif // SW_DEVICE_LIB_TESTING_TEST_ROM_CHERIOT_BAREMETAL_H_ |