1/** 2 * \file 3 * \brief Essential capability definitions. 4 */ 5 6/* 7 * Copyright (c) 2007-2012, 2016, ETH Zurich. 8 * Copyright (c) 2015, 2016 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#ifndef BARRELFISH_CAPABILITIES_H 17#define BARRELFISH_CAPABILITIES_H 18 19/* FIXME: OBJBITS and OBJSIZE defines must match sizes in Hamlet's capabilities/caps.hl */ 20 21// Size of CNode entry 22#define OBJBITS_CTE 6 23 24/// Number of entries in L2 CNode in bits 25#define L2_CNODE_BITS 8 26/// Number of entries in L2 CNode 27#define L2_CNODE_SLOTS (1UL << L2_CNODE_BITS) 28 29#ifndef __ASSEMBLER__ 30 31#include <assert.h> 32#include <stdbool.h> 33#include <barrelfish_kpi/types.h> 34 35#define CAPRIGHTS_READ (1 << 0) 36#define CAPRIGHTS_WRITE (1 << 1) 37#define CAPRIGHTS_EXECUTE (1 << 2) 38#define CAPRIGHTS_GRANT (1 << 3) 39#define CAPRIGHTS_IDENTIFY (1 << 4) 40#define CAPRIGHTS_NUM 5 41 42#define CAPRIGHTS_ALLRIGHTS ((1 << CAPRIGHTS_NUM) - 1) 43#define CAPRIGHTS_READ_WRITE (CAPRIGHTS_READ | CAPRIGHTS_WRITE) 44#define CAPRIGHTS_NORIGHTS 0 45 46typedef uint8_t CapRights; 47#define PRIuCAPRIGHTS PRIu8 48#define PRIxCAPRIGHTS PRIx8 49 50struct dcb; 51 52// capbits needs CapRights and dcb; 53#include <barrelfish_kpi/capbits.h> 54 55STATIC_ASSERT((L2_CNODE_SLOTS * (1UL << OBJBITS_CTE)) == OBJSIZE_L2CNODE, 56 "l2 cnode size doesn't match cte size"); 57 58static inline bool type_is_vnode(enum objtype type) 59{ 60 STATIC_ASSERT(50 == ObjType_Num, "Check VNode definitions"); 61 62 return (type == ObjType_VNode_x86_64_pml4 || 63 type == ObjType_VNode_x86_64_pdpt || 64 type == ObjType_VNode_x86_64_pdir || 65 type == ObjType_VNode_x86_64_ptable || 66 type == ObjType_VNode_x86_32_pdpt || 67 type == ObjType_VNode_x86_32_pdir || 68 type == ObjType_VNode_x86_32_ptable || 69 type == ObjType_VNode_AARCH64_l3 || 70 type == ObjType_VNode_AARCH64_l2 || 71 type == ObjType_VNode_AARCH64_l1 || 72 type == ObjType_VNode_AARCH64_l0 || 73 type == ObjType_VNode_ARM_l2 || 74 type == ObjType_VNode_ARM_l1 75 ); 76} 77 78static inline bool type_is_vroot(enum objtype type) 79{ 80 STATIC_ASSERT(50 == ObjType_Num, "Check VNode definitions"); 81 82 return (type == ObjType_VNode_x86_64_pml4 || 83#ifdef CONFIG_PAE 84 type == ObjType_VNode_x86_32_pdpt || 85#else 86 type == ObjType_VNode_x86_32_pdir || 87#endif 88 type == ObjType_VNode_AARCH64_l0 || 89 type == ObjType_VNode_ARM_l1 90 ); 91} 92/** 93 * Return size of vnode in bits. This is the size of a page table page. 94 * 95 * @param type Object type. 96 * 97 * @return Number of bits a VNode object occupies. 98 */ 99static inline size_t vnode_objbits(enum objtype type) 100{ 101 // This function should be emitted by hamlet or somesuch. 102 STATIC_ASSERT(50 == ObjType_Num, "Check VNode definitions"); 103 104 if (type == ObjType_VNode_x86_64_pml4 || 105 type == ObjType_VNode_x86_64_pdpt || 106 type == ObjType_VNode_x86_64_pdir || 107 type == ObjType_VNode_x86_64_ptable || 108 type == ObjType_VNode_x86_32_pdpt || 109 type == ObjType_VNode_x86_32_pdir || 110 type == ObjType_VNode_x86_32_ptable) 111 { 112 return 12; 113 } 114 else if (type == ObjType_VNode_AARCH64_l0 || 115 type == ObjType_VNode_AARCH64_l1 || 116 type == ObjType_VNode_AARCH64_l2 || 117 type == ObjType_VNode_AARCH64_l3) 118 { 119 return 12; 120 } 121 else if (type == ObjType_VNode_ARM_l1) 122 { 123 return 14; 124 } 125 else if (type == ObjType_VNode_ARM_l2) 126 { 127 return 10; 128 } 129 130 assert(0 && !"Page table size unknown."); 131 return 0; 132} 133 134/** 135 * Return size of vnode in bytes. This is the size of a page table page. 136 * 137 * @param type Object type. 138 * 139 * @return Size of a VNode in bytes. 140 * 141 * XXX: this should probably just do 1UL << vnode_objbits(type) for vnode 142 * objtypes -SG, 2016-07-06. 143 */ 144static inline size_t vnode_objsize(enum objtype type) 145{ 146 // This function should be emitted by hamlet or somesuch. 147 STATIC_ASSERT(50 == ObjType_Num, "Check VNode definitions"); 148 149 if (type == ObjType_VNode_x86_64_pml4 || 150 type == ObjType_VNode_x86_64_pdpt || 151 type == ObjType_VNode_x86_64_pdir || 152 type == ObjType_VNode_x86_64_ptable || 153 type == ObjType_VNode_x86_32_pdpt || 154 type == ObjType_VNode_x86_32_pdir || 155 type == ObjType_VNode_x86_32_ptable) 156 { 157 // XXX: cannot use BASE_PAGE_SIZE here because asmoffsets does not 158 // include the right files 159 return 4096; // BASE_PAGE_SIZE 160 } 161 else if (type == ObjType_VNode_AARCH64_l0 || 162 type == ObjType_VNode_AARCH64_l1 || 163 type == ObjType_VNode_AARCH64_l2 || 164 type == ObjType_VNode_AARCH64_l3) 165 { 166 return 4096; 167 } 168 else if (type == ObjType_VNode_ARM_l1) 169 { 170 // ARMv7 L1 page table is 16kB. 171 return 16384; 172 } 173 else if (type == ObjType_VNode_ARM_l2) 174 { 175 return 1024; 176 } 177 178 assert(0 && !"Page table size unknown."); 179 return 0; 180} 181 182/** 183 * Return number of page table entries for vnode in bits. 184 * @param type Object type. 185 * @return Number of page table entries in bits 186 */ 187static inline size_t vnode_entry_bits(enum objtype type) { 188 // This function should be emitted by hamlet or somesuch. 189 STATIC_ASSERT(50 == ObjType_Num, "Check VNode definitions"); 190 191 if (type == ObjType_VNode_x86_64_pml4 || 192 type == ObjType_VNode_x86_64_pdpt || 193 type == ObjType_VNode_x86_64_pdir || 194 type == ObjType_VNode_x86_64_ptable) 195 { 196 return 9; // log2(X86_64_PTABLE_SIZE) 197 } 198#ifdef CONFIG_PAE 199 if (type == ObjType_VNode_x86_32_pdpt) 200 { 201 return 2; // log2(X86_32_PDPTE_SIZE) 202 } 203 else if (type == ObjType_VNode_x86_32_pdir || 204 type == ObjType_VNode_x86_32_ptable) 205 { 206 return 9; // log2(X86_32_PTABLE_SIZE) == log2(X86_32_PDIR_SIZE) 207 } 208#else 209 if (type == ObjType_VNode_x86_32_pdir || 210 type == ObjType_VNode_x86_32_ptable) 211 { 212 return 10; // log2(X86_32_PTABLE_SIZE) == log2(X86_32_PDIR_SIZE) 213 } 214#endif 215 216 if (type == ObjType_VNode_AARCH64_l0 || 217 type == ObjType_VNode_AARCH64_l1 || 218 type == ObjType_VNode_AARCH64_l2 || 219 type == ObjType_VNode_AARCH64_l3) 220 { 221 return 9; // log2(ARM_MAX_ENTRIES) 222 } 223 224 if (type == ObjType_VNode_ARM_l2) 225 { 226 return 9; // log2(ARM_L2_MAX_ENTRIES) 227 } 228 else if (type == ObjType_VNode_ARM_l1) 229 { 230 return 12; // log2(ARM_L1_MAX_ENTRIES) 231 } 232 233 assert(!"unknown page table type"); 234 return 0; 235} 236 237/** 238 * Return number of slots for cnode in bits. 239 * @param type Object type. 240 * @return Number of page table entries in bits 241 */ 242static inline size_t cnode_get_slots(struct capability *cnode) { 243 STATIC_ASSERT(50 == ObjType_Num, "Check CNode definitions"); 244 245 switch (cnode->type) { 246 case ObjType_L1CNode: 247 return cnode->u.l1cnode.allocated_bytes / (1UL << OBJBITS_CTE); 248 case ObjType_L2CNode: 249 return L2_CNODE_SLOTS; 250 default: 251 assert(!"not a cnode"); 252 return 0; 253 } 254} 255 256static inline enum objtype get_mapping_type(enum objtype captype) 257{ 258 STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all mapping types"); 259 260 switch (captype) { 261 case ObjType_Frame: 262 return ObjType_Frame_Mapping; 263 case ObjType_DevFrame: 264 return ObjType_DevFrame_Mapping; 265 case ObjType_VNode_x86_64_pml4: 266 return ObjType_VNode_x86_64_pml4_Mapping; 267 case ObjType_VNode_x86_64_pdpt: 268 return ObjType_VNode_x86_64_pdpt_Mapping; 269 case ObjType_VNode_x86_64_pdir: 270 return ObjType_VNode_x86_64_pdir_Mapping; 271 case ObjType_VNode_x86_64_ptable: 272 return ObjType_VNode_x86_64_ptable_Mapping; 273 case ObjType_VNode_x86_32_pdpt: 274 return ObjType_VNode_x86_32_pdpt_Mapping; 275 case ObjType_VNode_x86_32_pdir: 276 return ObjType_VNode_x86_32_pdir_Mapping; 277 case ObjType_VNode_x86_32_ptable: 278 return ObjType_VNode_x86_32_ptable_Mapping; 279 case ObjType_VNode_ARM_l1: 280 return ObjType_VNode_ARM_l1_Mapping; 281 case ObjType_VNode_ARM_l2: 282 return ObjType_VNode_ARM_l2_Mapping; 283 case ObjType_VNode_AARCH64_l0: 284 return ObjType_VNode_AARCH64_l0_Mapping; 285 case ObjType_VNode_AARCH64_l1: 286 return ObjType_VNode_AARCH64_l1_Mapping; 287 case ObjType_VNode_AARCH64_l2: 288 return ObjType_VNode_AARCH64_l2_Mapping; 289 case ObjType_VNode_AARCH64_l3: 290 return ObjType_VNode_AARCH64_l3_Mapping; 291 /* all other types are not mappable */ 292 default: 293 return ObjType_Null; 294 } 295} 296 297static inline bool type_is_mapping(enum objtype type) 298{ 299 STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all mapping types"); 300 301 switch (type) { 302 case ObjType_Frame_Mapping: 303 case ObjType_DevFrame_Mapping: 304 case ObjType_VNode_x86_64_pml4_Mapping: 305 case ObjType_VNode_x86_64_pdpt_Mapping: 306 case ObjType_VNode_x86_64_pdir_Mapping: 307 case ObjType_VNode_x86_64_ptable_Mapping: 308 case ObjType_VNode_x86_32_pdpt_Mapping: 309 case ObjType_VNode_x86_32_pdir_Mapping: 310 case ObjType_VNode_x86_32_ptable_Mapping: 311 case ObjType_VNode_ARM_l1_Mapping: 312 case ObjType_VNode_ARM_l2_Mapping: 313 case ObjType_VNode_AARCH64_l0_Mapping: 314 case ObjType_VNode_AARCH64_l1_Mapping: 315 case ObjType_VNode_AARCH64_l2_Mapping: 316 case ObjType_VNode_AARCH64_l3_Mapping: 317 return true; 318 319 /* all other types are not mapping types */ 320 default: 321 return false; 322 } 323} 324 325static inline bool type_is_mappable(enum objtype type) 326{ 327 STATIC_ASSERT(50 == ObjType_Num, "Knowledge of all mappable types"); 328 329 switch (type) { 330 case ObjType_Frame: 331 case ObjType_DevFrame: 332 case ObjType_VNode_x86_64_pml4: 333 case ObjType_VNode_x86_64_pdpt: 334 case ObjType_VNode_x86_64_pdir: 335 case ObjType_VNode_x86_64_ptable: 336 case ObjType_VNode_x86_32_pdpt: 337 case ObjType_VNode_x86_32_pdir: 338 case ObjType_VNode_x86_32_ptable: 339 case ObjType_VNode_ARM_l1: 340 case ObjType_VNode_ARM_l2: 341 case ObjType_VNode_AARCH64_l0: 342 case ObjType_VNode_AARCH64_l1: 343 case ObjType_VNode_AARCH64_l2: 344 case ObjType_VNode_AARCH64_l3: 345 return true; 346 347 /* all other types are not mappable */ 348 default: 349 return false; 350 } 351} 352 353/** 354 * CNode capability commands. 355 */ 356enum cnode_cmd { 357 CNodeCmd_Copy, ///< Copy capability 358 CNodeCmd_Mint, ///< Mint capability 359 CNodeCmd_Retype, ///< Retype capability 360 CNodeCmd_Delete, ///< Delete capability 361 CNodeCmd_Revoke, ///< Revoke capability 362 CNodeCmd_Create, ///< Create capability 363 CNodeCmd_GetState, ///< Get distcap state for capability 364 CNodeCmd_GetSize, ///< Get Size of CNode, only applicable for L1 Cnode 365 CNodeCmd_Resize, ///< Resize CNode, only applicable for L1 Cnode 366}; 367 368enum vnode_cmd { 369 VNodeCmd_Map, 370 VNodeCmd_Unmap, 371 VNodeCmd_Identify, ///< Return the physical address of the VNode 372 VNodeCmd_ModifyFlags, 373}; 374 375/** 376 * Mapping commands 377 */ 378enum mapping_cmd { 379 MappingCmd_Modify, 380 MappingCmd_Destroy, 381}; 382 383/** 384 * Kernel capabilities commands. 385 * Monitor's invocations of capability operations 386 * which the kernel will not subject to cross core checks 387 */ 388enum kernel_cmd { 389 KernelCmd_Spawn_core, ///< Spawn a new kernel 390 KernelCmd_Identify_cap, ///< Return the meta data of a capability 391 KernelCmd_Identify_domains_cap, ///< Return the meta data of another domain's capability 392 KernelCmd_Remote_relations, ///< Set capability as being remote 393 KernelCmd_Cap_has_relations, ///< Return presence of local relations 394 KernelCmd_Create_cap, ///< Create a new capability 395 KernelCmd_Copy_existing, 396 KernelCmd_Get_core_id, ///< Returns the id of the core the domain is on 397 KernelCmd_Get_arch_id, ///< Returns arch id of caller's core 398 KernelCmd_Nullify_cap, ///< Set the capability to NULL allowed it to be reused 399 KernelCmd_Setup_trace, ///< Set up trace buffer 400 KernelCmd_Register, ///< Register monitor notify endpoint 401 KernelCmd_Domain_Id, ///< Set domain ID of dispatcher 402 KernelCmd_Get_cap_owner, 403 KernelCmd_Set_cap_owner, 404 KernelCmd_Lock_cap, 405 KernelCmd_Unlock_cap, 406 KernelCmd_Delete_last, 407 KernelCmd_Delete_foreigns, 408 KernelCmd_Revoke_mark_target, 409 KernelCmd_Revoke_mark_relations, 410 KernelCmd_Delete_step, 411 KernelCmd_Clear_step, 412 KernelCmd_Retype, 413 KernelCmd_Has_descendants, 414 KernelCmd_Is_retypeable, 415 KernelCmd_Sync_timer, 416 KernelCmd_IPI_Register, 417 KernelCmd_IPI_Delete, 418 KernelCmd_GetGlobalPhys, 419 KernelCmd_Add_kcb, ///< add extra kcb to be scheduled 420 KernelCmd_Remove_kcb, ///< remove kcb from scheduling ring 421 KernelCmd_Suspend_kcb_sched, ///< suspend/resume kcb scheduler 422 KernelCmd_Get_platform, ///< Get architecture platform 423 KernelCmd_Count 424}; 425 426/** 427 * Specific commands for dispatcher capabilities. 428 */ 429enum dispatcher_cmd { 430 DispatcherCmd_Setup, ///< Set dispatcher parameters 431 DispatcherCmd_Properties, ///< Set dispatcher properties 432 DispatcherCmd_PerfMon, ///< Performance monitoring 433 DispatcherCmd_SetupGuest, ///< Set up the DCB of a guest domain 434 DispatcherCmd_DumpPTables, ///< Dump hw page tables of dispatcher 435 DispatcherCmd_DumpCapabilities, ///< Dump capabilities of dispatcher 436 DispatcherCmd_Vmread, ///< Execute vmread on the current and active VMCS 437 DispatcherCmd_Vmwrite, ///< Execute vmwrite on the current and active VMCS 438 DispatcherCmd_Vmptrld, ///< Make VMCS clear and inactive 439 DispatcherCmd_Vmclear, ///< Make VMCS current and active 440}; 441 442/** 443 * Frame capability commands. 444 */ 445enum frame_cmd { 446 FrameCmd_Identify, ///< Return physical address of frame 447}; 448 449/** 450 * Kernel control block commands. 451 */ 452enum kcb_cmd { 453 KCBCmd_Clone = FrameCmd_Identify+1, ///< Duplicate core_data 454}; 455 456/** 457 * RAM capability commands 458 */ 459enum ram_cmd { 460 RAMCmd_Identify, ///< Return physical address of frame 461}; 462 463/** 464 * IRQ Table capability commands. 465 */ 466enum irqtable_cmd { 467 IRQTableCmd_Alloc, ///< Allocate new vector (XXX: HACK: this is x86 specific) 468 IRQTableCmd_AllocDestCap, ///< Allocate new dest capability (XXX: HACK: this is x86 specific) 469 IRQTableCmd_Set, ///< Set endpoint for IRQ# notifications 470 IRQTableCmd_Delete ///< Remove notification endpoint for IRQ# 471}; 472 473/** 474 * IRQ Vector commands. 475 */ 476 477enum irqdest_cmd { 478 IRQDestCmd_Connect, ///< Connect this capability to a messaging channel 479 IRQDestCmd_GetVector, ///< Return the local interrupt vector 480 IRQDestCmd_GetCpu ///< Return the local interrupt vector 481}; 482 483/** 484 * IRQ Vector commands. 485 */ 486 487enum irqsrc_cmd { 488 IRQSrcCmd_GetVecStart, ///< Return vector range start 489 IRQSrcCmd_GetVecEnd ///< Return vector range high 490}; 491 492 493/** 494 * IO capability commands. 495 */ 496enum io_cmd { 497 IOCmd_Outb, ///< Output byte to port 498 IOCmd_Outw, ///< Output word to port 499 IOCmd_Outd, ///< Output double word to port 500 IOCmd_Inb, ///< Input byte from port 501 IOCmd_Inw, ///< Input word from port 502 IOCmd_Ind ///< Input double word from port 503}; 504 505/** 506 * Notify capability commands. 507 */ 508enum notify_cmd { 509 NotifyCmd_Send 510}; 511 512 513/** 514 * Performance monitoring commands. 515 * Seems to be already included in the Dispatcher capability. 516 */ 517enum perfmon_cmd { 518 PerfmonCmd_Activate, ///< Activate performance counters 519 PerfmonCmd_Deactivate, ///< Deactivate performance counters 520 PerfmonCmd_Write ///< Read current performance counter values 521}; 522 523 524/** 525 * ID capability commands. 526 */ 527enum id_cmd { 528 IDCmd_Identify ///< Return system-wide unique ID 529}; 530 531/** 532 * IPI capability commands 533 */ 534 535enum ipi_cmd { 536 IPICmd_Send_Start, ///< Send Startup IPI to a destination core 537 IPICmd_Send_Init, ///< Send Init IPI to a destination core 538}; 539/** 540 * Maximum command ordinal. 541 */ 542#define CAP_MAX_CMD KernelCmd_Count 543 544/** 545 * \brief Values returned from frame identify invocation 546 */ 547struct frame_identity { 548 genpaddr_t base; ///< Physical base address of frame 549 gensize_t bytes; ///< Size of frame, in bytes 550}; 551 552/** 553 * \brief Values returned from the VNode identify invocation 554 */ 555struct vnode_identity { 556 genpaddr_t base; ///< Physical base address of the VNode 557 uint8_t type; ///< Type of VNode 558}; 559 560#endif // __ASSEMBLER__ 561 562#endif // BARRELFISH_CAPABILITIES_H 563