/*************************************************************************
*
*             Copyright 2006 Mentor Graphics Corporation
*                         All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
*************************************************************************/
/*************************************************************************
*
*   FILE NAME
*
*       ppc_debug.c
*
*   DESCRIPTION
*
*       This file contains the architecture debug functions
*
*       NOTE: The debugging support is designed around the GNU GDB
*             Remote Serial Protocol (RSP) specification.
*
*   FUNCTIONS
*
*       esal_ar_dbg_reg_map_blank
*       esal_ar_dbg_reg_map_info
*       esal_ar_dbg_reg_read_internal
*       esal_ar_dbg_reg_write_internal
*       esal_ar_dbg_breakpoint_handler
*       esal_ar_dbg_data_abort_handler
*       esal_ar_dbg_hardware_step_handler
*
*       ESAL_AR_DBG_Reg_Read
*       ESAL_AR_DBG_Reg_Write
*       ESAL_AR_DBG_Reg_Block_Read
*       ESAL_AR_DBG_Reg_Block_Write
*       ESAL_AR_DBG_Reg_Expedite_Read
*       ESAL_AR_DBG_Opcode_Read
*       ESAL_AR_DBG_Opcode_Write
*       ESAL_AR_DBG_Opcode_Nop_Get
*       ESAL_AR_DBG_Opcode_Brk_Get
*       ESAL_AR_DBG_Int_Read
*       ESAL_AR_DBG_Int_Write
*       ESAL_AR_DBG_Int_Enable
*       ESAL_AR_DBG_Int_Disable
*       ESAL_AR_DBG_Step_Addr_Get
*       ESAL_AR_DBG_Hardware_Step
*       ESAL_AR_DBG_Get_Support_Flags
*       ESAL_AR_DBG_Set_Protocol
*       ESAL_AR_DBG_Initialize
*       ESAL_AR_DBG_Terminate
*
*   DEPENDENCIES
*
*       nucleus.h
*       nucleus_gen_cfg.h
*       plus_core.h
*
*************************************************************************/

/* Include required header files */
#include            "nucleus.h"
#include            "nucleus_gen_cfg.h"
#include            "kernel/plus_core.h"

/* Exception handler */
VOID **(*ESAL_AR_DBG_OS_Exception_Handler)(VOID *stack_ptr);
UINT32                                  ESAL_AR_DBG_Exception_Return;
UINT32                                  ESAL_AR_DBG_Exception_MSR;
UINT32                                  ESAL_AR_DBG_Hardware_Step_MSR;

/* Generic debug operation flag */
extern INT                              ESAL_GE_DBG_Debug_Operation;

/* Generic exception handlers */
extern VOID **                          (*ESAL_GE_DBG_OS_Breakpoint_Handler)(VOID * stack_ptr);
extern VOID **                          (*ESAL_GE_DBG_OS_Hardware_Step_Handler)(VOID * stack_ptr);
extern VOID **                          (*ESAL_GE_DBG_OS_Data_Abort_Handler)(VOID * stack_ptr);

/* A matrix of register mappings into stack frame structures for the
   architecture supported. The order of register offset should match with
   the register numbers defined.  All arrays should include mappings for
   every register to support block register access even if the stack frame
   does not include all registers.  Note that the array size for each
   stack frame type goes up to the maximum register ID value to support
   access through array indexing based on a register ID. */
static  ESAL_AR_DBG_REG_MAP             esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_COUNT][ESAL_AR_DBG_REG_ID_MAX];

/* Local definitions */
typedef VOID (*ESAL_AR_DBG_EXCEPTION_HANDLER)(INT       exception_vector,
                                              VOID *    stack_ptr);

/* Original exception handlers */
ESAL_AR_DBG_EXCEPTION_HANDLER           ESAL_AR_DBG_Orig_Breakpoint_Handler;
ESAL_AR_DBG_EXCEPTION_HANDLER           ESAL_AR_DBG_Orig_Data_Abort_Handler;
ESAL_AR_DBG_EXCEPTION_HANDLER           ESAL_AR_DBG_Orig_Hardware_Step_Handler;

/* Local function prototypes */

static VOID esal_ar_dbg_reg_map_blank(ESAL_AR_DBG_REG_MAP *    p_map);

static INT esal_ar_dbg_reg_map_info(VOID *              p_stack_frame,
                                    INT                 stack_frame_type,
                                    INT                 reg_no,
                                    INT *               p_stack_type,
                                    INT *               p_reg_offset,
                                    UINT8 *             p_reg_size);

static INT esal_ar_dbg_reg_read_internal(VOID *              p_stack_frame,
                                         INT                 stack_frame_type,
                                         INT                 reg_no,
                                         VOID *              reg_val,
                                         UINT8 *             reg_size);

static INT esal_ar_dbg_reg_write_internal(VOID *               p_stack_frame,
                                          INT                  stack_frame_type,
                                          INT                  reg_no,
                                          VOID *               reg_val,
                                          UINT8 *              reg_size);

static VOID esal_ar_dbg_breakpoint_handler(INT exception_vector,
                                           VOID *stack_ptr);

static VOID esal_ar_dbg_data_abort_handler(INT exception_vector,
                                           VOID *stack_ptr);

/* Local functions */

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_reg_map_blank
*
*   DESCRIPTION
*
*       This function initializes a register map.
*
*       NOTE: Floating Point registers must be in the map whether they are
*             supported or not in Nucleus since GDB expects them.
*
*   INPUTS
*
*       p_map - Pointer to the register map structure.
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
static VOID esal_ar_dbg_reg_map_blank(ESAL_AR_DBG_REG_MAP *    p_map)
{
    INT     i;

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0)

    INT     fpu_reg_id[] = {ESAL_AR_DBG_REG_F0,
                            ESAL_AR_DBG_REG_F1,
                            ESAL_AR_DBG_REG_F2,
                            ESAL_AR_DBG_REG_F3,
                            ESAL_AR_DBG_REG_F4,
                            ESAL_AR_DBG_REG_F5,
                            ESAL_AR_DBG_REG_F6,
                            ESAL_AR_DBG_REG_F7,
                            ESAL_AR_DBG_REG_F8,
                            ESAL_AR_DBG_REG_F9,
                            ESAL_AR_DBG_REG_F10,
                            ESAL_AR_DBG_REG_F11,
                            ESAL_AR_DBG_REG_F12,
                            ESAL_AR_DBG_REG_F13,
                            ESAL_AR_DBG_REG_F14,
                            ESAL_AR_DBG_REG_F15,
                            ESAL_AR_DBG_REG_F16,
                            ESAL_AR_DBG_REG_F17,
                            ESAL_AR_DBG_REG_F18,
                            ESAL_AR_DBG_REG_F19,
                            ESAL_AR_DBG_REG_F20,
                            ESAL_AR_DBG_REG_F21,
                            ESAL_AR_DBG_REG_F22,
                            ESAL_AR_DBG_REG_F23,
                            ESAL_AR_DBG_REG_F24,
                            ESAL_AR_DBG_REG_F25,
                            ESAL_AR_DBG_REG_F26,
                            ESAL_AR_DBG_REG_F27,
                            ESAL_AR_DBG_REG_F28,
                            ESAL_AR_DBG_REG_F29,
                            ESAL_AR_DBG_REG_F30,
                            ESAL_AR_DBG_REG_F31};

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0) */

    /* Initialize all register mapping table to default values. */
    for (i = 0; i < ESAL_AR_DBG_REG_ID_MAX; i++)
    {
        p_map[i].offset = ESAL_AR_DBG_REG_NOT_MAPPED;
        p_map[i].size = 4;
    }

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0)

    /* Initialize FPU registers in mapping table. */
    for (i = 0; i < (sizeof(fpu_reg_id) / sizeof(INT)); i++)
    {
        p_map[fpu_reg_id[i]].size = 8;
    }

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0) */

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1)

    /* Initialize SPE registers in mapping table. */
    p_map[ESAL_AR_DBG_REG_ACC].size = 8;

    /* Initialize invalid registers in the mapping table. */
    p_map[ESAL_AR_DBG_REG_UNUSED_0].offset = ESAL_AR_DBG_REG_INVALID;
    p_map[ESAL_AR_DBG_REG_UNUSED_1].offset = ESAL_AR_DBG_REG_INVALID;
    p_map[ESAL_AR_DBG_REG_UNUSED_2].offset = ESAL_AR_DBG_REG_INVALID;

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1) */

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_reg_map_info
*
*   DESCRIPTION
*
*       This function provides the register map information for the
*       specified register.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_no - Register number.
*
*       p_stack_type - Return parameter that will be updated to contain
*                      the stack type in which the register resides if the
*                      operation is successful.  If the operation fail the
*                      value is undefined.
*
*       p_reg_offset - Return parameter that will be updated to contain
*                      the offset of the register into the provided stack
*                      frame if the operation is successful.  If the
*                      operation fails the value is undefined.
*
*       p_reg_size - Return parameter that will be updated to contain the
*                    size (in bytes) of the register value if the
*                    operation is successful.  If the operation fails the
*                    value is undefined.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates a successful read of the requested register.
*
*       NU_FALSE - Indicates an error or register is unavailable.
*
*************************************************************************/
static INT esal_ar_dbg_reg_map_info(VOID *              p_stack_frame,
                                    INT                 stack_frame_type,
                                    INT                 reg_no,
                                    INT *               p_stack_type,
                                    INT *               p_reg_offset,
                                    UINT8 *             p_reg_size)
{
    INT     esal_status;

    /* Determine how to proceed based on the stack frame type. */
    if ((stack_frame_type == ESAL_GE_DBG_STACK_FRAME_TYPE_THREAD) ||
        (stack_frame_type == ESAL_GE_DBG_STACK_FRAME_TYPE_EXCEPTION))
    {
        /* Get stack type based on stack frame type. */
        if (stack_frame_type == ESAL_GE_DBG_STACK_FRAME_TYPE_THREAD)
        {
            /* Thread stack frames may be either solicited (tool-set) or
               unsolicited (full architecture) */
            *p_stack_type = ESAL_GE_STK_TYPE_GET(p_stack_frame);
        }
        else
        {
            /* Exception stack frames are minimum architecture stack
               type. */
            *p_stack_type = ESAL_AR_DBG_STK_TYPE_EXCEPT;
        }

        /* Obtain register offset and size from register mapping */
        *p_reg_offset = esal_ar_dbg_reg_mappings[*p_stack_type][reg_no].offset;
        *p_reg_size = esal_ar_dbg_reg_mappings[*p_stack_type][reg_no].size;

        /* Indicate success */
        esal_status = NU_TRUE;

    }
    else
    {
        /* ERROR: Invalid stack frame type. */
        esal_status = NU_FALSE;

    }

    return (esal_status);
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_reg_read_internal
*
*   DESCRIPTION
*
*       This function reads the complete register information.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_no - Register number.
*
*       reg_val - Memory space large enough to contain the largest
*                 possible register value that may be returned.  Upon
*                 success, this memory will be updated with the value
*                 of the register (may be smaller than provided space).
*
*       reg_size - Return parameter that will be updated to contain the
*                  size (in bytes) of the register value if the operation
*                  is successful.  If the operation fails the value is
*                  undefined.*
*
*   OUTPUTS
*
*       ESAL_AR_DBG_REG_MAPPED - Indicates a successful read of the
*                                requested register.
*
*       ESAL_AR_DBG_REG_NOT_MAPPED - Indicates register is not mapped or
*                                    is not present in the stack frame.
*
*       ESAL_AR_DBG_REG_INVALID - Indicates register number is invalid.
*
*************************************************************************/
static INT esal_ar_dbg_reg_read_internal(VOID *              p_stack_frame,
                                         INT                 stack_frame_type,
                                         INT                 reg_no,
                                         VOID *              reg_val,
                                         UINT8 *             reg_size)
{
    INT     ret_val;
    INT     esal_status;
    INT     stack_type;
    INT     reg_offset;

    /* Get register information from register map */
    esal_status = esal_ar_dbg_reg_map_info(p_stack_frame,
                                           stack_frame_type,
                                           reg_no,
                                           &stack_type,
                                           &reg_offset,
                                           reg_size);

    if (esal_status == NU_TRUE)
    {
        /* Obtain the register value */
        switch (reg_offset)
        {
            case ESAL_AR_DBG_REG_STACK_POINTER:
            {
                /* SP register should be calculated depending on stack
                   type */
                switch (stack_type)
                {
                    case ESAL_AR_DBG_STK_TYPE_SOL:
                    {
                        /* Get SP value for solicited stack frame */
                        *((UINT32 *)reg_val) = (UINT32)p_stack_frame + ESAL_GE_STK_MIN_FRAME_SIZE;

                        /* Indicate success. */
                        ret_val = ESAL_AR_DBG_REG_MAPPED;

                        break;
                    }

                    case ESAL_AR_DBG_STK_TYPE_UNSOL:
                    {
                        /* Get SP value for unsolicited stack frame */
                        *((UINT32 *)reg_val) = (UINT32)p_stack_frame + ESAL_GE_STK_MAX_FRAME_SIZE;

                        /* Indicate success. */
                        ret_val = ESAL_AR_DBG_REG_MAPPED;

                        break;
                    }

                    case ESAL_AR_DBG_STK_TYPE_EXCEPT:
                    {
                        /* Get SP value for exception stack frame */
                        *((UINT32 *)reg_val) = (UINT32)p_stack_frame + ESAL_AR_DBG_STK_MIN_FRAME_SIZE;

                        /* Indicate success. */
                        ret_val = ESAL_AR_DBG_REG_MAPPED;

                        break;
                    }

                    default:
                    {
                        /* ERROR: Indicate unknown stack type */
                        ret_val = ESAL_AR_DBG_REG_NOT_MAPPED;

                        break;
                    }

                }

                break;
            }

            case ESAL_AR_DBG_REG_NOT_MAPPED:
            {
                /* ERROR: Indicate register is not mapped. */
                ret_val = ESAL_AR_DBG_REG_NOT_MAPPED;

                break;
            }

            case ESAL_AR_DBG_REG_INVALID:
            {
                /* ERROR: Indicate register is invalid. */
                ret_val = ESAL_AR_DBG_REG_INVALID;

                break;
            }

            default:
            {
                /* Read register value from stack. */
                ESAL_GE_MEM_Copy(reg_val, (p_stack_frame + reg_offset), *reg_size);

                /* Indicate success. */
                ret_val = ESAL_AR_DBG_REG_MAPPED;

                break;
            }

        }

    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_reg_write_internal
*
*   DESCRIPTION
*
*       This function write register stored in stack.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_no - Register number.
*
*       reg_val - Register value to write.  NOTE: the write size is
*                 predetermined by the register number.
*
*       reg_size - Return parameter that will be updated to indicate the
*                  size of the register data written if the operation is
*                  successful.  If the operation fails the value is
*                  undetermined.
*
*   OUTPUTS
*
*       ESAL_AR_DBG_REG_MAPPED - Indicates a successful write of the
*                                requested register.
*
*       ESAL_AR_DBG_REG_NOT_MAPPED - Indicates register is not mapped or
*                                    is not present in the stack frame or
*                                    cannot be written.
*
*       ESAL_AR_DBG_REG_INVALID - Indicates register number is invalid.
*
*************************************************************************/
static INT esal_ar_dbg_reg_write_internal(VOID *               p_stack_frame,
                                          INT                  stack_frame_type,
                                          INT                  reg_no,
                                          VOID *               reg_val,
                                          UINT8 *              reg_size)
{
    INT     ret_val;
    INT     esal_status;
    INT     stack_type;
    INT     reg_offset;

    ESAL_GE_MEM_DCACHE_ALL_FLUSH_INVAL();
    ESAL_GE_MEM_ICACHE_ALL_INVALIDATE();

    /* Get register information from register map */
    esal_status = esal_ar_dbg_reg_map_info(p_stack_frame,
                                           stack_frame_type,
                                           reg_no,
                                           &stack_type,
                                           &reg_offset,
                                           reg_size);

    if (esal_status == NU_TRUE)
    {
        /* Attempt to write the register value based on the offset */
        switch (reg_offset)
        {
            case ESAL_AR_DBG_REG_STACK_POINTER:
            case ESAL_AR_DBG_REG_NOT_MAPPED:
            {
                /* ERROR: Writing SP register is not allowed or register
                   is not present in stack frame or just not mapped. */
                ret_val = ESAL_AR_DBG_REG_NOT_MAPPED;

                break;
            }

            case ESAL_AR_DBG_REG_INVALID:
            {
                /* ERROR: Indicate register number is invalid. */
                ret_val = ESAL_AR_DBG_REG_INVALID;

                break;
            }

            default:
            {
                /* Write register value to stack. */
                memcpy((p_stack_frame + reg_offset), reg_val, *reg_size);

                /* Indicate success. */
                ret_val = ESAL_AR_DBG_REG_MAPPED;

                break;
            }

        }

    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_breakpoint_handler
*
*   DESCRIPTION
*
*       This is the breakpoint handler for the architecture.
*
*   INPUTS
*
*       exception_vector - The exception vector number.
*
*       stack_ptr - Pointer to the exception stack frame.
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
static VOID esal_ar_dbg_breakpoint_handler(INT          exception_vector,
                                           VOID *       stack_ptr)
{
    ESAL_AR_STK_MIN *   stk_frame = (ESAL_AR_STK_MIN *)stack_ptr;
    UINT32              exception_opcode;
    INT                 brk_exception;

    /* Read the exception opcode */
    exception_opcode = ESAL_GE_MEM_READ32(stk_frame -> rtn_address);

    /* Set flag based on if a breakpoint was hit or not */
    brk_exception = (exception_opcode == ESAL_AR_DBG_PPC_BRK_OPCODE);

    /* Check if this is a breakpoint exception */
    if (brk_exception)
    {
        /* Save exception return address and MSR from stack */
        ESAL_AR_DBG_Exception_Return = stk_frame -> rtn_address;
        ESAL_AR_DBG_Exception_MSR = stk_frame -> msr;

        /* Set the generic exception handler for breakpoints. */
        ESAL_AR_DBG_OS_Exception_Handler = ESAL_GE_DBG_OS_Breakpoint_Handler;

        /* Change exception return address so an unsolicited context can
           be saved and control returned to the OS */
        stk_frame -> rtn_address = (UINT32)ESAL_AR_DBG_Exception_Exit;

        /* Ensure interrupts stay locked-out */
        stk_frame -> msr &= ~ESAL_AR_INTERRUPTS_ENABLE_BITS;

        /* Force supervisor mode for breakpoint exception handling.
           Previous mode will be restored at end of exception handling. */
        stk_frame -> msr &= ~ESAL_AR_DBG_MSR_PR_BIT;

    }
    else
    {
        /* Call originally registered exception handler */
        ESAL_AR_DBG_Orig_Breakpoint_Handler(exception_vector, stack_ptr);
    }

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_data_abort_handler
*
*   DESCRIPTION
*
*       This is the data abort handler for the architecture.
*
*   INPUTS
*
*       exception_vector - The exception vector number.
*
*       stack_ptr - Pointer to the exception stack frame.
*
*   OUTPUTS
*
*       None
*
***********************************************************************/
static VOID esal_ar_dbg_data_abort_handler(INT      exception_vector,
                                           VOID *   stack_ptr)
{
    ESAL_AR_STK_MIN *   stk_frame = (ESAL_AR_STK_MIN *)stack_ptr;

    /* Determine how to proceed based on whether a debug operation is
       occurring or not. */
    if (ESAL_GE_DBG_Debug_Operation == 1)
    {
        /* Save exception return address and SPSR from stack */
        ESAL_AR_DBG_Exception_Return = stk_frame -> rtn_address;
        ESAL_AR_DBG_Exception_MSR = stk_frame -> msr;

        /* Set the generic exception handler for data aborts. */
        ESAL_AR_DBG_OS_Exception_Handler = ESAL_GE_DBG_OS_Data_Abort_Handler;

        /* Change exception return address so an unsolicited context can
           be saved and control returned to the OS */
        stk_frame -> rtn_address = (UINT32)ESAL_AR_DBG_Exception_Exit;

        /* Ensure interrupts stay locked-out */
        stk_frame -> msr &= ~ESAL_AR_INTERRUPTS_ENABLE_BITS;

        /* Force supervisor mode for breakpoint exception handling.
           Previous mode will be restored at end of exception handling. */
        stk_frame -> msr &= ~ESAL_AR_DBG_MSR_PR_BIT;

    }
    else
    {
        /* Call originally registered exception handler */
        ESAL_AR_DBG_Orig_Data_Abort_Handler(exception_vector, stack_ptr);
    }

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       esal_ar_dbg_hardware_step_handler
*
*   DESCRIPTION
*
*       This is the hardware stepping handler for the architecture.
*
*   INPUTS
*
*       exception_vector - The exception vector number.
*
*       stack_ptr - Pointer to the exception stack frame.
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
static VOID esal_ar_dbg_hardware_step_handler(INT          exception_vector,
                                              VOID *       stack_ptr)
{
    ESAL_AR_STK_MIN *   stk_frame = (ESAL_AR_STK_MIN *)stack_ptr;

    /* Save exception return address and MSR from stack */
    ESAL_AR_DBG_Exception_Return = stk_frame -> rtn_address;
    ESAL_AR_DBG_Exception_MSR = stk_frame -> msr;

    /* Set the generic exception handler for breakpoints. */
    ESAL_AR_DBG_OS_Exception_Handler = ESAL_GE_DBG_OS_Hardware_Step_Handler;

    /* Change exception return address so an unsolicited context can
       be saved and control returned to the OS */
    stk_frame -> rtn_address = (UINT32)ESAL_AR_DBG_Exception_Exit;

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0)

    /* Ensure single-stepping is disabled in saved MSR */
    ESAL_AR_DBG_Exception_MSR &= ~ESAL_AR_DBG_MSR_SE_BIT;

    /* Ensure interrupts and single-stepping are disabled and processor
       is in supervisor mode for exception handling. */
    stk_frame -> msr &= ~(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_PR_BIT | ESAL_AR_DBG_MSR_SE_BIT);

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0) */

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1)

    /* Ensure Debug Exceptions (trace) are disabled in saved MSR */
    ESAL_AR_DBG_Exception_MSR &= ~ESAL_AR_DBG_MSR_DE_BIT;

    /* Restore the interrupt state in saved MSR. */
    ESAL_AR_DBG_Exception_MSR |= ESAL_AR_DBG_Hardware_Step_MSR;

    /* Ensure interrupts and single-stepping are disabled and processor
       is in supervisor mode for exception handling. */
    stk_frame -> msr &= ~(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_PR_BIT | ESAL_AR_DBG_MSR_DE_BIT);

    {
        UINT32          reg_val;

        /* Disable instruction complete (trace) debug events */
        ESAL_TS_RTE_SPR_READ(ESAL_AR_DBG_DBCR0_REG_ID, &reg_val);
        reg_val &= ~ESAL_AR_DBG_DBCR0_ICMP_BIT;
        ESAL_TS_RTE_SPR_WRITE(ESAL_AR_DBG_DBCR0_REG_ID, reg_val);
        ESAL_TS_RTE_SYNC_EXECUTE();
        ESAL_TS_RTE_ISYNC_EXECUTE();

        /* Clear current instruction complete debug event */
        reg_val = ESAL_AR_DBG_DBSR_ICMP_BIT;
        ESAL_TS_RTE_SPR_WRITE(ESAL_AR_DBG_DBSR_REG_ID, reg_val);
        ESAL_TS_RTE_SYNC_EXECUTE();
        ESAL_TS_RTE_ISYNC_EXECUTE();
    }

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1) */

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Reg_Read
*
*   DESCRIPTION
*
*       This function reads a register stored in stack frame.
*
*       NOTE: This function should eventually be replaced with the
*             internal implementation to support variable-sized registers.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_no - Register number.
*
*       reg_val - Register value for return.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates a successful read of the requested register.
*
*       NU_FALSE - Indicates an error or register is unavailable.
*
*************************************************************************/
INT    ESAL_AR_DBG_Reg_Read(VOID *              p_stack_frame,
                            INT                 stack_frame_type,
                            INT                 reg_no,
                            ESAL_GE_DBG_REG *   reg_val)
{
    INT     ret_val;
    UINT8   reg_val_internal[ESAL_AR_DBG_REG_SIZE_MAX];
    UINT8   reg_size;

    /* Call internal register read function */
    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            reg_no,
                                            &reg_val_internal[0],
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Limit any returned value to 32-bits... */
        memcpy(reg_val, &reg_val_internal[0], sizeof(ESAL_GE_DBG_REG));

        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}


/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Reg_Write
*
*   DESCRIPTION
*
*       This function write register stored in stack
*
*       NOTE: This function should eventually be replaced with the
*             internal implementation to support variable-sized registers.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_no - Register number.
*
*       reg_val - Register value to write.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error occurred during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Reg_Write(VOID *                p_stack_frame,
                           INT                  stack_frame_type,
                           INT                  reg_no,
                           ESAL_GE_DBG_REG *    reg_val)
{
    INT     ret_val;
    UINT8   reg_size;

    /* Call internal register write function */
    ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                             stack_frame_type,
                                             reg_no,
                                             (VOID *)reg_val,
                                             &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Reg_Block_Read
*
*   DESCRIPTION
*
*       This function reads a block of registers stored in the stack.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_buff - Buffer address to copy register block.  Must be able to
*                  contain ESAL_AR_DBG_REG_COUNT register values (max).
*
*       blk_size - Return parameter that will be updated to contain the
*                  actual size of the register block.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Reg_Block_Read(VOID *       p_stack_frame,
                               INT          stack_frame_type,
                               VOID *       reg_buff,
                               UINT32 *     blk_size)
{
    INT                 ret_val;
    UINT8               i;
    UINT8               j;
    VOID *              reg_ptr;
    UINT8               reg_size;
    UINT32              block_size = 0;
    
    /* Initialize temporary register pointer */
    reg_ptr = reg_buff; 

    /* Read a block of registers */ 
    for (i = 0; i < ESAL_AR_DBG_REG_ID_MAX; i++)
    {
        /* Attempt to read the current register */
        ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                                stack_frame_type,
                                                i,
                                                reg_ptr,
                                                &reg_size);

        switch (ret_val)
        {
            case ESAL_AR_DBG_REG_MAPPED:
            {
                /* Move to next register memory in buffer */
                reg_ptr += reg_size;

                break;
            }

            case ESAL_AR_DBG_REG_NOT_MAPPED:
            {
                /* Set register value in the buffer to indicate register
                   value is unavailable taking into account the register
                   size */
                for (j = 0; j < reg_size; j += sizeof(UINT32))
                {
                    *((UINT32 *)reg_ptr) = ESAL_AR_DBG_REG_UNAVAIL_VAL;
                    reg_ptr += sizeof(UINT32);
                }

                break;
            }

            case ESAL_AR_DBG_REG_INVALID:
            default:
            {
                /* Add nothing to the buffer or block size. */
                reg_size = 0;

                break;
            }
        }
        
        /* Increment block size by the size of the register */
        block_size += reg_size;
        
    }
    
    /* return the block size */
    *blk_size = block_size;

    return (NU_TRUE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Reg_Block_Write
*
*   DESCRIPTION
*
*       This function writes a block of registers stored in the stack
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_buff - Buffer containing register block.  Buffer must contain
*                  ESAL_AR_DBG_NUM_REGS register values.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Reg_Block_Write(VOID *      p_stack_frame,
                                INT         stack_frame_type,
                                VOID *      reg_buff)
{
    INT                 ret_val;
    UINT8               i;
    VOID *              reg_ptr;
    UINT8               reg_size;
    
    /* Initialize temporary register pointer */
    reg_ptr = reg_buff;
    
    /* Write a block of registers */ 
    for (i = 0; i < ESAL_AR_DBG_REG_COUNT; i++)
    {
        /* Attempt to write register */
        ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                                 stack_frame_type,
                                                 i,
                                                 reg_ptr,
                                                 &reg_size);

        if (ret_val == ESAL_AR_DBG_REG_INVALID)
        {
            /* Do not move register buffer pointer forward. */
            reg_size = 0;
        }
        
        /* Increment buffer pointer */
        reg_ptr += reg_size;
        
    }

    return (NU_TRUE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Reg_Expedite_Read
*
*   DESCRIPTION
*
*       This function reads the registers needed for a stop reply packet.
*       This group is defined for ARM in the reg-arm.dat file in the GDB
*       distribution.  The registers returned for ARM are r11, sp and pc.
*       This function retrieves the register values stored in the stack.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       reg_buff - Buffer address to copy register block.
*
*       blk_size - The size of the read register block memory (in bytes).
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Reg_Expedite_Read(VOID *    p_stack_frame,
                                  INT       stack_frame_type,
                                  VOID *    reg_buff,
                                  UINT32 *  blk_size)
{
    INT                 ret_val;
    UINT32              i;
    UINT32              j;
    ESAL_GE_DBG_REG *   reg_ptr;
    UINT8               reg_size;
    UINT32              block_size = 0;
    UINT32              expedite_regs[] = {/* None */};

    /* Initialize temporary register pointer */
    reg_ptr = reg_buff; 
    
    /* Read the expedited registers */
    for (i = 0; i < (sizeof(expedite_regs) / sizeof(UINT32)); i++)
    {   
        /* Attempt to read the current register */
        ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                                stack_frame_type,
                                                expedite_regs[i],
                                                reg_ptr,
                                                &reg_size);

        switch (ret_val)
        {
            case ESAL_AR_DBG_REG_MAPPED:
            {
                /* Move to next register memory in buffer */
                reg_ptr += reg_size;

                break;
            }

            case ESAL_AR_DBG_REG_NOT_MAPPED:
            {
                /* Set register value in the buffer to indicate register
                   value is unavailable taking into account the register
                   size */
                for (j = 0; j < reg_size; j += sizeof(UINT32))
                {
                    *((UINT32 *)reg_ptr) = ESAL_AR_DBG_REG_UNAVAIL_VAL;
                    reg_ptr += sizeof(UINT32);
                }

                break;
            }

            case ESAL_AR_DBG_REG_INVALID:
            default:
            {
                /* Add nothing to the buffer or block size. */
                reg_size = 0;

                break;
            }
        }

        /* Increment block size by the size of the register */
        block_size += reg_size;

    }
    
    /* return the block size */
    *blk_size = block_size;
    
    return (NU_TRUE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Opcode_Read
*
*   DESCRIPTION
*
*       This function reads 4 byte (or 2 byte for thumb) instruction.
*
*   INPUTS
*
*       read_addr - Address to read.
*
*   OUTPUTS
*
*       Instruction value read from specified address.
*
*************************************************************************/
ESAL_GE_DBG_OPCODE ESAL_AR_DBG_Opcode_Read(VOID * read_addr)
{
    UINT32 opcode;

    /* Read 32bit value from given address. */
    opcode = ESAL_GE_MEM_READ32(read_addr);

    /* Return opcode to caller */
    return (opcode);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Opcode_Write
*
*   DESCRIPTION
*
*       This function writes 4 byte (or 2 byte for thumb) instruction
*
*   INPUTS
*
*       write_addr - Address to write.
*
*       opcode - Value to write.
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
VOID ESAL_AR_DBG_Opcode_Write(VOID *                write_addr,
                              ESAL_GE_DBG_OPCODE    opcode)
{
    /* Write 32bit value to given address. */
    ESAL_GE_MEM_WRITE32(write_addr, opcode);

    /* Invalidate cache. */
    ESAL_GE_MEM_DCACHE_FLUSH_INVAL(write_addr, 4);
    ESAL_GE_MEM_ICACHE_INVALIDATE(write_addr, 4);

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Opcode_Nop_Get
*
*   DESCRIPTION
*
*       This function returns NOP opcode for the specified address.
*
*   INPUTS
*
*       addr - Address to check.
*
*   OUTPUTS
*
*       NOP opcode value appropriate for address specified.
*
*************************************************************************/
ESAL_GE_DBG_OPCODE ESAL_AR_DBG_Opcode_Nop_Get(VOID * addr)
{
    /* Return the NOP opcode value. */
    return (ESAL_AR_DBG_PPC_NOP_OPCODE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Opcode_Brk_Get
*
*   DESCRIPTION
*
*       This function returns breakpoint opcode suitable for the address
*       specified.
*
*   INPUTS
*
*       addr - Address where breakpoint opcode will go.
*
*   OUTPUTS
*
*       Breakpoint opcode appropriate for the address specified.
*
*************************************************************************/
ESAL_GE_DBG_OPCODE ESAL_AR_DBG_Opcode_Brk_Get(VOID *   addr)
{
    /* Reference unused parameters to avoid compiler warnings */
    NU_UNUSED_PARAM(addr);

    /* NOTE: The PPC architecture uses the same opcode regardless of the
       address at which the opcode will be placed. */

    /* Return opcode to caller */
    return (ESAL_AR_DBG_PPC_BRK_OPCODE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Int_Read
*
*   DESCRIPTION
*
*       This function retrieves the interrupt state from the specified
*       stack frame.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       int_state - Return parameter that will contain the interrupt
*                   state if the operation is successful.  If the
*                   operation fails the value is undefined.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Int_Read(VOID *              p_stack_frame,
                         INT                 stack_frame_type,
                         UINT32 *            int_state)
{
    INT         ret_val;
    UINT32      msr_value;
    UINT8       reg_size;

    /* Read MSR register value. */
    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            ESAL_AR_DBG_REG_MSR,
                                            &msr_value,
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Save interrupt state values. */
        *int_state = (msr_value & ((UINT32)(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_ME_BIT)));

        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Int_Write
*
*   DESCRIPTION
*
*       This function writes the interrupt state in the specified stack
*       frame.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*       int_state - The interrupt state value to set.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Int_Write(VOID *              p_stack_frame,
                          INT                 stack_frame_type,
                          UINT32              int_state)
{
    INT         ret_val;
    UINT32      msr_value;
    UINT8       reg_size;

    /* Read CPSR register value. */

    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            ESAL_AR_DBG_REG_MSR,
                                            &msr_value,
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Restore interrupt state values. */
        msr_value = (msr_value & ~((UINT32)(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_ME_BIT)));
        msr_value = (msr_value | (int_state));

        /* Write MSR register value. */
        ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                                 stack_frame_type,
                                                 ESAL_AR_DBG_REG_MSR,
                                                 &msr_value,
                                                 &reg_size);

    }

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Int_Enable
*
*   DESCRIPTION
*
*       This function enables interrupts in the specified stack frame.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Int_Enable(VOID *              p_stack_frame,
                           INT                 stack_frame_type)
{
    INT         ret_val;
    UINT32      msr_value;
    UINT8       reg_size;

    /* Read MSR register value. */
    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            ESAL_AR_DBG_REG_MSR,
                                            &msr_value,
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Enable interrupts. */
        msr_value |= ((UINT32)(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_ME_BIT));

        /* Write MSR register value. */
        ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                                 stack_frame_type,
                                                 ESAL_AR_DBG_REG_MSR,
                                                 &msr_value,
                                                 &reg_size);
    }

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Int_Disable
*
*   DESCRIPTION
*
*       This function disables interrupts in the specified stack frame.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Int_Disable(VOID *              p_stack_frame,
                            INT                 stack_frame_type)
{
    INT         ret_val;
    UINT32      msr_value;
    UINT8       reg_size;

    /* Read MSR register value. */
    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            ESAL_AR_DBG_REG_MSR,
                                            &msr_value,
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Disable interrupts. */
        msr_value &= ~((UINT32)(ESAL_AR_DBG_MSR_EE_BIT | ESAL_AR_DBG_MSR_ME_BIT));

        /* Write MSR register value. */
        ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                                 stack_frame_type,
                                                 ESAL_AR_DBG_REG_MSR,
                                                 &msr_value,
                                                 &reg_size);

    }

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/***********************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Step_Addr_Get
*
*   DESCRIPTION
*
*       This function returns next program counter from given instruction.
*
*   INPUTS
*
*       addr - Address of current instruction.
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - stack frame type.
*
*   OUTPUTS
*
*       Next program counter value.
*
***********************************************************************/
VOID * ESAL_AR_DBG_Step_Addr_Get(VOID *     addr,
                                 VOID *     p_stack_frame,
                                 INT        stack_frame_type)
{
    /* Reference unused parameters to avoid compiler warnings */
    NU_UNUSED_PARAM(addr);
    NU_UNUSED_PARAM(p_stack_frame);
	NU_UNUSED_PARAM(stack_frame_type);

	/* NOTE: The PowerPC implementation uses hardware stepping so there is
	         no need for step address calculation. */

    /* Return NULL to caller */
    return (NU_NULL);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Hardware_Step
*
*   DESCRIPTION
*
*       This function performs a hardware-supported step operation.
*
*   INPUTS
*
*       p_stack_frame - Start address of stack memory.
*
*       stack_frame_type - Type of stack frame.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Hardware_Step(VOID * p_stack_frame, INT stack_frame_type)
{
    INT                 ret_val;
    ESAL_AR_DBG_REG     reg_val;
    UINT8               reg_size;

    NU_Protect(NU_NULL);

    /* Read the MSR value from the stack */
    ret_val = esal_ar_dbg_reg_read_internal(p_stack_frame,
                                            stack_frame_type,
                                            ESAL_AR_DBG_REG_MSR,
                                            &reg_val,
                                            &reg_size);

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0)

        /* Enable single-step trace exception */
        reg_val |= ESAL_AR_DBG_MSR_SE_BIT;

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 0) */

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1)

        /* Save the current interrupt state. */
        ESAL_AR_DBG_Hardware_Step_MSR = (reg_val & ESAL_AR_DBG_MSR_EE_BIT);

        /* Disable interrupts during stepping */
        reg_val &= ~ESAL_AR_DBG_MSR_EE_BIT;

        /* Enable debug exceptions (for trace) */
        reg_val |= ESAL_AR_DBG_MSR_DE_BIT;

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1) */

        /* Write the MSR value to the stack */
        ret_val = esal_ar_dbg_reg_write_internal(p_stack_frame,
                                                 stack_frame_type,
                                                 ESAL_AR_DBG_REG_MSR,
                                                 (VOID *)&reg_val,
                                                 &reg_size);
    }

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1)

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Enable instruction complete (trace) debug events.  Note: Debug
           events will only occur once MSR[DE] is enabled. */
        ESAL_TS_RTE_SPR_READ(ESAL_AR_DBG_DBCR0_REG_ID, &reg_val);
        reg_val |= ESAL_AR_DBG_DBCR0_ICMP_BIT;
        reg_val &= ~ESAL_AR_DBG_DBCR0_RST_BIT;
        ESAL_TS_RTE_SPR_WRITE(ESAL_AR_DBG_DBCR0_REG_ID, reg_val);
        ESAL_TS_RTE_SYNC_EXECUTE();
        ESAL_TS_RTE_ISYNC_EXECUTE();

        /* Clear any previous instruction complete debug events */
        reg_val = ESAL_AR_DBG_DBSR_ICMP_BIT;
        ESAL_TS_RTE_SPR_WRITE(ESAL_AR_DBG_DBSR_REG_ID, reg_val);
        ESAL_TS_RTE_SYNC_EXECUTE();
        ESAL_TS_RTE_ISYNC_EXECUTE();
    }

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1) */

    NU_Unprotect();

    if (ret_val == ESAL_AR_DBG_REG_MAPPED)
    {
        /* Indicate success */
        ret_val = NU_TRUE;
    }
    else
    {
        /* Indicate failure */
        ret_val = NU_FALSE;
    }

    return (ret_val);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Get_Support_Flags
*
*   DESCRIPTION
*
*       This function retrieves the debug support flags.
*
*   INPUTS
*
*       flags - The debug support flags value.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*       NU_FALSE - Indicates failure or error during operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Get_Support_Flags(UINT32 * flags)
{
    /* The PPC architecture support hardware stepping. */
    *flags = ESAL_GE_DBG_SUPPORT_HW_STEP;

    return (NU_TRUE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Set_Protocol
*
*   DESCRIPTION
*
*       This function returns the register model for the protocol
*       set by the debugging agent OS service.
*
*   INPUTS
*
*       dbg_prot - debug protocol to use.
*
*       stk_ptr - Obtains the stack pointer register id.
*
*       pc - Obtains the pc register id.
*
*   OUTPUTS
*
*       NU_TRUE - Indicates successful operation.
*
*************************************************************************/
INT ESAL_AR_DBG_Set_Protocol(UINT8      dbg_prot,
                             UINT8 *    stk_ptr,
                             UINT8 *    pc)
{
    /* Set stack pointer register id. */
    *stk_ptr = ESAL_AR_DBG_STACK_PTR_REGID;

    /* Set pc register id. */
    *pc = ESAL_AR_DBG_PC_IDX_REGID;

    return (NU_TRUE);
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Initialize
*
*   DESCRIPTION
*
*       This function initializes debugging at architecture level
*
*   INPUTS
*
*       None
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
VOID    ESAL_AR_DBG_Initialize(VOID)
{
    /* Initialize register mapping table for unsolicited stack frames. */
    esal_ar_dbg_reg_map_blank(&esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][0]);

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R0].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r0);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R1].offset = ESAL_AR_DBG_REG_STACK_POINTER;
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R3].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r3);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R4].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r4);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R5].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r5);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R6].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r6);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R7].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r7);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R8].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r8);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R9].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r9);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R10].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r10);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R11].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r11);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R12].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.r12);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R14].offset = ESAL_GE_STK_UNSOL_OFFSET (r14);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R15].offset = ESAL_GE_STK_UNSOL_OFFSET (r15);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R16].offset = ESAL_GE_STK_UNSOL_OFFSET (r16);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R17].offset = ESAL_GE_STK_UNSOL_OFFSET (r17);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R18].offset = ESAL_GE_STK_UNSOL_OFFSET (r18);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R19].offset = ESAL_GE_STK_UNSOL_OFFSET (r19);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R20].offset = ESAL_GE_STK_UNSOL_OFFSET (r20);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R21].offset = ESAL_GE_STK_UNSOL_OFFSET (r21);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R22].offset = ESAL_GE_STK_UNSOL_OFFSET (r22);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R23].offset = ESAL_GE_STK_UNSOL_OFFSET (r23);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R24].offset = ESAL_GE_STK_UNSOL_OFFSET (r24);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R25].offset = ESAL_GE_STK_UNSOL_OFFSET (r25);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R26].offset = ESAL_GE_STK_UNSOL_OFFSET (r26);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R27].offset = ESAL_GE_STK_UNSOL_OFFSET (r27);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R28].offset = ESAL_GE_STK_UNSOL_OFFSET (r28);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R29].offset = ESAL_GE_STK_UNSOL_OFFSET (r29);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R30].offset = ESAL_GE_STK_UNSOL_OFFSET (r30);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_R31].offset = ESAL_GE_STK_UNSOL_OFFSET (r31);

#if (PPC_DEBUG_FPU_DEV_ENABLE == NU_TRUE)

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F0].offset = ESAL_GE_STK_UNSOL_OFFSET (f0[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F1].offset = ESAL_GE_STK_UNSOL_OFFSET (f1[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F2].offset = ESAL_GE_STK_UNSOL_OFFSET (f2[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F3].offset = ESAL_GE_STK_UNSOL_OFFSET (f3[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F4].offset = ESAL_GE_STK_UNSOL_OFFSET (f4[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F5].offset = ESAL_GE_STK_UNSOL_OFFSET (f5[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F6].offset = ESAL_GE_STK_UNSOL_OFFSET (f6[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F7].offset = ESAL_GE_STK_UNSOL_OFFSET (f7[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F8].offset = ESAL_GE_STK_UNSOL_OFFSET (f8[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F9].offset = ESAL_GE_STK_UNSOL_OFFSET (f9[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F10].offset = ESAL_GE_STK_UNSOL_OFFSET (f10[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F11].offset = ESAL_GE_STK_UNSOL_OFFSET (f11[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F12].offset = ESAL_GE_STK_UNSOL_OFFSET (f12[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F13].offset = ESAL_GE_STK_UNSOL_OFFSET (f13[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F14].offset = ESAL_GE_STK_UNSOL_OFFSET (f14[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F15].offset = ESAL_GE_STK_UNSOL_OFFSET (f15[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F16].offset = ESAL_GE_STK_UNSOL_OFFSET (f16[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F17].offset = ESAL_GE_STK_UNSOL_OFFSET (f17[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F18].offset = ESAL_GE_STK_UNSOL_OFFSET (f18[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F19].offset = ESAL_GE_STK_UNSOL_OFFSET (f19[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F20].offset = ESAL_GE_STK_UNSOL_OFFSET (f20[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F21].offset = ESAL_GE_STK_UNSOL_OFFSET (f21[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F22].offset = ESAL_GE_STK_UNSOL_OFFSET (f22[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F23].offset = ESAL_GE_STK_UNSOL_OFFSET (f23[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F24].offset = ESAL_GE_STK_UNSOL_OFFSET (f24[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F25].offset = ESAL_GE_STK_UNSOL_OFFSET (f25[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F26].offset = ESAL_GE_STK_UNSOL_OFFSET (f26[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F27].offset = ESAL_GE_STK_UNSOL_OFFSET (f27[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F28].offset = ESAL_GE_STK_UNSOL_OFFSET (f28[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F29].offset = ESAL_GE_STK_UNSOL_OFFSET (f29[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F30].offset = ESAL_GE_STK_UNSOL_OFFSET (f30[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_F31].offset = ESAL_GE_STK_UNSOL_OFFSET (f31[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_FPSCR].offset = ESAL_GE_STK_UNSOL_OFFSET (fpscr);

#endif /* (PPC_DEBUG_FPU_DEV_ENABLE == NU_TRUE) */

#if (PPC_DEBUG_SPE_DEV_ENABLE == NU_TRUE)

    /* SPE REGISTER MAPPINGS NEEDED */

#endif /* (PPC_DEBUG_SPE_DEV_ENABLE == NU_TRUE) */

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_PC].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.rtn_address);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_MSR].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.msr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_CR].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.cr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_LR].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.lr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_CTR].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.ctr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_UNSOL][ESAL_AR_DBG_REG_XER].offset = ESAL_GE_STK_UNSOL_OFFSET (min_stack.xer);

    /* Initialize register mapping table for solicited stack frames. */
    esal_ar_dbg_reg_map_blank(&esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][0]);

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R14].offset = ESAL_GE_STK_SOL_OFFSET (r14);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R15].offset = ESAL_GE_STK_SOL_OFFSET (r15);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R16].offset = ESAL_GE_STK_SOL_OFFSET (r16);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R17].offset = ESAL_GE_STK_SOL_OFFSET (r17);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R18].offset = ESAL_GE_STK_SOL_OFFSET (r18);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R19].offset = ESAL_GE_STK_SOL_OFFSET (r19);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R20].offset = ESAL_GE_STK_SOL_OFFSET (r20);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R21].offset = ESAL_GE_STK_SOL_OFFSET (r21);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R22].offset = ESAL_GE_STK_SOL_OFFSET (r22);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R23].offset = ESAL_GE_STK_SOL_OFFSET (r23);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R24].offset = ESAL_GE_STK_SOL_OFFSET (r24);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R25].offset = ESAL_GE_STK_SOL_OFFSET (r25);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R26].offset = ESAL_GE_STK_SOL_OFFSET (r26);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R27].offset = ESAL_GE_STK_SOL_OFFSET (r27);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R28].offset = ESAL_GE_STK_SOL_OFFSET (r28);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R29].offset = ESAL_GE_STK_SOL_OFFSET (r29);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R30].offset = ESAL_GE_STK_SOL_OFFSET (r30);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_R31].offset = ESAL_GE_STK_SOL_OFFSET (r31);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_CR].offset = ESAL_GE_STK_SOL_OFFSET (cr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_PC].offset = ESAL_GE_STK_SOL_OFFSET (rtn_address);

#if (PPC_DEBUG_FPU_DEV_ENABLE == NU_TRUE)

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F14].offset = ESAL_GE_STK_SOL_OFFSET (f14[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F15].offset = ESAL_GE_STK_SOL_OFFSET (f15[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F16].offset = ESAL_GE_STK_SOL_OFFSET (f16[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F17].offset = ESAL_GE_STK_SOL_OFFSET (f17[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F18].offset = ESAL_GE_STK_SOL_OFFSET (f18[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F19].offset = ESAL_GE_STK_SOL_OFFSET (f19[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F20].offset = ESAL_GE_STK_SOL_OFFSET (f20[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F21].offset = ESAL_GE_STK_SOL_OFFSET (f21[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F22].offset = ESAL_GE_STK_SOL_OFFSET (f22[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F23].offset = ESAL_GE_STK_SOL_OFFSET (f23[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F24].offset = ESAL_GE_STK_SOL_OFFSET (f24[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F25].offset = ESAL_GE_STK_SOL_OFFSET (f25[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F26].offset = ESAL_GE_STK_SOL_OFFSET (f26[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F27].offset = ESAL_GE_STK_SOL_OFFSET (f27[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F28].offset = ESAL_GE_STK_SOL_OFFSET (f28[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F29].offset = ESAL_GE_STK_SOL_OFFSET (f29[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F30].offset = ESAL_GE_STK_SOL_OFFSET (f30[0]);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_SOL][ESAL_AR_DBG_REG_F31].offset = ESAL_GE_STK_SOL_OFFSET (f31[0]);

#endif /* (PPC_DEBUG_FPU_DEV_ENABLE == NU_TRUE) */

#if (PPC_DEBUG_SPE_DEV_ENABLE == NU_TRUE)

    /* SPE REGISTER MAPPINGS NEEDED */

#endif /* (PPC_DEBUG_SPE_DEV_ENABLE == NU_TRUE) */

    /* Initialize register mapping table for exception stack frames
       (architecture minimum stack used for exceptions). */
    esal_ar_dbg_reg_map_blank(&esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][0]);

    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_CTR].offset = ESAL_AR_DBG_STK_MIN_OFFSET (ctr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_XER].offset = ESAL_AR_DBG_STK_MIN_OFFSET (xer);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_CR].offset = ESAL_AR_DBG_STK_MIN_OFFSET (cr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_LR].offset = ESAL_AR_DBG_STK_MIN_OFFSET (lr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R0].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r0);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R1].offset = ESAL_AR_DBG_REG_STACK_POINTER;
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R3].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r3);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R4].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r4);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R5].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r5);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R6].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r6);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R7].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r7);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R8].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r8);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R9].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r9);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R10].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r10);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_PC].offset = ESAL_AR_DBG_STK_MIN_OFFSET (rtn_address);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_MSR].offset = ESAL_AR_DBG_STK_MIN_OFFSET (msr);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R11].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r11);
    esal_ar_dbg_reg_mappings[ESAL_AR_DBG_STK_TYPE_EXCEPT][ESAL_AR_DBG_REG_R12].offset = ESAL_AR_DBG_STK_MIN_OFFSET (r12);

    /* Setup breakpoint exception handler saving original handler. */
    ESAL_AR_DBG_Orig_Breakpoint_Handler = ESAL_GE_EXCEPT_HANDLER_GET(ESAL_AR_DBG_PPC_BREAKPOINT_VECTOR_ID);
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_BREAKPOINT_VECTOR_ID, esal_ar_dbg_breakpoint_handler);

    /* Setup data abort exception handler saving original handler. */
    ESAL_AR_DBG_Orig_Data_Abort_Handler = ESAL_GE_EXCEPT_HANDLER_GET(ESAL_AR_DBG_PPC_DATA_ABORT_VECTOR_ID);
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_DATA_ABORT_VECTOR_ID, esal_ar_dbg_data_abort_handler);

    /* Setup hardware stepping exception handler saving original handler. */
    ESAL_AR_DBG_Orig_Hardware_Step_Handler = ESAL_GE_EXCEPT_HANDLER_GET(ESAL_AR_DBG_PPC_HARDWARE_STEP_VECTOR_ID);
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_HARDWARE_STEP_VECTOR_ID, esal_ar_dbg_hardware_step_handler);

#if (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1)

    {
        UINT32      reg_val;

        /* Enable Internal Debugging Mode (IDM) and disable External Debug
           Mode (EDM). */
        ESAL_TS_RTE_SPR_READ(ESAL_AR_DBG_DBCR0_REG_ID, &reg_val);
        reg_val |= ESAL_AR_DBG_DBCR0_IDM_BIT;
        reg_val &= ~ESAL_AR_DBG_DBCR0_EDM_BIT;
        ESAL_TS_RTE_SPR_WRITE(ESAL_AR_DBG_DBCR0_REG_ID, reg_val);

        /* Disable Debug Exceptions for general operation (only used for
           hardware stepping). */
        ESAL_TS_RTE_MSR_READ(&reg_val);
        reg_val &= ~ESAL_AR_DBG_MSR_DE_BIT;
        ESAL_TS_RTE_MSR_WRITE(reg_val);
        ESAL_TS_RTE_SYNC_EXECUTE();
        ESAL_TS_RTE_ISYNC_EXECUTE();
    }

#endif /* (CFG_NU_OS_ARCH_PPC_COM_PPC_VARIANT == 1) */

    return;
}

/*************************************************************************
*
*   FUNCTION
*
*       ESAL_AR_DBG_Terminate
*
*   DESCRIPTION
*
*       This function terminates debugging at architecture level
*
*   INPUTS
*
*       None
*
*   OUTPUTS
*
*       None
*
*************************************************************************/
VOID ESAL_AR_DBG_Terminate(VOID)
{
    /* Restore all exception handlers. */
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_BREAKPOINT_VECTOR_ID, ESAL_AR_DBG_Orig_Breakpoint_Handler);
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_DATA_ABORT_VECTOR_ID, ESAL_AR_DBG_Orig_Data_Abort_Handler);
    ESAL_GE_EXCEPT_HANDLER_SET(ESAL_AR_DBG_PPC_HARDWARE_STEP_VECTOR_ID, ESAL_AR_DBG_Orig_Hardware_Step_Handler);

    return;
}
