mach_darwin.odin 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. package darwin
  2. foreign import mach "system:System"
  3. import "core:c"
  4. import "base:intrinsics"
  5. mach_port_t :: distinct c.uint
  6. task_t :: mach_port_t
  7. semaphore_t :: distinct u64
  8. kern_return_t :: distinct c.int
  9. thread_act_t :: distinct u64
  10. thread_state_t :: distinct ^u32
  11. thread_list_t :: [^]thread_act_t
  12. vm_region_recurse_info_t :: distinct ^i32
  13. task_info_t :: distinct ^i32
  14. MACH_PORT_NULL :: 0
  15. MACH_PORT_DEAD :: ~mach_port_t(0)
  16. MACH_MSG_PORT_DESCRIPTOR :: 0
  17. X86_THREAD_STATE32 :: 1
  18. X86_THREAD_STATE64 :: 4
  19. ARM_THREAD_STATE64 :: 6
  20. mach_msg_option_t :: distinct i32
  21. name_t :: distinct cstring
  22. vm_map_t :: mach_port_t
  23. mem_entry_name_port_t :: mach_port_t
  24. ipc_space_t :: mach_port_t
  25. thread_t :: mach_port_t
  26. vm_size_t :: distinct c.uintptr_t
  27. vm_address_t :: vm_offset_t
  28. vm_offset_t :: distinct c.uintptr_t
  29. // NOTE(beau): typedefed to int in the original headers
  30. boolean_t :: b32
  31. vm_prot_t :: distinct c.int
  32. vm_inherit_t :: distinct c.uint
  33. mach_port_name_t :: distinct c.uint
  34. mach_port_right_t :: distinct c.uint
  35. sync_policy_t :: distinct c.int
  36. mach_msg_port_descriptor_t :: struct {
  37. name: mach_port_t,
  38. _: u32,
  39. using _: bit_field u32 {
  40. _: u32 | 16,
  41. disposition: u32 | 8,
  42. type: u32 | 8,
  43. },
  44. }
  45. Task_Port_Type :: enum u32 {
  46. Kernel = 1,
  47. Host,
  48. Name,
  49. Bootstrap,
  50. Seatbelt = 7,
  51. Access = 9,
  52. }
  53. Bootstrap_Error :: enum u32 {
  54. Success,
  55. Not_Privileged = 1100,
  56. Name_In_Use = 1101,
  57. Unknown_Service = 1102,
  58. Service_Active = 1103,
  59. Bad_Count = 1104,
  60. No_Memory = 1105,
  61. No_Children = 1106,
  62. }
  63. Msg_Type :: enum u32 {
  64. Unstructured = 0,
  65. Bit = 0,
  66. Boolean = 0,
  67. Integer_16 = 1,
  68. Integer_32 = 2,
  69. Char = 8,
  70. Byte = 9,
  71. Integer_8 = 9,
  72. Real = 10,
  73. Integer_64 = 11,
  74. String = 12,
  75. String_C = 12,
  76. Port_Name = 15,
  77. Move_Receive = 16,
  78. Port_Receive = 16,
  79. Move_Send = 17,
  80. Port_Send = 17,
  81. Move_Send_Once = 18,
  82. Port_Send_Once = 18,
  83. Copy_Send = 19,
  84. Make_Send = 20,
  85. Make_Send_Once = 21,
  86. }
  87. Msg_Header_Bits :: enum u32 {
  88. Zero = 0,
  89. Remote_Mask = 0xff,
  90. Local_Mask = 0xff00,
  91. Migrated = 0x08000000,
  92. Unused = 0x07ff0000,
  93. Complex_Data = 0x10000000,
  94. Complex_Ports = 0x20000000,
  95. Circular = 0x40000000,
  96. Complex = 0x80000000,
  97. }
  98. mach_msg_type_t :: struct {
  99. using _: bit_field u32 {
  100. name: u32 | 8,
  101. size: u32 | 8,
  102. number: u32 | 12,
  103. inline: u32 | 1,
  104. longform: u32 | 1,
  105. deallocate: u32 | 1,
  106. unused: u32 | 1,
  107. },
  108. }
  109. mach_msg_header_t :: struct {
  110. msgh_bits: u32,
  111. msgh_size: u32,
  112. msgh_remote_port: mach_port_t,
  113. msgh_local_port: mach_port_t,
  114. msgh_voucher_port: u32,
  115. msgh_id: i32,
  116. }
  117. mach_msg_body_t :: struct {
  118. msgh_descriptor_count: u32,
  119. }
  120. mach_msg_trailer_t :: struct {
  121. msgh_trailer_type: u32,
  122. msgh_trailer_size: u32,
  123. }
  124. x86_thread_state32_t :: struct {
  125. eax: u32,
  126. ebx: u32,
  127. ecx: u32,
  128. edx: u32,
  129. edi: u32,
  130. esi: u32,
  131. ebp: u32,
  132. esp: u32,
  133. ss: u32,
  134. eflags: u32,
  135. eip: u32,
  136. cs: u32,
  137. ds: u32,
  138. es: u32,
  139. fs: u32,
  140. gs: u32,
  141. }
  142. X86_THREAD_STATE32_COUNT :: size_of(x86_thread_state32_t) / size_of(u32)
  143. x86_thread_state64_t :: struct #packed {
  144. rax: u64,
  145. rbx: u64,
  146. rcx: u64,
  147. rdx: u64,
  148. rdi: u64,
  149. rsi: u64,
  150. rbp: u64,
  151. rsp: u64,
  152. r8: u64,
  153. r9: u64,
  154. r10: u64,
  155. r11: u64,
  156. r12: u64,
  157. r13: u64,
  158. r14: u64,
  159. r15: u64,
  160. rip: u64,
  161. rflags: u64,
  162. cs: u64,
  163. fs: u64,
  164. gs: u64,
  165. }
  166. X86_THREAD_STATE64_COUNT :: size_of(x86_thread_state64_t) / size_of(u32)
  167. arm_thread_state64_t :: struct #packed {
  168. x: [29]u64,
  169. fp: u64,
  170. lr: u64,
  171. sp: u64,
  172. pc: u64,
  173. cpsr: u32,
  174. pad: u32,
  175. }
  176. ARM_THREAD_STATE64_COUNT :: size_of(arm_thread_state64_t) / size_of(u32)
  177. THREAD_IDENTIFIER_INFO :: 4
  178. thread_identifier_info :: struct {
  179. thread_id: u64,
  180. thread_handler: u64,
  181. dispatch_qaddr: u64,
  182. }
  183. THREAD_IDENTIFIER_INFO_COUNT :: size_of(thread_identifier_info) / size_of(u32)
  184. vm_region_submap_info_64 :: struct {
  185. protection: u32,
  186. max_protection: u32,
  187. inheritance: u32,
  188. offset: u64,
  189. user_tag: u32,
  190. pages_residept: u32,
  191. pages_shared_now_private: u32,
  192. pages_swapped_out: u32,
  193. pages_dirtied: u32,
  194. ref_count: u32,
  195. shadow_depth: u16,
  196. external_pager: u8,
  197. share_mode: u8,
  198. is_submap: b32,
  199. behavior: i32,
  200. object_id: u32,
  201. user_wired_count: u16,
  202. pages_reusable: u32,
  203. }
  204. VM_REGION_SUBMAP_INFO_COUNT_64 :: size_of(vm_region_submap_info_64) / size_of(u32)
  205. TASK_DYLD_INFO :: 17
  206. task_dyld_info :: struct {
  207. all_image_info_addr: u64,
  208. all_image_info_size: u64,
  209. all_image_info_format: i32,
  210. }
  211. TASK_DYLD_INFO_COUNT :: size_of(task_dyld_info) / size_of(u32)
  212. dyld_image_info :: struct {
  213. image_load_addr: u64,
  214. image_file_path: cstring,
  215. image_file_mod_date: u64,
  216. }
  217. dyld_uuid_info :: struct {
  218. image_load_addr: u64,
  219. image_uuid: [16]u8,
  220. }
  221. dyld_all_image_infos :: struct {
  222. version: u32,
  223. info_array_count: u32,
  224. info_array: rawptr,
  225. notification: rawptr,
  226. process_detached_from_shared_region: b32,
  227. libSystem_initialized: b32,
  228. dyld_image_load_addr: u64,
  229. jit_info: rawptr,
  230. dyld_version: cstring,
  231. error_message: cstring,
  232. termination_flags: u64,
  233. core_symbolication_shm_page: rawptr,
  234. system_order_flag: u64,
  235. uuid_array_count: u64,
  236. uuid_array: rawptr,
  237. dyld_all_image_infos_addr: u64,
  238. initial_image_count: u64,
  239. error_kind: u64,
  240. error_client_of_dylib_path: cstring,
  241. error_target_dylib_path: cstring,
  242. error_symbol: cstring,
  243. shared_cache_slide: u64,
  244. shared_cache_uuid: [16]u8,
  245. shared_cache_base_addr: u64,
  246. info_array_change_timestamp: u64,
  247. dyld_path: cstring,
  248. notify_ports: [8]mach_port_t,
  249. reserved: [7]u64,
  250. shared_cache_fsid: u64,
  251. shared_cache_fsobjid: u64,
  252. compact_dyld_image_info_addr: u64,
  253. compact_dyld_image_info_size: u64,
  254. platform: u32,
  255. aot_info_count: u32,
  256. aot_info_array: rawptr,
  257. aot_info_array_change_timestamp: u64,
  258. aot_shared_cache_base_address: u64,
  259. aot_shared_cache_uuid: [16]u8,
  260. }
  261. @(default_calling_convention="c")
  262. foreign mach {
  263. mach_task_self :: proc() -> mach_port_t ---
  264. mach_msg :: proc(header: rawptr, option: Msg_Option_Flags, send_size: u32, receive_limit: u32, receive_name: mach_port_t, timeout: u32, notify: mach_port_t) -> Kern_Return ---
  265. mach_msg_send :: proc(header: rawptr) -> Kern_Return ---
  266. mach_vm_allocate :: proc(target_task: task_t, adddress: u64, size: u64, flags: i32) -> Kern_Return ---
  267. mach_vm_deallocate :: proc(target_task: task_t, adddress: ^u64, size: u64) -> Kern_Return ---
  268. mach_vm_remap :: proc(target_task: task_t, page: rawptr, size: u64, mask: u64, flags: i32, src_task: task_t, src_address: u64, copy: b32, cur_protection: ^i32, max_protection: ^i32, inheritance: VM_Inherit) -> Kern_Return ---
  269. mach_vm_region_recurse :: proc(target_task: task_t, address: ^u64, size: ^u64, depth: ^u32, info: vm_region_recurse_info_t, count: ^u32) -> Kern_Return ---
  270. vm_page_size: u64
  271. vm_page_mask: u64
  272. vm_page_shift: i32
  273. mach_port_allocate :: proc(task: task_t, right: Port_Right, name: rawptr) -> Kern_Return ---
  274. mach_port_deallocate :: proc(task: task_t, name: u32) -> Kern_Return ---
  275. mach_port_extract_right :: proc(task: task_t, name: u32, msgt_name: u32, poly: ^mach_port_t, poly_poly: ^mach_port_t) -> Kern_Return ---
  276. task_get_special_port :: proc(task: task_t, port: i32, special_port: ^mach_port_t) -> Kern_Return ---
  277. task_suspend :: proc(task: task_t) -> Kern_Return ---
  278. task_resume :: proc(task: task_t) -> Kern_Return ---
  279. task_threads :: proc(task: task_t, thread_list: ^thread_list_t, list_count: ^u32) -> Kern_Return ---
  280. task_info :: proc(task: task_t, flavor: i32, info: task_info_t, count: ^u32) -> Kern_Return ---
  281. task_terminate :: proc(task: task_t) -> Kern_Return ---
  282. semaphore_create :: proc(task: task_t, semaphore: ^semaphore_t, policy: Sync_Policy, value: c.int) -> Kern_Return ---
  283. semaphore_destroy :: proc(task: task_t, semaphore: semaphore_t) -> Kern_Return ---
  284. semaphore_signal :: proc(semaphore: semaphore_t) -> Kern_Return ---
  285. semaphore_signal_all :: proc(semaphore: semaphore_t) -> Kern_Return ---
  286. semaphore_signal_thread :: proc(semaphore: semaphore_t, thread: thread_t) -> Kern_Return ---
  287. semaphore_wait :: proc(semaphore: semaphore_t) -> Kern_Return ---
  288. thread_get_state :: proc(thread: thread_act_t, flavor: i32, thread_state: thread_state_t, old_state_count: ^u32) -> Kern_Return ---
  289. thread_info :: proc(thread: thread_act_t, flavor: u32, thread_info: ^thread_identifier_info, info_count: ^u32) -> Kern_Return ---
  290. bootstrap_register2 :: proc(bp: mach_port_t, service_name: name_t, sp: mach_port_t, flags: u64) -> Kern_Return ---
  291. bootstrap_look_up :: proc(bp: mach_port_t, service_name: name_t, sp: ^mach_port_t) -> Kern_Return ---
  292. vm_map :: proc(
  293. target_task: vm_map_t,
  294. address: ^vm_address_t,
  295. size: vm_size_t,
  296. mask: vm_address_t,
  297. flags: VM_Flags,
  298. object: mem_entry_name_port_t,
  299. offset: vm_offset_t,
  300. copy: boolean_t,
  301. cur_protection,
  302. max_protection: VM_Prot_Flags,
  303. inheritance: VM_Inherit,
  304. ) -> Kern_Return ---
  305. mach_make_memory_entry :: proc(
  306. target_task: vm_map_t,
  307. size: ^vm_size_t,
  308. offset: vm_offset_t,
  309. permission: VM_Prot_Flags,
  310. object_handle: ^mem_entry_name_port_t,
  311. parent_entry: mem_entry_name_port_t,
  312. ) -> Kern_Return ---
  313. }
  314. Kern_Return :: enum kern_return_t {
  315. Success,
  316. /* Specified address is not currently valid.
  317. */
  318. Invalid_Address,
  319. /* Specified memory is valid, but does not permit the
  320. * required forms of access.
  321. */
  322. Protection_Failure,
  323. /* The address range specified is already in use, or
  324. * no address range of the size specified could be
  325. * found.
  326. */
  327. No_Space,
  328. /* The function requested was not applicable to this
  329. * type of argument, or an argument is invalid
  330. */
  331. Invalid_Argument,
  332. /* The function could not be performed. A catch-all.
  333. */
  334. Failure,
  335. /* A system resource could not be allocated to fulfill
  336. * this request. This failure may not be permanent.
  337. */
  338. Resource_Shortage,
  339. /* The task in question does not hold receive rights
  340. * for the port argument.
  341. */
  342. Not_Receiver,
  343. /* Bogus access restriction.
  344. */
  345. No_Access,
  346. /* During a page fault, the target address refers to a
  347. * memory object that has been destroyed. This
  348. * failure is permanent.
  349. */
  350. Memory_Failure,
  351. /* During a page fault, the memory object indicated
  352. * that the data could not be returned. This failure
  353. * may be temporary; future attempts to access this
  354. * same data may succeed, as defined by the memory
  355. * object.
  356. */
  357. Memory_Error,
  358. /* The receive right is already a member of the portset.
  359. */
  360. Already_In_Set,
  361. /* The receive right is not a member of a port set.
  362. */
  363. Not_In_Set,
  364. /* The name already denotes a right in the task.
  365. */
  366. Name_Exists,
  367. /* The operation was aborted. Ipc code will
  368. * catch this and reflect it as a message error.
  369. */
  370. Aborted,
  371. /* The name doesn't denote a right in the task.
  372. */
  373. Invalid_Name,
  374. /* Target task isn't an active task.
  375. */
  376. Invalid_Task,
  377. /* The name denotes a right, but not an appropriate right.
  378. */
  379. Invalid_Right,
  380. /* A blatant range error.
  381. */
  382. Invalid_Value,
  383. /* Operation would overflow limit on user-references.
  384. */
  385. URefs_Overflow,
  386. /* The supplied (port) capability is improper.
  387. */
  388. Invalid_Capability,
  389. /* The task already has send or receive rights
  390. * for the port under another name.
  391. */
  392. Right_Exists,
  393. /* Target host isn't actually a host.
  394. */
  395. Invalid_Host,
  396. /* An attempt was made to supply "precious" data
  397. * for memory that is already present in a
  398. * memory object.
  399. */
  400. Memory_Present,
  401. /* A page was requested of a memory manager via
  402. * memory_object_data_request for an object using
  403. * a MEMORY_OBJECT_COPY_CALL strategy, with the
  404. * VM_PROT_WANTS_COPY flag being used to specify
  405. * that the page desired is for a copy of the
  406. * object, and the memory manager has detected
  407. * the page was pushed into a copy of the object
  408. * while the kernel was walking the shadow chain
  409. * from the copy to the object. This error code
  410. * is delivered via memory_object_data_error
  411. * and is handled by the kernel (it forces the
  412. * kernel to restart the fault). It will not be
  413. * seen by users.
  414. */
  415. Memory_Data_Moved,
  416. /* A strategic copy was attempted of an object
  417. * upon which a quicker copy is now possible.
  418. * The caller should retry the copy using
  419. * vm_object_copy_quickly. This error code
  420. * is seen only by the kernel.
  421. */
  422. Memory_Restart_Copy,
  423. /* An argument applied to assert processor set privilege
  424. * was not a processor set control port.
  425. */
  426. Invalid_Processor_Set,
  427. /* The specified scheduling attributes exceed the thread's
  428. * limits.
  429. */
  430. Policy_Limit,
  431. /* The specified scheduling policy is not currently
  432. * enabled for the processor set.
  433. */
  434. Invalid_Policy,
  435. /* The external memory manager failed to initialize the
  436. * memory object.
  437. */
  438. Invalid_Object,
  439. /* A thread is attempting to wait for an event for which
  440. * there is already a waiting thread.
  441. */
  442. Already_Waiting,
  443. /* An attempt was made to destroy the default processor
  444. * set.
  445. */
  446. Default_Set,
  447. /* An attempt was made to fetch an exception port that is
  448. * protected, or to abort a thread while processing a
  449. * protected exception.
  450. */
  451. Exception_Protected,
  452. /* A ledger was required but not supplied.
  453. */
  454. Invalid_Ledger,
  455. /* The port was not a memory cache control port.
  456. */
  457. Invalid_Memory_Control,
  458. /* An argument supplied to assert security privilege
  459. * was not a host security port.
  460. */
  461. Invalid_Security,
  462. /* thread_depress_abort was called on a thread which
  463. * was not currently depressed.
  464. */
  465. Not_Depressed,
  466. /* Object has been terminated and is no longer available
  467. */
  468. Terminated,
  469. /* Lock set has been destroyed and is no longer available.
  470. */
  471. Lock_Set_Destroyed,
  472. /* The thread holding the lock terminated before releasing
  473. * the lock
  474. */
  475. Lock_Unstable,
  476. /* The lock is already owned by another thread
  477. */
  478. Lock_Owned,
  479. /* The lock is already owned by the calling thread
  480. */
  481. Lock_Owned_Self,
  482. /* Semaphore has been destroyed and is no longer available.
  483. */
  484. Semaphore_Destroyed,
  485. /* Return from RPC indicating the target server was
  486. * terminated before it successfully replied
  487. */
  488. Rpc_Server_Terminated,
  489. /* Terminate an orphaned activation.
  490. */
  491. RPC_Terminate_Orphan,
  492. /* Allow an orphaned activation to continue executing.
  493. */
  494. RPC_Continue_Orphan,
  495. /* Empty thread activation (No thread linked to it)
  496. */
  497. Not_Supported,
  498. /* Remote node down or inaccessible.
  499. */
  500. Node_Down,
  501. /* A signalled thread was not actually waiting. */
  502. Not_Waiting,
  503. /* Some thread-oriented operation (semaphore_wait) timed out
  504. */
  505. Operation_Timed_Out,
  506. /* During a page fault, indicates that the page was rejected
  507. * as a result of a signature check.
  508. */
  509. Codesign_Error,
  510. /* The requested property cannot be changed at this time.
  511. */
  512. Policy_Static,
  513. /* The provided buffer is of insufficient size for the requested data.
  514. */
  515. Insufficient_Buffer_Size,
  516. /* Denied by security policy
  517. */
  518. Denied,
  519. /* The KC on which the function is operating is missing
  520. */
  521. Missing_KC,
  522. /* The KC on which the function is operating is invalid
  523. */
  524. Invalid_KC,
  525. /* A search or query operation did not return a result
  526. */
  527. Not_Found,
  528. /* Maximum return value allowable
  529. */
  530. Return_Max = 0x100,
  531. }
  532. /*
  533. * VM allocation flags:
  534. *
  535. * VM_FLAGS_FIXED
  536. * (really the absence of VM_FLAGS_ANYWHERE)
  537. * Allocate new VM region at the specified virtual address, if possible.
  538. *
  539. * VM_FLAGS_ANYWHERE
  540. * Allocate new VM region anywhere it would fit in the address space.
  541. *
  542. * VM_FLAGS_PURGABLE
  543. * Create a purgable VM object for that new VM region.
  544. *
  545. * VM_FLAGS_4GB_CHUNK
  546. * The new VM region will be chunked up into 4GB sized pieces.
  547. *
  548. * VM_FLAGS_NO_PMAP_CHECK
  549. * (for DEBUG kernel config only, ignored for other configs)
  550. * Do not check that there is no stale pmap mapping for the new VM region.
  551. * This is useful for kernel memory allocations at bootstrap when building
  552. * the initial kernel address space while some memory is already in use.
  553. *
  554. * VM_FLAGS_OVERWRITE
  555. * The new VM region can replace existing VM regions if necessary
  556. * (to be used in combination with VM_FLAGS_FIXED).
  557. *
  558. * VM_FLAGS_NO_CACHE
  559. * Pages brought in to this VM region are placed on the speculative
  560. * queue instead of the active queue. In other words, they are not
  561. * cached so that they will be stolen first if memory runs low.
  562. */
  563. @(private="file")
  564. LOG2 :: intrinsics.constant_log2
  565. VM_Flag :: enum c.int {
  566. Anywhere,
  567. Purgable,
  568. _4GB_Chunk,
  569. Random_Addr,
  570. No_Cache,
  571. Resilient_Codesign,
  572. Resilient_Media,
  573. Permanent,
  574. // NOTE(beau): log 2 of the bit we want in the bit set so we get that bit in
  575. // the bit set
  576. TPRO = LOG2(0x1000),
  577. Overwrite = LOG2(0x4000),/* delete any existing mappings first */
  578. Superpage_Size_Any = LOG2(0x10000),
  579. Superpage_Size_2MB = LOG2(0x20000),
  580. __Superpage3 = LOG2(0x40000),
  581. Return_Data_Addr = LOG2(0x100000),
  582. Return_4K_Data_Addr = LOG2(0x800000),
  583. Alias_Mask1 = 24,
  584. Alias_Mask2,
  585. Alias_Mask3,
  586. Alias_Mask4,
  587. Alias_Mask5,
  588. Alias_Mask6,
  589. Alias_Mask7,
  590. Alias_Mask8,
  591. HW = TPRO,
  592. }
  593. VM_Flags :: distinct bit_set[VM_Flag; c.int]
  594. VM_FLAGS_FIXED :: VM_Flags{}
  595. /*
  596. * VM_FLAGS_SUPERPAGE_MASK
  597. * 3 bits that specify whether large pages should be used instead of
  598. * base pages (!=0), as well as the requested page size.
  599. */
  600. VM_FLAGS_SUPERPAGE_MASK :: VM_Flags {
  601. .Superpage_Size_Any,
  602. .Superpage_Size_2MB,
  603. .__Superpage3,
  604. }
  605. // 0xFF000000
  606. VM_FLAGS_ALIAS_MASK :: VM_Flags {
  607. .Alias_Mask1,
  608. .Alias_Mask2,
  609. .Alias_Mask3,
  610. .Alias_Mask4,
  611. .Alias_Mask5,
  612. .Alias_Mask6,
  613. .Alias_Mask7,
  614. .Alias_Mask8,
  615. }
  616. VM_GET_FLAGS_ALIAS :: proc(flags: VM_Flags) -> c.int {
  617. return transmute(c.int)(flags & VM_FLAGS_ALIAS_MASK) >> 24
  618. }
  619. // NOTE(beau): no need for VM_SET_FLAGS_ALIAS, just mask in things from
  620. // VM_Flag.Alias_Mask*
  621. /* These are the flags that we accept from user-space */
  622. VM_FLAGS_USER_ALLOCATE :: VM_Flags {
  623. .Anywhere,
  624. .Purgable,
  625. ._4GB_Chunk,
  626. .Random_Addr,
  627. .No_Cache,
  628. .Permanent,
  629. .Overwrite,
  630. } | VM_FLAGS_FIXED | VM_FLAGS_SUPERPAGE_MASK | VM_FLAGS_ALIAS_MASK
  631. VM_FLAGS_USER_MAP :: VM_Flags {
  632. .Return_4K_Data_Addr,
  633. .Return_Data_Addr,
  634. } | VM_FLAGS_USER_ALLOCATE
  635. VM_FLAGS_USER_REMAP :: VM_Flags {
  636. .Anywhere,
  637. .Random_Addr,
  638. .Overwrite,
  639. .Return_Data_Addr,
  640. .Resilient_Codesign,
  641. .Resilient_Media,
  642. } | VM_FLAGS_FIXED
  643. VM_FLAGS_SUPERPAGE_NONE :: VM_Flags{} /* no superpages, if all bits are 0 */
  644. /*
  645. * Protection values, defined as bits within the vm_prot_t type
  646. */
  647. VM_Prot :: enum vm_prot_t {
  648. Read,
  649. Write,
  650. Execute,
  651. }
  652. VM_Prot_Flags :: distinct bit_set[VM_Prot; vm_prot_t]
  653. VM_PROT_NONE :: VM_Prot_Flags{}
  654. VM_PROT_DEFAULT :: VM_Prot_Flags{.Read, .Write}
  655. VM_PROT_ALL :: VM_Prot_Flags{.Read, .Write, .Execute}
  656. /*
  657. * Mach msg options, defined as bits within the mach_msg_option_t type
  658. */
  659. Msg_Option :: enum mach_msg_option_t {
  660. Send_Msg,
  661. Receive_Msg,
  662. Send_Timeout = LOG2(0x10),
  663. Send_Notify = LOG2(0x20),
  664. Send_Interrupt = LOG2(0x40),
  665. Send_Cancel = LOG2(0x80),
  666. Receive_Timeout = LOG2(0x100),
  667. Receive_Notify = LOG2(0x200),
  668. Receive_Interrupt = LOG2(0x400),
  669. Receive_Large = LOG2(0x800),
  670. Send_Always = LOG2(0x10000),
  671. }
  672. Msg_Option_Flags :: distinct bit_set[Msg_Option; mach_msg_option_t]
  673. /*
  674. * Enumeration of valid values for mach_port_right_t
  675. */
  676. Port_Right :: enum mach_port_right_t {
  677. Send,
  678. Receive,
  679. Send_Once,
  680. Port_Set,
  681. Dead_Name,
  682. }
  683. /*
  684. * Enumeration of valid values for vm_inherit_t.
  685. */
  686. VM_Inherit :: enum vm_inherit_t {
  687. Share,
  688. Copy,
  689. None,
  690. Donate_Copy,
  691. Default = Copy,
  692. Last_Valid = None,
  693. }
  694. Sync_Policy :: enum sync_policy_t {
  695. Fifo,
  696. Fixed_Priority,
  697. Reversed,
  698. Order_Mask,
  699. Lifo = Fifo | Reversed,
  700. }
  701. mach_vm_trunc_page :: proc(v: u64) -> u64 {
  702. return v & ~vm_page_mask
  703. }