blob: 7ad3a51cd67d175e53a7c6c09e5908ec096136dd [file] [log] [blame]
/*
* 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_