2 * SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2018 National Instruments Corp
5 * Author: Moritz Fischer <moritz.fischer@ettus.com>
7 * Chromium-EC RTOS Task Awareness
10 #include <rtos/rtos.h>
11 #include <target/target.h>
12 #include <target/target_type.h>
14 #include "rtos_standard_stackings.h"
16 #define CROS_EC_MAX_TASKS 32
17 #define CROS_EC_MAX_NAME 200
18 #define CROS_EC_IDLE_STRING "<< idle >>"
19 #define BIT(x) (1 << (x))
21 struct chromium_ec_params
{
22 const char *target_name
;
24 off_t task_offset_next
;
26 off_t task_offset_events
;
27 off_t task_offset_runtime
;
28 const struct rtos_register_stacking
*stacking
;
31 static const struct chromium_ec_params chromium_ec_params_list
[] = {
33 .target_name
= "hla_target",
35 .task_offset_next
= 24,
37 .task_offset_events
= 4,
38 .task_offset_runtime
= 8,
39 .stacking
= &rtos_standard_Cortex_M3_stacking
,
43 .target_name
= "cortex_m",
45 .task_offset_next
= 24,
47 .task_offset_events
= 4,
48 .task_offset_runtime
= 8,
49 .stacking
= &rtos_standard_Cortex_M3_stacking
,
53 static const char * const chromium_ec_symbol_list
[] = {
64 enum chromium_ec_symbol_values
{
65 CHROMIUM_EC_VAL_start_called
= 0,
66 CHROMIUM_EC_VAL_current_task
,
67 CHROMIUM_EC_VAL_tasks
,
68 CHROMIUM_EC_VAL_tasks_enabled
,
69 CHROMIUM_EC_VAL_tasks_ready
,
70 CHROMIUM_EC_VAL_task_names
,
71 CHROMIUM_EC_VAL_build_info
,
73 CHROMIUM_EC_VAL_COUNT
,
76 #define CROS_EC_MAX_BUILDINFO 512
78 static bool chromium_ec_detect_rtos(struct target
*target
)
80 char build_info_buf
[CROS_EC_MAX_BUILDINFO
];
81 enum chromium_ec_symbol_values sym
;
84 if (!target
|| !target
->rtos
|| !target
->rtos
->symbols
)
87 for (sym
= CHROMIUM_EC_VAL_start_called
;
88 sym
< CHROMIUM_EC_VAL_COUNT
; sym
++) {
89 if (target
->rtos
->symbols
[sym
].address
) {
90 LOG_DEBUG("Chromium-EC: Symbol \"%s\" found",
91 chromium_ec_symbol_list
[sym
]);
93 LOG_ERROR("Chromium-EC: Symbol \"%s\" missing",
94 chromium_ec_symbol_list
[sym
]);
99 ret
= target_read_buffer(target
,
100 target
->rtos
->symbols
[CHROMIUM_EC_VAL_build_info
].address
,
101 sizeof(build_info_buf
),
102 (uint8_t *)build_info_buf
);
107 LOG_INFO("Chromium-EC: Buildinfo: %s", build_info_buf
);
109 return target
->rtos
->symbols
&&
110 target
->rtos
->symbols
[CHROMIUM_EC_VAL_start_called
].address
;
113 static int chromium_ec_create(struct target
*target
)
115 struct chromium_ec_params
*params
;
118 for (t
= 0; t
< ARRAY_SIZE(chromium_ec_params_list
); t
++)
119 if (!strcmp(chromium_ec_params_list
[t
].target_name
, target
->type
->name
)) {
120 params
= malloc(sizeof(*params
));
122 LOG_ERROR("Chromium-EC: out of memory");
126 memcpy(params
, &chromium_ec_params_list
[t
], sizeof(*params
));
127 target
->rtos
->rtos_specific_params
= (void *)params
;
128 target
->rtos
->current_thread
= 0;
129 target
->rtos
->thread_details
= NULL
;
130 target
->rtos
->thread_count
= 0;
132 LOG_INFO("Chromium-EC: Using target: %s", target
->type
->name
);
136 LOG_ERROR("Chromium-EC: target not supported: %s", target
->type
->name
);
140 static int chromium_ec_get_current_task_ptr(struct rtos
*rtos
, uint32_t *current_task
)
142 if (!rtos
|| !rtos
->symbols
)
145 return target_read_u32(rtos
->target
,
146 rtos
->symbols
[CHROMIUM_EC_VAL_current_task
].address
,
150 static int chromium_ec_get_num_tasks(struct rtos
*rtos
, int *num_tasks
)
152 uint32_t tasks_enabled
;
155 ret
= target_read_u32(rtos
->target
,
156 rtos
->symbols
[CHROMIUM_EC_VAL_tasks_enabled
].address
,
158 if (ret
!= ERROR_OK
) {
159 LOG_ERROR("Failed to determine #of tasks");
164 for (t
= 0; t
< CROS_EC_MAX_TASKS
; t
++)
165 if (tasks_enabled
& BIT(t
))
173 static int chromium_ec_update_threads(struct rtos
*rtos
)
175 uint32_t tasks_enabled
, tasks_ready
, start_called
;
176 uint32_t current_task
, thread_ptr
, name_ptr
;
177 char thread_str_buf
[CROS_EC_MAX_NAME
];
178 int ret
, t
, num_tasks
, tasks_found
;
179 struct chromium_ec_params
*params
;
180 uint8_t runtime_buf
[8];
184 params
= rtos
->rtos_specific_params
;
192 ret
= chromium_ec_get_num_tasks(rtos
, &num_tasks
);
193 if (ret
!= ERROR_OK
) {
194 LOG_ERROR("Failed to get number of tasks");
199 ret
= chromium_ec_get_current_task_ptr(rtos
, ¤t_task
);
200 if (ret
!= ERROR_OK
) {
201 LOG_ERROR("Failed to get current task");
204 LOG_DEBUG("Current task: %lx tasks_found: %d",
205 (unsigned long)current_task
,
208 /* set current task to what we read */
209 rtos
->current_thread
= current_task
;
211 /* Nuke the old tasks */
212 rtos_free_threadlist(rtos
);
214 /* One check if task switching has started ... */
216 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_start_called
].address
,
218 if (ret
!= ERROR_OK
) {
219 LOG_ERROR("Failed to load start_called");
223 if (!rtos
->current_thread
|| !num_tasks
|| !start_called
) {
226 rtos
->thread_details
= malloc(
227 sizeof(struct thread_detail
) * num_tasks
);
228 rtos
->thread_details
->threadid
= 1;
229 rtos
->thread_details
->exists
= true;
230 rtos
->thread_details
->extra_info_str
= NULL
;
231 rtos
->thread_details
->thread_name_str
= strdup("Current Execution");
233 if (!num_tasks
|| !start_called
) {
234 rtos
->thread_count
= 1;
238 /* create space for new thread details */
239 rtos
->thread_details
= malloc(
240 sizeof(struct thread_detail
) * num_tasks
);
244 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_tasks_enabled
].address
,
246 if (ret
!= ERROR_OK
) {
247 LOG_ERROR("Failed to load tasks_enabled");
252 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_tasks_ready
].address
,
254 if (ret
!= ERROR_OK
) {
255 LOG_ERROR("Failed to load tasks_ready");
259 thread_ptr
= rtos
->symbols
[CHROMIUM_EC_VAL_tasks
].address
;
262 for (t
= 0; t
< CROS_EC_MAX_TASKS
; t
++) {
263 if (!(tasks_enabled
& BIT(t
)))
266 if (thread_ptr
== current_task
)
267 rtos
->current_thread
= thread_ptr
;
269 rtos
->thread_details
[tasks_found
].threadid
= thread_ptr
;
270 ret
= target_read_u32(rtos
->target
,
271 rtos
->symbols
[CHROMIUM_EC_VAL_task_names
].address
+
272 params
->ptr_size
* t
, &name_ptr
);
273 if (ret
!= ERROR_OK
) {
274 LOG_ERROR("Failed to read name_ptr");
278 /* read name buffer */
279 ret
= target_read_buffer(rtos
->target
, name_ptr
, CROS_EC_MAX_NAME
,
280 (uint8_t *)thread_str_buf
);
281 if (ret
!= ERROR_OK
) {
282 LOG_ERROR("Failed to read task name");
286 /* sanitize string, gdb chokes on "<< idle >>" */
287 if (thread_str_buf
[CROS_EC_MAX_NAME
- 1] != '\0')
288 thread_str_buf
[CROS_EC_MAX_NAME
- 1] = '\0';
289 if (!strncmp(thread_str_buf
, CROS_EC_IDLE_STRING
, CROS_EC_MAX_NAME
))
290 rtos
->thread_details
[tasks_found
].thread_name_str
= strdup("IDLE");
292 rtos
->thread_details
[tasks_found
].thread_name_str
= strdup(thread_str_buf
);
295 ret
= target_read_u32(rtos
->target
,
296 thread_ptr
+ params
->task_offset_events
,
299 LOG_ERROR("Failed to get task %d's events", t
);
301 /* this is a bit kludgy but will do for now */
302 ret
= target_read_buffer(rtos
->target
,
303 thread_ptr
+ params
->task_offset_runtime
,
304 sizeof(runtime_buf
), runtime_buf
);
306 LOG_ERROR("Failed to get task %d's runtime", t
);
307 runtime
= target_buffer_get_u64(rtos
->target
, runtime_buf
);
309 /* Priority is simply the positon in the array */
310 if (thread_ptr
== current_task
)
311 snprintf(thread_str_buf
, sizeof(thread_str_buf
),
312 "State: Running, Priority: %u, Events: %" PRIx32
", Runtime: %" PRIu64
"\n",
315 snprintf(thread_str_buf
, sizeof(thread_str_buf
),
316 "State: %s, Priority: %u, Events: %" PRIx32
", Runtime: %" PRIu64
"\n",
317 tasks_ready
& BIT(t
) ? "Ready" : "Waiting", t
,
320 rtos
->thread_details
[tasks_found
].extra_info_str
= strdup(thread_str_buf
);
321 rtos
->thread_details
[tasks_found
].exists
= true;
323 thread_ptr
+= params
->task_offset_next
;
328 rtos
->thread_count
= tasks_found
;
333 static int chromium_ec_get_thread_reg_list(struct rtos
*rtos
,
335 struct rtos_reg
**reg_list
,
338 struct chromium_ec_params
*params
= rtos
->rtos_specific_params
;
339 uint32_t stack_ptr
= 0;
342 for (t
= 0; t
< rtos
->thread_count
; t
++)
343 if (threadid
== rtos
->thread_details
[t
].threadid
)
346 /* if we didn't find threadid, bail */
347 if (t
== rtos
->thread_count
)
350 ret
= target_read_u32(rtos
->target
,
351 rtos
->symbols
[CHROMIUM_EC_VAL_tasks
].address
+
352 params
->task_offset_next
* t
,
354 if (ret
!= ERROR_OK
) {
355 LOG_ERROR("Failed to load TCB");
359 return rtos_generic_stack_read(rtos
->target
, params
->stacking
,
360 stack_ptr
, reg_list
, num_regs
);
363 static int chromium_ec_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
367 *symbol_list
= calloc(ARRAY_SIZE(chromium_ec_symbol_list
),
368 sizeof(symbol_table_elem_t
));
369 if (!(*symbol_list
)) {
370 LOG_ERROR("Chromium-EC: out of memory");
374 for (s
= 0; s
< ARRAY_SIZE(chromium_ec_symbol_list
); s
++)
375 (*symbol_list
)[s
].symbol_name
= chromium_ec_symbol_list
[s
];
380 const struct rtos_type chromium_ec_rtos
= {
381 .name
= "Chromium-EC",
382 .detect_rtos
= chromium_ec_detect_rtos
,
383 .create
= chromium_ec_create
,
384 .update_threads
= chromium_ec_update_threads
,
385 .get_thread_reg_list
= chromium_ec_get_thread_reg_list
,
386 .get_symbol_list_to_lookup
= chromium_ec_get_symbol_list_to_lookup
,
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)