###
# GDB macros for analyzing RTEMS threads
#
#  10 July 2006 - Joel:
#    + Renamed all methods to start with rtems_ if public and rtems_helper_
#       if private
#    + Merged code to dump timer delta chain
#    + Added code to dump Classic Semaphores, Message Queues, and Regions
#    + Added support code to dump SuperCore Mutexes, Semaphores,
#        Message Queues, Thread Queues, and Heaps
#
#  TODO:
#    + rtems_task_backtrack is CPU specific.  How to fix?
#    + Need to detect when POSIX and ITRON are not configured so
#      a nice message is printed when those commands are used
#    + Add support for Classic API
#       - Periods
#       - Timers
#       - Partitions
#    + Add support for POSIX API
#       - Message Queues
#
# Commands implemented:
#    rtems_task_backtrack TCB
#    rtems_print_name name
#    rtems_internal_task index
#    rtems_internal_tasks
#    rtems_classic_tasks
#    rtems_classic_task index
#    rtems_classic_semaphore index
#    rtems_classic_semaphores
#    rtems_classic_message_queue index
#    rtems_classic_message_queues
#    rtems_classic_region index
#    rtems_classic_regions
#    rtems_posix_thread index
#    rtems_posix_threads
#    rtems_posix_semaphore index
#    rtems_posix_semaphores
#    rtems_posix_mutex index
#    rtems_posix_mutexes
#    rtems_tasks
#    rtems_internal_ticks_chain
#    rtems_internal_seconds_chain
#    rtems_malloc_walk
#    rtems_workspace_walk
#    rtems_tod
#    rtems_check_state
#

#############################################################################
########                   Public Helper Macros                      ########
#############################################################################

####################
# rtems_task_backtrack
#
# ABSTRACT
#    Print backtrace of an RTEMS task
#
# ARGUMENTS:
#    arg0 = pointer to the Thread_Control of the task.
#
define rtems_task_backtrack
  set $stkp = $arg0->Registers.gpr1
  set $stkp = *(void**)$stkp
  while $stkp != 0
      info line **((void**)$stkp+1)
    set $stkp = *(void**)$stkp
  end
end
document rtems_task_backtrack
  Usage: rtems_task_backtrack TCB
  Displays a stack trace for the specific task
end

####################
# rtems_print_name
#
# ABSTRACT
#    Print backtrace of an RTEMS task
#
# ARGUMENTS:
#    arg0 = object name -- 32 bit format
#
define rtems_print_name
        set $name = $arg0
  set $n0 = (char) ($name >> 24)
  if $n0 < ' ' || $n0 > 'z'
      set $n0=' '
  end
  printf "%c",$n0
  set $n1 = (char) (0xff & ($name >> 16))
  if $n1 < ' ' || $n1 > 'z'
      set $n1=' '
  end
  printf "%c",$n1
  set $n2 = (char) (0xff & ($name >> 8))
  if $n2 < ' ' || $n2 > 'z'
      set $n2=' '
  end
  printf "%c",$n2
  set $n3 = (char) (0xff & $name)
  if $n3 < ' ' || $n3 > 'z'
      set $n3=' '
  end
  printf "%c | ",$n3
end
document rtems_print_name
  Usage: rtems_print_name name
  Attempt to print the Classic API style name in ASCII
end

#############################################################################
########         Helper Macros - Use Only From Other Macros          ########
#############################################################################

####################
# rtems_helper_task_dump
#
# ABSTRACT
#    Print information about an RTEMS task
#
# ARGUMENTS
#    arg0 = Task index in the corresponding _Information table.
#    arg1 = pointer to the Thread_Control of the task.
#    arg2 = 1 for verbose output, 0 otherwise
#
define rtems_helper_task_dump
  set $d1t_num = $arg0
  set $pt = $arg1
  set $d1t_verbose = $arg2

  printf "%2d | ", $d1t_num
  set $id = $pt->Object.id
  set $name = (unsigned int)$pt->Object.name

        rtems_print_name $name
  printf "%08x | ",$id

  set $state = $pt->current_state
  set $pri = $pt->current_priority
  printf "%3d | ",$pri
  set $ticks = $pt->ticks_executed
  printf "%8d | ", $ticks

  if $state == 0
    printf "READY"
  end
  if $state & 1
    printf "DORM "
  end
  if $state & 2
    printf "SUSP "
  end
  if $state & 4
    printf "TRANS "
  end
  if $state & 8
    printf "DELAY "
  end
  if $state & 0x10
    printf "Wtime "
  end
  if $state & 0x20
    printf "Wbuf "
  end
  if $state & 0x40
    printf "Wseg "
  end
  if $state & 0x80
    printf "Wmsg "
  end
  if $state & 0x100
    printf "Wevnt "
  end
  if $state & 0x200
    printf "Wsem "
  end
  if $state & 0x400
    printf "Wmutex 0x%8x", $pt->Wait.id
  end
  if $state & 0x800
    printf "Wcvar "
  end
  if $state & 0x1000
    printf "Wjatx "
  end
  if $state & 0x2000
    printf "Wrpc "
  end
  if $state & 0x4000
    printf "Wrate "
  end
  if $state & 0x8000
    printf "Wsig "
  end
  if $state & 0x10000
    printf "Wisig "
  end

        printf "\n"
#    printf "\
#---+------+----------+-----+----------+------------------------------\n"
  if $d1t_verbose
     printf "\
BACKTRACE\n\
~~~~~~~~~\n"
     rtems_task_backtrack $pt
  end
end
# Internal Helper Do Not Document

####################
# rtems_helper_task_header
#
# ABSTRACT
#    Print the header of the task list table
#
define rtems_helper_task_header
    printf "\
=====================================================================\n"
  printf "\
 # | Name |    ID    | Pri |  Ticks   | State\n"
    printf "\
---+------+----------+-----+----------+------------------------------\n"
end
# Internal Helper Do Not Document

####################
# rtems_helper_show_task
#
# ABSTRACT
#    Support routine for verbose listing of a single task
#
# ARGUMENTS
#    arg0 = _Information table.
#    arg1 = index.
#
define rtems_helper_show_task
    rtems_helper_task_header
    set $pt = (Thread_Control *)$arg0.local_table[$arg1]
    rtems_helper_task_dump $arg1 $pt 1
end
# Internal Helper Do Not Document

####################
# rtems_helper_show_tasks
#
# ABSTRACT
#    Support routine for verbose listing of all tasks of a given class
#
# ARGUMENTS
#    arg0 = _Information table for the class (internal, classic, POSIX etc.).
#
define rtems_helper_show_tasks
  rtems_helper_task_header
  set $index = 1
  while $index <= $arg0.maximum
    set $pt = (Thread_Control *)$arg0.local_table[$index]
    if $pt != 0
    rtems_helper_task_dump $index $pt 0
    end
    set $index = $index + 1
  end
end
# Internal Helper Do Not Document

#############################################################################
########   Helper Macros For SuperCore - Use Only From Other Macros  ########
#############################################################################

####################
# rtems_helper_score_threadq
#
# ABSTRACT
#    Verbosely list a single SuperCore thread queue
#
# ARGUMENTS
#    arg0 = pointer to the thread queue
#
define rtems_helper_score_threadq
  set $tq = $arg0
  set $THREAD_QUEUE_DISCIPLINE_FIFO     = 0
  set $THREAD_QUEUE_DISCIPLINE_PRIORITY = 1

  if $tq->discipline == $THREAD_QUEUE_DISCIPLINE_FIFO
    printf "  FIFO - "
    set $limit = 1
  end

  if $tq->discipline == $THREAD_QUEUE_DISCIPLINE_PRIORITY
    printf "  PRIO - "
    set $limit = 3
  end


  # now walk them
  set $count = 0
  set $pri_index = 0
  set $queues = &$tq->Queues
  while $pri_index < $limit
    set $chain = &$queues.Priority[$pri_index]
    set $ptail = &$chain->permanent_null
    set $next = $chain->first
    while $next != $ptail
      set $t = (Thread_Control *)$next
      printf "0x%08x@%d ", $t->Object.id, $t->current_priority
      set $next = $next->next
      set $count = $count + 1
    end 
    set $pri_index = $pri_index + 1
  end
  if $count == 0
    printf "%s", "No waiting threads"
  end
end
# Internal Helper Do Not Document

####################
# rtems_helper_score_heap
#
# ABSTRACT
#    Verbosely list contents of a SuperCore Heap
#
# ARGUMENTS
#    arg0 = pointer to heap
#
define rtems_helper_score_heap
   set $heap = $arg0

   set $heapstart = $heap->start
   set $currentblock = $heapstart
   set $used = 0
   set $numused = 0
   set $free = 0
   set $numfree = 0
   while $currentblock->front_flag != 1
     if $currentblock->front_flag & 1
       if $arg0 != 0
 	printf "USED: %p %d\n", $currentblock, $currentblock->front_flag & ~1
       else
         printf "*"
       end
       set $used = $used + $currentblock->front_flag & ~1
       set $numused = $numused + 1
     else
       if $arg0 != 0
 	printf "FREE: %p %d\n", $currentblock, $currentblock->front_flag & ~1
       else
         printf "."
       end
       set $free = $free + $currentblock->front_flag & ~1
       set $numfree = $numfree + 1
     end
     set $currentblock = \
       (Heap_Block *)((char *)$currentblock + ($currentblock->front_flag&~1))
   end
   if $arg0 == 0
     printf "\n"
   end
   printf "TOTAL: %d (%d)\tUSED: %d (%d) \tFREE: %d (%d)\n", \
     $used + $free, $numused + $numfree, \
     $used, $numused, \
     $free, $numfree
end
# Internal Helper Do Not Document

####################
# rtems_helper_score_watchdog_chain
#
# ABSTRACT
#    Verbosely list a single SuperCore Watchdog chain
#
# ARGUMENTS
#    arg0 = pointer to Watchdog delta chain
#
define rtems_helper_score_watchdog_chain
  set $permt = &$arg0.permanent_null
  set $node = $arg0.first

  if $node == $permt
    printf "Empty\n"
  end
  while $node != $permt
   set $wnode = (Watchdog_Control *)$node
   #print $wnode
   printf "======================\n0x%x, %d handler=", \
      $wnode, $wnode.delta_interval
   print $wnode.routine
   print/x *$wnode
   set $node = $node.next
  end
end
# Internal Helper Do Not Document

####################
# rtems_helper_score_mutex
#
# ABSTRACT
#    Verbosely list a single SuperCore mutex
#
# ARGUMENTS
#    arg0 = pointer to the mutex
#
define rtems_helper_score_mutex
  set $m = $arg0
  set $CORE_MUTEX_DISCIPLINES_FIFO               = 0
  set $CORE_MUTEX_DISCIPLINES_PRIORITY           = 1
  set $CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT   = 2
  set $CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING   = 3

  set $d = $m->Attributes.discipline
  if $d == $CORE_MUTEX_DISCIPLINES_FIFO
    printf "FIFO "
  end
  if $d == $CORE_MUTEX_DISCIPLINES_PRIORITY
    printf "PRIO "
  end
  if $d == $CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT
    printf "INHT "
  end
  if $d == $CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
    printf "CEIL "
  end

  if $m->lock == 0 
    printf "LCK holder=0x%08x nest=%d\n", $m->holder_id, $m->nest_count
  else
    printf "UNL"
  end

  rtems_helper_score_threadq &$m->Wait_queue
end
# Internal Helper Do Not Document

####################
# rtems_helper_score_semaphore
#
# ABSTRACT
#    Verbosely list a single SuperCore semaphore
#
# ARGUMENTS
#    arg0 = pointer to the semaphore
#
define rtems_helper_score_semaphore
  set $s = $arg0

  if $s->count == 0 
    printf "Unavailable "
    rtems_helper_score_threadq &$s->Wait_queue
  else
    printf "Available Count=%d", $s->count
  end
end
# Internal Helper Do Not Document

####################
# rtems_helper_score_message_queue
#
# ABSTRACT
#    Verbosely list a single SuperCore Message Queue
#
# ARGUMENTS
#    arg0 = pointer to the message queue
#
define rtems_helper_score_message_queue
  set $mq = $arg0

  printf "%d/%d msgs ", \
    $mq->number_of_pending_messages, $mq->maximum_pending_messages
  if $mq->number_of_pending_messages == 0 
    rtems_helper_score_threadq &$mq->Wait_queue
  end
end
# Internal Helper Do Not Document

#############################################################################
########                     Internal Objects                        ########
#############################################################################

####################
# rtems_internal_task
#
# ABSTRACT
#    Verbosely list a single internal task
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_internal_task
  rtems_helper_show_task  _Thread_Internal_information $arg0
end
document rtems_internal_task
  Usage: rtems_internal_task index
  Displays detailed information about the specified internal RTEMS task
end

####################
# rtems_internal_tasks
#
# ABSTRACT
#    Dump all internal tasks
#
define rtems_internal_tasks
  rtems_helper_show_tasks  _Thread_Internal_information
end
document rtems_internal_tasks
  Usage: rtems_internal_tasks
  Displays a list of all internal RTEMS tasks
end

#############################################################################
########                        Classic API                          ########
#############################################################################

####################
# rtems_classic_tasks
#
# ABSTRACT
#    Dump all Classic tasks
#
define rtems_classic_tasks
  rtems_helper_show_tasks  _RTEMS_tasks_Information
end
document rtems_classic_tasks
  Usage: rtems_classic_tasks
  Displays a list of all Classic API RTEMS tasks
end

####################
# rtems_classic_task
#
# ABSTRACT
#    Verbosely list a single classic task
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_classic_task
  rtems_helper_show_task  _RTEMS_tasks_Information $arg0
end
document rtems_classic_task
  Usage: rtems_classic_task index
  Displays detailed information about the specified Classic API task
end

####################
# rtems_classic_semaphore
#
# ABSTRACT
#    Verbosely list a single Classic API semaphore
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_classic_semaphore

  set $d1t_num = $arg0
  set $inf = _Semaphore_Information
  set $sem = (Semaphore_Control *)$inf.local_table[$arg0]
  set $id = $sem->Object.id
  set $name = (unsigned int)$sem->Object.name

  printf "%2d | ", $d1t_num
        rtems_print_name $name
  printf "%08x | ",$id
  #  hack for is a mutex
  if $sem->attribute_set != 0
    printf "  Mutex "
    rtems_helper_score_mutex &$sem->Core_control.mutex 
  else
    printf "  Sem   " 
    rtems_helper_score_semaphore &$sem->Core_control.semaphore 
  end
  printf "\n"
  
end
document rtems_classic_semaphore
  Usage: rtems_classic_semaphore index
  Displays information about the specified Classic API Semaphore
end

####################
# rtems_classic_semaphores
#
# ABSTRACT
#    Verbosely list all Classic API semaphores
#
# ARGUMENTS: NONE
#
define rtems_classic_semaphores
  set $inf = _Semaphore_Information
  printf "\
=====================================================================\n"
  printf "\
 # | Name |    ID    | Information\n"
    printf "\
---+------+----------+-----------------------------------------------\n"
  set $index = 1
  while $index <= $inf.maximum
    set $pt = (Semaphore_Control *)$inf.local_table[$index]
    if $pt != 0
    rtems_classic_semaphore $index
    end
    set $index = $index + 1
  end
end
document rtems_classic_semaphores
  Usage: rtems_classic_semaphores
  Displays a list of all Classic API Semaphores
end


####################
# rtems_classic_message_queue
#
# ABSTRACT
#    Verbosely list a single Classic API Message Queue
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_classic_message_queue
  set $d1t_num = $arg0
  set $inf = _Message_queue_Information
  set $queue = (Message_queue_Control *)$inf.local_table[$arg0]
  set $id = $queue->Object.id
  set $name = (unsigned int)$queue->Object.name

  printf "%2d | ", $d1t_num
  rtems_print_name $name
  printf "%08x | ",$id
  rtems_helper_score_message_queue &$queue->message_queue 
  printf "\n"
end
document rtems_classic_message_queue
  Usage: rtems_classic_message_queue index
  Displays information about the specified Classic API Message Queue
end

####################
# rtems_classic_message_queues
#
# ABSTRACT
#    Verbosely list all Classic API Message Queues
#
# ARGUMENTS: NONE
#
define rtems_classic_message_queues
  set $inf = _Message_queue_Information
  printf "\
=====================================================================\n"
  printf "\
 # | Name |    ID    | Information\n"
    printf "\
---+------+----------+-----------------------------------------------\n"
  set $index = 1
  while $index <= $inf.maximum
    set $pt = (Message_queue_Control *)$inf.local_table[$index]
    if $pt != 0
    rtems_classic_message_queue $index
    end
    set $index = $index + 1
  end
end
document rtems_classic_message_queues
  Usage: rtems_classic_message_queues
  Displays a list of all Classic API Message Queues
end

####################
# rtems_classic_region
#
# ABSTRACT
#    Verbosely list a single Classic API Region
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_classic_region
  set $inf = _Region_Information
  set $d1t_num = $arg0
  set $r = (Region_Control *)$inf.local_table[$arg0]
  set $id = $r->Object.id
  set $name = (unsigned int)$r->Object.name

  printf "%2d | ", $d1t_num
  rtems_print_name $name
  printf "%08x | ",$id
  rtems_helper_score_heap &$r->Memory 
  printf "\n"
end
document rtems_classic_region
  Usage: rtems_classic_region index
  Displays information about the specified Classic API Region
end

####################
# rtems_classic_regions
#
# ABSTRACT
#    Verbosely list all Classic API Regions
#
# ARGUMENTS: NONE
#
define rtems_classic_regions
  set $inf = _Region_Information
  printf "\
=====================================================================\n"
  printf "\
 # | Name |    ID    | Information\n"
    printf "\
---+------+----------+-----------------------------------------------\n"
  set $index = 1
  while $index <= $inf.maximum
    set $pt = (Region_Control *)$inf.local_table[$index]
    if $pt != 0
    rtems_classic_region $index
    end
    set $index = $index + 1
  end
end
document rtems_classic_regions
  Usage: rtems_classic_regions
  Displays a list of all Classic API Regions
end

#############################################################################
########                          POSIX API                          ########
#############################################################################

####################
# rtems_posix_thread
#
# ABSTRACT
#    Verbosely list a single POSIX thread
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_posix_thread
  rtems_helper_show_task  _POSIX_Threads_Information $arg0
end
document rtems_posix_thread
  Usage: rtems_posix_thread index
  Displays detailed information about the specified POSIX API thread
end

####################
# rtems_posix_threads
#
# ABSTRACT
#    Dump all POSIX threads
#
# ARGUMENTS: NONE
#
define rtems_posix_threads
  rtems_helper_show_tasks  _POSIX_Threads_Information
end
document rtems_posix_threads
  Usage: rtems_posix_threads
  Displays a list of all POSIX API threads
end

####################
# rtems_posix_semaphore
#
# ABSTRACT
#    Verbosely list a single POSIX API semaphore
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_posix_semaphore

  set $d1t_num = $arg0
  set $inf = _POSIX_Semaphore_Information
  set $sem = (POSIX_Semaphore_Control *)$inf.local_table[$arg0]
  set $id = $sem->Object.id

  printf "%2d | ", $d1t_num
  if $sem->named
    printf "%s", (char *)$sem->Object.name
  end
  printf " %08x | ",$id
  rtems_helper_score_semaphore &$sem->Semaphore 
  printf "\n"
  
end
document rtems_posix_semaphore
  Usage: rtems_posix_semaphore index
  Displays information about the specified POSIX API Semaphore
end

####################
# rtems_posix_semaphores
#
# ABSTRACT
#    Verbosely list all POSIX API semaphores
#
# ARGUMENTS: NONE
#
define rtems_posix_semaphores
  set $inf = _POSIX_Semaphore_Information
  printf "\
=====================================================================\n"
  printf "\
 # |     ID    | Information\n"
    printf "\
---+-----------+-----------------------------------------------\n"
  set $index = 1
  while $index <= $inf.maximum
    set $pt = (POSIX_Semaphore_Control *)$inf.local_table[$index]
    if $pt != 0
    rtems_posix_semaphore $index
    end
    set $index = $index + 1
  end
end
document rtems_posix_semaphores
  Usage: rtems_posix_semaphores
  Displays a list of all POSIX API Semaphores
end

####################
# rtems_posix_mutex
#
# ABSTRACT
#    Verbosely list a single POSIX API mutex
#
# ARGUMENTS
#    arg0 = index in the _Information table
#
define rtems_posix_mutex

  set $d1t_num = $arg0
  set $inf = _POSIX_Mutex_Information
  set $mutex = (POSIX_Mutex_Control *)$inf.local_table[$arg0]
  set $id = $mutex->Object.id

  printf "%2d | ", $d1t_num
  printf "%08x | ",$id
  rtems_helper_score_mutex &$mutex->Mutex 
  printf "\n"
  
end
document rtems_posix_mutex
  Usage: rtems_posix_mutex index
  Displays information about the specified POSIX API Semaphore
end

####################
# rtems_posix_mutexes
#
# ABSTRACT
#    Verbosely list all POSIX API mutexes
#
# ARGUMENTS: NONE
#
define rtems_posix_mutexes
  set $inf = _POSIX_Mutex_Information
  printf "\
=====================================================================\n"
  printf "\
 # |    ID    | Information\n"
    printf "\
---+----------+-----------------------------------------------\n"
  set $index = 1
  while $index <= $inf.maximum
    set $pt = (POSIX_Mutex_Control *)$inf.local_table[$index]
    if $pt != 0
    rtems_posix_mutex $index
    end
    set $index = $index + 1
  end
end
document rtems_posix_mutexes
  Usage: rtems_posix_mutexes
  Displays a list of all POSIX API Mutexes
end

#############################################################################
########                    General and Cross API                    ########
#############################################################################

####################
# rtems_tasks
#
# ABSTRACT
#    Dump all tasks of all classes (internal, POSIX and Classic)
#
# ARGUMENTS: NONE
#
# TODO: For 4.6, check object information table for non-NULL
define rtems_tasks
  printf "Executing: 0x%x, Heir: 0x%x\n", _Thread_Executing->Object.id, \
    _Thread_Heir.Object.id
  printf "================================================================\n"
  printf "Internal Tasks\n"
  rtems_helper_show_tasks  _Thread_Internal_information
  printf "================================================================\n"
  printf "Classic Tasks\n"
  rtems_helper_show_tasks  _RTEMS_tasks_Information
  printf "================================================================\n"
  printf "POSIX Tasks\n"
  rtems_helper_show_tasks  _POSIX_Threads_Information
end
document rtems_tasks
  Usage: rtems_tasks
  Displays a list of all internal and API defined tasks/threads
end

####################
# rtems_internal_ticks_chain
#
# ABSTRACT
#    Verbosely list contents of ticks chain tickled from clock tick
#
# ARGUMENTS: NONE
#
define rtems_internal_ticks_chain
  rtems_helper_score_watchdog_chain _Watchdog_Ticks_chain
end
document rtems_internal_ticks_chain
  Usage: rtems_internal_ticks_chain
  Lists the contains of the internal RTEMS delta chain used to manage
  all timing events that are tick based.  This chain will contain
  timeouts, delays, API defined timers, and the TOD update timer.
end

####################
# rtems_internal_seconds_chain
#
# ABSTRACT
#    Verbosely list contents of seconds chain tickled from clock tick
#
# ARGUMENTS: NONE
#
define rtems_internal_seconds_chain
  rtems_helper_score_watchdog_chain _Watchdog_Seconds_chain
end
document rtems_internal_seconds_chain
  Usage: rtems_internal_seconds_chain
  Lists the contains of the internal RTEMS delta chain used to manage
  all timing events that are TOD based.
end

####################
# rtems_malloc_walk
#
# ABSTRACT
#    Verbosely list the contents and state of the C Program Heap
#
# ARGUMENTS: None
#
define rtems_malloc_walk
  set $heap = &(((Region_Control *)\
    _Region_Information->local_table[RTEMS_Malloc_Heap&0xffff])->Memory)
   
  rtems_helper_score_heap $heap
end
document rtems_malloc_walk
  Usage: rtems_malloc_walk
  Display information about the C program heap
end

####################
# rtems_workspace_walk
#
# ABSTRACT
#    Verbosely list the contents and state of the C Program Heap
#
# ARGUMENTS: None
#
define rtems_workspace_walk
  set $heap = &_Workspace_Area

  rtems_helper_score_heap $heap
end
document rtems_workspace_walk
  Usage: rtems_workspace_walk
  Display information about the RTEMS Executive Workspace
end

####################
# rtems_tod
#
# ABSTRACT
#    Print out the current time of day
#
# ARGUMENTS: NONE
#
define rtems_tod
  printf "Current Time MM/DD/YYYY HH:MM:SS -- %02d/%02d/%d %02d:%02d:%02d\n", \
    _TOD_Current.month, _TOD_Current.day, _TOD_Current.year, \
    _TOD_Current.hour, _TOD_Current.minute, _TOD_Current.second
end
document rtems_tod
  Usage: rtems_tod
  Display the current time of day according to RTEMS
  NOTE: If the TOD is not set, it will start at 1988.
end

####################
# rtems_check_state
#
# ABSTRACT
#    Check system state, dispatching critical section and ISR states
#
# ARGUMENTS: NONE
#
define rtems_check_state

  printf "RTEMS System State is: \n    "
  p _System_state_Current
  # Check Thread Dispatching Critical Sections
  set $tddl = _Thread_Dispatch_disable_level
  if $tddl == 0
    printf "NOT inside dispatching critical section\n"
  end
  if $tddl != 0
    printf "Inside dispatching critical section -- level = %d\n", $tddl
    if $tddl >= 100
      printf "HIGHLY PROBABLY DISPATCHING CRITICAL SECTION ERROR\n"
    end
  end

  # Check ISR Nesting and Dispatching Critical Sections
  set $isrnl = _ISR_Nest_level
  if $isrnl == 0
    printf "NOT inside an ISR\n"
  end
  if $isrnl != 0
    printf "Inside interrupt -- nest level = %d\n", $isrnl
    if $isrnl > $tddl
      printf "HIGHLY PROBABLY DISPATCHING CRITICAL SECTION ERROR\n"
      printf "ISR NEST LEVEL SHOULD ALWAYS BE >= DISPATCH DISABLE LEVEL\n"
    end
    if $isrnl < $tddl
      printf "It looks like you interrupted a dispatching critical section\n"
    end
  end
end
document rtems_check_state
  Usage: rtems_check_state
  This method displays information about the current state of RTEMS including
  dispatching disable critical sections and ISR nesting.  It performs some
  rudimentary consistency checks which might highlight problems.
end


