#ifndef BARRELFISH_CAPABILITIES_H
#define BARRELFISH_CAPABILITIES_H
-/* FIXME: OBJBITS defines must match sizes in Hamlet's capabilities/caps.hl */
+/* FIXME: OBJBITS and OBJSIZE defines must match sizes in Hamlet's capabilities/caps.hl */
// Size of CNode entry
#define OBJBITS_CTE 6
+// Size of L2 CNode table: resolve 8 bits of cap address
+#define OBJSIZE_L2CNODE (1UL << (OBJBITS_CTE + 8))
+
// Size of dispatcher
#define OBJBITS_DISPATCHER 10
static inline bool type_is_vnode(enum objtype type)
{
- STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+ STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
return (type == ObjType_VNode_x86_64_pml4 ||
type == ObjType_VNode_x86_64_pdpt ||
static inline size_t vnode_objbits(enum objtype type)
{
// This function should be emitted by hamlet or somesuch.
- STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+ STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
if (type == ObjType_VNode_x86_64_pml4 ||
type == ObjType_VNode_x86_64_pdpt ||
* @param type Object type.
*
* @return Size of a VNode in bytes.
+ *
+ * XXX: this should probably just do 1UL << vnode_objbits(type) for vnode
+ * objtypes -SG, 2016-07-06.
*/
static inline size_t vnode_objsize(enum objtype type)
{
// This function should be emitted by hamlet or somesuch.
- STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+ STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
if (type == ObjType_VNode_x86_64_pml4 ||
type == ObjType_VNode_x86_64_pdpt ||
*/
static inline size_t vnode_entry_bits(enum objtype type) {
// This function should be emitted by hamlet or somesuch.
- STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+ STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
if (type == ObjType_VNode_x86_64_pml4 ||
type == ObjType_VNode_x86_64_pdpt ||
static inline enum objtype get_mapping_type(enum objtype captype)
{
- STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+ STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mapping types");
switch (captype) {
case ObjType_Frame:
static inline bool type_is_mapping(enum objtype type)
{
- STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+ STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mapping types");
switch (type) {
case ObjType_Frame_Mapping:
static inline bool type_is_mappable(enum objtype type)
{
- STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+ STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mappable types");
switch (type) {
case ObjType_Frame:
struct capability monitor_ep;
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
int sprint_cap(char *buf, size_t len, struct capability *cap)
{
switch (cap->type) {
return ret;
}
+ case ObjType_L1CNode: {
+ int ret = snprintf(buf, len, "L1 CNode cap "
+ "(allocated bytes %#"PRIxGENSIZE
+ ", rights mask %#"PRIxCAPRIGHTS")",
+ get_size(cap), cap->u.l1cnode.rightsmask);
+ return ret;
+ }
+
+ case ObjType_L2CNode: {
+ int ret = snprintf(buf, len, "L2 CNode cap "
+ "(rights mask %#"PRIxCAPRIGHTS")",
+ cap->u.l1cnode.rightsmask);
+ return ret;
+ }
+
case ObjType_Dispatcher:
return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
// If you create more capability types you need to deal with them
// in the table below.
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == 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 / (1UL << OBJBITS_CTE);
}
+ case ObjType_L1CNode:
+ if (srcsize < OBJSIZE_L2CNODE || objsize < OBJSIZE_L2CNODE) {
+ // disallow L1 CNode to be smaller than 16kB.
+ return 0;
+ } else {
+ return srcsize / objsize;
+ }
+
+ case ObjType_L2CNode:
+ if (srcsize < OBJSIZE_L2CNODE || objsize != OBJSIZE_L2CNODE) {
+ // disallow L2 CNode creation if source too small or objsize wrong
+ return 0;
+ } else {
+ return srcsize / objsize;
+ }
+
+
case ObjType_VNode_x86_64_pml4:
case ObjType_VNode_x86_64_pdpt:
case ObjType_VNode_x86_64_pdir:
*
* For the meaning of the parameters, see the 'caps_create' function.
*/
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == 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)
TRACE(KERNEL, BZERO, 0);
break;
+ case ObjType_L1CNode:
+ case ObjType_L2CNode:
+ debug(SUBSYS_CAPS, "L%dCNode: zeroing %zu bytes @%#"PRIxLPADDR"\n",
+ type == ObjType_L1CNode ? 1 : 2, (size_t)objsize * count,
+ lpaddr);
+ TRACE(KERNEL, BZERO, 1);
+ memset((void*)lvaddr, 0, objsize * count);
+ TRACE(KERNEL, BZERO, 0);
+ break;
+
case ObjType_VNode_ARM_l1:
case ObjType_VNode_ARM_l2:
case ObjType_VNode_AARCH64_l1:
*/
// If you create more capability types you need to deal with them
// in the table below.
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == 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,
}
break;
+ case ObjType_L1CNode:
+ panic("caps_create L1CNode NYI!");
+ break;
+
+ case ObjType_L2CNode:
+ panic("caps_create L2CNode NYI!");
+ break;
+
case ObjType_VNode_ARM_l1:
{
size_t objsize_vnode = vnode_objsize(type);
//{{{1 Capability creation
/// check arguments, return true iff ok
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
static bool check_caps_create_arguments(enum objtype type,
size_t bytes, size_t objsize,
bool exact)
return true;
}
+ if (type == ObjType_L1CNode) {
+ panic("check_caps_create_arguments NYI for L1 CNode");
+ }
+
+ if (type == ObjType_L2CNode) {
+ panic("check_caps_create_arguments NYI for L2 CNode");
+ }
+
/* special case Dispatcher which is 1kB right now */
if (type == ObjType_Dispatcher) {
if (bytes & ((1UL << OBJBITS_DISPATCHER) - 1)) {
return SYS_ERR_OK;
}
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == 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`.
printk(LOG_WARN, "%s: CNode: objsize = %zu\n", __FUNCTION__, objsize);
return SYS_ERR_INVALID_SIZE;
}
+ else if (type == ObjType_L1CNode && objsize % OBJSIZE_L2CNODE != 0)
+ {
+ printk(LOG_WARN, "%s: L1CNode: objsize = %zu\n", __FUNCTION__, objsize);
+ return SYS_ERR_INVALID_SIZE;
+ }
+ else if (type == ObjType_L2CNode && objsize != OBJSIZE_L2CNODE)
+ {
+ printk(LOG_WARN, "%s: L2CNode: objsize = %zu\n", __FUNCTION__, objsize);
+ return SYS_ERR_INVALID_SIZE;
+ }
// TODO: clean up semantics for type == ObjType_CNode
assert((type == ObjType_CNode
&& ((objsize * sizeof(struct cte)) % BASE_PAGE_SIZE == 0)) ||
(type_is_mappable(type) && objsize % BASE_PAGE_SIZE == 0) ||
+ (type == ObjType_L1CNode && objsize % OBJSIZE_L2CNODE == 0 &&
+ objsize >= OBJSIZE_L2CNODE) ||
+ (type == ObjType_L2CNode && objsize == OBJSIZE_L2CNODE) ||
!(type_is_mappable(type) || type == ObjType_CNode));
/* No explicit retypes to Mapping allowed */
}
/// Create copies to a cte
+STATIC_ASSERT(48 == 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)
{
dest_cap->u.cnode.guard_size = param2;
break;
+ case ObjType_L1CNode:
+ case ObjType_L2CNode:
+ panic("Mint NYI for L1/L2 CNodes");
+
case ObjType_EndPoint:
// XXX: FIXME: check that buffer offset lies wholly within the disp frame
// can't easily enforce this here, because the dispatcher frame may not