        -:    0:Source:../../../os/common/ports/SIMIA32/chcore.h
        -:    0:Programs:16
        -:    1:/*
        -:    2:    ChibiOS - Copyright (C) 2006..2016 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: * @name    Port Capabilities and Constants
        -:   37: * @{
        -:   38: */
        -:   39:/**
        -:   40: * @brief   This port supports a realtime counter.
        -:   41: */
        -:   42:#define PORT_SUPPORTS_RT                TRUE
        -:   43:
        -:   44:/**
        -:   45: * @brief   Natural alignment constant.
        -:   46: * @note    It is the minimum alignment for pointer-size variables.
        -:   47: */
        -:   48:#define PORT_NATURAL_ALIGN              sizeof (void *)
        -:   49:
        -:   50:/**
        -:   51: * @brief   Stack alignment constant.
        -:   52: * @note    It is the alignement required for the stack pointer.
        -:   53: */
        -:   54:#define PORT_STACK_ALIGN                sizeof (stkalign_t)
        -:   55:
        -:   56:/**
        -:   57: * @brief   Working Areas alignment constant.
        -:   58: * @note    It is the alignment to be enforced for thread working areas.
        -:   59: */
        -:   60:#define PORT_WORKING_AREA_ALIGN         sizeof (stkalign_t)
        -:   61:/** @} */
        -:   62:
        -:   63:/**
        -:   64: * @name    Architecture and Compiler
        -:   65: * @{
        -:   66: */
        -:   67:/**
        -:   68: * Macro defining the a simulated architecture into x86.
        -:   69: */
        -:   70:#define PORT_ARCHITECTURE_SIMIA32
        -:   71:
        -:   72:/**
        -:   73: * Name of the implemented architecture.
        -:   74: */
        -:   75:#define PORT_ARCHITECTURE_NAME          "Simulator"
        -:   76:
        -:   77:/**
        -:   78: * @brief   Name of the architecture variant (optional).
        -:   79: */
        -:   80:#define PORT_CORE_VARIANT_NAME          "x86 (integer only)"
        -:   81:
        -:   82:/**
        -:   83: * @brief   Name of the compiler supported by this port.
        -:   84: */
        -:   85:#define PORT_COMPILER_NAME              "GCC " __VERSION__
        -:   86:
        -:   87:/**
        -:   88: * @brief   Port-specific information string.
        -:   89: */
        -:   90:#define PORT_INFO                       "No preemption"
        -:   91:/** @} */
        -:   92:
        -:   93:/*===========================================================================*/
        -:   94:/* Module pre-compile time settings.                                         */
        -:   95:/*===========================================================================*/
        -:   96:
        -:   97:/**
        -:   98: * @brief   Stack size for the system idle thread.
        -:   99: * @details This size depends on the idle thread implementation, usually
        -:  100: *          the idle thread should take no more space than those reserved
        -:  101: *          by @p PORT_INT_REQUIRED_STACK.
        -:  102: */
        -:  103:#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
        -:  104:#define PORT_IDLE_THREAD_STACK_SIZE     256
        -:  105:#endif
        -:  106:
        -:  107:/**
        -:  108: * @brief   Per-thread stack overhead for interrupts servicing.
        -:  109: * @details This constant is used in the calculation of the correct working
        -:  110: *          area size.
        -:  111: */
        -:  112:#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
        -:  113:#define PORT_INT_REQUIRED_STACK         16384
        -:  114:#endif
        -:  115:
        -:  116:/**
        -:  117: * @brief   Enables an alternative timer implementation.
        -:  118: * @details Usually the port uses a timer interface defined in the file
        -:  119: *          @p chcore_timer.h, if this option is enabled then the file
        -:  120: *          @p chcore_timer_alt.h is included instead.
        -:  121: */
        -:  122:#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__)
        -:  123:#define PORT_USE_ALT_TIMER              FALSE
        -:  124:#endif
        -:  125:
        -:  126:/*===========================================================================*/
        -:  127:/* Derived constants and error checks.                                       */
        -:  128:/*===========================================================================*/
        -:  129:
        -:  130:#if CH_DBG_ENABLE_STACK_CHECK
        -:  131:#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
        -:  132:#endif
        -:  133:
        -:  134:/*===========================================================================*/
        -:  135:/* Module data structures and types.                                         */
        -:  136:/*===========================================================================*/
        -:  137:
        -:  138:/* The following code is not processed when the file is included from an
        -:  139:   asm module.*/
        -:  140:#if !defined(_FROM_ASM_)
        -:  141:
        -:  142:/**
        -:  143: * @brief   16 bytes stack and memory alignment enforcement.
        -:  144: */
        -:  145:typedef struct {
        -:  146:  uint8_t a[16];
        -:  147:} stkalign_t __attribute__((aligned(16)));
        -:  148:
        -:  149:/**
        -:  150: * @brief   Type of a generic x86 register.
        -:  151: */
        -:  152:typedef void *regx86;
        -:  153:
        -:  154:/**
        -:  155: * @brief   Interrupt saved context.
        -:  156: * @details This structure represents the stack frame saved during a
        -:  157: *          preemption-capable interrupt handler.
        -:  158: */
        -:  159:struct port_extctx {
        -:  160:};
        -:  161:
        -:  162:/**
        -:  163: * @brief   System saved context.
        -:  164: * @details This structure represents the inner stack frame during a context
        -:  165: *          switch.
        -:  166: */
        -:  167:struct port_intctx {
        -:  168:  regx86  ebx;
        -:  169:  regx86  edi;
        -:  170:  regx86  esi;
        -:  171:  regx86  ebp;
        -:  172:  regx86  eip;
        -:  173:};
        -:  174:
        -:  175:/**
        -:  176: * @brief   Platform dependent part of the @p thread_t structure.
        -:  177: * @details This structure usually contains just the saved stack pointer
        -:  178: *          defined as a pointer to a @p port_intctx structure.
        -:  179: */
        -:  180:struct port_context {
        -:  181:  struct port_intctx *sp;
        -:  182:};
        -:  183:
        -:  184:#endif /* !defined(_FROM_ASM_) */
        -:  185:
        -:  186:/*===========================================================================*/
        -:  187:/* Module macros.                                                            */
        -:  188:/*===========================================================================*/
        -:  189:
        -:  190:#define APUSH(p, a) do {                                                    \
        -:  191:  (p) -= sizeof(void *);                                                    \
        -:  192:  *(void **)(p) = (void*)(a);                                               \
        -:  193:} while (false)
        -:  194:
        -:  195:/* Darwin requires the stack to be aligned to a 16-byte boundary at
        -:  196: * the time of a call instruction (in case the called function needs
        -:  197: * to save MMX registers). This aligns to 'mod' module 16, so that we'll end
        -:  198: * up with the right alignment after pushing the args. */
        -:  199:#define AALIGN(p, mask, mod)                                                \
        -:  200:  p = (void *)((((uint32_t)(p) - (uint32_t)(mod)) & ~(uint32_t)(mask)) + (uint32_t)(mod)) \
        -:  201:
        -:  202:/**
        -:  203: * @brief   Platform dependent part of the @p chThdCreateI() API.
        -:  204: * @details This code usually setup the context switching frame represented
        -:  205: *          by an @p port_intctx structure.
        -:  206: */
        -:  207:#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) {                      \
        -:  208:  /*lint -save -e611 -e9033 -e9074 -e9087 [10.8, 11.1, 11.3] Valid casts.*/ \
        -:  209:  uint8_t *esp = (uint8_t *)wtop;                                           \
        -:  210:  APUSH(esp, 0);                                                            \
        -:  211:  uint8_t *savebp = esp;                                                    \
        -:  212:  AALIGN(esp, 15, 8);                                                       \
        -:  213:  APUSH(esp, arg);                                                          \
        -:  214:  APUSH(esp, pf);                                                           \
        -:  215:  APUSH(esp, 0);                                                            \
        -:  216:  esp -= sizeof(struct port_intctx);                                        \
        -:  217:  ((struct port_intctx *)esp)->eip = (void *)_port_thread_start;            \
        -:  218:  ((struct port_intctx *)esp)->ebx = NULL;                                  \
        -:  219:  ((struct port_intctx *)esp)->edi = NULL;                                  \
        -:  220:  ((struct port_intctx *)esp)->esi = NULL;                                  \
        -:  221:  ((struct port_intctx *)esp)->ebp = (void *)savebp;                        \
        -:  222:  (tp)->ctx.sp = (struct port_intctx *)esp;                                 \
        -:  223:  /*lint -restore*/                                                         \
        -:  224:}
        -:  225:
        -:  226: /**
        -:  227: * @brief   Computes the thread working area global size.
        -:  228: * @note    There is no need to perform alignments in this macro.
        -:  229:  */
        -:  230:#define PORT_WA_SIZE(n) ((sizeof (void *) * 4U) +                           \
        -:  231:                         sizeof (struct port_intctx) +                      \
        -:  232:                         ((size_t)(n)) +                                    \
        -:  233:                         ((size_t)(PORT_INT_REQUIRED_STACK)))
        -:  234:
        -:  235:/**
        -:  236: * @brief   Static working area allocation.
        -:  237: * @details This macro is used to allocate a static thread working area
        -:  238: *          aligned as both position and size.
        -:  239: *
        -:  240: * @param[in] s         the name to be assigned to the stack array
        -:  241: * @param[in] n         the stack size to be assigned to the thread
        -:  242: */
        -:  243:#define PORT_WORKING_AREA(s, n)                                             \
        -:  244:  stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
        -:  245:
        -:  246:/**
        -:  247: * @brief   IRQ prologue code.
        -:  248: * @details This macro must be inserted at the start of all IRQ handlers
        -:  249: *          enabled to invoke system APIs.
        -:  250: */
        -:  251:#define PORT_IRQ_PROLOGUE() {                                               \
        -:  252:  port_isr_context_flag = true;                                             \
        -:  253:}
        -:  254:
        -:  255:/**
        -:  256: * @brief   IRQ epilogue code.
        -:  257: * @details This macro must be inserted at the end of all IRQ handlers
        -:  258: *          enabled to invoke system APIs.
        -:  259: */
        -:  260:#define PORT_IRQ_EPILOGUE() {                                               \
        -:  261:  port_isr_context_flag = false;                                            \
        -:  262:}
        -:  263:
        -:  264:/**
        -:  265: * @brief   IRQ handler function declaration.
        -:  266: * @note    @p id can be a function name or a vector number depending on the
        -:  267: *          port implementation.
        -:  268: */
        -:  269:#define PORT_IRQ_HANDLER(id) void id(void)
        -:  270:
        -:  271:/**
        -:  272: * @brief   Fast IRQ handler function declaration.
        -:  273: * @note    @p id can be a function name or a vector number depending on the
        -:  274: *          port implementation.
        -:  275: */
        -:  276:#define PORT_FAST_IRQ_HANDLER(id) void id(void)
        -:  277:
        -:  278:/*===========================================================================*/
        -:  279:/* External declarations.                                                    */
        -:  280:/*===========================================================================*/
        -:  281:
        -:  282:/* The following code is not processed when the file is included from an
        -:  283:   asm module.*/
        -:  284:#if !defined(_FROM_ASM_)
        -:  285:
        -:  286:extern bool port_isr_context_flag;
        -:  287:extern syssts_t port_irq_sts;
        -:  288:
        -:  289:#ifdef __cplusplus
        -:  290:extern "C" {
        -:  291:#endif
        -:  292:  /*lint -save -e950 [Dir-2.1] Non-ANSI keywords are fine in the port layer.*/
        -:  293:  __attribute__((fastcall)) void port_switch(thread_t *ntp, thread_t *otp);
        -:  294:  __attribute__((cdecl, noreturn)) void _port_thread_start(msg_t (*pf)(void *p),
        -:  295:                                                           void *p);
        -:  296:  /*lint -restore*/
        -:  297:  rtcnt_t port_rt_get_counter_value(void);
        -:  298:  void _sim_check_for_interrupts(void);
        -:  299:#ifdef __cplusplus
        -:  300:}
        -:  301:#endif
        -:  302:
        -:  303:#endif /* !defined(_FROM_ASM_) */
        -:  304:
        -:  305:/*===========================================================================*/
        -:  306:/* Module inline functions.                                                  */
        -:  307:/*===========================================================================*/
        -:  308:
        -:  309:/* The following code is not processed when the file is included from an
        -:  310:   asm module.*/
        -:  311:#if !defined(_FROM_ASM_)
        -:  312:
        -:  313:/**
        -:  314: * @brief   Port-related initialization code.
        -:  315: */
function port_init called 1 returned 100% blocks executed 100%
        1:  316:static inline void port_init(void) {
        -:  317:
        1:  318:  port_irq_sts = (syssts_t)0;
        1:  319:  port_isr_context_flag = false;
        1:  320:}
        -:  321:
        -:  322:/**
        -:  323: * @brief   Returns a word encoding the current interrupts status.
        -:  324: *
        -:  325: * @return              The interrupts status.
        -:  326: */
function port_get_irq_status called 3 returned 100% blocks executed 100%
        3:  327:static inline syssts_t port_get_irq_status(void) {
        -:  328:
        3:  329:  return port_irq_sts;
unconditional  0 taken 100%
        -:  330:}
        -:  331:
        -:  332:/**
        -:  333: * @brief   Checks the interrupt status.
        -:  334: *
        -:  335: * @param[in] sts       the interrupt status word
        -:  336: *
        -:  337: * @return              The interrupt status.
        -:  338: * @retval false        the word specified a disabled interrupts status.
        -:  339: * @retval true         the word specified an enabled interrupts status.
        -:  340: */
function port_irq_enabled called 6 returned 100% blocks executed 100%
        6:  341:static inline bool port_irq_enabled(syssts_t sts) {
        -:  342:
        6:  343:  return sts == (syssts_t)0;
unconditional  0 taken 100%
        -:  344:}
        -:  345:
        -:  346:/**
        -:  347: * @brief   Determines the current execution context.
        -:  348: *
        -:  349: * @return              The execution context.
        -:  350: * @retval false        not running in ISR mode.
        -:  351: * @retval true         running in ISR mode.
        -:  352: */
function port_is_isr_context called 2 returned 100% blocks executed 100%
        2:  353:static inline bool port_is_isr_context(void) {
        -:  354:
        2:  355:  return port_isr_context_flag;
unconditional  0 taken 100%
        -:  356:}
        -:  357:
        -:  358:/**
        -:  359: * @brief   Kernel-lock action.
        -:  360: * @details In this port this function disables interrupts globally.
        -:  361: */
function port_lock called 1 returned 100% blocks executed 100%
function port_lock called 71854240 returned 100% blocks executed 100%
function port_lock called 0 returned 0% blocks executed 0%
function port_lock called 97502346 returned 100% blocks executed 100%
function port_lock called 70326724 returned 100% blocks executed 100%
function port_lock called 15 returned 100% blocks executed 100%
function port_lock called 45 returned 100% blocks executed 100%
function port_lock called 70134768 returned 100% blocks executed 100%
function port_lock called 6 returned 100% blocks executed 100%
function port_lock called 27 returned 100% blocks executed 100%
function port_lock called 1 returned 100% blocks executed 100%
function port_lock called 56 returned 100% blocks executed 100%
309818229:  362:static inline void port_lock(void) {
        -:  363:
309818229:  364:  port_irq_sts = (syssts_t)1;
309818229:  365:}
        -:  366:
        -:  367:/**
        -:  368: * @brief   Kernel-unlock action.
        -:  369: * @details In this port this function enables interrupts globally.
        -:  370: */
function port_unlock called 1 returned 100% blocks executed 100%
function port_unlock called 58228598 returned 100% blocks executed 100%
function port_unlock called 0 returned 0% blocks executed 0%
function port_unlock called 97502346 returned 100% blocks executed 100%
function port_unlock called 70326724 returned 100% blocks executed 100%
function port_unlock called 15 returned 100% blocks executed 100%
function port_unlock called 45 returned 100% blocks executed 100%
function port_unlock called 70134768 returned 100% blocks executed 100%
function port_unlock called 6 returned 100% blocks executed 100%
function port_unlock called 27 returned 100% blocks executed 100%
function port_unlock called 1 returned 100% blocks executed 100%
function port_unlock called 56 returned 100% blocks executed 100%
296192587:  371:static inline void port_unlock(void) {
        -:  372:
296192587:  373:  port_irq_sts = (syssts_t)0;
296192587:  374:}
        -:  375:
        -:  376:/**
        -:  377: * @brief   Kernel-lock action from an interrupt handler.
        -:  378: * @details In this port this function disables interrupts globally.
        -:  379: * @note    Same as @p port_lock() in this port.
        -:  380: */
function port_lock_from_isr called 54 returned 100% blocks executed 100%
function port_lock_from_isr called 53 returned 100% blocks executed 100%
      107:  381:static inline void port_lock_from_isr(void) {
        -:  382:
      107:  383:  port_irq_sts = (syssts_t)1;
      107:  384:}
        -:  385:
        -:  386:/**
        -:  387: * @brief   Kernel-unlock action from an interrupt handler.
        -:  388: * @details In this port this function enables interrupts globally.
        -:  389: * @note    Same as @p port_lock() in this port.
        -:  390: */
function port_unlock_from_isr called 54 returned 100% blocks executed 100%
function port_unlock_from_isr called 53 returned 100% blocks executed 100%
      107:  391:static inline void port_unlock_from_isr(void) {
        -:  392:
      107:  393:  port_irq_sts = (syssts_t)0;
      107:  394:}
        -:  395:
        -:  396:/**
        -:  397: * @brief   Disables all the interrupt sources.
        -:  398: */
function port_disable called 0 returned 0% blocks executed 0%
    #####:  399:static inline void port_disable(void) {
        -:  400:
    #####:  401:  port_irq_sts = (syssts_t)1;
    #####:  402:}
        -:  403:
        -:  404:/**
        -:  405: * @brief   Disables the interrupt sources below kernel-level priority.
        -:  406: */
        -:  407:static inline void port_suspend(void) {
        -:  408:
        -:  409:  port_irq_sts = (syssts_t)1;
        -:  410:}
        -:  411:
        -:  412:/**
        -:  413: * @brief   Enables all the interrupt sources.
        -:  414: */
function port_enable called 1 returned 100% blocks executed 100%
        1:  415:static inline void port_enable(void) {
        -:  416:
        1:  417:  port_irq_sts = (syssts_t)0;
        1:  418:}
        -:  419:
        -:  420:/**
        -:  421: * @brief   Enters an architecture-dependent IRQ-waiting mode.
        -:  422: * @details The function is meant to return when an interrupt becomes pending.
        -:  423: *          The simplest implementation is an empty function or macro but this
        -:  424: *          would not take advantage of architecture-specific power saving
        -:  425: *          modes.
        -:  426: * @note    Implemented as an inlined @p WFI instruction.
        -:  427: */
function port_wait_for_interrupt called 151281947 returned 99% blocks executed 100%
151281947:  428:static inline void port_wait_for_interrupt(void) {
        -:  429:
151281947:  430:  _sim_check_for_interrupts();
call    0 returned 99%
151281946:  431:}
        -:  432:
        -:  433:#endif /* !defined(_FROM_ASM_) */
        -:  434:
        -:  435:/*===========================================================================*/
        -:  436:/* Module late inclusions.                                                   */
        -:  437:/*===========================================================================*/
        -:  438:
        -:  439:#if !defined(_FROM_ASM_)
        -:  440:
        -:  441:#if CH_CFG_ST_TIMEDELTA > 0
        -:  442:#if !PORT_USE_ALT_TIMER
        -:  443:#include "chcore_timer.h"
        -:  444:#else /* PORT_USE_ALT_TIMER */
        -:  445:#include "chcore_timer_alt.h"
        -:  446:#endif /* PORT_USE_ALT_TIMER */
        -:  447:#endif /* CH_CFG_ST_TIMEDELTA > 0 */
        -:  448:
        -:  449:#endif /* !defined(_FROM_ASM_) */
        -:  450:
        -:  451:#endif /* CHCORE_H */
        -:  452:
        -:  453:/** @} */
