From 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