struct capability monitor_ep;
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
int sprint_cap(char *buf, size_t len, struct capability *cap)
{
switch (cap->type) {
return snprintf(buf, len, "ID capability (coreid 0x%" PRIxCOREID
" core_local_id 0x%" PRIx32 ")", cap->u.id.coreid,
cap->u.id.core_local_id);
+ case ObjType_ProcessManager:
+ return snprintf(buf, len, "Process manager capability");
+
+ case ObjType_Domain:
+ return snprintf(buf, len, "Domain capability (coreid 0x%" PRIxCOREID
+ " core_local_id 0x%" PRIx32 ")", cap->u.domain.coreid,
+ cap->u.domain.core_local_id);
case ObjType_PerfMon:
return snprintf(buf, len, "PerfMon cap");
static uint32_t id_cap_counter = 1;
/**
+ * Domain capability core_local_id counter.
+ */
+ static uint32_t domain_cap_counter = 1;
+
+ /**
* Sets #dest equal to #src
*
* #dest cannot be in use.
// If you create more capability types you need to deal with them
// in the table below.
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t objsize)
{
switch(type) {
return srcsize / OBJSIZE_KCB;
}
+ case ObjType_Domain:
+ return L2_CNODE_SLOTS;
+
case ObjType_Kernel:
case ObjType_IRQTable:
case ObjType_IRQDest:
case ObjType_Notify_IPI:
case ObjType_PerfMon:
case ObjType_IPI:
+ case ObjType_ProcessManager:
case ObjType_VNode_ARM_l1_Mapping:
case ObjType_VNode_ARM_l2_Mapping:
case ObjType_VNode_AARCH64_l0_Mapping:
*
* For the meaning of the parameters, see the 'caps_create' function.
*/
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
static errval_t caps_zero_objects(enum objtype type, lpaddr_t lpaddr,
gensize_t objsize, size_t count)
*/
// If you create more capability types you need to deal with them
// in the table below.
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, gensize_t size,
gensize_t objsize, size_t count, coreid_t owner,
err = set_cap(&dest_caps->cap, &temp_cap);
break;
+ case ObjType_Domain:
+ // Domain type does not refer to a kernel object
+ assert(lpaddr == 0);
+ assert(size == 0);
+ assert(objsize == 0);
+ assert(count <= L2_CNODE_SLOTS);
+
+ // Prevent wrap around
+ if (domain_cap_counter + count >= UINT32_MAX) {
+ return SYS_ERR_DOMAIN_SPACE_EXHAUSTED;
+ }
+
+ for(size_t i = 0; i < count; i++) {
+ // Initialize type specific fields
+ temp_cap.u.domain.coreid = my_core_id;
+ temp_cap.u.domain.core_local_id = domain_cap_counter++;
+ // Insert the capability
+ err = set_cap(&dest_caps[i].cap, &temp_cap);
+ if (err_is_fail(err)) {
+ break;
+ }
+ }
+ break;
case ObjType_IO:
temp_cap.u.io.start = 0;
temp_cap.u.io.end = 65535;
case ObjType_EndPoint:
case ObjType_Notify_IPI:
case ObjType_PerfMon:
+ case ObjType_ProcessManager:
// These types do not refer to a kernel object
assert(lpaddr == 0);
assert(size == 0);
//{{{1 Capability creation
/// check arguments, return true iff ok
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
#ifndef NDEBUG
static bool check_caps_create_arguments(enum objtype type,
size_t bytes, size_t objsize,
return SYS_ERR_OK;
}
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
/// Retype caps
/// Create `count` new caps of `type` from `offset` in src, and put them in
/// `dest_cnode` starting at `dest_slot`.
src_cap->type == ObjType_Dispatcher ||
src_cap->type == ObjType_Frame ||
src_cap->type == ObjType_DevFrame ||
- src_cap->type == ObjType_IRQSrc);
+ src_cap->type == ObjType_IRQSrc ||
+ src_cap->type == ObjType_ProcessManager);
if (src_cap->type != ObjType_Dispatcher && src_cap->type != ObjType_IRQSrc) {
base = get_address(src_cap);
/* check that we can create `count` objs from `offset` in source, and
* update base accordingly */
- if (src_cap->type != ObjType_Dispatcher && src_cap->type != ObjType_IRQSrc) {
+ if (src_cap->type != ObjType_Dispatcher && src_cap->type != ObjType_IRQSrc
+ && src_cap->type != ObjType_Domain) {
// TODO: convince ourselves that this is the only condition on offset
if (offset + count * objsize > get_size(src_cap)) {
debug(SUBSYS_CAPS, "caps_retype: cannot create all %zu objects"
dest_cap->u.endpoint.listener = src_cap->u.dispatcher.dcb;
}
+ // XXX: Treat full object retypes to same type as copies as calling
+ // is_copy(dst, src) will return true for such retypes.
+ if (count == 1 && objsize == get_size(src_cap) && type == src_cap->type) {
+ // sanity check: is_copy() really returns true for the two caps
+ assert(is_copy(&dest_cte[0].cap, src_cap));
+ // If we're not owner, and type needs locality
+ if (src_cte->mdbnode.owner != my_core_id &&
+ distcap_needs_locality(dest_cte[0].cap.type))
+ {
+ // fix owner for new cap and set remote_copies bit
+ dest_cte[0].mdbnode.owner = src_cte->mdbnode.owner;
+ dest_cte[0].mdbnode.remote_copies = true;
+ }
+ }
+
/* Handle mapping */
for (size_t i = 0; i < count; i++) {
mdb_insert(&dest_cte[i]);
}
/// Create copies to a cte
- STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
+ STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all cap types");
errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
uintptr_t param1, uintptr_t param2)
{