T191: Implement prototype for new retype
[barrelfish] / kernel / capabilities.c
1 /**
2  * \file
3  * \brief Kernel capability management implementation.
4  */
5
6 /*
7  * Copyright (c) 2007-2012,2015, ETH Zurich.
8  * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
9  * All rights reserved.
10  *
11  * This file is distributed under the terms in the attached LICENSE file.
12  * If you do not find this file, copies can be found by writing to:
13  * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
14  */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <kernel.h>
19 #include <barrelfish_kpi/syscalls.h>
20 #include <barrelfish_kpi/paging_arch.h>
21 #include <barrelfish_kpi/lmp.h>
22 #include <offsets.h>
23 #include <capabilities.h>
24 #include <cap_predicates.h>
25 #include <distcaps.h>
26 #include <dispatch.h>
27 #include <kcb.h>
28 #include <paging_kernel_arch.h>
29 #include <mdb/mdb.h>
30 #include <mdb/mdb_tree.h>
31 #include <trace/trace.h>
32 #include <trace_definitions/trace_defs.h>
33 #include <wakeup.h>
34 #include <bitmacros.h>
35
36 #ifdef TRACE_PMEM_CAPS
37 uint64_t   trace_types_enabled = TRACE_TYPES_ENABLED_INITIAL;
38 genpaddr_t TRACE_PMEM_BEGIN    = TRACE_PMEM_BEGIN_INITIAL;
39 gensize_t  TRACE_PMEM_SIZE     = TRACE_PMEM_SIZE_INITIAL;
40
41 void caps_trace_ctrl(uint64_t types, genpaddr_t start, gensize_t size)
42 {
43     if (types) {
44         trace_types_enabled = types;
45         TRACE_PMEM_BEGIN = start;
46         TRACE_PMEM_SIZE = size;
47     } else {
48         trace_types_enabled = 0;
49     }
50 }
51 #endif
52
53 struct capability monitor_ep;
54
55 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
56 int sprint_cap(char *buf, size_t len, struct capability *cap)
57 {
58     switch (cap->type) {
59     case ObjType_PhysAddr:
60         return snprintf(buf, len,
61                         "physical address range cap (0x%" PRIxGENPADDR ":0x%zx)",
62                         cap->u.physaddr.base, cap->u.physaddr.bytes);
63
64     case ObjType_RAM:
65         return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%zx)",
66                         cap->u.ram.base, cap->u.ram.bytes);
67
68     case ObjType_CNode: {
69         int ret = snprintf(buf, len, "CNode cap "
70                            "(bits %u, rights mask 0x%" PRIxCAPRIGHTS ")",
71                            cap->u.cnode.bits, cap->u.cnode.rightsmask);
72         if (cap->u.cnode.guard_size != 0 && ret < len) {
73             ret += snprintf(&buf[ret], len - ret, " (guard 0x%" PRIxCADDR ":%u)",
74                             cap->u.cnode.guard, cap->u.cnode.guard_size);
75         }
76         return ret;
77     }
78
79     case ObjType_Dispatcher:
80         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
81
82     case ObjType_Frame:
83         return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%zx)",
84                         cap->u.frame.base, cap->u.frame.bytes);
85
86     case ObjType_DevFrame:
87         return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":0x%zx)",
88                         cap->u.frame.base, cap->u.devframe.bytes);
89
90     case ObjType_VNode_ARM_l1:
91         return snprintf(buf, len, "ARM L1 table at 0x%" PRIxGENPADDR,
92                         cap->u.vnode_arm_l1.base);
93
94     case ObjType_VNode_ARM_l2:
95         return snprintf(buf, len, "ARM L2 table at 0x%" PRIxGENPADDR,
96                         cap->u.vnode_arm_l2.base);
97
98     case ObjType_VNode_AARCH64_l1:
99         return snprintf(buf, len, "AARCH64 L1 table at 0x%" PRIxGENPADDR,
100                         cap->u.vnode_aarch64_l1.base);
101
102     case ObjType_VNode_AARCH64_l2:
103         return snprintf(buf, len, "AARCH64 L2 table at 0x%" PRIxGENPADDR,
104                         cap->u.vnode_aarch64_l2.base);
105
106     case ObjType_VNode_AARCH64_l3:
107         return snprintf(buf, len, "AARCH64 L3 table at 0x%" PRIxGENPADDR,
108                         cap->u.vnode_aarch64_l3.base);
109
110     case ObjType_VNode_x86_32_ptable:
111         return snprintf(buf, len, "x86_32 Page table at 0x%" PRIxGENPADDR,
112                         cap->u.vnode_x86_32_ptable.base);
113
114     case ObjType_VNode_x86_32_pdir:
115         return snprintf(buf, len, "x86_32 Page directory at 0x%" PRIxGENPADDR,
116                         cap->u.vnode_x86_32_pdir.base);
117
118     case ObjType_VNode_x86_32_pdpt:
119         return snprintf(buf, len, "x86_32 PDPT at 0x%" PRIxGENPADDR,
120                         cap->u.vnode_x86_32_pdpt.base);
121
122     case ObjType_VNode_x86_64_ptable:
123         return snprintf(buf, len, "x86_64 Page table at 0x%" PRIxGENPADDR,
124                         cap->u.vnode_x86_64_ptable.base);
125
126     case ObjType_VNode_x86_64_pdir:
127         return snprintf(buf, len, "x86_64 Page directory at 0x%" PRIxGENPADDR,
128                         cap->u.vnode_x86_64_pdir.base);
129
130     case ObjType_VNode_x86_64_pdpt:
131         return snprintf(buf, len, "x86_64 PDPT at 0x%" PRIxGENPADDR,
132                         cap->u.vnode_x86_64_pdpt.base);
133
134     case ObjType_VNode_x86_64_pml4:
135         return snprintf(buf, len, "x86_64 PML4 at 0x%" PRIxGENPADDR,
136                         cap->u.vnode_x86_64_pml4.base);
137
138     case ObjType_Frame_Mapping:
139         return snprintf(buf, len, "Frame Mapping (Frame cap @%p, "
140                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
141                                   cap->u.frame_mapping.frame,
142                                   cap->u.frame_mapping.pte,
143                                   cap->u.frame_mapping.pte_count);
144
145     case ObjType_DevFrame_Mapping:
146         return snprintf(buf, len, "DevFrame Mapping (DevFrame cap @%p, "
147                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
148                                   cap->u.devframe_mapping.frame,
149                                   cap->u.devframe_mapping.pte,
150                                   cap->u.devframe_mapping.pte_count);
151
152     case ObjType_VNode_x86_64_pml4_Mapping:
153         return snprintf(buf, len, "x86_64 PML4 Mapping (x86_64 PML4 cap @%p, "
154                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
155                                   cap->u.vnode_x86_64_pml4_mapping.frame,
156                                   cap->u.vnode_x86_64_pml4_mapping.pte,
157                                   cap->u.vnode_x86_64_pml4_mapping.pte_count);
158
159     case ObjType_VNode_x86_64_pdpt_Mapping:
160         return snprintf(buf, len, "x86_64 PDPT Mapping (x86_64 PDPT cap @%p, "
161                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
162                                   cap->u.vnode_x86_64_pdpt_mapping.frame,
163                                   cap->u.vnode_x86_64_pdpt_mapping.pte,
164                                   cap->u.vnode_x86_64_pdpt_mapping.pte_count);
165
166     case ObjType_VNode_x86_64_pdir_Mapping:
167         return snprintf(buf, len, "x86_64 PDIR Mapping (x86_64 PDIR cap @%p, "
168                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
169                                   cap->u.vnode_x86_64_pdir_mapping.frame,
170                                   cap->u.vnode_x86_64_pdir_mapping.pte,
171                                   cap->u.vnode_x86_64_pdir_mapping.pte_count);
172
173     case ObjType_VNode_x86_64_ptable_Mapping:
174         return snprintf(buf, len, "x86_64 PTABLE Mapping (x86_64 PTABLE cap @%p, "
175                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
176                                   cap->u.vnode_x86_64_ptable_mapping.frame,
177                                   cap->u.vnode_x86_64_ptable_mapping.pte,
178                                   cap->u.vnode_x86_64_ptable_mapping.pte_count);
179
180     case ObjType_VNode_x86_32_pdpt_Mapping:
181         return snprintf(buf, len, "x86_32 PDPT Mapping (x86_32 PDPT cap @%p, "
182                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
183                                   cap->u.vnode_x86_32_pdpt_mapping.frame,
184                                   cap->u.vnode_x86_32_pdpt_mapping.pte,
185                                   cap->u.vnode_x86_32_pdpt_mapping.pte_count);
186
187     case ObjType_VNode_x86_32_pdir_Mapping:
188         return snprintf(buf, len, "x86_32 PDIR Mapping (x86_32 PDIR cap @%p, "
189                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
190                                   cap->u.vnode_x86_32_pdir_mapping.frame,
191                                   cap->u.vnode_x86_32_pdir_mapping.pte,
192                                   cap->u.vnode_x86_32_pdir_mapping.pte_count);
193
194     case ObjType_VNode_x86_32_ptable_Mapping:
195         return snprintf(buf, len, "x86_32 PTABLE Mapping (x86_32 PTABLE cap @%p, "
196                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
197                                   cap->u.vnode_x86_32_ptable_mapping.frame,
198                                   cap->u.vnode_x86_32_ptable_mapping.pte,
199                                   cap->u.vnode_x86_32_ptable_mapping.pte_count);
200
201     case ObjType_VNode_ARM_l1_Mapping:
202         return snprintf(buf, len, "ARM l1 Mapping (ARM l1 cap @%p, "
203                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
204                                   cap->u.vnode_arm_l1_mapping.frame,
205                                   cap->u.vnode_arm_l1_mapping.pte,
206                                   cap->u.vnode_arm_l1_mapping.pte_count);
207
208     case ObjType_VNode_ARM_l2_Mapping:
209         return snprintf(buf, len, "ARM l2 Mapping (ARM l2 cap @%p, "
210                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
211                                   cap->u.vnode_arm_l2_mapping.frame,
212                                   cap->u.vnode_arm_l2_mapping.pte,
213                                   cap->u.vnode_arm_l2_mapping.pte_count);
214
215     case ObjType_VNode_AARCH64_l1_Mapping:
216         return snprintf(buf, len, "AARCH64 l1 Mapping (AARCH64 l1 cap @%p, "
217                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
218                                   cap->u.vnode_aarch64_l1_mapping.frame,
219                                   cap->u.vnode_aarch64_l1_mapping.pte,
220                                   cap->u.vnode_aarch64_l1_mapping.pte_count);
221
222     case ObjType_VNode_AARCH64_l2_Mapping:
223         return snprintf(buf, len, "AARCH64 l2 Mapping (AARCH64 l2 cap @%p, "
224                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
225                                   cap->u.vnode_aarch64_l2_mapping.frame,
226                                   cap->u.vnode_aarch64_l2_mapping.pte,
227                                   cap->u.vnode_aarch64_l2_mapping.pte_count);
228
229     case ObjType_VNode_AARCH64_l3_Mapping:
230         return snprintf(buf, len, "AARCH64 l3 Mapping (AARCH64 l3 cap @%p, "
231                                   "pte @0x%"PRIxLVADDR", pte_count=%hu)",
232                                   cap->u.vnode_aarch64_l3_mapping.frame,
233                                   cap->u.vnode_aarch64_l3_mapping.pte,
234                                   cap->u.vnode_aarch64_l3_mapping.pte_count);
235
236     case ObjType_IRQTable:
237         return snprintf(buf, len, "IRQTable cap");
238
239     case ObjType_IRQDest:
240         return snprintf(buf, len, "IRQDest cap (vec: %"PRIu64", ctrl: %"PRIu64")",
241                 cap->u.irqdest.vector, cap->u.irqdest.controller);
242
243     case ObjType_EndPoint:
244         return snprintf(buf, len, "EndPoint cap (disp %p offset 0x%" PRIxLVADDR ")",
245                         cap->u.endpoint.listener, cap->u.endpoint.epoffset);
246
247     case ObjType_IO:
248         return snprintf(buf, len, "IO cap (0x%hx-0x%hx)",
249                         cap->u.io.start, cap->u.io.end);
250
251     case ObjType_Kernel:
252         return snprintf(buf, len, "Kernel cap");
253
254     case ObjType_ID:
255         return snprintf(buf, len, "ID capability (coreid 0x%" PRIxCOREID
256                         " core_local_id 0x%" PRIx32 ")", cap->u.id.coreid,
257                         cap->u.id.core_local_id);
258
259     case ObjType_PerfMon:
260         return snprintf(buf, len, "PerfMon cap");
261
262     case ObjType_Null:
263         return snprintf(buf, len, "Null capability (empty slot)");
264
265     case ObjType_IPI:
266         return snprintf(buf, len, "IPI cap");
267
268     default:
269         return snprintf(buf, len, "UNKNOWN TYPE! (%d)", cap->type);
270     }
271 }
272
273 void caps_trace(const char *func, int line, struct cte *cte, const char *msg)
274 {
275     char cap_buf[512];
276     sprint_cap(cap_buf, 512, &cte->cap);
277
278     char disp_buf[64];
279     if (dcb_current) {
280         dispatcher_handle_t handle = dcb_current->disp;
281         struct dispatcher_shared_generic *disp =
282             get_dispatcher_shared_generic(handle);
283         snprintf(disp_buf, 64, "from %.*s", DISP_NAME_LEN, disp->name);
284     }
285     else {
286         strcpy(disp_buf, "no disp");
287     }
288
289     printk(LOG_WARN, "%s: %s:%d: %s %p %s"
290            " (owner:%" PRIuCOREID ", rc:%d/ra:%d/rd:%d)\n",
291            disp_buf, func, line, (msg ? : ""), cte, cap_buf, cte->mdbnode.owner,
292            cte->mdbnode.remote_copies, cte->mdbnode.remote_ancs,
293            cte->mdbnode.remote_descs);
294 }
295
296 /**
297  * ID capability core_local_id counter.
298  */
299 static uint32_t id_cap_counter = 1;
300
301 /**
302  *  Sets #dest equal to #src
303  *
304  * #dest cannot be in use.
305  */
306 static errval_t set_cap(struct capability *dest, struct capability *src)
307 {
308     /* Parameter checking */
309     assert(src  != NULL);
310     assert(dest != NULL);
311
312     // Reserved object bits must always be greater/equal to actual object size
313     assert((1UL << OBJBITS_CTE) >= sizeof(struct cte));
314
315     // Cannot overwrite an already existing cap
316     if (dest->type != ObjType_Null) {
317         return SYS_ERR_SLOT_IN_USE;
318     }
319
320     memcpy(dest, src, sizeof(struct capability));
321     return SYS_ERR_OK;
322 }
323
324 /**
325  * \brief Determine how many objects can be created in a specified region.
326  *
327  * This function computes the number of objects that can be created by a call
328  * to caps_create().
329  *
330  * \param type          Type of objects to create.
331  * \param bits          Size of memory area as 2^bits.
332  * \param objbits       For variable-sized objects, size multiplier as 2^bits.
333  *
334  * \return Number of objects to be created, or zero on error
335  */
336
337 // If you create more capability types you need to deal with them
338 // in the table below.
339 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
340
341 static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
342 {
343     switch(type) {
344     case ObjType_PhysAddr:
345     case ObjType_RAM:
346     case ObjType_Frame:
347     case ObjType_DevFrame:
348         if (objbits > bits) {
349             return 0;
350         } else {
351             return 1UL << (bits - objbits);
352         }
353
354     case ObjType_CNode:
355         if (bits < OBJBITS_CTE || objbits > bits - OBJBITS_CTE) {
356             return 0;
357         } else {
358             return 1UL << (bits - OBJBITS_CTE - objbits);
359         }
360
361     case ObjType_VNode_x86_64_pml4:
362     case ObjType_VNode_x86_64_pdpt:
363     case ObjType_VNode_x86_64_pdir:
364     case ObjType_VNode_x86_64_ptable:
365     case ObjType_VNode_x86_32_pdpt:
366     case ObjType_VNode_x86_32_pdir:
367     case ObjType_VNode_x86_32_ptable:
368     case ObjType_VNode_ARM_l1:
369     case ObjType_VNode_ARM_l2:
370     case ObjType_VNode_AARCH64_l1:
371     case ObjType_VNode_AARCH64_l2:
372     case ObjType_VNode_AARCH64_l3:
373     {
374         size_t objbits_vnode = vnode_objbits(type);
375         if (bits < objbits_vnode) {
376             return 0;
377         } else {
378             return 1UL << (bits - objbits_vnode);
379         }
380     }
381
382     case ObjType_Dispatcher:
383         if (bits < OBJBITS_DISPATCHER) {
384             return 0;
385         } else {
386             return 1UL << (bits - OBJBITS_DISPATCHER);
387         }
388
389     case ObjType_KernelControlBlock:
390         if (bits < OBJBITS_KCB) {
391             return 0;
392         } else {
393             return 1UL << (bits - OBJBITS_KCB);
394         }
395
396     case ObjType_Kernel:
397     case ObjType_IRQTable:
398     case ObjType_IRQDest:
399     case ObjType_IRQSrc:
400     case ObjType_IO:
401     case ObjType_EndPoint:
402     case ObjType_ID:
403     case ObjType_Notify_RCK:
404     case ObjType_Notify_IPI:
405     case ObjType_PerfMon:
406     case ObjType_IPI:
407     case ObjType_VNode_ARM_l1_Mapping:
408     case ObjType_VNode_ARM_l2_Mapping:
409     case ObjType_VNode_AARCH64_l1_Mapping:
410     case ObjType_VNode_AARCH64_l2_Mapping:
411     case ObjType_VNode_AARCH64_l3_Mapping:
412     case ObjType_VNode_x86_64_pml4_Mapping:
413     case ObjType_VNode_x86_64_pdpt_Mapping:
414     case ObjType_VNode_x86_64_pdir_Mapping:
415     case ObjType_VNode_x86_64_ptable_Mapping:
416     case ObjType_VNode_x86_32_pdpt_Mapping:
417     case ObjType_VNode_x86_32_pdir_Mapping:
418     case ObjType_VNode_x86_32_ptable_Mapping:
419     case ObjType_DevFrame_Mapping:
420     case ObjType_Frame_Mapping:
421         return 1;
422
423     default:
424         panic("invalid type");
425         return 0;
426     }
427 }
428
429 // If you create more capability types you need to deal with them
430 // in the table below.
431 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
432 static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t objsize)
433 {
434     switch(type) {
435     case ObjType_PhysAddr:
436     case ObjType_RAM:
437     case ObjType_Frame:
438     case ObjType_DevFrame:
439         if (objsize > srcsize) {
440             return 0;
441         } else {
442             return srcsize / objsize;
443         }
444
445     case ObjType_CNode:
446         if (srcsize < (1UL << OBJBITS_CTE) || objsize > (srcsize / (1UL << OBJBITS_CTE))) {
447             return 0;
448         } else {
449             return srcsize / objsize / (1UL << OBJBITS_CTE);
450         }
451
452     case ObjType_VNode_x86_64_pml4:
453     case ObjType_VNode_x86_64_pdpt:
454     case ObjType_VNode_x86_64_pdir:
455     case ObjType_VNode_x86_64_ptable:
456     case ObjType_VNode_x86_32_pdpt:
457     case ObjType_VNode_x86_32_pdir:
458     case ObjType_VNode_x86_32_ptable:
459     case ObjType_VNode_ARM_l1:
460     case ObjType_VNode_ARM_l2:
461     case ObjType_VNode_AARCH64_l1:
462     case ObjType_VNode_AARCH64_l2:
463     case ObjType_VNode_AARCH64_l3:
464     {
465         size_t objsize_vnode = 1UL << vnode_objbits(type);
466         if (srcsize < objsize_vnode) {
467             return 0;
468         } else {
469             return srcsize / objsize_vnode;
470         }
471     }
472
473     case ObjType_Dispatcher:
474         if (srcsize < 1UL << OBJBITS_DISPATCHER) {
475             return 0;
476         } else {
477             return srcsize / (1UL << OBJBITS_DISPATCHER);
478         }
479
480     case ObjType_KernelControlBlock:
481         if (srcsize < 1UL << OBJBITS_KCB) {
482             return 0;
483         } else {
484             return srcsize / (1UL << OBJBITS_KCB);
485         }
486
487     case ObjType_Kernel:
488     case ObjType_IRQTable:
489     case ObjType_IRQDest:
490     case ObjType_IRQSrc:
491     case ObjType_IO:
492     case ObjType_EndPoint:
493     case ObjType_ID:
494     case ObjType_Notify_RCK:
495     case ObjType_Notify_IPI:
496     case ObjType_PerfMon:
497     case ObjType_IPI:
498     case ObjType_VNode_ARM_l1_Mapping:
499     case ObjType_VNode_ARM_l2_Mapping:
500     case ObjType_VNode_AARCH64_l1_Mapping:
501     case ObjType_VNode_AARCH64_l2_Mapping:
502     case ObjType_VNode_AARCH64_l3_Mapping:
503     case ObjType_VNode_x86_64_pml4_Mapping:
504     case ObjType_VNode_x86_64_pdpt_Mapping:
505     case ObjType_VNode_x86_64_pdir_Mapping:
506     case ObjType_VNode_x86_64_ptable_Mapping:
507     case ObjType_VNode_x86_32_pdpt_Mapping:
508     case ObjType_VNode_x86_32_pdir_Mapping:
509     case ObjType_VNode_x86_32_ptable_Mapping:
510     case ObjType_DevFrame_Mapping:
511     case ObjType_Frame_Mapping:
512         return 1;
513
514     default:
515         panic("invalid type");
516         return 0;
517     }
518 }
519
520 /**
521  * \brief Initialize the objects for which local caps are about to be created.
522  *
523  * For the meaning of the parameters, see the 'caps_create' function.
524  */
525 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
526
527 static errval_t caps_init_objects(enum objtype type, lpaddr_t lpaddr, uint8_t
528                                   bits, uint8_t objbits, size_t numobjs)
529 {
530     // Virtual address of the memory the kernel object resides in
531     // XXX: A better of doing this,
532     // this is creating caps that the kernel cannot address.
533     // It assumes that the cap is not of the type which will have to zeroed out.
534     lvaddr_t lvaddr;
535     if(lpaddr < PADDR_SPACE_LIMIT) {
536         lvaddr = local_phys_to_mem(lpaddr);
537     } else {
538         lvaddr = 0;
539     }
540
541     switch (type) {
542
543     case ObjType_Frame:
544         trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_BZERO, 1);
545         // XXX: SCC hack, while we don't have a devframe allocator
546         if(lpaddr + ((lpaddr_t)1 << bits) < PADDR_SPACE_LIMIT) {
547             memset((void*)lvaddr, 0, (lvaddr_t)1 << bits);
548         } else {
549             printk(LOG_WARN, "Allocating RAM at 0x%" PRIxLPADDR
550                    " uninitialized\n", lpaddr);
551         }
552         trace_event(TRACE_SUBSYS_KERNEL, TRACE_EVENT_KERNEL_BZERO, 0);
553         break;
554
555     case ObjType_CNode:
556     case ObjType_VNode_ARM_l1:
557     case ObjType_VNode_ARM_l2:
558     case ObjType_VNode_AARCH64_l1:
559     case ObjType_VNode_AARCH64_l2:
560     case ObjType_VNode_AARCH64_l3:
561     case ObjType_VNode_x86_32_ptable:
562     case ObjType_VNode_x86_32_pdir:
563     case ObjType_VNode_x86_32_pdpt:
564     case ObjType_VNode_x86_64_ptable:
565     case ObjType_VNode_x86_64_pdir:
566     case ObjType_VNode_x86_64_pdpt:
567     case ObjType_VNode_x86_64_pml4:
568     case ObjType_Dispatcher:
569     case ObjType_KernelControlBlock:
570         TRACE(KERNEL, BZERO, 1);
571         memset((void*)lvaddr, 0, 1UL << bits);
572         TRACE(KERNEL, BZERO, 0);
573         break;
574
575     default:
576         break;
577
578     }
579
580     return SYS_ERR_OK;
581 }
582
583 /**
584  * \brief Initialize the objects for which local caps are about to be created.
585  *
586  * For the meaning of the parameters, see the 'caps_create' function.
587  */
588 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
589
590 static errval_t caps_zero_objects(enum objtype type, lpaddr_t lpaddr,
591                                   gensize_t objsize, size_t count)
592 {
593     // Virtual address of the memory the kernel object resides in
594     // XXX: A better of doing this,
595     // this is creating caps that the kernel cannot address.
596     // It assumes that the cap is not of the type which will have to zeroed out.
597     lvaddr_t lvaddr;
598     if(lpaddr < PADDR_SPACE_LIMIT) {
599         lvaddr = local_phys_to_mem(lpaddr);
600     } else {
601         lvaddr = 0;
602     }
603
604     switch (type) {
605
606     case ObjType_Frame:
607         TRACE(KERNEL, BZERO, 1);
608         memset((void*)lvaddr, 0, objsize * count);
609         TRACE(KERNEL, BZERO, 0);
610         break;
611
612     case ObjType_CNode:
613     case ObjType_VNode_ARM_l1:
614     case ObjType_VNode_ARM_l2:
615     case ObjType_VNode_AARCH64_l1:
616     case ObjType_VNode_AARCH64_l2:
617     case ObjType_VNode_AARCH64_l3:
618     case ObjType_VNode_x86_32_ptable:
619     case ObjType_VNode_x86_32_pdir:
620     case ObjType_VNode_x86_32_pdpt:
621     case ObjType_VNode_x86_64_ptable:
622     case ObjType_VNode_x86_64_pdir:
623     case ObjType_VNode_x86_64_pdpt:
624     case ObjType_VNode_x86_64_pml4:
625     case ObjType_Dispatcher:
626     case ObjType_KernelControlBlock:
627         TRACE(KERNEL, BZERO, 1);
628         memset((void*)lvaddr, 0, objsize * count);
629         TRACE(KERNEL, BZERO, 0);
630         break;
631
632     default:
633         break;
634
635     }
636
637     return SYS_ERR_OK;
638 }
639
640 /**
641  * \brief Create capabilities to kernel objects.
642  *
643  * This function creates kernel objects of 'type' into the memory
644  * area, based at 'addr' and of size 2^'bits', so they completely fill the
645  * area. For each created kernel object, a capability is created to it and
646  * put consecutively into the array of CTEs pointed to by 'caps'. The array
647  * needs to have the appropriate size to hold all created caps. Some kernel
648  * objects can have a variable size. In that case, 'objbits' should be non-zero
649  * and give the a size multiplier as 2^'objbits'.
650  *
651  * \param type          Type of objects to create.
652  * \param addr          Base address in the local address space.
653  * \param bits          Size of memory area as 2^bits.
654  * \param objbits       For variable-sized objects, size multiplier as 2^bits.
655  * \param numobjs       Number of objects to be created, from caps_numobjs()
656  * \param dest_caps     Pointer to array of CTEs to hold created caps.
657  *
658  * \return Error code
659  */
660 // If you create more capability types you need to deal with them
661 // in the table below.
662 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
663
664 static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
665                             uint8_t objbits, size_t numobjs, coreid_t owner,
666                             struct cte *dest_caps)
667 {
668     errval_t err;
669
670     /* Parameter checking */
671     assert(dest_caps != NULL);
672     assert(type != ObjType_Null);
673     assert(type < ObjType_Num);
674     assert(numobjs > 0);
675     assert(!type_is_mapping(type));
676
677     genpaddr_t genpaddr = local_phys_to_gen_phys(lpaddr);
678
679     // Virtual address of the memory the kernel object resides in
680     // XXX: A better of doing this,
681     // this is creating caps that the kernel cannot address.
682     // It assumes that the cap is not of the type which will have to zeroed out.
683     lvaddr_t lvaddr;
684     if(lpaddr < PADDR_SPACE_LIMIT) {
685         lvaddr = local_phys_to_mem(lpaddr);
686     } else {
687         lvaddr = 0;
688     }
689
690     /* Initialize the created capability */
691     struct capability src_cap;
692     memset(&src_cap, 0, sizeof(struct capability));
693     src_cap.type = type;
694     // XXX: Handle rights!
695     src_cap.rights = CAPRIGHTS_ALLRIGHTS;
696
697     // XXX: zeroing twice?! -SG, 2016-04-18
698     if (owner == my_core_id) {
699         // If we're creating new local objects, they need to be initialized
700         err = caps_init_objects(type, lpaddr, bits, objbits, numobjs);
701         if (err_is_fail(err)) {
702             return err;
703         }
704     }
705
706     size_t dest_i = 0;
707     err = SYS_ERR_OK;
708
709     /* Set the type specific fields and insert into #dest_caps */
710     switch(type) {
711     case ObjType_Frame:
712         TRACE(KERNEL, BZERO, 1);
713         // XXX: SCC hack, while we don't have a devframe allocator
714         if(lpaddr + ((lpaddr_t)1 << bits) < PADDR_SPACE_LIMIT) {
715             memset((void*)lvaddr, 0, (lvaddr_t)1 << bits);
716         } else {
717             printk(LOG_WARN, "Allocating RAM at 0x%" PRIxLPADDR
718                    " uninitialized\n", lpaddr);
719         }
720         TRACE(KERNEL, BZERO, 0);
721         for(dest_i = 0; dest_i < numobjs; dest_i++) {
722             // Initialize type specific fields
723             src_cap.u.frame.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
724             src_cap.u.frame.bytes = 1UL << objbits;
725             assert((get_size(&src_cap) & BASE_PAGE_MASK) == 0);
726             // Insert the capabilities
727             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
728             if (err_is_fail(err)) {
729                 break;
730             }
731         }
732         break;
733
734     case ObjType_PhysAddr:
735         for(dest_i = 0; dest_i < numobjs; dest_i++) {
736             // Initialize type specific fields
737             src_cap.u.physaddr.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
738             src_cap.u.physaddr.bytes = 1UL << objbits;
739             // Insert the capabilities
740             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
741             if (err_is_fail(err)) {
742                 break;
743             }
744         }
745         break;
746
747     case ObjType_RAM:
748         for(dest_i = 0; dest_i < numobjs; dest_i++) {
749             // Initialize type specific fields
750             src_cap.u.ram.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
751             src_cap.u.ram.bytes = 1UL << objbits;
752             // Insert the capabilities
753             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
754             if (err_is_fail(err)) {
755                 break;
756             }
757         }
758         break;
759
760     case ObjType_DevFrame:
761         for(dest_i = 0; dest_i < numobjs; dest_i++) {
762             // Initialize type specific fields
763             src_cap.u.devframe.base = genpaddr + dest_i * ((genpaddr_t)1 << objbits);
764             src_cap.u.devframe.bytes = 1UL << objbits;
765             // Insert the capabilities
766             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
767             if (err_is_fail(err)) {
768                 break;
769             }
770         }
771         break;
772
773     case ObjType_CNode:
774         assert((1UL << OBJBITS_CTE) >= sizeof(struct cte));
775         TRACE(KERNEL, BZERO, 1);
776         memset((void*)lvaddr, 0, 1UL << bits);
777         TRACE(KERNEL, BZERO, 0);
778
779         for(dest_i = 0; dest_i < numobjs; dest_i++) {
780             // Initialize type specific fields
781             src_cap.u.cnode.cnode =
782                 lpaddr + dest_i * ((lpaddr_t)1 << (objbits + OBJBITS_CTE));
783             src_cap.u.cnode.bits = objbits;
784             src_cap.u.cnode.guard = 0;
785             src_cap.u.cnode.guard_size = 0;
786             // XXX: Handle rights!
787             src_cap.u.cnode.rightsmask = CAPRIGHTS_ALLRIGHTS;
788             // Insert the capability
789             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
790             if (err_is_fail(err)) {
791                 break;
792             }
793         }
794         break;
795
796     case ObjType_VNode_ARM_l1:
797     {
798         size_t objbits_vnode = vnode_objbits(type);
799
800         TRACE(KERNEL, BZERO, 1);
801         memset((void*)lvaddr, 0, 1UL << bits);
802         TRACE(KERNEL, BZERO, 0);
803
804         for(dest_i = 0; dest_i < numobjs; dest_i++) {
805             // Initialize type specific fields
806             src_cap.u.vnode_arm_l1.base =
807                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
808
809 #ifdef __arm__
810             // Insert kernel/mem mappings into new table.
811             paging_make_good(
812                 gen_phys_to_local_phys(
813                     local_phys_to_mem(src_cap.u.vnode_arm_l1.base)
814                 ),
815                 1u << objbits_vnode
816                 );
817 #endif
818
819             // Insert the capability
820             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
821             if (err_is_fail(err)) {
822                 break;
823             }
824         }
825
826         break;
827     }
828
829     case ObjType_VNode_ARM_l2:
830     {
831         size_t objbits_vnode = vnode_objbits(type);
832
833         TRACE(KERNEL, BZERO, 1);
834         memset((void*)lvaddr, 0, 1UL << bits);
835         TRACE(KERNEL, BZERO, 0);
836
837         for(dest_i = 0; dest_i < numobjs; dest_i++) {
838             // Initialize type specific fields
839             src_cap.u.vnode_arm_l2.base =
840                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
841
842             // Insert the capability
843             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
844             if (err_is_fail(err)) {
845                 break;
846             }
847         }
848         break;
849     }
850
851     case ObjType_VNode_AARCH64_l1:
852     {
853         size_t objbits_vnode = vnode_objbits(type);
854
855         TRACE(KERNEL, BZERO, 1);
856         memset((void*)lvaddr, 0, 1UL << bits);
857         TRACE(KERNEL, BZERO, 0);
858
859         for(dest_i = 0; dest_i < numobjs; dest_i++) {
860             // Initialize type specific fields
861             src_cap.u.vnode_aarch64_l1.base =
862                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
863
864 #ifdef __aarch64__
865             // Insert kernel/mem mappings into new table.
866             lpaddr_t var = gen_phys_to_local_phys(src_cap.u.vnode_aarch64_l1.base);
867             paging_make_good(var);
868 #endif
869
870             // Insert the capability
871             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
872             if (err_is_fail(err)) {
873                 break;
874             }
875         }
876
877         break;
878     }
879
880     case ObjType_VNode_AARCH64_l2:
881     {
882         size_t objbits_vnode = vnode_objbits(type);
883
884         TRACE(KERNEL, BZERO, 1);
885         memset((void*)lvaddr, 0, 1UL << bits);
886         TRACE(KERNEL, BZERO, 0);
887
888         for(dest_i = 0; dest_i < numobjs; dest_i++) {
889             // Initialize type specific fields
890             src_cap.u.vnode_aarch64_l2.base =
891                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
892
893             // Insert the capability
894             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
895
896             if (err_is_fail(err)) {
897                 break;
898             }
899         }
900         break;
901     }
902
903     case ObjType_VNode_AARCH64_l3:
904     {
905         size_t objbits_vnode = vnode_objbits(type);
906
907         TRACE(KERNEL, BZERO, 1);
908         memset((void*)lvaddr, 0, 1UL << bits);
909         TRACE(KERNEL, BZERO, 0);
910
911         for(dest_i = 0; dest_i < numobjs; dest_i++) {
912             // Initialize type specific fields
913             src_cap.u.vnode_aarch64_l3.base =
914                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
915
916             // Insert the capability
917             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
918             if (err_is_fail(err)) {
919                 break;
920             }
921         }
922         break;
923     }
924
925     case ObjType_VNode_x86_32_ptable:
926     {
927         size_t objbits_vnode = vnode_objbits(type);
928
929         TRACE(KERNEL, BZERO, 1);
930         memset((void*)lvaddr, 0, 1UL << bits);
931         TRACE(KERNEL, BZERO, 0);
932
933         for(dest_i = 0; dest_i < numobjs; dest_i++) {
934             // Initialize type specific fields
935             src_cap.u.vnode_x86_32_ptable.base =
936                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
937
938             // Insert the capability
939             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
940             if (err_is_fail(err)) {
941                 break;
942             }
943         }
944         break;
945     }
946
947     case ObjType_VNode_x86_32_pdir:
948     {
949         size_t objbits_vnode = vnode_objbits(type);
950
951         TRACE(KERNEL, BZERO, 1);
952         memset((void*)lvaddr, 0, 1UL << bits);
953         TRACE(KERNEL, BZERO, 0);
954
955         for(dest_i = 0; dest_i < numobjs; dest_i++) {
956             // Initialize type specific fields
957             src_cap.u.vnode_x86_32_pdir.base =
958                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
959
960 #if defined(__i386__) && !defined(CONFIG_PAE)
961             // Make it a good PDE by inserting kernel/mem VSpaces
962             lpaddr = gen_phys_to_local_phys(src_cap.u.vnode_x86_32_pdir.base);
963             paging_x86_32_make_good_pdir(lpaddr);
964 #endif
965
966             // Insert the capability
967             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
968             if (err_is_fail(err)) {
969                 break;
970             }
971         }
972         break;
973     }
974
975     case ObjType_VNode_x86_32_pdpt:
976     {
977         size_t objbits_vnode = vnode_objbits(type);
978
979         TRACE(KERNEL, BZERO, 1);
980         memset((void*)lvaddr, 0, 1UL << bits);
981         TRACE(KERNEL, BZERO, 0);
982
983         for(dest_i = 0; dest_i < numobjs; dest_i++) {
984             // Initialize type specific fields
985             src_cap.u.vnode_x86_32_pdir.base =
986                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
987
988 #if defined(__i386__) && defined(CONFIG_PAE)
989             // Make it a good PDPTE by inserting kernel/mem VSpaces
990             lpaddr_t var =
991                 gen_phys_to_local_phys(src_cap.u.vnode_x86_32_pdpt.base);
992             paging_x86_32_make_good_pdpte(var);
993 #endif
994
995             // Insert the capability
996             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
997             if (err_is_fail(err)) {
998                 break;
999             }
1000         }
1001         break;
1002     }
1003
1004     case ObjType_VNode_x86_64_ptable:
1005     {
1006         size_t objbits_vnode = vnode_objbits(type);
1007
1008         TRACE(KERNEL, BZERO, 1);
1009         memset((void*)lvaddr, 0, 1UL << bits);
1010         TRACE(KERNEL, BZERO, 0);
1011
1012         for(dest_i = 0; dest_i < numobjs; dest_i++) {
1013             // Initialize type specific fields
1014             src_cap.u.vnode_x86_64_ptable.base =
1015                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1016
1017             // Insert the capability
1018             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
1019             if (err_is_fail(err)) {
1020                 break;
1021             }
1022         }
1023         break;
1024     }
1025
1026     case ObjType_VNode_x86_64_pdir:
1027     {
1028         size_t objbits_vnode = vnode_objbits(type);
1029
1030         TRACE(KERNEL, BZERO, 1);
1031         memset((void*)lvaddr, 0, 1UL << bits);
1032         TRACE(KERNEL, BZERO, 0);
1033
1034         for(dest_i = 0; dest_i < numobjs; dest_i++) {
1035             // Initialize type specific fields
1036             src_cap.u.vnode_x86_64_pdir.base =
1037                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1038
1039             // Insert the capability
1040             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
1041             if (err_is_fail(err)) {
1042                 break;
1043             }
1044         }
1045         break;
1046     }
1047
1048     case ObjType_VNode_x86_64_pdpt:
1049     {
1050         size_t objbits_vnode = vnode_objbits(type);
1051
1052         TRACE(KERNEL, BZERO, 1);
1053         memset((void*)lvaddr, 0, 1UL << bits);
1054         TRACE(KERNEL, BZERO, 0);
1055
1056         for(dest_i = 0; dest_i < numobjs; dest_i++) {
1057             // Initialize type specific fields
1058             src_cap.u.vnode_x86_64_pdpt.base =
1059                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1060
1061             // Insert the capability
1062             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
1063             if (err_is_fail(err)) {
1064                 break;
1065             }
1066         }
1067         break;
1068     }
1069
1070     case ObjType_VNode_x86_64_pml4:
1071     {
1072         size_t objbits_vnode = vnode_objbits(type);
1073
1074         TRACE(KERNEL, BZERO, 1);
1075         memset((void*)lvaddr, 0, 1UL << bits);
1076         TRACE(KERNEL, BZERO, 0);
1077
1078         for(dest_i = 0; dest_i < numobjs; dest_i++) {
1079             // Initialize type specific fields
1080             src_cap.u.vnode_x86_64_pml4.base =
1081                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1082
1083 #if defined(__x86_64__) || defined(__k1om__)
1084             // Make it a good PML4 by inserting kernel/mem VSpaces
1085             lpaddr_t var = gen_phys_to_local_phys(src_cap.u.vnode_x86_64_pml4.base);
1086             paging_x86_64_make_good_pml4(var);
1087 #endif
1088
1089             // Insert the capability
1090             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
1091             if (err_is_fail(err)) {
1092                 break;
1093             }
1094         }
1095
1096         break;
1097     }
1098
1099     case ObjType_Dispatcher:
1100         assert((1UL << OBJBITS_DISPATCHER) >= sizeof(struct dcb));
1101         TRACE(KERNEL, BZERO, 1);
1102         memset((void*)lvaddr, 0, 1UL << bits);
1103         TRACE(KERNEL, BZERO, 0);
1104
1105         for(dest_i = 0; dest_i < numobjs; dest_i++) {
1106             // Initialize type specific fields
1107             src_cap.u.dispatcher.dcb = (struct dcb *)
1108                 (lvaddr + dest_i * (1UL << OBJBITS_DISPATCHER));
1109             // Insert the capability
1110             err = set_cap(&dest_caps[dest_i].cap, &src_cap);
1111             if (err_is_fail(err)) {
1112                 break;
1113             }
1114         }
1115         break;
1116
1117     case ObjType_ID:
1118         // ID type does not refer to a kernel object
1119         assert(lpaddr  == 0);
1120         assert(bits    == 0);
1121         assert(objbits == 0);
1122         assert(numobjs == 1);
1123
1124         // Prevent wrap around
1125         if (id_cap_counter >= UINT32_MAX) {
1126             return SYS_ERR_ID_SPACE_EXHAUSTED;
1127         }
1128
1129         // Generate a new ID, core_local_id monotonically increases
1130         src_cap.u.id.coreid = my_core_id;
1131         src_cap.u.id.core_local_id = id_cap_counter++;
1132
1133         // Insert the capability
1134         err = set_cap(&dest_caps->cap, &src_cap);
1135         break;
1136
1137     case ObjType_IO:
1138         src_cap.u.io.start = 0;
1139         src_cap.u.io.end   = 65535;
1140         /* fall through */
1141
1142     case ObjType_Kernel:
1143     case ObjType_IPI:
1144     case ObjType_IRQTable:
1145     case ObjType_IRQDest:
1146     case ObjType_IRQSrc:
1147     case ObjType_EndPoint:
1148     case ObjType_Notify_RCK:
1149     case ObjType_Notify_IPI:
1150     case ObjType_PerfMon:
1151         // These types do not refer to a kernel object
1152         assert(lpaddr  == 0);
1153         assert(bits    == 0);
1154         assert(objbits == 0);
1155         assert(numobjs == 1);
1156
1157         // Insert the capability
1158         err = set_cap(&dest_caps->cap, &src_cap);
1159         if (err_is_ok(err)) {
1160             dest_i = 1;
1161         }
1162         break;
1163
1164     case ObjType_KernelControlBlock:
1165         assert((1UL << OBJBITS_KCB) >= sizeof(struct dcb));
1166
1167         for(size_t i = 0; i < numobjs; i++) {
1168             // Initialize type specific fields
1169             src_cap.u.kernelcontrolblock.kcb = (struct kcb *)
1170                 (lvaddr + i * (1UL << OBJBITS_KCB));
1171             // Insert the capability
1172             err = set_cap(&dest_caps[i].cap, &src_cap);
1173             if (err_is_fail(err)) {
1174                 return err;
1175             }
1176         }
1177         return SYS_ERR_OK;
1178
1179     default:
1180         panic("Unhandled capability type or capability of this type cannot"
1181               " be created");
1182     }
1183
1184     if (err_is_fail(err)) {
1185         // Revert the partially initialized caps to zero
1186         for (size_t i = 0; i < dest_i; i++) {
1187             memset(&dest_caps[i], 0, sizeof(dest_caps[i]));
1188         }
1189         return err;
1190     }
1191     else {
1192         // Set the owner for all the new caps
1193         for (size_t i = 0; i < dest_i; i++) {
1194             dest_caps[i].mdbnode.owner = owner;
1195         }
1196     }
1197
1198     return SYS_ERR_OK;
1199 }
1200
1201 /**
1202  * \brief Create capabilities to kernel objects.
1203  *
1204  * This function creates 'count' kernel objects of 'type' into the memory
1205  * area, based at 'addr' and of size 'objsize'. For each created kernel
1206  * object, a capability is created to it and put consecutively into the array
1207  * of CTEs pointed to by 'caps'. The array needs to have the appropriate size
1208  * to hold all created caps. Some kernel objects can have a variable size. In
1209  * that case, 'objsize' should be non-zero. and give the size multiplier. *
1210  *
1211  * \param type          Type of objects to create.
1212  * \param lpaddr        Base address in the local address space.
1213  * \param size          Size of memory area as bytes.
1214  * \param objsize       For variable-sized objects, size in bytes.
1215  * \param count         Number of objects to be created
1216  *                      (count <= caps_max_numobjs(type, size, objsize))
1217  * \param dest_caps     Pointer to array of CTEs to hold created caps.
1218  *
1219  * \return Error code
1220  */
1221 // If you create more capability types you need to deal with them
1222 // in the table below.
1223 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
1224
1225 static errval_t caps_create2(enum objtype type, lpaddr_t lpaddr, gensize_t size,
1226                              gensize_t objsize, size_t count, coreid_t owner,
1227                              struct cte *dest_caps)
1228 {
1229     errval_t err;
1230
1231     /* Parameter checking */
1232     assert(dest_caps != NULL);
1233     assert(type != ObjType_Null);
1234     assert(type < ObjType_Num);
1235     assert(count > 0);
1236     assert(objsize > 0 && objsize % BASE_PAGE_SIZE == 0);
1237     assert(!type_is_mapping(type));
1238
1239     genpaddr_t genpaddr = local_phys_to_gen_phys(lpaddr);
1240
1241     // Virtual address of the memory the kernel object resides in
1242     // XXX: A better of doing this,
1243     // this is creating caps that the kernel cannot address.
1244     // It assumes that the cap is not of the type which will have to zeroed out.
1245     lvaddr_t lvaddr;
1246     if(lpaddr < PADDR_SPACE_LIMIT) {
1247         lvaddr = local_phys_to_mem(lpaddr);
1248     } else {
1249         lvaddr = 0;
1250     }
1251
1252     /* Initialize the created capability */
1253     struct capability temp_cap;
1254     memset(&temp_cap, 0, sizeof(struct capability));
1255     temp_cap.type = type;
1256     // XXX: Handle rights!
1257     temp_cap.rights = CAPRIGHTS_ALLRIGHTS;
1258
1259     if (owner == my_core_id) {
1260         // If we're creating new local objects, they need to be initialized
1261         err = caps_zero_objects(type, lpaddr, objsize, count);
1262         if (err_is_fail(err)) {
1263             return err;
1264         }
1265     }
1266
1267     size_t dest_i = 0;
1268     err = SYS_ERR_OK;
1269
1270     /* Set the type specific fields and insert into #dest_caps */
1271     switch(type) {
1272     case ObjType_Frame:
1273         for(dest_i = 0; dest_i < count; dest_i++) {
1274             // Initialize type specific fields
1275             temp_cap.u.frame.base = genpaddr + dest_i * objsize;
1276             temp_cap.u.frame.bytes = objsize;
1277             assert((get_size(&temp_cap) & BASE_PAGE_MASK) == 0);
1278             // Insert the capability
1279             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1280             if (err_is_fail(err)) {
1281                 break;
1282             }
1283         }
1284         break;
1285
1286     case ObjType_PhysAddr:
1287         for(dest_i = 0; dest_i < count; dest_i++) {
1288             // Initialize type specific fields
1289             temp_cap.u.physaddr.base = genpaddr + dest_i * objsize;
1290             temp_cap.u.physaddr.bytes = objsize;
1291             // Insert the capability
1292             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1293             if (err_is_fail(err)) {
1294                 break;
1295             }
1296         }
1297         break;
1298
1299     case ObjType_RAM:
1300         for(dest_i = 0; dest_i < count; dest_i++) {
1301             // Initialize type specific fields
1302             temp_cap.u.ram.base = genpaddr + dest_i * objsize;
1303             temp_cap.u.ram.bytes = objsize;
1304             // Insert the capabilities
1305             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1306             if (err_is_fail(err)) {
1307                 break;
1308             }
1309         }
1310         break;
1311
1312     case ObjType_DevFrame:
1313         for(dest_i = 0; dest_i < count; dest_i++) {
1314             // Initialize type specific fields
1315             temp_cap.u.devframe.base = genpaddr + dest_i * objsize;
1316             temp_cap.u.devframe.bytes = objsize;
1317             // Insert the capabilities
1318             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1319             if (err_is_fail(err)) {
1320                 break;
1321             }
1322         }
1323         break;
1324
1325     case ObjType_CNode:
1326         assert((1UL << OBJBITS_CTE) >= sizeof(struct cte));
1327         // TODO: make CNodes not be power-of-two sized
1328         // (deferred to new CSpace layout)
1329         assert((1UL << log2cl(objsize)) == objsize);
1330
1331         for(dest_i = 0; dest_i < count; dest_i++) {
1332             // Initialize type specific fields
1333             temp_cap.u.cnode.cnode =
1334                 lpaddr + dest_i * ((lpaddr_t)1 << OBJBITS_CTE) * objsize;
1335             temp_cap.u.cnode.bits = log2cl(objsize);
1336             temp_cap.u.cnode.guard = 0;
1337             temp_cap.u.cnode.guard_size = 0;
1338             // XXX: Handle rights!
1339             temp_cap.u.cnode.rightsmask = CAPRIGHTS_ALLRIGHTS;
1340             // Insert the capability
1341             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1342             if (err_is_fail(err)) {
1343                 break;
1344             }
1345         }
1346         break;
1347
1348     case ObjType_VNode_ARM_l1:
1349     {
1350         size_t objbits_vnode = vnode_objbits(type);
1351
1352         for(dest_i = 0; dest_i < count; dest_i++) {
1353             // Initialize type specific fields
1354             temp_cap.u.vnode_arm_l1.base =
1355                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1356
1357 #ifdef __arm__
1358             // Insert kernel/mem mappings into new table.
1359             paging_make_good(
1360                 gen_phys_to_local_phys(
1361                     local_phys_to_mem(temp_cap.u.vnode_arm_l1.base)
1362                 ),
1363                 1u << objbits_vnode
1364                 );
1365 #endif
1366
1367             // Insert the capability
1368             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1369             if (err_is_fail(err)) {
1370                 break;
1371             }
1372         }
1373
1374         break;
1375     }
1376
1377     case ObjType_VNode_ARM_l2:
1378     {
1379         size_t objbits_vnode = vnode_objbits(type);
1380
1381         for(dest_i = 0; dest_i < count; dest_i++) {
1382             // Initialize type specific fields
1383             temp_cap.u.vnode_arm_l2.base =
1384                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1385
1386             // Insert the capability
1387             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1388             if (err_is_fail(err)) {
1389                 break;
1390             }
1391         }
1392         break;
1393     }
1394
1395     case ObjType_VNode_AARCH64_l1:
1396     {
1397         size_t objbits_vnode = vnode_objbits(type);
1398
1399         for(dest_i = 0; dest_i < count; dest_i++) {
1400             // Initialize type specific fields
1401             temp_cap.u.vnode_aarch64_l1.base =
1402                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1403
1404 #ifdef __aarch64__
1405             // Insert kernel/mem mappings into new table.
1406             lpaddr_t var = gen_phys_to_local_phys(temp_cap.u.vnode_aarch64_l1.base);
1407             paging_make_good(var);
1408 #endif
1409
1410             // Insert the capability
1411             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1412             if (err_is_fail(err)) {
1413                 break;
1414             }
1415         }
1416
1417         break;
1418     }
1419
1420     case ObjType_VNode_AARCH64_l2:
1421     {
1422         size_t objbits_vnode = vnode_objbits(type);
1423
1424         for(dest_i = 0; dest_i < count; dest_i++) {
1425             // Initialize type specific fields
1426             temp_cap.u.vnode_aarch64_l2.base =
1427                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1428
1429             // Insert the capability
1430             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1431
1432             if (err_is_fail(err)) {
1433                 break;
1434             }
1435         }
1436         break;
1437     }
1438
1439     case ObjType_VNode_AARCH64_l3:
1440     {
1441         size_t objbits_vnode = vnode_objbits(type);
1442
1443         for(dest_i = 0; dest_i < count; dest_i++) {
1444             // Initialize type specific fields
1445             temp_cap.u.vnode_aarch64_l3.base =
1446                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1447
1448             // Insert the capability
1449             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1450             if (err_is_fail(err)) {
1451                 break;
1452             }
1453         }
1454         break;
1455     }
1456
1457     case ObjType_VNode_x86_32_ptable:
1458     {
1459         size_t objbits_vnode = vnode_objbits(type);
1460
1461         for(dest_i = 0; dest_i < count; dest_i++) {
1462             // Initialize type specific fields
1463             temp_cap.u.vnode_x86_32_ptable.base =
1464                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1465
1466             // Insert the capability
1467             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1468             if (err_is_fail(err)) {
1469                 break;
1470             }
1471         }
1472         break;
1473     }
1474
1475     case ObjType_VNode_x86_32_pdir:
1476     {
1477         size_t objbits_vnode = vnode_objbits(type);
1478
1479         for(dest_i = 0; dest_i < count; dest_i++) {
1480             // Initialize type specific fields
1481             temp_cap.u.vnode_x86_32_pdir.base =
1482                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1483
1484 #if defined(__i386__) && !defined(CONFIG_PAE)
1485             // Make it a good PDE by inserting kernel/mem VSpaces
1486             lpaddr = gen_phys_to_local_phys(temp_cap.u.vnode_x86_32_pdir.base);
1487             paging_x86_32_make_good_pdir(lpaddr);
1488 #endif
1489
1490             // Insert the capability
1491             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1492             if (err_is_fail(err)) {
1493                 break;
1494             }
1495         }
1496         break;
1497     }
1498
1499     case ObjType_VNode_x86_32_pdpt:
1500     {
1501         size_t objbits_vnode = vnode_objbits(type);
1502
1503         for(dest_i = 0; dest_i < count; dest_i++) {
1504             // Initialize type specific fields
1505             temp_cap.u.vnode_x86_32_pdir.base =
1506                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1507
1508 #if defined(__i386__) && defined(CONFIG_PAE)
1509             // Make it a good PDPTE by inserting kernel/mem VSpaces
1510             lpaddr_t var =
1511                 gen_phys_to_local_phys(temp_cap.u.vnode_x86_32_pdpt.base);
1512             paging_x86_32_make_good_pdpte(var);
1513 #endif
1514
1515             // Insert the capability
1516             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1517             if (err_is_fail(err)) {
1518                 break;
1519             }
1520         }
1521         break;
1522     }
1523
1524     case ObjType_VNode_x86_64_ptable:
1525     {
1526         size_t objbits_vnode = vnode_objbits(type);
1527
1528         for(dest_i = 0; dest_i < count; dest_i++) {
1529             // Initialize type specific fields
1530             temp_cap.u.vnode_x86_64_ptable.base =
1531                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1532
1533             // Insert the capability
1534             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1535             if (err_is_fail(err)) {
1536                 break;
1537             }
1538         }
1539         break;
1540     }
1541
1542     case ObjType_VNode_x86_64_pdir:
1543     {
1544         size_t objbits_vnode = vnode_objbits(type);
1545
1546         for(dest_i = 0; dest_i < count; dest_i++) {
1547             // Initialize type specific fields
1548             temp_cap.u.vnode_x86_64_pdir.base =
1549                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1550
1551             // Insert the capability
1552             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1553             if (err_is_fail(err)) {
1554                 break;
1555             }
1556         }
1557         break;
1558     }
1559
1560     case ObjType_VNode_x86_64_pdpt:
1561     {
1562         size_t objbits_vnode = vnode_objbits(type);
1563
1564         for(dest_i = 0; dest_i < count; dest_i++) {
1565             // Initialize type specific fields
1566             temp_cap.u.vnode_x86_64_pdpt.base =
1567                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1568
1569             // Insert the capability
1570             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1571             if (err_is_fail(err)) {
1572                 break;
1573             }
1574         }
1575         break;
1576     }
1577
1578     case ObjType_VNode_x86_64_pml4:
1579     {
1580         size_t objbits_vnode = vnode_objbits(type);
1581
1582         for(dest_i = 0; dest_i < count; dest_i++) {
1583             // Initialize type specific fields
1584             temp_cap.u.vnode_x86_64_pml4.base =
1585                 genpaddr + dest_i * ((genpaddr_t)1 << objbits_vnode);
1586
1587 #if defined(__x86_64__) || defined(__k1om__)
1588             // Make it a good PML4 by inserting kernel/mem VSpaces
1589             lpaddr_t var = gen_phys_to_local_phys(temp_cap.u.vnode_x86_64_pml4.base);
1590             paging_x86_64_make_good_pml4(var);
1591 #endif
1592
1593             // Insert the capability
1594             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1595             if (err_is_fail(err)) {
1596                 break;
1597             }
1598         }
1599
1600         break;
1601     }
1602
1603     case ObjType_Dispatcher:
1604         assert((1UL << OBJBITS_DISPATCHER) >= sizeof(struct dcb));
1605
1606         for(dest_i = 0; dest_i < count; dest_i++) {
1607             // Initialize type specific fields
1608             temp_cap.u.dispatcher.dcb = (struct dcb *)
1609                 (lvaddr + dest_i * (1UL << OBJBITS_DISPATCHER));
1610             // Insert the capability
1611             err = set_cap(&dest_caps[dest_i].cap, &temp_cap);
1612             if (err_is_fail(err)) {
1613                 break;
1614             }
1615         }
1616         break;
1617
1618     case ObjType_ID:
1619         // ID type does not refer to a kernel object
1620         assert(lpaddr  == 0);
1621         assert(size    == 0);
1622         assert(objsize == 0);
1623         assert(count   == 1);
1624
1625         // Prevent wrap around
1626         if (id_cap_counter >= UINT32_MAX) {
1627             return SYS_ERR_ID_SPACE_EXHAUSTED;
1628         }
1629
1630         // Generate a new ID, core_local_id monotonically increases
1631         temp_cap.u.id.coreid = my_core_id;
1632         temp_cap.u.id.core_local_id = id_cap_counter++;
1633
1634         // Insert the capability
1635         err = set_cap(&dest_caps->cap, &temp_cap);
1636         break;
1637
1638     case ObjType_IO:
1639         temp_cap.u.io.start = 0;
1640         temp_cap.u.io.end   = 65535;
1641         /* fall through */
1642
1643     case ObjType_Kernel:
1644     case ObjType_IPI:
1645     case ObjType_IRQTable:
1646     case ObjType_IRQDest:
1647     case ObjType_IRQSrc:
1648     case ObjType_EndPoint:
1649     case ObjType_Notify_RCK:
1650     case ObjType_Notify_IPI:
1651     case ObjType_PerfMon:
1652         // These types do not refer to a kernel object
1653         assert(lpaddr  == 0);
1654         assert(size    == 0);
1655         assert(objsize == 0);
1656         assert(count   == 1);
1657
1658         // Insert the capability
1659         err = set_cap(&dest_caps->cap, &temp_cap);
1660         if (err_is_ok(err)) {
1661             dest_i = 1;
1662         }
1663         break;
1664
1665     case ObjType_KernelControlBlock:
1666         assert((1UL << OBJBITS_KCB) >= sizeof(struct dcb));
1667
1668         for(size_t i = 0; i < count; i++) {
1669             // Initialize type specific fields
1670             temp_cap.u.kernelcontrolblock.kcb = (struct kcb *)
1671                 (lvaddr + i * (1UL << OBJBITS_KCB));
1672             // Insert the capability
1673             err = set_cap(&dest_caps[i].cap, &temp_cap);
1674             if (err_is_fail(err)) {
1675                 return err;
1676             }
1677         }
1678         return SYS_ERR_OK;
1679
1680     default:
1681         panic("Unhandled capability type or capability of this type cannot"
1682               " be created");
1683     }
1684
1685     if (err_is_fail(err)) {
1686         // Revert the partially initialized caps to zero
1687         for (size_t i = 0; i < dest_i; i++) {
1688             memset(&dest_caps[i], 0, sizeof(dest_caps[i]));
1689         }
1690         return err;
1691     }
1692     else {
1693         // Set the owner for all the new caps
1694         for (size_t i = 0; i < dest_i; i++) {
1695             dest_caps[i].mdbnode.owner = owner;
1696         }
1697     }
1698
1699     return SYS_ERR_OK;
1700 }
1701
1702 /**
1703  * Look up a capability.
1704  *
1705  * Starting from #cnode_cap, recursively lookup the capability at #cptr
1706  * with #vbits.
1707  *
1708  * \bug Handle rights
1709  */
1710 errval_t caps_lookup_slot(struct capability *cnode_cap, capaddr_t cptr,
1711                           uint8_t vbits, struct cte **ret, CapRights rights)
1712 {
1713     TRACE(KERNEL, CAP_LOOKUP_SLOT, 0);
1714     /* parameter checking */
1715     assert(cnode_cap != NULL);
1716
1717     /* Can only resolve CNode type */
1718     if (cnode_cap->type != ObjType_CNode) {
1719         debug(SUBSYS_CAPS, "caps_lookup_slot: Cap to lookup not of type CNode\n"
1720               "cnode_cap->type = %u\n", cnode_cap->type);
1721         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1722         return SYS_ERR_CNODE_TYPE;
1723     }
1724
1725     /* Apply rights to this CNode */
1726     if ((cnode_cap->rights & rights) != rights) {
1727         debug(SUBSYS_CAPS, "caps_lookup_slot: Rights mismatch\n"
1728               "Passed rights = %u, cnode_cap->rights = %u\n",
1729               rights, cnode_cap->rights);
1730         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1731         return SYS_ERR_CNODE_RIGHTS;
1732     }
1733
1734     /* Number of bits resolved by this cnode (guard and bits) */
1735     uint8_t bits_resolved = cnode_cap->u.cnode.bits +
1736         cnode_cap->u.cnode.guard_size;
1737     // All CNodes must resolve at least one bit
1738     assert(bits_resolved > 0);
1739     // If lookup exceeded expected depth then table is malformed
1740     if (bits_resolved > vbits) {
1741         debug(SUBSYS_CAPS, "caps_lookup_slot: Lookup exceeded valid bits\n"
1742               "Cnode bits = %u, guard size = %u, valid bits = %u, bits_resolved = %u\n",
1743               cnode_cap->u.cnode.bits, cnode_cap->u.cnode.guard_size,
1744               vbits, bits_resolved);
1745         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1746         return SYS_ERR_DEPTH_EXCEEDED;
1747     }
1748
1749     /* Guard-check (bit-mask of guard in cptr must match guard in cnode cap) */
1750     capaddr_t cptr_guard = (cptr >> (vbits - cnode_cap->u.cnode.guard_size))
1751         & MASK(cnode_cap->u.cnode.guard_size);
1752     if (cptr_guard != cnode_cap->u.cnode.guard) {
1753         debug(SUBSYS_CAPS, "caps_lookup_slot: guard check failed\n"
1754               "Computed guard = %"PRIuCADDR", "
1755               "Cnode guard = %"PRIxCADDR", bits = %u\n",
1756               cptr_guard, cnode_cap->u.cnode.guard,
1757               cnode_cap->u.cnode.guard_size);
1758         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1759         return SYS_ERR_GUARD_MISMATCH;
1760     }
1761
1762     /* Locate capability in this cnode */
1763     // Offset into the cnode
1764     size_t offset = (cptr >> (vbits - bits_resolved)) &
1765         MASK(cnode_cap->u.cnode.bits);
1766     // The capability at the offset
1767     struct cte *next_slot = caps_locate_slot(cnode_cap->u.cnode.cnode, offset);
1768     // Do not return NULL type capability
1769     if (next_slot->cap.type == ObjType_Null) {
1770         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1771         return SYS_ERR_CAP_NOT_FOUND;
1772     }
1773
1774     /* Number of bits left to resolve */
1775     int bitsleft = vbits - bits_resolved;
1776     // If all bits have been resolved, return the capability
1777     if(bitsleft == 0) {
1778         *ret = next_slot;
1779         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1780         return SYS_ERR_OK;
1781     }
1782
1783     /* If next capability is not of type cnode, return it */
1784     // XXX: Is this consistent?
1785     if (next_slot->cap.type != ObjType_CNode) {
1786         *ret = next_slot;
1787         TRACE(KERNEL, CAP_LOOKUP_SLOT, 1);
1788         return SYS_ERR_OK;
1789     }
1790
1791     /* Descend to next level */
1792     return caps_lookup_slot(&next_slot->cap, cptr, bitsleft, ret, rights);
1793 }
1794
1795 /**
1796  * Wrapper for caps_lookup_slot returning capability instead of cte.
1797  */
1798 errval_t caps_lookup_cap(struct capability *cnode_cap, capaddr_t cptr,
1799                          uint8_t vbits, struct capability **ret, CapRights rights)
1800 {
1801     TRACE(KERNEL, CAP_LOOKUP_CAP, 0);
1802     struct cte *ret_cte;
1803     errval_t err = caps_lookup_slot(cnode_cap, cptr, vbits, &ret_cte, rights);
1804     if (err_is_fail(err)) {
1805         return err;
1806     }
1807     *ret = &ret_cte->cap;
1808     TRACE(KERNEL, CAP_LOOKUP_CAP, 1);
1809     return SYS_ERR_OK;
1810 }
1811
1812 /**
1813  * \brief Create a capability from an existing capability metadata.
1814  *
1815  * Used when sending capabilities across cores. The metadata is sent across
1816  * cores and the receiving monitor can create the new capability on its core.
1817  *
1818  * \bug Does not check that supplied owner matches existing copies of cap.
1819  */
1820 errval_t caps_create_from_existing(struct capability *root, capaddr_t cnode_cptr,
1821                                    int cnode_vbits, cslot_t dest_slot, coreid_t owner,
1822                                    struct capability *src)
1823 {
1824     TRACE(KERNEL, CAP_CREATE_FROM_EXISTING, 0);
1825     errval_t err;
1826     struct capability *cnode;
1827     err = caps_lookup_cap(root, cnode_cptr, cnode_vbits, &cnode,
1828                           CAPRIGHTS_READ_WRITE);
1829     if (err_is_fail(err)) {
1830         return err_push(err, SYS_ERR_SLOT_LOOKUP_FAIL);
1831     }
1832     if (cnode->type != ObjType_CNode) {
1833         return SYS_ERR_CNODE_TYPE;
1834     }
1835
1836     struct cte *dest = caps_locate_slot(cnode->u.cnode.cnode, dest_slot);
1837
1838     err = set_cap(&dest->cap, src);
1839     if (err_is_fail(err)) {
1840         return err;
1841     }
1842
1843     dest->mdbnode.owner = owner;
1844
1845     err = mdb_insert(dest);
1846     assert(err_is_ok(err));
1847
1848     struct cte *neighbour = NULL;
1849     if (!neighbour
1850         && (neighbour = mdb_predecessor(dest))
1851         && !is_copy(&dest->cap, &neighbour->cap))
1852     {
1853         neighbour = NULL;
1854     }
1855     if (!neighbour
1856         && (neighbour = mdb_successor(dest))
1857         && !is_copy(&dest->cap, &neighbour->cap))
1858     {
1859         neighbour = NULL;
1860     }
1861
1862     if (neighbour) {
1863         assert(!neighbour->mdbnode.in_delete);
1864         assert(neighbour->mdbnode.owner == owner);
1865 #define CP_ATTR(a) dest->mdbnode.a = neighbour->mdbnode.a
1866         CP_ATTR(locked);
1867         CP_ATTR(remote_copies);
1868         CP_ATTR(remote_ancs);
1869         CP_ATTR(remote_descs);
1870 #undef CP_ATTR
1871     }
1872     else {
1873         dest->mdbnode.locked = false;
1874         if (owner != my_core_id) {
1875             // For foreign caps it does not really matter if ancestors or
1876             // descendants exist
1877             dest->mdbnode.remote_copies = true;
1878             dest->mdbnode.remote_ancs = false;
1879             dest->mdbnode.remote_descs = false;
1880         }
1881         else {
1882             // We just created a new copy of a owned capability from nothing.
1883             // This is either caused by a retype, or by sharing a capability
1884             // that does not care about locality.
1885             // XXX: This should probably be done more explicitly -MN
1886             if (distcap_needs_locality(dest->cap.type)) {
1887                 // Retype, so have ancestors and no descendants
1888                 dest->mdbnode.remote_copies = false;
1889                 dest->mdbnode.remote_ancs = true;
1890                 dest->mdbnode.remote_descs = false;
1891             }
1892             else {
1893                 dest->mdbnode.remote_copies = false;
1894                 dest->mdbnode.remote_ancs = false;
1895                 dest->mdbnode.remote_descs = false;
1896             }
1897         }
1898     }
1899
1900     TRACE_CAP_MSG("created", dest);
1901
1902     TRACE(KERNEL, CAP_CREATE_FROM_EXISTING, 1);
1903     return SYS_ERR_OK;
1904 }
1905
1906 /// Create caps to new kernel objects.
1907 errval_t caps_create_new(enum objtype type, lpaddr_t addr, size_t bits,
1908                          size_t objbits, coreid_t owner, struct cte *caps)
1909 {
1910     TRACE(KERNEL, CAP_CREATE_NEW, 0);
1911     /* Parameter checking */
1912     assert(type != ObjType_EndPoint); // Cap of this type cannot be created
1913
1914     size_t numobjs = caps_numobjs(type, bits, objbits);
1915     assert(numobjs > 0);
1916
1917     /* Create the new capabilities */
1918     errval_t err = caps_create(type, addr, bits, objbits, numobjs, owner, caps);
1919     if (err_is_fail(err)) {
1920         return err;
1921     }
1922
1923     // Handle the mapping database
1924     set_init_mapping(caps, numobjs);
1925
1926     TRACE_CAP_MSG("created", &caps[0]);
1927
1928     TRACE(KERNEL, CAP_CREATE_NEW, 1);
1929     return SYS_ERR_OK;
1930 }
1931
1932 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
1933 /// Retype caps
1934 errval_t caps_retype(enum objtype type, size_t objbits,
1935                      struct capability *dest_cnode, cslot_t dest_slot,
1936                      struct cte *src_cte, bool from_monitor)
1937 {
1938     TRACE(KERNEL, CAP_RETYPE, 0);
1939     size_t numobjs;
1940     uint8_t bits = 0;
1941     genpaddr_t base = 0;
1942     errval_t err;
1943
1944     /* Parameter checking */
1945     assert(type != ObjType_Null);
1946     assert(type < ObjType_Num);
1947
1948     struct capability *src_cap = &src_cte->cap;
1949
1950     TRACE_CAP_MSG("retyping", src_cte);
1951
1952     /* No explicit retypes to Mapping allowed */
1953     if (type_is_mapping(type)) {
1954         return SYS_ERR_RETYPE_MAPPING_EXPLICIT;
1955     }
1956
1957     /* Check retypability */
1958     err = is_retypeable(src_cte, src_cap->type, type, from_monitor);
1959     if (err_is_fail(err)) {
1960         debug(SUBSYS_CAPS, "caps_retype: is_retypeable failed\n");
1961         return err;
1962     }
1963
1964     /* Create Destination caps as per source and destination type */
1965     switch(src_cap->type) {
1966     case ObjType_PhysAddr:
1967         bits = log2cl(src_cap->u.physaddr.bytes);
1968         base = src_cap->u.physaddr.base;
1969         break;
1970
1971     case ObjType_RAM:
1972         bits = log2cl(src_cap->u.ram.bytes);
1973         base = src_cap->u.ram.base;
1974         break;
1975
1976     case ObjType_Dispatcher:
1977         bits = base = 0;
1978         break;
1979
1980     case ObjType_Frame:
1981         bits = log2cl(src_cap->u.frame.bytes);
1982         base = src_cap->u.frame.base;
1983         break;
1984
1985     case ObjType_DevFrame:
1986         bits = log2cl(src_cap->u.devframe.bytes);
1987         base = src_cap->u.devframe.base;
1988         break;
1989
1990     default:
1991         panic("Unreachable case");
1992     }
1993
1994     /* determine number of objects to be created */
1995     numobjs = caps_numobjs(type, bits, objbits);
1996
1997     if (numobjs == 0) {
1998         debug(SUBSYS_CAPS, "caps_retype: numobjs == 0\n");
1999         return SYS_ERR_INVALID_SIZE_BITS;
2000     }
2001    // debug(SUBSYS_CAPS, "caps_retype: numobjs == %d\n", (int)numobjs);
2002
2003     /* check that destination slots all fit within target cnode */
2004     if (dest_slot + numobjs > (1UL << dest_cnode->u.cnode.bits)) {
2005         debug(SUBSYS_CAPS, "caps_retype: dest slots don't fit in cnode\n");
2006         return SYS_ERR_SLOTS_INVALID;
2007     }
2008
2009     /* check that destination slots are all empty */
2010     debug(SUBSYS_CAPS, "caps_retype: dest cnode is %#" PRIxLPADDR
2011           " dest_slot %d\n",
2012           dest_cnode->u.cnode.cnode, (int)dest_slot);
2013     for (cslot_t i = 0; i < numobjs; i++) {
2014         if (caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot + i)->cap.type
2015             != ObjType_Null) {
2016             debug(SUBSYS_CAPS, "caps_retype: dest slot %d in use\n",
2017                   (int)(dest_slot + i));
2018             return SYS_ERR_SLOTS_IN_USE;
2019         }
2020     }
2021
2022     /* create new caps */
2023     struct cte *dest_cte =
2024         caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot);
2025     err = caps_create(type, base, bits, objbits, numobjs, my_core_id, dest_cte);
2026     if (err_is_fail(err)) {
2027         debug(SUBSYS_CAPS, "caps_retype: failed to create a dest cap\n");
2028         return err_push(err, SYS_ERR_RETYPE_CREATE);
2029     }
2030
2031     /* special initialisation for endpoint caps */
2032     if (type == ObjType_EndPoint) {
2033         assert(src_cap->type == ObjType_Dispatcher);
2034         assert(numobjs == 1);
2035         struct capability *dest_cap = &dest_cte->cap;
2036         dest_cap->u.endpoint.listener = src_cap->u.dispatcher.dcb;
2037     }
2038
2039     /* Handle mapping */
2040     for (size_t i = 0; i < numobjs; i++) {
2041         mdb_insert(&dest_cte[i]);
2042     }
2043
2044 #ifdef TRACE_PMEM_CAPS
2045     for (size_t i = 0; i < numobjs; i++) {
2046         TRACE_CAP_MSG("created", &dest_cte[i]);
2047     }
2048 #endif
2049
2050     TRACE(KERNEL, CAP_RETYPE, 1);
2051     return SYS_ERR_OK;
2052 }
2053
2054 STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
2055 /// Retype caps
2056 /// Create `count` new caps of `type` from `offset` in src, and put them in
2057 /// `dest_cnode` starting at `dest_slot`.
2058 errval_t caps_retype2(enum objtype type, gensize_t objsize, size_t count,
2059                       struct capability *dest_cnode, cslot_t dest_slot,
2060                       struct cte *src_cte, gensize_t offset,
2061                       bool from_monitor)
2062 {
2063     TRACE(KERNEL, CAP_RETYPE, 0);
2064     size_t maxobjs;
2065     genpaddr_t base = 0;
2066     gensize_t size = 0;
2067     errval_t err;
2068
2069     /* Parameter checking */
2070     assert(type != ObjType_Null);
2071     assert(type < ObjType_Num);
2072     if (type == ObjType_Null || type >= ObjType_Num) {
2073         return SYS_ERR_INVALID_RETYPE;
2074     }
2075
2076     struct capability *src_cap = &src_cte->cap;
2077
2078     TRACE_CAP_MSG("retyping", src_cte);
2079
2080     /* No explicit retypes to Mapping allowed */
2081     if (type_is_mapping(type)) {
2082         return SYS_ERR_RETYPE_MAPPING_EXPLICIT;
2083     }
2084
2085     /* Check retypability */
2086     err = is_retypeable(src_cte, src_cap->type, type, from_monitor);
2087     if (err_is_fail(err)) {
2088         printk(LOG_NOTE, "caps_retype2: is_retypeable failed: %"PRIuERRV"\n", err);
2089         debug(SUBSYS_CAPS, "caps_retype2: is_retypeable failed\n");
2090         return err;
2091     }
2092     // from here: src cap type is one of these.
2093     assert(src_cap->type == ObjType_PhysAddr ||
2094            src_cap->type == ObjType_RAM ||
2095            src_cap->type == ObjType_Dispatcher ||
2096            src_cap->type == ObjType_Frame ||
2097            src_cap->type == ObjType_DevFrame);
2098
2099     if (src_cap->type != ObjType_Dispatcher) {
2100         base = get_address(src_cap);
2101         size = get_size(src_cap);
2102     }
2103
2104     /* check that size is multiple of BASE_PAGE_SIZE */
2105     if (objsize % BASE_PAGE_SIZE != 0) {
2106         return SYS_ERR_INVALID_SIZE;
2107     }
2108     assert(objsize % BASE_PAGE_SIZE == 0);
2109
2110     maxobjs = caps_max_numobjs(type, get_size(src_cap), objsize);
2111     // TODO: debug(SUBSYS_CAPS
2112     printk(LOG_NOTE, "maximum possible new object count: %zu\n", maxobjs);
2113
2114     if (maxobjs == 0) {
2115         debug(SUBSYS_CAPS, "caps_retype2: maxobjs == 0\n");
2116         return SYS_ERR_INVALID_SIZE;
2117     }
2118
2119     if (count > maxobjs) {
2120         debug(SUBSYS_CAPS, "caps_retype2: maxobjs = %zu, count = %zu\n", maxobjs, count);
2121         return SYS_ERR_RETYPE_INVALID_COUNT;
2122     }
2123     // from here: count <= maxobjs
2124     assert(count <= maxobjs);
2125
2126     /* check that we can create `count` objs from `offset` in source, and
2127      * update base accordingly */
2128     if (src_cap->type != ObjType_Dispatcher) {
2129         // TODO: check that this is the only condition on offset
2130         if (offset + count * objsize > get_size(src_cap)) {
2131             debug(SUBSYS_CAPS, "caps_retype2: cannot create all %zu objects"
2132                     " of size 0x%zx from offset 0x%zx\n", count, objsize, offset);
2133             return SYS_ERR_RETYPE_INVALID_OFFSET;
2134         }
2135         // adjust base address for new objects
2136         base += offset;
2137     }
2138
2139     /* check that destination slots all fit within target cnode */
2140     if (dest_slot + count > (1UL << dest_cnode->u.cnode.bits)) {
2141         debug(SUBSYS_CAPS, "caps_retype2: dest slots don't fit in cnode\n");
2142         return SYS_ERR_SLOTS_INVALID;
2143     }
2144
2145     /* check that destination slots are all empty */
2146     debug(SUBSYS_CAPS, "caps_retype2: dest cnode is %#" PRIxLPADDR
2147           " dest_slot %d\n",
2148           dest_cnode->u.cnode.cnode, (int)dest_slot);
2149     for (cslot_t i = 0; i < count; i++) {
2150         if (caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot + i)->cap.type
2151             != ObjType_Null) {
2152             debug(SUBSYS_CAPS, "caps_retype2: dest slot %d in use\n",
2153                   (int)(dest_slot + i));
2154             return SYS_ERR_SLOTS_IN_USE;
2155         }
2156     }
2157
2158     /* create new caps */
2159     struct cte *dest_cte =
2160         caps_locate_slot(dest_cnode->u.cnode.cnode, dest_slot);
2161     err = caps_create2(type, base, size, objsize, count, my_core_id, dest_cte);
2162     if (err_is_fail(err)) {
2163         debug(SUBSYS_CAPS, "caps_retype2: failed to create a dest cap\n");
2164         return err_push(err, SYS_ERR_RETYPE_CREATE);
2165     }
2166
2167     /* special initialisation for endpoint caps */
2168     if (type == ObjType_EndPoint) {
2169         assert(src_cap->type == ObjType_Dispatcher);
2170         assert(count == 1);
2171         struct capability *dest_cap = &dest_cte->cap;
2172         dest_cap->u.endpoint.listener = src_cap->u.dispatcher.dcb;
2173     }
2174
2175     /* Handle mapping */
2176     for (size_t i = 0; i < count; i++) {
2177         mdb_insert(&dest_cte[i]);
2178     }
2179
2180 #ifdef TRACE_PMEM_CAPS
2181     for (size_t i = 0; i < count; i++) {
2182         TRACE_CAP_MSG("created", &dest_cte[i]);
2183     }
2184 #endif
2185
2186     TRACE(KERNEL, CAP_RETYPE, 1);
2187     return SYS_ERR_OK;
2188 }
2189
2190
2191 /// Check the validity of a retype operation
2192 errval_t is_retypeable(struct cte *src_cte, enum objtype src_type,
2193                        enum objtype dest_type, bool from_monitor)
2194 {
2195     if (!is_well_founded(src_type, dest_type)) {
2196         return SYS_ERR_INVALID_RETYPE;
2197     } else if (!is_revoked_first(src_cte, src_type)){
2198         printf("err_revoke_first: (%p, %d, %d)\n", src_cte, src_type, dest_type);
2199         return SYS_ERR_REVOKE_FIRST;
2200     } else if (dest_type == ObjType_EndPoint && src_cte->mdbnode.owner == my_core_id) {
2201         // XXX: because of the current "multi-retype" hack for endpoints, a
2202         // dispatcher->endpoint retype can happen irrespective of the existence
2203         // of descendents on any core.
2204         // Howevery, we only do this for locally owned caps as the owner should
2205         // be notified that the cap has remote descendants
2206         return SYS_ERR_OK;
2207     } else if (!from_monitor && (src_cte->mdbnode.owner != my_core_id
2208                                  || src_cte->mdbnode.remote_descs)) {
2209         return SYS_ERR_RETRY_THROUGH_MONITOR;
2210     } else {
2211         return SYS_ERR_OK;
2212     }
2213 }
2214
2215 /// Create copies to a slot within a cnode
2216 errval_t caps_copy_to_cnode(struct cte *dest_cnode_cte, cslot_t dest_slot,
2217                             struct cte *src_cte, bool mint, uintptr_t param1,
2218                             uintptr_t param2)
2219 {
2220     /* Parameter Checking */
2221     assert(dest_cnode_cte->cap.type == ObjType_CNode);
2222
2223     struct cte *dest_cte;
2224     dest_cte = caps_locate_slot(dest_cnode_cte->cap.u.cnode.cnode, dest_slot);
2225     return caps_copy_to_cte(dest_cte, src_cte, mint, param1, param2);
2226
2227 }
2228
2229 /// Create copies to a cte
2230 errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
2231                           uintptr_t param1, uintptr_t param2)
2232 {
2233     errval_t err;
2234     /* Parameter checking */
2235     // Null checking
2236     assert(dest_cte != NULL);
2237     assert(src_cte != NULL);
2238
2239     struct capability *src_cap  = &src_cte->cap;
2240     struct capability *dest_cap = &dest_cte->cap;
2241     // NULL caps cannot be copied/minted
2242     if (src_cap->type == ObjType_Null) {
2243         return SYS_ERR_CAP_NOT_FOUND;
2244     }
2245     // Parameters should be 0 if not minting
2246     if (!mint) {
2247         assert(param1 == 0);
2248         assert(param2 == 0);
2249     }
2250
2251     assert(!src_cte->mdbnode.in_delete);
2252
2253     /* Insert #source_cap into #dest_cap */
2254     err = set_cap(dest_cap, src_cap);
2255     if (err_is_fail(err)) {
2256         return err;
2257     }
2258
2259     /* Transfer MDB attributes that must be equal for all copies */
2260 #define CP_ATTR(at) dest_cte->mdbnode.at = src_cte->mdbnode.at
2261     CP_ATTR(owner);
2262     CP_ATTR(locked);
2263     CP_ATTR(remote_copies);
2264     CP_ATTR(remote_ancs);
2265     CP_ATTR(remote_descs);
2266 #undef CP_ATTR
2267
2268     /* Copy is done */
2269     if(!mint) {
2270         TRACE_CAP_MSG("copied to", dest_cte);
2271         // Handle mapping here only for non-mint operations
2272         // (mint can change eq fields which would make the early insertion
2273         // invalid in some cases)
2274         mdb_insert(dest_cte);
2275         return SYS_ERR_OK;
2276     }
2277     else {
2278         TRACE_CAP_MSG("minting to", dest_cte);
2279     }
2280
2281     /* For minting, set the specified parameters */
2282     // Process source-specific parameters for minting
2283     // XXX: If failure, revert the insertion
2284     switch(src_cap->type) {
2285     case ObjType_CNode:
2286         if (param2 > CPTR_BITS) {
2287             return SYS_ERR_GUARD_SIZE_OVERFLOW;
2288         }
2289         dest_cap->u.cnode.guard      = param1;
2290         dest_cap->u.cnode.guard_size = param2;
2291         break;
2292
2293     case ObjType_EndPoint:
2294         // XXX: FIXME: check that buffer offset lies wholly within the disp frame
2295         // can't easily enforce this here, because the dispatcher frame may not
2296         // yet be setup
2297 /*        if (param1 < sizeof(struct dispatcher) ||
2298             dest_cap->u.endpoint.listener->disp == NULL ||
2299             param2 < IDC_RECV_LENGTH ||
2300             param1 + sizeof(struct idc_endpoint) + param2 * sizeof(uintptr_t) >
2301             (1UL << dest_cap->u.endpoint.listener->disp_cte.cap.u.frame.bits)) {
2302             return SYS_ERR_INVALID_EPBUF;
2303         }*/
2304         if (param2 < LMP_RECV_HEADER_LENGTH) {
2305             return SYS_ERR_INVALID_EPLEN;
2306         }
2307         dest_cap->u.endpoint.epoffset = param1;
2308         dest_cap->u.endpoint.epbuflen = param2;
2309         break;
2310
2311     case ObjType_IO:
2312         if(src_cap->u.io.start  <= param1) {
2313             dest_cap->u.io.start = param1;
2314         }
2315         if(src_cap->u.io.end  >= param2) {
2316             dest_cap->u.io.end = param2;
2317         }
2318         break;
2319
2320     default:
2321         // Unhandled source type for mint
2322         return SYS_ERR_INVALID_SOURCE_TYPE;
2323     }
2324
2325     // Insert after doing minting operation
2326     mdb_insert(dest_cte);
2327
2328     return SYS_ERR_OK;
2329 }