1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2018 National Instruments Corp
5 * Author: Moritz Fischer <moritz.fischer@ettus.com>
7 * Chromium-EC RTOS Task Awareness
14 #include <helper/bits.h>
15 #include <rtos/rtos.h>
16 #include <target/target.h>
17 #include <target/target_type.h>
19 #include "rtos_standard_stackings.h"
21 #define CROS_EC_MAX_TASKS 32
22 #define CROS_EC_MAX_NAME 200
23 #define CROS_EC_IDLE_STRING "<< idle >>"
25 struct chromium_ec_params
{
26 const char *target_name
;
28 off_t task_offset_next
;
30 off_t task_offset_events
;
31 off_t task_offset_runtime
;
32 const struct rtos_register_stacking
*stacking
;
35 static const struct chromium_ec_params chromium_ec_params_list
[] = {
37 .target_name
= "hla_target",
39 .task_offset_next
= 24,
41 .task_offset_events
= 4,
42 .task_offset_runtime
= 8,
43 .stacking
= &rtos_standard_cortex_m3_stacking
,
47 .target_name
= "cortex_m",
49 .task_offset_next
= 24,
51 .task_offset_events
= 4,
52 .task_offset_runtime
= 8,
53 .stacking
= &rtos_standard_cortex_m3_stacking
,
57 static const char * const chromium_ec_symbol_list
[] = {
68 enum chromium_ec_symbol_values
{
69 CHROMIUM_EC_VAL_START_CALLED
= 0,
70 CHROMIUM_EC_VAL_CURRENT_TASK
,
71 CHROMIUM_EC_VAL_TASKS
,
72 CHROMIUM_EC_VAL_TASKS_ENABLED
,
73 CHROMIUM_EC_VAL_TASKS_READY
,
74 CHROMIUM_EC_VAL_TASK_NAMES
,
75 CHROMIUM_EC_VAL_BUILD_INFO
,
77 CHROMIUM_EC_VAL_COUNT
,
80 #define CROS_EC_MAX_BUILDINFO 512
82 static bool chromium_ec_detect_rtos(struct target
*target
)
84 char build_info_buf
[CROS_EC_MAX_BUILDINFO
];
85 enum chromium_ec_symbol_values sym
;
88 if (!target
|| !target
->rtos
|| !target
->rtos
->symbols
)
91 for (sym
= CHROMIUM_EC_VAL_START_CALLED
;
92 sym
< CHROMIUM_EC_VAL_COUNT
; sym
++) {
93 if (target
->rtos
->symbols
[sym
].address
) {
94 LOG_DEBUG("Chromium-EC: Symbol \"%s\" found",
95 chromium_ec_symbol_list
[sym
]);
97 LOG_ERROR("Chromium-EC: Symbol \"%s\" missing",
98 chromium_ec_symbol_list
[sym
]);
103 ret
= target_read_buffer(target
,
104 target
->rtos
->symbols
[CHROMIUM_EC_VAL_BUILD_INFO
].address
,
105 sizeof(build_info_buf
),
106 (uint8_t *)build_info_buf
);
111 LOG_INFO("Chromium-EC: Buildinfo: %s", build_info_buf
);
113 return target
->rtos
->symbols
&&
114 target
->rtos
->symbols
[CHROMIUM_EC_VAL_START_CALLED
].address
;
117 static int chromium_ec_create(struct target
*target
)
119 struct chromium_ec_params
*params
;
122 for (t
= 0; t
< ARRAY_SIZE(chromium_ec_params_list
); t
++)
123 if (!strcmp(chromium_ec_params_list
[t
].target_name
, target
->type
->name
)) {
124 params
= malloc(sizeof(*params
));
126 LOG_ERROR("Chromium-EC: out of memory");
130 memcpy(params
, &chromium_ec_params_list
[t
], sizeof(*params
));
131 target
->rtos
->rtos_specific_params
= (void *)params
;
132 target
->rtos
->current_thread
= 0;
133 target
->rtos
->thread_details
= NULL
;
134 target
->rtos
->thread_count
= 0;
136 LOG_INFO("Chromium-EC: Using target: %s", target
->type
->name
);
140 LOG_ERROR("Chromium-EC: target not supported: %s", target
->type
->name
);
144 static int chromium_ec_get_current_task_ptr(struct rtos
*rtos
, uint32_t *current_task
)
146 if (!rtos
|| !rtos
->symbols
)
149 return target_read_u32(rtos
->target
,
150 rtos
->symbols
[CHROMIUM_EC_VAL_CURRENT_TASK
].address
,
154 static int chromium_ec_get_num_tasks(struct rtos
*rtos
, int *num_tasks
)
156 uint32_t tasks_enabled
;
159 ret
= target_read_u32(rtos
->target
,
160 rtos
->symbols
[CHROMIUM_EC_VAL_TASKS_ENABLED
].address
,
162 if (ret
!= ERROR_OK
) {
163 LOG_ERROR("Failed to determine #of tasks");
168 for (t
= 0; t
< CROS_EC_MAX_TASKS
; t
++)
169 if (tasks_enabled
& BIT(t
))
177 static int chromium_ec_update_threads(struct rtos
*rtos
)
179 uint32_t tasks_enabled
, tasks_ready
, start_called
;
180 uint32_t current_task
, thread_ptr
, name_ptr
;
181 char thread_str_buf
[CROS_EC_MAX_NAME
];
182 int ret
, t
, num_tasks
, tasks_found
;
183 struct chromium_ec_params
*params
;
184 uint8_t runtime_buf
[8];
188 params
= rtos
->rtos_specific_params
;
196 ret
= chromium_ec_get_num_tasks(rtos
, &num_tasks
);
197 if (ret
!= ERROR_OK
) {
198 LOG_ERROR("Failed to get number of tasks");
203 ret
= chromium_ec_get_current_task_ptr(rtos
, ¤t_task
);
204 if (ret
!= ERROR_OK
) {
205 LOG_ERROR("Failed to get current task");
208 LOG_DEBUG("Current task: %lx tasks_found: %d",
209 (unsigned long)current_task
,
212 /* set current task to what we read */
213 rtos
->current_thread
= current_task
;
215 /* Nuke the old tasks */
216 rtos_free_threadlist(rtos
);
218 /* One check if task switching has started ... */
220 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_START_CALLED
].address
,
222 if (ret
!= ERROR_OK
) {
223 LOG_ERROR("Failed to load start_called");
227 if (!rtos
->current_thread
|| !num_tasks
|| !start_called
) {
230 rtos
->thread_details
= malloc(
231 sizeof(struct thread_detail
) * num_tasks
);
232 rtos
->thread_details
->threadid
= 1;
233 rtos
->thread_details
->exists
= true;
234 rtos
->thread_details
->extra_info_str
= NULL
;
235 rtos
->thread_details
->thread_name_str
= strdup("Current Execution");
237 if (!num_tasks
|| !start_called
) {
238 rtos
->thread_count
= 1;
242 /* create space for new thread details */
243 rtos
->thread_details
= malloc(
244 sizeof(struct thread_detail
) * num_tasks
);
248 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_TASKS_ENABLED
].address
,
250 if (ret
!= ERROR_OK
) {
251 LOG_ERROR("Failed to load tasks_enabled");
256 ret
= target_read_u32(rtos
->target
, rtos
->symbols
[CHROMIUM_EC_VAL_TASKS_READY
].address
,
258 if (ret
!= ERROR_OK
) {
259 LOG_ERROR("Failed to load tasks_ready");
263 thread_ptr
= rtos
->symbols
[CHROMIUM_EC_VAL_TASKS
].address
;
266 for (t
= 0; t
< CROS_EC_MAX_TASKS
; t
++) {
267 if (!(tasks_enabled
& BIT(t
)))
270 if (thread_ptr
== current_task
)
271 rtos
->current_thread
= thread_ptr
;
273 rtos
->thread_details
[tasks_found
].threadid
= thread_ptr
;
274 ret
= target_read_u32(rtos
->target
,
275 rtos
->symbols
[CHROMIUM_EC_VAL_TASK_NAMES
].address
+
276 params
->ptr_size
* t
, &name_ptr
);
277 if (ret
!= ERROR_OK
) {
278 LOG_ERROR("Failed to read name_ptr");
282 /* read name buffer */
283 ret
= target_read_buffer(rtos
->target
, name_ptr
, CROS_EC_MAX_NAME
,
284 (uint8_t *)thread_str_buf
);
285 if (ret
!= ERROR_OK
) {
286 LOG_ERROR("Failed to read task name");
290 /* sanitize string, gdb chokes on "<< idle >>" */
291 if (thread_str_buf
[CROS_EC_MAX_NAME
- 1] != '\0')
292 thread_str_buf
[CROS_EC_MAX_NAME
- 1] = '\0';
293 if (!strncmp(thread_str_buf
, CROS_EC_IDLE_STRING
, CROS_EC_MAX_NAME
))
294 rtos
->thread_details
[tasks_found
].thread_name_str
= strdup("IDLE");
296 rtos
->thread_details
[tasks_found
].thread_name_str
= strdup(thread_str_buf
);
299 ret
= target_read_u32(rtos
->target
,
300 thread_ptr
+ params
->task_offset_events
,
303 LOG_ERROR("Failed to get task %d's events", t
);
305 /* this is a bit kludgy but will do for now */
306 ret
= target_read_buffer(rtos
->target
,
307 thread_ptr
+ params
->task_offset_runtime
,
308 sizeof(runtime_buf
), runtime_buf
);
310 LOG_ERROR("Failed to get task %d's runtime", t
);
311 runtime
= target_buffer_get_u64(rtos
->target
, runtime_buf
);
313 /* Priority is simply the position in the array */
314 if (thread_ptr
== current_task
)
315 snprintf(thread_str_buf
, sizeof(thread_str_buf
),
316 "State: Running, Priority: %u, Events: %" PRIx32
", Runtime: %" PRIu64
"\n",
319 snprintf(thread_str_buf
, sizeof(thread_str_buf
),
320 "State: %s, Priority: %u, Events: %" PRIx32
", Runtime: %" PRIu64
"\n",
321 tasks_ready
& BIT(t
) ? "Ready" : "Waiting", t
,
324 rtos
->thread_details
[tasks_found
].extra_info_str
= strdup(thread_str_buf
);
325 rtos
->thread_details
[tasks_found
].exists
= true;
327 thread_ptr
+= params
->task_offset_next
;
332 rtos
->thread_count
= tasks_found
;
337 static int chromium_ec_get_thread_reg_list(struct rtos
*rtos
,
339 struct rtos_reg
**reg_list
,
342 struct chromium_ec_params
*params
= rtos
->rtos_specific_params
;
343 uint32_t stack_ptr
= 0;
346 for (t
= 0; t
< rtos
->thread_count
; t
++)
347 if (threadid
== rtos
->thread_details
[t
].threadid
)
350 /* if we didn't find threadid, bail */
351 if (t
== rtos
->thread_count
)
354 ret
= target_read_u32(rtos
->target
,
355 rtos
->symbols
[CHROMIUM_EC_VAL_TASKS
].address
+
356 params
->task_offset_next
* t
,
358 if (ret
!= ERROR_OK
) {
359 LOG_ERROR("Failed to load TCB");
363 return rtos_generic_stack_read(rtos
->target
, params
->stacking
,
364 stack_ptr
, reg_list
, num_regs
);
367 static int chromium_ec_get_symbol_list_to_lookup(struct symbol_table_elem
*symbol_list
[])
371 *symbol_list
= calloc(ARRAY_SIZE(chromium_ec_symbol_list
),
372 sizeof(struct symbol_table_elem
));
373 if (!(*symbol_list
)) {
374 LOG_ERROR("Chromium-EC: out of memory");
378 for (s
= 0; s
< ARRAY_SIZE(chromium_ec_symbol_list
); s
++)
379 (*symbol_list
)[s
].symbol_name
= chromium_ec_symbol_list
[s
];
384 const struct rtos_type chromium_ec_rtos
= {
385 .name
= "Chromium-EC",
386 .detect_rtos
= chromium_ec_detect_rtos
,
387 .create
= chromium_ec_create
,
388 .update_threads
= chromium_ec_update_threads
,
389 .get_thread_reg_list
= chromium_ec_get_thread_reg_list
,
390 .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)