rtos/eCos: rename CamelCase symbols
[openocd.git] / src / rtos / eCos.c
1 /***************************************************************************
2 * *
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
7 * *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11 * GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License *
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
15 ***************************************************************************/
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <helper/time_support.h>
22 #include <jtag/jtag.h>
23 #include "target/target.h"
24 #include "target/target_type.h"
25 #include "rtos.h"
26 #include "helper/log.h"
27 #include "helper/types.h"
28 #include "rtos_ecos_stackings.h"
29
30 static bool ecos_detect_rtos(struct target *target);
31 static int ecos_create(struct target *target);
32 static int ecos_update_threads(struct rtos *rtos);
33 static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs);
34 static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);
35
36 struct ecos_thread_state {
37 int value;
38 const char *desc;
39 };
40
41 static const struct ecos_thread_state ecos_thread_states[] = {
42 { 0, "Ready" },
43 { 1, "Sleeping" },
44 { 2, "Countsleep" },
45 { 4, "Suspended" },
46 { 8, "Creating" },
47 { 16, "Exited" }
48 };
49
50 #define ECOS_NUM_STATES ARRAY_SIZE(ecos_thread_states)
51
52 struct ecos_params {
53 const char *target_name;
54 unsigned char pointer_width;
55 unsigned char thread_stack_offset;
56 unsigned char thread_name_offset;
57 unsigned char thread_state_offset;
58 unsigned char thread_next_offset;
59 unsigned char thread_uniqueid_offset;
60 const struct rtos_register_stacking *stacking_info;
61 };
62
63 static const struct ecos_params ecos_params_list[] = {
64 {
65 "cortex_m", /* target_name */
66 4, /* pointer_width; */
67 0x0c, /* thread_stack_offset; */
68 0x9c, /* thread_name_offset; */
69 0x3c, /* thread_state_offset; */
70 0xa0, /* thread_next_offset */
71 0x4c, /* thread_uniqueid_offset */
72 &rtos_ecos_cortex_m3_stacking /* stacking_info */
73 }
74 };
75
76 enum ecos_symbol_values {
77 ECOS_VAL_THREAD_LIST = 0,
78 ECOS_VAL_CURRENT_THREAD_PTR = 1
79 };
80
81 static const char * const ecos_symbol_list[] = {
82 "Cyg_Thread::thread_list",
83 "Cyg_Scheduler_Base::current_thread",
84 NULL
85 };
86
87 const struct rtos_type ecos_rtos = {
88 .name = "eCos",
89
90 .detect_rtos = ecos_detect_rtos,
91 .create = ecos_create,
92 .update_threads = ecos_update_threads,
93 .get_thread_reg_list = ecos_get_thread_reg_list,
94 .get_symbol_list_to_lookup = ecos_get_symbol_list_to_lookup,
95
96 };
97
98 static int ecos_update_threads(struct rtos *rtos)
99 {
100 int retval;
101 int tasks_found = 0;
102 int thread_list_size = 0;
103 const struct ecos_params *param;
104
105 if (rtos == NULL)
106 return -1;
107
108 if (rtos->rtos_specific_params == NULL)
109 return -3;
110
111 param = (const struct ecos_params *) rtos->rtos_specific_params;
112
113 if (rtos->symbols == NULL) {
114 LOG_ERROR("No symbols for eCos");
115 return -4;
116 }
117
118 if (rtos->symbols[ECOS_VAL_THREAD_LIST].address == 0) {
119 LOG_ERROR("Don't have the thread list head");
120 return -2;
121 }
122
123 /* wipe out previous thread details if any */
124 rtos_free_threadlist(rtos);
125
126 /* determine the number of current threads */
127 uint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address;
128 uint32_t thread_index;
129 target_read_buffer(rtos->target,
130 thread_list_head,
131 param->pointer_width,
132 (uint8_t *) &thread_index);
133 uint32_t first_thread = thread_index;
134 do {
135 thread_list_size++;
136 retval = target_read_buffer(rtos->target,
137 thread_index + param->thread_next_offset,
138 param->pointer_width,
139 (uint8_t *) &thread_index);
140 if (retval != ERROR_OK)
141 return retval;
142 } while (thread_index != first_thread);
143
144 /* read the current thread id */
145 uint32_t current_thread_addr;
146 retval = target_read_buffer(rtos->target,
147 rtos->symbols[ECOS_VAL_CURRENT_THREAD_PTR].address,
148 4,
149 (uint8_t *)&current_thread_addr);
150 if (retval != ERROR_OK)
151 return retval;
152 rtos->current_thread = 0;
153 retval = target_read_buffer(rtos->target,
154 current_thread_addr + param->thread_uniqueid_offset,
155 2,
156 (uint8_t *)&rtos->current_thread);
157 if (retval != ERROR_OK) {
158 LOG_ERROR("Could not read eCos current thread from target");
159 return retval;
160 }
161
162 if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
163 /* Either : No RTOS threads - there is always at least the current execution though */
164 /* OR : No current thread - all threads suspended - show the current execution
165 * of idling */
166 char tmp_str[] = "Current Execution";
167 thread_list_size++;
168 tasks_found++;
169 rtos->thread_details = malloc(
170 sizeof(struct thread_detail) * thread_list_size);
171 rtos->thread_details->threadid = 1;
172 rtos->thread_details->exists = true;
173 rtos->thread_details->extra_info_str = NULL;
174 rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
175 strcpy(rtos->thread_details->thread_name_str, tmp_str);
176
177 if (thread_list_size == 0) {
178 rtos->thread_count = 1;
179 return ERROR_OK;
180 }
181 } else {
182 /* create space for new thread details */
183 rtos->thread_details = malloc(
184 sizeof(struct thread_detail) * thread_list_size);
185 }
186
187 /* loop over all threads */
188 thread_index = first_thread;
189 do {
190
191 #define ECOS_THREAD_NAME_STR_SIZE (200)
192 char tmp_str[ECOS_THREAD_NAME_STR_SIZE];
193 unsigned int i = 0;
194 uint32_t name_ptr = 0;
195 uint32_t prev_thread_ptr;
196
197 /* Save the thread pointer */
198 uint16_t thread_id;
199 retval = target_read_buffer(rtos->target,
200 thread_index + param->thread_uniqueid_offset,
201 2,
202 (uint8_t *)&thread_id);
203 if (retval != ERROR_OK) {
204 LOG_ERROR("Could not read eCos thread id from target");
205 return retval;
206 }
207 rtos->thread_details[tasks_found].threadid = thread_id;
208
209 /* read the name pointer */
210 retval = target_read_buffer(rtos->target,
211 thread_index + param->thread_name_offset,
212 param->pointer_width,
213 (uint8_t *)&name_ptr);
214 if (retval != ERROR_OK) {
215 LOG_ERROR("Could not read eCos thread name pointer from target");
216 return retval;
217 }
218
219 /* Read the thread name */
220 retval =
221 target_read_buffer(rtos->target,
222 name_ptr,
223 ECOS_THREAD_NAME_STR_SIZE,
224 (uint8_t *)&tmp_str);
225 if (retval != ERROR_OK) {
226 LOG_ERROR("Error reading thread name from eCos target");
227 return retval;
228 }
229 tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00';
230
231 if (tmp_str[0] == '\x00')
232 strcpy(tmp_str, "No Name");
233
234 rtos->thread_details[tasks_found].thread_name_str =
235 malloc(strlen(tmp_str)+1);
236 strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
237
238 /* Read the thread status */
239 int64_t thread_status = 0;
240 retval = target_read_buffer(rtos->target,
241 thread_index + param->thread_state_offset,
242 4,
243 (uint8_t *)&thread_status);
244 if (retval != ERROR_OK) {
245 LOG_ERROR("Error reading thread state from eCos target");
246 return retval;
247 }
248
249 for (i = 0; (i < ECOS_NUM_STATES) && (ecos_thread_states[i].value != thread_status); i++) {
250 /*
251 * empty
252 */
253 }
254
255 const char *state_desc;
256 if (i < ECOS_NUM_STATES)
257 state_desc = ecos_thread_states[i].desc;
258 else
259 state_desc = "Unknown state";
260
261 rtos->thread_details[tasks_found].extra_info_str = malloc(strlen(
262 state_desc)+8);
263 sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc);
264
265 rtos->thread_details[tasks_found].exists = true;
266
267 tasks_found++;
268 prev_thread_ptr = thread_index;
269
270 /* Get the location of the next thread structure. */
271 thread_index = rtos->symbols[ECOS_VAL_THREAD_LIST].address;
272 retval = target_read_buffer(rtos->target,
273 prev_thread_ptr + param->thread_next_offset,
274 param->pointer_width,
275 (uint8_t *) &thread_index);
276 if (retval != ERROR_OK) {
277 LOG_ERROR("Error reading next thread pointer in eCos thread list");
278 return retval;
279 }
280 } while (thread_index != first_thread);
281
282 rtos->thread_count = tasks_found;
283 return 0;
284 }
285
286 static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
287 struct rtos_reg **reg_list, int *num_regs)
288 {
289 int retval;
290 const struct ecos_params *param;
291
292 if (rtos == NULL)
293 return -1;
294
295 if (thread_id == 0)
296 return -2;
297
298 if (rtos->rtos_specific_params == NULL)
299 return -3;
300
301 param = (const struct ecos_params *) rtos->rtos_specific_params;
302
303 /* Find the thread with that thread id */
304 uint16_t id = 0;
305 uint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address;
306 uint32_t thread_index;
307 target_read_buffer(rtos->target, thread_list_head, param->pointer_width,
308 (uint8_t *)&thread_index);
309 bool done = false;
310 while (!done) {
311 retval = target_read_buffer(rtos->target,
312 thread_index + param->thread_uniqueid_offset,
313 2,
314 (uint8_t *)&id);
315 if (retval != ERROR_OK) {
316 LOG_ERROR("Error reading unique id from eCos thread");
317 return retval;
318 }
319
320 if (id == thread_id) {
321 done = true;
322 break;
323 }
324 target_read_buffer(rtos->target,
325 thread_index + param->thread_next_offset,
326 param->pointer_width,
327 (uint8_t *) &thread_index);
328 }
329
330 if (done) {
331 /* Read the stack pointer */
332 int64_t stack_ptr = 0;
333 retval = target_read_buffer(rtos->target,
334 thread_index + param->thread_stack_offset,
335 param->pointer_width,
336 (uint8_t *)&stack_ptr);
337 if (retval != ERROR_OK) {
338 LOG_ERROR("Error reading stack frame from eCos thread");
339 return retval;
340 }
341
342 return rtos_generic_stack_read(rtos->target,
343 param->stacking_info,
344 stack_ptr,
345 reg_list,
346 num_regs);
347 }
348
349 return -1;
350 }
351
352 static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
353 {
354 unsigned int i;
355 *symbol_list = calloc(
356 ARRAY_SIZE(ecos_symbol_list), sizeof(struct symbol_table_elem));
357
358 for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++)
359 (*symbol_list)[i].symbol_name = ecos_symbol_list[i];
360
361 return 0;
362 }
363
364 static bool ecos_detect_rtos(struct target *target)
365 {
366 if ((target->rtos->symbols != NULL) &&
367 (target->rtos->symbols[ECOS_VAL_THREAD_LIST].address != 0)) {
368 /* looks like eCos */
369 return true;
370 }
371 return false;
372 }
373
374 static int ecos_create(struct target *target)
375 {
376 for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++)
377 if (strcmp(ecos_params_list[i].target_name, target->type->name) == 0) {
378 target->rtos->rtos_specific_params = (void *)&ecos_params_list[i];
379 target->rtos->current_thread = 0;
380 target->rtos->thread_details = NULL;
381 return 0;
382 }
383
384 LOG_ERROR("Could not find target in eCos compatibility list");
385 return -1;
386 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)