#include #include #include /* * About this defination, please refer to common/board_f.c * Pointer to initial global data area * * Here we initialize it if needed. */ #ifdef XTRN_DECLARE_GLOBAL_DATA_PTR #undef XTRN_DECLARE_GLOBAL_DATA_PTR #define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */ DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR); #else DECLARE_GLOBAL_DATA_PTR; #endif /* * one element record one function event : enter or exit * time [bit 31 ~ 3] : event time stamp, uint16_t about 32 seconds, * which is enough for boot0 & uboot * time [bit 2 ~ 0] : enter or exit flag * funaddr : function address, using "unsigned long" * (32-bits in arm, 64-bits in arm64) * In 32-bit-ARCH : 8-bytes can record one event * In 64-bit_ARCH : need 12-bytes */ struct ff_one_element { uint32_t time; unsigned long funaddr; }; #define ELEMENT_FLAG_BITS (3) #define ELEMENT_FLAG_MASK ((1< FF_MAX_ELEMENT_NUM) { ff_buf_full_flag = FF_BUF_FULL; return -1; } time = fun_gcc_get_arch_counter(); time = time / 24; *((uint32_t *)ff_buf_cur) = ((uint32_t)(time<> ARM64_HANDLE_LOW32BITS); #endif ff_buf_cur += sizeof(unsigned long); ff_buf_element_cnt++; return 0; } void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter(void *this_func, void *call_site) { ff_handle_one_event(this_func, FF_FUN_ENTER_FLAG); return; } void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit(void *this_func, void *call_site) { ff_handle_one_event(this_func, FF_FUN_EXIT_FLAG); return; } int __attribute__((__no_instrument_function__)) ff_ouput_print_buf(void) { return 0; /* only open this function when debug*/ int i; struct ff_one_element *element; char *buf_pointer = (char *)ff_print_buf + FF_BUF_HEAD_SIZE; printf("Reloc_off : 0x%lx : element_cnt=%d, FF_MAX_ELEMENT_NUM=%d\n", gd->reloc_off, ff_buf_element_cnt, FF_MAX_ELEMENT_NUM); for (i = 0; i < (ff_buf_element_cnt-1); i++) { element = (struct ff_one_element *)((char *)buf_pointer + i*sizeof(struct ff_one_element)); if (0 == element->time && 0 == element->funaddr) { element = (struct ff_one_element *)((char *)buf_pointer - gd->reloc_off + i*sizeof(struct ff_one_element)); } printf("%9d:%c:0x%lx\n", (element->time)>>ELEMENT_FLAG_BITS, ((((element->time) & ELEMENT_FLAG_MASK) == FF_FUN_ENTER_FLAG)?'G':'L'), element->funaddr); } return 0; } extern int __attribute__((__no_instrument_function__)) ff_write_fun_trace_data2flash(void *data_buffer, unsigned int data_size); int __attribute__((__no_instrument_function__)) ff_move_reloc_data(void) { unsigned int i; unsigned int data_size; struct ff_one_element *element; struct aw_uboot_trace_buf_head *buf_head; char *buf_pointer = (char *)ff_print_buf + FF_BUF_HEAD_SIZE; for (i = 0; i < (ff_buf_element_cnt-1); i++) { element = (struct ff_one_element *) ((char *)buf_pointer + i*sizeof(struct ff_one_element)); if (0 == element->time && 0 == element->funaddr) { *element = *((struct ff_one_element *) ((char *)buf_pointer - gd->reloc_off + i*sizeof(struct ff_one_element))); } else { break; } } /* * write the buf head size */ data_size = (ff_buf_element_cnt-1) * sizeof(struct ff_one_element); buf_head = (struct aw_uboot_trace_buf_head *)ff_print_buf; buf_head->reloc_off = gd->reloc_off; buf_head->valid_data_size = data_size; /* for debug */ #if 0 printf("buffer head info : reloc=0x%x, data_size=0x%x\n", buf_head->reloc_off, buf_head->valid_data_size); buf_pointer = (char *)ff_print_buf + FF_BUF_HEAD_SIZE; for (i = 0; i < (ff_buf_element_cnt-1); i++) { element = (struct ff_one_element *) ((char *)buf_pointer + i*sizeof(struct ff_one_element)); printf("* [%d, 0x%x] %9d:%c:0x%lux\n", i, (unsigned int)element, (element->time)>>ELEMENT_FLAG_BITS, ((((element->time) & ELEMENT_FLAG_MASK) == FF_FUN_ENTER_FLAG)?'G':'L'), element->funaddr); } #endif /* flush data to storage from ddr */ data_size += FF_BUF_HEAD_SIZE; ff_write_fun_trace_data2flash(ff_print_buf, data_size); return 0; }