/* * Copyright (C) 2017, 2019 JP Bonn, Ken Rabold * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup cpu_riscv_common * @ingroup cpu * @{ * * @file * @brief compile-time check of context_switch_frame offsets * * @author JP Bonn * @} */ #include #include "context_frame.h" #include "thread.h" #define CHECK_OFFSET(member) \ _Static_assert(offsetof(struct context_switch_frame, \ member) == member ## _OFFSET, \ "context_switch_frame offset mismatch for offset member"); static void check_context_switch_frame_alignment(void) __attribute__ ((unused)); /** * @brief Check size and offsets of context_switch_frame * * This does nothing at runtime. It is optimized out since it's only * doing compile-time checks. */ static void check_context_switch_frame_alignment(void) { _Static_assert(sizeof(struct context_switch_frame) % 16 == 0, "Stack pointer should be 16 byte aligned"); _Static_assert(sizeof(struct context_switch_frame) == CONTEXT_FRAME_SIZE, "context_switch_frame size mismatch"); CHECK_OFFSET(s0); CHECK_OFFSET(s1); CHECK_OFFSET(s2); CHECK_OFFSET(s3); CHECK_OFFSET(s4); CHECK_OFFSET(s5); CHECK_OFFSET(s6); CHECK_OFFSET(s7); CHECK_OFFSET(s8); CHECK_OFFSET(s9); CHECK_OFFSET(s10); CHECK_OFFSET(s11); CHECK_OFFSET(ra); CHECK_OFFSET(t0); CHECK_OFFSET(t1); CHECK_OFFSET(t2); CHECK_OFFSET(t3); CHECK_OFFSET(t4); CHECK_OFFSET(t5); CHECK_OFFSET(t6); CHECK_OFFSET(a0); CHECK_OFFSET(a1); CHECK_OFFSET(a2); CHECK_OFFSET(a3); CHECK_OFFSET(a4); CHECK_OFFSET(a5); CHECK_OFFSET(a6); CHECK_OFFSET(a7); CHECK_OFFSET(pc); CHECK_OFFSET(pad); /* * also check the SP offset in the _frame structure */ _Static_assert( offsetof(struct _thread, sp) == SP_OFFSET_IN_THREAD, "Offset of SP in _thread mismatch"); }