void State::Resume() { AssertCritical(); Cpu::GetCurrent().SetAsyncKernelTop((void *)GetStackTop()); if (iretInfo.cs & 3) { __asm__ __volatile__("swapgs"); } __asm__ __volatile__( "sub $0x28, %%rsp\n" "mov $5, %%rcx\n" "mov %%rsp, %%rdi\n" "rep movsq\n" "mov %%rdx, %%rdi\n" "iretq" : : "S" (&iretInfo), "d" (rdi) ); __builtin_unreachable(); }
void State::SuspendAndCall(void (* func)(void *), void * arg) { AssertCritical(); Cpu & cpu = Cpu::GetCurrent(); // we must be in kernel space, so we know the CS and SS iretInfo.cs = 8; iretInfo.ss = 0; __asm__ __volatile__( "movabsq $_anarch_suspend_and_call_return2, %%rax\n" "movq %%rax, (%%rsi)\n" // save RIP "pushfq\n" // save RFLAGS "pop %%rax\n" "mov %%rax, 0x10(%%rsi)\n" "mov %%rsp, 0x18(%%rsi)\n" // save RSP "mov %%rcx, %%rsp\n" // load new RSP "call *%%rbx\n" // call func(arg) "_anarch_suspend_and_call_return2:" : : "c" (cpu.GetStackTop()), "b" (func), "S" (&iretInfo), "D" (arg) : "rdx", "rax", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "memory"); }
anarch::SyscallRet SyscallHandler(uint16_t number, anarch::SyscallArgs & args) { AssertCritical(); // You might be like "holy crap this is terrible". I'd respond to you as // follows: out of all of the syscall mechanisms I've seen, this is the most // clear, efficient, and unified way to do it. switch (number) { case 0: PrintSyscall(args); break; case 1: ExitSyscall(args); break; case 2: return GetPidSyscall(); case 3: return GetUidSyscall(); case 4: return CountPageSizesSyscall(); case 5: return GetPageSizeSyscall(args); case 6: return GetPageAlignSyscall(args); case 7: return GetVMCapabilitiesSyscall(); case 8: return AllocateSyscall(args); case 9: FreeSyscall(args); break; case 10: return GetNanoTimeSyscall(); case 11: return VMReadSyscall(args); case 12: return VMMapSyscall(args); case 13: return VMMapAtSyscall(args); case 14: return VMUnmapSyscall(args); case 15: return VMUnmapAndReserveSyscall(args); case 16: return VMReserveSyscall(args); case 17: return VMReserveAtSyscall(args); case 18: return VMUnreserveSyscall(args); case 19: return VMRereserveSyscall(args); case 20: ExitThreadSyscall(); break; case 21: return GetThreadIdSyscall(); case 22: return LaunchThreadSyscall(args); case 23: SleepSyscall(args); break; case 24: SleepInfiniteSyscall(); break; case 25: return WakeupSyscall(args); case 26: SetColorSyscall(args); break; case 27: return CreatePortSyscall(); case 28: return DestroyPortSyscall(args); default: anarch::cerr << "unknown SyscallHandler(" << number << ", ...)" << anarch::endl; break; } return anarch::SyscallRet::Empty(); }
void CriticalLock::Seize() { AssertCritical(); super::Seize(); }
void CriticalLock::SeizeYielding() { AssertCritical(); super::SeizeYielding(); }
void CriticalLock::Release() { AssertCritical(); super::Release(); }
void Thread::SetCurrent(Thread * th) { AssertCritical(); anarch::Thread::SetUserInfo((void *)th); }