summaryrefslogtreecommitdiff
path: root/components/lwp/lwp_dbg.c
blob: 6fdac2cbb611424f9da53babbd0cd0f25c6ad286 (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
 * Copyright (c) 2006-2025 RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-07-11     RT-Thread    first version
 */
#include <rtthread.h>
#include <rthw.h>
#include <lwp.h>

/**
 * @brief Check if the current thread is in debug state.
 *
 * @return int Returns 1 if the thread is in debug state, 0 otherwise.
 */
int dbg_thread_in_debug(void)
{
    int ret = 0;
    struct rt_lwp *lwp = lwp_self();

    if (lwp && lwp->debug)
    {
        ret = 1;
    }
    return ret;
}

struct dbg_ops_t *rt_dbg_ops = RT_NULL;
RTM_EXPORT(rt_dbg_ops);

/**
 * @brief Register debugger operations.
 *
 * @param dbg_ops Pointer to debugger operations structure.
 */
void dbg_register(struct dbg_ops_t *dbg_ops)
{
    rt_dbg_ops = dbg_ops;
}
RTM_EXPORT(dbg_register);

/**
 * @brief Debug command handler function
 *
 * @param[in] argc Number of command arguments
 * @param[in] argv Array of command argument strings
 *
 * @return int Returns the result from the debug operations handler if available,
 *         otherwise returns -1 to indicate failure
 *
 * @note This function serves as a wrapper for debug operations, delegating to the registered
 *       debug operations handler if available. If no debug operations are registered,
 *       it prints an error message.
 */
static int dbg(int argc, char **argv)
{
    int ret = -1;

    if (rt_dbg_ops)
    {
        ret = rt_dbg_ops->dbg(argc, argv);
    }
    else
    {
        rt_kprintf("Error: DBG command is not enabled!\n");
    }
    return ret;
}
MSH_CMD_EXPORT(dbg, dbg);

/**
 * @brief Get the current instruction value from debug operations
 *
 * @return uint32_t Returns the current instruction value if debug operations are available,
 *         otherwise returns 0
 *
 * @note This function retrieves the current instruction value by calling the registered
 *       debug operations handler if available. If no debug operations are registered,
 *       it returns 0.
 */
uint32_t dbg_get_ins(void)
{
    uint32_t ins = 0;

    if (rt_dbg_ops)
    {
        ins = rt_dbg_ops->arch_get_ins();
    }
    return ins;
}

/**
 * @brief Activates single-step debugging mode if debug operations are registered
 *
 * @note This function checks if debug operations are registered (rt_dbg_ops) and if so,
 *       calls the architecture-specific single-step activation function.
 */
void dbg_activate_step(void)
{
    if (rt_dbg_ops)
    {
        rt_dbg_ops->arch_activate_step();
    }
}

/**
 * @brief Deactivates single-step debugging mode if debug operations are registered
 *
 * @note This function checks if debug operations are registered (rt_dbg_ops) and if so,
 *       calls the architecture-specific single-step deactivation function.
 */
void dbg_deactivate_step(void)
{
    if (rt_dbg_ops)
    {
        rt_dbg_ops->arch_deactivate_step();
    }
}

/**
 * @brief Checks for debug events and processes them if debug operations are registered
 *
 * @param[in] regs Pointer to the hardware exception stack containing register values
 * @param[in] esr Exception Syndrome Register value
 *
 * @return int Returns the result from the debug event check (0 if no debug operations registered)
 *
 * @note This function checks if debug operations are registered (rt_dbg_ops) and if so,
 *       calls the debug event checking function with the provided registers and exception status.
 *       If no debug operations are registered, it returns 0.
 */
int dbg_check_event(struct rt_hw_exp_stack *regs, unsigned long esr)
{
    int ret = 0;

    if (rt_dbg_ops)
    {
        ret = rt_dbg_ops->check_debug_event(regs, esr);
    }
    return ret;
}

/**
 * @brief Gets the GDB server communication channel if debug operations are registered
 *
 * @return rt_channel_t Returns the GDB server channel (RT_NULL if no debug operations registered)
 *
 * @note This function checks if debug operations are registered (rt_dbg_ops) and if so,
 *       retrieves the GDB server communication channel from the registered operations.
 *       If no debug operations are registered, it returns RT_NULL.
 */
rt_channel_t gdb_server_channel(void)
{
    rt_channel_t ret = RT_NULL;

    if (rt_dbg_ops)
    {
        ret = rt_dbg_ops->gdb_get_server_channel();
    }
    return ret;
}

/**
 * @brief Gets the current step type from debug operations
 *
 * @return int The current step type (0 if no debug operations are registered)
 *
 * @note This function checks if debug operations are registered (rt_dbg_ops) and if so,
 *       retrieves the current step type from the registered debug operations.
 *       If no debug operations are registered, it returns 0.
 */
int dbg_step_type(void)
{
    int ret = 0;

    if (rt_dbg_ops)
    {
        ret = rt_dbg_ops->gdb_get_step_type();
    }
    return ret;
}

/**
 * @brief Handles debug attach request
 *
 * @param[in] pc Pointer to the program counter value
 *
 * @note This function checks if debug operations are registered and calls
 *       the debug attach request handler if available.
 */
void dbg_attach_req(void *pc)
{
    if (rt_dbg_ops)
    {
        rt_dbg_ops->lwp_check_debug_attach_req(pc);
    }
}

/**
 * @brief Checks if debug suspend is requested
 *
 * @return int Returns the suspend status (0 if no debug operations are registered)
 *
 * @note This function checks if debug operations are registered and calls
 *       the debug suspend check handler if available.
 */
int dbg_check_suspend(void)
{
    int ret = 0;

    if (rt_dbg_ops)
    {
        ret = rt_dbg_ops->lwp_check_debug_suspend();
    }
    return ret;
}