managarm/hel
hel.h
Go to the documentation of this file.
1 
3 
4 #ifndef HEL_H
5 #define HEL_H
6 
7 #include <stddef.h>
8 #include <string.h>
9 #include <stdint.h>
10 
11 #include "hel-types.h"
12 
13 #ifdef __cplusplus
14 #define HEL_C_LINKAGE extern "C"
15 #else
16 #define HEL_C_LINKAGE
17 #endif
18 
19 enum {
20  // largest system call number plus 1
21  kHelNumCalls = 105,
22 
23  kHelCallLog = 1,
24  kHelCallPanic = 10,
25 
26  kHelCallNop = 2,
27  kHelCallSubmitAsyncNop = 3,
28 
29  kHelCallCreateUniverse = 62,
30  kHelCallTransferDescriptor = 66,
31  kHelCallDescriptorInfo = 32,
32  kHelCallGetCredentials = 84,
33  kHelCallCloseDescriptor = 21,
34 
35  kHelCallCreateQueue = 89,
36  kHelCallCancelAsync = 92,
37 
38  kHelCallAllocateMemory = 51,
39  kHelCallResizeMemory = 83,
40  kHelCallCreateManagedMemory = 64,
41  kHelCallCopyOnWrite = 39,
42  kHelCallAccessPhysical = 30,
43  kHelCallCreateSliceView = 88,
44  kHelCallForkMemory = 40,
45  kHelCallCreateSpace = 27,
46  kHelCallCreateIndirectMemory = 45,
47  kHelCallAlterMemoryIndirection = 52,
48  kHelCallMapMemory = 44,
49  kHelCallSubmitProtectMemory = 99,
50  kHelCallSubmitSynchronizeSpace = 53,
51  kHelCallUnmapMemory = 36,
52  kHelCallPointerPhysical = 43,
53  kHelCallSubmitReadMemory = 77,
54  kHelCallSubmitWriteMemory = 78,
55  kHelCallMemoryInfo = 26,
56  kHelCallSubmitManageMemory = 46,
57  kHelCallUpdateMemory = 47,
58  kHelCallSubmitLockMemoryView = 48,
59  kHelCallLoadahead = 49,
60  kHelCallCreateVirtualizedSpace = 50,
61 
62  kHelCallCreateThread = 67,
63  kHelCallQueryThreadStats = 95,
64  kHelCallSetPriority = 85,
65  kHelCallYield = 34,
66  kHelCallSubmitObserve = 74,
67  kHelCallKillThread = 87,
68  kHelCallInterruptThread = 86,
69  kHelCallResume = 61,
70  kHelCallLoadRegisters = 75,
71  kHelCallStoreRegisters = 76,
72  kHelCallQueryRegisterInfo = 102,
73  kHelCallWriteFsBase = 41,
74  kHelCallGetClock = 42,
75  kHelCallSubmitAwaitClock = 80,
76  kHelCallCreateVirtualizedCpu = 37,
77  kHelCallRunVirtualizedCpu = 38,
78  kHelCallGetRandomBytes = 101,
79  kHelCallWriteGsBase = 54,
80  kHelCallReadFsBase = 55,
81  kHelCallReadGsBase = 56,
82  kHelCallGetCurrentCpu = 57,
83 
84  kHelCallCreateStream = 68,
85  kHelCallSubmitAsync = 79,
86  kHelCallShutdownLane = 91,
87 
88  kHelCallFutexWait = 73,
89  kHelCallFutexWake = 71,
90 
91  kHelCallCreateOneshotEvent = 96,
92  kHelCallCreateBitsetEvent = 97,
93  kHelCallRaiseEvent = 98,
94  kHelCallAccessIrq = 14,
95  kHelCallAcknowledgeIrq = 81,
96  kHelCallSubmitAwaitEvent = 82,
97  kHelCallAutomateIrq = 94,
98 
99  kHelCallAccessIo = 11,
100  kHelCallEnableIo = 12,
101  kHelCallEnableFullIo = 35,
102 
103  kHelCallBindKernlet = 93,
104 
105  kHelCallGetAffinity = 103,
106  kHelCallSetAffinity = 100,
107 
108  kHelCallCreateToken = 104,
109 
110  kHelCallSuper = 0x80000000
111 };
112 
113 enum {
114  kHelErrNone = 0,
115  kHelErrIllegalSyscall = 5,
116  kHelErrIllegalArgs = 7,
117  kHelErrIllegalState = 15,
118  kHelErrUnsupportedOperation = 18,
119  kHelErrOutOfBounds = 19,
120  kHelErrQueueTooSmall = 14,
121  kHelErrCancelled = 12,
122  kHelErrNoDescriptor = 4,
123  kHelErrBadDescriptor = 2,
124  kHelErrThreadTerminated = 11,
125  kHelErrTransmissionMismatch = 13,
126  kHelErrLaneShutdown = 8,
127  kHelErrEndOfLane = 9,
128  kHelErrDismissed = 20,
129  kHelErrBufferTooSmall = 1,
130  kHelErrFault = 10,
131  kHelErrRemoteFault = 21,
132  kHelErrNoHardwareSupport = 16,
133  kHelErrNoMemory = 17,
134  kHelErrAlreadyExists = 22
135 };
136 
137 struct HelX86SegmentRegister {
138  uint64_t base;
139  uint32_t limit;
140  uint16_t selector;
141  uint8_t type, present, dpl, db, s, l, g, avl;
142 };
143 
144 struct HelX86DescriptorTable {
145  uint64_t base;
146  uint16_t limit;
147 };
148 
149 struct HelX86VirtualizationRegs {
150  uint64_t rax;
151  uint64_t rbx;
152  uint64_t rcx;
153  uint64_t rdx;
154  uint64_t rsi;
155  uint64_t rdi;
156  uint64_t rbp;
157  uint64_t r8;
158  uint64_t r9;
159  uint64_t r10;
160  uint64_t r11;
161  uint64_t r12;
162  uint64_t r13;
163  uint64_t r14;
164  uint64_t r15;
165 
166  uint64_t rsp;
167  uint64_t rip;
168  uint64_t rflags;
169 
170  struct HelX86SegmentRegister cs, ds, es, fs, gs, ss;
171  struct HelX86SegmentRegister tr, ldt;
172  struct HelX86DescriptorTable gdt, idt;
173 
174  uint64_t cr0, cr2, cr3, cr4, cr8;
175  uint64_t efer;
176  uint64_t apic_base;
177 };
178 
179 enum {
180  kHelNullHandle = 0,
181  kHelThisUniverse = -1,
182  kHelThisThread = -2,
183  kHelZeroMemory = -3
184 };
185 
186 enum {
187  kHelWaitInfinite = -1
188 };
189 
190 enum {
191  kHelAbiSystemV = 1
192 };
193 
194 enum {
195  kHelActionDismiss = 11,
196  kHelActionOffer = 5,
197  kHelActionAccept = 6,
198  kHelActionImbueCredentials = 8,
199  kHelActionExtractCredentials = 9,
200  kHelActionSendFromBuffer = 1,
201  kHelActionSendFromBufferSg = 10,
202  kHelActionRecvInline = 7,
203  kHelActionRecvToBuffer = 3,
204  kHelActionPushDescriptor = 2,
205  kHelActionPullDescriptor = 4
206 };
207 
208 enum {
209  kHelItemChain = 1,
210  kHelItemAncillary = 2,
211  kHelItemWantLane = (1 << 16),
212 };
213 
214 struct HelSgItem {
215  void *buffer;
216  size_t length;
217 };
218 
219 struct HelAction {
220  int type;
221  uint32_t flags;
222  // TODO: the following fields could be put into unions
223  void *buffer;
224  size_t length;
225  HelHandle handle;
226 };
227 
228 struct HelDescriptorInfo {
229  int type;
230 };
231 
232 enum HelAllocFlags {
233  kHelAllocContinuous = 4,
234  kHelAllocOnDemand = 1,
235 };
236 
237 struct HelAllocRestrictions {
238  int addressBits;
239 };
240 
241 enum HelManagedFlags {
242  kHelManagedReadahead = 1
243 };
244 
245 enum HelManageRequests {
246  kHelManageInitialize = 1,
247  kHelManageWriteback = 2
248 };
249 
250 enum HelMapFlags {
251  // Additional flags that may be set.
252  kHelMapProtRead = 256,
253  kHelMapProtWrite = 512,
254  kHelMapProtExecute = 1024,
255  kHelMapDontRequireBacking = 128,
256  kHelMapFixed = 2048,
257  kHelMapFixedNoReplace = 4096
258 };
259 
260 enum HelThreadFlags {
261  kHelThreadStopped = 1
262 };
263 
264 enum HelObservation {
265  kHelObserveNull = 0,
266  kHelObserveInterrupt = 4,
267  kHelObservePanic = 3,
268  kHelObserveBreakpoint = 1,
269  kHelObservePageFault = 2,
270  kHelObserveGeneralFault = 5,
271  kHelObserveIllegalInstruction = 6,
272  kHelObserveDivByZero = 7,
273  kHelObserveSuperCall = 0x80000000
274 };
275 
276 enum HelRegisterSets {
277  kHelRegsProgram = 1,
278  kHelRegsGeneral = 2,
279  kHelRegsThread = 3,
280  kHelRegsDebug = 4,
281  kHelRegsVirtualization = 5,
282  kHelRegsSimd = 6,
283  kHelRegsSignal = 7
284 };
285 
289  int setSize;
290 };
291 
292 #if defined(__x86_64__)
293 enum HelRegisterIndex {
294  kHelRegRax = 0,
295  kHelRegRbx = 1,
296  kHelRegRcx = 2,
297  kHelRegRdx = 3,
298  kHelRegRdi = 4,
299  kHelRegRsi = 5,
300  kHelRegR8 = 6,
301  kHelRegR9 = 7,
302  kHelRegR10 = 8,
303  kHelRegR11 = 9,
304  kHelRegR12 = 10,
305  kHelRegR13 = 11,
306  kHelRegR14 = 12,
307  kHelRegR15 = 13,
308  kHelRegRbp = 14,
309 
310  kHelNumGprs = 15,
311 
312  kHelRegIp = 0,
313  kHelRegSp = 1
314 };
315 
316 enum HelSyscallArgs {
317  kHelRegNumber = kHelRegRdi,
318  kHelRegError = kHelRegRdi,
319 
320  kHelRegArg0 = kHelRegRsi,
321  kHelRegArg1 = kHelRegRdx,
322  kHelRegArg2 = kHelRegRax,
323  kHelRegArg3 = kHelRegR8,
324  kHelRegArg4 = kHelRegR9,
325  kHelRegArg5 = kHelRegR10,
326  kHelRegArg6 = kHelRegR12,
327  kHelRegArg7 = kHelRegR13,
328  kHelRegArg8 = kHelRegR14,
329 
330  kHelRegOut0 = kHelRegRsi,
331  kHelRegOut1 = kHelRegRdx
332 };
333 
334 #elif defined(__aarch64__)
335 enum HelRegisterIndex {
336  kHelRegX0 = 0,
337  kHelRegX1,
338  kHelRegX2,
339  kHelRegX3,
340  kHelRegX4,
341  kHelRegX5,
342  kHelRegX6,
343  kHelRegX7,
344  kHelRegX8,
345  kHelRegX9,
346  kHelRegX10,
347  kHelRegX11,
348  kHelRegX12,
349  kHelRegX13,
350  kHelRegX14,
351  kHelRegX15,
352  kHelRegX16,
353  kHelRegX17,
354  kHelRegX18,
355  kHelRegX19,
356  kHelRegX20,
357  kHelRegX21,
358  kHelRegX22,
359  kHelRegX23,
360  kHelRegX24,
361  kHelRegX25,
362  kHelRegX26,
363  kHelRegX27,
364  kHelRegX28,
365  kHelRegX29,
366  kHelRegX30,
367 
368  kHelNumGprs = 31,
369 
370  kHelRegIp = 0,
371  kHelRegSp = 1
372 };
373 
374 enum HelSyscallArgs {
375  kHelRegNumber = kHelRegX0,
376  kHelRegError = kHelRegX0,
377 
378  kHelRegArg0 = kHelRegX1,
379  kHelRegArg1 = kHelRegX2,
380  kHelRegArg2 = kHelRegX3,
381  kHelRegArg3 = kHelRegX4,
382  kHelRegArg4 = kHelRegX5,
383  kHelRegArg5 = kHelRegX6,
384  kHelRegArg6 = kHelRegX7,
385  kHelRegArg7 = kHelRegX8,
386  kHelRegArg8 = kHelRegX9,
387 
388  kHelRegOut0 = kHelRegX1,
389  kHelRegOut1 = kHelRegX2
390 };
391 #endif
392 
393 struct HelQueueParameters {
394  uint32_t flags;
395  unsigned int ringShift;
396  unsigned int numChunks;
397  size_t chunkSize;
398 };
399 
401 static const int kHelHeadMask = 0xFFFFFF;
402 
404 static const int kHelHeadWaiters = (1 << 24);
405 
407 struct HelQueue {
410 
412  char padding[4];
413 
415  int indexQueue[];
416 };
417 
419 static const int kHelProgressMask = 0xFFFFFF;
420 
422 static const int kHelProgressWaiters = (1 << 24);
423 
425 static const int kHelProgressDone = (1 << 25);
426 
427 struct HelChunk {
429  int progressFutex;
430 
432  char padding[4];
433 
435  char buffer[];
436 };
437 
439 struct HelElement {
441  unsigned int length;
442  unsigned int reserved;
444  void *context;
445 };
446 
447 struct HelSimpleResult {
448  HelError error;
449  int reserved;
450 };
451 
452 struct HelCredentialsResult {
453  HelError error;
454  int reserved;
455  char credentials[16];
456 };
457 
458 struct HelManageResult {
459  HelError error;
460  int type;
461  uintptr_t offset;
462  size_t length;
463 };
464 
465 struct HelObserveResult {
466  HelError error;
467  unsigned int observation;
468  uint64_t sequence;
469 };
470 
471 struct HelInlineResult {
472  HelError error;
473  int reserved;
474  size_t length;
475  char data[];
476 };
477 
478 struct HelInlineResultNoFlex {
479  HelError error;
480  int reserved;
481  size_t length;
482 };
483 
484 struct HelLengthResult {
485  HelError error;
486  int reserved;
487  size_t length;
488 };
489 
490 struct HelHandleResult {
491  HelError error;
492  int reserved;
493  HelHandle handle;
494 };
495 
496 struct HelEventResult {
497  HelError error;
498  uint32_t bitset;
499  uint64_t sequence;
500 };
501 
502 enum HelAckFlags {
503  kHelAckAcknowledge = 2,
504  kHelAckNack = 3,
505  kHelAckKick = 1,
506  kHelAckClear = 0x100,
507 };
508 
509 union HelKernletData {
510  HelHandle handle;
511 };
512 
513 struct HelThreadStats {
514  uint64_t userTime;
515 };
516 
517 enum {
518  kHelVmexitHlt = 0,
519  kHelVmexitTranslationFault = 1,
520  kHelVmexitError = -1,
521  kHelVmexitUnknownPlatformSpecificExitCode = -2,
522 };
523 
524 struct HelVmexitReason {
525  uint32_t exitReason;
526  uint32_t code;
527  size_t address;
528  size_t flags;
529 };
530 
533 
539 HEL_C_LINKAGE HelError helLog(const char *string, size_t length);
540 
546 HEL_C_LINKAGE void helPanic(const char *string, size_t length)
547  __attribute__ (( noreturn ));
548 
552 
554 HEL_C_LINKAGE HelError helNop();
555 
559 HEL_C_LINKAGE HelError helSubmitAsyncNop(HelHandle queueHandle, uintptr_t context);
560 
564 
568 HEL_C_LINKAGE HelError helCreateUniverse(HelHandle *handle);
569 
577 HEL_C_LINKAGE HelError helTransferDescriptor(HelHandle handle, HelHandle universeHandle,
578  HelHandle *outHandle);
579 
580 HEL_C_LINKAGE HelError helDescriptorInfo(HelHandle handle, struct HelDescriptorInfo *info);
581 
587 HEL_C_LINKAGE HelError helGetCredentials(HelHandle handle, uint32_t flags,
588  char *credentials);
589 
595 HEL_C_LINKAGE HelError helCloseDescriptor(HelHandle universeHandle, HelHandle handle);
596 
600 
602 HEL_C_LINKAGE HelError helCreateQueue(struct HelQueueParameters *params,
603  HelHandle *handle);
604 
610 HEL_C_LINKAGE HelError helCancelAsync(HelHandle queueHandle, uint64_t asyncId);
611 
615 
625 HEL_C_LINKAGE HelError helAllocateMemory(size_t size, uint32_t flags,
626  struct HelAllocRestrictions *restrictions, HelHandle *handle);
627 
634 HEL_C_LINKAGE HelError helResizeMemory(HelHandle handle, size_t newSize);
635 
647 HEL_C_LINKAGE HelError helCreateManagedMemory(size_t size, uint32_t flags,
648  HelHandle *backingHandle, HelHandle *frontalHandle);
649 
660 HEL_C_LINKAGE HelError helCopyOnWrite(HelHandle memory,
661  uintptr_t offset, size_t size, HelHandle *handle);
662 
663 HEL_C_LINKAGE HelError helAccessPhysical(uintptr_t physical,
664  size_t size, HelHandle *handle);
665 
671 HEL_C_LINKAGE HelError helCreateIndirectMemory(size_t numSlots, HelHandle *handle);
672 
689 HEL_C_LINKAGE HelError helAlterMemoryIndirection(HelHandle indirectHandle, size_t slotIndex,
690  HelHandle memoryHandle, uintptr_t offset, size_t size);
691 
692 HEL_C_LINKAGE HelError helCreateSliceView(HelHandle bundle, uintptr_t offset, size_t size,
693  uint32_t flags, HelHandle *handle);
694 
702 HEL_C_LINKAGE HelError helForkMemory(HelHandle handle, HelHandle *forkedHandle);
703 
707 HEL_C_LINKAGE HelError helCreateSpace(HelHandle *handle);
708 
726 HEL_C_LINKAGE HelError helMapMemory(HelHandle memoryHandle, HelHandle spaceHandle,
727  void *pointer, uintptr_t offset, size_t size, uint32_t flags, void **actualPointer);
728 
740 HEL_C_LINKAGE HelError helSubmitProtectMemory(HelHandle spaceHandle,
741  void *pointer, size_t size, uint32_t flags,
742  HelHandle queueHandle, uintptr_t context);
743 
759 HEL_C_LINKAGE HelError helSubmitSynchronizeSpace(HelHandle spaceHandle,
760  void *pointer, size_t size,
761  HelHandle queueHandle, uintptr_t context);
762 
773 HEL_C_LINKAGE HelError helUnmapMemory(HelHandle spaceHandle, void *pointer, size_t size);
774 
775 HEL_C_LINKAGE HelError helPointerPhysical(const void *pointer, uintptr_t *physical);
776 
788 HEL_C_LINKAGE HelError helSubmitReadMemory(HelHandle handle, uintptr_t address,
789  size_t length, void *buffer,
790  HelHandle queue, uintptr_t context);
791 
803 HEL_C_LINKAGE HelError helSubmitWriteMemory(HelHandle handle, uintptr_t address,
804  size_t length, const void *buffer,
805  HelHandle queue, uintptr_t context);
806 
807 HEL_C_LINKAGE HelError helMemoryInfo(HelHandle handle,
808  size_t *size);
809 
810 HEL_C_LINKAGE HelError helSubmitManageMemory(HelHandle handle,
811  HelHandle queue, uintptr_t context);
812 
813 HEL_C_LINKAGE HelError helUpdateMemory(HelHandle handle, int type, uintptr_t offset, size_t length);
814 
815 HEL_C_LINKAGE HelError helSubmitLockMemoryView(HelHandle handle, uintptr_t offset, size_t size,
816  HelHandle queue, uintptr_t context);
817 
828 HEL_C_LINKAGE HelError helLoadahead(HelHandle handle, uintptr_t offset, size_t length);
829 
830 HEL_C_LINKAGE HelError helCreateVirtualizedSpace(HelHandle *handle);
831 
835 
849 HEL_C_LINKAGE HelError helCreateThread(HelHandle universe, HelHandle spaceHandle,
850  HelAbi abi, void *ip, void *sp, uint32_t flags, HelHandle *handle);
851 
857 HEL_C_LINKAGE HelError helQueryThreadStats(HelHandle handle, struct HelThreadStats *stats);
858 
867 HEL_C_LINKAGE HelError helSetPriority(HelHandle handle, int priority);
868 
870 HEL_C_LINKAGE HelError helYield();
871 
879 HEL_C_LINKAGE HelError helSubmitObserve(HelHandle handle, uint64_t sequence,
880  HelHandle queue, uintptr_t context);
881 
885 HEL_C_LINKAGE HelError helKillThread(HelHandle handle);
886 
893 HEL_C_LINKAGE HelError helInterruptThread(HelHandle handle);
894 
901 HEL_C_LINKAGE HelError helResume(HelHandle handle);
902 
910 HEL_C_LINKAGE HelError helLoadRegisters(HelHandle handle, int set, void *image);
911 
919 HEL_C_LINKAGE HelError helStoreRegisters(HelHandle handle, int set, const void *image);
920 
923 // Register set to query information for.
926 HEL_C_LINKAGE HelError helQueryRegisterInfo(int set, struct HelRegisterInfo *info);
927 
928 HEL_C_LINKAGE HelError helWriteFsBase(void *pointer);
929 
930 HEL_C_LINKAGE HelError helReadFsBase(void **pointer);
931 
932 HEL_C_LINKAGE HelError helWriteGsBase(void *pointer);
933 
934 HEL_C_LINKAGE HelError helReadGsBase(void **pointer);
935 
937 HEL_C_LINKAGE HelError helGetCurrentCpu(int *cpu);
938 
943 HEL_C_LINKAGE HelError helGetClock(uint64_t *counter);
944 
952 HEL_C_LINKAGE HelError helSubmitAwaitClock(uint64_t counter,
953  HelHandle queue, uintptr_t context, uint64_t *asyncId);
954 
955 HEL_C_LINKAGE HelError helCreateVirtualizedCpu(HelHandle handle, HelHandle *out_handle);
956 
957 HEL_C_LINKAGE HelError helRunVirtualizedCpu(HelHandle handle, struct HelVmexitReason *reason);
958 
959 HEL_C_LINKAGE HelError helGetRandomBytes(void *buffer, size_t wantedSize, size_t *actualSize);
960 
970 HEL_C_LINKAGE HelError helGetAffinity(HelHandle handle, uint8_t *mask, size_t size, size_t *actualSize);
971 
979 HEL_C_LINKAGE HelError helSetAffinity(HelHandle handle, uint8_t *mask, size_t size);
980 
984 
990 HEL_C_LINKAGE HelError helCreateStream(HelHandle *lane1, HelHandle *lane2);
991 
999 HEL_C_LINKAGE HelError helSubmitAsync(HelHandle handle, const struct HelAction *actions,
1000  size_t count, HelHandle queue, uintptr_t context, uint32_t flags);
1001 
1002 HEL_C_LINKAGE HelError helShutdownLane(HelHandle handle);
1003 
1011 HEL_C_LINKAGE HelError helCreateToken(HelHandle *handle);
1012 
1016 
1025 HEL_C_LINKAGE HelError helFutexWait(int *pointer, int expected, int64_t deadline);
1026 
1030 HEL_C_LINKAGE HelError helFutexWake(int *pointer);
1031 
1035 
1039 HEL_C_LINKAGE HelError helCreateOneshotEvent(HelHandle *handle);
1040 
1044 HEL_C_LINKAGE HelError helCreateBitsetEvent(HelHandle *handle);
1045 
1049 HEL_C_LINKAGE HelError helRaiseEvent(HelHandle handle);
1050 
1051 HEL_C_LINKAGE HelError helAccessIrq(int number, HelHandle *handle);
1052 
1053 HEL_C_LINKAGE HelError helAcknowledgeIrq(HelHandle handle, uint32_t flags, uint64_t sequence);
1054 
1062 HEL_C_LINKAGE HelError helSubmitAwaitEvent(HelHandle handle, uint64_t sequence,
1063  HelHandle queue, uintptr_t context);
1064 
1065 HEL_C_LINKAGE HelError helAutomateIrq(HelHandle handle, uint32_t flags, HelHandle kernlet);
1066 
1070 
1071 HEL_C_LINKAGE HelError helAccessIo(uintptr_t *port_array, size_t num_ports,
1072  HelHandle *handle);
1073 
1077 HEL_C_LINKAGE HelError helEnableIo(HelHandle handle);
1078 
1079 HEL_C_LINKAGE HelError helEnableFullIo();
1080 
1084 
1094 HEL_C_LINKAGE HelError helBindKernlet(HelHandle handle,
1095  const union HelKernletData *data, size_t numData, HelHandle *boundHandle);
1096 
1098 
1099 extern inline __attribute__ (( always_inline )) const char *_helErrorString(HelError code) {
1100  switch(code) {
1101  case kHelErrNone:
1102  return "Success";
1103  case kHelErrIllegalSyscall:
1104  return "Illegal syscall";
1105  case kHelErrIllegalArgs:
1106  return "Illegal arguments";
1107  case kHelErrIllegalState:
1108  return "Illegal state";
1109  case kHelErrUnsupportedOperation:
1110  return "Unsupported operation";
1111  case kHelErrNoDescriptor:
1112  return "No such descriptor";
1113  case kHelErrBadDescriptor:
1114  return "Illegal descriptor for this operation";
1115  case kHelErrThreadTerminated:
1116  return "Thread terminated already";
1117  case kHelErrLaneShutdown:
1118  return "Lane shutdown";
1119  case kHelErrEndOfLane:
1120  return "End of lane";
1121  case kHelErrDismissed:
1122  return "IPC item dismissed by remote";
1123  case kHelErrBufferTooSmall:
1124  return "Buffer too small";
1125  case kHelErrQueueTooSmall:
1126  return "Buffer too small";
1127  case kHelErrFault:
1128  return "Segfault";
1129  case kHelErrNoHardwareSupport:
1130  return "Missing hardware support for this feature";
1131  case kHelErrNoMemory:
1132  return "Out of memory";
1133  case kHelErrTransmissionMismatch:
1134  return "Transmission mismatch";
1135  case kHelErrCancelled:
1136  return "Cancelled";
1137  case kHelErrOutOfBounds:
1138  return "Out of bounds";
1139  case kHelErrAlreadyExists:
1140  return "Already exists";
1141  default:
1142  return 0;
1143  }
1144 }
1145 
1146 extern inline __attribute__ (( always_inline )) void _helCheckFailed(HelError err_code,
1147  const char *string, int fatal) {
1148  helLog(string, strlen(string));
1149 
1150  const char *err_string = _helErrorString(err_code);
1151  if(err_string == 0)
1152  err_string = "(Unexpected error code)";
1153  helLog(err_string, strlen(err_string));
1154  helLog("\n", 1);
1155 
1156  if(fatal)
1157  helPanic(0, 0);
1158 }
1159 
1160 #define HEL_STRINGIFY_AUX(x) #x
1161 #define HEL_STRINGIFY(x) HEL_STRINGIFY_AUX(x)
1162 
1163 #define HEL_CHECK(expr) do { HelError __error = expr; if(__error != kHelErrNone) \
1164  _helCheckFailed(__error, "HEL_CHECK failed: " #expr "\n" \
1165  " In file " __FILE__ " on line " HEL_STRINGIFY(__LINE__) "\n", 1); } while(0)
1166 #define HEL_SOFT_CHECK(expr) do { HelError __error = expr; if(__error != kHelErrNone) \
1167  _helCheckFailed(__error, "HEL_SOFT_CHECK failed: " #expr "\n" \
1168  " In file " __FILE__ " on line " HEL_STRINGIFY(__LINE__) "\n", 0); } while(0)
1169 
1170 #endif // HEL_H
1171 
helAllocateMemory
HEL_C_LINKAGE HelError helAllocateMemory(size_t size, uint32_t flags, struct HelAllocRestrictions *restrictions, HelHandle *handle)
Creates a memory object consisting of unmanaged RAM.
helLog
HEL_C_LINKAGE HelError helLog(const char *string, size_t length)
Writes a text message (e.g., a line of text) to the kernel's log.
helQueryThreadStats
HEL_C_LINKAGE HelError helQueryThreadStats(HelHandle handle, struct HelThreadStats *stats)
Query run-time statistics of a thread.
helUnmapMemory
HEL_C_LINKAGE HelError helUnmapMemory(HelHandle spaceHandle, void *pointer, size_t size)
Unmaps memory from an address space.
helSubmitProtectMemory
HEL_C_LINKAGE HelError helSubmitProtectMemory(HelHandle spaceHandle, void *pointer, size_t size, uint32_t flags, HelHandle queueHandle, uintptr_t context)
Changes protection attributes of a memory mapping.
helFutexWake
HEL_C_LINKAGE HelError helFutexWake(int *pointer)
Wakes up all waiters of a futex.
helCreateQueue
HEL_C_LINKAGE HelError helCreateQueue(struct HelQueueParameters *params, HelHandle *handle)
Creates an IPC queue.
HelElement::length
unsigned int length
Length of the element in bytes.
Definition: hel.h:441
HelQueue
In-memory kernel/user-space queue.
Definition: hel.h:407
helCreateStream
HEL_C_LINKAGE HelError helCreateStream(HelHandle *lane1, HelHandle *lane2)
Create a stream (which always consists of two lanes).
helSetAffinity
HEL_C_LINKAGE HelError helSetAffinity(HelHandle handle, uint8_t *mask, size_t size)
Set a thread's CPU affinity mask.
helFutexWait
HEL_C_LINKAGE HelError helFutexWait(int *pointer, int expected, int64_t deadline)
Waits on a futex.
helSubmitAsyncNop
HEL_C_LINKAGE HelError helSubmitAsyncNop(HelHandle queueHandle, uintptr_t context)
Does nothing, asynchronously (useful only for profiling).
helInterruptThread
HEL_C_LINKAGE HelError helInterruptThread(HelHandle handle)
Interrupt a thread.
helAlterMemoryIndirection
HEL_C_LINKAGE HelError helAlterMemoryIndirection(HelHandle indirectHandle, size_t slotIndex, HelHandle memoryHandle, uintptr_t offset, size_t size)
Modifies indirect memory objects.
helGetCredentials
HEL_C_LINKAGE HelError helGetCredentials(HelHandle handle, uint32_t flags, char *credentials)
Returns the credentials associated with a given descriptor.
HelElement::context
void * context
User-defined value.
Definition: hel.h:444
helKillThread
HEL_C_LINKAGE HelError helKillThread(HelHandle handle)
Kill (i.e., terminate) a thread.
kHelHeadWaiters
static const int kHelHeadWaiters
Can be set by the kernel to request a FutexWake on update.
Definition: hel.h:404
HelElement
A single element of a HelQueue.
Definition: hel.h:439
helSubmitAwaitClock
HEL_C_LINKAGE HelError helSubmitAwaitClock(uint64_t counter, HelHandle queue, uintptr_t context, uint64_t *asyncId)
Wait until time passes.
helSetPriority
HEL_C_LINKAGE HelError helSetPriority(HelHandle handle, int priority)
Set the priority of a thread.
helSubmitAwaitEvent
HEL_C_LINKAGE HelError helSubmitAwaitEvent(HelHandle handle, uint64_t sequence, HelHandle queue, uintptr_t context)
Wait for an event.
helCloseDescriptor
HEL_C_LINKAGE HelError helCloseDescriptor(HelHandle universeHandle, HelHandle handle)
Closes a descriptor.
HelRegisterInfo
Register-related information returned by helQueryRegisterInfo.
Definition: hel.h:287
helResizeMemory
HEL_C_LINKAGE HelError helResizeMemory(HelHandle handle, size_t newSize)
Resizes a memory object.
kHelProgressDone
static const int kHelProgressDone
Set by the kernel once it retires the chunk.
Definition: hel.h:425
helCreateOneshotEvent
HEL_C_LINKAGE HelError helCreateOneshotEvent(HelHandle *handle)
Create an event that fires at most once.
helYield
HEL_C_LINKAGE HelError helYield()
Yields the current thread.
kHelHeadMask
static const int kHelHeadMask
Mask to extract the current queue head.
Definition: hel.h:401
helTransferDescriptor
HEL_C_LINKAGE HelError helTransferDescriptor(HelHandle handle, HelHandle universeHandle, HelHandle *outHandle)
Copies descriptors from the current universe to another universe.
helLoadahead
HEL_C_LINKAGE HelError helLoadahead(HelHandle handle, uintptr_t offset, size_t length)
Notifies the kernel that a certain range of memory should be preloaded.
helSubmitWriteMemory
HEL_C_LINKAGE HelError helSubmitWriteMemory(HelHandle handle, uintptr_t address, size_t length, const void *buffer, HelHandle queue, uintptr_t context)
Store memory (i.e., bytes) to a descriptor.
helRaiseEvent
HEL_C_LINKAGE HelError helRaiseEvent(HelHandle handle)
Raise an event.
helLoadRegisters
HEL_C_LINKAGE HelError helLoadRegisters(HelHandle handle, int set, void *image)
Load a register image (e.g., from a thread).
helSubmitReadMemory
HEL_C_LINKAGE HelError helSubmitReadMemory(HelHandle handle, uintptr_t address, size_t length, void *buffer, HelHandle queue, uintptr_t context)
Load memory (i.e., bytes) from a descriptor.
helEnableIo
HEL_C_LINKAGE HelError helEnableIo(HelHandle handle)
Enable userspace access to hardware I/O resources.
HelQueue::indexQueue
int indexQueue[]
The actual queue.
Definition: hel.h:415
HelQueue::headFutex
int headFutex
Futex for kernel/user-space head synchronization.
Definition: hel.h:409
helCreateBitsetEvent
HEL_C_LINKAGE HelError helCreateBitsetEvent(HelHandle *handle)
Create an event consisting of multiple bits that can fire independently.
HelRegisterInfo::setSize
int setSize
Size of the selected register set.
Definition: hel.h:289
helGetCurrentCpu
HEL_C_LINKAGE HelError helGetCurrentCpu(int *cpu)
Gets the index of the cpu which the calling thread is running on.
helStoreRegisters
HEL_C_LINKAGE HelError helStoreRegisters(HelHandle handle, int set, const void *image)
Store a register image (e.g., to a thread).
helNop
HEL_C_LINKAGE HelError helNop()
Does nothing (useful only for profiling).
helSubmitObserve
HEL_C_LINKAGE HelError helSubmitObserve(HelHandle handle, uint64_t sequence, HelHandle queue, uintptr_t context)
Observe whether a thread changes its state.
helForkMemory
HEL_C_LINKAGE HelError helForkMemory(HelHandle handle, HelHandle *forkedHandle)
Forks memory objects, i.e., copies them using copy-on-write.
helCancelAsync
HEL_C_LINKAGE HelError helCancelAsync(HelHandle queueHandle, uint64_t asyncId)
Cancels an ongoing asynchronous operation.
helCreateThread
HEL_C_LINKAGE HelError helCreateThread(HelHandle universe, HelHandle spaceHandle, HelAbi abi, void *ip, void *sp, uint32_t flags, HelHandle *handle)
Create a new thread.
helSubmitSynchronizeSpace
HEL_C_LINKAGE HelError helSubmitSynchronizeSpace(HelHandle spaceHandle, void *pointer, size_t size, HelHandle queueHandle, uintptr_t context)
Notifies the kernel of dirty pages in a memory mapping.
helResume
HEL_C_LINKAGE HelError helResume(HelHandle handle)
Resume a suspended thread.
helCreateToken
HEL_C_LINKAGE HelError helCreateToken(HelHandle *handle)
Create a token object.
helCreateManagedMemory
HEL_C_LINKAGE HelError helCreateManagedMemory(size_t size, uint32_t flags, HelHandle *backingHandle, HelHandle *frontalHandle)
Creates a memory object that is managed by userspace.
helSubmitAsync
HEL_C_LINKAGE HelError helSubmitAsync(HelHandle handle, const struct HelAction *actions, size_t count, HelHandle queue, uintptr_t context, uint32_t flags)
Pass messages on a stream.
helCreateIndirectMemory
HEL_C_LINKAGE HelError helCreateIndirectMemory(size_t numSlots, HelHandle *handle)
Creates a memory object that obtains its memory by delegating to other memory objects.
helMapMemory
HEL_C_LINKAGE HelError helMapMemory(HelHandle memoryHandle, HelHandle spaceHandle, void *pointer, uintptr_t offset, size_t size, uint32_t flags, void **actualPointer)
Maps memory objects into an address space.
helCreateSpace
HEL_C_LINKAGE HelError helCreateSpace(HelHandle *handle)
Creates a virtual address space that threads can run in.
helPanic
HEL_C_LINKAGE void helPanic(const char *string, size_t length) __attribute__((noreturn))
Kills the current thread and writes an error message to the kernel's log.
HelQueue::padding
char padding[4]
Ensures that the buffer is 8-byte aligned.
Definition: hel.h:412
helCreateUniverse
HEL_C_LINKAGE HelError helCreateUniverse(HelHandle *handle)
Creates a new universe descriptor.
helGetClock
HEL_C_LINKAGE HelError helGetClock(uint64_t *counter)
Read the system-wide monotone clock.
helCopyOnWrite
HEL_C_LINKAGE HelError helCopyOnWrite(HelHandle memory, uintptr_t offset, size_t size, HelHandle *handle)
Creates memory object that obtains its memory by copy-on-write from another memory object.
kHelProgressWaiters
static const int kHelProgressWaiters
Can be set by userspace to request a FutexWake on update.
Definition: hel.h:422
helQueryRegisterInfo
HEL_C_LINKAGE HelError helQueryRegisterInfo(int set, struct HelRegisterInfo *info)
Query register-related information.
kHelProgressMask
static const int kHelProgressMask
Mask to extract the number of valid bytes in the chunk.
Definition: hel.h:419
helBindKernlet
HEL_C_LINKAGE HelError helBindKernlet(HelHandle handle, const union HelKernletData *data, size_t numData, HelHandle *boundHandle)
Bind parameters to a kernlet.
helGetAffinity
HEL_C_LINKAGE HelError helGetAffinity(HelHandle handle, uint8_t *mask, size_t size, size_t *actualSize)
Get a thread's CPU affinity mask.