#include "context.h" #include "../debug/assert.h" #include "../debug/kernelpanic.h" /*! \brief Panic function * * If the kickoff function (assigned in \ref prepareContext) *returns*, this * parameterless function will be called -- and stop the execution. */ static void panic() { // we should not come back here kernelpanic("Application should not return from context_kickoff"); } void prepareContext(void* tos, Context& context, void (*kickoff)(uintptr_t, uintptr_t, uintptr_t), uintptr_t param1, uintptr_t param2, uintptr_t param3) { assert(tos != nullptr && "Top Of Stack must not be nullptr"); assert((uintptr_t)tos % 16 == 0 && "Top Of Stack be 16 byte aligned"); assert(kickoff != nullptr && "Kickoff function missing"); // XXX Double check alignment. This seems to work, but the stack pointer for // `panic` should not be aligned to 16-bit? void** sp = reinterpret_cast(tos); *(--sp) = reinterpret_cast(panic); // return address *(--sp) = reinterpret_cast(kickoff); // start the thread in C land *(--sp) = reinterpret_cast(fake_systemv_abi); // pass via registers context = { .rbx = 0, .rbp = 0, .r12 = 0, .r13 = param3, .r14 = param2, // Second parameter to kickoff .r15 = param1, // First parameter to kickoff .rsp = reinterpret_cast(sp), }; }