25 #define LINUX_USER_KERNEL_BORDER 0xc0000000
28 #define MAX_THREADS 200
105 LOG_ERROR(
"Cannot compute linux virt2phys translation");
127 LOG_ERROR(
"linux awareness : address in user space");
151 const uint8_t *value_ptr =
buffer;
157 int64_t thread_id,
struct rtos_reg **reg_list,
int *num_regs)
170 if (next->threadid == thread_id)
174 }
while ((found == 0) && (next != tmp) && (next));
177 LOG_ERROR(
"could not find thread: %" PRIx64, thread_id);
182 struct reg **gdb_reg_list;
196 "current thread %" PRIx64
": no target to perform access of core id %" PRIx32,
207 *reg_list = calloc(*num_regs,
sizeof(
struct rtos_reg));
209 for (
int i = 0; i < *num_regs; ++i) {
210 if (!gdb_reg_list[i]->valid)
211 gdb_reg_list[i]->
type->
get(gdb_reg_list[i]);
213 (*reg_list)[i].number = gdb_reg_list[i]->
number;
214 (*reg_list)[i].size = gdb_reg_list[i]->
size;
216 buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].
size);
277 LOG_ERROR(
"fill_task_pid: unable to read memory");
289 uint8_t *
buffer = calloc(1, 4);
296 LOG_ERROR(
"fill_task: unable to read memory");
304 LOG_ERROR(
"fill task: unable to read memory");
312 LOG_ERROR(
"fill task: unable to read memory");
320 uint32_t asid_addr = val +
MM_CTX;
328 (
"fill task: unable to read memory -- ASID");
332 LOG_ERROR(
"fill task: unable to read memory");
342 uint32_t full_name[4];
346 for (i = 0; i < 17; i++)
352 LOG_ERROR(
"get_name: unable to read memory\n");
359 t->
name[3] = raw_name >> 24;
360 t->
name[2] = raw_name >> 16;
361 t->
name[1] = raw_name >> 8;
362 t->
name[0] = raw_name;
365 t->
name[7] = raw_name >> 24;
366 t->
name[6] = raw_name >> 16;
367 t->
name[5] = raw_name >> 8;
368 t->
name[4] = raw_name;
371 t->
name[11] = raw_name >> 24;
372 t->
name[10] = raw_name >> 16;
373 t->
name[9] = raw_name >> 8;
374 t->
name[8] = raw_name;
377 t->
name[15] = raw_name >> 24;
378 t->
name[14] = raw_name >> 16;
379 t->
name[13] = raw_name >> 8;
380 t->
name[12] = raw_name;
391 uint8_t *
buffer = calloc(1, 4);
399 ctt->TS = 0xdeadbeef;
404 struct reg **reg_list;
414 if (!reg_list[13]->
valid)
415 reg_list[13]->
type->
get(reg_list[13]);
417 buf = reg_list[13]->
value;
419 ti_addr = (val & 0xffffe000);
420 uint32_t ts_addr = ti_addr + 0xc;
425 uint32_t cpu, on_cpu = TS +
ONCPU;
434 while ((ct) && (ct->
core_id != (int32_t) cpu))
437 if ((ct) && (ct->
TS == 0xdeadbeef))
441 (
"error in linux current thread update");
445 t = calloc(1,
sizeof(
struct threads));
472 uint32_t *thread_info_addr_old)
475 uint32_t preempt_count_addr = 0;
476 uint32_t registers[10];
477 uint8_t *
buffer = calloc(1, 4);
478 uint32_t stack = base_addr +
QAT;
479 uint32_t thread_info_addr = 0;
480 uint32_t thread_info_addr_update = 0;
482 context->
R4 = 0xdeadbeef;
483 context->
R5 = 0xdeadbeef;
484 context->
R6 = 0xdeadbeef;
485 context->
R7 = 0xdeadbeef;
486 context->
R8 = 0xdeadbeef;
487 context->
R9 = 0xdeadbeef;
488 context->
IP = 0xdeadbeef;
489 context->
FP = 0xdeadbeef;
490 context->
SP = 0xdeadbeef;
491 context->
PC = 0xdeadbeef;
494 if (*thread_info_addr_old == 0xdeadbeef) {
500 LOG_ERROR(
"cpu_context: unable to read memory");
502 thread_info_addr_update = thread_info_addr;
504 thread_info_addr = *thread_info_addr_old;
506 preempt_count_addr = thread_info_addr +
PREEMPT;
512 if (*thread_info_addr_old != 0xdeadbeef) {
514 (
"cpu_context: cannot read at thread_info_addr");
518 (
"cpu_context : thread_info_addr in userspace!!!");
520 *thread_info_addr_old = 0xdeadbeef;
524 LOG_ERROR(
"cpu_context: unable to read memory");
530 (uint8_t *) registers);
534 LOG_ERROR(
"cpu_context: unable to read memory\n");
559 if (*thread_info_addr_old == 0xdeadbeef)
560 *thread_info_addr_old = thread_info_addr_update;
569 uint8_t *
buffer = calloc(1, 4);
579 LOG_ERROR(
"next task: unable to read memory");
608 LOG_INFO(
"del task %" PRId64, (*t)->threadid);
612 task_list = (*t)->
next;
618 *t = prev ? prev : task_list;
632 struct threads *temp = task_list;
657 while ((ct) && (ct->pid != pid))
659 while ((ct) && (ct->
TS != base_addr))
663 if ((ct) && (ct->pid == pid))
665 if ((ct) && (ct->
TS == base_addr))
741 t = calloc(1,
sizeof(
struct threads));
750 LOG_INFO(
"complete time %" PRId64
", thread mean %" PRId64
"\n",
784 os_linux->
name =
"linux";
826 if (ct->threadid == -1) {
830 t = calloc(1,
sizeof(
struct threads));
838 (
"linux identify_current_threads: unable to read pid");
876 LOG_INFO(
"current thread core %x identified %s",
877 ct->core_id, t->
name);
879 LOG_INFO(
"current thread core %x, reused %s",
880 ct->core_id, t->
name);
888 LOG_INFO(
"current thread core %x , already identified %s !!!",
889 ct->core_id, tmp.
name);
932 uint32_t previous = 0xdeadbeef;
939 (t->
base_addr != previous)) || (loop == 0)) {
946 retval = fill_task_pid(
target, t);
956 while (thread_list) {
958 if (t->
pid == thread_list->pid) {
960 if (t->
base_addr == thread_list->base_addr) {
962 if (!thread_list->status) {
964 if (t->
base_addr != thread_list->base_addr)
965 LOG_INFO(
"thread base_addr has changed !!");
969 thread_list->status = 1;
978 thread_list->context =
980 thread_list->base_addr,
981 &thread_list->thread_info_addr);
991 thread_list = thread_list->next;
1008 t = calloc(1,
sizeof(
struct threads));
1015 LOG_INFO(
"update thread done %" PRId64
", mean%" PRId64
"\n",
1032 LOG_INFO(
"received thread request without init task address");
1047 char *tmp_str = out_str;
1048 tmp_str += sprintf(tmp_str,
"m");
1052 tmp_str += sprintf(tmp_str,
"%016" PRIx64, temp->
threadid);
1055 tmp_str += sprintf(tmp_str,
",");
1083 char *out_strr = calloc(
MAX_THREADS * 17 + 10, 1);
1084 char *tmp_strr = out_strr;
1085 tmp_strr += sprintf(tmp_strr,
"m");
1087 tmp_strr += sprintf(tmp_strr,
"%016" PRIx64, temp->threadid);
1093 tmp_strr += sprintf(tmp_strr,
",");
1095 sprintf(tmp_strr,
"%016" PRIx64, temp->threadid);
1114 int64_t threadid = 0;
1117 sscanf(packet,
"qThreadExtraInfo,%" SCNx64, &threadid);
1123 char *tmp_str =
alloc_printf(
"%cPID: %" PRIu32
", Name: %s",
1124 temp->
status == 3 ?
'*' :
' ',
1130 char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
1131 size_t pkt_len =
hexify(hex_str, (
const uint8_t *)tmp_str,
1132 strlen(tmp_str), strlen(tmp_str) * 2 + 1);
1147 struct target *
target,
char const *packet,
int packet_size)
1153 sscanf(packet,
"T%" SCNx64, &threadid);
1180 LOG_INFO(
"gdb requested status on non existing thread");
1207 struct target *
target,
char const *packet,
int packet_size)
1217 int64_t current_gdb_thread_rq;
1220 if ((ct) && (ct->threadid == -1)) {
1223 while ((ct) && (ct->threadid == -1))
1230 LOG_INFO(
"no current thread identified");
1236 while ((ct) && (ct->threadid == -1)) {
1239 LOG_INFO(
"name of unidentified thread %s",
1248 if (packet[1] ==
'g') {
1249 sscanf(packet,
"Hg%16" SCNx64, ¤t_gdb_thread_rq);
1251 if (current_gdb_thread_rq == 0) {
1256 current_gdb_thread_rq;
1259 }
else if (packet[1] ==
'c') {
1260 sscanf(packet,
"Hc%16" SCNx64, ¤t_gdb_thread_rq);
1262 if ((current_gdb_thread_rq == 0) ||
1263 (current_gdb_thread_rq == ct->threadid)) {
1284 switch (packet[0]) {
1296 if (strncmp(packet,
"qSymbol", 7) == 0) {
1303 }
else if (strncmp(packet,
"qfThreadInfo", 12) == 0) {
1317 }
else if (strncmp(packet,
"qsThreadInfo", 12) == 0) {
1320 }
else if (strncmp(packet,
"qThreadExtraInfo,", 17) == 0) {
1342 if ((ct) && (ct->
threadid == -1)) {
1345 while ((ct) && (ct->
threadid == -1))
1352 LOG_WARNING(
"WARNING! current GDB thread do not match "
1353 "current thread running. "
1354 "Switch thread in GDB to threadid %d",
1357 LOG_INFO(
"threads_needs_update = 1");
1389 ct->TS = 0xdeadbeef;
1407 os_linux->
name =
"linux";
1419 ct->
TS = 0xdeadbeef;
1447 LOG_INFO(
"allocation for %d threads line",
1455 tmp += sprintf(tmp,
"PID\t\tCPU\t\tASID\t\tNAME\n");
1456 tmp += sprintf(tmp,
"---\t\t---\t\t----\t\t----\n");
1463 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1469 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1481 display = calloc(40, 1);
1482 sprintf(display,
"linux_ps_command failed\n");
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t size
Size of dw_spi_transaction::buffer.
uint32_t address
Starting address. Sector aligned.
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
static struct target * get_target_from_connection(struct connection *connection)
The JTAG interface can be implemented with a software or hardware fifo.
static struct current_thread * add_current_thread(struct current_thread *currents, struct current_thread *ct)
static int fill_task(struct target *target, struct threads *t)
static int clean_threadlist(struct target *target)
static int linux_os_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
static int linux_thread_extra_info(struct target *target, struct connection *connection, char const *packet, int packet_size)
static void linux_identify_current_threads(struct target *target)
static char * linux_ps_command(struct target *target)
static int linux_os_smp_init(struct target *target)
static uint32_t next_task(struct target *target, struct threads *t)
static int linux_gdb_thread_update(struct target *target, struct connection *connection, char const *packet, int packet_size)
static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
static int insert_into_threadlist(struct target *target, struct threads *t)
static int get_current(struct target *target, int create)
static int linux_gdb_h_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
static struct threads * liste_add_task(struct threads *task_list, struct threads *t, struct threads **last)
static int linux_compute_virt2phys(struct target *target, target_addr_t address)
static int linux_os_clean(struct target *target)
static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
static const char *const linux_symbol_list[]
static bool linux_os_detect(struct target *target)
#define LINUX_USER_KERNEL_BORDER
static int linux_get_tasks(struct target *target, int context)
static struct cpu_context * cpu_context_read(struct target *target, uint32_t base_addr, uint32_t *info_addr)
static int linux_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
static int get_name(struct target *target, struct threads *t)
const struct rtos_type linux_rtos
static int linux_gdb_thread_packet(struct target *target, struct connection *connection, char const *packet, int packet_size)
static int linux_os_dummy_update(struct rtos *rtos)
static int linux_task_update(struct target *target, int context)
static uint32_t get_buffer(struct target *target, const uint8_t *buffer)
static int linux_os_create(struct target *target)
static int linux_thread_packet(struct connection *connection, char const *packet, int packet_size)
static int linux_gdb_t_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
static struct threads * liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev)
char * alloc_printf(const char *format,...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
#define GDB_THREAD_PACKET_NOT_CONSUMED
target_addr_t addr
Start address to search for the control block.
#define foreach_smp_target(pos, head)
struct current_thread * next
struct threads * thread_list
struct current_thread * current_threads
int preupdtate_threadid_count
int(* get)(struct reg *reg)
const struct reg_arch_type * type
int(* create)(struct target *target)
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
struct symbol_table_elem * symbols
void * rtos_specific_params
Table should be terminated by an element with NULL in symbol_name.
int(* virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical)
struct list_head * smp_targets
struct target_type * type
struct cpu_context * context
uint32_t thread_info_addr
int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Obtain the registers for GDB.
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
#define ERROR_TARGET_FAILURE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.