/*=============================================================================
   Readme file for Debugging in UEFI.

  Copyright (c) 2013, 2015 - 2016, 2018 - 2019 Qualcomm Technologies, Inc. All rights reserved.

                              EDIT HISTORY


 when       who     what, where, why
 --------   ---     -----------------------------------------------------------
 03/08/16   yg      Update documentation
 10/28/15   bh      Update after path-related changes
 10/27/15   bh      Update for multiple driver debugging
 03/05/15   bh      Update after unification of 32/64-bit scripts
 06/05/13   yg      Initial version
=============================================================================*/


Debugging UEFI
--------------

Note:
Replace all instance of <TargetPkg> with valid target folder in QcomPkg:
e.g: QcomPkg\<TargetPkg> is "QcomPkg\SocPkg\855"

 ---------------------------
| Pre requisites and Setup  |
 ---------------------------

  1) Supported T32 sofware
  2) Startup scripts and shortcuts from the source tree
  3) JTAG connected and Target powered
     - If sys.m.a on Core 0 should be able to establish sync with CPU
  4) Source tree with built binaries including symbols available


 -----------
| Debugging |
 -----------

  Main UEFI debug scripts are common across all targets and architecture states. Some of the params change per
  target, so the starting scripts are located in the target tools folders. The script instructions hold good for
  both 32-bit and 64-bit UEFI builds. 

  Usage:
    do debug_uefi.cmm [[ram,][rel,][tools,][menu]] [sec|dxe|go|drvr1[,drvr2][,drvr2]] 

  Optional Arguments: choose any or all of the following options in a sensible manner, separated by commas where required 
    REL   :     Debug RELEASE build instead of the DEBUG builds (DEBUG builds debugging is default)
    RAM   :     Load the UEFI binary built from the source tree into RAM and start debugging (without needing to flash)
    TOOLS :     Load the tools binary built from the source tree into RAM and start using tools (no need to flash)
    <xxx> :     Other possible options are to load any other image like tests, etc. Refer to the script for more details
    MENU  :     Stop in the BDS menu without needing to press hotkeys or change variables
  
  Modules to debug: specify the modules to debug 
    SEC   :     Debug Sec module and stop at SEC entry point function. If need to debug further modules, then press enter
                in the area window. This also continues to debug Dxe and stops at Dxe entry point (click on area window 
                and type continue in t32 to bring to focus)
    DXE   :     Debug Dxe module, stop at Dxe entry point DxeMain as debugging starts
    go    :     Mostly used in conjunction with RAM loading. Load image into RAM and go without needing to load
                any symbols further. This is the fastest way of seeing if things work fine without flashing UEFI/XBL.
                Symbols can be loaded later using symbol_load.cmm as needed.
    drvr  :     This is string that can be used to search in the driver name/path to stop and debug.
                For example: "do debug_uefi runtime" would stop at the entry point functions of the drivers 
                CapsuleRuntimeDxe, RuntimeDxe, ResetRuntimeDxe etc. Search is NOT case sensitive.
    mult drvrs: String containing up to 3 comma-separate driver or application names, that each work similar to
                the "drvr" command mentioned above. 


  Debugging using T32 can be done in the following ways. Few possible examples of each method is also listed.
  1) Load the UEFI image into RAM for temporary debugging
     - This method helps when the code changes in development is not proven yet to flash it, or might crash,
       or just plain to try in easiest way without flashing (although time consuming).

     a) In T32 session, cd to "QcomPkg\<TargetPkg>\Tools" and run the following commands
     b) "do debug_uefi.cmm ram go"
          Loads the image into ram and just runs without loading symbols
     c) "do debug_uefi.cmm ram sec"
          Loads the image into ram and load symbols and stop at entry points of Sec and Dxe for debugging
     d) "do debug_uefi.cmm ram dxe"
          Loads the image into ram and load symbols and stop at entry point of Dxe for debugging
     e) "do debug_uefi.cmm ram test"
          Loads the image into ram and load symbols as drivers load and stop at entry point of 
          the image whose name matches "test" anywhere in the path
     f) "do debug_uefi.cmm ram test1,test2,test3"
          Loads the image into ram and load symbols as drivers load and stop at entry point of 
          the images whose names match any of the comma separated arguments, anywhere in the path
     g) "do debug_uefi.cmm ram,tools go"
          Loads both UEFI and tools images into ram and continues to execute, nodebug, no symbol load
     h) "do debug_uefi.cmm ram,tools,menu go"
          Loads UEFI and tools images into RAM and automatically stops in BDS menu nodebug, no symbol load

  2) The image is flashed to the storage device and debug by loading symbols when interested driver images get loaded
     - In this method, source and built binaries are available for the image that's flashed on the device
     - SBL's load the UEFI image into RAM to execute

     a) In Apps Boot Core T32 session, cd to QcomPkg\<TargetPkg>\Tools
     b) "do debug_uefi.cmm sec"
          start debug session by synchronously loading the symbols as drivers load. Stops at entry points of Sec and Dxe
     c) "do debug_uefi.cmm dxe"
          start debug session by synchronously loading the symbols as drivers load. Stops at entry point of Dxe
     d) "do debug_uefi.cmm test"
          start debug session by synchronously loading the symbols as drivers load. Stops at entry
          point of the image whose name matches "test" anywhere in the path
     e) "do debug_uefi.cmm test"
          start debug session by synchronously loading the symbols as drivers load. Stops at entry
          point of the image whose names match any of the comma separated arguements, anywhere in the path

  3) The image is already flashed to the storage device and debug by loading
     all symbols one shot when the target can be stopped (eg in shell) or
     target crashed in UEFI
       - In this method, source and built binaries are available for the image that's programmed
       - target is in crashed state in UEFI or is in UEFI doing something (or crash dumps are loaded into T32 simulator)
       - After placing a bkpt continuing to run would load other additional images need loading symbols for them

       do symbol_load.cmm [FORCE,INCR]
         Force : If build paths are changed during debug sessions, override the stored build path with current path.
         Incr  : Incrementally load any additional symbols after the last load. Helps with fast symbol loading when
                 additional images get loaded when a bkpt is placed. Also helps retain symbols for other images (Like TZ/HYP etc) and
                 load UEFI symbols as well. Note since symbols are not cleared, there is a chance for stale symbols being
                 around might confuse the T32 IDE, when in doubt first use default symbol load which clears all loaded
                 symbol definitions (or issue y.reset first).

     a) In Apps Boot Core T32 session, 
          - cd to QcomPkg\<TargetPkg>\Tools
          - sys.m.a
          - do symbol_load.cmm
             - or click on S soft button shown in T32 window

     b) When a bkpt is hit after loading additional symbols or when need to load UEFI symbols with other image symbols retained
          - cd to QcomPkg\<TargetPkg>\Tools
          - sys.m.a (also do sys.u as needed in simulator for crash dumps)
          - do symbol_load.cmm INCR
             - or click on iSym soft button shown in T32 window

NOTE: Subsequent calls to debug scritps can be made from any directory after executing debug_uefi script from TargetPkg once

  --------------------------------------------------------------------------------
|                 Debugging multithread/multicores                                |
  --------------------------------------------------------------------------------

  Qualcomm UEFI provides T32 scripts that help in debugging multithreaded/multicore UEFI feature.

  - To use the following script symbols should have been loaded already
  - QcomPkg/Tools/cmm/show_thread.cmm is the script that lists all the active threads in the system
     - For each thread in the system most of the details of its status is also shown, and if its blocked, the
        object in question that kept it blocked and potentially who owns the object (only for mutex)
     - Looking at the threads status and other details help to debug any deadlock related problems
     - If the threads are actively running in other CPU cores (1-7), then T32 can be attached to those cores
        and debug using regular UEFI debug scripts (symbol_load, log etc)
     - If any thread is "NOT in running" state, it can be viewed by switching to it and observing its stack frame
     - To view the non running threads only any core, use the script with thread full name or address
        - With this except the top most function in stack frame everything else below that will be relevant to the
          thread in question
        - The CPU Core state has to be restored back to exact same state before continuing to execute further again
           - To do this, go down the stackframe completely and hit enter in the area window to restore (or just type
             continue in T32 cmd window and hit enter in area window)
     - If debug_uefi or symbol_load scripts were run atleast once, T32 will have 2 quick access buttons to display
       the complete thread list (Red "T") and some Gic/Timer configuration (Red "G") buttons.


