0001-Add-soc-performance-monitor-utilites.patch0000644002162000023560000034370613324503746021154 0ustar a0850410cleartnpFrom 7830118ecb980766f4a6e3997769d7ae326bee77 Mon Sep 17 00:00:00 2001 From: Karthik Ramanan Date: Fri, 3 Jun 2016 18:32:50 +0530 Subject: [PATCH] Add soc performance monitor utilites Signed-off-by: Karthik Ramanan --- Makefile.am | 17 +- clients/Dra7xx_ddrstat_speed.c | 494 +++++++++++++ clients/soc_performance_monitor.c | 630 ++++++++++++++++ clients/soc_performance_monitor.h | 40 ++ clients/statcoll.c | 1433 +++++++++++++++++++++++++++++++++++++ clients/statcoll.h | 152 ++++ clients/statcoll_gui.h | 101 +++ clients/time_bar_graph.c | 515 +++++++++++++ clients/time_bar_graph.h | 93 +++ 10 files changed, 4873 insertions(+), 1 deletion(-) create mode 100644 clients/Dra7xx_ddrstat_speed.c create mode 100644 clients/soc_performance_monitor.c create mode 100644 clients/soc_performance_monitor.h create mode 100644 clients/statcoll.c create mode 100644 clients/statcoll.h create mode 100644 clients/statcoll_gui.h create mode 100644 clients/time_bar_graph.c create mode 100644 clients/time_bar_graph.h diff --git a/Makefile.am b/Makefile.am index 62719c9..55aed6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -432,7 +432,9 @@ demo_clients = \ weston-fullscreen \ weston-stacking \ weston-calibrator \ - weston-scaler + weston-scaler \ + soc-performance-monitor \ + soc-ddr-bw-visualizer if INSTALL_DEMO_CLIENTS bin_PROGRAMS += $(demo_clients) @@ -570,6 +572,19 @@ weston_image_SOURCES = clients/image.c weston_image_LDADD = libtoytoolkit.la weston_image_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) +noinst_LTLIBRARIES += libtimebargraph.la +libtimebargraph_la_SOURCES = clients/time_bar_graph.c clients/time_bar_graph.h +libtimebargraph_la_LIBADD = libtoytoolkit.la +libtimebargraph_la_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) $(CAIRO_CFLAGS) $(CAIRO_EGL_CFLAGS) + +soc_performance_monitor_SOURCES = clients/soc_performance_monitor.c clients/soc_performance_monitor.h +soc_performance_monitor_LDADD = libtoytoolkit.la libtimebargraph.la +soc_performance__CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) + +soc_ddr_bw_visualizer_SOURCES = clients/statcoll.c clients/Dra7xx_ddrstat_speed.c clients/statcoll.h clients/statcoll_gui.h +soc_ddr_bw_visualizer_LDADD = libtoytoolkit.la libtimebargraph.la +soc_ddr_bw_visualizer__CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) + weston_cliptest_SOURCES = \ clients/cliptest.c \ src/vertex-clipping.c \ diff --git a/clients/Dra7xx_ddrstat_speed.c b/clients/Dra7xx_ddrstat_speed.c new file mode 100644 index 0000000..af06733 --- /dev/null +++ b/clients/Dra7xx_ddrstat_speed.c @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2015 Texas Instruments + * Author: Karthik Ramanan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "statcoll.h" + +#define PAGE_SIZE 4096 + +#define EMIF1_BASE 0x4c000000 +#define EMIF2_BASE 0x4d000000 + +#define EMIF_PERF_CNT_1 0x80 +#define EMIF_PERF_CNT_2 0x84 +#define EMIF_PERF_CNT_CFG 0x88 +#define EMIF_PERF_CNT_TIM 0x90 + +static unsigned +tv_diff(struct timeval *tv1, struct timeval *tv2) +{ + return (tv2->tv_sec - tv1->tv_sec) * 1000000 + + (tv2->tv_usec - tv1->tv_usec); +} + + +struct emif_perf { + int code; + const char *name; +}; + +static const struct emif_perf emif_perf_tab[] = { + { 0, "access" }, + { 1, "activate" }, + { 2, "read" }, + { 3, "write" }, + { 4, "fifo_cmd" }, + { 5, "fifo_write" }, + { 6, "fifo_read" }, + { 7, "fifo_ret" }, + { 8, "prio" }, + { 9, "cmd_pend" }, + { 10, "data" }, +}; + +static void *emif1, *emif2; +static int BANDWIDTH=0; +static int DELAY = 1; +static int EMIF_PERF_CFG1 = 9; +static int EMIF_PERF_CFG2 = 10; + + +static int STATCOLL=0; +static int TOTAL_TIME; +static int INTERVAL_US; + +struct timeval t1, t2; + +FILE* outfile; +struct emif_stats { + uint32_t cycles; + uint32_t cnt1; + uint32_t cnt2; +}; + +static struct emif_stats emif1_start, emif1_end; +static struct emif_stats emif2_start, emif2_end; + +static void *emif_init(int fd, unsigned base) +{ + void *mem = + mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, base); + volatile uint32_t *emif = mem,temp; + + if (mem == MAP_FAILED){ + return NULL; + } + + emif[EMIF_PERF_CNT_CFG>>2] = EMIF_PERF_CFG2 << 16 | EMIF_PERF_CFG1; + + return mem; +} + +static void emif_read(volatile uint32_t *emif, struct emif_stats *st) +{ + st->cycles = emif[EMIF_PERF_CNT_TIM>>2]; + st->cnt1 = emif[EMIF_PERF_CNT_1>>2]; + st->cnt2 = emif[EMIF_PERF_CNT_2>>2]; +} + +static void emif_print(const char *tag, struct emif_stats *st1, + struct emif_stats *st2) +{ + uint32_t cycles = st2->cycles - st1->cycles; + uint32_t cnt1 = st2->cnt1 - st1->cnt1; + uint32_t cnt2 = st2->cnt2 - st1->cnt2; + printf("%s %s %2llu%% %s %2llu%%", tag, + emif_perf_tab[EMIF_PERF_CFG1].name, 100ull*cnt1/cycles, + emif_perf_tab[EMIF_PERF_CFG2].name, 100ull*cnt2/cycles); + fprintf(outfile,"%s%s= %2llu,%s%s= %2llu,", + tag, emif_perf_tab[EMIF_PERF_CFG1].name, 100ull*cnt1/cycles, + tag, emif_perf_tab[EMIF_PERF_CFG2].name, 100ull*cnt2/cycles); +} + +static int perf_init(void) +{ + int fd = open("/dev/mem", O_RDWR); + int err = 0; + + if (fd == -1){ + printf("error fd=open() \n"); + return -1; + } + emif1 = emif_init(fd, EMIF1_BASE); + emif2 = emif_init(fd, EMIF2_BASE); + + if (!emif1 || !emif2){ + printf("error if (!emif1 || !emif2) \n"); + err = -1; + } + + close(fd); + return err; +} + +static void perf_start(void) +{ + if (emif1) { + emif_read(emif1, &emif1_start); + emif_read(emif2, &emif2_start); + } +} + +static void perf_stop(void) +{ + if (emif1) { + emif_read(emif1, &emif1_end); + emif_read(emif2, &emif2_end); + } +} + +static void perf_print(void) +{ + if (emif1) { + emif_print("EMIF1", &emif1_start, &emif1_end); + printf("\t"); + emif_print("EMIF2", &emif2_start, &emif2_end); + printf("\r"); + fprintf(outfile, "\n"); + fflush(outfile); + fflush(stdout); + } +} + +static void perf_close(void) +{ + if (emif1) munmap(emif1, PAGE_SIZE); + if (emif2) munmap(emif2, PAGE_SIZE); +} + +static int get_cfg(const char *name, int def) +{ + char *end; + int n = strtol(name, &end, 0); + int i; + + if (!*end) + return n; + + for (i = 0; i < sizeof(emif_perf_tab)/sizeof(emif_perf_tab[0]); i++) + if (!strcmp(name, emif_perf_tab[i].name)) + return emif_perf_tab[i].code; + + return def; +} + + +unsigned int emif_freq() +{ + volatile unsigned *tim1; + unsigned v1, v2; + int fd; + + /*calculation EMIF frequency + EMIF_PERF_CNT_TIM = \n32-bit counter that + continuously counts number for + EMIF_FCLK clock cycles elapsed + after EMIFis brought out of reset*/ + + fd = open("/dev/mem", O_RDONLY); + if (fd == -1) { + perror("/dev/mem"); + return 1; + } + + void *mem = + mem = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, EMIF1_BASE); + if (mem == MAP_FAILED) { + perror("mmap"); + exit(1); + } + + tim1 = (unsigned *)((char*)mem + EMIF_PERF_CNT_TIM); + + v1 = *tim1; + gettimeofday(&t1, NULL); + sleep(2); + v2 = *tim1; + gettimeofday(&t2, NULL); + + munmap(mem, PAGE_SIZE); + close(fd); + + return (v2 - v1) / tv_diff(&t1, &t2); + +} + + +char config_file_path[100]; +char keylist[][50] = { + "DELAY", + "EMIF_PERF_CFG1", + "EMIF_PERF_CFG2", + "BANDWIDTH", + "STATCOLL", + "TOTAL_TIME", + "INTERVAL_US", + "INITIATORS", +}; + +char line[512], *p; +char tokens[6][512]; +int temp, flag = 0; +char *keyvalue, *pair; +char key[100]; +int linecount=0; + + +int debug=0; + +void print_valid_options(void) +{ + int i; + printf("Invalid key found\n"); + printf("Supported keys are :\n"); + for(i=0; i \n" + "## default : DELAY=1 EMIF_PERF_CFG1=9 EMIF_PERF_CFG2=10\n" + "## option : for EMIF_PERF_CFG1 and EMIF_PERF_CFG2\n" + "## 0 -> access,\n" + "## 1 -> activate,\n" + "## 2 -> read,\n" + "## 3 -> write,\n" + "## 4 -> fifo_cmd,\n" + "## 5 -> fifo_write,\n" + "## 6 -> fifo_read,\n" + "## 7 -> fifo_ret,\n" + "## 8 -> prio,\n" + "## 9 -> cmd_pend,\n" + "## 10 -> data \n##\n" + + "## EMIF frq : %d MHz\n\n", emif_freq() ); +} + + +int main(int argc, char **argv) +{ + int option; + FILE *fp; + int i; + int xpos = 600, ypos = 40; + + + /* Read config file */ + /* Initialize this to turn off verbosity of getopt */ + opterr = 0; + +// while ((option = getopt (argc, argv, "df:")) != -1) + while ((option = getopt (argc, argv, "dx:y:")) != -1) + { + switch(option) + { +#if 0 + case 'f': + strcpy(config_file_path, optarg); + break; +#endif + case 'd': + debug=1; + break; + case 'x': + xpos=atoi(optarg); + break; + case 'y': + ypos=atoi(optarg); + break; + + default: + printf("Invalid option.. Exiting\n"); + exit(0); + } + } + + printf("xpos = %d, ypos = %d\n", xpos, ypos); + + strcpy(config_file_path,"config.ini"); + fp = fopen(config_file_path, "r"); + if (fp == NULL) { + fprintf(stderr, "couldn't open the specified file\n"); + return -1; + } + + while (fgets(line, sizeof line, fp)) { + printd("Line is = %s", line); + + if (line[0] == '#' || line[0] == '\n') { + continue; + } + + memset(tokens, 0, sizeof(tokens)); + i = 0; + + pair = strtok (line," ,"); + while (pair != NULL) + { + printd ("\tPair is = %s\n",pair); + strcpy(tokens[i++], pair); + pair = strtok (NULL, " ,.-"); + } + + for(temp=0; temp< i; temp++) + { + printd("Line %d: %s\n", temp, tokens[temp]); + + keyvalue = strtok (tokens[temp]," ="); + while (keyvalue != NULL) + { + if(flag == 0) + { + if(validatekey(keyvalue)) + { + print_valid_options(); + exit(0); + } + strcpy(key, keyvalue); + printd ("\tKey is = %s\n",key); + flag++; + } + else + { + printd ("\tValue is = %s",keyvalue); + printd (" (%d)\n", atoi(keyvalue)); + add_key_value(key, atoi(keyvalue)); + flag = 0; + } + keyvalue = strtok (NULL, " ="); + } + } + + + + linecount++; + printd("%s", "------------------- \n"); + + } + + fclose(fp); + + printf("\n\nCOMPLETED: Parsing of the user specified parameters.. \n \ + \nConfiguring device now.. \n\n"); + if(BANDWIDTH == 1) { + bandwidth_usage(); + if (DELAY <= 0) + DELAY = 1; + + if (perf_init()){ + printf("perf_init return non zero \n"); + return 1; + } + + outfile = fopen("emif-performance.csv", "w+"); + if (!outfile) { + printf("\n Error opening file"); + } + for (;;) { + perf_start(); + sleep(DELAY); + perf_stop(); + perf_print(); + } + + fclose(outfile); + perf_close(); + return 0; + } + + if(STATCOLL == 1) { + printf("STATISTICS COLLECTOR option chosen\n"); + printf("------------------------------------------------\n\n"); + fp = fopen("initiators.cfg", "r"); + if (fp == NULL) { + fprintf(stderr, "couldn't open the specified file initiators.cfg'\n"); + return -1; + } + + int i=0; + char list[100][50]; + memset(list, sizeof(list), 0); + while (fgets(line, sizeof line, fp)) { + printf("Line is = %s", line); + /* Slightly strange way to chop off the \n character */ + strtok(line, "\n"); + strcpy(list[i++], line); + } + fclose(fp); + + statcoll_start(TOTAL_TIME, INTERVAL_US, list, xpos, ypos); + } + +} + diff --git a/clients/soc_performance_monitor.c b/clients/soc_performance_monitor.c new file mode 100644 index 0000000..5d1db32 --- /dev/null +++ b/clients/soc_performance_monitor.c @@ -0,0 +1,630 @@ +/* + * Copyright (C) 2016 Texas Instruments + * Author: Karthik Ramanan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "time_bar_graph.h" + +#include "soc_performance_monitor.h" + +static int debug=0; + +static char readfifo[100]; +static int MAX_WIDTH=1920; +static int MAX_HEIGHT=1080; +static int x_pos=0; +static int y_pos=40; + +void *ctx; +struct time_graph_create_params tg_p; +struct bar_graph_create_params bg_p; + +static int cpu_load_offset = 0; +static int total_cpu_load_items = 0; +static int total_elements = 0; + +struct _bar_graph_y_config *y_cfg; +struct _text_config *t_cfg; +char *tg_text[100]; +char *bg_text[100]; + + +int command_handler(int command, double *y, char **text) +{ + static int fd; + char buf[MAX_BUF]; + int i, bytes, offset; + + switch(command) + { + case OPEN: + fd = open(readfifo, O_RDONLY|O_NONBLOCK); + break; + + case READ: + + /* open, read, and display the message from the FIFO */ + bytes=read(fd, buf, MAX_BUF); + buf[bytes]='\0'; + if(bytes > 0) + { + char command[100]; + char string[100]; + sscanf(buf, "%s %s", command, string); + printd("Received %s\n", buf); + if(strcmp(command, "TABLE:") == 0) + { + char field[100], value[100], unit[100]; + sscanf(buf, "%s %s %s %s", command, field, value, unit); + for(i=0; iBL_START_X; + const int BL_START_Y = table_config->BL_START_Y; + const int BAR_GAP = table_config->BAR_GAP; + const int BAR_HEIGHT = table_config->BAR_HEIGHT; + const int BAR_WIDTH = table_config->BAR_WIDTH; + const int TR_START_X = table_config->TR_START_X; + const int TR_START_Y = table_config->TR_START_Y; + const int FONT_SIZE = table_config->FONT_SIZE; + printf("Filling from %d to %d\n", start_offset, end_offset); + cpu_load_offset = start_offset; + + for(i=start_offset; i< end_offset-1; i++) { + y_cfg[i*2].region.bottom_left.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH); + y_cfg[i*2].region.bottom_left.y = BL_START_Y; + y_cfg[i*2].region.top_right.x = TR_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH); + y_cfg[i*2].region.top_right.y = TR_START_Y; + y_cfg[i*2].line_color.r = 1.0; + y_cfg[i*2].line_color.g = 1.0; + y_cfg[i*2].line_color.b = 1.0; + y_cfg[i*2].line_color.a = 1.0; + y_cfg[i*2].fill_color.r = 0.0; + y_cfg[i*2].fill_color.g = 0.0; + y_cfg[i*2].fill_color.b = 1.0; + y_cfg[i*2].fill_color.a = 0.7; + + y_cfg[i*2+1].region.bottom_left.x = BL_START_X +(i-start_offset) * (BAR_GAP + BAR_WIDTH); + y_cfg[i*2+1].region.bottom_left.y = BL_START_Y; + y_cfg[i*2+1].region.top_right.x = TR_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH); + y_cfg[i*2+1].region.top_right.y = TR_START_Y; + y_cfg[i*2+1].line_color.r = 1.0; + y_cfg[i*2+1].line_color.g = 1.0; + y_cfg[i*2+1].line_color.b = 1.0; + y_cfg[i*2+1].line_color.a = 1.0; + y_cfg[i*2+1].fill_color.r = 1.0; + y_cfg[i*2+1].fill_color.g = 0.0; + y_cfg[i*2+1].fill_color.b = 0.0; + y_cfg[i*2+1].fill_color.a = 1.0; + + + t_cfg[i*2].color.r = 1.0; + t_cfg[i*2].color.g = 1.0; + t_cfg[i*2].color.b = 1.0; + t_cfg[i*2].color.a = 1.0; + t_cfg[i*2].at.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH); + t_cfg[i*2].at.y = BL_START_Y + FONT_SIZE; + t_cfg[i*2].fontsize = FONT_SIZE; + + t_cfg[i*2+1].color.r = 1.0; + t_cfg[i*2+1].color.g = 1.0; + t_cfg[i*2+1].color.b = 1.0; + t_cfg[i*2+1].color.a = 1.0; + t_cfg[i*2+1].at.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH); + t_cfg[i*2+1].at.y = BL_START_Y - BAR_HEIGHT - FONT_SIZE; + t_cfg[i*2+1].fontsize = FONT_SIZE; + + strcpy(bg_text[i*2], output[i - start_offset]); + strcpy(bg_text[i*2+1], "0%"); + } + + t_cfg[(end_offset-1)*2].color.r = 0.0; + t_cfg[(end_offset-1)*2].color.g = 1.0; + t_cfg[(end_offset-1)*2].color.b = 1.0; + t_cfg[(end_offset-1)*2].color.a = 1.0; + t_cfg[(end_offset-1)*2].at.x = BL_START_X + 80; + t_cfg[(end_offset-1)*2].at.y = TR_START_Y - 40; + t_cfg[(end_offset-1)*2].fontsize = FONT_SIZE + 3; + + printd("Copying title string %s\n", output[end_offset - start_offset -1]); + strcpy(bg_text[(end_offset-1)*2], output[end_offset - start_offset-1]); +} + +void fill_table_details(int start_offset, int end_offset, char **output, struct table_configuration *table_config) +{ + int i; + + const int BL_START_X = table_config->BL_START_X; + const int BL_START_Y = table_config->BL_START_Y; + const int BAR_GAP = table_config->BAR_GAP; + const int BAR_HEIGHT = table_config->BAR_HEIGHT; + const int BAR_WIDTH = table_config->BAR_WIDTH; + const int TR_START_X = table_config->TR_START_X; + const int TR_START_Y = table_config->TR_START_Y; + const int FONT_SIZE = table_config->FONT_SIZE; + printf("Filling from %d to %d\n", start_offset, end_offset); + + + char tokenize[200]; + char tokens[10][100]; + char *pair, *key, *value; + int k=0; + char title[100], unit[100]; + + strcpy(tokenize, output[end_offset - start_offset - 1]); + memset(tokens, 0, sizeof(tokens)); + + k=0; + pair = strtok (tokenize,","); + while (pair != NULL) { + strcpy(tokens[k++], pair); + pair = strtok (NULL, ","); + } + + i=0; + memset(title, 0, sizeof(title)); + memset(unit, 0, sizeof(unit)); + while(i < k) { + key=strtok(tokens[i], "="); + if(key != NULL) { + if(strcmp(key,"TITLE") == 0) { + value = strtok(NULL, "="); + if(value != NULL) { + strcpy(title, value); + } + } + if(strcmp(key,"UNIT") == 0) { + value = strtok(NULL, "="); + if(value != NULL) { + strcpy(unit, value); + } + } + } + i++; + } + + for(i=start_offset; i< end_offset-1; i++) { + y_cfg[i*2].region.bottom_left.x = BL_START_X; + y_cfg[i*2].region.bottom_left.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT); + y_cfg[i*2].region.top_right.x = TR_START_X; + y_cfg[i*2].region.top_right.y = TR_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT); + y_cfg[i*2].line_color.r = 1.0; + y_cfg[i*2].line_color.g = 1.0; + y_cfg[i*2].line_color.b = 1.0; + y_cfg[i*2].line_color.a = 1.0; + y_cfg[i*2].fill_color.r = 0.0; + y_cfg[i*2].fill_color.g = 0.3; + y_cfg[i*2].fill_color.b = 0.0; + y_cfg[i*2].fill_color.a = 0.7; + + y_cfg[i*2+1].region.bottom_left.x = TR_START_X; + y_cfg[i*2+1].region.bottom_left.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT); + y_cfg[i*2+1].region.top_right.x = TR_START_X + (BAR_WIDTH); //+ 1 * BL_START_X; + y_cfg[i*2+1].region.top_right.y = TR_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT);; + y_cfg[i*2+1].line_color.r = 1.0; + y_cfg[i*2+1].line_color.g = 1.0; + y_cfg[i*2+1].line_color.b = 1.0; + y_cfg[i*2+1].line_color.a = 1.0; + y_cfg[i*2+1].fill_color.r = 0.3; + y_cfg[i*2+1].fill_color.g = 0.0; + y_cfg[i*2+1].fill_color.b = 0.0; + y_cfg[i*2+1].fill_color.a = 0.7; + + + t_cfg[i*2].color.r = 1.0; + t_cfg[i*2].color.g = 1.0; + t_cfg[i*2].color.b = 1.0; + t_cfg[i*2].color.a = 1.0; + t_cfg[i*2].at.x = BL_START_X + 5; + t_cfg[i*2].at.y = BL_START_Y + (i - start_offset) * (BAR_GAP+BAR_HEIGHT) -5; + t_cfg[i*2].fontsize = FONT_SIZE; + + t_cfg[i*2+1].color.r = 1.0; + t_cfg[i*2+1].color.g = 1.0; + t_cfg[i*2+1].color.b = 1.0; + t_cfg[i*2+1].color.a = 1.0; + t_cfg[i*2+1].at.x = TR_START_X + 50;//BAR_WIDTH + TR_START_X; + t_cfg[i*2+1].at.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT) -5; + t_cfg[i*2+1].fontsize = FONT_SIZE; + + printd("Copying string %s at %d\n", output[i-start_offset], i); + strcpy(bg_text[i*2], output[i-start_offset]); + printd("Setting text 0 %s at %d\n", unit, i*2+1); + sprintf(bg_text[i*2+1], "0 %s", unit); + } + for(i=start_offset; i< end_offset*2; i++) { + printd("%d - (%d, %d) to (%d, %d)\n", i, y_cfg[i].region.bottom_left.x, y_cfg[i].region.bottom_left.y, y_cfg[i].region.top_right.x, y_cfg[i].region.top_right.y); + } + + t_cfg[(end_offset-1)*2].color.r = 0.0; + t_cfg[(end_offset-1)*2].color.g = 1.0; + t_cfg[(end_offset-1)*2].color.b = 1.0; + t_cfg[(end_offset-1)*2].color.a = 1.0; + t_cfg[(end_offset-1)*2].at.x = BL_START_X + 80; + t_cfg[(end_offset-1)*2].at.y = BL_START_Y - 40; + t_cfg[(end_offset-1)*2].fontsize = FONT_SIZE + 3; + + printd("Copying title string %s\n", title); + strcpy(bg_text[(end_offset-1)*2], title); + +} + + +int get_key_value_from_string(char *string, char *limiter, char *key, char *value) +{ + char *mykey, *myvalue; + + mykey=strtok(string, limiter); + if(mykey != NULL) { + myvalue = strtok(NULL, "="); + strtok(myvalue, "\n"); + if(myvalue == NULL) { + return -1; + } + } + else { + return -1; + } + printd("Key is %s\n", mykey); + printd("Value is %s\n", myvalue); + strcpy(key, mykey); + strcpy(value, myvalue); + return 0; + +} + +void populate_table_configuration(struct table_configuration *tbl_cfg, int cur_items, char **item_list) +{ + static int total_items = 0; + static int total_tables = 0; + + tbl_cfg->BAR_HEIGHT = 25; + tbl_cfg->BAR_WIDTH = 150; + tbl_cfg->BL_START_X = 40; + tbl_cfg->BL_START_Y = 80 + (total_items + total_tables) * tbl_cfg->BAR_HEIGHT; + tbl_cfg->BAR_GAP = 0; + tbl_cfg->TR_START_X = tbl_cfg->BL_START_X + tbl_cfg->BAR_WIDTH; + tbl_cfg->TR_START_Y = tbl_cfg->BL_START_Y - tbl_cfg->BAR_HEIGHT; + tbl_cfg->FONT_SIZE = 15; + + printf("Proceeding with filling out details...\n"); + if(cur_items > 0) + fill_table_details(total_items, total_items+cur_items, item_list, tbl_cfg); + + total_items += cur_items; + if(cur_items > 0) + total_tables++; + + printf("total_items = %d, total_tables = %d\n", total_items, total_tables); + return; +} + +int fill_list_from_section(char **section_list, char *section_name) +{ + int total_items, j; + + for(j=0; j<20; j++) { + section_list[j] = malloc(100); + } + + total_items = get_strings_in_section(section_name, section_list); + printf("\tThe total values in the section %s are %d\n", section_name, total_items); + for(j=0; j 0) { + fill_cpu_load_details(total_boot_items+total_temperature_items+total_voltage_items+total_frequency_items, total_boot_items+total_temperature_items+total_voltage_items+total_frequency_items+total_cpu_load_items, cpu_load_list, &cpu_load_config); + } + else { + cpu_load_offset = total_boot_items + total_temperature_items + total_voltage_items + total_frequency_items; + } + + tg_p.title=(char *)malloc(100); + sprintf(tg_p.title, "CPU Usage[@position-req=%dx%d]", x_pos, y_pos); + tg_p.height = MAX_HEIGHT; + tg_p.width = MAX_WIDTH; + + struct _y_config *tg_y_cfg = malloc(tg_p.num_of_y_items * sizeof(struct _y_config)); + tg_p.y_config_array = tg_y_cfg; + tg_p.text_config_array = t_cfg; + + printf("Proceeding to create starting visualization...\n"); + ctx = time_graph_create(argc, argv, &tg_p); + if (!ctx) { + printf("Unable to create time_graph... \n"); + exit(0); + } + + ctx = bar_graph_create(argc, argv, &bg_p); + if (!ctx) { + printf("Error creating context\n"); + exit(0); + } + + command_handler(OPEN, NULL, NULL); + + /* Plot the graph first time */ + time_graph_plot(ctx, tg_y, (const char **)tg_text); + bar_graph_plot(ctx, bg_y, (const char **)bg_text); + + while (!sigtermed) + { + usleep(refresh_rate); + int bytes_read = command_handler(READ, bg_y, bg_text); + if(bytes_read > 0) { + time_graph_plot(ctx, tg_y, (const char **)tg_text); + bar_graph_plot(ctx, bg_y, (const char **)bg_text); + } + } + + bar_graph_destroy(ctx); + command_handler(CLOSE, NULL, NULL); + return 0; +} diff --git a/clients/soc_performance_monitor.h b/clients/soc_performance_monitor.h new file mode 100644 index 0000000..861c8c7 --- /dev/null +++ b/clients/soc_performance_monitor.h @@ -0,0 +1,40 @@ +#define __SLEEP usleep(1000000) + +#define MAX_BUF 1024 +#define OPEN 1 +#define READ 2 +#define CLOSE 3 + +#define MAX_COLORS 12 + +#define printd(fmt, ...) \ + do { if (debug) fprintf(stderr, fmt, __VA_ARGS__); } while (0) + + +struct _rgba pallette[MAX_COLORS] = +{ + { 1.0, 0.0, 0.0, 1.0 }, + { 0.0, 0.5, 0.0, 1.0 }, + { 0.0, 0.0, 1.0, 1.0 }, + { 0.0, 0.0, 0.0, 1.0 }, + { 0.0, 0.5, 1.0, 1.0 }, + { 1.0, 0.0, 1.0, 1.0 }, + { 0.5, 0.5, 1.0, 1.0 }, + { 1.0, 0.5, 0.0, 1.0 }, + { 0.5, 0.5, 0.25, 1.0 }, + { 0.5, 0.0, 0.0, 1.0 }, + { 1.0, 0.5, 0.5, 1.0 }, + { 0.0, 0.0, 0.20, 1.0 } +}; + +struct table_configuration { + int BL_START_X; + int BL_START_Y; + int BAR_GAP; + int BAR_HEIGHT; + int BAR_WIDTH; + int TR_START_X; + int TR_START_Y; + int FONT_SIZE; +}; + diff --git a/clients/statcoll.c b/clients/statcoll.c new file mode 100644 index 0000000..5d5cae7 --- /dev/null +++ b/clients/statcoll.c @@ -0,0 +1,1433 @@ +/* + * Copyright (C) 2015 Texas Instruments + * created by prash@ti.com on 16 Jan 2013 + * Adapted to Linux with changes in framework: Karthik R + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "statcoll.h" +#include "statcoll_gui.h" +#include "time_bar_graph.h" + +#define ENABLE_MODE 0x0 +#define READ_STATUS_MODE 0x1 + + + +#define OPEN 1 +#define READ 2 +#define CLOSE 3 + + +#if 1 +#define __SLEEP sleep(1) +#else +#define __SLEEP usleep(100000) +#endif +//#define DUMMY_MODE + +#define MAX_COLORS 12 + +struct _rgba pallette[MAX_COLORS] = +{ + { 1.0, 0.0, 0.0, 1.0 }, + { 0.0, 0.5, 0.0, 1.0 }, + { 0.0, 0.0, 1.0, 1.0 }, + { 0.0, 0.0, 0.0, 1.0 }, + { 0.0, 0.5, 1.0, 1.0 }, + { 1.0, 0.0, 1.0, 1.0 }, + { 0.5, 0.5, 1.0, 1.0 }, + { 1.0, 0.5, 0.0, 1.0 }, + { 0.5, 0.5, 0.25, 1.0 }, + { 0.5, 0.0, 0.0, 1.0 }, + { 1.0, 0.5, 0.5, 1.0 }, + { 0.0, 0.0, 0.20, 1.0 } +}; + +const struct list_of_initiators initiators[STATCOL_MAX] = +{ + { STATCOL_EMIF1_SYS, "STATCOL_EMIF1_SYS" }, + { STATCOL_EMIF2_SYS,"STATCOL_EMIF2_SYS" }, + { STATCOL_MA_MPU_P1,"STATCOL_MPU_P1" }, + { STATCOL_MA_MPU_P2,"STATCOL_MPU_P2" }, + { STATCOL_MPU1,"STATCOL_MPU1" }, + { STATCOL_MMU1,"STATCOL_MMU1" }, + { STATCOL_TPTC_RD1,"STATCOL_TPTC_RD1" }, + { STATCOL_TPTC_WR1,"STATCOL_TPTC_WR1" }, + { STATCOL_TPTC_RD2,"STATCOL_TPTC_RD2" }, + { STATCOL_TPTC_WR2,"STATCOL_TPTC_WR2" }, + { STATCOL_VIP1_P1,"STATCOL_VIP1_P1" }, + { STATCOL_VIP1_P2,"STATCOL_VIP1_P2" }, + { STATCOL_VIP2_P1,"STATCOL_VIP2_P1" }, + { STATCOL_VIP2_P2,"STATCOL_VIP2_P2" }, + { STATCOL_VIP3_P1,"STATCOL_VIP3_P1" }, + { STATCOL_VIP3_P2,"STATCOL_VIP3_P2" }, + { STATCOL_VPE_P1,"STATCOL_VPE_P1" }, + { STATCOL_VPE_P2,"STATCOL_VPE_P2" }, + { STATCOL_EVE1_TC0,"STATCOL_EVE1_TC0" }, + { STATCOL_EVE1_TC1,"STATCOL_EVE1_TC1" }, + { STATCOL_EVE2_TC0,"STATCOL_EVE2_TC0" }, + { STATCOL_EVE2_TC1,"STATCOL_EVE2_TC1" }, + { STATCOL_EVE3_TC0,"STATCOL_EVE3_TC0" }, + { STATCOL_EVE3_TC1,"STATCOL_EVE3_TC1" }, + { STATCOL_EVE4_TC0,"STATCOL_EVE4_TC0" }, + { STATCOL_EVE4_TC1,"STATCOL_EVE4_TC1" }, + { STATCOL_DSP1_MDMA,"STATCOL_DSP1_MDMA" }, + { STATCOL_DSP1_EDMA,"STATCOL_DSP1_EDMA" }, + { STATCOL_DSP2_MDMA,"STATCOL_DSP2_MDMA" }, + { STATCOL_DSP2_EDMA,"STATCOL_DSP2_EDMA" }, + { STATCOL_IVA,"STATCOL_IVA" }, + { STATCOL_GPU_P1,"STATCOL_GPU_P1" }, + { STATCOL_GPU_P2,"STATCOL_GPU_P2" }, + { STATCOL_BB2D_P1,"STATCOL_BB2D_P1" }, + { STATCOL_DSS,"STATCOL_DSS" }, + { STATCOL_CSI2_2,"STATCOL_CSI2_2" }, + { STATCOL_MMU2,"STATCOL_MMU2" }, + { STATCOL_IPU1,"STATCOL_IPU1" }, + { STATCOL_IPU2,"STATCOL_IPU2" }, + { STATCOL_DMA_SYSTEM_RD,"STATCOL_DMA_SYSTEM_RD" }, + { STATCOL_DMA_SYSTEM_WR,"STATCOL_DMA_SYSTEM_WR" }, + { STATCOL_CSI2_1,"STATCOL_CSI2_1" }, + { STATCOL_USB3_SS,"STATCOL_USB3_SS" }, + { STATCOL_USB2_SS,"STATCOL_USB2_SS" }, + { STATCOL_USB2_ULPI_SS1,"STATCOL_USB2_ULPI_SS1" }, + { STATCOL_USB2_ULPI_SS2,"STATCOL_USB2_ULPI_SS2" }, + { STATCOL_PCIE_SS1,"STATCOL_PCIE_SS1" }, + { STATCOL_PCIE_SS2,"STATCOL_PCIE_SS2" }, + { STATCOL_DSP1_CFG,"STATCOL_DSP1_CFG" }, + { STATCOL_DSP2_CFG,"STATCOL_DSP2_CFG" }, + { STATCOL_GMAC_SW,"STATCOL_GMAC_SW" }, + { STATCOL_PRUSS1_P1,"STATCOL_PRUSS1_P1" }, + { STATCOL_PRUSS1_P2,"STATCOL_PRUSS1_P2" }, + { STATCOL_PRUSS2_P1,"STATCOL_PRUSS2_P1" }, + { STATCOL_PRUSS2_P2,"STATCOL_PRUSS2_P2" }, + { STATCOL_DMA_CRYPTO_RD,"STATCOL_DMA_CRYPTO_RD" }, + { STATCOL_DMA_CRYPTO_WR,"STATCOL_DMA_CRYPTO_WR" }, + { STATCOL_MPU2,"STATCOL_MPU2" }, + { STATCOL_MMC1,"STATCOL_MMC1" }, + { STATCOL_MMC2,"STATCOL_MMC2" }, + { STATCOL_SATA,"STATCOL_SATA" }, + { STATCOL_MLBSS,"STATCOL_MLBSS" }, + { STATCOL_BB2D_P2,"STATCOL_BB2D_P2" }, + { STATCOL_IEEE1500,"STATCOL_IEEE1500" }, + { STATCOL_DBG,"STATCOL_DBG" }, + { STATCOL_VCP1,"STATCOL_VCP1" }, + { STATCOL_OCMC_RAM1,"STATCOL_OCMC_RAM1" }, + { STATCOL_OCMC_RAM2,"STATCOL_OCMC_RAM2" }, + { STATCOL_OCMC_RAM3,"STATCOL_OCMC_RAM3" }, + { STATCOL_GPMC,"STATCOL_GPMC" }, + { STATCOL_MCASP1,"STATCOL_MCASP1" }, + { STATCOL_MCASP2,"STATCOL_MCASP2" }, + { STATCOL_MCASP3,"STATCOL_MCASP3" }, + { STATCOL_VCP2, "STATCOL_VCP2" } +}; + +StatCollectorObj gStatColState; + +static void *statcoll_base_mem; +static int *l3_3_clkctrl; + +static UInt32 *statCountDSS = NULL; +static UInt32 *statCountIVA = NULL; +static UInt32 *statCountBB2DP1 = NULL; +static UInt32 *statCountBB2DP2 = NULL; +static UInt32 *statCountUSB4 = NULL; +static UInt32 *statCountSata = NULL; +static UInt32 *statCountEmif1 = NULL; +static UInt32 *statCountEmif2 = NULL; + + +static statcoll_initiators_object global_object[STATCOL_MAX]; +UInt32 statCountIdx = 0; +UInt32 TRACE_SZ = 0; + +void create_overall_box(struct _bar_graph_y_config *y_cfg, struct _text_config *t_cfg, char *text[]) +{ + int i=0; + + memset(y_cfg, 0x0, sizeof(struct _y_config)*25); + memset(t_cfg, 0x0, sizeof(struct _text_config)*25); + + + for(i=0; iline_color.r = 1.0; + (y_cfg+i)->line_color.g = 1.0; + (y_cfg+i)->line_color.b = 1.0; + (y_cfg+i)->line_color.a = 0.7; + (y_cfg+i)->fill_color.r = 0.0; + (y_cfg+i)->fill_color.g = 0.0; + (y_cfg+i)->fill_color.b = 0.0; + (y_cfg+i)->fill_color.a = 0.1; + } + + (y_cfg+0)->region.bottom_left.x = 0; + (y_cfg+0)->region.bottom_left.y = MAX_HEIGHT - HEIGHT_EMIF_AREA; + (y_cfg+0)->region.top_right.x = MAX_WIDTH; + (y_cfg+0)->region.top_right.y = 0; + + (t_cfg+0)->at.x = MAX_WIDTH/2 - 8*FONT_SIZE - 50; + (t_cfg+0)->at.y = BORDER - FONT_SIZE + 6; + strcpy(text[0], string_list[0]); + + (y_cfg+1)->region.bottom_left.x = TIME_GRAPH_AREA_BL_X; + (y_cfg+1)->region.bottom_left.y = TIME_GRAPH_AREA_BL_Y; + (y_cfg+1)->region.top_right.x = TIME_GRAPH_AREA_TR_X; + (y_cfg+1)->region.top_right.y = TIME_GRAPH_AREA_TR_Y; + + (t_cfg+1)->at.x = TIME_GRAPH_AREA_BL_X - 2*FONT_SIZE; + (t_cfg+1)->at.y = TIME_GRAPH_AREA_TR_Y; + strcpy(text[1],string_list[1]); + + for(i=2; i<7; i++) + { + (y_cfg+i)->region.bottom_left.x = TIME_GRAPH_AREA_BL_X; + (y_cfg+i)->region.bottom_left.y = TIME_GRAPH_AREA_BL_Y;// - (i-2) * (30); + (y_cfg+i)->region.top_right.x = TIME_GRAPH_AREA_TR_X; + (y_cfg+i)->region.top_right.y = TIME_GRAPH_AREA_TR_Y + (i-1) * ((TIME_GRAPH_AREA_BL_Y - TIME_GRAPH_AREA_TR_Y)/5); + (t_cfg+i)->at.x = TIME_GRAPH_AREA_BL_X - 2*FONT_SIZE; + (t_cfg+i)->at.y = TIME_GRAPH_AREA_TR_Y + (i-1) * ((TIME_GRAPH_AREA_BL_Y - TIME_GRAPH_AREA_TR_Y)/5);//TIME_GRAPH_AREA_TR_Y; + strcpy(text[i],string_list[i]); + } + +#if 1 + (y_cfg+7)->region.bottom_left.x = EMIF_AREA_BL_X; + (y_cfg+7)->region.bottom_left.y = EMIF_AREA_BL_Y; + (y_cfg+7)->region.top_right.x = EMIF_AREA_TR_X; + (y_cfg+7)->region.top_right.y = EMIF_AREA_TR_Y; + + (t_cfg+7)->at.x = WIDTH_EMIF_AREA/2 - 2*FONT_SIZE; + (t_cfg+7)->at.y = EMIF_AREA_TR_Y + FONT_SIZE; + strcpy(text[7],string_list[7]); + + for(i=8; i<12; i=i+2) + { + (y_cfg+i)->region.bottom_left.x = EMIF_AREA_BL_X + BORDER + (i-8)*(BAR_WIDTH+BAR_GAP)/2; + (y_cfg+i)->region.bottom_left.y = EMIF_AREA_BL_Y - BORDER/2;// - (i-2) * (30); + (y_cfg+i)->region.top_right.x = EMIF_AREA_BL_X + BORDER + BAR_WIDTH + (i-8) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i)->region.top_right.y = EMIF_AREA_TR_Y + BORDER * 1.2; + + (y_cfg+i)->fill_color.r = 1.0; + (y_cfg+i)->fill_color.g = 0.0; + (y_cfg+i)->fill_color.b = 0.0; + (y_cfg+i)->fill_color.a = 0.1; + + (y_cfg+i+1)->region.bottom_left.x = EMIF_AREA_BL_X + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i+1)->region.bottom_left.y = EMIF_AREA_BL_Y - BORDER/2; + (y_cfg+i+1)->region.top_right.x = EMIF_AREA_BL_X + BORDER + BAR_WIDTH + (i-8) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i+1)->region.top_right.y = EMIF_AREA_TR_Y + BORDER*1.2; + + (y_cfg+i+1)->fill_color.r = 0.0; + (y_cfg+i+1)->fill_color.g = 1.0; + (y_cfg+i+1)->fill_color.b = 0.0; + (y_cfg+i+1)->fill_color.a = 1.0; + + (t_cfg+i)->at.x = EMIF_AREA_BL_X + BAR_WIDTH + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2- 2.2*FONT_SIZE; + (t_cfg+i)->at.y = EMIF_AREA_TR_Y + BORDER*1.2 -5; + + /* Fixed strings */ + (t_cfg+i+1)->at.x = EMIF_AREA_BL_X + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2; + (t_cfg+i+1)->at.y = EMIF_AREA_BL_Y;// - BORDER + FONT_SIZE; + + strcpy(text[i],string_list[i]); + strcpy(text[i+1],string_list[i+1]); + } + + (y_cfg+12)->region.bottom_left.x = INITIATORS_AREA_BL_X; + (y_cfg+12)->region.bottom_left.y = INITIATORS_AREA_BL_Y; + (y_cfg+12)->region.top_right.x = INITIATORS_AREA_TR_X; + (y_cfg+12)->region.top_right.y = INITIATORS_AREA_TR_Y; + + (t_cfg+12)->at.x = EMIF_AREA_TR_X + (INITIATORS_AREA_TR_X - INITIATORS_AREA_BL_X)/2 - 4 * FONT_SIZE; + (t_cfg+12)->at.y = INITIATORS_AREA_TR_Y + FONT_SIZE; + strcpy(text[12],string_list[12]); + + for(i=13; i<25; i=i+2) + { + (y_cfg+i)->region.bottom_left.x = INITIATORS_AREA_BL_X + BORDER + (i-13)*(BAR_WIDTH+BAR_GAP)/2; + (y_cfg+i)->region.bottom_left.y = INITIATORS_AREA_BL_Y - BORDER/2;// - (i-2) * (30); + (y_cfg+i)->region.top_right.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i)->region.top_right.y = INITIATORS_AREA_TR_Y + BORDER*1.2; + + (y_cfg+i)->fill_color.r = 1.0; + (y_cfg+i)->fill_color.g = 0.0; + (y_cfg+i)->fill_color.b = 0.0; + (y_cfg+i)->fill_color.a = 0.1; + + (y_cfg+i+1)->region.bottom_left.x = INITIATORS_AREA_BL_X + BORDER + (i-13) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i+1)->region.bottom_left.y = INITIATORS_AREA_BL_Y - BORDER/2;// - (i-2) * (30); + (y_cfg+i+1)->region.top_right.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2; + (y_cfg+i+1)->region.top_right.y = INITIATORS_AREA_TR_Y + BORDER* 1.2; + + (y_cfg+i+1)->fill_color.r = 0.0; + (y_cfg+i+1)->fill_color.g = 1.0; + (y_cfg+i+1)->fill_color.b = 0.0; + (y_cfg+i+1)->fill_color.a = 1.0; + + (t_cfg+i)->at.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2 - 2.2* FONT_SIZE; + (t_cfg+i)->at.y = INITIATORS_AREA_TR_Y + BORDER*1.2 -5; + + (t_cfg+i+1)->at.x = INITIATORS_AREA_BL_X + BORDER + (i-13)*(BAR_WIDTH+BAR_GAP)/2; + (t_cfg+i+1)->at.y = INITIATORS_AREA_BL_Y; + + strcpy(text[i],string_list[i]); + strcpy(text[i+1],string_list[i+1]); + } +#endif + +#if 0 + for(i=0; i<25; i++) + printf("(%d, %d) to (%d, %d)\n", (y_cfg +i)->region.bottom_left.x,(y_cfg +i)->region.bottom_left.y,(y_cfg +i)->region.top_right.x, (y_cfg +i)->region.top_right.y); +#endif + + + + for(i=0; i<25; i++) { + (t_cfg+i)->color.r = 0.0; + (t_cfg+i)->color.g = 1.0; + (t_cfg+i)->color.b = 1.0; + (t_cfg+i)->color.a = 1.0; + (t_cfg+i)->fontsize = FONT_SIZE; + } + (t_cfg+0)->fontsize = 20; + + +} + + +void statCollectorInit() +{ + int index; + + gStatColState.stat0_filter_cnt = 0; + gStatColState.stat1_filter_cnt = 0; + gStatColState.stat2_filter_cnt = 0; + gStatColState.stat3_filter_cnt = 0; + gStatColState.stat4_filter_cnt = 0; + gStatColState.stat5_filter_cnt = 0; + gStatColState.stat6_filter_cnt = 0; + gStatColState.stat7_filter_cnt = 0; + gStatColState.stat8_filter_cnt = 0; + gStatColState.stat9_filter_cnt = 0; + + for(index=STATCOL_EMIF1_SYS; index < STATCOL_MAX; index++) + { + global_object[index].b_enabled = 0; + + strcpy(global_object[index].name, initiators[index].name); + + global_object[index].readings = malloc(TRACE_SZ * sizeof(UInt32)); + memset(global_object[index].readings, 0, TRACE_SZ * sizeof(UInt32)); + + global_object[index].timestamp = NULL; + + global_object[index].group_id = 0xFF; + global_object[index].counter_id = 0; + global_object[index].base_address = 0; + global_object[index].mux_req = 0; + } + +} + +void wr_stat_reg(UInt32 address, UInt32 data) +{ + UInt32 *mymem = statcoll_base_mem; + UInt32 delta = (address - STATCOLL_BASE) / 4; +#ifndef DUMMY_MODE + mymem[delta] = data; +#else + printf("WRITE: Address = 0x%x, Data = 0x%x\n", address, data); +#endif +} + +UInt32 rd_stat_reg(UInt32 address) +{ +#ifndef DUMMY_MODE + UInt32 *mymem = statcoll_base_mem; + UInt32 data; + UInt32 delta = (address - STATCOLL_BASE) / 4; + data = mymem[delta]; + return data; +#else + printf("READ: Address = 0x%x\n", address); +#endif +} + +UInt32 statCollectorControlInitialize(UInt32 instance_id) +{ + UInt32 cur_base_address = 0; + UInt32 cur_event_mux_req; + UInt32 cur_event_mux_resp; + UInt32 cur_stat_filter_cnt; + + switch (instance_id) + { + case STATCOL_EMIF1_SYS: + cur_base_address = stat_coll0_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat0_filter_cnt; + global_object[instance_id].group_id = 0; + break; + case STATCOL_EMIF2_SYS: + cur_base_address = stat_coll0_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat0_filter_cnt; + global_object[instance_id].group_id = 0; + break; + case STATCOL_MA_MPU_P1: + cur_base_address = stat_coll0_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat0_filter_cnt; + global_object[instance_id].group_id = 0; + break; + case STATCOL_MA_MPU_P2: + cur_base_address = stat_coll0_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat0_filter_cnt; + global_object[instance_id].group_id = 0; + break; + case STATCOL_MPU1: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_MMU1: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_TPTC_RD1: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_TPTC_WR1: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_TPTC_RD2: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_TPTC_WR2: + cur_base_address = stat_coll1_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat1_filter_cnt; + global_object[instance_id].group_id = 1; + break; + case STATCOL_VIP1_P1: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VIP1_P2: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VIP2_P1: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VIP2_P2: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VIP3_P1: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VIP3_P2: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VPE_P1: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_VPE_P2: + cur_base_address = stat_coll2_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat2_filter_cnt; + global_object[instance_id].group_id = 2; + break; + case STATCOL_EVE1_TC0: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE1_TC1: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE2_TC0: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE2_TC1: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE3_TC0: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE3_TC1: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE4_TC0: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_EVE4_TC1: + cur_base_address = stat_coll3_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat3_filter_cnt; + global_object[instance_id].group_id = 3; + break; + case STATCOL_DSP1_MDMA: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_DSP1_EDMA: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_DSP2_MDMA: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_DSP2_EDMA: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_IVA: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_GPU_P1: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_GPU_P2: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_BB2D_P1: + cur_base_address = stat_coll4_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat4_filter_cnt; + global_object[instance_id].group_id = 4; + break; + case STATCOL_DSS: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_CSI2_2: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_MMU2: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_IPU1: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_IPU2: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_DMA_SYSTEM_RD: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_DMA_SYSTEM_WR: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_CSI2_1: + cur_base_address = stat_coll5_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat5_filter_cnt; + global_object[instance_id].group_id = 5; + break; + case STATCOL_USB3_SS: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_USB2_SS: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_USB2_ULPI_SS1: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_USB2_ULPI_SS2: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_PCIE_SS1: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_PCIE_SS2: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_DSP1_CFG: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_DSP2_CFG: + cur_base_address = stat_coll6_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat6_filter_cnt; + global_object[instance_id].group_id = 6; + break; + case STATCOL_GMAC_SW: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_PRUSS1_P1: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_PRUSS1_P2: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_PRUSS2_P1: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_PRUSS2_P2: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_DMA_CRYPTO_RD: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_DMA_CRYPTO_WR: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_MPU2: + cur_base_address = stat_coll7_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat7_filter_cnt; + global_object[instance_id].group_id = 7; + break; + case STATCOL_MMC1: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_MMC2: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_SATA: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_MLBSS: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_BB2D_P2: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_IEEE1500: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_DBG: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_VCP1: + cur_base_address = stat_coll8_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat8_filter_cnt; + global_object[instance_id].group_id = 8; + break; + case STATCOL_OCMC_RAM1: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 0; + cur_event_mux_resp = 1; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_OCMC_RAM2: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 2; + cur_event_mux_resp = 3; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_OCMC_RAM3: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 4; + cur_event_mux_resp = 5; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_GPMC: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 6; + cur_event_mux_resp = 7; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_MCASP1: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 8; + cur_event_mux_resp = 9; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_MCASP2: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 10; + cur_event_mux_resp = 11; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_MCASP3: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 12; + cur_event_mux_resp = 13; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + case STATCOL_VCP2: + cur_base_address = stat_coll9_base_address; + cur_event_mux_req = 14; + cur_event_mux_resp = 15; + gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1; + cur_stat_filter_cnt = gStatColState.stat9_filter_cnt; + global_object[instance_id].group_id = 9; + break; + default: + printf("ERROR: Unknown initiator %d\n", instance_id); + exit(0); + }; + + { + if ( cur_stat_filter_cnt > 4 ) + { + printf("WARNING: We have exhausted filters/counters.....\n"); + return 0; + } + // Global Enable Stat Collector + wr_stat_reg(cur_base_address+0x8,0x1); + + // Soft Enable Stat Collector + wr_stat_reg(cur_base_address+0xC,0x1); + + wr_stat_reg(cur_base_address+0x18,0x5); + // Operation of Stat Collector / RespEvt => Packet + wr_stat_reg(cur_base_address+0x1C,0x5); + + + // Event Sel + wr_stat_reg(cur_base_address+0x20+4*(cur_stat_filter_cnt-1),cur_event_mux_req); + + // Op is EventInfo + wr_stat_reg(cur_base_address+0x1FC+(0x158*(cur_stat_filter_cnt-1)),2); + + // Event Info Sel Op -> packet length + wr_stat_reg(cur_base_address+0x1F8+(0x158*(cur_stat_filter_cnt-1)),0); + + // Filter Global Enable + wr_stat_reg(cur_base_address+0xAC+(0x158*(cur_stat_filter_cnt-1)),0x1); + + // Filter Enable + wr_stat_reg(cur_base_address+0xBC+(0x158*(cur_stat_filter_cnt-1)),0x1); + + // Manual dump + wr_stat_reg(cur_base_address+0x54,0x1); + // use send register to reset counters + + } + + global_object[instance_id].mux_req = cur_event_mux_req; + global_object[instance_id].base_address = cur_base_address; + global_object[instance_id].counter_id = cur_stat_filter_cnt; + global_object[instance_id].b_enabled = 1; + + return cur_stat_filter_cnt; +} + + + +void statCollectorReadGroup(UInt32 group_id) +{ + int i=0; + UInt32 cur_base_address = 0x45001000 + ((group_id - 1) * 0x1000); + + wr_stat_reg(cur_base_address+0xC,0x0); + + for(i=0; i < STATCOL_MAX; i++) + { + if(global_object[i].group_id == (group_id - 1) && + global_object[i].b_enabled == 1) + { + UInt32 cur_stat_filter_cnt = global_object[i].counter_id; + + global_object[i].readings[statCountIdx] = rd_stat_reg(cur_base_address+0x8C+((cur_stat_filter_cnt-1)*4)); + } + } + + wr_stat_reg(cur_base_address+0xC,0x1); +} + + +volatile sig_atomic_t sigtermed = 0; + +void my_signal_handler(int signum) +{ + if (signum == SIGTERM || signum == SIGINT) { + sigtermed = 1; + } +} + +struct sort +{ + int pos; + double value; +}; + + +void *ctx; +struct time_graph_create_params p; +char xpos_string[100], ypos_string[100]; + +void mpu_handler(int command) +{ +#if 1 + static int fd; + char buf[1000]; + char * tabledata= "/tmp/statcollfifo"; + int i; + int bytes; + static int offset = 13; + + switch(command) + { + case OPEN: + fd = open(tabledata, O_RDONLY|O_NONBLOCK); + break; + + case READ: + + /* open, read, and display the message from the FIFO */ + bytes=read(fd, buf, 1000); + if(bytes > 0) + { + char str[100]; + char value[100]; + sscanf(buf, "%s %s", str, value); + if(strcmp(str, "MOVE:") == 0) + { + printf("Received MOVE command : %s\n", buf); + sprintf(p.title, "CPU Usage[@position-req=%sx%s]", value, ypos_string); + move_graph(ctx, &p); + } + else + { + printf("ERROR: Received unexpected data from FIFO - \" %s \" \n", buf); + } + memset(buf, 0x0, sizeof(buf)); + } + + break; + + case CLOSE: + close(fd); + break; + } +#endif + return; +} + + +UInt32 statcoll_start(UInt32 TOTAL_TIME, UInt32 INTERVAL_US, char list[][50], UInt32 xpos, UInt32 ypos) +{ + int i, fd, index; + UInt32 counterIdDss, counterIdIva, counterIdBB2dP1, counterIdBB2dP2, counterIdUsb4, counterIdSata, counterIdEmif1, counterIdEmif2; + + if (SIG_ERR == signal(SIGPIPE,SIG_IGN)) + exit(1); + + if (SIG_ERR == signal(SIGINT,my_signal_handler)) + exit(1); + + if (SIG_ERR == signal(SIGTERM,my_signal_handler)) + exit(1); + + + struct timeval tv1, tv2; + gettimeofday(&tv1, NULL); + printf("------------------------------------------------\n"); + printf("Compile time = %s %s\n",__DATE__, __TIME__); + printf("------------------------------------------------\n\n"); + //printd("Start time = %d\n", time(NULL)); + //printd("Time seconds = %d, usecs = %d\n", tv.tv_sec, tv.tv_usec); + + statcoll_params params; + memset(¶ms, sizeof(params), 0); + params.INTERVAL_US = INTERVAL_US; + params.TOTAL_TIME = TOTAL_TIME; + + i=0; + index=0; + + while(list[i][0] != 0) + { + for(index=0; index< STATCOL_MAX; index++) { + if(strcmp(list[i], initiators[index].name) == 0) + { + strcpy(params.user_config_list[params.no_of_initiators].name, list[i]); + params.user_config_list[params.no_of_initiators++].id = initiators[index].id; + break; + } + } + + if(index == STATCOL_MAX) { + printf("ERROR: Unknown initiator.%d.. .%s. \n", i, list[i]); + //exit(0); + } + i++; + } + + struct bar_graph_create_params bg_p; + struct _y_config *y_cfg; + struct _text_config *t_cfg; + double *y; + double *bg_y; + char *text_list[STATCOL_MAX]; + + struct _bar_graph_y_config *bg_y_cfg; + struct _text_config *bg_t_cfg; + char *bg_text_list[STATCOL_MAX]; + + sprintf(xpos_string, "%d", xpos); + sprintf(ypos_string, "%d", ypos); + p.title=(char *)malloc(100); + sprintf(p.title, "CPU Usage[@position-req=%sx%s]", xpos_string, ypos_string); + //p.height = MAX_HEIGHT - HEIGHT_EMIF_AREA; + p.height = MAX_HEIGHT;// - HEIGHT_EMIF_AREA; + p.width = MAX_WIDTH; + p.draw_area.bottom_left.x = TIME_GRAPH_AREA_BL_X; + p.draw_area.bottom_left.y = TIME_GRAPH_AREA_BL_Y; + p.draw_area.top_right.x = TIME_GRAPH_AREA_TR_X; + p.draw_area.top_right.y = TIME_GRAPH_AREA_TR_Y; + p.time_span = 120000; // 120 seconds + p.num_of_y_items = params.no_of_initiators+1; + p.num_of_text_items = 0;//params.no_of_initiators; + + + y_cfg = malloc((params.no_of_initiators+1) * sizeof(struct _y_config)); + t_cfg = malloc(params.no_of_initiators * sizeof(struct _text_config)); + y = malloc((params.no_of_initiators+1) * sizeof(double)); + p.y_config_array = y_cfg; + p.text_config_array = t_cfg; + + bg_y_cfg = malloc(TOTAL_Y_PARAMETERS * sizeof(struct _bar_graph_y_config)); + bg_t_cfg = malloc(TOTAL_Y_PARAMETERS * sizeof(struct _text_config)); + bg_y = malloc(TOTAL_Y_PARAMETERS * sizeof(double)); + + for(i=0; iline_color.r = pallette[i%MAX_COLORS].r; + ((struct _y_config *)y_cfg+i)->line_color.g = pallette[i%MAX_COLORS].g; + ((struct _y_config *)y_cfg+i)->line_color.b = pallette[i%MAX_COLORS].b; + ((struct _y_config *)y_cfg+i)->line_color.a = 0.0;//pallette[i%MAX_COLORS].a; + + ((struct _y_config *)y_cfg+i)->fill_color.r = 0.0; + ((struct _y_config *)y_cfg+i)->fill_color.g = 1.0; + ((struct _y_config *)y_cfg+i)->fill_color.b = 0.0; + ((struct _y_config *)y_cfg+i)->fill_color.a = 0.5; + + i++; + } + + ((struct _y_config *)y_cfg+i)->line_color.r = 0.0; + ((struct _y_config *)y_cfg+i)->line_color.g = 0.0; + ((struct _y_config *)y_cfg+i)->line_color.b = 0.0; + ((struct _y_config *)y_cfg+i)->line_color.a = 0.5; + ((struct _y_config *)y_cfg+i)->fill_color.r = 0.1; + ((struct _y_config *)y_cfg+i)->fill_color.g = 0.9; + ((struct _y_config *)y_cfg+i)->fill_color.b = 0.5; + ((struct _y_config *)y_cfg+i)->fill_color.a = 1.0; + + bg_p.title = "CPU Usage"; + + bg_p.num_of_y_items = TOTAL_Y_PARAMETERS; + bg_p.y_config_array = bg_y_cfg; + bg_p.num_of_text_items = TOTAL_Y_PARAMETERS; + bg_p.text_config_array = bg_t_cfg; + + + int argc; + char *argv[10]; + ctx = time_graph_create(argc, argv, &p); + if (!ctx) { + printf("Error creating context\n"); + exit(0); + } + + printf("\n Context after time_graph_create = 0x%x\n", ctx); + ctx = bar_graph_create(argc, argv, &bg_p); + if (!ctx) { + printf("Error creating context\n"); + exit(0); + } + + printf("\n Context after bar_graph_create= 0x%x\n", ctx); + + printf("Total configured initiators = %d\n", params.no_of_initiators); + + + fd = open("/dev/mem", O_RDWR); + if (fd == -1){ + printf("error fd=open() \n"); + return -1; + } + statcoll_base_mem = mmap(NULL, STATCOLL_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, STATCOLL_BASE); + + if (statcoll_base_mem == MAP_FAILED){ + printf("ERROR: mmap failed \n"); + return; + } + close(fd); + + fd = open("/dev/mem", O_RDWR); + if (fd == -1){ + printf("error fd=open() \n"); + return -1; + } + l3_3_clkctrl = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CM_L3INSTR_REGISTER_BASE); + if (l3_3_clkctrl == MAP_FAILED){ + printf("ERROR: mmap failed for CM_L3INSTR_REGISTER_BASE\n"); + return; + } + close(fd); + + printf("SUCCESS: Mapped 0x%x to user space address 0x%x\n", STATCOLL_BASE, statcoll_base_mem); + printf("INTERVAL = %d usecs\n", INTERVAL_US); + printf("TOTAL TIME = %d seconds\n", TOTAL_TIME); + TRACE_SZ = (TOTAL_TIME * 1000000)/INTERVAL_US; + printf("TRACE SIZE = %d samples\n", TRACE_SZ); + + printf("**************************************\n"); + printf("Going to initialize the L3 clocks \n"); + l3_3_clkctrl[CM_L3INSTR_L3INSTR_CLKSTCTRL_OFFSET >> 2] = 0x2; + l3_3_clkctrl[CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET >> 2] = 0x1; + printf("**************************************\n"); + + while( (l3_3_clkctrl[CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET >> 2] & 0x30000) != 0x0) + { + printf("Waiting on module to be functional\n"); + } + + statCollectorInit(); + + printf("SUCCESS: Initialized STAT COLLECTOR\n"); + /* Initialize all enabled initiators */ + for(index =0; index < params.no_of_initiators; index++) { + printf("\t\t Initialized %s\n", params.user_config_list[index].name); + statCollectorControlInitialize(params.user_config_list[index].id); + } + + const char *bg_text = "CPU Utilization"; + + int second_counter=0; + memset(y, 0x0, sizeof(double)* (params.no_of_initiators+1)); + + + + + mpu_handler(OPEN); + + + while(statCountIdx != (TRACE_SZ - 1)) + { + usleep(INTERVAL_US); + int group; + for(group = 1; group<11; group++) + statCollectorReadGroup(group); + + mpu_handler(READ); + + if(statCountIdx != 0 ) + for(i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "window.h" +#include "../shared/cairo-util.h" +#include "time_bar_graph.h" + +//#define DEBUG 1 +#ifdef DEBUG +#define DBG(x...) printf(x) +#else +#define DBG(x...) // printf(x) +#endif + +#define MAX_ITEMS 180 +#define MAX_TEXT_SIZE 128 + +struct graph_dataset_point { + int next_index; + double y_values[MAX_ITEMS]; +}; + +struct graph_data { + int dataset_size; + int first_index, last_index, num_elems; + uint64_t last_time; + struct graph_dataset_point dataset[1]; +}; + +struct graph { + struct display *display; + struct window *window; + struct widget *widget; + int width, height; + struct time_graph_create_params params; + struct bar_graph_create_params bar_graph_params; + struct _y_config y_config_array[MAX_ITEMS]; + struct _text_config text_config_array[MAX_ITEMS]; + + /* Bar graph parameters */ + struct _bar_graph_y_config bar_graph_y_config_array[MAX_ITEMS]; + struct _text_config bar_graph_text_config_array[MAX_ITEMS]; + + pthread_t thr; + int eventfd; + struct task task; + double x_scaling_factor; + pthread_mutex_t mtx; + double time_graph_y_values[MAX_ITEMS]; + char text_values[MAX_ITEMS][MAX_TEXT_SIZE]; + + double bar_graph_y_values[MAX_ITEMS]; + char bar_graph_text_values[MAX_ITEMS][MAX_TEXT_SIZE]; + + uint64_t time_now; + time_t start_time_tv_sec; + struct graph_data *data; +}; + +struct graph *global_graph=NULL; +static void +draw_stuff(struct graph *g, cairo_surface_t *surface) +{ + cairo_t *cr; + int i, j, n_elems; + double c_x, c_y, d_x, d_y; + + cr = cairo_create(surface); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.5); + cairo_paint(cr); + cairo_select_font_face(cr, "mono", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_line_width (cr, 1.0); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + pthread_mutex_lock(&g->mtx); + for (j=0; g->data->num_elems > 0 && jparams.num_of_y_items; j++) { + n_elems = g->data->num_elems; + DBG("first_index: %d, last_index: %d\n", g->data->first_index, g->data->last_index); + if (g->y_config_array[j].fill_color.a != 0.0) + cairo_move_to(cr, (double)g->params.draw_area.bottom_left.x, (double)g->params.draw_area.bottom_left.y); + c_x = (double)g->params.draw_area.bottom_left.x; + c_y = (double)g->params.draw_area.bottom_left.y; + d_x = 0; + i = g->data->first_index; + while (n_elems) { + DBG("index: %d, x: %f, y: %f, next_index: %d\n", i, c_x, + g->data->dataset[i].y_values[j], g->data->dataset[i].next_index); + d_y = g->data->dataset[i].y_values[j] - c_y; + c_y = g->data->dataset[i].y_values[j]; + c_x = c_x + d_x; + if (g->y_config_array[j].fill_color.a == 0.0 && n_elems == g->data->num_elems) { + cairo_move_to(cr, c_x, c_y); + } else { + cairo_curve_to(cr, c_x - (d_x * 0.75), c_y - (d_y * 0.92), c_x - (d_x * 0.25), c_y - (d_y * 0.08), c_x, c_y); + } + if (g->data->dataset[i].next_index > i) { + d_x = (g->data->dataset[i].next_index - i); + } else { + d_x = (g->data->dataset_size + g->data->dataset[i].next_index - i); + } + i = g->data->dataset[i].next_index; + n_elems--; + } + if (g->y_config_array[j].fill_color.a != 0.0) { + cairo_line_to(cr, c_x, (double)g->params.draw_area.bottom_left.y); + cairo_line_to(cr, (double)g->params.draw_area.bottom_left.x, (double)g->params.draw_area.bottom_left.y); + cairo_close_path(cr); + cairo_set_source_rgba(cr, g->y_config_array[j].fill_color.r, g->y_config_array[j].fill_color.g, + g->y_config_array[j].fill_color.b, g->y_config_array[j].fill_color.a); + cairo_fill_preserve(cr); + } + cairo_set_source_rgba(cr, g->y_config_array[j].line_color.r, g->y_config_array[j].line_color.g, + g->y_config_array[j].line_color.b, g->y_config_array[j].line_color.a); + cairo_stroke(cr); + } + + for (j=0; jparams.num_of_text_items; j++) { + cairo_move_to(cr, (double)g->text_config_array[j].at.x, (double)g->text_config_array[j].at.y); + cairo_set_font_size(cr, g->text_config_array[j].fontsize); + cairo_set_source_rgba(cr, g->text_config_array[j].color.r, g->text_config_array[j].color.g, + g->text_config_array[j].color.b, g->text_config_array[j].color.a); + cairo_show_text(cr, g->text_values[j]); + } + + + for (j=0; jbar_graph_params.num_of_y_items; j++) { + cairo_move_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x, + (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y); + c_y = (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y - + (g->bar_graph_y_values[j] * (double)(g->bar_graph_params.y_config_array[j].region.bottom_left.y - + g->bar_graph_params.y_config_array[j].region.top_right.y)); + cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x, c_y); + cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.top_right.x, c_y); + cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.top_right.x, + (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y); + cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x, + (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y); + cairo_close_path(cr); + cairo_set_source_rgba(cr, g->bar_graph_y_config_array[j].fill_color.r, g->bar_graph_y_config_array[j].fill_color.g, + g->bar_graph_y_config_array[j].fill_color.b, g->bar_graph_y_config_array[j].fill_color.a); + cairo_fill_preserve(cr); + cairo_set_source_rgba(cr, g->bar_graph_y_config_array[j].line_color.r, g->bar_graph_y_config_array[j].line_color.g, + g->bar_graph_y_config_array[j].line_color.b, g->bar_graph_y_config_array[j].line_color.a); + cairo_stroke(cr); + } + for (j=0; jbar_graph_params.num_of_text_items; j++) { + cairo_move_to(cr, (double)g->bar_graph_text_config_array[j].at.x, (double)g->bar_graph_text_config_array[j].at.y); + cairo_set_font_size(cr, g->bar_graph_text_config_array[j].fontsize); + cairo_set_source_rgba(cr, g->bar_graph_text_config_array[j].color.r, g->bar_graph_text_config_array[j].color.g, + g->bar_graph_text_config_array[j].color.b, g->bar_graph_text_config_array[j].color.a); + cairo_save (cr); + //cairo_rotate(cr, 2*3.14*21/24); + cairo_show_text(cr, g->bar_graph_text_values[j]); + cairo_restore(cr); + } + pthread_mutex_unlock(&g->mtx); + cairo_destroy(cr); +} + +static void +resize_handler(struct widget *widget, + int32_t width, int32_t height, void *data) +{ + struct graph *g = data; + + /* Dont resize me */ + widget_set_size(g->widget, g->width, g->height); +} + +static void +redraw_handler(struct widget *widget, void *data) +{ + struct graph *g = data; + cairo_surface_t *surface; + + surface = window_get_surface(g->window); + if (surface == NULL || + cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "failed to create cairo egl surface\n"); + return; + } + + draw_stuff(g, surface); + cairo_surface_destroy(surface); +} + +static void +button_handler(struct widget *widget, + struct input *input, uint32_t time, + uint32_t button, enum wl_pointer_button_state state, void *data) +{ + struct graph *g = data; + + switch (button) { + case BTN_LEFT: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + window_move(g->window, input, + display_get_serial(g->display)); + break; + case BTN_MIDDLE: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + widget_schedule_redraw(widget); + break; + case BTN_RIGHT: + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + window_show_frame_menu(g->window, input, time); + break; + } +} + +static void +touch_down_handler(struct widget *widget, struct input *input, + uint32_t serial, uint32_t time, int32_t id, + float x, float y, void *data) +{ + struct graph *g = data; + window_move(g->window, input, display_get_serial(g->display)); +} + +static void task_run(struct task *task, uint32_t events) +{ + eventfd_t e; + struct graph *g = (struct graph *)(task->link.prev); + uint64_t time_diff; + int elems, tmp, incr, i; + double y; + + eventfd_read(g->eventfd, &e); + if(e == 1) { + pthread_mutex_lock(&g->mtx); + /* Process new data */ + DBG("time_now: %llu, last_time: %llu\n", g->time_now, g->data->last_time); + if (g->time_now > g->data->last_time) { + time_diff = g->time_now - g->data->last_time; + y = (double)time_diff * g->x_scaling_factor; + incr = (int)y; + DBG("incr: %d\n", incr); + + if (g->data->last_index >= g->data->first_index) elems = g->data->last_index - g->data->first_index + 1; + else elems = g->data->dataset_size - g->data->first_index + g->data->last_index + 1; + /* Move first index to make room for new element */ + while (g->data->dataset_size > 0 && (elems + incr) > g->data->dataset_size) { + tmp = g->data->dataset[g->data->first_index].next_index - g->data->first_index; + if (tmp < 0) tmp = g->data->dataset_size + tmp; + g->data->first_index = g->data->dataset[g->data->first_index].next_index; + elems -= tmp; + g->data->num_elems--; + } + for (i=0; iparams.num_of_y_items; i++) { + /* Scale Y */ + y = g->time_graph_y_values[i] * (double)(g->params.draw_area.bottom_left.y-g->params.draw_area.top_right.y); + y = (double)g->params.draw_area.bottom_left.y - y; + g->data->dataset[g->data->last_index].y_values[i] = y; + } + g->data->dataset[g->data->last_index].next_index = g->data->last_index + incr; + if (g->data->dataset[g->data->last_index].next_index >= g->data->dataset_size) + g->data->dataset[g->data->last_index].next_index -= g->data->dataset_size; + g->data->num_elems++; + g->data->last_index = g->data->dataset[g->data->last_index].next_index; + g->data->last_time = g->time_now; + } + pthread_mutex_unlock(&g->mtx); + } + widget_schedule_redraw(g->widget); + DBG("event task ran...\n"); +} + +void *time_graph_create(int argc, char *argv[], struct time_graph_create_params *cp) +{ + struct graph *g; + struct display *d; + int dataset_size; + struct timeval tv; + + if (cp->num_of_y_items > MAX_ITEMS) return NULL; + if (cp->num_of_text_items > MAX_ITEMS) return NULL; + + g = (struct graph*)malloc(sizeof(struct graph)); + if (g == NULL) { + fprintf(stderr, "failed to allocate memory\n"); + return NULL; + } + global_graph = g; + g->params = *cp; + if (cp->num_of_y_items) + memcpy(&g->y_config_array[0], cp->y_config_array, + sizeof(struct _y_config) * cp->num_of_y_items); + if (cp->num_of_text_items) + memcpy(&g->text_config_array[0], cp->text_config_array, + sizeof(struct _text_config) * cp->num_of_text_items); + d = display_create(&argc, argv); + if (d == NULL) { + fprintf(stderr, "failed to create display: %m\n"); + return NULL; + } + g->display = d; + //g->bg_image = load_cairo_surface(cp->bg_image); + g->width = cp->width; //cairo_image_surface_get_width(g->bg_image); + g->height = cp->height; //cairo_image_surface_get_height(g->bg_image); + dataset_size = cp->draw_area.top_right.x - cp->draw_area.bottom_left.x; + g->data = (struct graph_data *)malloc(sizeof(struct graph_data) + + (dataset_size * sizeof(struct graph_dataset_point))); + if (!g->data) { + fprintf(stderr, "failed to allocate memory\n"); + display_destroy(g->display); + //cairo_surface_destroy(g->bg_image); + free(g); + return NULL; + } + g->data->first_index = 0; + g->data->last_index = 0; + g->data->num_elems = 0; + g->data->dataset_size = dataset_size; + g->x_scaling_factor = (double)dataset_size / (double)cp->time_span; + g->window = window_create(d); + g->widget = window_add_widget(g->window, g); + window_set_title(g->window, cp->title); + widget_set_resize_handler(g->widget, resize_handler); + widget_set_redraw_handler(g->widget, redraw_handler); + widget_set_button_handler(g->widget, button_handler); + widget_set_default_cursor(g->widget, CURSOR_HAND1); + widget_set_touch_down_handler(g->widget, touch_down_handler); + window_schedule_resize(g->window, g->width, g->height); + g->eventfd = eventfd(0, 0); + g->task.run = task_run; + g->task.link.prev = (struct wl_list*)g; + g->task.link.next = NULL; + display_watch_fd(d, g->eventfd, EPOLLIN, &g->task); + pthread_mutex_init(&g->mtx, NULL); + + if (0 != pthread_create(&g->thr, NULL, (void *(*)(void *))display_run, (void *)d)) { + fprintf(stderr, "pthread_create failed: %m\n"); + widget_destroy(g->widget); + window_destroy(g->window); + display_destroy(g->display); + //cairo_surface_destroy(g->bg_image); + free(g->data); + close(g->eventfd); + free(g); + return NULL; + } + gettimeofday(&tv, NULL); + g->start_time_tv_sec = tv.tv_sec; + g->data->last_time = 0; + return (void*)g; +} + +void move_graph(void *ctx, struct time_graph_create_params *cp) +{ + struct graph *g = ctx; + window_set_title(g->window, cp->title); +} + +void time_graph_plot(void *ctx, double *y_values, const char *text_values[]) +{ + struct timeval tv; + struct graph *g = ctx; + int i; + pthread_mutex_lock(&g->mtx); + gettimeofday(&tv, NULL); + g->time_now = ((tv.tv_sec - g->start_time_tv_sec) * 1000) + (tv.tv_usec / 1000); + memcpy(g->time_graph_y_values, y_values, g->params.num_of_y_items * sizeof(double)); + for (i=0;iparams.num_of_text_items; i++) { + strncpy(g->text_values[i], text_values[i], MAX_TEXT_SIZE); + g->text_values[i][MAX_TEXT_SIZE-1] = '\0'; + } + pthread_mutex_unlock(&g->mtx); + eventfd_write(g->eventfd, (eventfd_t)1); +} + +void time_graph_destroy(void *ctx) +{ + struct graph *g = (struct graph *)ctx; + display_exit(g->display); + eventfd_write(g->eventfd, (eventfd_t)1); + pthread_join(g->thr, NULL); + widget_destroy(g->widget); + window_destroy(g->window); + display_destroy(g->display); + free(g->data); + close(g->eventfd); + free(g); + global_graph=NULL; +} + +void util_get_cpu_usage(double *cpu_usage) +{ + static FILE *fp = NULL; + char buf[256]; + uint64_t tot; + uint64_t u, n, s, i, w, x, y, z; + static uint64_t last_i = 0, last_total = 0; + + + if (!fp) { + if (!(fp = fopen("/proc/stat", "r"))) + fprintf(stderr, "Failed /proc/stat open: %s", strerror(errno)); + } + if (fp) { + while (1) { + rewind(fp); + fflush(fp); + if (!fgets(buf, sizeof(buf), fp)) { + fprintf(stderr, "failed /proc/stat read\n"); + } else { + sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", + &u, + &n, + &s, + &i, + &w, + &x, + &y, + &z + ); + if (last_total == 0) { + last_total = u+n+s+i+w+x+y+z; + last_i = i; + usleep(100000); + } else { + tot = u+n+s+i+w+x+y+z; + *cpu_usage = (1.0 - ((double)(i-last_i)/(double)(tot-last_total))); + last_i = i; + last_total = tot; + break; + } + } + } + } +} + +void *bar_graph_create(int argc, char *argv[], struct bar_graph_create_params *cp) +{ + struct graph *g; + struct display *d; + struct timeval tv; + + if (cp->num_of_y_items > MAX_ITEMS) return NULL; + if (cp->num_of_text_items > MAX_ITEMS) return NULL; + + if (global_graph == NULL) { + fprintf(stderr, "graph not initialized invoke time_graph_create first\n"); + return NULL; + } + g=global_graph; + g->bar_graph_params = *cp; + if (cp->num_of_y_items) + memcpy(&g->bar_graph_y_config_array[0], cp->y_config_array, + sizeof(struct _bar_graph_y_config) * cp->num_of_y_items); + if (cp->num_of_text_items) + memcpy(&g->bar_graph_text_config_array[0], cp->text_config_array, + sizeof(struct _text_config) * cp->num_of_text_items); + + return g; +} + +void bar_graph_plot(void *ctx, double *y_values, const char *text_values[]) +{ + struct graph *g = ctx; + int i; + pthread_mutex_lock(&g->mtx); + memcpy(g->bar_graph_y_values, y_values, g->bar_graph_params.num_of_y_items * sizeof(double)); + for (i=0;ibar_graph_params.num_of_text_items; i++) { + strncpy(g->bar_graph_text_values[i], text_values[i], MAX_TEXT_SIZE); + g->bar_graph_text_values[i][MAX_TEXT_SIZE-1] = '\0'; + } + pthread_mutex_unlock(&g->mtx); + //eventfd_write(g->eventfd, (eventfd_t)2); +} + +void bar_graph_destroy(void *ctx) +{ + printf("Nothing to be done for this call\n"); + return; +} + diff --git a/clients/time_bar_graph.h b/clients/time_bar_graph.h new file mode 100644 index 0000000..97ac05a --- /dev/null +++ b/clients/time_bar_graph.h @@ -0,0 +1,93 @@ + +#ifndef _BAR_GRAPH_H_ +#define _BAR_GRAPH_H_ + +#include + +struct _rgba { + double r, g, b, a; // Values between 0 and 1 +}; + +struct _coordinate { + uint32_t x, y; // Co-ordinates relative to top-left of the window +}; + +struct _rect { + struct _coordinate bottom_left, top_right; +}; + +struct _y_config { + struct _rgba line_color; // Line color + struct _rgba fill_color; // Fill color, 0 alpha => no fill +}; + +struct _text_config { + struct _rgba color; // Color for drawing the text, RGBA + struct _coordinate at; // where to draw the text + int fontsize; // Font size +}; + +struct time_graph_create_params { + char *title; + //const char *bg_image; + uint32_t width; + uint32_t height; + struct _rect draw_area; + uint32_t time_span; // Amount of time the graph has to span in milliseconds + uint32_t num_of_y_items; + struct _y_config *y_config_array; + uint32_t num_of_text_items; + struct _text_config *text_config_array; +}; + + +struct _bar_graph_y_config { + struct _rect region; // Region for the bar graph + struct _rgba line_color; // Color for drawing the line, RGBA + struct _rgba fill_color; // Fill under the line with color RGBA, 0 => no fill +}; + +struct bar_graph_create_params { + char *title; + //const char *bg_image; + uint32_t num_of_y_items; + struct _bar_graph_y_config *y_config_array; + uint32_t num_of_text_items; + struct _text_config *text_config_array; +}; + +/* Creates a time graph using create parameters */ +void *bar_graph_create(int argc, char *argv[], struct bar_graph_create_params *cp); + +void move_graph(void *ctx, struct time_graph_create_params *cp); + +/* Plots a new set of y-values from the values in the array y_values. + The number of values must be equal to "num_of_y_items" from create params + y_values must be normalized between 0.0 to 1.0 +*/ +void bar_graph_plot(void *ctx, double *y_values, const char *text_values[]); + +/* Destroy the graph */ +void bar_graph_destroy(void *ctx); + + +/* Creates a time graph using create parameters */ +void *time_graph_create(int argc, char *argv[], struct time_graph_create_params *cp); + +/* + * Plots a new set of points from the values in the array y_values. + * The number of values in the array y_values must be equal to "num_of_y_items" + * from create params + * y_values must be normalized between 0.0 to 1.0 + + * The number of values in the array text_values must be equal to "num_of_text_items" + * from create params +*/ +void time_graph_plot(void *ctx, double *y_values, const char *text_values[]); + +/* Destroy the graph */ +void time_graph_destroy(void *ctx); + +void util_get_cpu_usage(double *cpu_usage); + +#endif /* _BAR_GRAPH_H_ */ -- 1.9.1 0001-ivi-shell-add_screen_remove_layer-API.patch0000644002162000023560000000514113324503746021203 0ustar a0850410cleartnpFrom deee858b0b199d8cfa8033a46d7078f30b23725e Mon Sep 17 00:00:00 2001 From: "Ucan, Emre (ADITG/SW1)" Date: Thu, 2 Mar 2017 08:47:33 +0000 Subject: [PATCH] ivi-shell: add_screen_remove_layer API It is analagous to layer_remove_surface API. The API removes a layer from the render order of the screen. v3: add the new vfunc at the end of the ivi_layout_interface struct. Upstream-Status: Backport Signed-off-by: Emre Ucan Reviewed-by: Eugen Friedrich Reviewed-by: Pekka Paalanen --- ivi-shell/ivi-layout-export.h | 10 ++++++++++ ivi-shell/ivi-layout.c | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h index 2317d6e..39ffde1 100644 --- a/ivi-shell/ivi-layout-export.h +++ b/ivi-shell/ivi-layout-export.h @@ -578,6 +578,16 @@ struct ivi_layout_interface { */ struct ivi_layout_surface * (*get_surface)(struct weston_surface *surface); + + /** + * \brief Remove a ivi_layer to a weston_output which is currently managed + * by the service + * + * \return IVI_SUCCEEDED if the method call was successful + * \return IVI_FAILED if the method call was failed + */ + int32_t (*screen_remove_layer)(struct weston_output *output, + struct ivi_layout_layer *removelayer); }; #ifdef __cplusplus diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c index 298e18e..8e4280b 100644 --- a/ivi-shell/ivi-layout.c +++ b/ivi-shell/ivi-layout.c @@ -1664,6 +1664,27 @@ ivi_layout_screen_add_layer(struct weston_output *output, } static int32_t +ivi_layout_screen_remove_layer(struct weston_output *output, + struct ivi_layout_layer *removelayer) +{ + struct ivi_layout_screen *iviscrn; + + if (output == NULL || removelayer == NULL) { + weston_log("ivi_layout_screen_remove_layer: invalid argument\n"); + return IVI_FAILED; + } + + iviscrn = get_screen_from_output(output); + + wl_list_remove(&removelayer->pending.link); + wl_list_init(&removelayer->pending.link); + + iviscrn->order.dirty = 1; + + return IVI_SUCCEEDED; +} + +static int32_t ivi_layout_screen_set_render_order(struct weston_output *output, struct ivi_layout_layer **pLayer, const int32_t number) @@ -2088,6 +2109,7 @@ static struct ivi_layout_interface ivi_layout_interface = { */ .get_screens_under_layer = ivi_layout_get_screens_under_layer, .screen_add_layer = ivi_layout_screen_add_layer, + .screen_remove_layer = ivi_layout_screen_remove_layer, .screen_set_render_order = ivi_layout_screen_set_render_order, /** -- 1.9.1 0001-udev-seat-restrict-udev-enumeration-to-card0.patch0000644002162000023560000000261213324503746022470 0ustar a0850410cleartnpFrom e57e9245dcb5d1349467c7fc36d153f3336f6a1a Mon Sep 17 00:00:00 2001 From: Karthik Ramanan Date: Mon, 12 Mar 2018 10:46:29 +0530 Subject: [PATCH 1/4] udev-seat: restrict udev enumeration to card0 In case of separate GPU and Display devices as found in embedded systems, we could have modeset node and render node controlled by different drivers. There is a distinct possibility that udev enumeration returns the DRM device corresponding to render node as the primary DRM device. Obviously, modeset operations cannot be done on the GPU DRM device. Restrict the udev enumeration to card0 and ensure that DRM device corresponding to display is returned as the primary DRM device. Upstream-Status: Pending Signed-off-by: Anand Balagopalakrishnan Signed-off-by: Karthik Ramanan --- libweston/compositor-drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 1d38f05..649b4f5 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -2957,7 +2957,7 @@ find_primary_gpu(struct drm_backend *b, const char *seat) e = udev_enumerate_new(b->udev); udev_enumerate_add_match_subsystem(e, "drm"); - udev_enumerate_add_match_sysname(e, "card[0-9]*"); + udev_enumerate_add_match_sysname(e, "card0"); udev_enumerate_scan_devices(e); drm_device = NULL; -- 1.9.1 0002-weston-Allow-visual_id-to-be-0.patch0000644002162000023560000000202713324503746017554 0ustar a0850410cleartnpFrom 5695eab02bb88318bf99d568b6d0e4592d5f9981 Mon Sep 17 00:00:00 2001 From: Karthik Ramanan Date: Mon, 12 Mar 2018 10:47:02 +0530 Subject: [PATCH 2/4] weston: Allow visual_id to be 0 The inquiry of visual id from egl API eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) is an optional feature. The visual id will be set to 0 if this feature is not supported. Therefore, the return condition @function match_config_to_visual() should be (id == visual_id || id == 0) instead of (id == visual_id) Upstream status: Pending Signed-off-by: Eric Ruei Signed-off-by: Karthik Ramanan --- libweston/gl-renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c index c6091af..9299dc6 100644 --- a/libweston/gl-renderer.c +++ b/libweston/gl-renderer.c @@ -2575,7 +2575,7 @@ match_config_to_visual(EGLDisplay egl_display, &id)) continue; - if (id == visual_id) + if (id == visual_id || id == 0) return i; } -- 1.9.1 0003-weston-Fix-virtual-keyboard-display-issue-for-QT5-ap.patch0000644002162000023560000000307013324503746023752 0ustar a0850410cleartnpFrom 9c3cf93336b77a1eecc1d72ffec3b113161a822b Mon Sep 17 00:00:00 2001 From: Karthik Ramanan Date: Mon, 12 Mar 2018 10:54:45 +0530 Subject: [PATCH 3/4] weston: Fix virtual keyboard display issue for QT5 application The virtual keyboard does pop up as expected, however, it will never hide even when the application is terminated. This problem is due to the order of the text APIs( text_input_activate and test_input_show_input_panel) are invoked in QT5 and a potential bug of the API implementation. The virtual keyboard works as expected if the test_input_show_input_panel() is invoked prior to the test_input_activate() as most of the weston sample applications do. However, the problem will show up if that order is reversed and the reason why is that the current_panel is not set in this case and hence this panel cannot be hidden. It is required to set the current_panel to the text_input when the input_panel becomes visible at the first time. Upstream status: Pending Signed-off-by: Eric Ruei Signed-off-by: Karthik Ramanan --- compositor/text-backend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/compositor/text-backend.c b/compositor/text-backend.c index bf5c45c..d8b0bb1 100644 --- a/compositor/text-backend.c +++ b/compositor/text-backend.c @@ -340,6 +340,7 @@ text_input_show_input_panel(struct wl_client *client, text_input->surface); wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle); + text_input->manager->current_panel = text_input; } } -- 1.9.1 0004-weston-Fix-touch-screen-crash-issue.patch0000644002162000023560000000256113324503746020734 0ustar a0850410cleartnpFrom 60250e9dc57fe56148c8a24bba107bce8a873fb4 Mon Sep 17 00:00:00 2001 From: Karthik Ramanan Date: Mon, 12 Mar 2018 10:56:28 +0530 Subject: [PATCH 4/4] weston: Fix touch screen crash issue Touch screen operation causes the weston to crash with segment fault sometimes. The crash occurs when the coordinate (x,y) passed to the weston input module is outside the view window, hence the weston compositor is not able to pick up a display view and there is no code to detect this condition at function notify_touch(). Upstream status: pending Signed-off-by: Eric Ruei Signed-off-by: Karthik Ramanan --- libweston/input.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libweston/input.c b/libweston/input.c index 4fedc55..bcb2f28 100644 --- a/libweston/input.c +++ b/libweston/input.c @@ -2185,6 +2185,12 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, * until all touch points are up again. */ if (touch->num_tp == 1) { ev = weston_compositor_pick_view(ec, x, y, &sx, &sy); + if (!ev) + { + weston_log("notify_touch: weston_compositor_pick_view(%d, %d) failed to find a view!\n", + wl_fixed_to_int(x), wl_fixed_to_int(y)); + return; + } weston_touch_set_focus(touch, ev); } else if (!touch->focus) { /* Unexpected condition: We have non-initial touch but -- 1.9.1