        -:    0:Source:../../../os/rt/ports/SIMIA32/chcore.h
        -:    0:Programs:17
        -:    1:/*
        -:    2:    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
        -:    3:
        -:    4:    This file is part of ChibiOS.
        -:    5:
        -:    6:    ChibiOS is free software; you can redistribute it and/or modify
        -:    7:    it under the terms of the GNU General Public License as published by
        -:    8:    the Free Software Foundation; either version 3 of the License, or
        -:    9:    (at your option) any later version.
        -:   10:
        -:   11:    ChibiOS is distributed in the hope that it will be useful,
        -:   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        -:   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        -:   14:    GNU General Public License for more details.
        -:   15:
        -:   16:    You should have received a copy of the GNU General Public License
        -:   17:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
        -:   18:*/
        -:   19:
        -:   20:/**
        -:   21: * @file    SIMIA32/chcore.h
        -:   22: * @brief   Simulator on IA32 port macros and structures.
        -:   23: *
        -:   24: * @addtogroup SIMIA32_GCC_CORE
        -:   25: * @{
        -:   26: */
        -:   27:
        -:   28:#ifndef _CHCORE_H_
        -:   29:#define _CHCORE_H_
        -:   30:
        -:   31:/*===========================================================================*/
        -:   32:/* Module constants.                                                         */
        -:   33:/*===========================================================================*/
        -:   34:
        -:   35:/**
        -:   36: * Macro defining the a simulated architecture into x86.
        -:   37: */
        -:   38:#define PORT_ARCHITECTURE_SIMIA32
        -:   39:
        -:   40:/**
        -:   41: * Name of the implemented architecture.
        -:   42: */
        -:   43:#define PORT_ARCHITECTURE_NAME          "Simulator"
        -:   44:
        -:   45:/**
        -:   46: * @brief   Name of the architecture variant (optional).
        -:   47: */
        -:   48:#define PORT_CORE_VARIANT_NAME          "x86 (integer only)"
        -:   49:
        -:   50:/**
        -:   51: * @brief   Name of the compiler supported by this port.
        -:   52: */
        -:   53:#define PORT_COMPILER_NAME              "GCC " __VERSION__
        -:   54:
        -:   55:/**
        -:   56: * @brief   Port-specific information string.
        -:   57: */
        -:   58:#define PORT_INFO                       "No preemption"
        -:   59:
        -:   60:/**
        -:   61: * @brief   This port supports a realtime counter.
        -:   62: */
        -:   63:#define PORT_SUPPORTS_RT                TRUE
        -:   64:
        -:   65:/*===========================================================================*/
        -:   66:/* Module pre-compile time settings.                                         */
        -:   67:/*===========================================================================*/
        -:   68:
        -:   69:/**
        -:   70: * @brief   Stack size for the system idle thread.
        -:   71: * @details This size depends on the idle thread implementation, usually
        -:   72: *          the idle thread should take no more space than those reserved
        -:   73: *          by @p PORT_INT_REQUIRED_STACK.
        -:   74: */
        -:   75:#ifndef PORT_IDLE_THREAD_STACK_SIZE
        -:   76:#define PORT_IDLE_THREAD_STACK_SIZE     256
        -:   77:#endif
        -:   78:
        -:   79:/**
        -:   80: * @brief   Per-thread stack overhead for interrupts servicing.
        -:   81: * @details This constant is used in the calculation of the correct working
        -:   82: *          area size.
        -:   83: */
        -:   84:#ifndef PORT_INT_REQUIRED_STACK
        -:   85:#define PORT_INT_REQUIRED_STACK         16384
        -:   86:#endif
        -:   87:
        -:   88:/**
        -:   89: * @brief   Enables an alternative timer implementation.
        -:   90: * @details Usually the port uses a timer interface defined in the file
        -:   91: *          @p chcore_timer.h, if this option is enabled then the file
        -:   92: *          @p chcore_timer_alt.h is included instead.
        -:   93: */
        -:   94:#if !defined(PORT_USE_ALT_TIMER)
        -:   95:#define PORT_USE_ALT_TIMER              FALSE
        -:   96:#endif
        -:   97:
        -:   98:/*===========================================================================*/
        -:   99:/* Derived constants and error checks.                                       */
        -:  100:/*===========================================================================*/
        -:  101:
        -:  102:#if CH_DBG_ENABLE_STACK_CHECK
        -:  103:#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
        -:  104:#endif
        -:  105:
        -:  106:/*===========================================================================*/
        -:  107:/* Module data structures and types.                                         */
        -:  108:/*===========================================================================*/
        -:  109:
        -:  110:/**
        -:  111: * @brief   16 bytes stack and memory alignment enforcement.
        -:  112: */
        -:  113:typedef struct {
        -:  114:  uint8_t a[16];
        -:  115:} stkalign_t __attribute__((aligned(16)));
        -:  116:
        -:  117:/**
        -:  118: * @brief   Type of a generic x86 register.
        -:  119: */
        -:  120:typedef void *regx86;
        -:  121:
        -:  122:/**
        -:  123: * @brief   Interrupt saved context.
        -:  124: * @details This structure represents the stack frame saved during a
        -:  125: *          preemption-capable interrupt handler.
        -:  126: */
        -:  127:struct port_extctx {
        -:  128:};
        -:  129:
        -:  130:/**
        -:  131: * @brief   System saved context.
        -:  132: * @details This structure represents the inner stack frame during a context
        -:  133: *          switch.
        -:  134: */
        -:  135:struct port_intctx {
        -:  136:  regx86  ebx;
        -:  137:  regx86  edi;
        -:  138:  regx86  esi;
        -:  139:  regx86  ebp;
        -:  140:  regx86  eip;
        -:  141:};
        -:  142:
        -:  143:/**
        -:  144: * @brief   Platform dependent part of the @p thread_t structure.
        -:  145: * @details In this port the structure just holds a pointer to the
        -:  146: *          @p port_intctx structure representing the stack pointer
        -:  147: *          at context switch time.
        -:  148: */
        -:  149:struct context {
        -:  150:  struct port_intctx *esp;
        -:  151:};
        -:  152:
        -:  153:/*===========================================================================*/
        -:  154:/* Module macros.                                                            */
        -:  155:/*===========================================================================*/
        -:  156:
        -:  157:#define APUSH(p, a) do {                                                    \
        -:  158:  (p) -= sizeof(void *);                                                    \
        -:  159:  *(void **)(p) = (void*)(a);                                               \
        -:  160:} while (false)
        -:  161:
        -:  162:/* Darwin requires the stack to be aligned to a 16-byte boundary at
        -:  163: * the time of a call instruction (in case the called function needs
        -:  164: * to save MMX registers). This aligns to 'mod' module 16, so that we'll end
        -:  165: * up with the right alignment after pushing the args. */
        -:  166:#define AALIGN(p, mask, mod)                                                \
        -:  167:  p = (void *)((((uint32_t)(p) - (uint32_t)(mod)) & ~(uint32_t)(mask)) + (uint32_t)(mod)) \
        -:  168:
        -:  169:/**
        -:  170: * @brief   Platform dependent part of the @p chThdCreateI() API.
        -:  171: * @details This code usually setup the context switching frame represented
        -:  172: *          by an @p port_intctx structure.
        -:  173: */
        -:  174:#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) {                 \
        -:  175:  /*lint -save -e611 -e9033 -e9074 -e9087 [10.8, 11.1, 11.3] Valid casts.*/ \
        -:  176:  uint8_t *esp = (uint8_t *)workspace + wsize;                              \
        -:  177:  APUSH(esp, 0);                                                            \
        -:  178:  uint8_t *savebp = esp;                                                    \
        -:  179:  AALIGN(esp, 15, 8);                                                       \
        -:  180:  APUSH(esp, arg);                                                          \
        -:  181:  APUSH(esp, pf);                                                           \
        -:  182:  APUSH(esp, 0);                                                            \
        -:  183:  esp -= sizeof(struct port_intctx);                                        \
        -:  184:  ((struct port_intctx *)esp)->eip = (void *)_port_thread_start;            \
        -:  185:  ((struct port_intctx *)esp)->ebx = NULL;                                  \
        -:  186:  ((struct port_intctx *)esp)->edi = NULL;                                  \
        -:  187:  ((struct port_intctx *)esp)->esi = NULL;                                  \
        -:  188:  ((struct port_intctx *)esp)->ebp = (void *)savebp;                        \
        -:  189:  (tp)->p_ctx.esp = (struct port_intctx *)esp;                              \
        -:  190:  /*lint -restore*/                                                         \
        -:  191:}
        -:  192:
        -:  193: /**
        -:  194: * @brief   Computes the thread working area global size.
        -:  195: * @note    There is no need to perform alignments in this macro.
        -:  196:  */
        -:  197:#define PORT_WA_SIZE(n) ((sizeof(void *) * 4U) +                            \
        -:  198:                         sizeof(struct port_intctx) +                       \
        -:  199:                         ((size_t)(n)) +                                    \
        -:  200:                         ((size_t)(PORT_INT_REQUIRED_STACK)))
        -:  201:
        -:  202:/**
        -:  203: * @brief   IRQ prologue code.
        -:  204: * @details This macro must be inserted at the start of all IRQ handlers
        -:  205: *          enabled to invoke system APIs.
        -:  206: */
        -:  207:#define PORT_IRQ_PROLOGUE() {                                               \
        -:  208:  port_isr_context_flag = true;                                             \
        -:  209:}
        -:  210:
        -:  211:/**
        -:  212: * @brief   IRQ epilogue code.
        -:  213: * @details This macro must be inserted at the end of all IRQ handlers
        -:  214: *          enabled to invoke system APIs.
        -:  215: */
        -:  216:#define PORT_IRQ_EPILOGUE() {                                               \
        -:  217:  port_isr_context_flag = false;                                            \
        -:  218:}
        -:  219:
        -:  220:
        -:  221:/**
        -:  222: * @brief   IRQ handler function declaration.
        -:  223: * @note    @p id can be a function name or a vector number depending on the
        -:  224: *          port implementation.
        -:  225: */
        -:  226:#define PORT_IRQ_HANDLER(id) void id(void)
        -:  227:
        -:  228:/**
        -:  229: * @brief   Fast IRQ handler function declaration.
        -:  230: * @note    @p id can be a function name or a vector number depending on the
        -:  231: *          port implementation.
        -:  232: */
        -:  233:#define PORT_FAST_IRQ_HANDLER(id) void id(void)
        -:  234:
        -:  235:/*===========================================================================*/
        -:  236:/* External declarations.                                                    */
        -:  237:/*===========================================================================*/
        -:  238:
        -:  239:extern bool port_isr_context_flag;
        -:  240:extern syssts_t port_irq_sts;
        -:  241:
        -:  242:#ifdef __cplusplus
        -:  243:extern "C" {
        -:  244:#endif
        -:  245:  /*lint -save -e950 [Dir-2.1] Non-ANSI keywords are fine in the port layer.*/
        -:  246:  __attribute__((fastcall)) void port_switch(thread_t *ntp, thread_t *otp);
        -:  247:  __attribute__((cdecl, noreturn)) void _port_thread_start(msg_t (*pf)(void *p),
        -:  248:                                                           void *p);
        -:  249:  /*lint -restore*/
        -:  250:  rtcnt_t port_rt_get_counter_value(void);
        -:  251:  void _sim_check_for_interrupts(void);
        -:  252:#ifdef __cplusplus
        -:  253:}
        -:  254:#endif
        -:  255:
        -:  256:/*===========================================================================*/
        -:  257:/* Module inline functions.                                                  */
        -:  258:/*===========================================================================*/
        -:  259:
        -:  260:/**
        -:  261: * @brief   Port-related initialization code.
        -:  262: */
function port_init called 1 returned 100% blocks executed 100%
        1:  263:static inline void port_init(void) {
        -:  264:
        1:  265:  port_irq_sts = (syssts_t)0;
        1:  266:  port_isr_context_flag = false;
        1:  267:}
        -:  268:
        -:  269:/**
        -:  270: * @brief   Returns a word encoding the current interrupts status.
        -:  271: *
        -:  272: * @return              The interrupts status.
        -:  273: */
function port_get_irq_status called 3 returned 100% blocks executed 100%
        3:  274:static inline syssts_t port_get_irq_status(void) {
        -:  275:
        3:  276:  return port_irq_sts;
unconditional  0 taken 100%
        -:  277:}
        -:  278:
        -:  279:/**
        -:  280: * @brief   Checks the interrupt status.
        -:  281: *
        -:  282: * @param[in] sts       the interrupt status word
        -:  283: *
        -:  284: * @return              The interrupt status.
        -:  285: * @retvel false        the word specified a disabled interrupts status.
        -:  286: * @retvel true         the word specified an enabled interrupts status.
        -:  287: */
function port_irq_enabled called 6 returned 100% blocks executed 100%
        6:  288:static inline bool port_irq_enabled(syssts_t sts) {
        -:  289:
        6:  290:  return sts == (syssts_t)0;
unconditional  0 taken 100%
        -:  291:}
        -:  292:
        -:  293:/**
        -:  294: * @brief   Determines the current execution context.
        -:  295: *
        -:  296: * @return              The execution context.
        -:  297: * @retval false        not running in ISR mode.
        -:  298: * @retval true         running in ISR mode.
        -:  299: */
function port_is_isr_context called 2 returned 100% blocks executed 100%
        2:  300:static inline bool port_is_isr_context(void) {
        -:  301:
        2:  302:  return port_isr_context_flag;
unconditional  0 taken 100%
        -:  303:}
        -:  304:
        -:  305:/**
        -:  306: * @brief   Kernel-lock action.
        -:  307: * @details In this port this function disables interrupts globally.
        -:  308: */
function port_lock called 1 returned 100% blocks executed 100%
function port_lock called 64514294 returned 100% blocks executed 100%
function port_lock called 6778427 returned 100% blocks executed 100%
function port_lock called 23 returned 100% blocks executed 100%
function port_lock called 119563852 returned 100% blocks executed 100%
function port_lock called 84417205 returned 100% blocks executed 100%
function port_lock called 15 returned 100% blocks executed 100%
function port_lock called 35 returned 100% blocks executed 100%
function port_lock called 78477372 returned 100% blocks executed 100%
function port_lock called 16 returned 100% blocks executed 100%
function port_lock called 39011542 returned 100% blocks executed 100%
function port_lock called 2 returned 100% blocks executed 100%
function port_lock called 41 returned 100% blocks executed 100%
392762825:  309:static inline void port_lock(void) {
        -:  310:
392762825:  311:  port_irq_sts = (syssts_t)1;
392762825:  312:}
        -:  313:
        -:  314:/**
        -:  315: * @brief   Kernel-unlock action.
        -:  316: * @details In this port this function enables interrupts globally.
        -:  317: */
function port_unlock called 1 returned 100% blocks executed 100%
function port_unlock called 48629864 returned 100% blocks executed 100%
function port_unlock called 6778427 returned 100% blocks executed 100%
function port_unlock called 23 returned 100% blocks executed 100%
function port_unlock called 119563852 returned 100% blocks executed 100%
function port_unlock called 84417205 returned 100% blocks executed 100%
function port_unlock called 15 returned 100% blocks executed 100%
function port_unlock called 35 returned 100% blocks executed 100%
function port_unlock called 78477372 returned 100% blocks executed 100%
function port_unlock called 16 returned 100% blocks executed 100%
function port_unlock called 39011542 returned 100% blocks executed 100%
function port_unlock called 2 returned 100% blocks executed 100%
function port_unlock called 41 returned 100% blocks executed 100%
376878395:  318:static inline void port_unlock(void) {
        -:  319:
376878395:  320:  port_irq_sts = (syssts_t)0;
376878395:  321:}
        -:  322:
        -:  323:/**
        -:  324: * @brief   Kernel-lock action from an interrupt handler.
        -:  325: * @details In this port this function disables interrupts globally.
        -:  326: * @note    Same as @p port_lock() in this port.
        -:  327: */
function port_lock_from_isr called 73 returned 100% blocks executed 100%
function port_lock_from_isr called 61 returned 100% blocks executed 100%
      134:  328:static inline void port_lock_from_isr(void) {
        -:  329:
      134:  330:  port_irq_sts = (syssts_t)1;
      134:  331:}
        -:  332:
        -:  333:/**
        -:  334: * @brief   Kernel-unlock action from an interrupt handler.
        -:  335: * @details In this port this function enables interrupts globally.
        -:  336: * @note    Same as @p port_lock() in this port.
        -:  337: */
function port_unlock_from_isr called 73 returned 100% blocks executed 100%
function port_unlock_from_isr called 61 returned 100% blocks executed 100%
      134:  338:static inline void port_unlock_from_isr(void) {
        -:  339:
      134:  340:  port_irq_sts = (syssts_t)0;
      134:  341:}
        -:  342:
        -:  343:/**
        -:  344: * @brief   Disables all the interrupt sources.
        -:  345: */
function port_disable called 0 returned 0% blocks executed 0%
    #####:  346:static inline void port_disable(void) {
        -:  347:
    #####:  348:  port_irq_sts = (syssts_t)1;
    #####:  349:}
        -:  350:
        -:  351:/**
        -:  352: * @brief   Disables the interrupt sources below kernel-level priority.
        -:  353: */
        -:  354:static inline void port_suspend(void) {
        -:  355:
        -:  356:  port_irq_sts = (syssts_t)1;
        -:  357:}
        -:  358:
        -:  359:/**
        -:  360: * @brief   Enables all the interrupt sources.
        -:  361: */
function port_enable called 1 returned 100% blocks executed 100%
        1:  362:static inline void port_enable(void) {
        -:  363:
        1:  364:  port_irq_sts = (syssts_t)0;
        1:  365:}
        -:  366:
        -:  367:/**
        -:  368: * @brief   Enters an architecture-dependent IRQ-waiting mode.
        -:  369: * @details The function is meant to return when an interrupt becomes pending.
        -:  370: *          The simplest implementation is an empty function or macro but this
        -:  371: *          would not take advantage of architecture-specific power saving
        -:  372: *          modes.
        -:  373: * @note    Implemented as an inlined @p WFI instruction.
        -:  374: */
function port_wait_for_interrupt called 269506521 returned 99% blocks executed 100%
269506521:  375:static inline void port_wait_for_interrupt(void) {
        -:  376:
269506521:  377:  _sim_check_for_interrupts();
call    0 returned 99%
269506520:  378:}
        -:  379:
        -:  380:#endif /* _CHCORE_H_ */
        -:  381:
        -:  382:/** @} */
