aos/include/aos/kernel_cap_invocations.h
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

150 lines
4.8 KiB
C

/*
* Copyright (c) 2016, ETH Zurich.
*
* This file is distributed under the terms in the attached LICENSE file. If
* you do not find this file, copies can be found by writing to: ETH Zurich
* D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
*/
#ifndef __KERNEL_CAP_INVOCATIONS
#define __KERNEL_CAP_INVOCATIONS
#include <aos/aos.h>
#define DEBUG_INVOCATION(x...)
/**
* \brief Spawn a new core.
*
* \param core_id MPID of the core to be booted
* \param cpu_type Barrelfish target CPU type
* \param core_data Address of struct core_data for new core in kernel-virtual
* memory
*/
static inline errval_t
invoke_monitor_spawn_core(hwid_t core_id, enum cpu_type cpu_type,
genpaddr_t entry, genpaddr_t context,
uint64_t psci_use_hvc)
{
DEBUG_INVOCATION("%s: called from %p\n", __FUNCTION__,
__builtin_return_address(0));
return cap_invoke6(cap_ipi, IPICmd_Send_Start, core_id, cpu_type,
entry, context, psci_use_hvc).error;
}
static inline errval_t
invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int level,
capaddr_t slot, coreid_t owner)
{
DEBUG_INVOCATION("%s: called from %p\n", __FUNCTION__,
__builtin_return_address(0));
return cap_invoke6(cap_kernel, KernelCmd_Create_cap, caddr, level, slot,
owner, (uintptr_t)raw).error;
}
/**
* \brief Create a RAM cap ab initio, by invoking the kernel cap.
*
* \param dest Location to place new RAM cap
* \param base Base address of the region
* \param bytes Size of region to create
* \param coreid Which core should own the capability
*
* Forges a capability to the given region of physical memory. This is only
* possible in domains that have access to the kernel capability, and is an
* inherently unsafe operation, as it bypasses all checks in the capability
* system. As the CPU drivers don't communicate directly however, this is the
* only way to transfer a capability between cores. This must *only* be used
* for the root RAM region to be managed by a newly-booted core - if used for
* anything else, it will break things, *badly*.
*
* XXX Warning Warning Warning
* XXX Again - be *very* careful with this, and make sure you understand what
* it's doing. You're establishing the *root of trust* for the new core. If
* you use this for *anything* else, you're doing it wrong!
* XXX Warning Warning Warning
*
*/
static inline errval_t
ram_forge(struct capref dest, genpaddr_t base, gensize_t bytes,
coreid_t coreid) {
struct capability ram_cap = {
.type = ObjType_RAM,
.rights = CAPRIGHTS_READ_WRITE,
.u.ram = {
.base = base,
.pasid = 0,
.bytes = bytes
}
};
return invoke_monitor_create_cap((uint64_t *)&ram_cap,
get_cnode_addr(dest),
get_cnode_level(dest),
dest.slot, coreid);
}
/**
* \brief Create a Frame cap ab initio, by invoking the kernel cap.
*
* \param dest Location to place new Frame cap
* \param base Base address of the region
* \param bytes Size of region to create
* \param coreid Which core should own the capability
*
* As for ram_forge, but for frames. Same warnings apply!
*
*/
static inline errval_t
frame_forge(struct capref dest, genpaddr_t base, gensize_t bytes,
coreid_t coreid) {
struct capability frame_cap = {
.type = ObjType_Frame,
.rights = CAPRIGHTS_READ_WRITE,
.u.frame = {
.base = base,
.bytes = bytes
}
};
return invoke_monitor_create_cap((uint64_t *)&frame_cap,
get_cnode_addr(dest),
get_cnode_level(dest),
dest.slot, coreid);
}
/**
* \brief Create a DevFrame cap ab initio, by invoking the kernel cap.
*
* \param dest Location to place new Frame cap
* \param base Base address of the region
* \param bytes Size of region to create
* \param coreid Which core should own the capability
*
* As for ram_forge, but for devframes. Same warnings apply!
*
*/
static inline errval_t
devframe_forge(struct capref dest, genpaddr_t base, gensize_t bytes,
coreid_t coreid) {
struct capability frame_cap = {
.type = ObjType_DevFrame,
.rights = CAPRIGHTS_READ_WRITE,
.u.frame = {
.base = base,
.bytes = bytes
}
};
return invoke_monitor_create_cap((uint64_t *)&frame_cap,
get_cnode_addr(dest),
get_cnode_level(dest),
dest.slot, coreid);
}
#endif /* __KERNEL_CAP_INVOCATIONS */