summaryrefslogtreecommitdiffstats
path: root/src/occ/cmdh/ffdc.c
blob: 7f83e129db5508544dd1b92673db627202626987 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

/******************************************************************************
 * @file ffdc.c
 * @brief FFDC support routines.
 ******************************************************************************/

/******************************************************************************
 * @page ChangeLogs Change Logs
 * @section _ffdc_c ffdc.c
 * @verbatim
 *
 * Flag    Def/Fea    Userid    Date        Description
 * ------- ---------- --------  ----------  ------------------------------------
 *         916980     sbroyles  03/10/2014  Created
 * @endverbatim
 ******************************************************************************/

//******************************************************************************
// Includes
//******************************************************************************
#include "ffdc.h"

//******************************************************************************
// Externs
//******************************************************************************

//******************************************************************************
// Defines/Enums
//******************************************************************************

//******************************************************************************
// Functions
//******************************************************************************

// Function Specification //////////////////////////////////////////////////////
//
// Name: ffdc_thread_dumper
//
// Description: Dump the state of the thread provided
//
// Flow:              FN=None
//
// End Function Specification //////////////////////////////////////////////////
void
ffdc_thread_dumper(SsxThread *i_thread, void *o_ffdc_buffer)
{
    // Format of data dumped into FFDC buffer.  The buffer space allocated must
    // match the size of the dump.  The dumped structure must agree with the
    // structure of the FFDC defined in ll_ffdc.S.
    //
    // Offset   Length  Contents
    // 0x00     1       Length of thread dump
    // 0x01     1       Priority
    // 0x02     1       State
    // 0x03     1       Flags
    // 0x04     4       Thread timer
    // 0x08     4       Semaphore
    // 0x0c     4       SRR0
    // 0x10     4       SRR1
    // 0x14     4       SRR2
    // 0x18     4       SRR3
    // 0x1c     4       LR
    // 0x20     32      Thread stack unwind
    //
    // Total length = 64 bytes

    uint8_t *l_byte_ptr = (uint8_t *)o_ffdc_buffer;
    // Store length, priority, state and flags to buffer
    l_byte_ptr[0] = 64;
    l_byte_ptr[1] = (uint8_t)(i_thread->priority);
    l_byte_ptr[2] = (uint8_t)(i_thread->state);
    l_byte_ptr[3] = (uint8_t)(i_thread->flags);

    // Store Timer, Semaphore
    uint32_t *l_word_ptr = (uint32_t *)(l_byte_ptr + 4);
    l_word_ptr[0] = (uint32_t)&(i_thread->timer);
    l_word_ptr[1] = (uint32_t)(i_thread->semaphore);

    // Store SRR0-3 and LR from saved context
    SsxThreadContext *l_threadCtx = (SsxThreadContext *)(i_thread->saved_stack_pointer);
    l_word_ptr[2] = (uint32_t)(l_threadCtx->srr0);
    l_word_ptr[3] = (uint32_t)(l_threadCtx->srr1);
    l_word_ptr[4] = (uint32_t)(l_threadCtx->srr2);
    l_word_ptr[5] = (uint32_t)(l_threadCtx->srr3);
    l_word_ptr[6] = (uint32_t)(l_threadCtx->lr);

    // Store up to 8 LRs from stack chain, set stack frame pointer to caller's
    // frame.
    uint32_t *l_sptr = (uint32_t *)(((uint32_t*)l_threadCtx->r1)[0]);
    // Reset the ffdc pointer
    l_word_ptr = &l_word_ptr[7];
    ffdc_stack_unwind(l_sptr, l_word_ptr, 8);
}
// End of ffdc_thread_dumper


// Function Specification //////////////////////////////////////////////////////
//
// Name: ffdc_stack_unwind
//
// Description: Unwind the link registers from the provided stack pointer.
//
// Flow:              FN=None
//
// End Function Specification //////////////////////////////////////////////////
void
ffdc_stack_unwind(uint32_t *i_sptr, uint32_t *o_buffer, uint32_t i_frameCount)
{
    // Format of the data dumped to the output buffer.
    // The caller must provide at least one 32 bit word per frame requested by
    // frame count parameter.
    //
    // Offset   Length  Contents
    // 0x00     4       Link register for frame n
    // 0x04     4       Link register for frame n+1
    // ... do as many as frames as requested

    uint32_t *l_sptr = i_sptr;
    int i = 0;
    // Loop through the frames storing the LR words
    for (i = 0; i < i_frameCount; i++)
    {
        // Stop storing if we get to the last frame
        if (l_sptr == NULL)
        {
            // Zero out the remaining words in the buffer and break
            for (; i < i_frameCount; i++)
            {
                o_buffer[i] = 0x00000000;
            }
            break;
        }
        else
        {
            o_buffer[i] = (uint32_t)(l_sptr[1]);
            l_sptr = (uint32_t *)l_sptr[0];
        }
    }
}
// End of ffdc_stack_unwind


//
// End of ffdc.c
//
OpenPOWER on IntegriCloud