diff options
author | Doug Deao | 2013-08-04 00:42:02 -0500 |
---|---|---|
committer | Doug Deao | 2013-08-04 00:46:07 -0500 |
commit | 656421425b7ca41064d4e726d8c6e6f453d83851 (patch) | |
tree | 45f734c6ed2afe248711f63be474a4e07916a336 | |
download | ctprof_srv-656421425b7ca41064d4e726d8c6e6f453d83851.tar.gz ctprof_srv-656421425b7ca41064d4e726d8c6e6f453d83851.tar.xz ctprof_srv-656421425b7ca41064d4e726d8c6e6f453d83851.zip |
Release 1.0. See the RELEASE_NOTES file for details.
-rw-r--r-- | RELEASE_NOTES | 91 | ||||
-rw-r--r-- | common/error_handler.c | 123 | ||||
-rw-r--r-- | common/error_handler.h | 56 | ||||
-rw-r--r-- | common/logging.c | 154 | ||||
-rw-r--r-- | common/logging.h | 82 | ||||
-rw-r--r-- | ctprofsrv_1.0_Manifest.htm | 1826 | ||||
-rw-r--r-- | example_app/ctprof_ex.c | 207 | ||||
-rw-r--r-- | example_app/ctprof_utility.c | 184 | ||||
-rw-r--r-- | example_app/ctprof_utility.h | 56 | ||||
-rw-r--r-- | example_app/makefile | 71 | ||||
-rw-r--r-- | server/ETBAddr.h | 418 | ||||
-rw-r--r-- | server/ETBInterface.h | 506 | ||||
-rw-r--r-- | server/TIETB.c | 2739 | ||||
-rw-r--r-- | server/command_handler.c | 653 | ||||
-rw-r--r-- | server/command_handler.h | 45 | ||||
-rw-r--r-- | server/ctoolsprof.h | 92 | ||||
-rw-r--r-- | server/ctoolsprof_srv_main.c | 439 | ||||
-rw-r--r-- | server/error.c | 73 | ||||
-rw-r--r-- | server/error.h | 82 | ||||
-rw-r--r-- | server/etb_handler.c | 666 | ||||
-rw-r--r-- | server/etb_handler.h | 56 | ||||
-rw-r--r-- | server/makefile | 89 | ||||
-rw-r--r-- | server/remote_commands.c | 1397 | ||||
-rw-r--r-- | server/remote_commands.h | 71 | ||||
-rw-r--r-- | server/signal_handler.c | 238 | ||||
-rw-r--r-- | server/signal_handler.h | 47 | ||||
-rw-r--r-- | server/socket.c | 483 | ||||
-rw-r--r-- | server/socket.h | 56 |
28 files changed, 11000 insertions, 0 deletions
diff --git a/RELEASE_NOTES b/RELEASE_NOTES new file mode 100644 index 0000000..60b59d2 --- /dev/null +++ b/RELEASE_NOTES | |||
@@ -0,0 +1,91 @@ | |||
1 | ctprof_srv | ||
2 | |||
3 | Version 1.0 | ||
4 | Release Date: 7/32/2013 | ||
5 | |||
6 | Description | ||
7 | =========== | ||
8 | |||
9 | Ctprof provides system level bus profiling use cases for any slave in the | ||
10 | device that has a CP Tracer. Ctprof is made up of two components; ctprof | ||
11 | which is the host client application, and ctprof_srv which is the target | ||
12 | server application. The client is delivered with TI's CCS emupacks (see | ||
13 | System Requirements for minimum emupack revision for this release) and can be | ||
14 | installed independent of CCS. The server is delivered as source with an example | ||
15 | application which also contains a small "C" file that can be integrated with | ||
16 | your application for coordinating collection activity with ctprof_srv. | ||
17 | |||
18 | Organization | ||
19 | ============ | ||
20 | |||
21 | The ctools_srv project is delivered as source in three directories: | ||
22 | |||
23 | server | ||
24 | common | ||
25 | example_app | ||
26 | |||
27 | Both the server and example_app have makefiles. | ||
28 | |||
29 | Make & Installation | ||
30 | =================== | ||
31 | |||
32 | If using SC-MCSDK 02.02.00 then ctprof_srv and ctprof_ex should be | ||
33 | pre-installed in the /usr directory. Otherwise: | ||
34 | |||
35 | The server and example_app directories contain makefiles that utilizes the | ||
36 | CROSS_COMPILE environment variable. Both release and debug versions can be made. | ||
37 | The executable is saved in the release or debug directories. | ||
38 | |||
39 | Examples: | ||
40 | |||
41 | make clean debug | ||
42 | make clean release | ||
43 | make clean release install DESTDIR=/your/favorite/utility/dir | ||
44 | make clean all (make both the debug and release versions) | ||
45 | |||
46 | Typically the executable files will need to be copied to the appropriate target | ||
47 | system's Linux bin directory. | ||
48 | |||
49 | System Requirements | ||
50 | =================== | ||
51 | |||
52 | - A Host Linux machine (Ubuntu 10.4 or higher) with emupack 5.1.NNN.0 installed. | ||
53 | - A TCI6414 EVM or equivalent target system with a working network connection | ||
54 | (TCP is used). | ||
55 | - Requires the SC-MCSDK 02.02.00 Linux image. | ||
56 | |||
57 | Documentation | ||
58 | ============= | ||
59 | |||
60 | The server should simply be run in the background from the console: | ||
61 | |||
62 | $ctprof_srv & | ||
63 | |||
64 | Use -h to see options. | ||
65 | |||
66 | The client is then used from a host to connect to the server and issue | ||
67 | use case commands (like measure utilized bandwidth or latency of a specific | ||
68 | slave) that are serviced by ctprof_srv through a socket interface. | ||
69 | |||
70 | See http://processors.wiki.ti.com/index.php/CToolsLib/ctoolsprof for | ||
71 | documentation and examples. | ||
72 | |||
73 | History | ||
74 | ======= | ||
75 | |||
76 | July 31/2013 - First release | ||
77 | |||
78 | |||
79 | Known Deficiencies | ||
80 | ================== | ||
81 | |||
82 | Enhancements & New Features | ||
83 | =========================== | ||
84 | |||
85 | Bug Fixes | ||
86 | ========= | ||
87 | |||
88 | End of Document | ||
89 | |||
90 | |||
91 | |||
diff --git a/common/error_handler.c b/common/error_handler.c new file mode 100644 index 0000000..e3b6d22 --- /dev/null +++ b/common/error_handler.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * error_handler.c | ||
3 | * | ||
4 | * Ctools Profiler Common Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <stdbool.h> | ||
42 | #include <string.h> | ||
43 | #include <errno.h> | ||
44 | #include <semaphore.h> | ||
45 | #include "error_handler.h" | ||
46 | #include "logging.h" | ||
47 | #include "ctoolsprof.h" | ||
48 | |||
49 | /***************************************************************************** | ||
50 | * Note: This file must be compatible with c++ | ||
51 | * | ||
52 | * TODO: need to add context msg for things like filenames operands | ||
53 | *****************************************************************************/ | ||
54 | char * error_type[] = { | ||
55 | /* [ERR_TYPE_SYSTEM] = */ "system", | ||
56 | /* [ERR_TYPE_LOCAL] = */ "ctoolsprof" | ||
57 | }; | ||
58 | |||
59 | typedef enum {FATAL, NON_FATAL} error_prefix_t; | ||
60 | |||
61 | char * error_prefix[] = { | ||
62 | /* [FATAL] = */ "Fatal Error", | ||
63 | /* [NON_FATAL] = */ "Non Fatal Error" | ||
64 | }; | ||
65 | |||
66 | /****************************************************************************** | ||
67 | * error_handler() | ||
68 | * | ||
69 | * - Print the error to stderr. | ||
70 | * - Log the error. | ||
71 | * - Clean-up if fatal and call exit(). | ||
72 | *****************************************************************************/ | ||
73 | #if DEBUG | ||
74 | void error_handler(error_type_t err_type, err_id_t err_id, const char * file, | ||
75 | const char * func, int line ) | ||
76 | #else | ||
77 | void error_handler(error_type_t err_type, err_id_t err_id) | ||
78 | #endif | ||
79 | { | ||
80 | bool fatal; | ||
81 | char *msg_prefix; | ||
82 | char *err_msg; | ||
83 | char *sys_msg = ""; | ||
84 | char * fmt; | ||
85 | |||
86 | LOGMSG2("Error id is %d\n", err_id); | ||
87 | |||
88 | if (g_interactive_mode && err_type == ERR_TYPE_LOCAL){ | ||
89 | msg_prefix = (error_info[err_id].fatal) ? error_prefix[FATAL] | ||
90 | : error_prefix[NON_FATAL]; | ||
91 | fatal = error_info[err_id].fatal; | ||
92 | err_msg = error_info[err_id].msg; | ||
93 | } else if (!g_interactive_mode && err_type == ERR_TYPE_LOCAL){ | ||
94 | msg_prefix = error_prefix[FATAL]; | ||
95 | fatal = true; | ||
96 | err_msg = error_info[err_id].msg; | ||
97 | } else { | ||
98 | msg_prefix = error_prefix[FATAL]; | ||
99 | fatal = true; | ||
100 | sys_msg = strerror(errno); | ||
101 | err_msg = error_info[err_id].msg; | ||
102 | } | ||
103 | |||
104 | #if DEBUG | ||
105 | fmt = "%s:%d:%s: %s: %s: %s: %s\n"; | ||
106 | fprintf(stderr, fmt, file, line, func, error_type[err_type], msg_prefix, | ||
107 | sys_msg, err_msg); | ||
108 | |||
109 | LOGERR(fmt, file, line, func, error_type[err_type], msg_prefix, sys_msg, | ||
110 | err_msg); | ||
111 | #else | ||
112 | fmt = "%s: %s: %s: %s\n"; | ||
113 | fprintf(stderr, fmt, error_type[err_type], msg_prefix, sys_msg, err_msg); | ||
114 | |||
115 | LOGERR(fmt, error_type[err_type], msg_prefix, sys_msg, err_msg); | ||
116 | #endif | ||
117 | |||
118 | if (fatal) { | ||
119 | clean_up(); | ||
120 | exit(-1); | ||
121 | } | ||
122 | } | ||
123 | |||
diff --git a/common/error_handler.h b/common/error_handler.h new file mode 100644 index 0000000..ab65071 --- /dev/null +++ b/common/error_handler.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * error_handler.h | ||
3 | * | ||
4 | * Ctools Profiler Common Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #ifndef ERRORHANDLER_H | ||
39 | #define ERRORHANDLER_H | ||
40 | |||
41 | #include "error.h" | ||
42 | |||
43 | typedef enum { ERR_TYPE_SYSTEM, ERR_TYPE_LOCAL} error_type_t; | ||
44 | |||
45 | #if DEBUG | ||
46 | void error_handler(error_type_t err_type, err_id_t err_id, const char * file, | ||
47 | const char * func, int line ); | ||
48 | |||
49 | #define err_handler(x,y) error_handler(x,y, __FILE__, __func__, __LINE__) | ||
50 | #else | ||
51 | void error_handler(error_type_t err_type, err_id_t err_id); | ||
52 | |||
53 | #define err_handler error_handler | ||
54 | |||
55 | #endif | ||
56 | #endif | ||
diff --git a/common/logging.c b/common/logging.c new file mode 100644 index 0000000..19fa5d4 --- /dev/null +++ b/common/logging.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | * logging.c | ||
3 | * | ||
4 | * Ctools Profiler Common Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <stdbool.h> | ||
41 | #include <stdarg.h> | ||
42 | #include <sys/time.h> | ||
43 | #include <time.h> | ||
44 | #include "error_handler.h" | ||
45 | #include "logging.h" | ||
46 | |||
47 | bool g_log_enable = false; | ||
48 | int g_log_level = 0; | ||
49 | |||
50 | static FILE *logout; | ||
51 | |||
52 | #define time_buf_size 16 | ||
53 | static char time_buf[time_buf_size]; | ||
54 | /***************************************************************************** | ||
55 | * Internal Function Prototypes | ||
56 | * - See Private Function section below for implementations ) | ||
57 | *****************************************************************************/ | ||
58 | char * get_timestamp(); | ||
59 | |||
60 | /***************************************************************************** | ||
61 | * Public functions | ||
62 | *****************************************************************************/ | ||
63 | /****************************************************************************** | ||
64 | * log_handler() (for --logfile option) | ||
65 | * | ||
66 | * - Enable logging to ctprof_log.txt and set log level. | ||
67 | *****************************************************************************/ | ||
68 | void log_handler(void **argv, int argc) | ||
69 | { | ||
70 | |||
71 | if ((int)argv[0] > 2) { | ||
72 | err_handler(ERR_TYPE_LOCAL, ERR_OPT_ARG); | ||
73 | } | ||
74 | |||
75 | if (g_log_enable == false) { | ||
76 | logout = fopen(LOG_FILENAME,"w"); | ||
77 | if (logout == NULL) { | ||
78 | err_handler(ERR_TYPE_LOCAL, ERR_LOG_FILE); | ||
79 | return; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | g_log_level = (int)argv[0]; | ||
84 | g_log_enable = true; | ||
85 | |||
86 | fprintf(logout, "Log level set to %d\n", (int)argv[0]); | ||
87 | |||
88 | } | ||
89 | |||
90 | /****************************************************************************** | ||
91 | * log_msg() | ||
92 | * | ||
93 | * - log message to logout with timestamp in milliseconds | ||
94 | * - Display format " M|F|E H:M:S:MS | Function:Line: Message" | ||
95 | * where: | ||
96 | * M - message | ||
97 | * F - function start | ||
98 | * E - error | ||
99 | *****************************************************************************/ | ||
100 | void log_msg( log_type_t log_type, const char * format, ...) | ||
101 | { | ||
102 | char * prefix; | ||
103 | va_list marker; | ||
104 | |||
105 | |||
106 | switch (log_type) { | ||
107 | case LOG_MSG: | ||
108 | prefix = " M "; | ||
109 | break; | ||
110 | case LOG_ERR: | ||
111 | prefix = " E "; | ||
112 | break; | ||
113 | case LOG_FUNC: | ||
114 | prefix = " F "; | ||
115 | }; | ||
116 | |||
117 | va_start( marker, format); | ||
118 | fprintf(logout, "%s %s | ", prefix, get_timestamp()); | ||
119 | vfprintf(logout, format, marker); | ||
120 | fprintf(logout,"\n"); | ||
121 | va_end(marker); | ||
122 | fflush(logout); | ||
123 | |||
124 | } | ||
125 | /***************************************************************************** | ||
126 | * Private functions | ||
127 | *****************************************************************************/ | ||
128 | /****************************************************************************** | ||
129 | * -get_timestamp | ||
130 | * Provide timestamp string in H:M:S:MS | ||
131 | * | ||
132 | * TODO: Use of gettimeofday (which is part of the POSIX standard) works | ||
133 | * for Linux but not for Windows. For Windows we must implement our own version | ||
134 | * of gettimeofday per the guide at: | ||
135 | * http://suacommunity.com/dictionary/gettimeofday-entry.php | ||
136 | *****************************************************************************/ | ||
137 | char * get_timestamp() | ||
138 | { | ||
139 | |||
140 | struct timeval tv; | ||
141 | time_t curtime; | ||
142 | int time_size = 0; | ||
143 | |||
144 | gettimeofday(&tv, NULL); | ||
145 | curtime = tv.tv_sec; | ||
146 | |||
147 | time_size = strftime(time_buf, time_buf_size, "%T", localtime(&curtime)); | ||
148 | snprintf(time_buf + time_size, time_buf_size, ":%03ld", tv.tv_usec/1000); | ||
149 | |||
150 | return time_buf; | ||
151 | } | ||
152 | |||
153 | |||
154 | |||
diff --git a/common/logging.h b/common/logging.h new file mode 100644 index 0000000..23f236f --- /dev/null +++ b/common/logging.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * logging.h | ||
3 | * | ||
4 | * Ctools Profiler Common Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef LOGGING_H | ||
40 | #define LOGGING_H | ||
41 | |||
42 | extern bool g_log_enable; | ||
43 | extern int g_log_level; | ||
44 | |||
45 | #ifdef CLIENT | ||
46 | #define LOG_FILENAME "ctprof_log.txt" | ||
47 | #endif | ||
48 | #ifdef SERVER | ||
49 | #define LOG_FILENAME "ctprof_srv_log.txt" | ||
50 | #endif | ||
51 | |||
52 | typedef enum {LOG_MSG, LOG_ERR, LOG_FUNC} log_type_t; | ||
53 | |||
54 | void log_handler(void **notused, int argc); | ||
55 | void log_msg( log_type_t log_type, const char * format, ...); | ||
56 | |||
57 | |||
58 | #define IF_LOGGING_ENABLED if (g_log_enable) | ||
59 | |||
60 | #define LOGFUNC() if (g_log_enable && g_log_level > 0) { \ | ||
61 | log_msg(LOG_FUNC,"%s", __func__); \ | ||
62 | } | ||
63 | |||
64 | #define LOGMSG0(...) if (g_log_enable && g_log_level >= 0) {\ | ||
65 | log_msg(LOG_MSG, __VA_ARGS__); \ | ||
66 | } | ||
67 | |||
68 | #define LOGMSG1(...) if (g_log_enable && g_log_level >= 1) {\ | ||
69 | log_msg(LOG_MSG, __VA_ARGS__); \ | ||
70 | } | ||
71 | |||
72 | |||
73 | #define LOGMSG2(...) if (g_log_enable && g_log_level >= 2) {\ | ||
74 | log_msg(LOG_MSG, __VA_ARGS__); \ | ||
75 | } | ||
76 | |||
77 | |||
78 | #define LOGERR(...) if (g_log_enable) { \ | ||
79 | log_msg(LOG_ERR, __VA_ARGS__); \ | ||
80 | } | ||
81 | #endif | ||
82 | |||
diff --git a/ctprofsrv_1.0_Manifest.htm b/ctprofsrv_1.0_Manifest.htm new file mode 100644 index 0000000..b86c8e3 --- /dev/null +++ b/ctprofsrv_1.0_Manifest.htm | |||
@@ -0,0 +1,1826 @@ | |||
1 | <html xmlns:v="urn:schemas-microsoft-com:vml" | ||
2 | xmlns:o="urn:schemas-microsoft-com:office:office" | ||
3 | xmlns:w="urn:schemas-microsoft-com:office:word" | ||
4 | xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" | ||
5 | xmlns="http://www.w3.org/TR/REC-html40"> | ||
6 | |||
7 | <head> | ||
8 | <meta http-equiv=Content-Type content="text/html; charset=windows-1252"> | ||
9 | <meta name=ProgId content=Word.Document> | ||
10 | <meta name=Generator content="Microsoft Word 12"> | ||
11 | <meta name=Originator content="Microsoft Word 12"> | ||
12 | <link rel=File-List href="ctprofsrv_1.0_Manifest_files/filelist.xml"> | ||
13 | <link rel=Edit-Time-Data href="ctprofsrv_1.0_Manifest_files/editdata.mso"> | ||
14 | <!--[if !mso]> | ||
15 | <style> | ||
16 | v\:* {behavior:url(#default#VML);} | ||
17 | o\:* {behavior:url(#default#VML);} | ||
18 | w\:* {behavior:url(#default#VML);} | ||
19 | .shape {behavior:url(#default#VML);} | ||
20 | </style> | ||
21 | <![endif]--> | ||
22 | <title>ASP Software Manifest</title> | ||
23 | <!--[if gte mso 9]><xml> | ||
24 | <o:DocumentProperties> | ||
25 | <o:Subject>Software Manifest</o:Subject> | ||
26 | <o:Author>Texas Instruments, Incorporated</o:Author> | ||
27 | <o:Keywords>Manifest Open Source License</o:Keywords> | ||
28 | <o:Description>This document lists the licensing for a specific software release.</o:Description> | ||
29 | <o:Template>Normal</o:Template> | ||
30 | <o:LastAuthor>a0343404</o:LastAuthor> | ||
31 | <o:Revision>4</o:Revision> | ||
32 | <o:TotalTime>69</o:TotalTime> | ||
33 | <o:LastPrinted>2011-06-27T19:49:00Z</o:LastPrinted> | ||
34 | <o:Created>2013-07-30T22:10:00Z</o:Created> | ||
35 | <o:LastSaved>2013-08-01T13:28:00Z</o:LastSaved> | ||
36 | <o:Pages>2</o:Pages> | ||
37 | <o:Words>803</o:Words> | ||
38 | <o:Characters>4580</o:Characters> | ||
39 | <o:Category>Manifest</o:Category> | ||
40 | <o:Company>Texas Instruments</o:Company> | ||
41 | <o:Lines>38</o:Lines> | ||
42 | <o:Paragraphs>10</o:Paragraphs> | ||
43 | <o:CharactersWithSpaces>5373</o:CharactersWithSpaces> | ||
44 | <o:Version>12.00</o:Version> | ||
45 | </o:DocumentProperties> | ||
46 | <o:OfficeDocumentSettings> | ||
47 | <o:RelyOnVML/> | ||
48 | <o:AllowPNG/> | ||
49 | </o:OfficeDocumentSettings> | ||
50 | </xml><![endif]--> | ||
51 | <link rel=themeData href="ctprofsrv_1.0_Manifest_files/themedata.thmx"> | ||
52 | <link rel=colorSchemeMapping | ||
53 | href="ctprofsrv_1.0_Manifest_files/colorschememapping.xml"> | ||
54 | <!--[if gte mso 9]><xml> | ||
55 | <w:WordDocument> | ||
56 | <w:Zoom>110</w:Zoom> | ||
57 | <w:SpellingState>Clean</w:SpellingState> | ||
58 | <w:GrammarState>Clean</w:GrammarState> | ||
59 | <w:TrackMoves>false</w:TrackMoves> | ||
60 | <w:TrackFormatting/> | ||
61 | <w:PunctuationKerning/> | ||
62 | <w:ValidateAgainstSchemas/> | ||
63 | <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> | ||
64 | <w:IgnoreMixedContent>false</w:IgnoreMixedContent> | ||
65 | <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> | ||
66 | <w:DoNotPromoteQF/> | ||
67 | <w:LidThemeOther>EN-US</w:LidThemeOther> | ||
68 | <w:LidThemeAsian>X-NONE</w:LidThemeAsian> | ||
69 | <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> | ||
70 | <w:Compatibility> | ||
71 | <w:BreakWrappedTables/> | ||
72 | <w:SnapToGridInCell/> | ||
73 | <w:WrapTextWithPunct/> | ||
74 | <w:UseAsianBreakRules/> | ||
75 | <w:DontGrowAutofit/> | ||
76 | <w:SplitPgBreakAndParaMark/> | ||
77 | <w:DontVertAlignCellWithSp/> | ||
78 | <w:DontBreakConstrainedForcedTables/> | ||
79 | <w:DontVertAlignInTxbx/> | ||
80 | <w:Word11KerningPairs/> | ||
81 | <w:CachedColBalance/> | ||
82 | </w:Compatibility> | ||
83 | <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> | ||
84 | <m:mathPr> | ||
85 | <m:mathFont m:val="Cambria Math"/> | ||
86 | <m:brkBin m:val="before"/> | ||
87 | <m:brkBinSub m:val="--"/> | ||
88 | <m:smallFrac m:val="off"/> | ||
89 | <m:dispDef/> | ||
90 | <m:lMargin m:val="0"/> | ||
91 | <m:rMargin m:val="0"/> | ||
92 | <m:defJc m:val="centerGroup"/> | ||
93 | <m:wrapIndent m:val="1440"/> | ||
94 | <m:intLim m:val="subSup"/> | ||
95 | <m:naryLim m:val="undOvr"/> | ||
96 | </m:mathPr></w:WordDocument> | ||
97 | </xml><![endif]--><!--[if gte mso 9]><xml> | ||
98 | <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false" | ||
99 | DefSemiHidden="false" DefQFormat="false" LatentStyleCount="267"> | ||
100 | <w:LsdException Locked="true" QFormat="true" Name="Normal"/> | ||
101 | <w:LsdException Locked="true" QFormat="true" Name="heading 1"/> | ||
102 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
103 | QFormat="true" Name="heading 2"/> | ||
104 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
105 | QFormat="true" Name="heading 3"/> | ||
106 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
107 | QFormat="true" Name="heading 4"/> | ||
108 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
109 | QFormat="true" Name="heading 5"/> | ||
110 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
111 | QFormat="true" Name="heading 6"/> | ||
112 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
113 | QFormat="true" Name="heading 7"/> | ||
114 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
115 | QFormat="true" Name="heading 8"/> | ||
116 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
117 | QFormat="true" Name="heading 9"/> | ||
118 | <w:LsdException Locked="true" Name="toc 1"/> | ||
119 | <w:LsdException Locked="true" Name="toc 2"/> | ||
120 | <w:LsdException Locked="true" Name="toc 3"/> | ||
121 | <w:LsdException Locked="true" Name="toc 4"/> | ||
122 | <w:LsdException Locked="true" Name="toc 5"/> | ||
123 | <w:LsdException Locked="true" Name="toc 6"/> | ||
124 | <w:LsdException Locked="true" Name="toc 7"/> | ||
125 | <w:LsdException Locked="true" Name="toc 8"/> | ||
126 | <w:LsdException Locked="true" Name="toc 9"/> | ||
127 | <w:LsdException Locked="true" SemiHidden="true" UnhideWhenUsed="true" | ||
128 | QFormat="true" Name="caption"/> | ||
129 | <w:LsdException Locked="true" QFormat="true" Name="Title"/> | ||
130 | <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/> | ||
131 | <w:LsdException Locked="true" QFormat="true" Name="Subtitle"/> | ||
132 | <w:LsdException Locked="false" Priority="99" Name="Hyperlink"/> | ||
133 | <w:LsdException Locked="true" QFormat="true" Name="Strong"/> | ||
134 | <w:LsdException Locked="true" QFormat="true" Name="Emphasis"/> | ||
135 | <w:LsdException Locked="false" Priority="99" Name="HTML Preformatted"/> | ||
136 | <w:LsdException Locked="false" Priority="99" Name="No List"/> | ||
137 | <w:LsdException Locked="true" Name="Table Grid"/> | ||
138 | <w:LsdException Locked="false" Priority="99" SemiHidden="true" | ||
139 | Name="Placeholder Text"/> | ||
140 | <w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/> | ||
141 | <w:LsdException Locked="false" Priority="60" Name="Light Shading"/> | ||
142 | <w:LsdException Locked="false" Priority="61" Name="Light List"/> | ||
143 | <w:LsdException Locked="false" Priority="62" Name="Light Grid"/> | ||
144 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/> | ||
145 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/> | ||
146 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1"/> | ||
147 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2"/> | ||
148 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/> | ||
149 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/> | ||
150 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/> | ||
151 | <w:LsdException Locked="false" Priority="70" Name="Dark List"/> | ||
152 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/> | ||
153 | <w:LsdException Locked="false" Priority="72" Name="Colorful List"/> | ||
154 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/> | ||
155 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/> | ||
156 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/> | ||
157 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/> | ||
158 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/> | ||
159 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/> | ||
160 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/> | ||
161 | <w:LsdException Locked="false" Priority="99" SemiHidden="true" Name="Revision"/> | ||
162 | <w:LsdException Locked="false" Priority="34" QFormat="true" | ||
163 | Name="List Paragraph"/> | ||
164 | <w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/> | ||
165 | <w:LsdException Locked="false" Priority="30" QFormat="true" | ||
166 | Name="Intense Quote"/> | ||
167 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/> | ||
168 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/> | ||
169 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/> | ||
170 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/> | ||
171 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/> | ||
172 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/> | ||
173 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/> | ||
174 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/> | ||
175 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/> | ||
176 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/> | ||
177 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/> | ||
178 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/> | ||
179 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/> | ||
180 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/> | ||
181 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/> | ||
182 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/> | ||
183 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/> | ||
184 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/> | ||
185 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/> | ||
186 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/> | ||
187 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/> | ||
188 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/> | ||
189 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/> | ||
190 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/> | ||
191 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/> | ||
192 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/> | ||
193 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/> | ||
194 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/> | ||
195 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/> | ||
196 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/> | ||
197 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/> | ||
198 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/> | ||
199 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/> | ||
200 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/> | ||
201 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/> | ||
202 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/> | ||
203 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/> | ||
204 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/> | ||
205 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/> | ||
206 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/> | ||
207 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/> | ||
208 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/> | ||
209 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/> | ||
210 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/> | ||
211 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/> | ||
212 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/> | ||
213 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/> | ||
214 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/> | ||
215 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/> | ||
216 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/> | ||
217 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/> | ||
218 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/> | ||
219 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/> | ||
220 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/> | ||
221 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/> | ||
222 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/> | ||
223 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/> | ||
224 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/> | ||
225 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/> | ||
226 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/> | ||
227 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/> | ||
228 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/> | ||
229 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/> | ||
230 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/> | ||
231 | <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/> | ||
232 | <w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/> | ||
233 | <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/> | ||
234 | <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/> | ||
235 | <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/> | ||
236 | <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/> | ||
237 | <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/> | ||
238 | <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/> | ||
239 | <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/> | ||
240 | <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/> | ||
241 | <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/> | ||
242 | <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/> | ||
243 | <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/> | ||
244 | <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/> | ||
245 | <w:LsdException Locked="false" Priority="19" QFormat="true" | ||
246 | Name="Subtle Emphasis"/> | ||
247 | <w:LsdException Locked="false" Priority="21" QFormat="true" | ||
248 | Name="Intense Emphasis"/> | ||
249 | <w:LsdException Locked="false" Priority="31" QFormat="true" | ||
250 | Name="Subtle Reference"/> | ||
251 | <w:LsdException Locked="false" Priority="32" QFormat="true" | ||
252 | Name="Intense Reference"/> | ||
253 | <w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/> | ||
254 | <w:LsdException Locked="false" Priority="37" SemiHidden="true" | ||
255 | UnhideWhenUsed="true" Name="Bibliography"/> | ||
256 | <w:LsdException Locked="false" Priority="39" SemiHidden="true" | ||
257 | UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/> | ||
258 | </w:LatentStyles> | ||
259 | </xml><![endif]--> | ||
260 | <style> | ||
261 | <!-- | ||
262 | /* Font Definitions */ | ||
263 | @font-face | ||
264 | {font-family:"MS Mincho"; | ||
265 | panose-1:2 2 6 9 4 2 5 8 3 4; | ||
266 | mso-font-alt:"\FF2D\FF33 \660E\671D"; | ||
267 | mso-font-charset:128; | ||
268 | mso-generic-font-family:modern; | ||
269 | mso-font-pitch:fixed; | ||
270 | mso-font-signature:-536870145 1791491579 18 0 131231 0;} | ||
271 | @font-face | ||
272 | {font-family:"Cambria Math"; | ||
273 | panose-1:2 4 5 3 5 4 6 3 2 4; | ||
274 | mso-font-charset:0; | ||
275 | mso-generic-font-family:roman; | ||
276 | mso-font-pitch:variable; | ||
277 | mso-font-signature:-536870145 1107305727 0 0 415 0;} | ||
278 | @font-face | ||
279 | {font-family:Calibri; | ||
280 | panose-1:2 15 5 2 2 2 4 3 2 4; | ||
281 | mso-font-charset:0; | ||
282 | mso-generic-font-family:swiss; | ||
283 | mso-font-pitch:variable; | ||
284 | mso-font-signature:-520092929 1073786111 9 0 415 0;} | ||
285 | @font-face | ||
286 | {font-family:Tahoma; | ||
287 | panose-1:2 11 6 4 3 5 4 4 2 4; | ||
288 | mso-font-charset:0; | ||
289 | mso-generic-font-family:swiss; | ||
290 | mso-font-pitch:variable; | ||
291 | mso-font-signature:-520081665 -1073717157 41 0 66047 0;} | ||
292 | @font-face | ||
293 | {font-family:"\@MS Mincho"; | ||
294 | panose-1:2 2 6 9 4 2 5 8 3 4; | ||
295 | mso-font-charset:128; | ||
296 | mso-generic-font-family:modern; | ||
297 | mso-font-pitch:fixed; | ||
298 | mso-font-signature:-536870145 1791491579 18 0 131231 0;} | ||
299 | @font-face | ||
300 | {font-family:Consolas; | ||
301 | panose-1:2 11 6 9 2 2 4 3 2 4; | ||
302 | mso-font-charset:0; | ||
303 | mso-generic-font-family:modern; | ||
304 | mso-font-pitch:fixed; | ||
305 | mso-font-signature:-520092929 1073806591 9 0 415 0;} | ||
306 | /* Style Definitions */ | ||
307 | p.MsoNormal, li.MsoNormal, div.MsoNormal | ||
308 | {mso-style-unhide:no; | ||
309 | mso-style-qformat:yes; | ||
310 | mso-style-parent:""; | ||
311 | margin:0in; | ||
312 | margin-bottom:.0001pt; | ||
313 | mso-pagination:widow-orphan; | ||
314 | font-size:10.0pt; | ||
315 | font-family:"Arial","sans-serif"; | ||
316 | mso-fareast-font-family:"Times New Roman"; | ||
317 | mso-font-kerning:11.0pt;} | ||
318 | p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText | ||
319 | {mso-style-noshow:yes; | ||
320 | mso-style-unhide:no; | ||
321 | mso-style-link:"Footnote Text Char"; | ||
322 | margin:0in; | ||
323 | margin-bottom:.0001pt; | ||
324 | mso-pagination:widow-orphan; | ||
325 | font-size:10.0pt; | ||
326 | font-family:"Arial","sans-serif"; | ||
327 | mso-fareast-font-family:"Times New Roman"; | ||
328 | mso-font-kerning:11.0pt;} | ||
329 | p.MsoHeader, li.MsoHeader, div.MsoHeader | ||
330 | {mso-style-unhide:no; | ||
331 | mso-style-link:"Header Char"; | ||
332 | margin:0in; | ||
333 | margin-bottom:.0001pt; | ||
334 | mso-pagination:widow-orphan; | ||
335 | tab-stops:center 3.0in right 6.0in; | ||
336 | font-size:10.0pt; | ||
337 | font-family:"Arial","sans-serif"; | ||
338 | mso-fareast-font-family:"Times New Roman"; | ||
339 | mso-font-kerning:11.0pt;} | ||
340 | p.MsoFooter, li.MsoFooter, div.MsoFooter | ||
341 | {mso-style-unhide:no; | ||
342 | mso-style-link:"Footer Char"; | ||
343 | margin:0in; | ||
344 | margin-bottom:.0001pt; | ||
345 | mso-pagination:widow-orphan; | ||
346 | tab-stops:center 3.0in right 6.0in; | ||
347 | font-size:10.0pt; | ||
348 | font-family:"Arial","sans-serif"; | ||
349 | mso-fareast-font-family:"Times New Roman"; | ||
350 | mso-font-kerning:11.0pt;} | ||
351 | span.MsoFootnoteReference | ||
352 | {mso-style-noshow:yes; | ||
353 | mso-style-unhide:no; | ||
354 | font-family:"Times New Roman","serif"; | ||
355 | mso-ascii-font-family:"Times New Roman"; | ||
356 | mso-hansi-font-family:"Times New Roman"; | ||
357 | mso-bidi-font-family:"Times New Roman"; | ||
358 | vertical-align:super;} | ||
359 | p.MsoBodyText, li.MsoBodyText, div.MsoBodyText | ||
360 | {mso-style-unhide:no; | ||
361 | mso-style-link:"Body Text Char"; | ||
362 | margin-top:0in; | ||
363 | margin-right:0in; | ||
364 | margin-bottom:6.0pt; | ||
365 | margin-left:0in; | ||
366 | mso-pagination:widow-orphan; | ||
367 | font-size:10.0pt; | ||
368 | font-family:"Arial","sans-serif"; | ||
369 | mso-fareast-font-family:"Times New Roman"; | ||
370 | mso-font-kerning:11.0pt;} | ||
371 | p.MsoBlockText, li.MsoBlockText, div.MsoBlockText | ||
372 | {mso-style-unhide:no; | ||
373 | margin-top:0in; | ||
374 | margin-right:1.0in; | ||
375 | margin-bottom:6.0pt; | ||
376 | margin-left:1.0in; | ||
377 | mso-pagination:widow-orphan; | ||
378 | font-size:10.0pt; | ||
379 | font-family:"Arial","sans-serif"; | ||
380 | mso-fareast-font-family:"Times New Roman"; | ||
381 | mso-font-kerning:11.0pt;} | ||
382 | a:link, span.MsoHyperlink | ||
383 | {mso-style-priority:99; | ||
384 | mso-style-unhide:no; | ||
385 | color:blue; | ||
386 | text-decoration:underline; | ||
387 | text-underline:single;} | ||
388 | a:visited, span.MsoHyperlinkFollowed | ||
389 | {mso-style-unhide:no; | ||
390 | color:purple; | ||
391 | mso-themecolor:followedhyperlink; | ||
392 | text-decoration:underline; | ||
393 | text-underline:single;} | ||
394 | p.MsoDocumentMap, li.MsoDocumentMap, div.MsoDocumentMap | ||
395 | {mso-style-noshow:yes; | ||
396 | mso-style-unhide:no; | ||
397 | mso-style-link:"Document Map Char"; | ||
398 | margin:0in; | ||
399 | margin-bottom:.0001pt; | ||
400 | mso-pagination:widow-orphan; | ||
401 | background:navy; | ||
402 | font-size:10.0pt; | ||
403 | font-family:"Tahoma","sans-serif"; | ||
404 | mso-fareast-font-family:"Times New Roman"; | ||
405 | mso-font-kerning:11.0pt;} | ||
406 | pre | ||
407 | {mso-style-priority:99; | ||
408 | mso-style-unhide:no; | ||
409 | mso-style-link:"HTML Preformatted Char"; | ||
410 | margin:0in; | ||
411 | margin-bottom:.0001pt; | ||
412 | mso-pagination:widow-orphan; | ||
413 | font-size:10.0pt; | ||
414 | font-family:"Courier New"; | ||
415 | mso-fareast-font-family:Calibri; | ||
416 | mso-fareast-theme-font:minor-latin;} | ||
417 | p.MsoAcetate, li.MsoAcetate, div.MsoAcetate | ||
418 | {mso-style-noshow:yes; | ||
419 | mso-style-unhide:no; | ||
420 | mso-style-link:"Balloon Text Char"; | ||
421 | margin:0in; | ||
422 | margin-bottom:.0001pt; | ||
423 | mso-pagination:widow-orphan; | ||
424 | font-size:8.0pt; | ||
425 | font-family:"Tahoma","sans-serif"; | ||
426 | mso-fareast-font-family:"Times New Roman"; | ||
427 | mso-font-kerning:11.0pt;} | ||
428 | span.HTMLPreformattedChar | ||
429 | {mso-style-name:"HTML Preformatted Char"; | ||
430 | mso-style-priority:99; | ||
431 | mso-style-unhide:no; | ||
432 | mso-style-locked:yes; | ||
433 | mso-style-link:"HTML Preformatted"; | ||
434 | font-family:"Courier New"; | ||
435 | mso-ascii-font-family:"Courier New"; | ||
436 | mso-fareast-font-family:Calibri; | ||
437 | mso-fareast-theme-font:minor-latin; | ||
438 | mso-hansi-font-family:"Courier New"; | ||
439 | mso-bidi-font-family:"Courier New";} | ||
440 | span.FootnoteTextChar | ||
441 | {mso-style-name:"Footnote Text Char"; | ||
442 | mso-style-noshow:yes; | ||
443 | mso-style-unhide:no; | ||
444 | mso-style-locked:yes; | ||
445 | mso-style-link:"Footnote Text"; | ||
446 | font-family:"Arial","sans-serif"; | ||
447 | mso-ascii-font-family:Arial; | ||
448 | mso-hansi-font-family:Arial; | ||
449 | mso-bidi-font-family:Arial; | ||
450 | mso-font-kerning:11.0pt;} | ||
451 | span.HeaderChar | ||
452 | {mso-style-name:"Header Char"; | ||
453 | mso-style-noshow:yes; | ||
454 | mso-style-unhide:no; | ||
455 | mso-style-locked:yes; | ||
456 | mso-style-link:Header; | ||
457 | font-family:"Arial","sans-serif"; | ||
458 | mso-ascii-font-family:Arial; | ||
459 | mso-hansi-font-family:Arial; | ||
460 | mso-bidi-font-family:Arial; | ||
461 | mso-font-kerning:11.0pt;} | ||
462 | span.FooterChar | ||
463 | {mso-style-name:"Footer Char"; | ||
464 | mso-style-noshow:yes; | ||
465 | mso-style-unhide:no; | ||
466 | mso-style-locked:yes; | ||
467 | mso-style-link:Footer; | ||
468 | font-family:"Arial","sans-serif"; | ||
469 | mso-ascii-font-family:Arial; | ||
470 | mso-hansi-font-family:Arial; | ||
471 | mso-bidi-font-family:Arial; | ||
472 | mso-font-kerning:11.0pt;} | ||
473 | span.BodyTextChar | ||
474 | {mso-style-name:"Body Text Char"; | ||
475 | mso-style-noshow:yes; | ||
476 | mso-style-unhide:no; | ||
477 | mso-style-locked:yes; | ||
478 | mso-style-link:"Body Text"; | ||
479 | font-family:"Arial","sans-serif"; | ||
480 | mso-ascii-font-family:Arial; | ||
481 | mso-hansi-font-family:Arial; | ||
482 | mso-bidi-font-family:Arial; | ||
483 | mso-font-kerning:11.0pt;} | ||
484 | span.DocumentMapChar | ||
485 | {mso-style-name:"Document Map Char"; | ||
486 | mso-style-noshow:yes; | ||
487 | mso-style-unhide:no; | ||
488 | mso-style-locked:yes; | ||
489 | mso-style-link:"Document Map"; | ||
490 | mso-ansi-font-size:1.0pt; | ||
491 | font-family:"Arial","sans-serif"; | ||
492 | mso-ascii-font-family:Arial; | ||
493 | mso-hansi-font-family:Arial; | ||
494 | mso-bidi-font-family:Arial; | ||
495 | mso-font-kerning:11.0pt;} | ||
496 | span.BalloonTextChar | ||
497 | {mso-style-name:"Balloon Text Char"; | ||
498 | mso-style-noshow:yes; | ||
499 | mso-style-unhide:no; | ||
500 | mso-style-locked:yes; | ||
501 | mso-style-link:"Balloon Text"; | ||
502 | mso-ansi-font-size:1.0pt; | ||
503 | font-family:"Arial","sans-serif"; | ||
504 | mso-ascii-font-family:Arial; | ||
505 | mso-hansi-font-family:Arial; | ||
506 | mso-bidi-font-family:Arial; | ||
507 | mso-font-kerning:11.0pt;} | ||
508 | p.EditorsComment, li.EditorsComment, div.EditorsComment | ||
509 | {mso-style-name:"Editors Comment"; | ||
510 | mso-style-unhide:no; | ||
511 | mso-style-parent:"Block Text"; | ||
512 | mso-style-next:"Body Text"; | ||
513 | margin-top:0in; | ||
514 | margin-right:1.0in; | ||
515 | margin-bottom:6.0pt; | ||
516 | margin-left:1.0in; | ||
517 | mso-pagination:widow-orphan; | ||
518 | font-size:10.0pt; | ||
519 | font-family:"Arial","sans-serif"; | ||
520 | mso-fareast-font-family:"Times New Roman"; | ||
521 | mso-font-kerning:11.0pt; | ||
522 | font-style:italic; | ||
523 | mso-bidi-font-style:normal;} | ||
524 | p.StyleEditorsCommentCustomColorRGB51153255, li.StyleEditorsCommentCustomColorRGB51153255, div.StyleEditorsCommentCustomColorRGB51153255 | ||
525 | {mso-style-name:"Style Editors Comment + Custom Color\(RGB\(51153255\)\)"; | ||
526 | mso-style-update:auto; | ||
527 | mso-style-unhide:no; | ||
528 | mso-style-parent:"Editors Comment"; | ||
529 | margin-top:0in; | ||
530 | margin-right:1.0in; | ||
531 | margin-bottom:6.0pt; | ||
532 | margin-left:0in; | ||
533 | mso-pagination:widow-orphan; | ||
534 | font-size:10.0pt; | ||
535 | font-family:"Arial","sans-serif"; | ||
536 | mso-fareast-font-family:"Times New Roman"; | ||
537 | color:#3399FF; | ||
538 | mso-font-kerning:11.0pt; | ||
539 | font-style:italic;} | ||
540 | span.1ParaChar | ||
541 | {mso-style-name:"1_Para Char"; | ||
542 | mso-style-unhide:no; | ||
543 | mso-style-locked:yes; | ||
544 | mso-style-link:1_Para; | ||
545 | font-family:"Arial","sans-serif"; | ||
546 | mso-ascii-font-family:Arial; | ||
547 | mso-hansi-font-family:Arial; | ||
548 | mso-bidi-font-family:Arial; | ||
549 | mso-font-kerning:10.0pt; | ||
550 | mso-ansi-language:EN-US; | ||
551 | mso-fareast-language:EN-US; | ||
552 | mso-bidi-language:AR-SA;} | ||
553 | p.1Para, li.1Para, div.1Para | ||
554 | {mso-style-name:1_Para; | ||
555 | mso-style-unhide:no; | ||
556 | mso-style-parent:""; | ||
557 | mso-style-link:"1_Para Char"; | ||
558 | margin-top:10.0pt; | ||
559 | margin-right:0in; | ||
560 | margin-bottom:6.0pt; | ||
561 | margin-left:0in; | ||
562 | text-align:justify; | ||
563 | line-height:11.0pt; | ||
564 | mso-line-height-rule:exactly; | ||
565 | mso-pagination:widow-orphan lines-together; | ||
566 | font-size:10.0pt; | ||
567 | font-family:"Arial","sans-serif"; | ||
568 | mso-fareast-font-family:"Times New Roman"; | ||
569 | mso-font-kerning:10.0pt;} | ||
570 | span.SpellE | ||
571 | {mso-style-name:""; | ||
572 | mso-spl-e:yes;} | ||
573 | span.GramE | ||
574 | {mso-style-name:""; | ||
575 | mso-gram-e:yes;} | ||
576 | .MsoChpDefault | ||
577 | {mso-style-type:export-only; | ||
578 | mso-default-props:yes; | ||
579 | font-size:10.0pt; | ||
580 | mso-ansi-font-size:10.0pt; | ||
581 | mso-bidi-font-size:10.0pt;} | ||
582 | @page WordSection1 | ||
583 | {size:11.0in 8.5in; | ||
584 | mso-page-orientation:landscape; | ||
585 | margin:1.25in 1.0in 1.25in 1.0in; | ||
586 | mso-header-margin:.5in; | ||
587 | mso-footer-margin:.5in; | ||
588 | mso-paper-source:0;} | ||
589 | div.WordSection1 | ||
590 | {page:WordSection1;} | ||
591 | --> | ||
592 | </style> | ||
593 | <!--[if gte mso 10]> | ||
594 | <style> | ||
595 | /* Style Definitions */ | ||
596 | table.MsoNormalTable | ||
597 | {mso-style-name:"Table Normal"; | ||
598 | mso-tstyle-rowband-size:0; | ||
599 | mso-tstyle-colband-size:0; | ||
600 | mso-style-noshow:yes; | ||
601 | mso-style-priority:99; | ||
602 | mso-style-qformat:yes; | ||
603 | mso-style-parent:""; | ||
604 | mso-padding-alt:0in 5.4pt 0in 5.4pt; | ||
605 | mso-para-margin:0in; | ||
606 | mso-para-margin-bottom:.0001pt; | ||
607 | mso-pagination:widow-orphan; | ||
608 | font-size:10.0pt; | ||
609 | font-family:"Times New Roman","serif";} | ||
610 | table.MsoTableGrid | ||
611 | {mso-style-name:"Table Grid"; | ||
612 | mso-tstyle-rowband-size:0; | ||
613 | mso-tstyle-colband-size:0; | ||
614 | mso-style-unhide:no; | ||
615 | border:solid windowtext 1.0pt; | ||
616 | mso-border-alt:solid windowtext .5pt; | ||
617 | mso-padding-alt:0in 5.4pt 0in 5.4pt; | ||
618 | mso-border-insideh:.5pt solid windowtext; | ||
619 | mso-border-insidev:.5pt solid windowtext; | ||
620 | mso-para-margin:0in; | ||
621 | mso-para-margin-bottom:.0001pt; | ||
622 | mso-pagination:widow-orphan; | ||
623 | font-size:10.0pt; | ||
624 | font-family:"Times New Roman","serif";} | ||
625 | </style> | ||
626 | <![endif]--><!--[if gte mso 9]><xml> | ||
627 | <o:shapedefaults v:ext="edit" spidmax="9218"/> | ||
628 | </xml><![endif]--><!--[if gte mso 9]><xml> | ||
629 | <o:shapelayout v:ext="edit"> | ||
630 | <o:idmap v:ext="edit" data="1"/> | ||
631 | </o:shapelayout></xml><![endif]--> | ||
632 | </head> | ||
633 | |||
634 | <body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'> | ||
635 | |||
636 | <div class=WordSection1> | ||
637 | |||
638 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
639 | |||
640 | <p class=MsoNormal style='mso-outline-level:1'><v:shapetype id="_x0000_t75" | ||
641 | coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" | ||
642 | filled="f" stroked="f"> | ||
643 | <v:stroke joinstyle="miter"/> | ||
644 | <v:formulas> | ||
645 | <v:f eqn="if lineDrawn pixelLineWidth 0"/> | ||
646 | <v:f eqn="sum @0 1 0"/> | ||
647 | <v:f eqn="sum 0 0 @1"/> | ||
648 | <v:f eqn="prod @2 1 2"/> | ||
649 | <v:f eqn="prod @3 21600 pixelWidth"/> | ||
650 | <v:f eqn="prod @3 21600 pixelHeight"/> | ||
651 | <v:f eqn="sum @0 0 1"/> | ||
652 | <v:f eqn="prod @6 1 2"/> | ||
653 | <v:f eqn="prod @7 21600 pixelWidth"/> | ||
654 | <v:f eqn="sum @8 21600 0"/> | ||
655 | <v:f eqn="prod @7 21600 pixelHeight"/> | ||
656 | <v:f eqn="sum @10 21600 0"/> | ||
657 | </v:formulas> | ||
658 | <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> | ||
659 | <o:lock v:ext="edit" aspectratio="t"/> | ||
660 | </v:shapetype><v:shape id="Picture_x0020_1" o:spid="_x0000_i1025" type="#_x0000_t75" | ||
661 | alt="hdr_ti_logo" style='width:180pt;height:24.75pt;visibility:visible; | ||
662 | mso-wrap-style:square;mso-left-percent:-10001;mso-top-percent:-10001; | ||
663 | mso-position-horizontal:absolute;mso-position-horizontal-relative:char; | ||
664 | mso-position-vertical:absolute;mso-position-vertical-relative:line; | ||
665 | mso-left-percent:-10001;mso-top-percent:-10001'> | ||
666 | <v:textbox style='mso-rotate-with-shape:t'/> | ||
667 | </v:shape><b style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt'><span | ||
668 | style='mso-spacerun:yes'> | ||
669 | </span><span style='mso-spacerun:yes'> </span><span | ||
670 | style='mso-spacerun:yes'> </span>August 1, 2013<o:p></o:p></span></b></p> | ||
671 | |||
672 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
673 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
674 | |||
675 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
676 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
677 | |||
678 | <p class=MsoNormal><v:line id="_x0000_s1028" style='position:absolute;flip:y; | ||
679 | z-index:1;mso-position-horizontal-relative:page; | ||
680 | mso-position-vertical-relative:page' from="396pt,-17.65pt" to="396pt,342.9pt" | ||
681 | strokecolor="white"> | ||
682 | <w:wrap anchorx="page" anchory="page"/> | ||
683 | <w:anchorlock/> | ||
684 | </v:line><span class=SpellE><span class=GramE><b style='mso-bidi-font-weight: | ||
685 | normal'><span style='font-size:12.0pt'>ctprof_srv</span></b></span></span><b | ||
686 | style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt'> Manifest<o:p></o:p></span></b></p> | ||
687 | |||
688 | <p class=MsoNormal><o:p> </o:p></p> | ||
689 | |||
690 | <p class=MsoNormal><o:p> </o:p></p> | ||
691 | |||
692 | <p class=MsoNormal><o:p> </o:p></p> | ||
693 | |||
694 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
695 | normal'><span style='font-size:12.0pt'>Legend <o:p></o:p></span></b></p> | ||
696 | |||
697 | <p class=MsoNormal><o:p> </o:p></p> | ||
698 | |||
699 | <table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0 | ||
700 | style='border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt; | ||
701 | mso-yfti-tbllook:480;mso-padding-alt:0in 5.4pt 0in 5.4pt;mso-border-insideh: | ||
702 | .5pt solid windowtext;mso-border-insidev:.5pt solid windowtext'> | ||
703 | <tr style='mso-yfti-irow:0;mso-yfti-firstrow:yes'> | ||
704 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
705 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
706 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
707 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Software | ||
708 | Name </span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
709 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
710 | </td> | ||
711 | <td width=748 valign=top style='width:560.7pt;border:solid windowtext 1.0pt; | ||
712 | border-left:none;mso-border-left-alt:solid windowtext .5pt;mso-border-alt: | ||
713 | solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
714 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
715 | 2.0pt;margin-left:0in'>The name of the application or file<span | ||
716 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
717 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
718 | </td> | ||
719 | </tr> | ||
720 | <tr style='mso-yfti-irow:1'> | ||
721 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
722 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
723 | padding:0in 5.4pt 0in 5.4pt'> | ||
724 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
725 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Version | ||
726 | </span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
727 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
728 | </td> | ||
729 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
730 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
731 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
732 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
733 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
734 | 2.0pt;margin-left:0in'>Version of the application or file<span | ||
735 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
736 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
737 | </td> | ||
738 | </tr> | ||
739 | <tr style='mso-yfti-irow:2'> | ||
740 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
741 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
742 | padding:0in 5.4pt 0in 5.4pt'> | ||
743 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
744 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>License | ||
745 | Type</span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
746 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
747 | </td> | ||
748 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
749 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
750 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
751 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
752 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
753 | 2.0pt;margin-left:0in'>Type of license(s) under which TI will be providing | ||
754 | software to the licensee (e.g. BSD, GPLv2, TI TSPA License, TI Commercial | ||
755 | License). See Open Source Reference License Disclaimer in the Disclaimers Section.<span | ||
756 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
757 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
758 | </td> | ||
759 | </tr> | ||
760 | <tr style='mso-yfti-irow:3'> | ||
761 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
762 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
763 | padding:0in 5.4pt 0in 5.4pt'> | ||
764 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
765 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Location | ||
766 | </span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
767 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
768 | </td> | ||
769 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
770 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
771 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
772 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
773 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
774 | 2.0pt;margin-left:0in'>The directory name and path on the media (or in an | ||
775 | archive) where the Software is located.<span style='font-size:12.0pt; | ||
776 | font-family:"Times New Roman","serif";mso-fareast-font-family:Calibri; | ||
777 | mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
778 | </td> | ||
779 | </tr> | ||
780 | <tr style='mso-yfti-irow:4'> | ||
781 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
782 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
783 | padding:0in 5.4pt 0in 5.4pt'> | ||
784 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
785 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Delivered | ||
786 | As</span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
787 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
788 | </td> | ||
789 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
790 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
791 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
792 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
793 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
794 | 2.0pt;margin-left:0in'>This field will either be “Source”, “Binary” or “Source | ||
795 | and Binary” and is the form the content of the Software is delivered | ||
796 | in. If the Software is delivered in an archive format, this field | ||
797 | applies to the contents of the archive. If the word Limited is used with | ||
798 | Source, as in “Limited Source” or “Limited Source and Binary” then only | ||
799 | portions of the Source for the application are provided.<span | ||
800 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
801 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
802 | </td> | ||
803 | </tr> | ||
804 | <tr style='mso-yfti-irow:5'> | ||
805 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
806 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
807 | padding:0in 5.4pt 0in 5.4pt'> | ||
808 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
809 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Modified | ||
810 | by TI</span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
811 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
812 | </td> | ||
813 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
814 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
815 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
816 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
817 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
818 | 2.0pt;margin-left:0in'>This field will either be “Yes” or “No”. A “Yes” means | ||
819 | TI has made changes to the Software. A “No” means TI has not made any | ||
820 | changes. Note: This field is not applicable for Software “Obtained from” TI.<span | ||
821 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
822 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
823 | </td> | ||
824 | </tr> | ||
825 | <tr style='mso-yfti-irow:6;mso-yfti-lastrow:yes'> | ||
826 | <td width=131 valign=top style='width:98.1pt;border:solid windowtext 1.0pt; | ||
827 | border-top:none;mso-border-top-alt:solid windowtext .5pt;mso-border-alt:solid windowtext .5pt; | ||
828 | padding:0in 5.4pt 0in 5.4pt'> | ||
829 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
830 | 2.0pt;margin-left:0in'><b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'>Obtained | ||
831 | from</span></b><span style='font-size:12.0pt;font-family:"Times New Roman","serif"; | ||
832 | mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
833 | </td> | ||
834 | <td width=748 valign=top style='width:560.7pt;border-top:none;border-left: | ||
835 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
836 | mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt; | ||
837 | mso-border-alt:solid windowtext .5pt;padding:0in 5.4pt 0in 5.4pt'> | ||
838 | <p class=MsoNormal style='margin-top:3.0pt;margin-right:0in;margin-bottom: | ||
839 | 2.0pt;margin-left:0in'>This field specifies from where or from whom TI | ||
840 | obtained the Software. It may be a URL to an Open Source site, a 3<sup>rd</sup> | ||
841 | party licensor, or TI (if TI developed the software). If this field contains | ||
842 | a link to Open Source software, the date TI downloaded the Software is also | ||
843 | recorded. See Links Disclaimer in the Disclaimers Section.<span | ||
844 | style='font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family: | ||
845 | Calibri;mso-fareast-theme-font:minor-latin'><o:p></o:p></span></p> | ||
846 | </td> | ||
847 | </tr> | ||
848 | </table> | ||
849 | |||
850 | <p class=MsoNormal><o:p> </o:p></p> | ||
851 | |||
852 | <p class=MsoNormal><o:p> </o:p></p> | ||
853 | |||
854 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
855 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
856 | |||
857 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
858 | normal'><span style='font-size:12.0pt'>DISCLAIMERS<o:p></o:p></span></b></p> | ||
859 | |||
860 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
861 | |||
862 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
863 | normal'><u>Export Control Classification Number (ECCN)<o:p></o:p></u></b></p> | ||
864 | |||
865 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
866 | |||
867 | <p class=MsoNormal style='margin-left:.5in;mso-outline-level:1'>Any use of ECCNs | ||
868 | listed in the Manifest is at the user’s risk and without recourse to TI.<span | ||
869 | style='mso-spacerun:yes'> </span>Your company, as the exporter of record, is | ||
870 | responsible for determining the correct classification of any item at the time | ||
871 | of export. Any export classification by TI of Software is for TI’s internal use | ||
872 | only and shall not be construed as a representation or warranty regarding the | ||
873 | proper export classification for such Software or whether an export license or | ||
874 | other documentation is required for exporting such Software<b style='mso-bidi-font-weight: | ||
875 | normal'><span style='font-size:12.0pt'>.<span style='mso-spacerun:yes'> | ||
876 | </span><o:p></o:p></span></b></p> | ||
877 | |||
878 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
879 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
880 | |||
881 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
882 | normal'><u>Links in the Manifest<o:p></o:p></u></b></p> | ||
883 | |||
884 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
885 | |||
886 | <p class=1Para style='margin-left:.5in'>Any links appearing on this Manifest | ||
887 | (for example in the “Obtained from” field) were verified at the time the | ||
888 | Manifest was created. TI makes no guarantee that any listed links will remain | ||
889 | active in the future.</p> | ||
890 | |||
891 | <p class=1Para><b style='mso-bidi-font-weight:normal'><u>Open Source License | ||
892 | References<o:p></o:p></u></b></p> | ||
893 | |||
894 | <p class=1Para style='margin-left:.5in'>Your company is responsible for | ||
895 | confirming the applicable license terms for any open source Software listed in | ||
896 | this Manifest that was not “Obtained from” TI.<span style='mso-spacerun:yes'> | ||
897 | </span>Any open source license specified in this Manifest for Software that was | ||
898 | not “Obtained from” TI is for TI’s internal use only and shall not be construed | ||
899 | as a representation or warranty regarding the proper open source license terms | ||
900 | for such Software.</p> | ||
901 | |||
902 | <b style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt; | ||
903 | font-family:"Arial","sans-serif";mso-fareast-font-family:"Times New Roman"; | ||
904 | mso-font-kerning:11.0pt;mso-ansi-language:EN-US;mso-fareast-language:EN-US; | ||
905 | mso-bidi-language:AR-SA'><br clear=all style='mso-special-character:line-break; | ||
906 | page-break-before:always'> | ||
907 | </span></b> | ||
908 | |||
909 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
910 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
911 | |||
912 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
913 | normal'><span style='font-size:12.0pt'>Export Information<o:p></o:p></span></b></p> | ||
914 | |||
915 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
916 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
917 | |||
918 | <p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning: | ||
919 | 0pt;mso-fareast-language:JA'>ECCN for Software included in this release:<o:p></o:p></span></p> | ||
920 | |||
921 | <p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>Publically | ||
922 | Available</span><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning: | ||
923 | 0pt;mso-fareast-language:JA'> <o:p></o:p></span></p> | ||
924 | |||
925 | <p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning: | ||
926 | 0pt;mso-fareast-language:JA'><o:p> </o:p></span></p> | ||
927 | |||
928 | <p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning: | ||
929 | 0pt;mso-fareast-language:JA'>ECCN for Technology (e.g., user documentation, | ||
930 | specifications) included in this release:<o:p></o:p></span></p> | ||
931 | |||
932 | <p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>N/A</span><span | ||
933 | style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:0pt;mso-fareast-language: | ||
934 | JA'><o:p></o:p></span></p> | ||
935 | |||
936 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
937 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
938 | |||
939 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
940 | |||
941 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
942 | normal'><span style='font-size:12.0pt'>Manifest<o:p></o:p></span></b></p> | ||
943 | |||
944 | <p class=MsoNormal><o:p> </o:p></p> | ||
945 | |||
946 | <p class=MsoNormal>See Legend above for a description of the columns and | ||
947 | possible values.</p> | ||
948 | |||
949 | <p class=MsoNormal><o:p> </o:p></p> | ||
950 | |||
951 | <table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0 width=865 | ||
952 | style='width:648.85pt;border-collapse:collapse;border:none;mso-border-alt: | ||
953 | solid windowtext .5pt;mso-yfti-tbllook:480;mso-padding-alt:0in 5.4pt 0in 5.4pt; | ||
954 | mso-border-insideh:.75pt solid windowtext;mso-border-insidev:.75pt solid windowtext'> | ||
955 | <thead> | ||
956 | <tr style='mso-yfti-irow:0;mso-yfti-firstrow:yes;page-break-inside:avoid'> | ||
957 | <td width=115 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
958 | mso-border-top-alt:.5pt;mso-border-left-alt:.5pt;mso-border-bottom-alt:.75pt; | ||
959 | mso-border-right-alt:.75pt;mso-border-color-alt:windowtext;mso-border-style-alt: | ||
960 | solid;background:#E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
961 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
962 | normal'>Software Name<o:p></o:p></b></p> | ||
963 | </td> | ||
964 | <td width=76 valign=top style='width:56.9pt;border:solid windowtext 1.0pt; | ||
965 | border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt: | ||
966 | solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background: | ||
967 | #E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
968 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
969 | normal'>Version<o:p></o:p></b></p> | ||
970 | </td> | ||
971 | <td width=89 valign=top style='width:66.4pt;border:solid windowtext 1.0pt; | ||
972 | border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt: | ||
973 | solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background: | ||
974 | #E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
975 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
976 | normal'>License Type<o:p></o:p></b></p> | ||
977 | </td> | ||
978 | <td width=84 valign=top style='width:63.0pt;border:solid windowtext 1.0pt; | ||
979 | border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt: | ||
980 | solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background: | ||
981 | #E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
982 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
983 | normal'>Delivered <o:p></o:p></b></p> | ||
984 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
985 | normal'>As <o:p></o:p></b></p> | ||
986 | </td> | ||
987 | <td width=108 valign=top style='width:81.0pt;border:solid windowtext 1.0pt; | ||
988 | border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-alt: | ||
989 | solid windowtext .75pt;mso-border-top-alt:solid windowtext .5pt;background: | ||
990 | #E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
991 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
992 | normal'>Modified by <o:p></o:p></b></p> | ||
993 | <p class=MsoNormal style='margin-top:3.0pt'><b style='mso-bidi-font-weight: | ||
994 | normal'>TI <o:p></o:p></b></p> | ||
995 | </td> | ||
996 | <td width=394 colspan=2 valign=top style='width:295.15pt;border:solid windowtext 1.0pt; | ||
997 | border-left:none;mso-border-left-alt:solid windowtext .75pt;mso-border-top-alt: | ||
998 | .5pt;mso-border-left-alt:.75pt;mso-border-bottom-alt:.75pt;mso-border-right-alt: | ||
999 | .5pt;mso-border-color-alt:windowtext;mso-border-style-alt:solid;background: | ||
1000 | #E6E6E6;padding:0in 5.4pt 0in 5.4pt'> | ||
1001 | <p class=MsoNormal style='margin-top:3.0pt;mso-outline-level:1'><b | ||
1002 | style='mso-bidi-font-weight:normal'><span style='font-size:9.0pt'><o:p> </o:p></span></b></p> | ||
1003 | </td> | ||
1004 | </tr> | ||
1005 | </thead> | ||
1006 | <tr style='mso-yfti-irow:1;page-break-inside:avoid'> | ||
1007 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1008 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1009 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1010 | 0in 5.4pt 0in 5.4pt'> | ||
1011 | <p class=MsoNormal><span class=SpellE>ctprof_srv</span></p> | ||
1012 | </td> | ||
1013 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1014 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1015 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1016 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1017 | <p class=MsoNormal>1.0</p> | ||
1018 | </td> | ||
1019 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1020 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1021 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1022 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1023 | <p class=MsoNormal>BSD</p> | ||
1024 | </td> | ||
1025 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1026 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1027 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1028 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1029 | <p class=MsoNormal>“Source and Binary”</p> | ||
1030 | </td> | ||
1031 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1032 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1033 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1034 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1035 | <p class=MsoNormal>N/A</p> | ||
1036 | </td> | ||
1037 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1038 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1039 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1040 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1041 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1042 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1043 | </td> | ||
1044 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1045 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1046 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1047 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1048 | padding:0in 5.4pt 0in 5.4pt'> | ||
1049 | <p class=MsoNormal>./<span class=SpellE>ctoolsprof</span>/server</p> | ||
1050 | </td> | ||
1051 | </tr> | ||
1052 | <tr style='mso-yfti-irow:2;page-break-inside:avoid'> | ||
1053 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1054 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1055 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1056 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1057 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1058 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1059 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1060 | </td> | ||
1061 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1062 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1063 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1064 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1065 | padding:0in 5.4pt 0in 5.4pt'> | ||
1066 | <p class=MsoNormal>TI</p> | ||
1067 | </td> | ||
1068 | </tr> | ||
1069 | <tr style='mso-yfti-irow:3;page-break-inside:avoid'> | ||
1070 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1071 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1072 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1073 | 0in 5.4pt 0in 5.4pt'> | ||
1074 | <p class=MsoNormal><span class=SpellE>ctprof_ex</span></p> | ||
1075 | </td> | ||
1076 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1077 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1078 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1079 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1080 | <p class=MsoNormal>1.0</p> | ||
1081 | </td> | ||
1082 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1083 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1084 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1085 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1086 | <p class=MsoNormal>BSD</p> | ||
1087 | </td> | ||
1088 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1089 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1090 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1091 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1092 | <p class=MsoNormal>“Source and Binary”</p> | ||
1093 | </td> | ||
1094 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1095 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1096 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1097 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1098 | <p class=MsoNormal>N/A</p> | ||
1099 | </td> | ||
1100 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1101 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1102 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1103 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1104 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1105 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1106 | </td> | ||
1107 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1108 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1109 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1110 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1111 | padding:0in 5.4pt 0in 5.4pt'> | ||
1112 | <p class=MsoNormal>./<span class=SpellE>ctoolsprof</span>/<span class=SpellE>example_app</span></p> | ||
1113 | </td> | ||
1114 | </tr> | ||
1115 | <tr style='mso-yfti-irow:4;page-break-inside:avoid'> | ||
1116 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1117 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1118 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1119 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1120 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1121 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1122 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1123 | </td> | ||
1124 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1125 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1126 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1127 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1128 | padding:0in 5.4pt 0in 5.4pt'> | ||
1129 | <p class=MsoNormal>TI</p> | ||
1130 | <p class=MsoNormal><o:p> </o:p></p> | ||
1131 | </td> | ||
1132 | </tr> | ||
1133 | <tr style='mso-yfti-irow:5;page-break-inside:avoid'> | ||
1134 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1135 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1136 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1137 | 0in 5.4pt 0in 5.4pt'> | ||
1138 | <p class=MsoNormal><o:p> </o:p></p> | ||
1139 | </td> | ||
1140 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1141 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1142 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1143 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1144 | <p class=MsoNormal><o:p> </o:p></p> | ||
1145 | </td> | ||
1146 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1147 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1148 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1149 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1150 | <p class=MsoNormal><o:p> </o:p></p> | ||
1151 | </td> | ||
1152 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1153 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1154 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1155 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1156 | <p class=MsoNormal><o:p> </o:p></p> | ||
1157 | </td> | ||
1158 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1159 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1160 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1161 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1162 | <p class=MsoNormal><o:p> </o:p></p> | ||
1163 | </td> | ||
1164 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1165 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1166 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1167 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1168 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1169 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1170 | </td> | ||
1171 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1172 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1173 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1174 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1175 | padding:0in 5.4pt 0in 5.4pt'> | ||
1176 | <p class=MsoNormal><o:p> </o:p></p> | ||
1177 | </td> | ||
1178 | </tr> | ||
1179 | <tr style='mso-yfti-irow:6;page-break-inside:avoid'> | ||
1180 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1181 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1182 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1183 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1184 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1185 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1186 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1187 | </td> | ||
1188 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1189 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1190 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1191 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1192 | padding:0in 5.4pt 0in 5.4pt'> | ||
1193 | <p class=MsoNormal><o:p> </o:p></p> | ||
1194 | </td> | ||
1195 | </tr> | ||
1196 | <tr style='mso-yfti-irow:7;page-break-inside:avoid'> | ||
1197 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1198 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1199 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1200 | 0in 5.4pt 0in 5.4pt'> | ||
1201 | <p class=MsoNormal><o:p> </o:p></p> | ||
1202 | </td> | ||
1203 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1204 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1205 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1206 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1207 | <p class=MsoNormal><o:p> </o:p></p> | ||
1208 | </td> | ||
1209 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1210 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1211 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1212 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1213 | <p class=MsoNormal><o:p> </o:p></p> | ||
1214 | </td> | ||
1215 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1216 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1217 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1218 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1219 | <p class=MsoNormal><o:p> </o:p></p> | ||
1220 | </td> | ||
1221 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1222 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1223 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1224 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1225 | <p class=MsoNormal><o:p> </o:p></p> | ||
1226 | </td> | ||
1227 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1228 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1229 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1230 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1231 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1232 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1233 | </td> | ||
1234 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1235 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1236 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1237 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1238 | padding:0in 5.4pt 0in 5.4pt'> | ||
1239 | <p class=MsoNormal><o:p> </o:p></p> | ||
1240 | </td> | ||
1241 | </tr> | ||
1242 | <tr style='mso-yfti-irow:8;page-break-inside:avoid'> | ||
1243 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1244 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1245 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1246 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1247 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1248 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1249 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1250 | </td> | ||
1251 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1252 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1253 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1254 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1255 | padding:0in 5.4pt 0in 5.4pt'> | ||
1256 | <p class=MsoNormal><o:p> </o:p></p> | ||
1257 | </td> | ||
1258 | </tr> | ||
1259 | <tr style='mso-yfti-irow:9;page-break-inside:avoid'> | ||
1260 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1261 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1262 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1263 | 0in 5.4pt 0in 5.4pt'> | ||
1264 | <p class=MsoNormal><o:p> </o:p></p> | ||
1265 | </td> | ||
1266 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1267 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1268 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1269 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1270 | <p class=MsoNormal><o:p> </o:p></p> | ||
1271 | </td> | ||
1272 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1273 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1274 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1275 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1276 | <p class=MsoNormal><o:p> </o:p></p> | ||
1277 | </td> | ||
1278 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1279 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1280 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1281 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1282 | <p class=MsoNormal><o:p> </o:p></p> | ||
1283 | </td> | ||
1284 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1285 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1286 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1287 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1288 | <p class=MsoNormal><o:p> </o:p></p> | ||
1289 | </td> | ||
1290 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1291 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1292 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1293 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1294 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1295 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1296 | </td> | ||
1297 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1298 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1299 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1300 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1301 | padding:0in 5.4pt 0in 5.4pt'> | ||
1302 | <p class=MsoNormal><o:p> </o:p></p> | ||
1303 | </td> | ||
1304 | </tr> | ||
1305 | <tr style='mso-yfti-irow:10;page-break-inside:avoid'> | ||
1306 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1307 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1308 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1309 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1310 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1311 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1312 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1313 | </td> | ||
1314 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1315 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1316 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1317 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1318 | padding:0in 5.4pt 0in 5.4pt'> | ||
1319 | <p class=MsoNormal><o:p> </o:p></p> | ||
1320 | </td> | ||
1321 | </tr> | ||
1322 | <tr style='mso-yfti-irow:11;page-break-inside:avoid'> | ||
1323 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1324 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1325 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1326 | 0in 5.4pt 0in 5.4pt'> | ||
1327 | <p class=MsoNormal><o:p> </o:p></p> | ||
1328 | </td> | ||
1329 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1330 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1331 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1332 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1333 | <p class=MsoNormal><o:p> </o:p></p> | ||
1334 | </td> | ||
1335 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1336 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1337 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1338 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1339 | <p class=MsoNormal><o:p> </o:p></p> | ||
1340 | </td> | ||
1341 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1342 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1343 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1344 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1345 | <p class=MsoNormal><o:p> </o:p></p> | ||
1346 | </td> | ||
1347 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1348 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1349 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1350 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1351 | <p class=MsoNormal><o:p> </o:p></p> | ||
1352 | </td> | ||
1353 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1354 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1355 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1356 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1357 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1358 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1359 | </td> | ||
1360 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1361 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1362 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1363 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1364 | padding:0in 5.4pt 0in 5.4pt'> | ||
1365 | <p class=MsoNormal><o:p> </o:p></p> | ||
1366 | </td> | ||
1367 | </tr> | ||
1368 | <tr style='mso-yfti-irow:12;page-break-inside:avoid'> | ||
1369 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1370 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1371 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1372 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1373 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1374 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1375 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1376 | </td> | ||
1377 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1378 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1379 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1380 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1381 | padding:0in 5.4pt 0in 5.4pt'> | ||
1382 | <p class=MsoNormal><o:p> </o:p></p> | ||
1383 | </td> | ||
1384 | </tr> | ||
1385 | <tr style='mso-yfti-irow:13;page-break-inside:avoid'> | ||
1386 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1387 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1388 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1389 | 0in 5.4pt 0in 5.4pt'> | ||
1390 | <p class=MsoNormal><o:p> </o:p></p> | ||
1391 | </td> | ||
1392 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1393 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1394 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1395 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1396 | <p class=MsoNormal><o:p> </o:p></p> | ||
1397 | </td> | ||
1398 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1399 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1400 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1401 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1402 | <p class=MsoNormal><o:p> </o:p></p> | ||
1403 | </td> | ||
1404 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1405 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1406 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1407 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1408 | <p class=MsoNormal><o:p> </o:p></p> | ||
1409 | </td> | ||
1410 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1411 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1412 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1413 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1414 | <p class=MsoNormal><o:p> </o:p></p> | ||
1415 | </td> | ||
1416 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1417 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1418 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1419 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1420 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1421 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1422 | </td> | ||
1423 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1424 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1425 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1426 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1427 | padding:0in 5.4pt 0in 5.4pt'> | ||
1428 | <p class=MsoNormal><o:p> </o:p></p> | ||
1429 | </td> | ||
1430 | </tr> | ||
1431 | <tr style='mso-yfti-irow:14;page-break-inside:avoid'> | ||
1432 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1433 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1434 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1435 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1436 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1437 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1438 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1439 | </td> | ||
1440 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1441 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1442 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1443 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1444 | padding:0in 5.4pt 0in 5.4pt'> | ||
1445 | <p class=MsoNormal><o:p> </o:p></p> | ||
1446 | </td> | ||
1447 | </tr> | ||
1448 | <tr style='mso-yfti-irow:15;page-break-inside:avoid'> | ||
1449 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1450 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1451 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1452 | 0in 5.4pt 0in 5.4pt'> | ||
1453 | <p class=MsoNormal><o:p> </o:p></p> | ||
1454 | </td> | ||
1455 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1456 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1457 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1458 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1459 | <p class=MsoNormal><o:p> </o:p></p> | ||
1460 | </td> | ||
1461 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1462 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1463 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1464 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1465 | <p class=MsoNormal><o:p> </o:p></p> | ||
1466 | </td> | ||
1467 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1468 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1469 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1470 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1471 | <p class=MsoNormal><o:p> </o:p></p> | ||
1472 | </td> | ||
1473 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1474 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1475 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1476 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1477 | <p class=MsoNormal><o:p> </o:p></p> | ||
1478 | </td> | ||
1479 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1480 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1481 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1482 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1483 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1484 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1485 | </td> | ||
1486 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1487 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1488 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1489 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1490 | padding:0in 5.4pt 0in 5.4pt'> | ||
1491 | <p class=MsoNormal><o:p> </o:p></p> | ||
1492 | </td> | ||
1493 | </tr> | ||
1494 | <tr style='mso-yfti-irow:16;page-break-inside:avoid'> | ||
1495 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1496 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1497 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1498 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1499 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1500 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1501 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1502 | </td> | ||
1503 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1504 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1505 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1506 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1507 | padding:0in 5.4pt 0in 5.4pt'> | ||
1508 | <p class=MsoNormal><o:p> </o:p></p> | ||
1509 | </td> | ||
1510 | </tr> | ||
1511 | <tr style='mso-yfti-irow:17;page-break-inside:avoid'> | ||
1512 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1513 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-alt: | ||
1514 | solid windowtext .75pt;mso-border-left-alt:solid windowtext .5pt;padding: | ||
1515 | 0in 5.4pt 0in 5.4pt'> | ||
1516 | <p class=MsoNormal><o:p> </o:p></p> | ||
1517 | </td> | ||
1518 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1519 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1520 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1521 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1522 | <p class=MsoNormal><o:p> </o:p></p> | ||
1523 | </td> | ||
1524 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1525 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1526 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1527 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1528 | <p class=MsoNormal><o:p> </o:p></p> | ||
1529 | </td> | ||
1530 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1531 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1532 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1533 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1534 | <p class=MsoNormal><o:p> </o:p></p> | ||
1535 | </td> | ||
1536 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1537 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1538 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1539 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1540 | <p class=MsoNormal><o:p> </o:p></p> | ||
1541 | </td> | ||
1542 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1543 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1544 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1545 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1546 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1547 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1548 | </td> | ||
1549 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1550 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1551 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1552 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1553 | padding:0in 5.4pt 0in 5.4pt'> | ||
1554 | <p class=MsoNormal><o:p> </o:p></p> | ||
1555 | </td> | ||
1556 | </tr> | ||
1557 | <tr style='mso-yfti-irow:18;page-break-inside:avoid'> | ||
1558 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1559 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1560 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1561 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1562 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1563 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1564 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1565 | </td> | ||
1566 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1567 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1568 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1569 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1570 | padding:0in 5.4pt 0in 5.4pt'> | ||
1571 | <p class=MsoNormal><o:p> </o:p></p> | ||
1572 | </td> | ||
1573 | </tr> | ||
1574 | <tr style='mso-yfti-irow:19;page-break-inside:avoid'> | ||
1575 | <td width=115 rowspan=2 valign=top style='width:1.2in;border:solid windowtext 1.0pt; | ||
1576 | border-top:none;mso-border-top-alt:solid windowtext .75pt;mso-border-top-alt: | ||
1577 | .75pt;mso-border-left-alt:.5pt;mso-border-bottom-alt:.5pt;mso-border-right-alt: | ||
1578 | .75pt;mso-border-color-alt:windowtext;mso-border-style-alt:solid;padding: | ||
1579 | 0in 5.4pt 0in 5.4pt'> | ||
1580 | <p class=MsoNormal><o:p> </o:p></p> | ||
1581 | </td> | ||
1582 | <td width=76 rowspan=2 valign=top style='width:56.9pt;border-top:none; | ||
1583 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1584 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1585 | mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt; | ||
1586 | padding:0in 5.4pt 0in 5.4pt'> | ||
1587 | <p class=MsoNormal><o:p> </o:p></p> | ||
1588 | </td> | ||
1589 | <td width=89 rowspan=2 valign=top style='width:66.4pt;border-top:none; | ||
1590 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1591 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1592 | mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt; | ||
1593 | padding:0in 5.4pt 0in 5.4pt'> | ||
1594 | <p class=MsoNormal><o:p> </o:p></p> | ||
1595 | </td> | ||
1596 | <td width=84 rowspan=2 valign=top style='width:63.0pt;border-top:none; | ||
1597 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1598 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1599 | mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt; | ||
1600 | padding:0in 5.4pt 0in 5.4pt'> | ||
1601 | <p class=MsoNormal><o:p> </o:p></p> | ||
1602 | </td> | ||
1603 | <td width=108 rowspan=2 valign=top style='width:81.0pt;border-top:none; | ||
1604 | border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1605 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1606 | mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt; | ||
1607 | padding:0in 5.4pt 0in 5.4pt'> | ||
1608 | <p class=MsoNormal><o:p> </o:p></p> | ||
1609 | </td> | ||
1610 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1611 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1612 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1613 | mso-border-alt:solid windowtext .75pt;padding:0in 5.4pt 0in 5.4pt'> | ||
1614 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1615 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'>Location<o:p></o:p></b></p> | ||
1616 | </td> | ||
1617 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1618 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1619 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1620 | mso-border-alt:solid windowtext .75pt;mso-border-right-alt:solid windowtext .5pt; | ||
1621 | padding:0in 5.4pt 0in 5.4pt'> | ||
1622 | <p class=MsoNormal><o:p> </o:p></p> | ||
1623 | </td> | ||
1624 | </tr> | ||
1625 | <tr style='mso-yfti-irow:20;mso-yfti-lastrow:yes;page-break-inside:avoid'> | ||
1626 | <td width=104 valign=top style='width:77.9pt;border-top:none;border-left: | ||
1627 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1628 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1629 | mso-border-alt:solid windowtext .75pt;mso-border-bottom-alt:solid windowtext .5pt; | ||
1630 | padding:0in 5.4pt 0in 5.4pt'> | ||
1631 | <p class=MsoNormal style='margin-top:2.0pt;margin-right:0in;margin-bottom: | ||
1632 | 2.0pt;margin-left:0in'><b style='mso-bidi-font-weight:normal'><span | ||
1633 | style='font-size:9.0pt'>Obtained from</span></b></p> | ||
1634 | </td> | ||
1635 | <td width=290 valign=top style='width:217.25pt;border-top:none;border-left: | ||
1636 | none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt; | ||
1637 | mso-border-top-alt:solid windowtext .75pt;mso-border-left-alt:solid windowtext .75pt; | ||
1638 | mso-border-top-alt:.75pt;mso-border-left-alt:.75pt;mso-border-bottom-alt: | ||
1639 | .5pt;mso-border-right-alt:.5pt;mso-border-color-alt:windowtext;mso-border-style-alt: | ||
1640 | solid;padding:0in 5.4pt 0in 5.4pt'> | ||
1641 | <p class=MsoNormal><o:p> </o:p></p> | ||
1642 | </td> | ||
1643 | </tr> | ||
1644 | </table> | ||
1645 | |||
1646 | <p class=MsoNormal><o:p> </o:p></p> | ||
1647 | |||
1648 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
1649 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
1650 | |||
1651 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
1652 | normal'><span style='font-size:12.0pt'><o:p> </o:p></span></b></p> | ||
1653 | |||
1654 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
1655 | normal'><span style='font-size:12.0pt'>Credits <o:p></o:p></span></b></p> | ||
1656 | |||
1657 | <p class=MsoNormal style='mso-outline-level:1'><span style='font-size:12.0pt'><o:p> </o:p></span></p> | ||
1658 | |||
1659 | <p class=MsoNormal style='mso-outline-level:1'><o:p> </o:p></p> | ||
1660 | |||
1661 | <p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight: | ||
1662 | normal'><span style='font-size:12.0pt'>Licenses <o:p></o:p></span></b></p> | ||
1663 | |||
1664 | <p class=MsoNormal><o:p> </o:p></p> | ||
1665 | |||
1666 | <p class=MsoNormal><o:p> </o:p></p> | ||
1667 | |||
1668 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1669 | 0pt'>/*<o:p></o:p></span></p> | ||
1670 | |||
1671 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1672 | 0pt'><span style='mso-spacerun:yes'> </span>* <span class=SpellE>ctoolsprof_srv_main.c</span><o:p></o:p></span></p> | ||
1673 | |||
1674 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1675 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1676 | |||
1677 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1678 | 0pt'><span style='mso-spacerun:yes'> </span>* <span class=SpellE>Ctools</span> | ||
1679 | Profiler Server Implementation<o:p></o:p></span></p> | ||
1680 | |||
1681 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1682 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1683 | |||
1684 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1685 | 0pt'><span style='mso-spacerun:yes'> </span>* Copyright (C) 2013 Texas | ||
1686 | Instruments Incorporated - http://www.ti.com/ <o:p></o:p></span></p> | ||
1687 | |||
1688 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1689 | 0pt'><span style='mso-spacerun:yes'> </span>* <o:p></o:p></span></p> | ||
1690 | |||
1691 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1692 | 0pt'><span style='mso-spacerun:yes'> </span>* <o:p></o:p></span></p> | ||
1693 | |||
1694 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1695 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1696 | style='mso-spacerun:yes'> </span>Redistribution</span> and use in source and | ||
1697 | binary forms, with or without <o:p></o:p></span></p> | ||
1698 | |||
1699 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1700 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1701 | style='mso-spacerun:yes'> </span>modification</span>, are permitted provided | ||
1702 | that the following conditions <o:p></o:p></span></p> | ||
1703 | |||
1704 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1705 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1706 | style='mso-spacerun:yes'> </span>are</span> met:<o:p></o:p></span></p> | ||
1707 | |||
1708 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1709 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1710 | |||
1711 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1712 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1713 | </span>Redistributions of source code must retain the above copyright <o:p></o:p></span></p> | ||
1714 | |||
1715 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1716 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1717 | </span><span class=GramE>notice</span>, this list of conditions and the | ||
1718 | following disclaimer.<o:p></o:p></span></p> | ||
1719 | |||
1720 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1721 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1722 | |||
1723 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1724 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1725 | </span>Redistributions in binary form must reproduce the above copyright<o:p></o:p></span></p> | ||
1726 | |||
1727 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1728 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1729 | </span><span class=GramE>notice</span>, this list of conditions and the | ||
1730 | following disclaimer in the <o:p></o:p></span></p> | ||
1731 | |||
1732 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1733 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1734 | </span><span class=GramE>documentation</span> and/or other materials provided | ||
1735 | with the<span style='mso-spacerun:yes'> </span><o:p></o:p></span></p> | ||
1736 | |||
1737 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1738 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1739 | </span><span class=GramE>distribution</span>.<o:p></o:p></span></p> | ||
1740 | |||
1741 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1742 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1743 | |||
1744 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1745 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1746 | </span>Neither the name of Texas Instruments Incorporated nor the names of<o:p></o:p></span></p> | ||
1747 | |||
1748 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1749 | 0pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'> | ||
1750 | </span><span class=GramE>its</span> contributors may be used to endorse or | ||
1751 | promote products derived<o:p></o:p></span></p> | ||
1752 | |||
1753 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1754 | 0pt'><span style='mso-spacerun:yes'> </span>* <span | ||
1755 | style='mso-spacerun:yes'> </span><span class=GramE>from</span> this software | ||
1756 | without specific prior written permission.<o:p></o:p></span></p> | ||
1757 | |||
1758 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1759 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1760 | |||
1761 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1762 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1763 | style='mso-spacerun:yes'> </span>THIS</span> SOFTWARE IS PROVIDED BY THE | ||
1764 | COPYRIGHT HOLDERS AND CONTRIBUTORS <o:p></o:p></span></p> | ||
1765 | |||
1766 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1767 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1768 | style='mso-spacerun:yes'> </span>"</span>AS IS" AND ANY EXPRESS OR | ||
1769 | IMPLIED WARRANTIES, INCLUDING, BUT NOT <o:p></o:p></span></p> | ||
1770 | |||
1771 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1772 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1773 | style='mso-spacerun:yes'> </span>LIMITED</span> TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
1774 | AND FITNESS FOR<o:p></o:p></span></p> | ||
1775 | |||
1776 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1777 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1778 | style='mso-spacerun:yes'> </span>A</span> PARTICULAR PURPOSE ARE DISCLAIMED. | ||
1779 | IN NO EVENT SHALL THE COPYRIGHT <o:p></o:p></span></p> | ||
1780 | |||
1781 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1782 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1783 | style='mso-spacerun:yes'> </span>OWNER</span> OR CONTRIBUTORS BE LIABLE FOR | ||
1784 | ANY DIRECT, INDIRECT, INCIDENTAL, <o:p></o:p></span></p> | ||
1785 | |||
1786 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1787 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1788 | style='mso-spacerun:yes'> </span>SPECIAL</span>, EXEMPLARY, OR CONSEQUENTIAL | ||
1789 | DAMAGES (INCLUDING, BUT NOT <o:p></o:p></span></p> | ||
1790 | |||
1791 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1792 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1793 | style='mso-spacerun:yes'> </span>LIMITED</span> TO, PROCUREMENT OF SUBSTITUTE | ||
1794 | GOODS OR SERVICES; LOSS OF USE,<o:p></o:p></span></p> | ||
1795 | |||
1796 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1797 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1798 | style='mso-spacerun:yes'> </span>DATA</span>, OR PROFITS; OR BUSINESS | ||
1799 | INTERRUPTION) HOWEVER CAUSED AND ON ANY<o:p></o:p></span></p> | ||
1800 | |||
1801 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1802 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1803 | style='mso-spacerun:yes'> </span>THEORY</span> OF LIABILITY, WHETHER IN | ||
1804 | CONTRACT, STRICT LIABILITY, OR TORT <o:p></o:p></span></p> | ||
1805 | |||
1806 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1807 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1808 | style='mso-spacerun:yes'> </span>(</span>INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
1809 | IN ANY WAY OUT OF THE USE <o:p></o:p></span></p> | ||
1810 | |||
1811 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1812 | 0pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span | ||
1813 | style='mso-spacerun:yes'> </span>OF</span> THIS SOFTWARE, EVEN IF ADVISED OF | ||
1814 | THE POSSIBILITY OF SUCH DAMAGE.<o:p></o:p></span></p> | ||
1815 | |||
1816 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1817 | 0pt'><span style='mso-spacerun:yes'> </span>*<o:p></o:p></span></p> | ||
1818 | |||
1819 | <p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning: | ||
1820 | 0pt'>*/<o:p></o:p></span></p> | ||
1821 | |||
1822 | </div> | ||
1823 | |||
1824 | </body> | ||
1825 | |||
1826 | </html> | ||
diff --git a/example_app/ctprof_ex.c b/example_app/ctprof_ex.c new file mode 100644 index 0000000..4e44a25 --- /dev/null +++ b/example_app/ctprof_ex.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * ctprof_ex.c | ||
3 | * | ||
4 | * Ctools Profiler Example Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <stdbool.h> | ||
42 | #include <getopt.h> | ||
43 | #include <stdint.h> | ||
44 | #include <sys/mman.h> | ||
45 | #include <fcntl.h> | ||
46 | #include "ctprof_utility.h" | ||
47 | |||
48 | const int g_major_version = 0; | ||
49 | const int g_minor_version = 1; | ||
50 | const int g_copyright_year = 2013; | ||
51 | |||
52 | FILE *g_stdout; | ||
53 | FILE *g_stderr; | ||
54 | char * g_whoami; | ||
55 | |||
56 | struct memory_blk_t{ | ||
57 | char * name; | ||
58 | uint32_t phy_addr; | ||
59 | void * v_addr; | ||
60 | size_t phy_size; | ||
61 | }; | ||
62 | |||
63 | struct memory_blk_t memory_table[] = { | ||
64 | {"Corepac L2_0", 0x10800000, 0, 1024*1024}, /* Corepac 0 L2 */ | ||
65 | {"Corepac L2_1", 0x11800000, 0, 1024*1024}, /* Corepac 1 L2 */ | ||
66 | {"Corepac L2_2", 0x12800000, 0, 1024*1024}, /* Corepac 2 L2 */ | ||
67 | {"Corepac L2_3", 0x13800000, 0, 1024*1024} /* Corepac 3 L2 */ | ||
68 | }; | ||
69 | |||
70 | const int zero_test_words = 65536; | ||
71 | const int memory_table_elements = sizeof(memory_table)/sizeof(struct memory_blk_t); | ||
72 | |||
73 | static struct option long_options[] = { | ||
74 | {"interations", required_argument, 0, 'i'}, | ||
75 | {"quiet", no_argument, 0,'q'}, | ||
76 | {"help", no_argument, 0, 'h'}, | ||
77 | {"version", no_argument, 0, 'v'} | ||
78 | }; | ||
79 | |||
80 | static char * short_options = "i:qhv"; | ||
81 | |||
82 | static int test_iterations = 1; | ||
83 | |||
84 | |||
85 | #define USE_SIGNALS 1 | ||
86 | |||
87 | int main(int argc, char *argv[]) | ||
88 | { | ||
89 | /* Intialize globals */ | ||
90 | g_stdout = stdout; | ||
91 | g_stderr = stderr; | ||
92 | g_whoami = argv[0]; | ||
93 | |||
94 | /* evaluate commamnd line */ | ||
95 | while (1) { | ||
96 | |||
97 | int option, option_index = 0; | ||
98 | |||
99 | option = getopt_long(argc, argv, short_options, long_options, &option_index); | ||
100 | |||
101 | if (option == -1) break; | ||
102 | |||
103 | switch (option) { | ||
104 | case 'i': | ||
105 | test_iterations = atoi(optarg); | ||
106 | break; | ||
107 | case 'q': | ||
108 | g_stdout = fopen("/dev/null", "w"); | ||
109 | break; | ||
110 | case 'h': | ||
111 | fprintf(g_stdout, "Usage: ctprof_ex [ihqv]\n"); | ||
112 | fprintf(g_stdout, " --iterations/-i <n> Run test n times\n"); | ||
113 | fprintf(g_stdout, " --help/-h Print this\n"); | ||
114 | fprintf(g_stdout, " --quiet/-q Send stdout to /dev/null\n"); | ||
115 | fprintf(g_stdout, " --version/-v Print version\n"); | ||
116 | fprintf(g_stdout, "\n"); | ||
117 | exit(0); | ||
118 | case 'v': | ||
119 | fprintf(g_stdout, "ctprof_ex version %d.%d\n", | ||
120 | g_major_version, g_minor_version); | ||
121 | fprintf(g_stdout, "Copyright (C) %d Texas Instruments, Inc.\n", | ||
122 | g_copyright_year); | ||
123 | exit(0); | ||
124 | break; | ||
125 | default: | ||
126 | fprintf(g_stderr,"Invalid option - try -h\n"); | ||
127 | exit(0); | ||
128 | } /* End of switch */ | ||
129 | |||
130 | }/* end of while*/ | ||
131 | |||
132 | /************************************************************/ | ||
133 | /* Wait until ctprof is recording to start */ | ||
134 | /************************************************************/ | ||
135 | if (ctprof_pipe_open() == -1) { | ||
136 | fprintf(g_stderr, "Can't open pipe to ctprof\n"); | ||
137 | exit(-1); | ||
138 | } | ||
139 | |||
140 | #if USE_SIGNALS | ||
141 | ctprof_ready_wait(); | ||
142 | ctprof_start_recording(); | ||
143 | #endif | ||
144 | ctprof_recording_wait(); | ||
145 | |||
146 | /************************************************************/ | ||
147 | /* Map each memory table element */ | ||
148 | /************************************************************/ | ||
149 | int mem_fd = open("/dev/mem", O_RDWR | O_SYNC | O_RSYNC ); | ||
150 | if (mem_fd == -1) { | ||
151 | fprintf(g_stderr, "Can't open /dev/mem\n"); | ||
152 | exit(-1); | ||
153 | } | ||
154 | |||
155 | for (int i = 0; i < memory_table_elements; i++) { | ||
156 | memory_table[i].v_addr = mmap(0, memory_table[i].phy_size, | ||
157 | PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, | ||
158 | memory_table[i].phy_addr); | ||
159 | |||
160 | mlock(memory_table[i].v_addr, memory_table[i].phy_size); | ||
161 | } | ||
162 | |||
163 | /************************************************************/ | ||
164 | /* Test Loop */ | ||
165 | /************************************************************/ | ||
166 | while (test_iterations != 0) { | ||
167 | |||
168 | fprintf(g_stdout, "\r%s:Test Iterations left %d\n", g_whoami, test_iterations); | ||
169 | |||
170 | /* This test writes zero to the first 64K words of each memory_table element */ | ||
171 | for (int i = 0; i < memory_table_elements; i++) { | ||
172 | |||
173 | #if USE_SIGNALS | ||
174 | if (i == 2) { | ||
175 | ctprof_end_recording(); | ||
176 | ctprof_stopped_wait(); | ||
177 | } | ||
178 | #endif | ||
179 | fprintf(g_stdout, "\r%s:Testing %d words of %s\n", g_whoami, zero_test_words, memory_table[i].name); | ||
180 | |||
181 | uint32_t * addr = (uint32_t *)memory_table[i].v_addr; | ||
182 | for (int n = 0; n < zero_test_words; n++) { | ||
183 | *addr++ = 0; | ||
184 | } | ||
185 | |||
186 | addr = (uint32_t *)memory_table[i].v_addr; | ||
187 | int test_failed_cnt = 0; | ||
188 | |||
189 | for (int n = 0; n < zero_test_words; n++) { | ||
190 | if (*addr++ != 0 ) { | ||
191 | test_failed_cnt++; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | fprintf(g_stdout, "\r%s:%s had %d failures\n", g_whoami, memory_table[i].name, test_failed_cnt); | ||
196 | |||
197 | } | ||
198 | test_iterations--; | ||
199 | |||
200 | } /* End of while*/ | ||
201 | |||
202 | fprintf(g_stdout, "\r%s:Exiting\n", g_whoami); | ||
203 | ctprof_pipe_close(); | ||
204 | exit(0); | ||
205 | } | ||
206 | |||
207 | |||
diff --git a/example_app/ctprof_utility.c b/example_app/ctprof_utility.c new file mode 100644 index 0000000..3d1320d --- /dev/null +++ b/example_app/ctprof_utility.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * ctprof_utility.c | ||
3 | * | ||
4 | * Ctools Profiler Utility Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <string.h> | ||
42 | #include <stdbool.h> | ||
43 | #include <unistd.h> | ||
44 | #include <fcntl.h> | ||
45 | #include <signal.h> | ||
46 | #include "ctprof_utility.h" | ||
47 | |||
48 | static char * fifo_filename = "ctprof_fifo"; | ||
49 | //static FILE * fp; | ||
50 | static int ctprof_pipe_fd; | ||
51 | static bool fifo_opened = false; | ||
52 | static char readbuf[32]; | ||
53 | |||
54 | /* State definitions | ||
55 | * ready - ctprof_srv is ready for a signal | ||
56 | * recording - ctprof_srv is recording | ||
57 | * stopped - ctprof_srv has stopped recording | ||
58 | */ | ||
59 | static const char msg_recording[] = "ctprof recording\n"; | ||
60 | static const char msg_stopped[] = "ctprof stopped\n"; | ||
61 | static const char msg_ready[] = "ctprof ready\n"; | ||
62 | |||
63 | |||
64 | |||
65 | /* Note: This implementation uses named pipes for very | ||
66 | * simple ipc. This could be changed in the future to | ||
67 | * use sockets or some other ipc so check the requirements | ||
68 | * for the version of ctprof you are using | ||
69 | */ | ||
70 | |||
71 | static pid_t ctprof_srv_pid; | ||
72 | |||
73 | int ctprof_pipe_open(void) | ||
74 | { | ||
75 | /* If fifo can't be opend then return -1 */ | ||
76 | if (!fifo_opened) { | ||
77 | if (-1 == (ctprof_pipe_fd = open(fifo_filename, O_RDONLY))) { | ||
78 | return -1; | ||
79 | } | ||
80 | fifo_opened = true; | ||
81 | } | ||
82 | |||
83 | read(ctprof_pipe_fd, &ctprof_srv_pid, sizeof(pid_t)); | ||
84 | |||
85 | } | ||
86 | |||
87 | void ctprof_pipe_close(void) | ||
88 | { | ||
89 | if (fifo_opened) { | ||
90 | close(ctprof_pipe_fd); | ||
91 | fifo_opened = false; | ||
92 | } | ||
93 | |||
94 | } | ||
95 | |||
96 | static pid_t ctprof_get_pid(void) | ||
97 | { | ||
98 | if (fifo_opened) { | ||
99 | return ctprof_srv_pid; | ||
100 | } else { | ||
101 | return -1; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | ctprof_state_t ctprof_get_state(void) | ||
106 | { | ||
107 | /* If the fifo opened sucessfully, then fgets should block | ||
108 | * until data is avaiable. | ||
109 | */ | ||
110 | if (fifo_opened) { | ||
111 | read(ctprof_pipe_fd, readbuf, sizeof(readbuf)); | ||
112 | |||
113 | if (0 == strcmp(readbuf, msg_recording)) { | ||
114 | return CTPROF_RECORDING; | ||
115 | } | ||
116 | if (0 == strcmp(readbuf, msg_stopped)) { | ||
117 | return CTPROF_STOPPED; | ||
118 | } | ||
119 | if (0 == strcmp(readbuf, msg_ready)) { | ||
120 | return CTPROF_READY; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | return -1; | ||
125 | |||
126 | } | ||
127 | |||
128 | void ctprof_ready_wait() | ||
129 | { | ||
130 | ctprof_state_t ctprof_state; | ||
131 | |||
132 | do { | ||
133 | |||
134 | ctprof_state = ctprof_get_state(); | ||
135 | |||
136 | if(ctprof_state == CTPROF_READY) { | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | } while (1); | ||
141 | } | ||
142 | |||
143 | void ctprof_recording_wait() | ||
144 | { | ||
145 | ctprof_state_t ctprof_state; | ||
146 | |||
147 | do { | ||
148 | |||
149 | ctprof_state = ctprof_get_state(); | ||
150 | |||
151 | if(ctprof_state == CTPROF_RECORDING) { | ||
152 | break; | ||
153 | } | ||
154 | |||
155 | } while (1); | ||
156 | } | ||
157 | |||
158 | void ctprof_stopped_wait() | ||
159 | { | ||
160 | ctprof_state_t ctprof_state; | ||
161 | |||
162 | do { | ||
163 | |||
164 | ctprof_state = ctprof_get_state(); | ||
165 | |||
166 | if(ctprof_state == CTPROF_STOPPED) { | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | } while (1); | ||
171 | } | ||
172 | |||
173 | /* Start recording with a signal*/ | ||
174 | void ctprof_start_recording() | ||
175 | { | ||
176 | kill(ctprof_get_pid(), SIGUSR1); | ||
177 | } | ||
178 | |||
179 | /* End recording for this session*/ | ||
180 | void ctprof_end_recording() | ||
181 | { | ||
182 | kill(ctprof_get_pid(), SIGUSR2); | ||
183 | } | ||
184 | |||
diff --git a/example_app/ctprof_utility.h b/example_app/ctprof_utility.h new file mode 100644 index 0000000..e062dce --- /dev/null +++ b/example_app/ctprof_utility.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * ctprof_utility.h | ||
3 | * | ||
4 | * Ctools Profiler Utility Interface | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #ifndef CTPROF_UTILITY_H | ||
39 | #define CTPROF_UTILITY_H | ||
40 | |||
41 | typedef enum { | ||
42 | CTPROF_READY, | ||
43 | CTPROF_STOPPED, | ||
44 | CTPROF_RECORDING, | ||
45 | } ctprof_state_t; | ||
46 | |||
47 | int ctprof_pipe_open(void); | ||
48 | void ctprof_pipe_close(void); | ||
49 | ctprof_state_t ctprof_get_state(void); | ||
50 | void ctprof_ready_wait(); | ||
51 | void ctprof_recording_wait(); | ||
52 | void ctprof_stopped_wait(); | ||
53 | void ctprof_start_recording(); | ||
54 | void ctprof_end_recording(); | ||
55 | |||
56 | #endif | ||
diff --git a/example_app/makefile b/example_app/makefile new file mode 100644 index 0000000..6371d48 --- /dev/null +++ b/example_app/makefile | |||
@@ -0,0 +1,71 @@ | |||
1 | # | ||
2 | # makefile for ctoolsprof server | ||
3 | # | ||
4 | # examples: | ||
5 | # make debug install | ||
6 | # make release install | ||
7 | # make clean debug install | ||
8 | # make clean release install OR make all | ||
9 | |||
10 | ifeq ($(findstring arm, $(MAKECMDGOALS)), arm) | ||
11 | CC= $(CROSS_COMPILE)gcc --static | ||
12 | else | ||
13 | CC = gcc | ||
14 | endif | ||
15 | |||
16 | ifeq ($(findstring debug, $(MAKECMDGOALS)), debug) | ||
17 | CFLAGS= -std=c99 -c -g -Wall $(INC_PATH) -D DEBUG -D _GNU_SOURCE $(TEST) | ||
18 | OBJDIR= ./debug | ||
19 | else | ||
20 | CFLAGS= -std=c99 -c -O2 $(INC_PATH) -D SERVER -D _GNU_SOURCE $(TEST) | ||
21 | OBJDIR= ./release | ||
22 | endif | ||
23 | LFLAGS = | ||
24 | LIBS= | ||
25 | LIB_PATH= | ||
26 | INCLUDE_PATH = -I ../example_app | ||
27 | |||
28 | .PHONY: clean debug release install arm | ||
29 | |||
30 | all: clean release install | ||
31 | |||
32 | # | ||
33 | # Declare.c and .h dependencies | ||
34 | # | ||
35 | ctprof_ex.o: ctprof_ex.c | ||
36 | ctprof_utility.o : ctprof_utility.h ctprof_utility.c | ||
37 | |||
38 | # | ||
39 | # Add objects | ||
40 | # | ||
41 | |||
42 | OBJECTS = $(addprefix $(OBJDIR)/, ctprof_ex.o ctprof_utility.o) | ||
43 | |||
44 | #.c.o: | ||
45 | # @echo "Compiling" $< | ||
46 | # $(CC) $(CFLAGS) $< | ||
47 | |||
48 | $(OBJDIR)/%.o: %.c | ||
49 | @echo "Compiling" $< | ||
50 | @mkdir -p $(OBJDIR) | ||
51 | $(CC) $(CFLAGS) $(INCLUDE_PATH) -o $@ $< | ||
52 | |||
53 | ctprof_ex: $(OBJECTS) | ||
54 | @echo "Building target" $@ | ||
55 | $(CC) $(LFLAGS) $(LIBS_PATH) -o $@ $(OBJECTS) $(LIBS) | ||
56 | |||
57 | debug: ctprof_ex | ||
58 | @echo "debug build complete" | ||
59 | |||
60 | release: ctprof_ex | ||
61 | @echo "release build complete" | ||
62 | |||
63 | arm: ctprof_ex | ||
64 | @echo "ARM version built" | ||
65 | |||
66 | install: | ||
67 | mv ctprof_ex ~/bin/ctprof_ex | ||
68 | |||
69 | clean: | ||
70 | -rm $(OBJECTS) | ||
71 | |||
diff --git a/server/ETBAddr.h b/server/ETBAddr.h new file mode 100644 index 0000000..2c812c6 --- /dev/null +++ b/server/ETBAddr.h | |||
@@ -0,0 +1,418 @@ | |||
1 | /**************************************************************************** | ||
2 | CToolsLib - ETB Library | ||
3 | |||
4 | Copyright (c) 2009-2012 Texas Instruments Inc. (www.ti.com) | ||
5 | All rights reserved. | ||
6 | |||
7 | Redistribution and use in source and binary forms, with or without | ||
8 | modification, are permitted provided that the following conditions | ||
9 | are met: | ||
10 | 1. Redistributions of source code must retain the above copyright | ||
11 | notice, this list of conditions and the following disclaimer. | ||
12 | 2. Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | 3. The name of the author may not be used to endorse or promote products | ||
16 | derived from this software without specific prior written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||
19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | ****************************************************************************/ | ||
29 | #ifndef __ETB_ADDR_H | ||
30 | #define __ETB_ADDR_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "C" { | ||
34 | #endif | ||
35 | |||
36 | /*! \file CSETBAddr.h | ||
37 | \version 1.2 | ||
38 | |||
39 | This file contains the ETB and TI Data Trace Formatter addresses. | ||
40 | The "n" parameter used for the address is a CPU enumeration for homogeneous multi-core devices. | ||
41 | For example, TCI6488 has n values as 0,1,3 for the three DSPs. | ||
42 | If a device does not have such multiple cores and associated ETBs, n is unused and should be 0. | ||
43 | where ETB is being programmed and accessed. | ||
44 | */ | ||
45 | |||
46 | /************************************************************************** | ||
47 | Device specific information | ||
48 | A new device can be supported by adding a device preprocessor | ||
49 | block specifying base addresses. | ||
50 | **************************************************************************/ | ||
51 | |||
52 | #if defined(TCI6612) || defined(TCI6614) || defined(TCI6616) || defined(TCI6618) \ | ||
53 | || defined(C6657) || defined(C6670) || defined(C6671) || defined(C6672) || defined(C6674) || defined(C6678) || defined(C66AK2Hxx) || defined(C66AK2Exx) && !defined(C66x) | ||
54 | |||
55 | #define C66x | ||
56 | |||
57 | #endif | ||
58 | |||
59 | #if defined(TCI6486) | ||
60 | #define NUM_ETB_INSTANCES 6 | ||
61 | #define DTF_PRESENT 1 | ||
62 | #define SYSETB_PRESENT 0 | ||
63 | |||
64 | /* ETB base address for different device types */ | ||
65 | #define _ETB_BaseAddress(n) ( 0x02C40000 + (n<<12) ) /* Base Address for ETB MMRs associated with GEMx */ | ||
66 | /* DTF MMR address. */ | ||
67 | #define DTF_CNTL(n) ( 0x02A80100 + (n << 4)) /* memory mapped address for DTF Control register for GEMx */ | ||
68 | |||
69 | #elif defined(TCI6488) | ||
70 | #define NUM_ETB_INSTANCES 3 | ||
71 | #define DTF_PRESENT 1 | ||
72 | #define SYSETB_PRESENT 0 | ||
73 | |||
74 | /* ETB base address for different device types */ | ||
75 | #define _ETB_BaseAddress(n) ( 0x02AD0000 + (n<<15) ) /* Base Address for ETB MMRs associated with GEMx */ | ||
76 | /* DTF MMR address. */ | ||
77 | #define DTF_CNTL(n) (0x02880400 + (n << 2)) /* memory mapped address for DTF Control register for GEMx */ | ||
78 | |||
79 | #elif defined(TCI6484) | ||
80 | #define NUM_ETB_INSTANCES 1 | ||
81 | #define DTF_PRESENT 1 | ||
82 | #define SYSETB_PRESENT 0 | ||
83 | |||
84 | /* ETB base address for different device types */ | ||
85 | #define _ETB_BaseAddress(n) (0x02AD0000) /* Base Address for ETB MMRs associated with GEMx */ | ||
86 | /* DTF MMR address */ | ||
87 | #define DTF_BASE(n) (0x02AD1000) | ||
88 | #define DTF_CNTL(n) (DTF_BASE(n) + 0x000) /* memory mapped address for DTF Control register for GEMx */ | ||
89 | #define TAGSET(n) (DTF_BASE(n) + 0xFA0) /* memory mapped address for DTF Control register for GEMx */ | ||
90 | #define TAGCLR(n) (DTF_BASE(n) + 0xFA4) /* memory mapped address for DTF Control register for GEMx */ | ||
91 | #define DTF_LOCK(n) (DTF_BASE(n) + 0xFB0) /* memory mapped address for DTF Control register for GEMx */ | ||
92 | #define DTF_LOCK_STATUS(n) (DTF_BASE(n) + 0xFB4) /* memory mapped address for DTF Control register for GEMx */ | ||
93 | #define ID(n) (DTF_BASE(n) + 0xFC8) /* memory mapped address for DTF Control register for GEMx */ | ||
94 | /* PSC MMR address */ | ||
95 | #define PSC_BASE (0x02AC0000) | ||
96 | #define PSC_MDCTL(n) (PSC_BASE+ 0xA00 + (4*n)) /* memory mapped address for Module Control Register for clock, reset and EMU behavior control */ | ||
97 | #define PSC_MDSTAT(n) (PSC_BASE+ 0x800 + (4*n)) /* memory mapped address for Module status register */ | ||
98 | #define PSC_PTCMD (PSC_BASE+ 0x120) /* memory mapped address for transition command register */ | ||
99 | #define PSC_PTSTAT (PSC_BASE+ 0x128) /* memory mapped address for transition command status register */ | ||
100 | |||
101 | #elif defined(C66x) | ||
102 | #define NUM_ETB_INSTANCES 9 /* For 6616, there are 4 DSP ETB and 1 SYS ETB. For 6678/6608, there are 8 DSP ETB and 1 SYS ETB */ | ||
103 | #define SYSETB_PRESENT 1 | ||
104 | #define SYS_ETB_ID 8 /* calculated to get system etb base address using _ETB_BaseAddress(n). For keystone2 devices, SYS_ETB_ID (TBR) | ||
105 | is not used to get system etb base address using _ETB_BaseAddress(n). */ | ||
106 | #ifndef __linux | ||
107 | #define DTF_PRESENT 1 | ||
108 | #define DMA_SUPPORT | ||
109 | #endif | ||
110 | |||
111 | #if defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
112 | /* Get ETB base address for different cores and system ETB */ | ||
113 | #define _ETB_BaseAddress(n) ((n==SYS_ETB_ID)?(0x03019000):(0x027D0000 + (n << 16))) /* Base Address for ETB MMRs associated with CorePACx and SYS ETB (TBR) */ | ||
114 | #else | ||
115 | #ifdef __linux | ||
116 | #define ETB_BaseAddress(n) (0x027D0000 + (n << 16)) | ||
117 | #define _ETB_BaseAddress(n) virtural_ETB_BaseAddress[n] | ||
118 | #define SIZEOF_ETB_SPACE 4096 | ||
119 | #else | ||
120 | /* Get ETB base address for different cores and system ETB */ | ||
121 | #define _ETB_BaseAddress(n) (0x027D0000 + (n << 16)) /* Base Address for ETB MMRs associated with CorePACx and SYS ETB*/ | ||
122 | #endif | ||
123 | #endif | ||
124 | |||
125 | /* Debug SS MIPI STM TBR DMA slave port address */ | ||
126 | #define TBR_RBD (0x02850000) | ||
127 | |||
128 | /* DTF MMR address */ | ||
129 | #ifdef __linux | ||
130 | #define DTF_BaseAddress(n) (0x02440000 + (n << 16)) | ||
131 | #define DTF_BASE(n) virtural_DTF_BaseAddress[n] | ||
132 | #define SIZEOF_DTF_SPACE 4096 | ||
133 | #else | ||
134 | #define DTF_BASE(n) (0x02440000 + (n << 16)) | ||
135 | #endif | ||
136 | #define DTF_CNTL(n) (DTF_BASE(n) + 0x000) /* memory mapped address for DTF Control register for C66x */ | ||
137 | #define TAGSET(n) (DTF_BASE(n) + 0xFA0) /* memory mapped address for DTF Control register for C66x */ | ||
138 | #define TAGCLR(n) (DTF_BASE(n) + 0xFA4) /* memory mapped address for DTF Control register for C66x */ | ||
139 | #define DTF_LOCK(n) (DTF_BASE(n) + 0xFB0) /* memory mapped address for DTF Control register for C66x */ | ||
140 | #define DTF_LOCK_STATUS(n) (DTF_BASE(n) + 0xFB4) /* memory mapped address for DTF Control register for C66x */ | ||
141 | #define ID(n) (DTF_BASE(n) + 0xFC8) /* memory mapped address for DTF Control register for C66x */ | ||
142 | |||
143 | /* PSC MMR address */ | ||
144 | #ifdef __linux | ||
145 | #define PSC_BaseAddress (0x02350000) | ||
146 | #define PSC_BASE virtural_PSC_BaseAddress | ||
147 | #define SIZEOF_PSC_SPACE 4096 | ||
148 | #else | ||
149 | #define PSC_BASE (0x02350000) | ||
150 | #endif | ||
151 | #define PSC_PDSTAT(n) (PSC_BASE + 0x200 + (4*n)) | ||
152 | #define PSC_PDCTL(n) (PSC_BASE + 0x300 + (4*n)) /* memory mapped address for Power Domain Control Register */ | ||
153 | #define PSC_MDCTL(n) (PSC_BASE + 0xA00 + (4*n)) /* memory mapped address for Module Control Register for clock, reset and EMU behavior control */ | ||
154 | #define PSC_MDSTAT(n) (PSC_BASE+ 0x800 + (4*n)) /* memory mapped address for Module status register */ | ||
155 | #define PSC_PTCMD (PSC_BASE + 0x120) /* memory mapped address for transition command register */ | ||
156 | #define PSC_PTSTAT (PSC_BASE + 0x128) /* memory mapped address for transition command status register */ | ||
157 | |||
158 | #elif defined(TI816x) | ||
159 | #define NUM_ETB_INSTANCES 1 | ||
160 | #define SYSETB_PRESENT 1 | ||
161 | #define SYS_ETB_ID 1 | ||
162 | |||
163 | /* ETB base address for different device types */ | ||
164 | // the variable 'n' is used as a dummy and always 'zero' is added to the base address. This is done to remove a compiler warning | ||
165 | #define _ETB_BaseAddress(n) ( 0x4B162000 + (0 << n) ) /* Base Address for ETB MMRs associated with TI81x - one ETB*/ | ||
166 | |||
167 | #if defined(ETM) | ||
168 | #define DTF_PRESENT 0 | ||
169 | #elif defined(DSP) | ||
170 | #define DTF_PRESENT 1 | ||
171 | #elif defined(STM) | ||
172 | #define DTF_PRESENT 0 | ||
173 | #endif | ||
174 | |||
175 | /* DTF MMR address */ | ||
176 | #define DTF_BASE(n) (0x4B166000 + (n << 16)) | ||
177 | #define DTF_CNTL(n) (DTF_BASE(n) + 0x000) /* memory mapped address for DTF Control register for C66x */ | ||
178 | #define TAGSET(n) (DTF_BASE(n) + 0xFA0) /* memory mapped address for DTF Control register for C66x */ | ||
179 | #define TAGCLR(n) (DTF_BASE(n) + 0xFA4) /* memory mapped address for DTF Control register for C66x */ | ||
180 | #define DTF_LOCK(n) (DTF_BASE(n) + 0xFB0) /* memory mapped address for DTF Control register for C66x */ | ||
181 | #define DTF_LOCK_STATUS(n) (DTF_BASE(n) + 0xFB4) /* memory mapped address for DTF Control register for C66x */ | ||
182 | #define ID(n) (DTF_BASE(n) + 0xFC8) /* memory mapped address for DTF Control register for C66x */ | ||
183 | |||
184 | #elif defined(OMAP3x)//OMAP3 | ||
185 | #define DTF_PRESENT 0 | ||
186 | #error Need to find out ETB base address from device data sheet for this device. | ||
187 | |||
188 | #elif defined(_OMAP) || defined(_OMAP54xx) | ||
189 | #define NUM_ETB_INSTANCES 1 | ||
190 | #define SYSETB_PRESENT 1 | ||
191 | #define SYS_ETB_ID 1 | ||
192 | |||
193 | #ifdef _OMAP | ||
194 | /* ETB base address for OMAP devices */ | ||
195 | // the variable 'n' is used as a dummy and always 'zero' is added to the base address. This is done to remove a compiler warning | ||
196 | #define _ETB_BaseAddress(n) ( 0x54162000 + (0 << n) ) /* Base Address for ETB MMRs - one ETB */ | ||
197 | #endif | ||
198 | |||
199 | #ifdef _OMAP54xx | ||
200 | /* TBR base address for OMAP54xx ES2 devices */ | ||
201 | /* Note that for OMAP5 ES1 the OMAP4430 A9 build will work - _OMAP */ | ||
202 | #define _ETB_BaseAddress(n) ( 0x54167000 ) /* Base Address for ETB MMRs - one ETB */ | ||
203 | #endif | ||
204 | |||
205 | #if defined(ETM) | ||
206 | #define DTF_PRESENT 0 | ||
207 | #elif defined(DSP) | ||
208 | #define DTF_PRESENT 1 | ||
209 | #elif defined(STM) | ||
210 | #define DTF_PRESENT 0 | ||
211 | #endif | ||
212 | |||
213 | #ifdef _OMAP54xx | ||
214 | #define ENABLE_ETB_FORMATTER | ||
215 | #endif | ||
216 | /* DTF (Trace Funnel) MMR address, Registers defined in CoreSight Components TRM */ | ||
217 | #define DTF_BASE(n) (0x54164000 + (n << 16)) | ||
218 | #define DTF_CNTL(n) (DTF_BASE(n) + 0x000) /* Funnel control register */ | ||
219 | #define TAGSET(n) (DTF_BASE(n) + 0xFA0) /* Claim Tag Set register */ | ||
220 | #define TAGCLR(n) (DTF_BASE(n) + 0xFA4) /* Claim Tag Clear register */ | ||
221 | #define DTF_LOCK(n) (DTF_BASE(n) + 0xFB0) /* Lock Access - WO */ | ||
222 | #define DTF_LOCK_STATUS(n) (DTF_BASE(n) + 0xFB4) /* Lock Status - RO */ | ||
223 | #define ID(n) (DTF_BASE(n) + 0xFC8) /* Device ID */ | ||
224 | |||
225 | #elif defined(TCI6612_CSETB) || defined(TCI6614_CSETB) | ||
226 | #define NUM_ETB_INSTANCES 1 | ||
227 | #define SYSETB_PRESENT 1 | ||
228 | #define SYS_ETB_ID 1 | ||
229 | #define DTF_PRESENT 0 | ||
230 | |||
231 | /* ETB base address for TCI6614 device */ | ||
232 | // the variable 'n' is used as a dummy and always 'zero' is added to the base address. This is done to remove a compiler warning | ||
233 | #define _ETB_BaseAddress(n) ( 0x025A6000 + (0 << n) ) /* Base Address for CS-ETB */ | ||
234 | |||
235 | #elif defined(C66AK2Hxx_CSSTM_ETB) || defined(C66AK2Exx_CSSTM_ETB) | ||
236 | |||
237 | #define NUM_ETB_INSTANCES 1 | ||
238 | #define SYSETB_PRESENT 1 | ||
239 | #define SYS_ETB_ID 1 | ||
240 | #define DTF_PRESENT 0 | ||
241 | #define DMA_SUPPORT | ||
242 | |||
243 | /* CSSTM ETB base address for Keystone2 devices */ | ||
244 | #define _ETB_BaseAddress(n) (0x03020000 + (n << 12)) /* Base Address for CSSTM-ETB, 'n' is the A15 MPU SS id. For keystone2, there is only one A15 MPU SS and n=0 */ | ||
245 | |||
246 | /* CSSTM TBR DMA slave port address */ | ||
247 | #define TBR_RBD (0x027D4000) | ||
248 | |||
249 | #if defined(C66AK2Hxx_CSSTM_ETB) | ||
250 | #define C66AK2Hxx | ||
251 | #elif defined(C66AK2Exx_CSSTM_ETB) | ||
252 | #define C66AK2Exx | ||
253 | #endif | ||
254 | |||
255 | #elif defined(C66AK2Hxx_CSSTM_ETB) || defined(C66AK2Exx_CSSTM_ETB) | ||
256 | |||
257 | #define NUM_ETB_INSTANCES 1 | ||
258 | #define SYSETB_PRESENT 1 | ||
259 | #define SYS_ETB_ID 1 | ||
260 | #define DTF_PRESENT 0 | ||
261 | |||
262 | /* CSSTM ETB base address for Keystone2 devices */ | ||
263 | #define _ETB_BaseAddress(n) (0x03020000 + (n << 12)) /* Base Address for CSSTM-ETB, 'n' is the A15 MPU SS id. For keystone2, there is only one A15 MPU SS and n=0 */ | ||
264 | |||
265 | /* CSSTM TBR DMA slave port address */ | ||
266 | #define TBR_RBD (0x027D4000) | ||
267 | |||
268 | #if defined(C66AK2Hxx_CSSTM_ETB) | ||
269 | #define C66AK2Hxx | ||
270 | #elif defined(C66AK2Exx_CSSTM_ETB) | ||
271 | #define C66AK2Exx | ||
272 | #endif | ||
273 | |||
274 | #else | ||
275 | #error No device type preprocessor defined for the ETBLib | ||
276 | #endif | ||
277 | |||
278 | |||
279 | |||
280 | |||
281 | /************************************************************************** | ||
282 | No changes need to be made below this point to support a new device | ||
283 | **************************************************************************/ | ||
284 | |||
285 | /* Registers common for both TI-ETB and TBR implementations*/ | ||
286 | |||
287 | /* ETB RAM Depth Register RDP */ | ||
288 | /* TBR RAM Size Register */ | ||
289 | #define ETB_RDP(n) (_ETB_BaseAddress(n) + 0x004) | ||
290 | /* ETB Status Register STS */ | ||
291 | /* TBR Status Register */ | ||
292 | #define ETB_STS(n) (_ETB_BaseAddress(n) + 0x00C) | ||
293 | /* ETB/TBR RAM Read Data Register RRD */ | ||
294 | #define ETB_RRD(n) (_ETB_BaseAddress(n) + 0x010) | ||
295 | /* ETB/TBR RAM Read Pointer Register RRP */ | ||
296 | #define ETB_RRP(n) (_ETB_BaseAddress(n) + 0x014) | ||
297 | /* ETB/TBR RAM Write Pointer Register RWP */ | ||
298 | #define ETB_RWP(n) (_ETB_BaseAddress(n) + 0x018) | ||
299 | /* ETB/TBR Trigger counter register */ | ||
300 | #define ETB_TRIG(n) (_ETB_BaseAddress(n) + 0x01C) | ||
301 | /* ETB/TBR Control Register CTL */ | ||
302 | #define ETB_CTL(n) (_ETB_BaseAddress(n) + 0x020) | ||
303 | /* ETB/TBR RAM Write Data Register RWD */ | ||
304 | #define ETB_RWD(n) (_ETB_BaseAddressn(n)+ 0x024) | ||
305 | /* ETB Formatter and Flush Status Register FFSR */ | ||
306 | /* TBR Operation Status Register OPSTAT */ | ||
307 | #define ETB_FFSR(n) (_ETB_BaseAddress(n) + 0x300) | ||
308 | /* ETB Formatter and Flush Control Register FFCR */ | ||
309 | /* TBR Operations Control Register OPCTRL*/ | ||
310 | #define ETB_FFCR(n) (_ETB_BaseAddress(n) + 0x304) | ||
311 | /* ETB/TBR Lock Access Register */ | ||
312 | #define ETB_LOCK(n) (_ETB_BaseAddress(n) + 0xFB0) | ||
313 | /* ETB/TBR Lock Status Register */ | ||
314 | #define ETB_LOCK_STATUS(n) (_ETB_BaseAddress(n) + 0xFB4) | ||
315 | /* ETB/TBR device ID Register */ | ||
316 | #define ETB_DEVID(n) (_ETB_BaseAddress(n) + 0xFC8) | ||
317 | |||
318 | /* Registers specific to TI-ETB implementation*/ | ||
319 | #define ETB_WIDTH(n) (_ETB_BaseAddress(n) + 0x008) /* ETB RAM Width Register STS */ | ||
320 | #define ETB_RBD(n) (_ETB_BaseAddress(n) + 0xA00) /* ETB RAM burst read Register */ | ||
321 | #define ETB_TI_CTL(n) (_ETB_BaseAddress(n) + 0xE20) /* ETB TI Control Register */ | ||
322 | #define ETB_IRST(n) (_ETB_BaseAddress(n) + 0xE00) /* ETB TI Interrupt Raw Status Register */ | ||
323 | #define ETB_ICST(n) (_ETB_BaseAddress(n) + 0xE04) /* ETB TI Interrupt Raw Status Register */ | ||
324 | #define ETB_IER(n) (_ETB_BaseAddress(n) + 0xE0C) /* ETB TI Interrupt Enable Register */ | ||
325 | #define ETB_IECST(n) (_ETB_BaseAddress(n) + 0xE10) /* Clear interrupt enable bits */ | ||
326 | |||
327 | /* Registers specific to TBR implementation */ | ||
328 | #define TBR_FIFOSZ(n) (_ETB_BaseAddress(n) + 0x008) /*TBR Output FIFO Size Register */ | ||
329 | #define TBR_OUTLVL(n) (_ETB_BaseAddress(n) + 0x100) /*Output FIFO Trigger Level Register */ | ||
330 | #define TBR_SICTRL(n) (_ETB_BaseAddress(n) + 0x104) /*TBR System Interface Control */ | ||
331 | #define TBR_IDPERIOD(n) (_ETB_BaseAddress(n) + 0x108) /*ID Repeat Period Register */ | ||
332 | #define TBR_SEQCNTL(n) (_ETB_BaseAddress(n) + 0x10C) /*Message Sequence Insertion Control */ | ||
333 | #define TBR_EOI(n) (_ETB_BaseAddress(n) + 0x120) /*TBR EOI register */ | ||
334 | #define TBR_IRQSTATUS_RAW(n) (_ETB_BaseAddress(n) + 0x124) /*TBR IRQ Status (Raw) register */ | ||
335 | #define TBR_IRQSTATUS(n) (_ETB_BaseAddress(n) + 0x128) /*TBR IRQ Status register */ | ||
336 | #define TBR_IRQENABLE_SET(n) (_ETB_BaseAddress(n) + 0x12C) /*TBR IRQ Enable set register */ | ||
337 | #define TBR_IRQENABLE_CLR(n) (_ETB_BaseAddress(n) + 0x130) /*TBR IRQ Enable clear register */ | ||
338 | #define TBR_CLAIMSET(n) (_ETB_BaseAddress(n) + 0xFA0) /*Claim Tag Set Register */ | ||
339 | #define TBR_CLAIMCLR(n) (_ETB_BaseAddress(n) + 0xFA4) /*Claim Tag Clear Register */ | ||
340 | #define TBR_AUTHSTAT(n) (_ETB_BaseAddress(n) + 0xFB8) /*Authorization Status Register */ | ||
341 | |||
342 | |||
343 | /* ETB enable bit */ | ||
344 | #define ETB_ENABLE 0x00000001 | ||
345 | /* ETB Status Register Bit definitions */ | ||
346 | #define ETB_STS_ACQCOMP 0x00000004 /* bit 2: 1=acquisition complete */ | ||
347 | #define ETB_STS_FULL 0x00000001 /* bit 0: 1=RAM full */ | ||
348 | /* ETB Formatter and Flush Status Register bits */ | ||
349 | #define ETB_FLUSH_INPROGRESS 0x00000001 /* bit 0: 1 = flush in progress */ | ||
350 | /* ETB unlock value */ | ||
351 | #define ETB_UNLOCK_VAL 0xC5ACCE55 /* Value to unlock ETB for register accesses */ | ||
352 | |||
353 | /* DTF values */ | ||
354 | #define LOCK_STATUS_IMP_BIT (1<<0) | ||
355 | #define LOCK_STATUS_STAT_BIT (1<<1) | ||
356 | #define DTF_ID_MAJOR_MASK (0xF<<4) | ||
357 | #define DTF_ID_MAJOR_VER1 (0x1<<4) | ||
358 | #define DTF_ID_MAJOR_VER2 (0x2<<4) | ||
359 | #define TI_ETB_CIRCULARMODE_BIT (0x1<<1) | ||
360 | #define TI_ETB_TI_MODE (0x1<<0) | ||
361 | |||
362 | #define TBR_BRIDGE_MODE (0x1<<1) | ||
363 | #define TBR_BUFFER_MODE (0xFFFFFFFD) | ||
364 | |||
365 | #define DTF_VER2_FLUSH_BIT (1<<7) | ||
366 | |||
367 | #define TI_ETB_IRST_UNDERFLOW (1 << 3) | ||
368 | #define TI_ETB_IRST_OVERFLOW (1 << 2) | ||
369 | #define TI_ETB_IRST_FULL (1 << 1) | ||
370 | #define TI_ETB_IRST_HALF_FULL (1 << 0) | ||
371 | |||
372 | #define TBR_IRST_AQCMP (1 << 1) | ||
373 | #define TBR_IRST_DAV (1 << 0) | ||
374 | #define TBR_STP_FULL (1 << 15) | ||
375 | |||
376 | #define TBR_TWP_DISABLE (0xFFFFFFFE) | ||
377 | #define TBR_TWP_ENABLE (0x1) | ||
378 | |||
379 | #define TBR_TWP_IDPERIOD (0x8) | ||
380 | |||
381 | #define TBR_TWP_SEQATBID (0x6F << 16) | ||
382 | #define TBR_TWP_SEQPERIOD (0x10) | ||
383 | |||
384 | /* TBR Operations Control Register (OPCTRL)bits */ | ||
385 | #define TBR_OUTFLUSH_INPROGRESS (1<<16) /* bit 16: 1 = output flush in progress */ | ||
386 | #define TBR_OUTFLUSH_START (1<<16) /* set bit 16 = 1 : output flush in started */ | ||
387 | |||
388 | /* TBR Status Register(STAT) bits */ | ||
389 | #define TBR_DRAIN_INPROGRESS (1<<4) /* bit 4: 1 = DMA drain in progress */ | ||
390 | |||
391 | /* TBR System interface control (SICTRL) register */ | ||
392 | #define TBR_READ_REQ_PENDING (1<<1) | ||
393 | |||
394 | #if defined(C66AK2Hxx_CSSTM_ETB) || defined(C66AK2Exx_CSSTM_ETB) | ||
395 | |||
396 | #define TBR_NUMBLOCK (0xF) | ||
397 | #define TBR_BLOCKSZ (0x1F) | ||
398 | |||
399 | #else | ||
400 | |||
401 | #define TBR_NUMBLOCK (0xF) | ||
402 | #define TBR_BLOCKSZ (0x3F) | ||
403 | |||
404 | #endif | ||
405 | |||
406 | /* TI-ETB and TBR device identifiers */ | ||
407 | #define ETB_DEVICE_ID (0x20) | ||
408 | #define TBR_DEVICE_ID (0x11) | ||
409 | |||
410 | |||
411 | /* ETB Maximum Burst Size value */ | ||
412 | #define ETB_BURST_SIZE 0x400 | ||
413 | |||
414 | #ifdef __cplusplus | ||
415 | } | ||
416 | #endif | ||
417 | |||
418 | #endif //__ETB_ADDR_H | ||
diff --git a/server/ETBInterface.h b/server/ETBInterface.h new file mode 100644 index 0000000..7e5ce61 --- /dev/null +++ b/server/ETBInterface.h | |||
@@ -0,0 +1,506 @@ | |||
1 | #ifndef __ETB_INTERFACE_H | ||
2 | #define __ETB_INTERFACE_H | ||
3 | |||
4 | #include <stdint.h> /*ANSI C99 specific type definitions */ | ||
5 | /* | ||
6 | * Embedded Trace Buffer (ETB) API | ||
7 | * | ||
8 | * Copyright (C) 2009-2012 Texas Instruments Incorporated - http://www.ti.com/ | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
20 | * its contributors may be used to endorse or promote products derived | ||
21 | * from this software without specific prior written permission. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
26 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
27 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
28 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
29 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | #ifdef __cplusplus | ||
38 | extern "C" { | ||
39 | #endif | ||
40 | |||
41 | /*! \file ETBInterface.h | ||
42 | \version 1.7 | ||
43 | Application Access to Embedded Trace Buffer. | ||
44 | |||
45 | This module allows users to program ETB debug hardware. | ||
46 | */ | ||
47 | /* The mainpage for doxygen has been added to the end of this file */ | ||
48 | |||
49 | /*! \par ETBLIB_MAJOR_VERSION | ||
50 | ETBLib major revision. This number will be changed for API modifications. | ||
51 | */ | ||
52 | #define ETBLIB_MAJOR_VERSION (0x1) | ||
53 | |||
54 | /*! \par ETBLIB_MINOR_VERSION | ||
55 | ETBLib minor revision. This number will be changed for bug fixes. | ||
56 | */ | ||
57 | #define ETBLIB_MINOR_VERSION (0xD) | ||
58 | |||
59 | /*! \par SYS_ETB | ||
60 | If the ETB is for System Trace (STM), use SYS_ETB as a coreID. | ||
61 | */ | ||
62 | #define SYS_ETB 0xFF | ||
63 | |||
64 | #if defined(TCI6612) || defined(TCI6614) || defined(TCI6616) || defined(TCI6618) && !defined(C6670) | ||
65 | #define C6670 | ||
66 | #endif | ||
67 | |||
68 | #if defined(C6671) || defined(C6672) || defined(C6674) && !defined(C6678) | ||
69 | #define C6678 | ||
70 | #endif | ||
71 | |||
72 | |||
73 | /*! \par eETB_Error | ||
74 | Common function return error enumeration. | ||
75 | */ | ||
76 | typedef enum _eETB_Error | ||
77 | { | ||
78 | |||
79 | eETB_Success = 0, /*!< Function completed successfully */ | ||
80 | eETB_Error_Bad_Param = -1, /*!< Error, method parameter error */ | ||
81 | eETB_Error_Program = -2, /*!< Error, Error programming hardware */ | ||
82 | eETB_Error_Cannot_Own = -3, /*!< Error, Error programming hardware, ownership cannot be taken */ | ||
83 | eETB_Error_Cannot_Read = -4, /*!< Error, Cannot read ETB as ETB is not in a readable state */ | ||
84 | eETB_Error_Cannot_Write = -5, /*!< Error, Cannot write ETB as ETB is not in a writabe state */ | ||
85 | eETB_Error_Psc_Enabling = -6, /*!< Error, Error programming hardware, Cannot enable PSC modules for ETB */ | ||
86 | eETB_Overflow = -7, /*!< Error, Read Overflow - TI Mode only */ | ||
87 | eETB_Underflow = -8 /*!< Error. Read Underflow - TI Mode only */ | ||
88 | } eETB_Error ; | ||
89 | |||
90 | |||
91 | /*! \par ETB_errorCallback | ||
92 | The callback function is called with the function's exit status. Note that this function is not exported | ||
93 | by the interface, but is used as a parameter for calls. | ||
94 | |||
95 | \param[in] eETB_Error error returned by calling routine. | ||
96 | \return void | ||
97 | |||
98 | \par Details: | ||
99 | \details | ||
100 | This is a user provided callback normally used to centralize error handling and error is desired to be handled in a | ||
101 | callback routine provided by the caller instead a return error code. | ||
102 | */ | ||
103 | typedef void(*ETB_errorCallback)(eETB_Error); | ||
104 | |||
105 | |||
106 | /*! \par eETB_Mode | ||
107 | Type of ETB mode. This is used to define ETB mode during an ETB_open call. | ||
108 | This mode should be very carefully selected as per the actual ETB on chip. | ||
109 | */ | ||
110 | typedef enum _eETB_Mode | ||
111 | { | ||
112 | eETB_Circular = 0, /*!< Circular mode for ETB11, CSETB, TI ETB. Only circular buffer mode and can't be read while capturing*/ | ||
113 | eETB_TI_Mode = 1, /*!< For TI-ETB implemetation, this is TI ETB mode (simultaneneous read/write) with a circular buffer mode | ||
114 | For Keystone2 SYS ETB and CSSTM ETB, provides circular buffer mode with no support for simultaneneous read/write of ETB buffer*/ | ||
115 | eETB_Stop_Buffer = 2, /*!< Stop on buffer full mode*/ | ||
116 | eETB_TI_Mode_AND_Stop_Buffer = 3 /*!< For TI-ETB implemetation, this is TI ETB mode (simultaneneous read/write) with stop on buffer full mode | ||
117 | For Keystone2 SYS ETB and CSSTM ETB, provides stop on buffer full mode with no support for simultaneneous read/write of ETB buffer */ | ||
118 | } eETB_Mode ; | ||
119 | |||
120 | /*! \par eDMA_Mode | ||
121 | Type of DMA mode. This is used to define the DMA mode during a DMA configuraion. | ||
122 | */ | ||
123 | typedef enum _eDMA_Mode | ||
124 | { | ||
125 | eDMA_Circular = 0, /*!< Circular mode */ | ||
126 | eDMA_Stop_Buffer = 1 /*!< Stop on buffer full mode */ | ||
127 | } eDMA_Mode ; | ||
128 | |||
129 | /*! \par eCIC_Select | ||
130 | The Chip-level Interrupt Controller number values. | ||
131 | */ | ||
132 | typedef enum _eCIC_Select | ||
133 | { | ||
134 | eCIC_0, | ||
135 | eCIC_1, | ||
136 | eCIC_2, | ||
137 | eCIC_3 | ||
138 | } eCIC_Select; | ||
139 | |||
140 | /*! \par DMAConfig | ||
141 | \brief DMA configuration structure | ||
142 | */ | ||
143 | typedef struct _DMAConfig | ||
144 | { | ||
145 | #if defined(C6670) || defined(C6678) | ||
146 | |||
147 | uint32_t cc; /*!< EDMA3 channel controller number. Only applicable for C6670 and C6678 devices. */ | ||
148 | uint16_t clrChannel; /*!< 1st DMA channel number for DMA draining (needs to | ||
149 | be able to access CPINTC). Application must have | ||
150 | configured the channel to PaRAM mapping for this | ||
151 | channel before using this API. Only applicable for C6670 and C6678 devices. | ||
152 | */ | ||
153 | uint16_t etbChannel; /*!< 2nd DMA channel number for DMA draining (needs to | ||
154 | be able to access the ETB). Application must have | ||
155 | configured the channel to PaRAM mapping for this | ||
156 | channel before using this API. Only applicable for C6670 and C6678 devices. | ||
157 | */ | ||
158 | eCIC_Select cic; /*!< External chip level interrupt controller INTCx, | ||
159 | also called Chip Interrupt Controller CICx. | ||
160 | Selection from the eCIC_Select enumeration. | ||
161 | Only applicable for C6670 and C6678 devices. | ||
162 | */ | ||
163 | |||
164 | #endif | ||
165 | |||
166 | uint16_t linkparam[3]; /*!< 3 additional parameter RAM entry numbers (used for | ||
167 | linking by the library). Thses must be different | ||
168 | PaRAM entries than thos mapped to channel 1 & 2. | ||
169 | */ | ||
170 | uint32_t dbufAddress; /*!< DMA Drain buffer address */ | ||
171 | uint32_t dbufWords; /*!< DMA Drain buffer size in 32-bit words */ | ||
172 | eDMA_Mode mode; /*!< DMA Drain buffer mode (only eDMA_Circular and | ||
173 | eDMA_Stop_Buffer are valid values) | ||
174 | */ | ||
175 | } DMAConfig; | ||
176 | |||
177 | /*! \par DMAStatus | ||
178 | \brief DMA status structure | ||
179 | \details | ||
180 | This structure is populated in the ETB_flush_dma function to provide the | ||
181 | address for the beginning of the circular buffer and the number of words | ||
182 | that have been transferred into it. The buffer address and size that are | ||
183 | provided in the DMA configuration structure is duplicated here to provide | ||
184 | all of the information required to manage reading the circular buffer. | ||
185 | */ | ||
186 | typedef struct _DMAStatus | ||
187 | { | ||
188 | uint32_t startAddr; /*!< Current starting lcoation address in DMA drain | ||
189 | buffer. | ||
190 | */ | ||
191 | uint32_t availableWords; /*!< Total number of 32-bit words that have been written | ||
192 | into the DMA drain buffer. | ||
193 | */ | ||
194 | uint32_t isWrapped; /*!< DMA Drain buffer is full and has started writing | ||
195 | over previously written words. | ||
196 | */ | ||
197 | uint32_t dbufAddress; /*!< DMA Drain buffer address */ | ||
198 | uint32_t dbufWords; /*!< DMA Drain buffer size in 32-bit words */ | ||
199 | uint32_t flushRequired; /*!< Only allow flushing ETB once related to DMA */ | ||
200 | } DMAStatus; | ||
201 | |||
202 | /*! \par ETBHandle | ||
203 | ETB Handle object. This is an incomplete structure, thus making the actual implementation | ||
204 | private to the ETBLib. | ||
205 | */ | ||
206 | |||
207 | typedef struct _ETBHandle_t ETBHandle; | ||
208 | |||
209 | /*! \par ETBHandle_Pntr | ||
210 | Pointer to a ETB Handle object | ||
211 | */ | ||
212 | |||
213 | typedef ETBHandle * ETBHandle_Pntr; | ||
214 | |||
215 | /*! \par ETBStatus | ||
216 | \brief ETB status structure definition. | ||
217 | */ | ||
218 | typedef struct _ETBStatus | ||
219 | { | ||
220 | uint8_t canRead; /*!< ETB can be read*/ | ||
221 | uint8_t isWrapped; /*!< ETB is wrapped */ | ||
222 | uint32_t availableWords; /*!< ETB has the available words to be read */ | ||
223 | uint32_t ETB_TraceCaptureEn; /*!< ETB trace capture is enabled or not */ | ||
224 | uint32_t overflow; /*!< ETB overflow occurred (only used if trying to read | ||
225 | while writting the ETB in non-DMA mode) */ | ||
226 | } ETBStatus; | ||
227 | |||
228 | /*! \par ETBCapability | ||
229 | \brief ETB status structure definition. | ||
230 | */ | ||
231 | typedef struct _ETBProperties | ||
232 | { | ||
233 | uint8_t is_dma_supported; /*!< ETB-EDMA extension supported or not*/ | ||
234 | |||
235 | }ETBProperties; | ||
236 | |||
237 | /*! \par ETB_open | ||
238 | \brief Open and initialize ETB. | ||
239 | |||
240 | \param[in] pErrCallBack is called if not NULL and this function returns any eETB_Error value other than eETB_Success. | ||
241 | \param[in] mode is the mode in which ETB should be used. Most commonly it is eETB_Circular. | ||
242 | \param[in] coreID core ID (0,1,2....) for a device with homogeneous DSPs or CPUs. For example, TCI6488 would have this parameter as 0,1, or 2. For device with no such multiple cores and associated ETBs, its should be defeulted to 0. | ||
243 | If the ETB is for System Trace (STM), use SYS_ETB as a coreID. | ||
244 | \param[out] ppHandle is pointer to a ETBhandle pointer, the pointer is allocated by the ETBLib so caller should not allocate the pointer. This should be passed back to "ETB_close()" call, once done. | ||
245 | \param[out] pETBSizeInWords contains size of ETB buffer in 32 bit words, if successfully opened. | ||
246 | \return eETB_Error. | ||
247 | |||
248 | \par Details: | ||
249 | \details | ||
250 | This function must be called as the very first call to initialize ETB module access. | ||
251 | The return value is NULL, if failed. | ||
252 | An allocated handle pointer is returned, if success. | ||
253 | */ | ||
254 | eETB_Error ETB_open(ETB_errorCallback pErrCallBack, eETB_Mode mode, uint8_t coreID, ETBHandle** ppHandle, uint32_t* pETBSizeInWords); | ||
255 | |||
256 | |||
257 | /*! \par ETB_enable | ||
258 | Enable ETB to start capturing data. | ||
259 | |||
260 | \param[in] pETBHandle ETB Handle pointer. | ||
261 | \param[in] triggerCount is number of words written to ETB RAM following a trigger event. This is only used for ARM. Use 0 for DSP. | ||
262 | \return eETB_Error. | ||
263 | |||
264 | \par Details: | ||
265 | \details | ||
266 | This function enables ETB. As soon as ETB is enabled, it starts capturing trace data. | ||
267 | The ETB should be enabled after trace export, clocks and data trace formatter (if applicable) has been programmed. | ||
268 | */ | ||
269 | eETB_Error ETB_enable(ETBHandle* pETBHandle, uint32_t triggerCount); | ||
270 | |||
271 | /*! \par ETB_disable | ||
272 | Disable ETB to stop capturing data. | ||
273 | |||
274 | \param[in] pETBHandle ETB Handle pointer. | ||
275 | \return eETB_Error. | ||
276 | |||
277 | \par Details: | ||
278 | \details | ||
279 | This function disables ETB. As soon as ETB is disabled, it stops capturing trace data. | ||
280 | A CoreSight ETB is ready to be read once it is disabled. | ||
281 | A TI ETB in TI_ETB mode does not need to be disabled before reading out the ETB contents. | ||
282 | */ | ||
283 | eETB_Error ETB_disable(ETBHandle* pETBHandle); | ||
284 | |||
285 | /*! \par ETB_status | ||
286 | Function to check the ETB status to check if it is ready to be read. | ||
287 | |||
288 | \param[in] pETBHandle ETB Handle pointer. | ||
289 | \param[out] status contains ETB status parameters. | ||
290 | \return eETB_Error. | ||
291 | |||
292 | \par Details: | ||
293 | \details | ||
294 | This function provides information ETB state. | ||
295 | Before making a call to ETB_read , it is expected to call this method to get the state of the ETB. | ||
296 | */ | ||
297 | eETB_Error ETB_status(ETBHandle* pETBHandle, ETBStatus* status); | ||
298 | |||
299 | /*! \par ETB_read | ||
300 | Function to read out ETB RAM contents. | ||
301 | |||
302 | \param[in] pETBHandle ETB Handle pointer. | ||
303 | \param[in] pBuffer an allocated buffer pointer passed in that would contain ETB buffer on return. | ||
304 | \param[in] bufferLength is the size of the allocated buffer in 32 bit long words unit. | ||
305 | \param[in] startWord is the index (0 based) of the ETB word to start reading. ETB_canread() provides number of available words. Use 0 for reading from a valid start of buffer. | ||
306 | \param[in] requestSize is the requested number of words to be read from the ETB. | ||
307 | \param[out] pRetSize contains the actual number of read words and retured as part of pBuffer. | ||
308 | \return eETB_Error. | ||
309 | |||
310 | \par Details: | ||
311 | \details | ||
312 | This function reads ETB contents, if the ETB can be read. | ||
313 | Caller of this function is responsible to allocate and deallocate the buffer. | ||
314 | If the request size is more than available ETB words and the buffer size is at least the request size, request sise is returned. | ||
315 | If the buffer is NULL or allocated size is less than the requested words, an error is returned. | ||
316 | |||
317 | \note | ||
318 | If using the DMA drain buffer, ETB_flush_dma <b>MUST</b> be called before | ||
319 | using this read function. | ||
320 | |||
321 | */ | ||
322 | eETB_Error ETB_read(ETBHandle* pETBHandle, uint32_t *pBuffer, uint32_t bufferLength, uint32_t startWord, uint32_t requestSize, uint32_t* pRetSize); | ||
323 | |||
324 | /*! \par ETB_close | ||
325 | Function to close the ETB and relese ETB handle pointer. | ||
326 | |||
327 | \param[in] pETBHandle ETB Handle pointer. | ||
328 | \return eETB_Error | ||
329 | |||
330 | \par Details: | ||
331 | \details | ||
332 | This function should be the last call made once your are done with the ETB. | ||
333 | After closing th ETB, ETB_open call is requuired before ETB can be used again. | ||
334 | */ | ||
335 | eETB_Error ETB_close(ETBHandle* pETBHandle); | ||
336 | |||
337 | /*! \par ETB_flush | ||
338 | Flush the ETB. | ||
339 | |||
340 | \param[in] pHandle ETB Handle pointer. | ||
341 | \return eETB_Error. | ||
342 | |||
343 | \par Details: | ||
344 | \details | ||
345 | This function flushes the ETB input buffer and ADTF. If you have temporarily stopped trace export | ||
346 | with TEND, the flush will provide the end of the current trace packet, avoiding the "insufficient | ||
347 | data" error when decoding. | ||
348 | |||
349 | If DSP Core-ETB is configured in EDMA mode, the ADTF is both flushed and stopped by ETB_flush(). | ||
350 | If DSP Core-ETB is configured in non-EDMA mode, only the ADTF is flushed by ETB_flush(). In this case | ||
351 | the ADTF is stopped in the ETB_disable function. | ||
352 | If System ETB is configured either in EDMA or non-EDMA mode, STM data is flushed to the ETB by ETB_flush(). | ||
353 | |||
354 | This function is only valid if the library has been opened in TI mode. | ||
355 | Note that if you are not in TI mode the ETB_disable function performs the flush operation. | ||
356 | |||
357 | Note: When the ETB is configured in EDMA mode, ETB_flush() must be called prior to ETB_flush_dma(). | ||
358 | |||
359 | */ | ||
360 | eETB_Error ETB_flush(ETBHandle* pHandle); | ||
361 | |||
362 | /*! \par ETB_config_dma | ||
363 | Configure the DMA used to interface with the ETB. | ||
364 | |||
365 | \param[in] pHandle | ||
366 | \param[in] pConfig | ||
367 | \return eETB_Error. | ||
368 | |||
369 | \par Details: | ||
370 | \details | ||
371 | This function is passed a configuration structure that is used to setup the | ||
372 | EDMA3 to transfer data written into the ETB to a location in memory. The | ||
373 | ETB half-full and full interrupts are used as system events to start each | ||
374 | transaction. The interrupts are routed from the ETB through the chip-level | ||
375 | INTCx (interrupt controller) to an input event in the EDMA3. Two DMA channels | ||
376 | are required, one for clearing the INTCx system interrupt status register, | ||
377 | and the second for transferring data from the ETB to the drain buffer in | ||
378 | memory. | ||
379 | |||
380 | ETB_open must be called before this configuration function with the option | ||
381 | eETB_TI_Mode. Any other option will cause this function to return in error. | ||
382 | |||
383 | \note The application is responsible for all DMA channel and parameter | ||
384 | RAM mapping and configuration. | ||
385 | |||
386 | */ | ||
387 | |||
388 | eETB_Error ETB_config_dma(ETBHandle* pHandle, const DMAConfig *pConfig); | ||
389 | |||
390 | /*! \par ETB_flush_dma | ||
391 | Configure a DMA transfer to flush remaining words in ETB to memory buffer. | ||
392 | |||
393 | \param[in] pHandle | ||
394 | \param[in] pStatus | ||
395 | \return eETB_Error. | ||
396 | |||
397 | \par Details: | ||
398 | \details | ||
399 | This function is used to copy any remaining information in the ETB that | ||
400 | has not reached the half-full or full mark in the buffer. Status information | ||
401 | is populated in the DMAStatus structure that can be used to manage collecting | ||
402 | information from the drain buffer in memory. | ||
403 | |||
404 | The DMA drain functions will only use a multiple of half of the the ETB | ||
405 | size. If the number of words that is passed as part of the DMA configuration | ||
406 | is not a multiple of half the ETB size, the DMA status value in the handle | ||
407 | will get set to the number of words that are actually being used. | ||
408 | |||
409 | |||
410 | \note | ||
411 | The application must have stopped all tracing and ETB_flush function must be | ||
412 | called before this function. | ||
413 | |||
414 | */ | ||
415 | eETB_Error ETB_flush_dma(ETBHandle* pHandle, DMAStatus *pStatus); | ||
416 | |||
417 | /*! \par ETB_setDmaStatus | ||
418 | Set the DMAStatus structure used by the DMA library functions. | ||
419 | |||
420 | \param[in] pHandle | ||
421 | \param[in] pStatus | ||
422 | |||
423 | \par Details: | ||
424 | \details | ||
425 | When using the DMA drain functionality with multiple DMA buffers, this | ||
426 | function is required to set the correct status parameters before making | ||
427 | dependent API calls such as ETB_read. | ||
428 | |||
429 | */ | ||
430 | void ETB_setDmaStatus(ETBHandle* pHandle, DMAStatus *pStatus); | ||
431 | |||
432 | /*! \par ETB_getProperties | ||
433 | Set the properties(capabilties supported) by the ETB. | ||
434 | |||
435 | \param[in] pProperties | ||
436 | |||
437 | \par Details: | ||
438 | \details | ||
439 | This API can be used by the application to determine the capabilities | ||
440 | supported by ETB of a particular device. For example: The Application | ||
441 | can determine whether ETB-DMA extension is supported or not. | ||
442 | */ | ||
443 | void ETB_getProperties(ETBProperties *pProperties); | ||
444 | |||
445 | #ifdef __cplusplus | ||
446 | } | ||
447 | #endif | ||
448 | |||
449 | #endif //__ETB_INTERFACE_H | ||
450 | |||
451 | /******************************************************************************/ | ||
452 | /* ***** DOXYGEN ***** */ | ||
453 | /******************************************************************************/ | ||
454 | /*! \mainpage | ||
455 | \par Introduction | ||
456 | The ETB Library provides an application interface to program and drain the | ||
457 | Embedded Trace Buffer (ETB). There are two kinds of ETB in TI devices, CSETB and | ||
458 | TIETB. The ETBLib contains CCSv5 projects in the ETBLib/project directory | ||
459 | specifying the supported devices and rules to pickup specific files and flags | ||
460 | for different devices. \n\n | ||
461 | For C66xx devices using the TIETB in TI mode (enabling the ETB to be read while | ||
462 | enabled and actively getting written) there is also an option to use the EDMA3 | ||
463 | to drain the ETB to specified memory buffer. | ||
464 | |||
465 | \par EDMA3 Drain Buffer | ||
466 | The DMA drain buffer is used to increase the amount of storage used for | ||
467 | trace data beyond the size of the ETB. The DMA uses the half-full and full | ||
468 | interrupt from the ETB as a trigger to start a transaction that will read half | ||
469 | of the ETB for each interrupt. For all Keystone1 devices except C6657, The ETB | ||
470 | interrupts must get routed through the chip-level interrupt controller (INTCx) | ||
471 | to interface with the EDMA3 controller. Where as in case of all keystone2 and | ||
472 | C6657, the ETB half and full events are directly connected to the EDMA3 controller. | ||
473 | \n\n | ||
474 | \subpage edma3_page | ||
475 | \n | ||
476 | \note If the Drain Buffer is located in MSMC or DDR3 memory, it should be put in | ||
477 | a non-cacheable region. | ||
478 | \n | ||
479 | |||
480 | \par Devices supported by the library are: | ||
481 | |||
482 | - C6A816x, also referenced as TI816x (Netra) | ||
483 | - C66xx (C6670, TCI6614/16/18) | ||
484 | - C6678 | ||
485 | - OMAP-A9 | ||
486 | - OMAP-A15 | ||
487 | - TCI6484 | ||
488 | - TCI6488 | ||
489 | - C6657 | ||
490 | - C66AK2Hxx (Keystone 2) | ||
491 | |||
492 | \par API Functions: | ||
493 | |||
494 | - #ETB_open | ||
495 | - #ETB_enable | ||
496 | - #ETB_disable | ||
497 | - #ETB_status | ||
498 | - #ETB_read | ||
499 | - #ETB_close | ||
500 | - #ETB_flush | ||
501 | - #ETB_config_dma | ||
502 | - #ETB_flush_dma | ||
503 | - #ETB_setDmaStatus | ||
504 | - #ETB_getProperties | ||
505 | |||
506 | */ | ||
diff --git a/server/TIETB.c b/server/TIETB.c new file mode 100644 index 0000000..114e53e --- /dev/null +++ b/server/TIETB.c | |||
@@ -0,0 +1,2739 @@ | |||
1 | /**************************************************************************** | ||
2 | CToolsLib - ETB Library | ||
3 | |||
4 | Copyright (c) 2009-2010 Texas Instruments Inc. (www.ti.com) | ||
5 | All rights reserved. | ||
6 | |||
7 | Redistribution and use in source and binary forms, with or without | ||
8 | modification, are permitted provided that the following conditions | ||
9 | are met: | ||
10 | 1. Redistributions of source code must retain the above copyright | ||
11 | notice, this list of conditions and the following disclaimer. | ||
12 | 2. Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | 3. The name of the author may not be used to endorse or promote products | ||
16 | derived from this software without specific prior written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||
19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | ****************************************************************************/ | ||
29 | |||
30 | /*! \file TIETB.c | ||
31 | \version 1.7 | ||
32 | */ | ||
33 | //#include <stdio.h> | ||
34 | //#include <stdlib.h> | ||
35 | |||
36 | #include "ETBInterface.h" | ||
37 | #include "ETBAddr.h" | ||
38 | |||
39 | #ifdef DMA_SUPPORT | ||
40 | #include "edma_dev-c66xx.h" | ||
41 | |||
42 | #if defined(C66AK2Hxx_CSSTM_ETB) | ||
43 | |||
44 | #define GET_GLOBAL_ADDR(addr) (uint32_t)(addr) | ||
45 | |||
46 | #else | ||
47 | |||
48 | #define GET_GLOBAL_ADDR(addr) \ | ||
49 | (uint32_t)( ((uint32_t)(addr)) < (uint32_t)0x00900000 ? \ | ||
50 | ((uint32_t)(addr) | (uint32_t)((DNUM + 16) << 24)) : (uint32_t)(addr) ) | ||
51 | #endif | ||
52 | #endif | ||
53 | |||
54 | #if DTF_PRESENT | ||
55 | #include "c6x.h" | ||
56 | #endif | ||
57 | |||
58 | //////////////////////////////////////////////////////////////////////////////////////////////// | ||
59 | // | ||
60 | // Private structs | ||
61 | // | ||
62 | //////////////////////////////////////////////////////////////////////////////////////////////// | ||
63 | |||
64 | #if defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) || defined(C66AK2Hxx_CSSTM_ETB) || defined(C66AK2Exx_CSSTM_ETB) | ||
65 | |||
66 | /* DMA config structure used internally | ||
67 | for C6657 and keystone2 devices | ||
68 | */ | ||
69 | typedef struct _DMAConfigInt | ||
70 | { | ||
71 | |||
72 | uint32_t cc; /* EDMA3 channel controller number. */ | ||
73 | |||
74 | uint16_t etbhalfChannel; /* ETB half full channel for DMA draining (needs to | ||
75 | be able to access the ETB). | ||
76 | */ | ||
77 | uint16_t etbfullChannel; /* ETB full channel for DMA draining (needs to | ||
78 | be able to access the ETB). | ||
79 | */ | ||
80 | uint16_t linkparam[3]; /* 3 additional parameter RAM entry numbers. | ||
81 | */ | ||
82 | uint32_t dbufAddress; /* DMA Drain buffer address */ | ||
83 | uint32_t dbufWords; /* DMA Drain buffer size in 32-bit words */ | ||
84 | eDMA_Mode mode; /* DMA Drain buffer mode (only eDMA_Circular and | ||
85 | eDMA_Stop_Buffer are valid values) | ||
86 | */ | ||
87 | } DMAConfigInt; | ||
88 | |||
89 | #endif | ||
90 | |||
91 | struct _ETBHandle_t | ||
92 | { | ||
93 | uint32_t ulContext; /*!< ETB context handle*/ | ||
94 | uint8_t id; /*!< ETB core user ID*/ | ||
95 | uint8_t dnum; /*!< Detected CPU ID*/ | ||
96 | ETB_errorCallback pCallBack; /*!< ETB error callback*/ | ||
97 | |||
98 | #if defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) || defined(C66AK2Hxx_CSSTM_ETB) || defined(C66AK2Exx_CSSTM_ETB) | ||
99 | |||
100 | DMAConfigInt *pDmaConfig; /*!< ETB DMA pointer, NULL when dma not used */ | ||
101 | |||
102 | #else | ||
103 | |||
104 | DMAConfig *pDmaConfig; /*!< ETB DMA pointer, NULL when dma not used */ | ||
105 | |||
106 | #endif | ||
107 | |||
108 | DMAStatus dmaStatus; /*!< Copy of ETB DMA status, populated when | ||
109 | ETB_flush_dma is called, used during ETB_read | ||
110 | calls. | ||
111 | */ | ||
112 | }; | ||
113 | |||
114 | #ifdef __linux | ||
115 | static uint32_t virtural_ETB_BaseAddress[NUM_ETB_INSTANCES] = {0}; | ||
116 | static uint32_t virtural_DTF_BaseAddress[NUM_ETB_INSTANCES] = {0}; | ||
117 | static uint32_t virtural_PSC_BaseAddress = 0; | ||
118 | #endif | ||
119 | |||
120 | // Max timeout for ETB DMA transfers to complete | ||
121 | #define ETB_DMA_TIMEOUT 100000 | ||
122 | |||
123 | /* ETB module access handle - virual for this library */ | ||
124 | static ETBHandle stHandle[NUM_ETB_INSTANCES]; | ||
125 | |||
126 | /* Enumeration to define the options available to the internal flush function */ | ||
127 | typedef enum _eETB_Options | ||
128 | { | ||
129 | eETB_OPT_NONE = 0, /*!< No options selected */ | ||
130 | eETB_STOP_FORMATTER /*!< Stop the formatter once a flush has completed */ | ||
131 | } eETB_OPTIONS; | ||
132 | |||
133 | /* Enumeration for ETB and TBR types */ | ||
134 | typedef enum _ETB_Type | ||
135 | { | ||
136 | TBR_TYPE = 0, /*!< TBR type */ | ||
137 | ETB_TYPE /*!< ETB type */ | ||
138 | }ETB_Type; | ||
139 | |||
140 | /* Internal ETB flush function used by API function for common purposes */ | ||
141 | static eETB_Error flush(ETBHandle *pHandle, eETB_OPTIONS options); | ||
142 | |||
143 | /*! RETURN_ETB_CALLBACK | ||
144 | ImplementaMacro to return API error. | ||
145 | */ | ||
146 | #define RETURN_ETB_CALLBACK(id,retValue) \ | ||
147 | if ( 0 != stHandle[id].pCallBack ) stHandle[id].pCallBack(retValue); return retValue | ||
148 | |||
149 | // ETBLib symbols for CCS ETB Receiver (Trace capture and decoding) | ||
150 | // ETBLib symbols need to be placed in external memory (MSMC or DDR3) | ||
151 | // for STM driver to read from these symbols | ||
152 | |||
153 | #pragma DATA_SECTION(etbLib_buffer_start_addr,"ETBLib_ExtMem"); | ||
154 | #pragma DATA_SECTION(etbLib_buffer_size,"ETBLib_ExtMem"); | ||
155 | #pragma DATA_SECTION(etbLib_buffer_data_start,"ETBLib_ExtMem"); | ||
156 | volatile uint32_t etbLib_buffer_start_addr[NUM_ETB_INSTANCES]; //start of ETB buffer | ||
157 | volatile uint32_t etbLib_buffer_size[NUM_ETB_INSTANCES]; //number of Bytes | ||
158 | volatile uint32_t etbLib_buffer_data_start[NUM_ETB_INSTANCES]; //address after circular buffer wrap point, where oldest data starts | ||
159 | |||
160 | #if SYSETB_PRESENT | ||
161 | |||
162 | #pragma DATA_SECTION(etbLib_sys_etb_index,"ETBLib_ExtMem"); | ||
163 | volatile uint32_t etbLib_sys_etb_index = SYS_ETB_ID; //symbol for SYS_ETB index | ||
164 | |||
165 | #endif | ||
166 | |||
167 | /***************************************************************** | ||
168 | * Data that will be accessed by EDMA3 HW. | ||
169 | * Application should link this data into appropriate memory so | ||
170 | * that interference to the application is minimized | ||
171 | *****************************************************************/ | ||
172 | /* | ||
173 | * If this data section is located in MSMC or DDR3 memory, it should | ||
174 | * be put in a non-cacheable region. | ||
175 | */ | ||
176 | #ifdef DMA_SUPPORT | ||
177 | |||
178 | #pragma DATA_SECTION(etbLib_bufferWrapped,"ETBLib_dmaData"); | ||
179 | |||
180 | #if defined(C6670) | ||
181 | |||
182 | #pragma DATA_SECTION(etbLib_cpCicEventClearValue,"ETBLib_dmaData"); | ||
183 | #pragma DATA_SECTION(etbLib_cpCicEventClearIndexReg,"ETBLib_dmaData"); | ||
184 | |||
185 | static uint32_t etbLib_cpCicEventClearValue[2][NUM_ETB_INSTANCES][2] = { | ||
186 | { | ||
187 | {CIC1_EVT_TETBHFULLINT0, CIC1_EVT_TETBFULLINT0}, | ||
188 | {CIC1_EVT_TETBHFULLINT1, CIC1_EVT_TETBFULLINT1}, | ||
189 | {CIC1_EVT_TETBHFULLINT2, CIC1_EVT_TETBFULLINT2}, | ||
190 | {CIC1_EVT_TETBHFULLINT3, CIC1_EVT_TETBFULLINT3}, | ||
191 | {0, 0}, | ||
192 | {0, 0}, | ||
193 | {0, 0}, | ||
194 | {0, 0}, | ||
195 | {CIC1_EVT_TETBHFULLINT, CIC1_EVT_TETBFULLINT} | ||
196 | }, | ||
197 | { | ||
198 | {CIC2_EVT_TETBHFULLINT0, CIC2_EVT_TETBFULLINT0}, | ||
199 | {CIC2_EVT_TETBHFULLINT1, CIC2_EVT_TETBFULLINT1}, | ||
200 | {CIC2_EVT_TETBHFULLINT2, CIC2_EVT_TETBFULLINT2}, | ||
201 | {CIC2_EVT_TETBHFULLINT3, CIC2_EVT_TETBFULLINT3}, | ||
202 | {0, 0}, | ||
203 | {0, 0}, | ||
204 | {0, 0}, | ||
205 | {0, 0}, | ||
206 | {CIC2_EVT_TETBHFULLINT, CIC2_EVT_TETBFULLINT} | ||
207 | } | ||
208 | }; | ||
209 | |||
210 | static uint32_t etbLib_cpCicEventClearIndexReg[2] = {CIC1_STATUS_CLR_INDEX_REG, CIC2_STATUS_CLR_INDEX_REG}; | ||
211 | |||
212 | #elif defined(C6678) | ||
213 | |||
214 | #pragma DATA_SECTION(etbLib_cpCicEventClearValue,"ETBLib_dmaData"); | ||
215 | #pragma DATA_SECTION(etbLib_cpCicEventClearIndexReg,"ETBLib_dmaData"); | ||
216 | |||
217 | static uint32_t etbLib_cpCicEventClearValue[2][NUM_ETB_INSTANCES][2] = | ||
218 | { | ||
219 | { | ||
220 | {CIC2_EVT_TETBHFULLINT0, CIC2_EVT_TETBFULLINT0}, | ||
221 | {CIC2_EVT_TETBHFULLINT1, CIC2_EVT_TETBFULLINT1}, | ||
222 | {CIC2_EVT_TETBHFULLINT2, CIC2_EVT_TETBFULLINT2}, | ||
223 | {CIC2_EVT_TETBHFULLINT3, CIC2_EVT_TETBFULLINT3}, | ||
224 | {CIC2_EVT_TETBHFULLINT4, CIC2_EVT_TETBFULLINT4}, | ||
225 | {CIC2_EVT_TETBHFULLINT5, CIC2_EVT_TETBFULLINT5}, | ||
226 | {CIC2_EVT_TETBHFULLINT6, CIC2_EVT_TETBFULLINT6}, | ||
227 | {CIC2_EVT_TETBHFULLINT7, CIC2_EVT_TETBFULLINT7}, | ||
228 | {CIC2_EVT_TETBHFULLINT, CIC2_EVT_TETBFULLINT} | ||
229 | }, | ||
230 | { | ||
231 | {CIC3_EVT_TETBHFULLINT0, CIC3_EVT_TETBFULLINT0}, | ||
232 | {CIC3_EVT_TETBHFULLINT1, CIC3_EVT_TETBFULLINT1}, | ||
233 | {CIC3_EVT_TETBHFULLINT2, CIC3_EVT_TETBFULLINT2}, | ||
234 | {CIC3_EVT_TETBHFULLINT3, CIC3_EVT_TETBFULLINT3}, | ||
235 | {CIC3_EVT_TETBHFULLINT4, CIC3_EVT_TETBFULLINT4}, | ||
236 | {CIC3_EVT_TETBHFULLINT5, CIC3_EVT_TETBFULLINT5}, | ||
237 | {CIC3_EVT_TETBHFULLINT6, CIC3_EVT_TETBFULLINT6}, | ||
238 | {CIC3_EVT_TETBHFULLINT7, CIC3_EVT_TETBFULLINT7}, | ||
239 | {CIC3_EVT_TETBHFULLINT, CIC3_EVT_TETBFULLINT} | ||
240 | } | ||
241 | }; | ||
242 | |||
243 | static uint32_t etbLib_cpCicEventClearIndexReg[2] = {CIC2_STATUS_CLR_INDEX_REG, CIC3_STATUS_CLR_INDEX_REG}; | ||
244 | |||
245 | #endif | ||
246 | |||
247 | static uint32_t etbLib_bufferWrapped[NUM_ETB_INSTANCES][2]; | ||
248 | |||
249 | #pragma DATA_SECTION(etb_disable,"ETBLib_dmaData"); | ||
250 | static uint32_t etb_disable = 0x0; | ||
251 | |||
252 | #endif //#ifdef DMA_SUPPORT | ||
253 | |||
254 | /** | ||
255 | * Normalize_ID(uint32_t id) - Normalize core/sys ETB ID | ||
256 | */ | ||
257 | static uint32_t Normalize_ID(uint32_t id) | ||
258 | { | ||
259 | #if SYSETB_PRESENT | ||
260 | if(id == SYS_ETB || id == SYS_ETB_ID) | ||
261 | { | ||
262 | id = SYS_ETB_ID; | ||
263 | } | ||
264 | #endif | ||
265 | return id; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * Handle_index(uint32_t id) - Get handle id for the core/sys ETB | ||
270 | */ | ||
271 | static uint32_t Handle_index(uint32_t id) | ||
272 | { | ||
273 | #if SYSETB_PRESENT | ||
274 | if(id == SYS_ETB || id == SYS_ETB_ID) | ||
275 | { | ||
276 | id = NUM_ETB_INSTANCES -1; | ||
277 | } | ||
278 | #endif | ||
279 | return id; | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * Check whether the coreID passed is associated with a TI-ETB or TBR implementation | ||
284 | * returns TBR_TYPE = 0 - for TBR implementation and ETB_TYPE = 1 - for TI-ETB implementation | ||
285 | */ | ||
286 | static ETB_Type check_etb_type(uint32_t id) | ||
287 | { | ||
288 | uint32_t dev_id; | ||
289 | // Read ETB device ID register | ||
290 | dev_id = *((volatile uint32_t*)ETB_DEVID(id)); | ||
291 | |||
292 | if(dev_id == ETB_DEVICE_ID) | ||
293 | { | ||
294 | // Return TI-ETB type | ||
295 | return(ETB_TYPE); | ||
296 | } | ||
297 | else if(dev_id == TBR_DEVICE_ID) | ||
298 | { | ||
299 | //Return TBR type | ||
300 | return(TBR_TYPE); | ||
301 | } | ||
302 | |||
303 | //By default always return TI-ETB type | ||
304 | return(ETB_TYPE); | ||
305 | } | ||
306 | |||
307 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
308 | |||
309 | /** | ||
310 | * Need_DTF(ETBHandle* pHandle) - Do we need to program DTF. Returns 1 (true) or 0 (false) | ||
311 | */ | ||
312 | static uint32_t Need_DTF(ETBHandle* pHandle) | ||
313 | { | ||
314 | #if SYSETB_PRESENT | ||
315 | if(pHandle->id == SYS_ETB || pHandle->id == SYS_ETB_ID) | ||
316 | { | ||
317 | return 0; | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | if (pHandle->id != pHandle->dnum) | ||
322 | { | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | #if DTF_PRESENT | ||
327 | return 1; | ||
328 | #else | ||
329 | return 0; | ||
330 | #endif | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Workaround_portownership() - Work around to setup correct debug port ownership | ||
335 | */ | ||
336 | static void Workaround_portownership() | ||
337 | { | ||
338 | uint32_t status=0; | ||
339 | status = *(volatile uint32_t*)0x1bc013c; | ||
340 | status= status | 01; | ||
341 | *(volatile uint32_t*)0x1bc013c = status; | ||
342 | } | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Program_Power_Sleep() - Work around to setup correct debug port ownership | ||
347 | */ | ||
348 | eETB_Error Program_Power_Sleep(uint8_t coreID) | ||
349 | { | ||
350 | uint32_t status=0; | ||
351 | uint32_t ptcmdValue = 0; | ||
352 | uint32_t retry = 1000; | ||
353 | |||
354 | /* Program Power and Sleep Controls */ | ||
355 | #if defined(TCI6484) | ||
356 | /* Enable DEBUGSS */ | ||
357 | *((volatile uint32_t*)PSC_MDCTL(6)) = 0x3; | ||
358 | |||
359 | /* Power domain Go transition command */ | ||
360 | ptcmdValue = 0x1; | ||
361 | |||
362 | #elif defined(C66x) | ||
363 | /* If etb powered up and both etb and debugss enabled then exit */ | ||
364 | { | ||
365 | uint32_t etb_power_state; | ||
366 | uint32_t debugss_cptracers_enable; | ||
367 | uint32_t etb_enable; | ||
368 | |||
369 | etb_power_state = *((volatile uint32_t*)PSC_PDSTAT(1)); | ||
370 | |||
371 | debugss_cptracers_enable = *((volatile uint32_t*)PSC_MDSTAT(5)); | ||
372 | |||
373 | etb_enable = *((volatile uint32_t*)PSC_MDSTAT(6)); | ||
374 | |||
375 | if ((etb_power_state & 1) && (debugss_cptracers_enable & 3) && (etb_enable & 3)) | ||
376 | { | ||
377 | return eETB_Success; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | /* Enable TETB power domain*/ | ||
382 | |||
383 | /* Power domain Go transition command for TETB power domain */ | ||
384 | ptcmdValue = 0x2; | ||
385 | |||
386 | /* Power up DebugSS */ | ||
387 | *((volatile uint32_t*)PSC_PDCTL(1)) = 0x1; | ||
388 | |||
389 | // Issue GO for the DebugSS power domain | ||
390 | *((volatile uint32_t*)PSC_PTCMD) = ptcmdValue; | ||
391 | |||
392 | //Wait for the domain transition to complete | ||
393 | do | ||
394 | { | ||
395 | status = *(volatile uint32_t*)PSC_PTSTAT; | ||
396 | retry--; | ||
397 | } while( ( ( status & ptcmdValue ) != 0 ) && ( retry != 0 ) ); | ||
398 | if ( retry == 0 ) return eETB_Error_Psc_Enabling; | ||
399 | |||
400 | /* Enable DEBUGSS subsystem */ | ||
401 | *((volatile uint32_t*)PSC_MDCTL(5)) = 0x3; | ||
402 | /* Enable Per-core TETB and system TETB subsystem */ | ||
403 | *((volatile uint32_t*)PSC_MDCTL(6)) = 0x3; | ||
404 | |||
405 | #endif | ||
406 | |||
407 | /* Power domain Go transition command for enabled power domain */ | ||
408 | *((volatile uint32_t*)PSC_PTCMD) = ptcmdValue; | ||
409 | |||
410 | //Wait for the domain transition to complete | ||
411 | retry = 1000; | ||
412 | do | ||
413 | { | ||
414 | status = *(volatile uint32_t*)PSC_PTSTAT; | ||
415 | retry--; | ||
416 | } while( ( ( status & ptcmdValue ) != 0 ) && ( retry != 0 ) ); | ||
417 | if ( retry == 0 ) return eETB_Error_Psc_Enabling; | ||
418 | |||
419 | /* Check that the modules have been properly enabled */ | ||
420 | #if defined(TCI6484) | ||
421 | if ((*((volatile uint32_t*)PSC_MDSTAT(6)) & 0x3F) != 0x3) | ||
422 | return eETB_Error_Psc_Enabling; | ||
423 | |||
424 | Workaround_portownership(); | ||
425 | |||
426 | #elif defined(C66x) | ||
427 | if ((*((volatile uint32_t*)PSC_MDSTAT(5)) & 0x3F) != 0x3 || | ||
428 | (*((volatile uint32_t*)PSC_MDSTAT(6)) & 0x3F) != 0x3) | ||
429 | return eETB_Error_Psc_Enabling; | ||
430 | Workaround_portownership(); | ||
431 | |||
432 | #endif | ||
433 | return eETB_Success; | ||
434 | } | ||
435 | //#endif //#ifndef _OMAP54xx | ||
436 | #endif | ||
437 | |||
438 | #if defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) || defined(C66AK2Hxx_CSSTM_ETB) | ||
439 | |||
440 | static uint8_t get_edma_buffer_info (ETBHandle* pHandle, DMAStatus *pStatus, uint32_t paramAddress, uint16_t paramIdx, int32_t remWords) | ||
441 | { | ||
442 | int32_t remBytes; | ||
443 | |||
444 | remBytes = (remWords * 4); | ||
445 | |||
446 | /* Check for buffer wrap */ | ||
447 | if(etbLib_bufferWrapped[pHandle->id][0]) | ||
448 | { | ||
449 | pStatus->availableWords = pHandle->dmaStatus.dbufWords; | ||
450 | pStatus->startAddr = PARAM_DST_REG(paramAddress) + remBytes; | ||
451 | pStatus->isWrapped = 1; | ||
452 | } | ||
453 | else | ||
454 | { | ||
455 | pStatus->availableWords = (PARAM_DST_REG(paramAddress) - | ||
456 | pHandle->pDmaConfig->dbufAddress) / 4; | ||
457 | pStatus->availableWords += remWords; | ||
458 | pStatus->startAddr = pHandle->pDmaConfig->dbufAddress; | ||
459 | pStatus->isWrapped = 0; | ||
460 | } | ||
461 | |||
462 | /* Copy the DMA status into the handle for later management. The status | ||
463 | * value for the number of words may be different than what was in the | ||
464 | * configuration structure. This value is set during configuration. | ||
465 | */ | ||
466 | pStatus->dbufAddress = pHandle->pDmaConfig->dbufAddress; | ||
467 | pStatus->dbufWords = pHandle->dmaStatus.dbufWords; | ||
468 | pStatus->flushRequired = pHandle->dmaStatus.flushRequired; | ||
469 | pHandle->dmaStatus = *pStatus; | ||
470 | |||
471 | /* If the mode has been set to non-circular and the buffer wrapped flag | ||
472 | * is set, then the memory buffer if full, otherwise continue the | ||
473 | * configuration for the final DMA. | ||
474 | */ | ||
475 | if((pHandle->pDmaConfig->mode == eDMA_Stop_Buffer) && | ||
476 | (etbLib_bufferWrapped[pHandle->id][0])) | ||
477 | { | ||
478 | /* If the buffer wrapped, the startAddr value is incorrect from | ||
479 | * above, set back to beginning of the buffer. | ||
480 | */ | ||
481 | pStatus->startAddr = pHandle->pDmaConfig->dbufAddress; | ||
482 | pHandle->dmaStatus.startAddr = pHandle->pDmaConfig->dbufAddress; | ||
483 | return(1); | ||
484 | } | ||
485 | |||
486 | // Update the 3 symbols which are required for CCS ETB receiver | ||
487 | etbLib_buffer_start_addr[pHandle->id] = pHandle->pDmaConfig->dbufAddress; //CCS ETB receiver will always get a linearized buffer for the non-EDMA ETB drain case | ||
488 | etbLib_buffer_size[pHandle->id] = pStatus->availableWords * 4; //Number of bytes available | ||
489 | etbLib_buffer_data_start[pHandle->id] = pStatus->startAddr; //circular buffer wrap point | ||
490 | |||
491 | return(0); | ||
492 | } | ||
493 | |||
494 | #endif | ||
495 | |||
496 | /** | ||
497 | * ETB_open - open ETB programming module interface | ||
498 | */ | ||
499 | |||
500 | eETB_Error ETB_open(ETB_errorCallback pErrCallBack, eETB_Mode mode, uint8_t coreID, ETBHandle** ppHandle, uint32_t* pETBSizeInWords) | ||
501 | { | ||
502 | uint32_t dnum = 0; | ||
503 | uint32_t status, value; | ||
504 | |||
505 | #if DTF_PRESENT | ||
506 | dnum = DNUM; | ||
507 | #endif | ||
508 | coreID = Normalize_ID(coreID); | ||
509 | |||
510 | #if SYSETB_PRESENT | ||
511 | // populate SYS_ETB index symbol | ||
512 | if(coreID == SYS_ETB_ID) | ||
513 | { | ||
514 | etbLib_sys_etb_index = SYS_ETB_ID; | ||
515 | } | ||
516 | |||
517 | #endif | ||
518 | |||
519 | if(Handle_index(coreID) >= NUM_ETB_INSTANCES) | ||
520 | { | ||
521 | return eETB_Error_Bad_Param; | ||
522 | } | ||
523 | |||
524 | if ((ppHandle == 0 ) || ( pETBSizeInWords == 0) ) | ||
525 | { | ||
526 | return eETB_Error_Bad_Param; | ||
527 | } | ||
528 | |||
529 | #ifdef __linux | ||
530 | virtural_ETB_BaseAddress[coreID] = cTools_memMap(ETB_BaseAddress(coreID), SIZEOF_ETB_SPACE); | ||
531 | virtural_DTF_BaseAddress[coreID] = cTools_memMap(DTF_BaseAddress(coreID), SIZEOF_DTF_SPACE); | ||
532 | if (virtural_PSC_BaseAddress == 0) | ||
533 | { | ||
534 | virtural_PSC_BaseAddress = cTools_memMap(PSC_BaseAddress, SIZEOF_PSC_SPACE); | ||
535 | } | ||
536 | #endif | ||
537 | |||
538 | |||
539 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
540 | |||
541 | eETB_Error retVal = eETB_Success; | ||
542 | |||
543 | retVal = Program_Power_Sleep(coreID); | ||
544 | if (retVal != eETB_Success) | ||
545 | return retVal; | ||
546 | |||
547 | #endif | ||
548 | |||
549 | if(check_etb_type(coreID) == ETB_TYPE) | ||
550 | { | ||
551 | |||
552 | // Reset the ETB | ||
553 | *((volatile uint32_t*)ETB_TI_CTL(coreID)) = *((volatile uint32_t*)ETB_TI_CTL(coreID)) | 0x4; | ||
554 | |||
555 | /* Unlock ETB in order to enable accesses to any ETB registers below. */ | ||
556 | *((volatile uint32_t*)ETB_LOCK(coreID)) = ETB_UNLOCK_VAL; | ||
557 | |||
558 | /* Size of the ETB. ETB_RDP contains number of 32 bit wide words. */ | ||
559 | *pETBSizeInWords = (*((volatile uint32_t*)ETB_RDP(coreID))); | ||
560 | |||
561 | /* Setup ETB mode */ | ||
562 | if ((eETB_TI_Mode == mode) || (eETB_TI_Mode_AND_Stop_Buffer == mode)) | ||
563 | *((volatile uint32_t*)ETB_TI_CTL(coreID)) = TI_ETB_TI_MODE; | ||
564 | |||
565 | status = *((volatile uint32_t*)ETB_TI_CTL(coreID)); | ||
566 | if((eETB_Stop_Buffer != mode) && (eETB_TI_Mode_AND_Stop_Buffer != mode)) | ||
567 | { | ||
568 | /* Set TI ETB for circular mode - clear the bit. */ | ||
569 | *((volatile uint32_t*)ETB_TI_CTL(coreID)) = status & ~(TI_ETB_CIRCULARMODE_BIT); | ||
570 | } | ||
571 | else | ||
572 | { | ||
573 | /* Set TI ETB as stop buffer full mode - set the bit. */ | ||
574 | *((volatile uint32_t*)ETB_TI_CTL(coreID)) = status | TI_ETB_CIRCULARMODE_BIT; | ||
575 | } | ||
576 | } | ||
577 | else //TBR implementation | ||
578 | { | ||
579 | // Reset the ETB | ||
580 | *((volatile uint32_t*)ETB_CTL(coreID)) = *((volatile uint32_t*)ETB_CTL(coreID)) | 0x4; | ||
581 | |||
582 | //Read claim tag value and check if TBR is not already claimed | ||
583 | // Assumption here is that the debugger will set the claim bit to get ownership of the TBR | ||
584 | status = *((volatile uint32_t*)TBR_CLAIMCLR(coreID)); | ||
585 | |||
586 | if(status != 0) | ||
587 | { | ||
588 | return eETB_Error_Cannot_Own; | ||
589 | } | ||
590 | |||
591 | /* Unlock to enable accesses */ | ||
592 | status = (*((volatile uint32_t*)ETB_LOCK_STATUS(coreID))); | ||
593 | if (status & LOCK_STATUS_IMP_BIT) | ||
594 | { | ||
595 | /* If this bit is set, it device access is locked, we need to unlock the device*/ | ||
596 | if (status & LOCK_STATUS_STAT_BIT) | ||
597 | { | ||
598 | /* Unlock ETB in order to enable accesses to any ETB registers below. */ | ||
599 | *((volatile uint32_t*)ETB_LOCK(coreID)) = ETB_UNLOCK_VAL; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* Size of the ETB. ETB_RDP contains number of 32 bit wide words. */ | ||
604 | value = (*((volatile uint32_t*)ETB_RDP(coreID))); | ||
605 | *pETBSizeInWords = (1 << (value-1)) << 10; | ||
606 | |||
607 | /* Setup TBR mode */ | ||
608 | value = (*((volatile uint32_t*)ETB_FFCR(coreID))); | ||
609 | |||
610 | /* Setup TBR in buffer mode */ | ||
611 | *((volatile uint32_t*)ETB_CTL(coreID)) &= TBR_BUFFER_MODE; | ||
612 | |||
613 | if((eETB_Stop_Buffer == mode) || (eETB_TI_Mode_AND_Stop_Buffer == mode)) | ||
614 | { | ||
615 | //Configure stop on Full mode | ||
616 | (*((volatile uint32_t*)ETB_FFCR(coreID))) = value | TBR_STP_FULL; | ||
617 | } | ||
618 | else if((eETB_Circular == mode) || (eETB_TI_Mode == mode)) | ||
619 | { | ||
620 | //Configure circular mode | ||
621 | (*((volatile uint32_t*)ETB_FFCR(coreID))) = value & (~(uint32_t)TBR_STP_FULL); | ||
622 | } | ||
623 | } | ||
624 | |||
625 | /* Set ETB context in the handle*/ | ||
626 | stHandle[Handle_index(coreID)].ulContext = ETB_UNLOCK_VAL; | ||
627 | stHandle[Handle_index(coreID)].id = coreID; | ||
628 | stHandle[Handle_index(coreID)].dnum = dnum; | ||
629 | stHandle[Handle_index(coreID)].pCallBack = pErrCallBack; | ||
630 | stHandle[Handle_index(coreID)].pDmaConfig = 0; | ||
631 | stHandle[Handle_index(coreID)].dmaStatus.startAddr = 0; | ||
632 | stHandle[Handle_index(coreID)].dmaStatus.availableWords = 0; | ||
633 | stHandle[Handle_index(coreID)].dmaStatus.isWrapped = 0; | ||
634 | stHandle[Handle_index(coreID)].dmaStatus.dbufAddress = 0; | ||
635 | stHandle[Handle_index(coreID)].dmaStatus.dbufWords = 0; | ||
636 | stHandle[Handle_index(coreID)].dmaStatus.flushRequired = 1; | ||
637 | |||
638 | *ppHandle = &stHandle[Handle_index(coreID)]; | ||
639 | return eETB_Success; | ||
640 | } | ||
641 | |||
642 | |||
643 | #if defined(TCI6484) | ||
644 | /** | ||
645 | * TCI6484_discard_nops- TCI6484 ADTF defecrt work around to flush the the stuck packet. | ||
646 | * | ||
647 | */ | ||
648 | eETB_Error TCI6484_nops(uint8_t coreID, uint8_t discard) | ||
649 | { | ||
650 | uint32_t value = 0; | ||
651 | |||
652 | value = *(volatile uint32_t*)(DTF_CNTL(coreID)); | ||
653 | |||
654 | if (discard == 1) | ||
655 | { | ||
656 | value = value | (0x2); | ||
657 | } | ||
658 | else | ||
659 | { | ||
660 | value = value & (~0x2); | ||
661 | } | ||
662 | value = value | (0x1<<4); | ||
663 | |||
664 | *(volatile uint32_t*)(DTF_CNTL(coreID)) = value; | ||
665 | |||
666 | return eETB_Success; | ||
667 | } | ||
668 | #endif | ||
669 | |||
670 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
671 | |||
672 | /** | ||
673 | * DTF_flush - Flush data from the ADTF | ||
674 | */ | ||
675 | eETB_Error DTF_flush(uint8_t n) | ||
676 | { | ||
677 | /* Only ADTF v2 support software flush. Thus, the first step is to read | ||
678 | version ID to verify to version number */ | ||
679 | |||
680 | if ((*(volatile uint32_t*)(ID(n)) & DTF_ID_MAJOR_MASK) == DTF_ID_MAJOR_VER2) | ||
681 | { | ||
682 | /* The way the ADTFv2 flush work is to write 1 to the flush bit and then | ||
683 | clear it after that. That is because ADTF is looking for the rising edge of the signal. */ | ||
684 | *(volatile uint32_t*)(DTF_CNTL(n)) = *(volatile uint32_t*)(DTF_CNTL(n)) | DTF_VER2_FLUSH_BIT; | ||
685 | } | ||
686 | |||
687 | #if defined(TCI6484) /* ADTF bug work around in TCI6484 */ | ||
688 | /* flush the ADTF */ | ||
689 | TCI6484_nops(n, 0); | ||
690 | TCI6484_nops(n, 1); | ||
691 | #endif | ||
692 | return eETB_Success; | ||
693 | } | ||
694 | |||
695 | #endif | ||
696 | |||
697 | /** | ||
698 | * ETB_enable- Enable ETB to capture trace data | ||
699 | */ | ||
700 | eETB_Error ETB_enable(ETBHandle* pHandle, uint32_t triggerCount) | ||
701 | { | ||
702 | uint32_t etbControl; | ||
703 | uint32_t waitCount = 1000; | ||
704 | |||
705 | |||
706 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
707 | { | ||
708 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
709 | } | ||
710 | |||
711 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
712 | |||
713 | /* Setup DTF, if available */ | ||
714 | if(Need_DTF(pHandle)) | ||
715 | { | ||
716 | uint32_t value; | ||
717 | /* Unlock to enable accesses */ | ||
718 | value = *(volatile uint32_t*)(DTF_LOCK_STATUS(pHandle->id)); | ||
719 | if (value & LOCK_STATUS_IMP_BIT) | ||
720 | { | ||
721 | /* If this bit is set, it device access is locked, we need to unlock the device*/ | ||
722 | if (value & LOCK_STATUS_STAT_BIT) | ||
723 | { | ||
724 | *(volatile uint32_t*)(DTF_LOCK(pHandle->id)) = ETB_UNLOCK_VAL; | ||
725 | } | ||
726 | } | ||
727 | /* Claim Tag Set */ | ||
728 | *(volatile uint32_t*)(TAGSET(pHandle->id)) = 0x1; | ||
729 | |||
730 | /* Enable ADTF */ | ||
731 | *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) = *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) | 0x1; | ||
732 | } | ||
733 | |||
734 | #endif | ||
735 | |||
736 | /* Make sure that tracing is disabled or the write to the following | ||
737 | * registers will not actually get written. | ||
738 | */ | ||
739 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) = *((volatile uint32_t*)ETB_CTL(pHandle->id)) & (~ETB_ENABLE);/* DISABLE TraceCaptEn */ | ||
740 | |||
741 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
742 | { | ||
743 | /* ETB FIFO reset by writing 0 to ETB RAM Write Pointer Register. */ | ||
744 | *((volatile uint32_t*)ETB_RWP(pHandle->id)) = 0; | ||
745 | |||
746 | /* Initialize RDP. */ | ||
747 | *((volatile uint32_t*)ETB_RRP(pHandle->id)) = 0; | ||
748 | |||
749 | /* Clear all interrupts before enabling trace, just to make sure nothing pending*/ | ||
750 | *((volatile uint32_t*)ETB_ICST(pHandle->id)) = (TI_ETB_IRST_FULL | | ||
751 | TI_ETB_IRST_HALF_FULL | | ||
752 | TI_ETB_IRST_OVERFLOW | | ||
753 | TI_ETB_IRST_UNDERFLOW); | ||
754 | } | ||
755 | else | ||
756 | { | ||
757 | /* Clear all interrupts before enabling trace, just to make sure nothing pending*/ | ||
758 | *((volatile uint32_t*)TBR_IRQSTATUS(pHandle->id)) = (TBR_IRST_DAV | | ||
759 | TBR_IRST_AQCMP); | ||
760 | } | ||
761 | |||
762 | /* Disable formatting and put ETB formatter into bypass mode. */ | ||
763 | /* Clear all control bits except STP_FULL */ | ||
764 | *((volatile uint32_t*)ETB_FFCR(pHandle->id)) &= TBR_STP_FULL; /* For TI-ETB: EnFCont=0, EnFTC=0 */ | ||
765 | |||
766 | if(check_etb_type(pHandle->id) == TBR_TYPE) | ||
767 | { | ||
768 | //Set ID period to 8. Artificial ID will be added, if there is no ID change for 8 TWP frames | ||
769 | *((volatile uint32_t*)TBR_IDPERIOD(pHandle->id)) = TBR_TWP_IDPERIOD; | ||
770 | |||
771 | *((volatile uint32_t*)TBR_SEQCNTL(pHandle->id)) = TBR_TWP_SEQATBID | TBR_TWP_SEQPERIOD; | ||
772 | |||
773 | //Always enable TBR TWP formatter | ||
774 | *((volatile uint32_t*)ETB_FFCR(pHandle->id)) = *((volatile uint32_t*)ETB_FFCR(pHandle->id)) | TBR_TWP_ENABLE; | ||
775 | //*((volatile uint32_t*)ETB_FFCR(pHandle->id)) = *((volatile uint32_t*)ETB_FFCR(pHandle->id)) & TBR_TWP_DISABLE; | ||
776 | } | ||
777 | |||
778 | /* Setup Trigger counter. */ | ||
779 | *((volatile uint32_t*)ETB_TRIG(pHandle->id)) = triggerCount; | ||
780 | |||
781 | #ifdef DMA_SUPPORT | ||
782 | /* If the DMA has been enabled, indicated by dma pointer non-null, enable | ||
783 | * the ETB half-full and full interrupts. | ||
784 | */ | ||
785 | if(pHandle->pDmaConfig != 0) | ||
786 | { | ||
787 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
788 | { | ||
789 | *((volatile uint32_t*)ETB_IER(pHandle->id)) = (TI_ETB_IRST_FULL | | ||
790 | TI_ETB_IRST_HALF_FULL); | ||
791 | } | ||
792 | } | ||
793 | #endif | ||
794 | |||
795 | /* Enable ETB data capture by writing ETB Control Register. */ | ||
796 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) = *((volatile uint32_t*)ETB_CTL(pHandle->id)) | ETB_ENABLE; /* TraceCaptEn =1 */ | ||
797 | |||
798 | /* Put some delays in here - make sure we can read back. */ | ||
799 | do | ||
800 | { | ||
801 | etbControl = *((volatile uint32_t*)ETB_CTL(pHandle->id)); | ||
802 | waitCount--; | ||
803 | } while (((etbControl & 0x1) != ETB_ENABLE) && (waitCount > 0)); | ||
804 | |||
805 | if(waitCount ==0) | ||
806 | { | ||
807 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
808 | } | ||
809 | |||
810 | return eETB_Success; | ||
811 | } | ||
812 | |||
813 | /** | ||
814 | * ETB_disable - Disable ETB to stop capturing trace data | ||
815 | */ | ||
816 | eETB_Error ETB_disable(ETBHandle* pHandle) | ||
817 | { | ||
818 | eETB_Error ret = eETB_Success; | ||
819 | |||
820 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
821 | { | ||
822 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
823 | } | ||
824 | |||
825 | /* Flush ETB, wait until after disabling data capture to check status. | ||
826 | * This function will not return until the flush has completed. | ||
827 | */ | ||
828 | // Perform Flush + stop formatter only for non-EDMA examples. For EDMA examples | ||
829 | // the Flush + stop formatter is already done using the ETB_flush() API | ||
830 | if(pHandle->pDmaConfig == 0) | ||
831 | { | ||
832 | ret = flush(pHandle, eETB_STOP_FORMATTER); | ||
833 | } | ||
834 | |||
835 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
836 | |||
837 | if(Need_DTF(pHandle)) | ||
838 | { | ||
839 | /* Disable ADTF */ | ||
840 | *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) = *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) | (~0x1); | ||
841 | } | ||
842 | |||
843 | #endif | ||
844 | |||
845 | /* Disable ETB data capture by writing ETB Control Register. */ | ||
846 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) = *((volatile uint32_t*)ETB_CTL(pHandle->id)) & (~ETB_ENABLE); /* TraceCaptEn =0 */ | ||
847 | |||
848 | if(ret != eETB_Success) | ||
849 | { | ||
850 | RETURN_ETB_CALLBACK(pHandle->id, ret); | ||
851 | } | ||
852 | |||
853 | // Wait for ETB Acquisition Complete | ||
854 | /* ==> The code to check the ETB_STS register for ETB_STS_ACQCOMP bit | ||
855 | * is not necessary if a manual flush has occurred and | ||
856 | * completed. For the TBR case, the disable trace capture will | ||
857 | * cause a flush, polling this bit would serve a purpose. | ||
858 | */ | ||
859 | |||
860 | #ifdef DMA_SUPPORT | ||
861 | /* If the DMA has been enabled, indicated by dma pointer non-null, disable | ||
862 | * the ETB half-full and full interrupts. | ||
863 | */ | ||
864 | if(pHandle->pDmaConfig != 0) | ||
865 | { | ||
866 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
867 | { | ||
868 | *((volatile uint32_t*)ETB_IECST(pHandle->id)) = (TI_ETB_IRST_FULL | | ||
869 | TI_ETB_IRST_HALF_FULL); | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | *((volatile uint32_t*)TBR_IRQENABLE_CLR(pHandle->id)) = TBR_IRST_DAV; | ||
874 | } | ||
875 | } | ||
876 | #endif | ||
877 | return ret; | ||
878 | } | ||
879 | |||
880 | |||
881 | /** | ||
882 | * ETB_status- Get ETB status | ||
883 | * | ||
884 | ETB status register . | ||
885 | STS: | ||
886 | RAMFull=1 [0], RAMEmpty=0 [0] | ||
887 | Triggered=1 [1], NotTriggered=0 [1] | ||
888 | AccqComp=1 [2], NotAccqComp=0 [2] | ||
889 | FtEmpty=1 [3], NotFtEmpty=0 [3] | ||
890 | x --> reserved | ||
891 | v --> read value | ||
892 | 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 | ||
893 | ________________________________________________________________________________________________ | ||
894 | |x | x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| x| v| v| v| v| | ||
895 | |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__| | ||
896 | |||
897 | */ | ||
898 | eETB_Error ETB_status(ETBHandle* pHandle, ETBStatus* status) | ||
899 | { | ||
900 | uint32_t etbStatus, etbControl=0, etb_size; | ||
901 | |||
902 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
903 | { | ||
904 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
905 | } | ||
906 | |||
907 | if(status == 0 ) | ||
908 | { | ||
909 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Bad_Param); | ||
910 | } | ||
911 | |||
912 | //Get ETB Trace capture enable status | ||
913 | status->ETB_TraceCaptureEn = *((volatile uint32_t*)ETB_CTL(pHandle->id)); | ||
914 | |||
915 | #ifdef DMA_SUPPORT | ||
916 | |||
917 | if(pHandle->pDmaConfig != 0) | ||
918 | { | ||
919 | uint32_t paramAddress; | ||
920 | uint16_t paramIdx; | ||
921 | |||
922 | #if defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
923 | |||
924 | paramIdx = (EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
925 | pHandle->pDmaConfig->etbhalfChannel) >> 5); | ||
926 | |||
927 | #elif defined(C6670) || defined(C6678) | ||
928 | |||
929 | paramIdx = (EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
930 | pHandle->pDmaConfig->etbChannel) >> 5); | ||
931 | #endif | ||
932 | |||
933 | paramAddress = EDMA_TPCC_PARAM_BASE_ADDR(pHandle->pDmaConfig->cc) + | ||
934 | (0x20 * paramIdx); | ||
935 | |||
936 | /* Check for buffer wrap */ | ||
937 | if(etbLib_bufferWrapped[pHandle->id][0]) | ||
938 | { | ||
939 | status->availableWords = pHandle->dmaStatus.dbufWords; | ||
940 | status->isWrapped = 1; | ||
941 | status->canRead = 1; | ||
942 | } | ||
943 | else | ||
944 | { | ||
945 | status->availableWords = (PARAM_DST_REG(paramAddress) - | ||
946 | pHandle->pDmaConfig->dbufAddress) / 4; | ||
947 | status->isWrapped = 0; | ||
948 | status->canRead = 1; | ||
949 | } | ||
950 | } | ||
951 | else | ||
952 | #endif | ||
953 | { | ||
954 | status->canRead=0; | ||
955 | status->availableWords=0; | ||
956 | status->isWrapped=0; | ||
957 | status->overflow = 0; | ||
958 | etbStatus = *((volatile uint32_t*)ETB_STS(pHandle->id)); | ||
959 | |||
960 | if (etbStatus & TI_ETB_IRST_OVERFLOW) | ||
961 | { | ||
962 | status->overflow = 1; | ||
963 | } | ||
964 | |||
965 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
966 | { | ||
967 | if ((TI_ETB_TI_MODE & *((volatile uint32_t*)ETB_TI_CTL(pHandle->id))) == | ||
968 | TI_ETB_TI_MODE) | ||
969 | { | ||
970 | /* In this case we must take into account the number of words already read */ | ||
971 | status->canRead = 1; | ||
972 | } | ||
973 | else | ||
974 | { | ||
975 | |||
976 | etbControl = *((volatile uint32_t*)ETB_CTL(pHandle->id)); | ||
977 | |||
978 | if(etbControl == ETB_ENABLE) | ||
979 | { | ||
980 | return eETB_Success; | ||
981 | } | ||
982 | |||
983 | if((etbStatus & ETB_STS_ACQCOMP) == ETB_STS_ACQCOMP) | ||
984 | { | ||
985 | status->canRead = 1; | ||
986 | } | ||
987 | } | ||
988 | |||
989 | // get size of the ETB buffer in words | ||
990 | etb_size = (*((volatile uint32_t*)ETB_RDP(pHandle->id))); | ||
991 | } | ||
992 | else | ||
993 | { | ||
994 | etbControl = *((volatile uint32_t*)ETB_CTL(pHandle->id)); | ||
995 | |||
996 | if(etbControl == ETB_ENABLE) | ||
997 | { | ||
998 | return eETB_Success; | ||
999 | } | ||
1000 | |||
1001 | if((etbStatus & ETB_STS_ACQCOMP) == ETB_STS_ACQCOMP) | ||
1002 | { | ||
1003 | status->canRead = 1; | ||
1004 | } | ||
1005 | |||
1006 | // get size of the TBR buffer in words | ||
1007 | etb_size = (*((volatile uint32_t*)ETB_RDP(pHandle->id))); | ||
1008 | etb_size = (1 << (etb_size-1)) << 10; | ||
1009 | } | ||
1010 | |||
1011 | if ((etbStatus & ETB_STS_FULL) == ETB_STS_FULL) | ||
1012 | { | ||
1013 | status->isWrapped = 1; | ||
1014 | status->availableWords = etb_size; | ||
1015 | } | ||
1016 | else | ||
1017 | status->availableWords = *((volatile uint32_t*)ETB_RWP(pHandle->id)); | ||
1018 | } | ||
1019 | return eETB_Success; | ||
1020 | } | ||
1021 | |||
1022 | |||
1023 | /** | ||
1024 | * ETB_read- Read ETB data | ||
1025 | * | ||
1026 | * Reference Diagram for DMA drain buffer parameters: | ||
1027 | * | ||
1028 | * Wrapped buffer: Non-Wrapped buffer: | ||
1029 | * _______________ _______________ | ||
1030 | * |_______________| -> dbufStartAddr |_______________| -> dbufStartAddr | ||
1031 | * | | | | && dataStartAddr | ||
1032 | * | | | | | ||
1033 | * // // // // | ||
1034 | * |_______________| // // | ||
1035 | * |_______________| -> dataEndAddr |_______________| | ||
1036 | * |_______________| -> dataStartAddr |_______________| -> dataEndAddr | ||
1037 | * | | | \\\\\\\\\\\\ | | ||
1038 | * | | | //////////// | No data | ||
1039 | * // // // \\\\\\\\\\\\ // | ||
1040 | * |_______________| | //////////// | | ||
1041 | * |_______________| -> dbufEndAddr |_______________| -> dbufEndAddr | ||
1042 | * | ||
1043 | */ | ||
1044 | eETB_Error ETB_read(ETBHandle* pHandle, uint32_t *pBuffer, | ||
1045 | uint32_t bufferLength, uint32_t startWord, | ||
1046 | uint32_t readLength, uint32_t* pRetLength) | ||
1047 | { | ||
1048 | ETBStatus status; | ||
1049 | uint32_t idx, startAddr, depth, value; | ||
1050 | |||
1051 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
1052 | { | ||
1053 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1054 | } | ||
1055 | /* Check if we have proper buffer pointer */ | ||
1056 | if(pBuffer == 0) | ||
1057 | { | ||
1058 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Bad_Param); | ||
1059 | } | ||
1060 | |||
1061 | *pRetLength =0; | ||
1062 | |||
1063 | #ifdef DMA_SUPPORT | ||
1064 | /* If the DMA has been configured to empty the ETB, then read from the memory | ||
1065 | * buffer instead of the ETB hardware registers. | ||
1066 | */ | ||
1067 | if(pHandle->pDmaConfig != 0) | ||
1068 | { | ||
1069 | uint32_t *pDmaBuffer; | ||
1070 | uint32_t dataStartAddr; // Start of data address in case of wrap | ||
1071 | uint32_t dataEndAddr; // End of data address | ||
1072 | uint32_t wordCnt; // Number of words that will be copied | ||
1073 | int32_t remWords; // Remaining words to read from drain buffer | ||
1074 | uint32_t dbufEndAddr; // End of buffer address | ||
1075 | uint32_t dbufStartAddr = pHandle->dmaStatus.dbufAddress; | ||
1076 | |||
1077 | /* Set/calculate address values */ | ||
1078 | dataStartAddr = pHandle->dmaStatus.startAddr; | ||
1079 | dbufEndAddr = pHandle->dmaStatus.dbufAddress + (pHandle->dmaStatus.dbufWords*4) - 1; | ||
1080 | |||
1081 | /* If the data starting address is not equal to the buffer starting address, | ||
1082 | * then the buffer has wrapped, the ending data address will be | ||
1083 | * the previous word's address. Otherwise, it will be the starting address | ||
1084 | * plus the number of words written into the drain buffer. | ||
1085 | */ | ||
1086 | if(dataStartAddr > dbufStartAddr) | ||
1087 | { | ||
1088 | dataEndAddr = dataStartAddr - sizeof(uint32_t); | ||
1089 | } | ||
1090 | else | ||
1091 | { | ||
1092 | dataEndAddr = dataStartAddr + ((pHandle->dmaStatus.availableWords-1) * 4); | ||
1093 | } | ||
1094 | /* The startWord variable is passed into this function as an offset for | ||
1095 | * this read request. The value is translated into bytes from words to | ||
1096 | * get the correct address value to start reading words from the drain | ||
1097 | * buffer. | ||
1098 | */ | ||
1099 | startAddr = dataStartAddr + (startWord * 4); | ||
1100 | |||
1101 | /* Check to see if the starting address is past the end of the buffer */ | ||
1102 | // if(startAddr > dbufEndAddr) | ||
1103 | // { | ||
1104 | // /* Subtract 1 from the difference to account for 0-based counting */ | ||
1105 | // startAddr = ((startAddr - dbufEndAddr) + dbufStartAddr) - 1; | ||
1106 | // } | ||
1107 | |||
1108 | /* Initially set the total word count to the specified buffer length, | ||
1109 | * then check if the requested read length is less, then finally if | ||
1110 | * the remaining words left in the drain buffer is less. | ||
1111 | */ | ||
1112 | wordCnt = bufferLength; | ||
1113 | if(readLength < wordCnt) | ||
1114 | { | ||
1115 | wordCnt = readLength; | ||
1116 | } | ||
1117 | |||
1118 | /* The following calculation is using the remaining words variable to calculate | ||
1119 | * byte address values. The conversion from bytes to words will occur after the | ||
1120 | * calculations have been completed. | ||
1121 | */ | ||
1122 | remWords = dataEndAddr - startAddr; | ||
1123 | if(remWords < 0) | ||
1124 | { | ||
1125 | if(pHandle->dmaStatus.isWrapped) | ||
1126 | { | ||
1127 | /* 1 is added back to the end address to use the size vs. address */ | ||
1128 | remWords = ((dbufEndAddr+1) - startAddr) + (dataEndAddr - dbufStartAddr); | ||
1129 | } | ||
1130 | else | ||
1131 | { | ||
1132 | remWords = 0; | ||
1133 | } | ||
1134 | } | ||
1135 | /* Convert from bytes to words */ | ||
1136 | if(remWords != 0) | ||
1137 | { | ||
1138 | remWords /= 4; | ||
1139 | remWords += 1; /* 1 added for 0-based counting */ | ||
1140 | } | ||
1141 | |||
1142 | if(remWords < wordCnt) | ||
1143 | { | ||
1144 | wordCnt = remWords; | ||
1145 | } | ||
1146 | |||
1147 | /* Loop through and copy the data from the ETB buffer into the provided | ||
1148 | * buffer. | ||
1149 | */ | ||
1150 | pDmaBuffer = (uint32_t *)startAddr; | ||
1151 | for(idx = 0; idx < wordCnt; idx++) | ||
1152 | { | ||
1153 | /* Check for startAddr past the total words in the buffer and set | ||
1154 | * the pointer/address values to the buffer's starting address. | ||
1155 | */ | ||
1156 | if(startAddr > dbufEndAddr) | ||
1157 | { | ||
1158 | pDmaBuffer = (uint32_t *)(pHandle->dmaStatus.dbufAddress + (startAddr - (dbufEndAddr+1))); | ||
1159 | startAddr = pHandle->dmaStatus.dbufAddress; | ||
1160 | } | ||
1161 | pBuffer[idx] = *pDmaBuffer++; | ||
1162 | |||
1163 | (*pRetLength)++; | ||
1164 | |||
1165 | startAddr += 4; /* Increment by full-word */ | ||
1166 | } | ||
1167 | } | ||
1168 | else | ||
1169 | #endif | ||
1170 | { | ||
1171 | /* Get the status of the ETB before we can start reading. */ | ||
1172 | if(eETB_Success == ETB_status(pHandle, &status)) | ||
1173 | { | ||
1174 | if(status.canRead == 0) | ||
1175 | { | ||
1176 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Cannot_Read); | ||
1177 | } | ||
1178 | |||
1179 | // Update the 3 symbols which are required for CCS ETB receiver | ||
1180 | etbLib_buffer_start_addr[pHandle->id] = (uint32_t)pBuffer; //CCS ETB receiver will always get a linearized buffer for the non-EDMA ETB drain case | ||
1181 | etbLib_buffer_size[pHandle->id] = status.availableWords * 4; //Number of bytes available | ||
1182 | etbLib_buffer_data_start[pHandle->id] = etbLib_buffer_start_addr[pHandle->id]; //circular buffer wrap point, if equal to the start address, no unwrapping of the buffer is required | ||
1183 | |||
1184 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1185 | { | ||
1186 | /* ETB depth */ | ||
1187 | depth = *((volatile uint32_t*)ETB_RDP(pHandle->id)); | ||
1188 | } | ||
1189 | else | ||
1190 | { | ||
1191 | /* ETB depth */ | ||
1192 | value = (*((volatile uint32_t*)ETB_RDP(pHandle->id))); | ||
1193 | depth = (1 << (value-1)) << 10; | ||
1194 | } | ||
1195 | |||
1196 | /* Check if the buffer is wrapped or not; set read pointers | ||
1197 | * accordingly. | ||
1198 | */ | ||
1199 | if(status.isWrapped == 1) | ||
1200 | { | ||
1201 | startAddr = | ||
1202 | *((volatile uint32_t*)ETB_RWP(pHandle->id)) + startWord; | ||
1203 | } | ||
1204 | else | ||
1205 | { | ||
1206 | startAddr = 0x0 + startWord; | ||
1207 | } | ||
1208 | |||
1209 | /* Adjust the read size for the available user buffer and requested | ||
1210 | * data. | ||
1211 | */ | ||
1212 | if(bufferLength < status.availableWords) | ||
1213 | status.availableWords = bufferLength; | ||
1214 | |||
1215 | if(readLength < status.availableWords) | ||
1216 | status.availableWords = readLength; | ||
1217 | |||
1218 | /* Adjust to accomodate the start word. */ | ||
1219 | if(startWord < status.availableWords) | ||
1220 | status.availableWords = status.availableWords - startWord; | ||
1221 | else | ||
1222 | status.availableWords =0; | ||
1223 | |||
1224 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1225 | { | ||
1226 | // Not valid to write the RRP if TIETB has not wrapped | ||
1227 | if(status.isWrapped == 1) | ||
1228 | { | ||
1229 | /* Initialize the ETB RAM read pointer register with startAddr*/ | ||
1230 | *((volatile uint32_t*)ETB_RRP(pHandle->id)) = startAddr; | ||
1231 | |||
1232 | /* Clear the overflow flag*/ | ||
1233 | *((volatile uint32_t*)ETB_ICST(pHandle->id)) = TI_ETB_IRST_OVERFLOW; | ||
1234 | } | ||
1235 | } | ||
1236 | else | ||
1237 | { | ||
1238 | /* Initialize the ETB RAM read pointer register with startAddr*/ | ||
1239 | *((volatile uint32_t*)ETB_RRP(pHandle->id)) = startAddr; | ||
1240 | } | ||
1241 | |||
1242 | /* Now read trace data out of ETB */ | ||
1243 | for (idx = 0; idx < status.availableWords; idx++) | ||
1244 | { | ||
1245 | /* Read the ETB RAM read data register to retrieve trace data. | ||
1246 | * This would cause the read pointer register value to | ||
1247 | * auto-increment. | ||
1248 | */ | ||
1249 | pBuffer[idx] = *((volatile uint32_t*)ETB_RRD(pHandle->id)); | ||
1250 | |||
1251 | (*pRetLength)++; | ||
1252 | |||
1253 | startAddr++; | ||
1254 | |||
1255 | if(startAddr == depth) | ||
1256 | { | ||
1257 | /*Now wrap from begining */ | ||
1258 | startAddr = 0x0; | ||
1259 | *((volatile uint32_t*)ETB_RRP(pHandle->id)) = startAddr; | ||
1260 | } | ||
1261 | } | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | return eETB_Success; | ||
1266 | } | ||
1267 | |||
1268 | |||
1269 | /** | ||
1270 | * ETB_close- Close ETB programming module interface | ||
1271 | */ | ||
1272 | eETB_Error ETB_close(ETBHandle* pHandle) | ||
1273 | { | ||
1274 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
1275 | { | ||
1276 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1277 | } | ||
1278 | |||
1279 | #if !defined(C66AK2Hxx_CSSTM_ETB) && !defined(C66AK2Exx_CSSTM_ETB) && !defined(_OMAP54xx) | ||
1280 | |||
1281 | /* Disable DTF, if available */ | ||
1282 | if(Need_DTF(pHandle)) | ||
1283 | { | ||
1284 | // Claim Tag Clear | ||
1285 | *(volatile uint32_t*)(TAGCLR(pHandle->id)) = 0x1; | ||
1286 | |||
1287 | /* Disable ADTF */ | ||
1288 | *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) = *(volatile uint32_t*)(DTF_CNTL(pHandle->id)) & (~0x1); | ||
1289 | } | ||
1290 | |||
1291 | #endif | ||
1292 | |||
1293 | if(pHandle->ulContext == ETB_UNLOCK_VAL) | ||
1294 | { | ||
1295 | pHandle->ulContext = 0; | ||
1296 | } | ||
1297 | |||
1298 | #ifdef __linux | ||
1299 | { | ||
1300 | int i; | ||
1301 | cTools_memUnMap(virtural_ETB_BaseAddress[pHandle->id], SIZEOF_ETB_SPACE); | ||
1302 | cTools_memUnMap(virtural_DTF_BaseAddress[pHandle->id], SIZEOF_DTF_SPACE); | ||
1303 | virtural_ETB_BaseAddress[pHandle->id] = 0; | ||
1304 | virtural_DTF_BaseAddress[pHandle->id] = 0; | ||
1305 | |||
1306 | /* Only close the PSC if no other instances of ETBs are open */ | ||
1307 | for (i = 0; i < NUM_ETB_INSTANCES; i++) { | ||
1308 | if (virtural_ETB_BaseAddress[pHandle->id] != 0) break; | ||
1309 | } | ||
1310 | if ( i == NUM_ETB_INSTANCES) | ||
1311 | { | ||
1312 | cTools_memUnMap(virtural_PSC_BaseAddress, SIZEOF_PSC_SPACE); | ||
1313 | virtural_PSC_BaseAddress = 0; | ||
1314 | } | ||
1315 | } | ||
1316 | #endif | ||
1317 | |||
1318 | return eETB_Success; | ||
1319 | } | ||
1320 | |||
1321 | /** | ||
1322 | * ETB_flush - Flush the ETB and ADTF in c6484 case | ||
1323 | */ | ||
1324 | eETB_Error ETB_flush(ETBHandle* pHandle) | ||
1325 | { | ||
1326 | eETB_Error ret; | ||
1327 | |||
1328 | if(!pHandle || pHandle->ulContext != ETB_UNLOCK_VAL) | ||
1329 | { | ||
1330 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1331 | } | ||
1332 | |||
1333 | #ifdef DMA_SUPPORT | ||
1334 | // Stop the formatter + Flush to the ETB, if EDMA mode is enabled or its a STM-ETB | ||
1335 | if((pHandle->pDmaConfig != 0) || (pHandle->id == SYS_ETB_ID)) | ||
1336 | { | ||
1337 | ret = flush(pHandle, eETB_STOP_FORMATTER); | ||
1338 | } | ||
1339 | else // Only Flush to the ETB, if EDMA mode is disabled | ||
1340 | #endif | ||
1341 | { | ||
1342 | ret = flush(pHandle, eETB_OPT_NONE); | ||
1343 | } | ||
1344 | |||
1345 | return ret; | ||
1346 | } | ||
1347 | |||
1348 | /** | ||
1349 | * flush - internal function used to flush the ETB from both the ETB_Disable API | ||
1350 | * and the ETB_flush API. | ||
1351 | */ | ||
1352 | static eETB_Error flush(ETBHandle *pHandle, eETB_OPTIONS options) | ||
1353 | { | ||
1354 | eETB_Error ret = eETB_Success; | ||
1355 | uint32_t etbControl; | ||
1356 | uint32_t status; | ||
1357 | uint32_t retry; | ||
1358 | #if defined(C6670) || defined(C6678) | ||
1359 | |||
1360 | #ifdef DMA_SUPPORT | ||
1361 | |||
1362 | uint32_t rrp; | ||
1363 | uint32_t cntr = 0; | ||
1364 | |||
1365 | if(pHandle->pDmaConfig != 0) | ||
1366 | { | ||
1367 | // Check for both Stop On Full mode is enabled and ETBLib buffer is wrapped | ||
1368 | if((etbLib_bufferWrapped[pHandle->id][0] == 1) && (pHandle->pDmaConfig->mode == eDMA_Stop_Buffer)) | ||
1369 | { | ||
1370 | // Re-enable the ETB trace as the ETB trace was disabled by EDMA on buffer full | ||
1371 | /* Enable ETB data capture by writing ETB Control Register. */ | ||
1372 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) |= ETB_ENABLE; /* TraceCaptEn =1 */ | ||
1373 | } | ||
1374 | } | ||
1375 | |||
1376 | /* If using DMA to drain the ETB, disable the event coming from the ETB | ||
1377 | * interrupts in case the flush causes the ETB to cross the half-full or | ||
1378 | * full threshold. If this were to occur and start a DMA transaction the | ||
1379 | * data or PaRAM could get corrupted when the ETB_flush_dma function is | ||
1380 | * called. After the flush occurs the read from the Event Register will | ||
1381 | * identify if an interrupt occurred from the ETB. | ||
1382 | * | ||
1383 | * This code will only get executed on the 1st call, it is expected this | ||
1384 | * function is called directly before calling the DMA flush function. | ||
1385 | * Afterwards the ETB read pointer will not be on an even half or full | ||
1386 | * boundary and the while loop below would timeout. The configuration | ||
1387 | * function will need to get called before another capture can occur. | ||
1388 | */ | ||
1389 | if((pHandle->pDmaConfig != 0) && (pHandle->dmaStatus.flushRequired)) | ||
1390 | { | ||
1391 | uint32_t etbHalfSize; | ||
1392 | |||
1393 | /* By this point the ETB read register should be stable and at 0 or half | ||
1394 | * the ETB size, if not, then wait for the previous DMA to complete. | ||
1395 | */ | ||
1396 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
1397 | etbHalfSize = *((volatile uint32_t*)ETB_RDP(pHandle->id)); | ||
1398 | etbHalfSize /= 2; | ||
1399 | while((rrp != 0) && (rrp != etbHalfSize)) | ||
1400 | { | ||
1401 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
1402 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1403 | break; | ||
1404 | } | ||
1405 | |||
1406 | /* Disable Event Register */ | ||
1407 | if(pHandle->pDmaConfig->clrChannel > 31) | ||
1408 | { | ||
1409 | EDMA3_EECRH_REG(pHandle->pDmaConfig->cc) = | ||
1410 | (1 << (pHandle->pDmaConfig->clrChannel-32)); | ||
1411 | } | ||
1412 | else | ||
1413 | { | ||
1414 | EDMA3_EECR_REG(pHandle->pDmaConfig->cc) = | ||
1415 | (1 << pHandle->pDmaConfig->clrChannel); | ||
1416 | } | ||
1417 | |||
1418 | /* Clear Interrupt Pending register for ETB channel */ | ||
1419 | if(pHandle->pDmaConfig->etbChannel > 31) | ||
1420 | { | ||
1421 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
1422 | (1 << (pHandle->pDmaConfig->etbChannel - 32)); | ||
1423 | } | ||
1424 | else | ||
1425 | { | ||
1426 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
1427 | (1 << pHandle->pDmaConfig->etbChannel); | ||
1428 | } | ||
1429 | } | ||
1430 | |||
1431 | #endif | ||
1432 | |||
1433 | #elif defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
1434 | |||
1435 | #ifdef DMA_SUPPORT | ||
1436 | |||
1437 | uint32_t rrp; | ||
1438 | uint32_t cntr = 0; | ||
1439 | |||
1440 | if(pHandle->pDmaConfig != 0) | ||
1441 | { | ||
1442 | // Check for both Stop On Full mode is enabled and ETBLib buffer is wrapped | ||
1443 | if((etbLib_bufferWrapped[pHandle->id][0] == 1) && (pHandle->pDmaConfig->mode == eDMA_Stop_Buffer)) | ||
1444 | { | ||
1445 | // Re-enable the ETB trace as the ETB trace was disabled by EDMA on buffer full | ||
1446 | /* Enable ETB data capture by writing ETB Control Register. */ | ||
1447 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) |= ETB_ENABLE; /* TraceCaptEn =1 */ | ||
1448 | } | ||
1449 | } | ||
1450 | |||
1451 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1452 | { | ||
1453 | |||
1454 | /* If using DMA to drain the ETB, disable the event coming from the ETB | ||
1455 | * interrupts in case the flush causes the ETB to cross the half-full or | ||
1456 | * full threshold. If this were to occur and start a DMA transaction the | ||
1457 | * data or PaRAM could get corrupted when the ETB_flush_dma function is | ||
1458 | * called. After the flush occurs the read from the Event Register will | ||
1459 | * identify if an interrupt occurred from the ETB. | ||
1460 | * | ||
1461 | * This code will only get executed on the 1st call, it is expected this | ||
1462 | * function is called directly before calling the DMA flush function. | ||
1463 | * Afterwards the ETB read pointer will not be on an even half or full | ||
1464 | * boundary and the while loop below would timeout. The configuration | ||
1465 | * function will need to get called before another capture can occur. | ||
1466 | */ | ||
1467 | if((pHandle->pDmaConfig != 0) && (pHandle->dmaStatus.flushRequired)) | ||
1468 | { | ||
1469 | uint32_t etbHalfSize; | ||
1470 | |||
1471 | /* By this point the ETB read register should be stable and at 0 or half | ||
1472 | * the ETB size, if not, then wait for the previous DMA to complete. | ||
1473 | */ | ||
1474 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
1475 | etbHalfSize = *((volatile uint32_t*)ETB_RDP(pHandle->id)); | ||
1476 | etbHalfSize /= 2; | ||
1477 | while((rrp != 0) && (rrp != etbHalfSize)) | ||
1478 | { | ||
1479 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
1480 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1481 | break; | ||
1482 | } | ||
1483 | |||
1484 | /* Disable etbhalf Event Register */ | ||
1485 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
1486 | { | ||
1487 | EDMA3_EECRH_REG(pHandle->pDmaConfig->cc) = | ||
1488 | (1 << (pHandle->pDmaConfig->etbhalfChannel-32)); | ||
1489 | } | ||
1490 | else | ||
1491 | { | ||
1492 | EDMA3_EECR_REG(pHandle->pDmaConfig->cc) = | ||
1493 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
1494 | } | ||
1495 | |||
1496 | /* Disable etbfull Event Register */ | ||
1497 | if(pHandle->pDmaConfig->etbfullChannel > 31) | ||
1498 | { | ||
1499 | EDMA3_EECRH_REG(pHandle->pDmaConfig->cc) = | ||
1500 | (1 << (pHandle->pDmaConfig->etbfullChannel-32)); | ||
1501 | } | ||
1502 | else | ||
1503 | { | ||
1504 | EDMA3_EECR_REG(pHandle->pDmaConfig->cc) = | ||
1505 | (1 << pHandle->pDmaConfig->etbfullChannel); | ||
1506 | } | ||
1507 | |||
1508 | /* Clear Interrupt Pending register for ETB half channel */ | ||
1509 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
1510 | { | ||
1511 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
1512 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32)); | ||
1513 | } | ||
1514 | else | ||
1515 | { | ||
1516 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
1517 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
1518 | } | ||
1519 | } | ||
1520 | } | ||
1521 | |||
1522 | #endif | ||
1523 | #endif | ||
1524 | |||
1525 | #ifdef TCI6484 | ||
1526 | /* In the TCI6484 case the DTF flush is not integrated so we must do a manual flush */ | ||
1527 | if(Need_DTF(pHandle)) | ||
1528 | { | ||
1529 | ret = DTF_flush(pHandle->id); | ||
1530 | if ( eETB_Success != ret ) | ||
1531 | { | ||
1532 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1533 | } | ||
1534 | } | ||
1535 | #endif | ||
1536 | /* Flush ETB and DTF*/ | ||
1537 | etbControl = *((volatile uint32_t*)ETB_FFCR(pHandle->id)); | ||
1538 | |||
1539 | if(options == eETB_STOP_FORMATTER) | ||
1540 | { | ||
1541 | etbControl |= (1 << 12); /* Stop Formatter bit */ | ||
1542 | } | ||
1543 | *((volatile uint32_t*)ETB_FFCR(pHandle->id)) = etbControl; | ||
1544 | |||
1545 | etbControl |= (1<<6); /* Manual flush */ | ||
1546 | *((volatile uint32_t*)ETB_FFCR(pHandle->id)) = etbControl; | ||
1547 | |||
1548 | // Wait for the flush to complete | ||
1549 | retry = 1000; | ||
1550 | do | ||
1551 | { | ||
1552 | status = *(volatile uint32_t*)ETB_FFSR(pHandle->id); | ||
1553 | retry--; | ||
1554 | } while( ( ( status & ETB_FLUSH_INPROGRESS ) != 0 ) && ( retry != 0 ) ); | ||
1555 | |||
1556 | #if defined(C6670) || defined(C6678) | ||
1557 | |||
1558 | #ifdef DMA_SUPPORT | ||
1559 | |||
1560 | /* If using the DMA to drain the ETB, will need to check if the flush caused | ||
1561 | * a threshold interrupt from the ETB. | ||
1562 | */ | ||
1563 | if((pHandle->pDmaConfig != 0) && (pHandle->dmaStatus.flushRequired)) | ||
1564 | { | ||
1565 | uint32_t regValue; | ||
1566 | |||
1567 | /* Read the event register, check for an event, then start and wait for | ||
1568 | * the DMA to complete before continuing. | ||
1569 | */ | ||
1570 | if(pHandle->pDmaConfig->clrChannel > 31) | ||
1571 | { | ||
1572 | regValue = EDMA3_ERH_REG(pHandle->pDmaConfig->cc) & | ||
1573 | (1 << (pHandle->pDmaConfig->clrChannel-32)); | ||
1574 | EDMA3_EESRH_REG(pHandle->pDmaConfig->cc) = | ||
1575 | (1 << (pHandle->pDmaConfig->clrChannel-32)); | ||
1576 | } | ||
1577 | else | ||
1578 | { | ||
1579 | regValue = EDMA3_ER_REG(pHandle->pDmaConfig->cc) & | ||
1580 | (1 << pHandle->pDmaConfig->clrChannel); | ||
1581 | EDMA3_EESR_REG(pHandle->pDmaConfig->cc) = | ||
1582 | (1 << pHandle->pDmaConfig->clrChannel); | ||
1583 | } | ||
1584 | |||
1585 | if(regValue) | ||
1586 | { | ||
1587 | cntr = 0; | ||
1588 | if(pHandle->pDmaConfig->etbChannel > 31) | ||
1589 | { | ||
1590 | while((EDMA3_IPRH_REG(pHandle->pDmaConfig->cc) & | ||
1591 | (1 << (pHandle->pDmaConfig->etbChannel - 32))) == 0) | ||
1592 | { | ||
1593 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1594 | break; | ||
1595 | } | ||
1596 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
1597 | (1 << (pHandle->pDmaConfig->etbChannel - 32)); | ||
1598 | } | ||
1599 | else | ||
1600 | { | ||
1601 | while((EDMA3_IPR_REG(pHandle->pDmaConfig->cc) & | ||
1602 | (1 << pHandle->pDmaConfig->etbChannel)) == 0) | ||
1603 | { | ||
1604 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1605 | break; | ||
1606 | } | ||
1607 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
1608 | (1 << pHandle->pDmaConfig->etbChannel); | ||
1609 | } | ||
1610 | } | ||
1611 | |||
1612 | /* Clear flag indicating not to excercise DMA code for any consecutive calls | ||
1613 | to this function. | ||
1614 | */ | ||
1615 | pHandle->dmaStatus.flushRequired = 0; | ||
1616 | } | ||
1617 | |||
1618 | #endif | ||
1619 | |||
1620 | #elif defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
1621 | |||
1622 | #ifdef DMA_SUPPORT | ||
1623 | |||
1624 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1625 | { | ||
1626 | /* If using the DMA to drain the ETB, will need to check if the flush caused | ||
1627 | * a threshold interrupt from the ETB. | ||
1628 | */ | ||
1629 | if((pHandle->pDmaConfig != 0) && (pHandle->dmaStatus.flushRequired)) | ||
1630 | { | ||
1631 | uint32_t regValue1, regValue2; | ||
1632 | |||
1633 | /* Read the event register, check for a etbhalf or etbfull event, then start and wait for | ||
1634 | * the DMA to complete before continuing. | ||
1635 | */ | ||
1636 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
1637 | { | ||
1638 | regValue1 = EDMA3_ERH_REG(pHandle->pDmaConfig->cc) & | ||
1639 | (1 << (pHandle->pDmaConfig->etbhalfChannel-32)); | ||
1640 | EDMA3_EESRH_REG(pHandle->pDmaConfig->cc) = | ||
1641 | (1 << (pHandle->pDmaConfig->etbhalfChannel-32)); | ||
1642 | } | ||
1643 | else | ||
1644 | { | ||
1645 | regValue1 = EDMA3_ER_REG(pHandle->pDmaConfig->cc) & | ||
1646 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
1647 | EDMA3_EESR_REG(pHandle->pDmaConfig->cc) = | ||
1648 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
1649 | } | ||
1650 | |||
1651 | if(pHandle->pDmaConfig->etbfullChannel > 31) | ||
1652 | { | ||
1653 | regValue2 = EDMA3_ERH_REG(pHandle->pDmaConfig->cc) & | ||
1654 | (1 << (pHandle->pDmaConfig->etbfullChannel-32)); | ||
1655 | EDMA3_EESRH_REG(pHandle->pDmaConfig->cc) = | ||
1656 | (1 << (pHandle->pDmaConfig->etbfullChannel-32)); | ||
1657 | } | ||
1658 | else | ||
1659 | { | ||
1660 | regValue2 = EDMA3_ER_REG(pHandle->pDmaConfig->cc) & | ||
1661 | (1 << pHandle->pDmaConfig->etbfullChannel); | ||
1662 | EDMA3_EESR_REG(pHandle->pDmaConfig->cc) = | ||
1663 | (1 << pHandle->pDmaConfig->etbfullChannel); | ||
1664 | } | ||
1665 | |||
1666 | if((regValue1 != 0) || (regValue2 != 0)) | ||
1667 | { | ||
1668 | cntr = 0; | ||
1669 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
1670 | { | ||
1671 | while((EDMA3_IPRH_REG(pHandle->pDmaConfig->cc) & | ||
1672 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32))) == 0) | ||
1673 | { | ||
1674 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1675 | break; | ||
1676 | } | ||
1677 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
1678 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32)); | ||
1679 | } | ||
1680 | else | ||
1681 | { | ||
1682 | while((EDMA3_IPR_REG(pHandle->pDmaConfig->cc) & | ||
1683 | (1 << pHandle->pDmaConfig->etbhalfChannel)) == 0) | ||
1684 | { | ||
1685 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
1686 | break; | ||
1687 | } | ||
1688 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
1689 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1693 | /* Clear flag indicating not to excercise DMA code for any consecutive calls | ||
1694 | to this function. | ||
1695 | */ | ||
1696 | pHandle->dmaStatus.flushRequired = 0; | ||
1697 | } | ||
1698 | |||
1699 | *((volatile uint32_t*)ETB_FFCR(pHandle->id)) = 0; | ||
1700 | } | ||
1701 | |||
1702 | #endif | ||
1703 | #endif | ||
1704 | |||
1705 | if ( retry == 0 ) | ||
1706 | { | ||
1707 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1708 | } | ||
1709 | |||
1710 | return ret; | ||
1711 | } | ||
1712 | |||
1713 | #ifdef DMA_SUPPORT | ||
1714 | /******************************************************************************/ | ||
1715 | /*! \copydoc ETB_config_dma | ||
1716 | */ | ||
1717 | eETB_Error ETB_config_dma(ETBHandle* pHandle, const DMAConfig *pConfig) | ||
1718 | { | ||
1719 | #if defined(C6670) || defined(C6678) | ||
1720 | |||
1721 | uint32_t paramBase; | ||
1722 | uint16_t paramIdx; | ||
1723 | uint32_t etbSize; | ||
1724 | uint32_t etbHalfSize; | ||
1725 | uint32_t clr1param; | ||
1726 | uint32_t clr2param; | ||
1727 | uint32_t etb1param; | ||
1728 | uint32_t etb2param; | ||
1729 | uint32_t etb3param; | ||
1730 | struct edma3_param param; | ||
1731 | /* Fixed location to store DMA configuration parameters */ | ||
1732 | static DMAConfig dmaConfig[NUM_ETB_INSTANCES]; | ||
1733 | |||
1734 | // For C6678, Index = 0 (CIC2), Index = 1 (CIC3) | ||
1735 | // For C6670, Index = 0 (CIC1), Index = 1 (CIC2) | ||
1736 | uint8_t cic_index = 0; | ||
1737 | |||
1738 | if(!pHandle || (pHandle->ulContext != ETB_UNLOCK_VAL) || !pConfig) | ||
1739 | { | ||
1740 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1741 | } | ||
1742 | |||
1743 | if ((TI_ETB_TI_MODE & *((volatile uint32_t*)ETB_TI_CTL(pHandle->id))) != TI_ETB_TI_MODE ) | ||
1744 | { | ||
1745 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1746 | } | ||
1747 | |||
1748 | #if defined(C6670) | ||
1749 | if(!(pConfig->cic == eCIC_1 || pConfig->cic == eCIC_2)) | ||
1750 | { | ||
1751 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1752 | } | ||
1753 | |||
1754 | #elif defined(C6678) | ||
1755 | if(!(pConfig->cic == eCIC_2 || pConfig->cic == eCIC_3)) | ||
1756 | { | ||
1757 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1758 | } | ||
1759 | |||
1760 | #endif | ||
1761 | |||
1762 | /* Validate the Channel Controller value and set the Parameter RAM base | ||
1763 | * address value | ||
1764 | */ | ||
1765 | switch(pConfig->cc) | ||
1766 | { | ||
1767 | case 0: | ||
1768 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(0); | ||
1769 | break; | ||
1770 | case 1: | ||
1771 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(1); | ||
1772 | break; | ||
1773 | case 2: | ||
1774 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(2); | ||
1775 | break; | ||
1776 | default: | ||
1777 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1778 | } | ||
1779 | |||
1780 | /* Calculate the address values for the specific PaRAM's. The PaRAM numbers | ||
1781 | * for the DMA channels provided are determined by reading the DMA to | ||
1782 | * PaRAM mapping registers. | ||
1783 | */ | ||
1784 | paramIdx = (EDMA3_DCHMAP_REG(pConfig->cc,pConfig->clrChannel) >> 5); | ||
1785 | clr1param = paramBase + (0x20 * paramIdx); | ||
1786 | clr2param = paramBase + (0x20 * pConfig->linkparam[0]); | ||
1787 | paramIdx = (EDMA3_DCHMAP_REG(pConfig->cc,pConfig->etbChannel) >> 5); | ||
1788 | etb1param = paramBase + (0x20 * paramIdx); | ||
1789 | etb2param = paramBase + (0x20 * pConfig->linkparam[1]); | ||
1790 | etb3param = paramBase + (0x20 * pConfig->linkparam[2]); | ||
1791 | |||
1792 | etbLib_bufferWrapped[pHandle->id][0] = 0; | ||
1793 | etbLib_bufferWrapped[pHandle->id][1] = 1; | ||
1794 | |||
1795 | /* Store configuration information */ | ||
1796 | dmaConfig[Handle_index(pHandle->id)].cc = pConfig->cc; | ||
1797 | dmaConfig[Handle_index(pHandle->id)].clrChannel = pConfig->clrChannel; | ||
1798 | dmaConfig[Handle_index(pHandle->id)].etbChannel = pConfig->etbChannel; | ||
1799 | dmaConfig[Handle_index(pHandle->id)].linkparam[0] = pConfig->linkparam[0]; | ||
1800 | dmaConfig[Handle_index(pHandle->id)].linkparam[1] = pConfig->linkparam[1]; | ||
1801 | dmaConfig[Handle_index(pHandle->id)].linkparam[2] = pConfig->linkparam[2]; | ||
1802 | dmaConfig[Handle_index(pHandle->id)].dbufAddress = pConfig->dbufAddress; | ||
1803 | dmaConfig[Handle_index(pHandle->id)].dbufWords = pConfig->dbufWords; | ||
1804 | dmaConfig[Handle_index(pHandle->id)].mode = pConfig->mode; | ||
1805 | dmaConfig[Handle_index(pHandle->id)].cic = pConfig->cic; | ||
1806 | pHandle->pDmaConfig = &dmaConfig[Handle_index(pHandle->id)]; | ||
1807 | |||
1808 | /* Get the size of the ETB for this instance to determine the count values | ||
1809 | * required for the EDMA parameter ram (PaRAM) configuration. The size if | ||
1810 | * provided in words, convert to bytes for calculations. The count values | ||
1811 | * for the EDMA are in bytes. | ||
1812 | */ | ||
1813 | etbSize = *((volatile uint32_t*)ETB_RDP(pHandle->id)); | ||
1814 | etbSize *= 4; | ||
1815 | etbHalfSize = etbSize / 2; | ||
1816 | |||
1817 | #if defined(C6670) | ||
1818 | |||
1819 | cic_index = pHandle->pDmaConfig->cic - 1; | ||
1820 | |||
1821 | #elif defined(C6678) | ||
1822 | |||
1823 | cic_index = pHandle->pDmaConfig->cic - 2; | ||
1824 | |||
1825 | #endif | ||
1826 | |||
1827 | /* The following 2 PaRAM's are used to clear the INTC1 event register. When | ||
1828 | * the bit for the specific event in the register is set, no other incoming | ||
1829 | * events will get forwarded to its corresponding output until the event | ||
1830 | * has been cleared. | ||
1831 | * The early completion is used to chain to the start of the ETB transfer | ||
1832 | * PaRAM. | ||
1833 | */ | ||
1834 | param.options = (PARAM_OPT_TCCHEN | | ||
1835 | PARAM_OPT_TCC(pConfig->etbChannel) | | ||
1836 | PARAM_OPT_TCC_EARLY| | ||
1837 | PARAM_OPT_AB_SYNC); | ||
1838 | param.src_addr = GET_GLOBAL_ADDR(&etbLib_cpCicEventClearValue[cic_index][pHandle->id][0]); | ||
1839 | param.ab_cnt = (PARAM_BCNT(2) | PARAM_ACNT(4)); | ||
1840 | param.dst_addr = etbLib_cpCicEventClearIndexReg[cic_index]; | ||
1841 | param.srcdst_bidx = 4; | ||
1842 | param.link_bcnt = PARAM_LINK(clr2param); | ||
1843 | param.srcdst_cidx = 0; | ||
1844 | param.ccnt = 1; | ||
1845 | |||
1846 | /* Copy local structure to actual PaRAM memory locations */ | ||
1847 | *(struct edma3_param *)clr1param = param; | ||
1848 | *(struct edma3_param *)clr2param = param; | ||
1849 | |||
1850 | /* Create the PaRAM entries that will be used to transfer data from ETB RAM | ||
1851 | * Burst Data Read Register locations to a drain buffer in memory. The | ||
1852 | * second PaRAM is used once to transfer a buffer wrapped flag that is used | ||
1853 | * to indicate the drain buffer has wrapped. It is linked to the 3rd PaRAM | ||
1854 | * that is used to reload with initial values to tranfer data from ETB. | ||
1855 | */ | ||
1856 | param.options = (PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | | ||
1857 | PARAM_OPT_TCCHEN | | ||
1858 | PARAM_OPT_TCC(pConfig->etbChannel) | | ||
1859 | PARAM_OPT_AB_SYNC); | ||
1860 | param.src_addr = ETB_RBD(pHandle->id); | ||
1861 | param.ab_cnt = PARAM_BCNT(etbHalfSize / ETB_BURST_SIZE) | PARAM_ACNT(ETB_BURST_SIZE); | ||
1862 | param.dst_addr = pConfig->dbufAddress; | ||
1863 | param.srcdst_bidx = PARAM_DST_BIDX(ETB_BURST_SIZE); | ||
1864 | param.link_bcnt = PARAM_LINK(etb2param); | ||
1865 | param.srcdst_cidx = PARAM_DST_CIDX(etbHalfSize); | ||
1866 | param.ccnt = (pConfig->dbufWords*4) / etbHalfSize; | ||
1867 | |||
1868 | /* Set the DMA status to the actual number of words used in the provided | ||
1869 | * buffer, also reset any previous status settings. | ||
1870 | */ | ||
1871 | pHandle->dmaStatus.startAddr = 0; | ||
1872 | pHandle->dmaStatus.availableWords = 0; | ||
1873 | pHandle->dmaStatus.isWrapped = 0; | ||
1874 | pHandle->dmaStatus.dbufAddress = 0; | ||
1875 | pHandle->dmaStatus.flushRequired = 1; | ||
1876 | pHandle->dmaStatus.dbufWords = (param.ccnt * etbHalfSize) / 4; | ||
1877 | |||
1878 | /* Copy local structure to actual PaRAM memory locations */ | ||
1879 | *(struct edma3_param *)etb1param = param; | ||
1880 | |||
1881 | if(pConfig->mode != eDMA_Stop_Buffer) | ||
1882 | { | ||
1883 | |||
1884 | /* Change the 3rd PaRAM to not link to 2nd for wrap processing, just | ||
1885 | * link to self for reloading purposes, Transfer chaining completion is | ||
1886 | * also not needed except for the 1st occurance. | ||
1887 | */ | ||
1888 | param.options = PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | PARAM_OPT_AB_SYNC; | ||
1889 | param.link_bcnt = PARAM_LINK(etb3param); | ||
1890 | } | ||
1891 | else | ||
1892 | { | ||
1893 | /* If the DMA mode has been configured as non-circular, configure etbparam3 to disable ETB trace | ||
1894 | * set the link value to a NULL after disabling ETB trace. | ||
1895 | */ | ||
1896 | |||
1897 | param.options = PARAM_OPT_TCC_EARLY; | ||
1898 | param.src_addr = GET_GLOBAL_ADDR(&etb_disable); | ||
1899 | param.ab_cnt = (PARAM_BCNT(1) | PARAM_ACNT(4)); | ||
1900 | param.dst_addr = ETB_CTL(pHandle->id); | ||
1901 | param.srcdst_bidx = 0; | ||
1902 | param.link_bcnt = PARAM_LINK(0xffff); | ||
1903 | param.srcdst_cidx = 0; | ||
1904 | param.ccnt = 1; | ||
1905 | } | ||
1906 | |||
1907 | *(struct edma3_param *)etb3param = param; | ||
1908 | |||
1909 | if(pConfig->mode != eDMA_Stop_Buffer) | ||
1910 | { | ||
1911 | /* 2nd PaRAM configuration, no transfer chaining completion, but an early | ||
1912 | * link completion. | ||
1913 | */ | ||
1914 | param.options = PARAM_OPT_TCC_EARLY; | ||
1915 | } | ||
1916 | else | ||
1917 | { | ||
1918 | /* For Stop on full buffer mode, link to etb3param which disables ETB trace capture */ | ||
1919 | param.options = (PARAM_OPT_TCC_EARLY | PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | | ||
1920 | PARAM_OPT_TCCHEN | | ||
1921 | PARAM_OPT_TCC(pConfig->etbChannel)); | ||
1922 | } | ||
1923 | |||
1924 | param.src_addr = GET_GLOBAL_ADDR(&etbLib_bufferWrapped[pHandle->id][1]); | ||
1925 | param.ab_cnt = PARAM_BCNT(1) | PARAM_ACNT(4); | ||
1926 | param.dst_addr = GET_GLOBAL_ADDR(&etbLib_bufferWrapped[pHandle->id][0]); | ||
1927 | param.srcdst_bidx = 0; | ||
1928 | param.link_bcnt = PARAM_LINK(etb3param); | ||
1929 | param.srcdst_cidx = 0; | ||
1930 | param.ccnt = 1; | ||
1931 | |||
1932 | /* Copy local structure to actual PaRAM memory locations */ | ||
1933 | *(struct edma3_param *)etb2param = param; | ||
1934 | |||
1935 | /* Enable event for specific channel that is used to clear the INTCx | ||
1936 | * interrupt status. This is the EDMA event that is used to start the DMA | ||
1937 | * transactions. | ||
1938 | */ | ||
1939 | if(pConfig->clrChannel > 31) | ||
1940 | { | ||
1941 | EDMA3_EESRH_REG(pConfig->cc) = (1 << (pConfig->clrChannel-32)); | ||
1942 | } | ||
1943 | else | ||
1944 | { | ||
1945 | EDMA3_EESR_REG(pConfig->cc) = (1 << pConfig->clrChannel); | ||
1946 | } | ||
1947 | |||
1948 | #elif defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
1949 | |||
1950 | uint32_t paramBase; | ||
1951 | uint32_t etbSize; | ||
1952 | uint32_t etbHalfSize; | ||
1953 | uint32_t etb1param; | ||
1954 | uint32_t etb2param; | ||
1955 | uint32_t etb3param; | ||
1956 | struct edma3_param param; | ||
1957 | |||
1958 | /* Fixed location to store DMA configuration parameters */ | ||
1959 | static DMAConfigInt dmaConfig[NUM_ETB_INSTANCES]; | ||
1960 | |||
1961 | if(!pHandle || (pHandle->ulContext != ETB_UNLOCK_VAL) || !pConfig) | ||
1962 | { | ||
1963 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1964 | } | ||
1965 | |||
1966 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1967 | { | ||
1968 | if ((TI_ETB_TI_MODE & *((volatile uint32_t*)ETB_TI_CTL(pHandle->id))) != TI_ETB_TI_MODE ) | ||
1969 | { | ||
1970 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
1971 | } | ||
1972 | } | ||
1973 | |||
1974 | /* Store configuration information */ | ||
1975 | |||
1976 | #if defined(C6657) | ||
1977 | |||
1978 | dmaConfig[Handle_index(pHandle->id)].cc = 2; //The ETB half-full and full events are directly connected to EDMA CC in C6657 | ||
1979 | if(pHandle->id == SYS_ETB_ID) | ||
1980 | { | ||
1981 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC_TETBHFULLINT; //ETB half-full event | ||
1982 | dmaConfig[Handle_index(pHandle->id)].etbfullChannel = EDMACC_TETBFULLINT; //ETB full event | ||
1983 | } | ||
1984 | else | ||
1985 | { | ||
1986 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC_TETBHFULLINT0 + pHandle->id; //ETB half-full event | ||
1987 | dmaConfig[Handle_index(pHandle->id)].etbfullChannel = EDMACC_TETBFULLINT0 + pHandle->id; //ETB full event | ||
1988 | } | ||
1989 | |||
1990 | #endif | ||
1991 | |||
1992 | #if defined(C66AK2Hxx) | ||
1993 | |||
1994 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
1995 | { | ||
1996 | if(pHandle->id < 4) | ||
1997 | { | ||
1998 | dmaConfig[Handle_index(pHandle->id)].cc = 3; //The core 0-3 ETB half-full and full events are directly connected to EDMA CC # 3 in 6AK2Hxx | ||
1999 | } | ||
2000 | else | ||
2001 | { | ||
2002 | dmaConfig[Handle_index(pHandle->id)].cc = 2; //The core 4-7 ETB half-full and full events are directly connected to EDMA CC # 2 in 6AK2Hxx | ||
2003 | } | ||
2004 | |||
2005 | if(pHandle->id < 4) | ||
2006 | { | ||
2007 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC3_TETBHFULLINT0 + (pHandle->id * 2); //ETB half-full event | ||
2008 | dmaConfig[Handle_index(pHandle->id)].etbfullChannel = EDMACC3_TETBFULLINT0 + (pHandle->id * 2); //ETB full event | ||
2009 | } | ||
2010 | else | ||
2011 | { | ||
2012 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC2_TETBHFULLINT4 + ((pHandle->id-4) * 2); //ETB half-full event | ||
2013 | dmaConfig[Handle_index(pHandle->id)].etbfullChannel = EDMACC2_TETBFULLINT4 + ((pHandle->id-4) * 2); //ETB full event | ||
2014 | } | ||
2015 | } | ||
2016 | else | ||
2017 | { | ||
2018 | //Setup SYS ETB or CSSTM ETB for DMA drain mode | ||
2019 | //TBR system bridge operation | ||
2020 | |||
2021 | // Setup TBR in system bridge (DMA) mode | ||
2022 | *((volatile uint32_t*)ETB_CTL(pHandle->id)) |= TBR_BRIDGE_MODE; | ||
2023 | |||
2024 | dmaConfig[Handle_index(pHandle->id)].cc = 4; //The DebugSS TBR and Tetris TBR DMA events are directly connected to EDMA CC # 3 in 6AK2Hxx | ||
2025 | |||
2026 | #if defined(C66AK2Hxx_CSSTM_ETB) | ||
2027 | |||
2028 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC4_TETRISTBR_DMAINT; //TBR DMA event | ||
2029 | |||
2030 | #else | ||
2031 | |||
2032 | dmaConfig[Handle_index(pHandle->id)].etbhalfChannel = EDMACC4_DBGTBR_DMAINT; //TBR DMA event | ||
2033 | |||
2034 | #endif | ||
2035 | //Setup DMA trigger thresholds | ||
2036 | *((volatile uint32_t*)TBR_OUTLVL(pHandle->id)) = ((TBR_NUMBLOCK << 8) | TBR_BLOCKSZ); | ||
2037 | |||
2038 | //Enable DMA trigger | ||
2039 | *((volatile uint32_t*)TBR_IRQENABLE_SET(pHandle->id)) = TBR_IRST_DAV; | ||
2040 | |||
2041 | } | ||
2042 | |||
2043 | #endif | ||
2044 | |||
2045 | dmaConfig[Handle_index(pHandle->id)].linkparam[0] = pConfig->linkparam[0]; | ||
2046 | dmaConfig[Handle_index(pHandle->id)].linkparam[1] = pConfig->linkparam[1]; | ||
2047 | dmaConfig[Handle_index(pHandle->id)].linkparam[2] = pConfig->linkparam[2]; | ||
2048 | dmaConfig[Handle_index(pHandle->id)].dbufAddress = pConfig->dbufAddress; | ||
2049 | dmaConfig[Handle_index(pHandle->id)].dbufWords = pConfig->dbufWords; | ||
2050 | dmaConfig[Handle_index(pHandle->id)].mode = pConfig->mode; | ||
2051 | pHandle->pDmaConfig = &dmaConfig[Handle_index(pHandle->id)]; | ||
2052 | |||
2053 | /* Validate the Channel Controller value and set the Parameter RAM base | ||
2054 | * address value | ||
2055 | */ | ||
2056 | switch(pHandle->pDmaConfig->cc) | ||
2057 | { | ||
2058 | case 0: | ||
2059 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(0); | ||
2060 | break; | ||
2061 | case 1: | ||
2062 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(1); | ||
2063 | break; | ||
2064 | case 2: | ||
2065 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(2); | ||
2066 | break; | ||
2067 | case 3: | ||
2068 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(3); | ||
2069 | break; | ||
2070 | case 4: | ||
2071 | paramBase = EDMA_TPCC_PARAM_BASE_ADDR(4); | ||
2072 | break; | ||
2073 | default: | ||
2074 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2075 | } | ||
2076 | |||
2077 | // Mapping linkparam[0] to the ETB half channel | ||
2078 | EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc,pHandle->pDmaConfig->etbhalfChannel) = (pHandle->pDmaConfig->linkparam[0] << 5); | ||
2079 | |||
2080 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
2081 | { | ||
2082 | // Mapping ETB full channel is only required for TI-ETB | ||
2083 | // Mapping linkparam[0] to the ETB full channel | ||
2084 | EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc,pHandle->pDmaConfig->etbfullChannel) = (pHandle->pDmaConfig->linkparam[0] << 5); | ||
2085 | } | ||
2086 | |||
2087 | /* Calculate the param address for etb1param, etb2param and etb3param | ||
2088 | */ | ||
2089 | |||
2090 | etb1param = paramBase + (0x20 * pConfig->linkparam[0]); | ||
2091 | etb2param = paramBase + (0x20 * pConfig->linkparam[1]); | ||
2092 | etb3param = paramBase + (0x20 * pConfig->linkparam[2]); | ||
2093 | |||
2094 | etbLib_bufferWrapped[pHandle->id][0] = 0; | ||
2095 | etbLib_bufferWrapped[pHandle->id][1] = 1; | ||
2096 | |||
2097 | /* Create the PaRAM entries that will be used to transfer data from ETB RAM | ||
2098 | * Burst Data Read Register locations to a drain buffer in memory. The | ||
2099 | * second PaRAM is used once to transfer a buffer wrapped flag that is used | ||
2100 | * to indicate the drain buffer has wrapped. It is linked to the 3rd PaRAM | ||
2101 | * that is used to reload with initial values to transfer data from ETB. | ||
2102 | */ | ||
2103 | param.options = (PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | | ||
2104 | PARAM_OPT_TCCHEN | | ||
2105 | PARAM_OPT_TCC(pHandle->pDmaConfig->etbhalfChannel) | | ||
2106 | PARAM_OPT_AB_SYNC); | ||
2107 | |||
2108 | /* Get the size of the ETB for this instance to determine the count values | ||
2109 | * required for the EDMA parameter ram (PaRAM) configuration. The size if | ||
2110 | * provided in words, convert to bytes for calculations. The count values | ||
2111 | * for the EDMA are in bytes. | ||
2112 | */ | ||
2113 | |||
2114 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
2115 | { | ||
2116 | // get ETB buffer size | ||
2117 | etbSize = *((volatile uint32_t*)ETB_RDP(pHandle->id)); | ||
2118 | |||
2119 | // get starting address of the ETB buffer | ||
2120 | param.src_addr = ETB_RBD(pHandle->id); | ||
2121 | } | ||
2122 | else | ||
2123 | { | ||
2124 | // get TBR buffer size | ||
2125 | etbSize = (*((volatile uint32_t*)ETB_RDP(pHandle->id))); | ||
2126 | etbSize = (1 << (etbSize-1)) << 10; | ||
2127 | |||
2128 | // get starting address of the TBR buffer | ||
2129 | param.src_addr = TBR_RBD; | ||
2130 | } | ||
2131 | |||
2132 | etbSize *= 4; | ||
2133 | etbHalfSize = etbSize / 2; | ||
2134 | |||
2135 | param.ab_cnt = PARAM_BCNT(etbHalfSize / ETB_BURST_SIZE) | PARAM_ACNT(ETB_BURST_SIZE); | ||
2136 | param.dst_addr = pConfig->dbufAddress; | ||
2137 | param.srcdst_bidx = PARAM_DST_BIDX(ETB_BURST_SIZE); | ||
2138 | param.link_bcnt = PARAM_LINK(etb2param); | ||
2139 | param.srcdst_cidx = PARAM_DST_CIDX(etbHalfSize); | ||
2140 | param.ccnt = (pConfig->dbufWords*4) / etbHalfSize; | ||
2141 | |||
2142 | /* Set the DMA status to the actual number of words used in the provided | ||
2143 | * buffer, also reset any previous status settings. | ||
2144 | */ | ||
2145 | pHandle->dmaStatus.startAddr = 0; | ||
2146 | pHandle->dmaStatus.availableWords = 0; | ||
2147 | pHandle->dmaStatus.isWrapped = 0; | ||
2148 | pHandle->dmaStatus.dbufAddress = 0; | ||
2149 | pHandle->dmaStatus.flushRequired = 1; | ||
2150 | pHandle->dmaStatus.dbufWords = (param.ccnt * etbHalfSize) / 4; | ||
2151 | |||
2152 | /* Copy local structure to actual PaRAM memory locations */ | ||
2153 | *(struct edma3_param *)etb1param = param; | ||
2154 | |||
2155 | if(pConfig->mode != eDMA_Stop_Buffer) | ||
2156 | { | ||
2157 | |||
2158 | /* Change the 3rd PaRAM to not link to 2nd for wrap processing, just | ||
2159 | * link to self for reloading purposes, Transfer chaining completion is | ||
2160 | * also not needed except for the 1st occurance. | ||
2161 | */ | ||
2162 | param.options = PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | PARAM_OPT_AB_SYNC; | ||
2163 | param.link_bcnt = PARAM_LINK(etb3param); | ||
2164 | } | ||
2165 | else | ||
2166 | { | ||
2167 | /* If the DMA mode has been configured as non-circular, configure etbparam3 to disable ETB trace | ||
2168 | * set the link value to a NULL after disabling ETB trace. | ||
2169 | */ | ||
2170 | |||
2171 | param.options = PARAM_OPT_TCC_EARLY; | ||
2172 | param.src_addr = GET_GLOBAL_ADDR(&etb_disable); | ||
2173 | param.ab_cnt = (PARAM_BCNT(1) | PARAM_ACNT(4)); | ||
2174 | param.dst_addr = ETB_CTL(pHandle->id); | ||
2175 | param.srcdst_bidx = 0; | ||
2176 | param.link_bcnt = PARAM_LINK(0xffff); | ||
2177 | param.srcdst_cidx = 0; | ||
2178 | param.ccnt = 1; | ||
2179 | } | ||
2180 | |||
2181 | *(struct edma3_param *)etb3param = param; | ||
2182 | |||
2183 | if(pConfig->mode != eDMA_Stop_Buffer) | ||
2184 | { | ||
2185 | /* 2nd PaRAM configuration, no transfer chaining completion, but an early | ||
2186 | * link completion. | ||
2187 | */ | ||
2188 | param.options = PARAM_OPT_TCC_EARLY; | ||
2189 | } | ||
2190 | else | ||
2191 | { | ||
2192 | /* For Stop on full buffer mode, link to etb3param which disables ETB trace capture */ | ||
2193 | param.options = (PARAM_OPT_TCC_EARLY | PARAM_OPT_ITCINTEN | PARAM_OPT_TCINTEN | | ||
2194 | PARAM_OPT_TCCHEN | | ||
2195 | PARAM_OPT_TCC(pHandle->pDmaConfig->etbhalfChannel)); | ||
2196 | } | ||
2197 | |||
2198 | param.src_addr = GET_GLOBAL_ADDR(&etbLib_bufferWrapped[pHandle->id][1]); | ||
2199 | param.ab_cnt = PARAM_BCNT(1) | PARAM_ACNT(4); | ||
2200 | param.dst_addr = GET_GLOBAL_ADDR(&etbLib_bufferWrapped[pHandle->id][0]); | ||
2201 | param.srcdst_bidx = 0; | ||
2202 | param.link_bcnt = PARAM_LINK(etb3param); | ||
2203 | param.srcdst_cidx = 0; | ||
2204 | param.ccnt = 1; | ||
2205 | |||
2206 | /* Copy local structure to actual PaRAM memory locations */ | ||
2207 | *(struct edma3_param *)etb2param = param; | ||
2208 | |||
2209 | /* Enable event for etb half and etb full channel that. This is the EDMA event that is used to start the DMA | ||
2210 | * transactions. | ||
2211 | */ | ||
2212 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
2213 | { | ||
2214 | EDMA3_EESRH_REG(pHandle->pDmaConfig->cc) = (1 << (pHandle->pDmaConfig->etbhalfChannel-32)); | ||
2215 | } | ||
2216 | else | ||
2217 | { | ||
2218 | EDMA3_EESR_REG(pHandle->pDmaConfig->cc) = (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
2219 | } | ||
2220 | |||
2221 | if(pHandle->pDmaConfig->etbfullChannel > 31) | ||
2222 | { | ||
2223 | EDMA3_EESRH_REG(pHandle->pDmaConfig->cc) = (1 << (pHandle->pDmaConfig->etbfullChannel-32)); | ||
2224 | } | ||
2225 | else | ||
2226 | { | ||
2227 | EDMA3_EESR_REG(pHandle->pDmaConfig->cc) = (1 << pHandle->pDmaConfig->etbfullChannel); | ||
2228 | } | ||
2229 | |||
2230 | #endif | ||
2231 | |||
2232 | return eETB_Success; | ||
2233 | } | ||
2234 | |||
2235 | /******************************************************************************/ | ||
2236 | /*! \copydoc ETB_flush_dma | ||
2237 | */ | ||
2238 | eETB_Error ETB_flush_dma(ETBHandle* pHandle, DMAStatus *pStatus) | ||
2239 | { | ||
2240 | #if defined(C6670) || defined(C6678) | ||
2241 | |||
2242 | int32_t remWords; | ||
2243 | uint32_t rwp; | ||
2244 | uint32_t rrp; | ||
2245 | uint16_t paramIdx; | ||
2246 | uint32_t paramAddress; | ||
2247 | volatile uint32_t cntr = 0; | ||
2248 | |||
2249 | // For C6678, Index = 0 (CIC2), Index = 1 (CIC3) | ||
2250 | // For C6670, Index = 0 (CIC1), Index = 1 (CIC2) | ||
2251 | uint8_t cic_index = 0; | ||
2252 | |||
2253 | if(!pHandle || !pStatus) | ||
2254 | { | ||
2255 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2256 | } | ||
2257 | if(!pHandle->pDmaConfig) | ||
2258 | { | ||
2259 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2260 | } | ||
2261 | |||
2262 | #if defined(C6670) | ||
2263 | if(!(pHandle->pDmaConfig->cic == eCIC_1 || pHandle->pDmaConfig->cic == eCIC_2)) | ||
2264 | { | ||
2265 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2266 | } | ||
2267 | |||
2268 | #elif defined(C6678) | ||
2269 | if(!(pHandle->pDmaConfig->cic == eCIC_2 || pHandle->pDmaConfig->cic == eCIC_3)) | ||
2270 | { | ||
2271 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2272 | } | ||
2273 | |||
2274 | #endif | ||
2275 | |||
2276 | #if defined(C6670) | ||
2277 | |||
2278 | cic_index = pHandle->pDmaConfig->cic - 1; | ||
2279 | |||
2280 | #elif defined(C6678) | ||
2281 | |||
2282 | cic_index = pHandle->pDmaConfig->cic - 2; | ||
2283 | |||
2284 | #endif | ||
2285 | |||
2286 | rwp = *((volatile uint32_t*)ETB_RWP(pHandle->id)); | ||
2287 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
2288 | |||
2289 | remWords = rwp - rrp; | ||
2290 | // printf(" rwp: %x, rrp: %x, diff: %d\n", rwp, rrp, remWords); | ||
2291 | |||
2292 | if(remWords > 0) | ||
2293 | { | ||
2294 | int32_t remBytes; | ||
2295 | uint16_t clrParamIdx; | ||
2296 | |||
2297 | remBytes = (remWords * 4); | ||
2298 | /* Change the PaRAM set value for the DMA channel that handles the ETB | ||
2299 | * event to the drain PaRAM. This method is more efficient than copying | ||
2300 | * the PaRAM contents. | ||
2301 | */ | ||
2302 | paramIdx = (EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
2303 | pHandle->pDmaConfig->etbChannel) >> 5); | ||
2304 | clrParamIdx = (EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
2305 | pHandle->pDmaConfig->clrChannel) >> 5); | ||
2306 | EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
2307 | pHandle->pDmaConfig->clrChannel) = (paramIdx<<5); | ||
2308 | paramAddress = EDMA_TPCC_PARAM_BASE_ADDR(pHandle->pDmaConfig->cc) + | ||
2309 | (0x20 * paramIdx); | ||
2310 | |||
2311 | /* Check for buffer wrap */ | ||
2312 | if(etbLib_bufferWrapped[pHandle->id][0]) | ||
2313 | { | ||
2314 | pStatus->availableWords = pHandle->dmaStatus.dbufWords; | ||
2315 | pStatus->startAddr = PARAM_DST_REG(paramAddress) + remBytes; | ||
2316 | pStatus->isWrapped = 1; | ||
2317 | } | ||
2318 | else | ||
2319 | { | ||
2320 | pStatus->availableWords = (PARAM_DST_REG(paramAddress) - | ||
2321 | pHandle->pDmaConfig->dbufAddress) / 4; | ||
2322 | pStatus->availableWords += remWords; | ||
2323 | pStatus->startAddr = pHandle->pDmaConfig->dbufAddress; | ||
2324 | pStatus->isWrapped = 0; | ||
2325 | } | ||
2326 | |||
2327 | /* Copy the DMA status into the handle for later management. The status | ||
2328 | * value for the number of words may be different than what was in the | ||
2329 | * configuration structure. This value is set during configuration. | ||
2330 | */ | ||
2331 | pStatus->dbufAddress = pHandle->pDmaConfig->dbufAddress; | ||
2332 | pStatus->dbufWords = pHandle->dmaStatus.dbufWords; | ||
2333 | pStatus->flushRequired = pHandle->dmaStatus.flushRequired; | ||
2334 | pHandle->dmaStatus = *pStatus; | ||
2335 | |||
2336 | /* If the mode has been set to non-circular and the buffer wrapped flag | ||
2337 | * is set, then the memory buffer if full, otherwise continue the | ||
2338 | * configuration for the final DMA. | ||
2339 | */ | ||
2340 | if((pHandle->pDmaConfig->mode == eDMA_Stop_Buffer) && | ||
2341 | (etbLib_bufferWrapped[pHandle->id][0])) | ||
2342 | { | ||
2343 | /* If the buffer wrapped, the startAddr value is incorrect from | ||
2344 | * above, set back to beginning of the buffer. | ||
2345 | */ | ||
2346 | pStatus->startAddr = pHandle->pDmaConfig->dbufAddress; | ||
2347 | pHandle->dmaStatus.startAddr = pHandle->pDmaConfig->dbufAddress; | ||
2348 | return eETB_Success; | ||
2349 | } | ||
2350 | |||
2351 | // Update the 3 symbols which are required for CCS ETB receiver | ||
2352 | etbLib_buffer_start_addr[pHandle->id] = pHandle->pDmaConfig->dbufAddress; //CCS ETB receiver will always get a linearized buffer for the non-EDMA ETB drain case | ||
2353 | etbLib_buffer_size[pHandle->id] = pStatus->availableWords * 4; //Number of bytes available | ||
2354 | etbLib_buffer_data_start[pHandle->id] = pStatus->startAddr; //circular buffer wrap point | ||
2355 | |||
2356 | if(remBytes > ETB_BURST_SIZE) | ||
2357 | { | ||
2358 | uint16_t transCnt; | ||
2359 | |||
2360 | /* Split the transfer into burst transactions. | ||
2361 | * Any remaining data beyond an even multiple of burst size bytes | ||
2362 | * will get linked for a single remaining transaction. | ||
2363 | */ | ||
2364 | transCnt = remBytes / ETB_BURST_SIZE; | ||
2365 | PARAM_AB_CNT_REG(paramAddress) &= ~PARAM_BCNT_MASK; | ||
2366 | PARAM_AB_CNT_REG(paramAddress) |= PARAM_BCNT(transCnt); | ||
2367 | PARAM_CCNT_REG(paramAddress) = 1; | ||
2368 | |||
2369 | /* Adjust the remaining byte count */ | ||
2370 | remBytes -= (transCnt * ETB_BURST_SIZE); | ||
2371 | } | ||
2372 | else | ||
2373 | { | ||
2374 | PARAM_AB_CNT_REG(paramAddress) = PARAM_BCNT(1) | PARAM_ACNT(remBytes); | ||
2375 | PARAM_CCNT_REG(paramAddress) = 1; | ||
2376 | remBytes = 0; | ||
2377 | } | ||
2378 | /* If there are remaining bytes to transfer, setup link param for final | ||
2379 | * transaction. | ||
2380 | */ | ||
2381 | if(remBytes > 0) | ||
2382 | { | ||
2383 | uint32_t etb3param; | ||
2384 | |||
2385 | etb3param = EDMA_TPCC_PARAM_BASE_ADDR(pHandle->pDmaConfig->cc) + | ||
2386 | (0x20 * pHandle->pDmaConfig->linkparam[2]); | ||
2387 | |||
2388 | /* Further ETB PaRAM modifications */ | ||
2389 | PARAM_OPT_REG(paramAddress) = (PARAM_OPT_TCCHEN | | ||
2390 | PARAM_OPT_TCC(pHandle->pDmaConfig->clrChannel) | | ||
2391 | PARAM_OPT_AB_SYNC); | ||
2392 | PARAM_LINK_REG(paramAddress) &= ~PARAM_LINK_MASK; | ||
2393 | PARAM_LINK_REG(paramAddress) |= PARAM_LINK(etb3param); | ||
2394 | |||
2395 | /* ETB linked PaRAM modifications */ | ||
2396 | PARAM_OPT_REG(etb3param) = (PARAM_OPT_TCINTEN | | ||
2397 | PARAM_OPT_TCC(pHandle->pDmaConfig->clrChannel) | | ||
2398 | PARAM_OPT_AB_SYNC); | ||
2399 | PARAM_AB_CNT_REG(etb3param) = PARAM_BCNT(1) | PARAM_ACNT(remBytes); | ||
2400 | PARAM_DST_REG(etb3param) = PARAM_DST_REG(paramAddress) + | ||
2401 | (PARAM_BCNT_VALUE(paramAddress) * ETB_BURST_SIZE); | ||
2402 | PARAM_CCNT_REG(etb3param) = 1; | ||
2403 | PARAM_LINK_REG(etb3param) &= ~PARAM_LINK_MASK; | ||
2404 | PARAM_LINK_REG(etb3param) |= PARAM_LINK(0xffff); | ||
2405 | } | ||
2406 | else | ||
2407 | { | ||
2408 | PARAM_OPT_REG(paramAddress) = (PARAM_OPT_TCINTEN | | ||
2409 | PARAM_OPT_TCC(pHandle->pDmaConfig->clrChannel) | | ||
2410 | PARAM_OPT_AB_SYNC); | ||
2411 | } | ||
2412 | |||
2413 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][0]; | ||
2414 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][1]; | ||
2415 | |||
2416 | if(pHandle->pDmaConfig->clrChannel > 31) | ||
2417 | { | ||
2418 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
2419 | (1 << (pHandle->pDmaConfig->clrChannel - 32)); | ||
2420 | } | ||
2421 | else | ||
2422 | { | ||
2423 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
2424 | (1 << pHandle->pDmaConfig->clrChannel); | ||
2425 | } | ||
2426 | |||
2427 | /* Force an event manually from the ETB interrupt register */ | ||
2428 | *((volatile uint32_t*)ETB_IRST(pHandle->id)) = 1; | ||
2429 | |||
2430 | /* Poll the interrupt pending bit for transaction completion */ | ||
2431 | cntr = 0; | ||
2432 | if(pHandle->pDmaConfig->clrChannel > 31) | ||
2433 | { | ||
2434 | while((EDMA3_IPRH_REG(pHandle->pDmaConfig->cc) & | ||
2435 | (1 << (pHandle->pDmaConfig->clrChannel - 32))) == 0) | ||
2436 | { | ||
2437 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
2438 | break; | ||
2439 | } | ||
2440 | |||
2441 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][0]; | ||
2442 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][1]; | ||
2443 | |||
2444 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
2445 | (1 << (pHandle->pDmaConfig->clrChannel - 32)); | ||
2446 | } | ||
2447 | else | ||
2448 | { | ||
2449 | while((EDMA3_IPR_REG(pHandle->pDmaConfig->cc) & | ||
2450 | (1 << pHandle->pDmaConfig->clrChannel)) == 0) | ||
2451 | { | ||
2452 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
2453 | break; | ||
2454 | } | ||
2455 | |||
2456 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][0]; | ||
2457 | CIC_STATUS_CLR_INDEX_REG(pHandle->pDmaConfig->cic) = etbLib_cpCicEventClearValue[cic_index][pHandle->id][1]; | ||
2458 | |||
2459 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
2460 | (1 << pHandle->pDmaConfig->clrChannel); | ||
2461 | } | ||
2462 | |||
2463 | /* Restore DMA Channel map for Clear Channel PaRAM index */ | ||
2464 | EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
2465 | pHandle->pDmaConfig->clrChannel) = (clrParamIdx<<5); | ||
2466 | |||
2467 | // printf("Pending Cntr: %d\n", cntr); | ||
2468 | } | ||
2469 | else if(remWords < 0) | ||
2470 | { | ||
2471 | // printf(" *** remWords < 0, %d\n",remWords); | ||
2472 | /* Report error if < 0, otherwise nothing to read from ETB */ | ||
2473 | return eETB_Overflow; | ||
2474 | |||
2475 | } | ||
2476 | |||
2477 | #elif defined(C6657) || defined(C66AK2Hxx) || defined(C66AK2Exx) | ||
2478 | |||
2479 | int32_t remWords, remBytes; | ||
2480 | uint32_t rwp; | ||
2481 | uint32_t rrp; | ||
2482 | uint32_t paramAddress; | ||
2483 | uint16_t paramIdx; | ||
2484 | uint32_t retry, status; | ||
2485 | volatile uint32_t cntr = 0; | ||
2486 | |||
2487 | if(!pHandle || !pStatus) | ||
2488 | { | ||
2489 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2490 | } | ||
2491 | if(!pHandle->pDmaConfig) | ||
2492 | { | ||
2493 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2494 | } | ||
2495 | |||
2496 | /* Change the PaRAM set value for the DMA channel that handles the ETB | ||
2497 | * event to the drain PaRAM. This method is more efficient than copying | ||
2498 | * the PaRAM contents. | ||
2499 | */ | ||
2500 | paramIdx = (EDMA3_DCHMAP_REG(pHandle->pDmaConfig->cc, | ||
2501 | pHandle->pDmaConfig->etbhalfChannel) >> 5); | ||
2502 | paramAddress = EDMA_TPCC_PARAM_BASE_ADDR(pHandle->pDmaConfig->cc) + | ||
2503 | (0x20 * paramIdx); | ||
2504 | |||
2505 | if(check_etb_type(pHandle->id) == ETB_TYPE) | ||
2506 | { | ||
2507 | rwp = *((volatile uint32_t*)ETB_RWP(pHandle->id)); | ||
2508 | rrp = *((volatile uint32_t*)ETB_RRP(pHandle->id)); | ||
2509 | |||
2510 | remWords = rwp - rrp; | ||
2511 | // printf(" rwp: %x, rrp: %x, diff: %d\n", rwp, rrp, remWords); | ||
2512 | |||
2513 | if(remWords > 0) | ||
2514 | { | ||
2515 | remBytes = (remWords * 4); | ||
2516 | |||
2517 | //Get EDMA buffer information | ||
2518 | if(get_edma_buffer_info(pHandle, pStatus, paramAddress, paramIdx, remWords)) | ||
2519 | { | ||
2520 | return eETB_Success; | ||
2521 | } | ||
2522 | |||
2523 | if(remBytes > ETB_BURST_SIZE) | ||
2524 | { | ||
2525 | uint16_t transCnt; | ||
2526 | |||
2527 | /* Split the transfer into burst transactions. | ||
2528 | * Any remaining data beyond an even multiple of burst size bytes | ||
2529 | * will get linked for a single remaining transaction. | ||
2530 | */ | ||
2531 | transCnt = remBytes / ETB_BURST_SIZE; | ||
2532 | PARAM_AB_CNT_REG(paramAddress) &= ~PARAM_BCNT_MASK; | ||
2533 | PARAM_AB_CNT_REG(paramAddress) |= PARAM_BCNT(transCnt); | ||
2534 | PARAM_CCNT_REG(paramAddress) = 1; | ||
2535 | |||
2536 | /* Adjust the remaining byte count */ | ||
2537 | remBytes -= (transCnt * ETB_BURST_SIZE); | ||
2538 | } | ||
2539 | else | ||
2540 | { | ||
2541 | PARAM_AB_CNT_REG(paramAddress) = PARAM_BCNT(1) | PARAM_ACNT(remBytes); | ||
2542 | PARAM_CCNT_REG(paramAddress) = 1; | ||
2543 | remBytes = 0; | ||
2544 | } | ||
2545 | /* If there are remaining bytes to transfer, setup link param for final | ||
2546 | * transaction. | ||
2547 | */ | ||
2548 | if(remBytes > 0) | ||
2549 | { | ||
2550 | uint32_t etb3param; | ||
2551 | |||
2552 | etb3param = EDMA_TPCC_PARAM_BASE_ADDR(pHandle->pDmaConfig->cc) + | ||
2553 | (0x20 * pHandle->pDmaConfig->linkparam[2]); | ||
2554 | |||
2555 | /* Further ETB PaRAM modifications */ | ||
2556 | PARAM_OPT_REG(paramAddress) = (PARAM_OPT_TCCHEN | | ||
2557 | PARAM_OPT_TCC(pHandle->pDmaConfig->etbhalfChannel) | | ||
2558 | PARAM_OPT_AB_SYNC); | ||
2559 | PARAM_LINK_REG(paramAddress) &= ~PARAM_LINK_MASK; | ||
2560 | PARAM_LINK_REG(paramAddress) |= PARAM_LINK(etb3param); | ||
2561 | |||
2562 | /* ETB linked PaRAM modifications */ | ||
2563 | PARAM_OPT_REG(etb3param) = (PARAM_OPT_TCINTEN | | ||
2564 | PARAM_OPT_TCC(pHandle->pDmaConfig->etbhalfChannel) | | ||
2565 | PARAM_OPT_AB_SYNC); | ||
2566 | PARAM_AB_CNT_REG(etb3param) = PARAM_BCNT(1) | PARAM_ACNT(remBytes); | ||
2567 | PARAM_DST_REG(etb3param) = PARAM_DST_REG(paramAddress) + | ||
2568 | (PARAM_BCNT_VALUE(paramAddress) * ETB_BURST_SIZE); | ||
2569 | PARAM_CCNT_REG(etb3param) = 1; | ||
2570 | PARAM_LINK_REG(etb3param) &= ~PARAM_LINK_MASK; | ||
2571 | PARAM_LINK_REG(etb3param) |= PARAM_LINK(0xffff); | ||
2572 | } | ||
2573 | else | ||
2574 | { | ||
2575 | PARAM_OPT_REG(paramAddress) = (PARAM_OPT_TCINTEN | | ||
2576 | PARAM_OPT_TCC(pHandle->pDmaConfig->etbhalfChannel) | | ||
2577 | PARAM_OPT_AB_SYNC); | ||
2578 | } | ||
2579 | |||
2580 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
2581 | { | ||
2582 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
2583 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32)); | ||
2584 | } | ||
2585 | else | ||
2586 | { | ||
2587 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
2588 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
2589 | } | ||
2590 | |||
2591 | /* Force an event manually from the ETB interrupt register */ | ||
2592 | *((volatile uint32_t*)ETB_IRST(pHandle->id)) = 1; | ||
2593 | |||
2594 | /* Poll the interrupt pending bit for transaction completion */ | ||
2595 | cntr = 0; | ||
2596 | if(pHandle->pDmaConfig->etbhalfChannel > 31) | ||
2597 | { | ||
2598 | while((EDMA3_IPRH_REG(pHandle->pDmaConfig->cc) & | ||
2599 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32))) == 0) | ||
2600 | { | ||
2601 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
2602 | break; | ||
2603 | } | ||
2604 | |||
2605 | EDMA3_ICRH_REG(pHandle->pDmaConfig->cc) = | ||
2606 | (1 << (pHandle->pDmaConfig->etbhalfChannel - 32)); | ||
2607 | } | ||
2608 | else | ||
2609 | { | ||
2610 | while((EDMA3_IPR_REG(pHandle->pDmaConfig->cc) & | ||
2611 | (1 << pHandle->pDmaConfig->etbhalfChannel)) == 0) | ||
2612 | { | ||
2613 | if(cntr++ > ETB_DMA_TIMEOUT) | ||
2614 | break; | ||
2615 | } | ||
2616 | |||
2617 | EDMA3_ICR_REG(pHandle->pDmaConfig->cc) = | ||
2618 | (1 << pHandle->pDmaConfig->etbhalfChannel); | ||
2619 | } | ||
2620 | } | ||
2621 | else if(remWords < 0) | ||
2622 | { | ||
2623 | // printf(" *** remWords < 0, %d\n",remWords); | ||
2624 | /* Report error if < 0, otherwise nothing to read from ETB */ | ||
2625 | return eETB_Overflow; | ||
2626 | |||
2627 | } | ||
2628 | } | ||
2629 | else | ||
2630 | { | ||
2631 | //Perform an Output flush from the TBR | ||
2632 | // Wait for any previous output flush to complete | ||
2633 | retry = 50000; // Give enough time for a DMA transfer equal to half the size of the TBR | ||
2634 | do | ||
2635 | { | ||
2636 | status = *(volatile uint32_t*)ETB_FFCR(pHandle->id); | ||
2637 | retry--; | ||
2638 | }while( ( ( status & TBR_OUTFLUSH_INPROGRESS ) != 0 ) && ( retry != 0 ) ); | ||
2639 | |||
2640 | // Return error if timeout occurs on the above operation | ||
2641 | if (retry == 0) | ||
2642 | { | ||
2643 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2644 | } | ||
2645 | |||
2646 | // Issue an output flush | ||
2647 | status = *(volatile uint32_t*)ETB_FFCR(pHandle->id); | ||
2648 | *(volatile uint32_t*)ETB_FFCR(pHandle->id) = status | TBR_OUTFLUSH_START; | ||
2649 | |||
2650 | // Wait for output flush to complete | ||
2651 | retry = 50000; | ||
2652 | do | ||
2653 | { | ||
2654 | status = *(volatile uint32_t*)ETB_FFCR(pHandle->id); | ||
2655 | retry--; | ||
2656 | }while(((status & TBR_OUTFLUSH_INPROGRESS) != 0 ) && (retry != 0)); | ||
2657 | |||
2658 | // Return error if timeout occurs on the above operation | ||
2659 | if (retry == 0) | ||
2660 | { | ||
2661 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2662 | } | ||
2663 | |||
2664 | // Wait for final DMA transfer to complete | ||
2665 | //retry = 50000; // Give enough time for a DMA transfer equal to half the size of the TBR | ||
2666 | retry = 500; | ||
2667 | do | ||
2668 | { | ||
2669 | status = *((volatile uint32_t*)ETB_STS(pHandle->id)); | ||
2670 | retry--; | ||
2671 | }while(((status & TBR_DRAIN_INPROGRESS) != TBR_DRAIN_INPROGRESS) && ( retry != 0 )); | ||
2672 | |||
2673 | // Return error if timeout occurs on the above operation | ||
2674 | if (retry == 0) | ||
2675 | { | ||
2676 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2677 | } | ||
2678 | |||
2679 | //Make sure there are no pending read requests on the TBR slave port | ||
2680 | retry = 50000; | ||
2681 | do | ||
2682 | { | ||
2683 | status = *((volatile uint32_t*)TBR_SICTRL(pHandle->id)); | ||
2684 | retry--; | ||
2685 | }while(((status & TBR_READ_REQ_PENDING) != 0) && ( retry != 0 )); | ||
2686 | |||
2687 | // Return error if timeout occurs on the above operation | ||
2688 | if (retry == 0) | ||
2689 | { | ||
2690 | RETURN_ETB_CALLBACK(pHandle->id, eETB_Error_Program); | ||
2691 | } | ||
2692 | |||
2693 | //Get EDMA buffer information | ||
2694 | if(get_edma_buffer_info(pHandle, pStatus, paramAddress, paramIdx, 0)) | ||
2695 | { | ||
2696 | return eETB_Success; | ||
2697 | } | ||
2698 | } | ||
2699 | |||
2700 | #endif | ||
2701 | |||
2702 | return eETB_Success; | ||
2703 | } | ||
2704 | |||
2705 | /******************************************************************************/ | ||
2706 | /*! \copydoc ETB_setDmaStatus | ||
2707 | */ | ||
2708 | void ETB_setDmaStatus(ETBHandle* pHandle, DMAStatus *pStatus) | ||
2709 | { | ||
2710 | if(!pHandle || !pStatus) | ||
2711 | { | ||
2712 | return; | ||
2713 | } | ||
2714 | if(!pHandle->pDmaConfig) | ||
2715 | { | ||
2716 | return; | ||
2717 | } | ||
2718 | pHandle->dmaStatus = *pStatus; | ||
2719 | } | ||
2720 | #endif | ||
2721 | |||
2722 | /******************************************************************************/ | ||
2723 | /*! \copydoc ETB_getProperties | ||
2724 | */ | ||
2725 | void ETB_getProperties(ETBProperties *pProperties) | ||
2726 | { | ||
2727 | |||
2728 | #ifdef DMA_SUPPORT | ||
2729 | |||
2730 | pProperties->is_dma_supported = 1; | ||
2731 | |||
2732 | #else | ||
2733 | |||
2734 | pProperties->is_dma_supported = 0; | ||
2735 | |||
2736 | #endif | ||
2737 | |||
2738 | return; | ||
2739 | } | ||
diff --git a/server/command_handler.c b/server/command_handler.c new file mode 100644 index 0000000..e8b0780 --- /dev/null +++ b/server/command_handler.c | |||
@@ -0,0 +1,653 @@ | |||
1 | /* | ||
2 | * command_handler.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <stdbool.h> | ||
41 | #include <string.h> | ||
42 | #include <stdint.h> | ||
43 | #include "error_handler.h" | ||
44 | #include "logging.h" | ||
45 | #include "socket.h" | ||
46 | #include "remote_commands.h" | ||
47 | |||
48 | /***************************************************************************** | ||
49 | * Internal Function Prototypes | ||
50 | * - See Private Function section below for implementations ) | ||
51 | *****************************************************************************/ | ||
52 | static inline uint8_t calculate_checksum( uint8_t *buf, unsigned int len ); | ||
53 | static inline uint8_t int_to_hexdigit(unsigned val); | ||
54 | static inline void send_response(uint8_t * response); | ||
55 | static void command_dispatch(char * cmd, int cmd_len, char * response, size_t rsp_size); | ||
56 | static void command_clr_buf(uint8_t * pbuf); | ||
57 | |||
58 | static void get_memory_arguments(char * cbuf, uint32_t * addr, size_t * len, char ** data); | ||
59 | static void process_memory_write(char * cbuf, char * rbuf, size_t rsp_size); | ||
60 | static void process_memory_read(char * cbuf, char * rbuf, size_t rsp_size); | ||
61 | static void process_remote(char * cbuf, char * rbuf, size_t rsp_size); | ||
62 | static void process_disable_ack(char * cbuf, char * rbuf, size_t rsp_size); | ||
63 | |||
64 | /***************************************************************************** | ||
65 | * Remote Serial Protocol (RSP) Definitions | ||
66 | * - RSP commands consists of remote commands and target commands (memory read | ||
67 | * and memory write. | ||
68 | * | ||
69 | *****************************************************************************/ | ||
70 | |||
71 | /* RSP Commands */ | ||
72 | typedef enum { | ||
73 | READ_MEMORY_CMD, | ||
74 | WRITE_MEMORY_CMD, | ||
75 | REMOTE_CMD, | ||
76 | DISABLE_ACK_CMD | ||
77 | } rsp_cmd_t; | ||
78 | |||
79 | typedef void (* proc_func_t)(char * cbuf, char * rbuf, size_t rbuf_size); | ||
80 | |||
81 | struct rsp_command_table_t { | ||
82 | char * cmd; | ||
83 | proc_func_t process; | ||
84 | }; | ||
85 | |||
86 | static struct rsp_command_table_t rsp_command_table[] = { | ||
87 | [READ_MEMORY_CMD] = {"m", process_memory_read}, | ||
88 | [WRITE_MEMORY_CMD] = {"M", process_memory_write}, | ||
89 | [REMOTE_CMD] = {"qRcmd,", process_remote}, | ||
90 | [DISABLE_ACK_CMD] = {"QStartNoAckMode", process_disable_ack} | ||
91 | }; | ||
92 | |||
93 | /* RSP remote command table */ | ||
94 | typedef void (* rmt_func_t)(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
95 | |||
96 | struct remote_command_table_t { | ||
97 | char * cmd; | ||
98 | rmt_func_t process; | ||
99 | }; | ||
100 | |||
101 | /* The commands from this table are provided from remote_commands.h */ | ||
102 | static struct remote_command_table_t remote_command_table[] = { | ||
103 | {"set", set_command_handler}, | ||
104 | {"mmap", mmap_command_handler}, | ||
105 | {"ummap", ummap_command_handler}, | ||
106 | {"version", version_command_handler}, | ||
107 | {"arm", modcntl_add_command_handler}, | ||
108 | {"disarm", modcntl_add_command_handler}, | ||
109 | {"rm_arm", modcntl_remove_command_handler}, | ||
110 | {"rm_disarm", modcntl_remove_command_handler}, | ||
111 | {"start", start_command_handler}, | ||
112 | {"end", end_command_handler}, | ||
113 | {"status", status_command_handler} | ||
114 | }; | ||
115 | |||
116 | /* RSP constants */ | ||
117 | static bool rsp_ack_enabled = true; | ||
118 | static const char *ACK = "+"; | ||
119 | static const char *NACK = "-"; | ||
120 | static const char *rsp_msg_ok = "OK"; | ||
121 | |||
122 | /* RSP State */ | ||
123 | typedef enum {AWAITING_COMMAND, AWAITING_ACK} command_state_t; | ||
124 | static command_state_t command_state = AWAITING_COMMAND; | ||
125 | |||
126 | /* RSP buffers*/ | ||
127 | #define MAX_COMMAND_SIZE 256 | ||
128 | static uint8_t cmd_buf[MAX_COMMAND_SIZE]; | ||
129 | static uint8_t rsp_buf[MAX_COMMAND_SIZE]; | ||
130 | |||
131 | /***************************************************************************** | ||
132 | * Statics | ||
133 | * | ||
134 | *****************************************************************************/ | ||
135 | static int cmd_socket; | ||
136 | |||
137 | /***************************************************************************** | ||
138 | * Public Functions | ||
139 | * | ||
140 | *****************************************************************************/ | ||
141 | /***************************************************************************** | ||
142 | * command_init() | ||
143 | * | ||
144 | * Initialize the client command handler with a socket. | ||
145 | * | ||
146 | *****************************************************************************/ | ||
147 | void command_init(int socket) | ||
148 | { | ||
149 | LOGFUNC(); | ||
150 | cmd_socket = socket; | ||
151 | command_clr_buf(cmd_buf); | ||
152 | |||
153 | command_state = AWAITING_COMMAND; | ||
154 | rsp_ack_enabled = true; | ||
155 | } | ||
156 | |||
157 | /***************************************************************************** | ||
158 | * command_process() | ||
159 | * | ||
160 | * This is where all client commands are received and executed. | ||
161 | * | ||
162 | * - RSP packet definition is: | ||
163 | * $packet-data#checksum | ||
164 | * | ||
165 | * Where checksum is a 2 digit module 256 sum (in hex) of the packet-data. | ||
166 | * Initial response from the server is “+/-“ where “+†indicates the packet-data | ||
167 | * transmitted successfully, and “-“ indicates the packet-data needs to be resent. | ||
168 | * All values are sent in HEX format without leading “0xâ€. | ||
169 | * | ||
170 | * Examples: | ||
171 | * $Maddr,length:data#checksum - Write length bytes of memory starting at addr. | ||
172 | * $maddr,length#checksum - Read length bytes of memory starting at addr. | ||
173 | * $qRcmd,mmap addr,size#checksum - Map memory block at addr of size in bytes. | ||
174 | * | ||
175 | *****************************************************************************/ | ||
176 | void command_process() | ||
177 | { | ||
178 | uint8_t * pbuf = cmd_buf; | ||
179 | uint8_t * cksum_marker; | ||
180 | int retry; | ||
181 | size_t cmd_len; | ||
182 | |||
183 | LOGFUNC(); | ||
184 | |||
185 | /* Provide size of receive buffer as MAX_COMMAND_SIZE -1 | ||
186 | * because we want room for at least one NULL character in the buffer. | ||
187 | */ | ||
188 | retry = socket_recv_data(cmd_socket, cmd_buf, MAX_COMMAND_SIZE - 1, 0, | ||
189 | &cmd_len); | ||
190 | |||
191 | if ((retry) || (cmd_len == 0)) { | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | LOGMSG1("%s:Received msg length %d, message is:%s, command state is %d", | ||
196 | __func__, cmd_len, cmd_buf, command_state); | ||
197 | |||
198 | /* Note: Since the server is non-blocking the ACK (if AWAITING_ACK set) | ||
199 | * and the next command can be combined into a single message. | ||
200 | */ | ||
201 | if (command_state == AWAITING_ACK) { | ||
202 | if (cmd_buf[0] == '+') { | ||
203 | command_state = AWAITING_COMMAND; | ||
204 | LOGMSG1("%s:Processed ACK", __func__); | ||
205 | |||
206 | if (cmd_len > 1) { | ||
207 | pbuf++; | ||
208 | } else { | ||
209 | command_clr_buf(cmd_buf); | ||
210 | command_clr_buf(rsp_buf); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | } | ||
215 | if (cmd_buf[0] == '-') { | ||
216 | send_response(rsp_buf); | ||
217 | LOGMSG1("%s:Processed NACK", __func__); | ||
218 | return; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | /* First character of RSP commands must be $ */ | ||
223 | if (('$' != pbuf[0]) || !( cksum_marker = (uint8_t *)strchr((char *)pbuf, '#'))) { | ||
224 | err_handler(ERR_TYPE_LOCAL, ERR_RSP_INVALID); | ||
225 | } | ||
226 | |||
227 | /* get past first character and determine the actual command length */ | ||
228 | pbuf++; | ||
229 | cmd_len = cksum_marker - pbuf; | ||
230 | |||
231 | /* Validate checksum */ | ||
232 | if (rsp_ack_enabled == true) { | ||
233 | uint8_t ck_sum = calculate_checksum( pbuf, cmd_len ); | ||
234 | uint8_t c1 = pbuf[cmd_len+1]; | ||
235 | uint8_t c2 = pbuf[cmd_len+2]; | ||
236 | |||
237 | if ((c1 != int_to_hexdigit(ck_sum >> 4)) || | ||
238 | (c2 != int_to_hexdigit(ck_sum & 0xf ))) { | ||
239 | /* Simply means resend command*/ | ||
240 | send_response((uint8_t *)NACK); | ||
241 | return; | ||
242 | } | ||
243 | else { | ||
244 | send_response((uint8_t *)ACK); | ||
245 | } | ||
246 | |||
247 | } | ||
248 | |||
249 | /* Replace the # with 0 so it looks like the end of the string */ | ||
250 | *cksum_marker = 0; | ||
251 | |||
252 | LOGMSG1("%s:Received command from client:%s", __func__, pbuf); | ||
253 | |||
254 | /* Execute the command */ | ||
255 | { | ||
256 | uint8_t * rsp_p = rsp_buf; | ||
257 | uint8_t ck_sum = 0; | ||
258 | int rsp_len; | ||
259 | |||
260 | command_clr_buf(rsp_buf); | ||
261 | rsp_p[0] = '$'; | ||
262 | rsp_p++; | ||
263 | |||
264 | command_dispatch((char *)pbuf, cmd_len, (char *)rsp_p, sizeof(rsp_buf)-1); | ||
265 | |||
266 | rsp_len = strlen((char *)rsp_p); | ||
267 | |||
268 | if (rsp_ack_enabled == true) { | ||
269 | ck_sum = calculate_checksum(rsp_p, rsp_len); | ||
270 | } | ||
271 | |||
272 | rsp_p[rsp_len] = '#'; | ||
273 | rsp_p[rsp_len+1] = int_to_hexdigit(ck_sum >> 4); | ||
274 | rsp_p[rsp_len+2] = int_to_hexdigit(ck_sum & 0xf); | ||
275 | |||
276 | send_response(rsp_buf); | ||
277 | |||
278 | LOGMSG1("%s:Sent response to client:%s", __func__, rsp_buf); | ||
279 | |||
280 | if (rsp_ack_enabled == true) { | ||
281 | command_state = AWAITING_ACK; | ||
282 | } else { | ||
283 | command_clr_buf(cmd_buf); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | } | ||
288 | |||
289 | /***************************************************************************** | ||
290 | * Private functions | ||
291 | * | ||
292 | *****************************************************************************/ | ||
293 | /***************************************************************************** | ||
294 | * command_clr_buf() | ||
295 | * | ||
296 | * Fill the command buffer with the NULL character. | ||
297 | * Note: This is done so strchr will not have problems if a non-conforming rsp | ||
298 | * command is received. | ||
299 | * | ||
300 | *****************************************************************************/ | ||
301 | void command_clr_buf(uint8_t * pbuf) | ||
302 | { | ||
303 | memset((char *)pbuf, '\0', MAX_COMMAND_SIZE); | ||
304 | } | ||
305 | |||
306 | /***************************************************************************** | ||
307 | * calculate_checksum() | ||
308 | * | ||
309 | * Calculate the RSP checksum | ||
310 | * | ||
311 | *****************************************************************************/ | ||
312 | static inline uint8_t calculate_checksum( uint8_t *buf, unsigned int len ) | ||
313 | { | ||
314 | unsigned checksum = 0; | ||
315 | while ( len-- > 0 ) { | ||
316 | checksum += *buf++; | ||
317 | } | ||
318 | return checksum & 0xFF; | ||
319 | } | ||
320 | |||
321 | /***************************************************************************** | ||
322 | * int_to_hexdigit() | ||
323 | * | ||
324 | * Convert a int digit to a hex ascii value. | ||
325 | * | ||
326 | *****************************************************************************/ | ||
327 | static const uint8_t inttohex_table[] = { | ||
328 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' | ||
329 | }; | ||
330 | |||
331 | static inline uint8_t int_to_hexdigit(unsigned int val) | ||
332 | { | ||
333 | if ( val > 0xF) { | ||
334 | err_handler(ERR_TYPE_LOCAL, ERR_RSP_INVALID); | ||
335 | } | ||
336 | return inttohex_table[val]; | ||
337 | } | ||
338 | |||
339 | /***************************************************************************** | ||
340 | * send_response() | ||
341 | * | ||
342 | * Once the command is processed this function is used to send the response | ||
343 | * back to the client. | ||
344 | * | ||
345 | *****************************************************************************/ | ||
346 | static inline void send_response(uint8_t * response) | ||
347 | { | ||
348 | size_t send_offset = 0; | ||
349 | size_t retlen; | ||
350 | int retval; | ||
351 | |||
352 | /* The command socket is non-blocking so must check for EAGAIN */ | ||
353 | do { | ||
354 | retval = socket_send_data(cmd_socket, response, | ||
355 | strlen((char *)response), send_offset, &retlen); | ||
356 | } while(retval); | ||
357 | } | ||
358 | |||
359 | /***************************************************************************** | ||
360 | * command_dispatch() | ||
361 | * | ||
362 | * - Search the rsp_command_table for a known cmd that matches the received cmd | ||
363 | * - Use the command index to execute the rsp command handler. | ||
364 | * | ||
365 | *****************************************************************************/ | ||
366 | void command_dispatch(char * cmd, int cmd_len, char * response, size_t rsp_size) | ||
367 | { | ||
368 | int rsp_cmd_elements = sizeof(rsp_command_table)/sizeof(struct rsp_command_table_t); | ||
369 | int cmd_index; | ||
370 | char * pcmd = cmd; | ||
371 | |||
372 | LOGFUNC(); | ||
373 | |||
374 | /* Search the rsp_command_table for a known cmd that matches the received cmd. */ | ||
375 | for ( cmd_index = 0; cmd_index < rsp_cmd_elements; cmd_index++) { | ||
376 | |||
377 | char *rsp_cmd = strstr(cmd, rsp_command_table[cmd_index].cmd); | ||
378 | if (rsp_cmd == cmd) { | ||
379 | pcmd += strlen(rsp_command_table[cmd_index].cmd); | ||
380 | |||
381 | LOGMSG1("%s:RSP Command match found:%s", __func__, | ||
382 | rsp_command_table[cmd_index].cmd); | ||
383 | |||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | if (cmd_index == rsp_cmd_elements) { | ||
389 | err_handler(ERR_TYPE_LOCAL, ERR_RSP_INVALID); | ||
390 | } | ||
391 | |||
392 | |||
393 | /* Process the command */ | ||
394 | rsp_command_table[cmd_index].process(pcmd, response, rsp_size); | ||
395 | } | ||
396 | |||
397 | /***************************************************************************** | ||
398 | * get_memory_arguments() | ||
399 | * | ||
400 | * Convert ascii memory command arguments (addr, len, and data) and into | ||
401 | * values. | ||
402 | * | ||
403 | * Note - data is not converted to value in this function. It simply returns | ||
404 | * a char * to the data value if this is a write, else NULL is returned. | ||
405 | * | ||
406 | *****************************************************************************/ | ||
407 | static void get_memory_arguments(char * cbuf, uint32_t * addr, size_t * len, char ** data) | ||
408 | { | ||
409 | char * tokins = ",:"; | ||
410 | /* arg[0] used to hold the char * to the address */ | ||
411 | /* arg[1] used to hold the char * to the length in bytes */ | ||
412 | /* arg[2] used to hold a char * to the data if this is a write */ | ||
413 | char * arg[3] = {NULL,NULL,NULL}; | ||
414 | char addr_str[] = "0x00000000"; | ||
415 | char len_str[] = "0x00000000"; | ||
416 | int starting_digit; | ||
417 | |||
418 | int i = 0; | ||
419 | arg[i] = strtok(cbuf, tokins); | ||
420 | while (arg[i] != NULL) { | ||
421 | #if DEBUG | ||
422 | if ((strlen(arg[i]) == 0) || (strlen(arg[i]) > 8)) { | ||
423 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
424 | } | ||
425 | #endif | ||
426 | arg[++i] = strtok(NULL, tokins); | ||
427 | /* Don't overflow the arg array */ | ||
428 | if (i == 2) break; | ||
429 | } | ||
430 | |||
431 | #if DEBUG | ||
432 | if ( (arg[0] == NULL) || (arg[1] == NULL)) { | ||
433 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
434 | } | ||
435 | |||
436 | #endif | ||
437 | |||
438 | starting_digit = 10 - strlen(arg[0]); | ||
439 | strcpy(&addr_str[starting_digit], arg[0]); | ||
440 | |||
441 | starting_digit = 10 - strlen(arg[1]); | ||
442 | strcpy(&len_str[starting_digit], arg[1]); | ||
443 | |||
444 | *addr = strtoul(addr_str, NULL, 16); | ||
445 | *len = strtoul(len_str, NULL, 16); /* in bytes */ | ||
446 | *data = arg[2]; | ||
447 | |||
448 | } | ||
449 | |||
450 | /***************************************************************************** | ||
451 | * process_memory_write() | ||
452 | * | ||
453 | * RSP target memory write command. | ||
454 | * | ||
455 | * Note - data is restricted to N 32-bit hex values. | ||
456 | * | ||
457 | *****************************************************************************/ | ||
458 | static void process_memory_write(char * cbuf, char * rbuf, size_t rsp_size) | ||
459 | { | ||
460 | uint32_t addr; | ||
461 | size_t len; | ||
462 | char * data_str; | ||
463 | |||
464 | get_memory_arguments(cbuf, &addr, &len, &data_str); | ||
465 | #if DEBUG | ||
466 | if ((data_str == NULL) || (len % 4 != 0) || (addr & 0x3)) { | ||
467 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
468 | } | ||
469 | #endif | ||
470 | |||
471 | /* Client must send 8 hex digits per word */ | ||
472 | do { | ||
473 | /* Do a 32-bit write */ | ||
474 | uint32_t data; | ||
475 | int offset = 0; | ||
476 | char word[] = "0x00000000"; /* data_str is in byte order 78563412 for 0x12345678*/ | ||
477 | |||
478 | int num_digits = strlen(data_str + offset); | ||
479 | if (num_digits > 8) { | ||
480 | num_digits = 8; | ||
481 | } | ||
482 | |||
483 | for (int i = 0; i < num_digits; i += 2) { | ||
484 | word[8 - i] = data_str[offset + i]; | ||
485 | word[9 - i] = data_str[offset + i + 1]; | ||
486 | } | ||
487 | |||
488 | data = strtoul(word, NULL, 16); | ||
489 | |||
490 | remote_memory_write( addr, sizeof(uint32_t), &data); | ||
491 | |||
492 | offset += 8; | ||
493 | len -= 4; | ||
494 | |||
495 | } while (len != 0); | ||
496 | |||
497 | #if DEBUG | ||
498 | if (strlen(rsp_msg_ok) > rsp_size) { | ||
499 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
500 | } | ||
501 | #endif | ||
502 | strcpy(rbuf, rsp_msg_ok); | ||
503 | |||
504 | } | ||
505 | |||
506 | /***************************************************************************** | ||
507 | * process_memory_read() | ||
508 | * | ||
509 | * RSP target memory read command. | ||
510 | * | ||
511 | * Note - data is restricted to N 32-bit hex values. | ||
512 | * | ||
513 | *****************************************************************************/ | ||
514 | static void process_memory_read(char * cbuf, char * rbuf, size_t rsp_size) | ||
515 | { | ||
516 | uint32_t addr; | ||
517 | size_t len; | ||
518 | char * rsp = rbuf; | ||
519 | char * data_str; | ||
520 | #if DEBUG | ||
521 | int digit_cnt = 0; | ||
522 | #endif | ||
523 | |||
524 | get_memory_arguments(cbuf, &addr, &len, &data_str); | ||
525 | |||
526 | #if DEBUG | ||
527 | /* data_str only valid for write, not read */ | ||
528 | if ((data_str != NULL) || (len % 4 != 0) || (addr & 0x3)) { | ||
529 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
530 | } | ||
531 | #endif | ||
532 | |||
533 | /* Will send 8 hex digits per word */ | ||
534 | do { | ||
535 | /* Do a 32-bit write */ | ||
536 | uint32_t data, adj_data, mask; | ||
537 | int num_digits; | ||
538 | |||
539 | #if DEBUG | ||
540 | if (digit_cnt > rsp_size) { | ||
541 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
542 | } | ||
543 | #endif | ||
544 | |||
545 | remote_memory_read(addr, sizeof(uint32_t), &data); | ||
546 | |||
547 | /* when len < 4 bytes suppress leading zeros */ | ||
548 | if (len > 4) { | ||
549 | num_digits = 8; | ||
550 | } else { | ||
551 | if (data < 256) num_digits = 2; | ||
552 | else if ((data > 255) && (data < 65536)) num_digits = 4; | ||
553 | else if ((data > 65535) && ( data < 16777216)) num_digits = 6; | ||
554 | else if (data > 16777215) num_digits = 8; | ||
555 | } | ||
556 | |||
557 | for (int i = 0; i < num_digits; i += 2) { | ||
558 | adj_data = data >> (i * 4); | ||
559 | mask = 0xf0; | ||
560 | *rsp++ = int_to_hexdigit((adj_data & mask) >> 4); | ||
561 | *rsp++ = int_to_hexdigit(adj_data & (mask >> 4)); | ||
562 | } | ||
563 | |||
564 | #if DEBUG | ||
565 | digit_cnt += num_digits; | ||
566 | #endif | ||
567 | len -= sizeof(uint32_t); | ||
568 | |||
569 | } while (len != 0); | ||
570 | |||
571 | } | ||
572 | |||
573 | /***************************************************************************** | ||
574 | * process_remote() | ||
575 | * | ||
576 | * Process remote RSP commands | ||
577 | * | ||
578 | * - Search the remote_command_table for a known cmd that matches the received cmd. | ||
579 | * - Tokenize the remote command into argv argc pair. | ||
580 | * - Execute the command from the remote command table. | ||
581 | * | ||
582 | *****************************************************************************/ | ||
583 | static void process_remote(char * cbuf, char * rbuf, size_t rsp_size) | ||
584 | { | ||
585 | |||
586 | int remote_element_cnt = sizeof(remote_command_table)/sizeof(struct remote_command_table_t); | ||
587 | int op_index; | ||
588 | |||
589 | LOGFUNC(); | ||
590 | |||
591 | /* Search the remote_command_table for a known cmd that matches the received cmd */ | ||
592 | for ( op_index = 0; op_index < remote_element_cnt; op_index++) { | ||
593 | /* Search the cmd string for the rsp command prefix */ | ||
594 | char *rsp_cmd = strstr(cbuf, remote_command_table[op_index].cmd); | ||
595 | |||
596 | if (rsp_cmd == cbuf) { | ||
597 | LOGMSG1("%s:Remote command match found:%s", __func__, | ||
598 | remote_command_table[op_index].cmd); | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | if (op_index == remote_element_cnt) { | ||
604 | err_handler(ERR_TYPE_LOCAL, ERR_RSP_INVALID); | ||
605 | } | ||
606 | |||
607 | /* Tokenize the remote command into argv argc pair. */ | ||
608 | { | ||
609 | #define MAX_REMOTE_ARGS 6 | ||
610 | char * argv[MAX_REMOTE_ARGS]; | ||
611 | int argc = 0; | ||
612 | char * tokins = " ,"; /* Space and comma */ | ||
613 | |||
614 | argv[argc] = strtok(cbuf, tokins); | ||
615 | while (argv[argc]) { | ||
616 | argc++; | ||
617 | #if DEBUG | ||
618 | if ( argc == MAX_REMOTE_ARGS) { | ||
619 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
620 | } | ||
621 | #endif | ||
622 | argv[argc] = strtok(NULL, tokins); | ||
623 | } | ||
624 | |||
625 | /* Process the command */ | ||
626 | |||
627 | IF_LOGGING_ENABLED { | ||
628 | for (int i = 0; i < argc; i++) { | ||
629 | LOGMSG1("%s: argv[%d] is:%s", __func__, i, argv[i]); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | remote_command_table[op_index].process(argc, argv, rbuf, rsp_size); | ||
634 | |||
635 | LOGMSG1("%s:Remote command complete, responding with:%s", __func__, rbuf); | ||
636 | |||
637 | } | ||
638 | |||
639 | } | ||
640 | |||
641 | static void process_disable_ack(char * cbuf, char * rbuf, size_t rsp_size) | ||
642 | { | ||
643 | rsp_ack_enabled = false; | ||
644 | |||
645 | #if DEBUG | ||
646 | if (strlen(rsp_msg_ok) > rsp_size) { | ||
647 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
648 | } | ||
649 | #endif | ||
650 | strcpy(rbuf, rsp_msg_ok); | ||
651 | |||
652 | } | ||
653 | |||
diff --git a/server/command_handler.h b/server/command_handler.h new file mode 100644 index 0000000..1a191cb --- /dev/null +++ b/server/command_handler.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * command_handler.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef COMMAND_HANDLER_H | ||
40 | #define COMMAND_HANDLER_H | ||
41 | |||
42 | void command_init(int socket); | ||
43 | void command_process(); | ||
44 | |||
45 | #endif | ||
diff --git a/server/ctoolsprof.h b/server/ctoolsprof.h new file mode 100644 index 0000000..0674057 --- /dev/null +++ b/server/ctoolsprof.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * ctoolsprof.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef CTOOLSPROF_H | ||
40 | #define CTOOLSPROF_H | ||
41 | |||
42 | /* Define ctoolsprof gloabls */ | ||
43 | extern const int g_major_version; | ||
44 | extern const int g_minor_version; | ||
45 | extern const int g_copyright_year; | ||
46 | |||
47 | extern FILE *g_stdout; | ||
48 | //extern FILE *g_logout; | ||
49 | extern FILE *g_stderr; | ||
50 | extern char * g_whoami; | ||
51 | |||
52 | extern bool g_fifo_used; | ||
53 | extern bool g_fifo_enabled; | ||
54 | extern int g_fifo_fd; | ||
55 | |||
56 | extern bool g_interactive_mode; | ||
57 | |||
58 | /* State definitions | ||
59 | * Uninitialized - have nerver called the start_command_handler(). | ||
60 | * Waiting - Called start_command_handler but recording may be delayed or need a signal from the user app. | ||
61 | * Stopped - Was recording, but now stopped. | ||
62 | * Recording - Obviously the receiver is recording. | ||
63 | */ | ||
64 | typedef enum { | ||
65 | STATE_UNINITIALIZED, | ||
66 | STATE_WAITING, | ||
67 | STATE_STOPPED, | ||
68 | STATE_RECORDING | ||
69 | } recording_state_t; | ||
70 | |||
71 | typedef enum { | ||
72 | ETB_MODE_ONESHOT_FIXED, | ||
73 | ETB_MODE_ONESHOT_CIRCULAR, | ||
74 | ETB_MODE_DRAIN, | ||
75 | ETB_MODE_LAST | ||
76 | } etb_mode_t; | ||
77 | |||
78 | typedef struct { | ||
79 | bool delay_active; | ||
80 | bool duration_active; | ||
81 | bool signal_active; | ||
82 | bool etb_active; | ||
83 | bool socket_disconnect; | ||
84 | etb_mode_t etb_mode; | ||
85 | recording_state_t recording; | ||
86 | } monitor_state_t; | ||
87 | |||
88 | extern monitor_state_t global_state; | ||
89 | |||
90 | void clean_up(); | ||
91 | |||
92 | #endif | ||
diff --git a/server/ctoolsprof_srv_main.c b/server/ctoolsprof_srv_main.c new file mode 100644 index 0000000..c5c79d9 --- /dev/null +++ b/server/ctoolsprof_srv_main.c | |||
@@ -0,0 +1,439 @@ | |||
1 | /* | ||
2 | * ctoolsprof_srv_main.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <stdbool.h> | ||
41 | #include <string.h> | ||
42 | #include <getopt.h> | ||
43 | #include <stdint.h> | ||
44 | #include <sys/types.h> | ||
45 | #include <sys/stat.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <unistd.h> | ||
48 | #include <errno.h> | ||
49 | #include "error_handler.h" | ||
50 | #include "logging.h" | ||
51 | #include "socket.h" | ||
52 | #include "command_handler.h" | ||
53 | #include "remote_commands.h" | ||
54 | #include "signal_handler.h" | ||
55 | #include "etb_handler.h" | ||
56 | #include "ctoolsprof.h" | ||
57 | |||
58 | const int g_major_version = 1; | ||
59 | const int g_minor_version = 0; | ||
60 | const int g_copyright_year = 2013; | ||
61 | |||
62 | FILE *g_stdout; | ||
63 | FILE *g_stderr; | ||
64 | char * g_whoami; | ||
65 | |||
66 | /* This is used by error_handler.c to determine if an error causes | ||
67 | * program exit or decides based on if the error is fatal or not. | ||
68 | */ | ||
69 | bool g_interactive_mode = false; | ||
70 | |||
71 | /* This is used to enable sending the server state over a named pipe */ | ||
72 | bool g_fifo_used = false; | ||
73 | bool g_fifo_enabled = false; | ||
74 | int g_fifo_fd = -1; | ||
75 | static char * fifo_filename = "ctprof_fifo"; | ||
76 | |||
77 | static int cmd_port = 54242; | ||
78 | static int etb_port = 54243; | ||
79 | //static int log_port = 54244; | ||
80 | |||
81 | /* Global server state initialization*/ | ||
82 | monitor_state_t global_state = { | ||
83 | .delay_active = false, | ||
84 | .duration_active = false, | ||
85 | .signal_active = false, | ||
86 | .etb_active = false, | ||
87 | .socket_disconnect = true, | ||
88 | .etb_mode = 0, | ||
89 | .recording = STATE_UNINITIALIZED | ||
90 | }; | ||
91 | |||
92 | static int cmd_socket; | ||
93 | static int etb_socket; | ||
94 | |||
95 | |||
96 | /***************************************************************************** | ||
97 | * Private functions | ||
98 | *****************************************************************************/ | ||
99 | |||
100 | /***************************************************************************** | ||
101 | * socket_connect() | ||
102 | * | ||
103 | * This function called by main to open the command and etb sockets with the | ||
104 | * client (running on the host). | ||
105 | * | ||
106 | * - Initialize the socket tables. | ||
107 | * - Create command and etb ports. This binds, listens for the client and then | ||
108 | * accepts the | ||
109 | * - Make each port non-blocking and register with their handler functions. | ||
110 | * - Set the global socket disconnect state to false. | ||
111 | * | ||
112 | *****************************************************************************/ | ||
113 | |||
114 | static void socket_connect(void) | ||
115 | { | ||
116 | LOGFUNC(); | ||
117 | |||
118 | /* Initialize the socket tables */ | ||
119 | socket_open(); | ||
120 | fprintf(g_stdout, "%s:Waiting for client to connect\n", g_whoami); | ||
121 | |||
122 | /* Configure a socket port and wait until client connects */ | ||
123 | cmd_socket = socket_server_create(cmd_port); | ||
124 | fprintf(g_stdout, "%s:Client command port connected\n", g_whoami); | ||
125 | |||
126 | /* Optimize the command socket for server operation. */ | ||
127 | socket_command_optimize(cmd_socket); | ||
128 | |||
129 | etb_socket = socket_server_create(etb_port); | ||
130 | fprintf(g_stdout, "%s:Client etb service port connected\n", g_whoami); | ||
131 | |||
132 | |||
133 | /* Make the command socket non-blocking so we don't | ||
134 | * wait on writes to complete. Add command socket to | ||
135 | * list of read file descriptors to socket_wait() to wait on. | ||
136 | */ | ||
137 | socket_set_nonblocking(cmd_socket); | ||
138 | bool is_read_socket = true; | ||
139 | socket_add_list(cmd_socket, is_read_socket); | ||
140 | |||
141 | /* Register the command socket with the command handler */ | ||
142 | command_init(cmd_socket); | ||
143 | |||
144 | /* Make the etb socket non-blocking and register the | ||
145 | * etb socket with the etb_handler. | ||
146 | * Note - unlike the command socket, no need to add | ||
147 | * the etb socket to the list of sockets to check by | ||
148 | * socket_wait() until there is some ETB data available. | ||
149 | */ | ||
150 | socket_set_nonblocking(etb_socket); | ||
151 | etb_init(etb_socket); | ||
152 | |||
153 | global_state.socket_disconnect = false; | ||
154 | |||
155 | } | ||
156 | |||
157 | /***************************************************************************** | ||
158 | * clean_up_socket() | ||
159 | * | ||
160 | * This function called by main when main detects a socket disconnect. Normally | ||
161 | * a socket disconnect only occurs when the client terminates. | ||
162 | * | ||
163 | *****************************************************************************/ | ||
164 | static void clean_up_socket(void) | ||
165 | { | ||
166 | |||
167 | LOGFUNC(); | ||
168 | |||
169 | socket_remove_list(cmd_socket); | ||
170 | socket_remove_list(etb_socket); | ||
171 | socket_close(cmd_socket); | ||
172 | socket_close(etb_socket); | ||
173 | |||
174 | } | ||
175 | |||
176 | /***************************************************************************** | ||
177 | * Public functions | ||
178 | *****************************************************************************/ | ||
179 | |||
180 | /***************************************************************************** | ||
181 | * main() | ||
182 | * | ||
183 | * Main evaluates a set of simple command line parameters and then drops into | ||
184 | * an endless loop that processes client commands or returns trace data | ||
185 | * (if available). | ||
186 | * | ||
187 | * TODO: | ||
188 | * - Add command line option to send server logging data back to the client. | ||
189 | *****************************************************************************/ | ||
190 | |||
191 | int main(int argc, char *argv[]) | ||
192 | { | ||
193 | /* Initialize globals */ | ||
194 | g_stdout = stdout; | ||
195 | g_stderr = stderr; | ||
196 | g_whoami = argv[0]; | ||
197 | |||
198 | signal_handler_init(start_recording, stop_recording); | ||
199 | |||
200 | /* evaluate command line */ | ||
201 | while (1) { | ||
202 | struct option long_options[] = { | ||
203 | {"port", required_argument, 0, 'p'}, | ||
204 | {"pipe", no_argument, 0,'P'}, | ||
205 | {"quiet", no_argument, 0,'q'}, | ||
206 | {"help", no_argument, 0, 'h'}, | ||
207 | {"logging", required_argument, 0, 'l'}, | ||
208 | {"version", no_argument, 0, 'v'} | ||
209 | }; | ||
210 | char * short_options = "p:qhl:vP"; | ||
211 | int option, option_index = 0; | ||
212 | |||
213 | option = getopt_long(argc, argv, short_options, long_options, &option_index); | ||
214 | |||
215 | /* No more options then all done */ | ||
216 | if (option == -1) break; | ||
217 | |||
218 | switch (option) { | ||
219 | case 'P': | ||
220 | { | ||
221 | struct stat fifo_stat; | ||
222 | if (stat(fifo_filename, &fifo_stat) == 0) { | ||
223 | if(!S_ISFIFO(fifo_stat.st_mode)) { | ||
224 | fprintf(g_stderr, "%s:%s already exists but is not a fifo", | ||
225 | g_whoami, fifo_filename); | ||
226 | err_handler(ERR_TYPE_SYSTEM, ERR_FIFO_MAKE); | ||
227 | } | ||
228 | } else { | ||
229 | if (mkfifo(fifo_filename, 0666) == -1) { | ||
230 | fprintf(g_stderr, "%s:Can't make %s fifo file", | ||
231 | g_whoami, fifo_filename); | ||
232 | err_handler(ERR_TYPE_SYSTEM, ERR_FIFO_MAKE); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | g_fifo_used = true; | ||
237 | g_fifo_enabled = false; | ||
238 | break; | ||
239 | } | ||
240 | case 'p': | ||
241 | cmd_port = atoi(optarg); | ||
242 | etb_port = cmd_port + 1; | ||
243 | // log_port = cmd_port + 2; | ||
244 | break; | ||
245 | case 'q': | ||
246 | g_stdout = fopen("/dev/null", "w"); | ||
247 | break; | ||
248 | case '?': /* getopt did not understand the option */ | ||
249 | case 'h': | ||
250 | fprintf(g_stdout, "Usage: %s [hlpPqv]\n", g_whoami); | ||
251 | fprintf(g_stdout, " --help/-h Print this\n"); | ||
252 | fprintf(g_stdout, " --logging/-l <level> Enable logging to LOG_FILENAME\n"); | ||
253 | fprintf(g_stdout, " Level 0 - User information logging\n"); | ||
254 | fprintf(g_stdout, " Level 1 - Debug logging\n"); | ||
255 | fprintf(g_stdout, " --port/-p <ip port> Set port value\n"); | ||
256 | fprintf(g_stdout, " --pipe/-P Issue server recording state over a named pipe\n"); | ||
257 | fprintf(g_stdout, " --quiet/-q Send stdout to /dev/null\n"); | ||
258 | fprintf(g_stdout, " --version/-v Print version\n"); | ||
259 | fprintf(g_stdout, "\n"); | ||
260 | exit(0); | ||
261 | case 'l': | ||
262 | { | ||
263 | /* Yes, this looks a bit strange, but in order to use the same | ||
264 | * log_handler for both server and client, must conform to argtable convention | ||
265 | */ | ||
266 | int level[1] = {atoi(optarg)}; | ||
267 | log_handler((void **)&level, 1); | ||
268 | if (level[1] == 0) | ||
269 | fprintf(g_stdout, "%s:Logging level set to user info logging\n", | ||
270 | g_whoami); | ||
271 | else | ||
272 | fprintf(g_stdout, "%s:Logging level set to debug logging\n", | ||
273 | g_whoami); | ||
274 | break; | ||
275 | } | ||
276 | case 'v': | ||
277 | fprintf(g_stdout, "%s:version %d.%d\n", g_whoami, g_major_version, | ||
278 | g_minor_version); | ||
279 | fprintf(g_stdout, "%s:Copyright (C) %d Texas Instruments, Inc.\n", | ||
280 | g_whoami, g_copyright_year); | ||
281 | exit(0); | ||
282 | break; | ||
283 | default: | ||
284 | err_handler(ERR_TYPE_LOCAL, ERR_PARSER); | ||
285 | } /* End of switch */ | ||
286 | |||
287 | } | ||
288 | |||
289 | /* This loop is the heart of the server! */ | ||
290 | do { | ||
291 | |||
292 | /* If disconnected then try to reconnect - will stall here until a | ||
293 | * client connects. | ||
294 | */ | ||
295 | if (global_state.socket_disconnect) { | ||
296 | LOGMSG2("%s:global_state.socket_disconnect is true", __func__); | ||
297 | socket_connect(); | ||
298 | } | ||
299 | |||
300 | /* Open the fifo if required */ | ||
301 | if ((g_fifo_used == true) && (g_fifo_fd == -1)) { | ||
302 | |||
303 | fprintf(g_stdout,"%s:Opening pipe for writing. " | ||
304 | "Waiting on pipe to be open for reading.\n", | ||
305 | g_whoami); | ||
306 | |||
307 | LOGMSG2("%s:Opening pipe for writing.", __func__); | ||
308 | |||
309 | if ((g_fifo_fd = open(fifo_filename, O_WRONLY)) == -1) { | ||
310 | fprintf(g_stderr, "%s:Can't open %s fifo file", g_whoami, | ||
311 | fifo_filename ); | ||
312 | err_handler(ERR_TYPE_SYSTEM, ERR_FIFO_OPEN); | ||
313 | } | ||
314 | |||
315 | fprintf(g_stdout,"%s:pipe open for reading\n", g_whoami); | ||
316 | LOGMSG2("%s:pipe open for reading", __func__); | ||
317 | } | ||
318 | |||
319 | /* If the fifo is used (set by command line -P option) but it is not | ||
320 | * enabled, time to enable it and send the first message (the server's pid). | ||
321 | */ | ||
322 | if ((g_fifo_used == true) && (g_fifo_enabled == false)) { | ||
323 | size_t wr_bytecnt; | ||
324 | g_fifo_enabled = true; | ||
325 | |||
326 | /* First message written is this task's pid */ | ||
327 | pid_t mypid = getpid(); | ||
328 | wr_bytecnt = write(g_fifo_fd, &mypid, sizeof(pid_t)); | ||
329 | |||
330 | if ((wr_bytecnt == -1) && (errno == EPIPE)) { | ||
331 | fprintf(g_stdout,"%s:warning - pipe reading end closed when sending pid.\n" | ||
332 | "%s: This can be caused by issuing a client operation before\n" | ||
333 | "%s: starting the task that opens the pipe's reading end.\n", | ||
334 | g_whoami, g_whoami, g_whoami); | ||
335 | } | ||
336 | |||
337 | LOGMSG2("%s:write my pid %d to pipe", __func__, mypid); | ||
338 | } | ||
339 | |||
340 | #if DEBUG | ||
341 | int state = 0; | ||
342 | fprintf (g_stdout,"Processing ...|"); | ||
343 | #endif | ||
344 | /* This is the processing loop - socket_wait will wait for: | ||
345 | * - A command socket message | ||
346 | * - An empty etb socket that is ready for more trace data | ||
347 | * - Or a timeout (socket_wait() returns 0 on a timeout) | ||
348 | */ | ||
349 | |||
350 | while (!socket_wait()) { | ||
351 | /* socket_wait() timeout - go check for available trace data */ | ||
352 | #if DEBUG | ||
353 | state++; | ||
354 | if (state == 1) fprintf (g_stdout, "\b/"); | ||
355 | else if (state == 2) fprintf (g_stdout, "\b-"); | ||
356 | else if (state == 3) fprintf (g_stdout, "\b\\"); | ||
357 | else if (state == 4) {fprintf (g_stdout, "\b|"); state = 0;} | ||
358 | fflush(stdout); | ||
359 | #endif | ||
360 | /* Don't want signals messing with our etb processing */ | ||
361 | signal_handler_block(); | ||
362 | |||
363 | if ((global_state.recording == STATE_RECORDING) | ||
364 | && (global_state.etb_active == true) | ||
365 | && (global_state.etb_mode == ETB_MODE_DRAIN)) { | ||
366 | |||
367 | etb_add_queue(ETB_QUEUE_LIMIT); | ||
368 | |||
369 | } | ||
370 | |||
371 | signal_handler_unblock(); | ||
372 | |||
373 | } | ||
374 | /* socket_wait() returned non-zero which means there is either a | ||
375 | * command message ready to service or the etb socket is ready | ||
376 | * for more data. | ||
377 | */ | ||
378 | #if DEBUG | ||
379 | fprintf(g_stdout, "\r"); | ||
380 | #endif | ||
381 | /* Don't want signals messing with our command or etb processing. */ | ||
382 | signal_handler_block(); | ||
383 | |||
384 | /* If the command socket is on the read ready list, a command | ||
385 | * message is ready to process. | ||
386 | */ | ||
387 | if (socket_check_read_list(cmd_socket)) { | ||
388 | command_process(); | ||
389 | |||
390 | } | ||
391 | |||
392 | /* If the etb socket is on the write ready list, then more | ||
393 | * etb data can be sent to the etb socket. | ||
394 | */ | ||
395 | if (socket_check_write_list(etb_socket)) { | ||
396 | etb_send_from_queue(); | ||
397 | } | ||
398 | |||
399 | signal_handler_unblock(); | ||
400 | |||
401 | /* Check for a client disconnect. This can only happen from | ||
402 | * socket_recv_data() (see socket.c). | ||
403 | */ | ||
404 | if (global_state.socket_disconnect) { | ||
405 | clean_up_socket(); | ||
406 | } | ||
407 | |||
408 | } while (1); | ||
409 | |||
410 | socket_remove_list(cmd_socket); | ||
411 | socket_close(cmd_socket); | ||
412 | |||
413 | } | ||
414 | |||
415 | /***************************************************************************** | ||
416 | * clean_up() | ||
417 | * | ||
418 | * This function is called to clean up any resources being used. It is called | ||
419 | * only by the error_handler.c when a fatal error is encountered, or when any | ||
420 | * error is encountered if not in interactive mode. | ||
421 | * | ||
422 | *****************************************************************************/ | ||
423 | void clean_up(void) | ||
424 | { | ||
425 | LOGFUNC(); | ||
426 | |||
427 | clean_up_socket(); | ||
428 | |||
429 | if (g_fifo_enabled) { | ||
430 | close(g_fifo_fd); | ||
431 | } | ||
432 | |||
433 | if (g_fifo_used) { | ||
434 | unlink(fifo_filename); | ||
435 | } | ||
436 | |||
437 | } | ||
438 | |||
439 | |||
diff --git a/server/error.c b/server/error.c new file mode 100644 index 0000000..741dcf6 --- /dev/null +++ b/server/error.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * error.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include "error.h" | ||
40 | |||
41 | struct error_info_t error_info[] = { | ||
42 | [ERR_NONE] = {"No error", false}, | ||
43 | [ERR_MEM_ALLOC] = {"Memory Allocation Error", true}, | ||
44 | [ERR_PARSER] = {"Invalid option - try --help", true}, | ||
45 | [ERR_OPT_ARG] = {"Invalid option argument - try --help", false}, | ||
46 | [ERR_LOG_FILE] = {"Can not open ctprof_srv_log.txt", false}, | ||
47 | [ERR_SOCKET_CREATE] = {"Error opening socket - try a different port", true}, | ||
48 | [ERR_SOCKET_BIND] = {"Error binding socket - try a different port", true}, | ||
49 | [ERR_SOCKET_LISTEN] = {"Error listening socket - try a different port", true}, | ||
50 | [ERR_SOCKET_ACCEPT] = {"Error accepting client - try a different port", true}, | ||
51 | [ERR_SOCKET_WRITE] = {"Can not write to client", true}, | ||
52 | [ERR_SOCKET_READ] = {"Can not read from client", true}, | ||
53 | [ERR_SOCKET_CONNECT] = {"Socket connection failure", true}, | ||
54 | [ERR_SOCKET_DISCONNECT] = {"Socket disconnected", true}, | ||
55 | [ERR_SOCKET_SEND] = {"Socket error on send", true}, | ||
56 | [ERR_SOCKET_RECV] = {"Socket error on receive", true}, | ||
57 | [ERR_SOCKET_READY] = {"Error while waiting for socket to become ready", true}, | ||
58 | [ERR_SOCKET_OPTION] = {"Error while trying to modify socket options - try a different port", true}, | ||
59 | [ERR_SOCKET_FLAGS] = {"Error modifying socket file descriptor flags", true}, | ||
60 | [ERR_SOCKET_MAX] = {"Maximum number of open sockets exceeded", true}, | ||
61 | [ERR_RSP_INVALID] = {"Invalid command received", true}, | ||
62 | [ERR_MMAP_OPEN] = {"Can not open '/dev/mem' with O_RDWR | O_SYNC | O_RSYNC attributes", true}, | ||
63 | [ERR_MMAP_FAIL] = {"Can not map region", true}, | ||
64 | [ERR_MUNMAP_FAIL] = {"Can not unmap region", true}, | ||
65 | [ERR_INVALID_SIGNAL_CAUGHT] = {"Invalid signal caught", true}, | ||
66 | [ERR_SEM_OPEN] = {"Semaphore open error", true}, | ||
67 | [ERR_ETB_ISSUE] = {"ETB Library error - see log file for details", true}, | ||
68 | [ERR_ETB_OVERFLOW] = {"ETB overflow error", false}, | ||
69 | [ERR_FIFO_MAKE] = {"FIFO file make error", true}, | ||
70 | [ERR_FIFO_OPEN] = {"FIFO file open error", true}, | ||
71 | [ERR_DEBUG] = {"Software error", true} | ||
72 | |||
73 | }; | ||
diff --git a/server/error.h b/server/error.h new file mode 100644 index 0000000..bbdb9bf --- /dev/null +++ b/server/error.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * error.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #ifndef ERROR_H | ||
39 | #define ERROR_H | ||
40 | |||
41 | #include <stdbool.h> | ||
42 | |||
43 | struct error_info_t { | ||
44 | char *msg; | ||
45 | bool fatal; | ||
46 | }; | ||
47 | |||
48 | typedef enum { ERR_NONE, | ||
49 | ERR_MEM_ALLOC, | ||
50 | ERR_PARSER, | ||
51 | ERR_OPT_ARG, | ||
52 | ERR_LOG_FILE, | ||
53 | ERR_SOCKET_CREATE, | ||
54 | ERR_SOCKET_BIND, | ||
55 | ERR_SOCKET_LISTEN, | ||
56 | ERR_SOCKET_ACCEPT, | ||
57 | ERR_SOCKET_WRITE, | ||
58 | ERR_SOCKET_READ, | ||
59 | ERR_SOCKET_CONNECT, | ||
60 | ERR_SOCKET_DISCONNECT, | ||
61 | ERR_SOCKET_SEND, | ||
62 | ERR_SOCKET_RECV, | ||
63 | ERR_SOCKET_READY, | ||
64 | ERR_SOCKET_OPTION, | ||
65 | ERR_SOCKET_FLAGS, | ||
66 | ERR_SOCKET_MAX, | ||
67 | ERR_RSP_INVALID, | ||
68 | ERR_MMAP_OPEN, | ||
69 | ERR_MMAP_FAIL, | ||
70 | ERR_MUNMAP_FAIL, | ||
71 | ERR_INVALID_SIGNAL_CAUGHT, | ||
72 | ERR_SEM_OPEN, | ||
73 | ERR_ETB_ISSUE, | ||
74 | ERR_ETB_OVERFLOW, | ||
75 | ERR_FIFO_MAKE, | ||
76 | ERR_FIFO_OPEN, | ||
77 | ERR_DEBUG | ||
78 | }err_id_t; | ||
79 | |||
80 | extern struct error_info_t error_info[]; | ||
81 | |||
82 | #endif | ||
diff --git a/server/etb_handler.c b/server/etb_handler.c new file mode 100644 index 0000000..1d6d498 --- /dev/null +++ b/server/etb_handler.c | |||
@@ -0,0 +1,666 @@ | |||
1 | /* | ||
2 | * etb_handler.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <string.h> | ||
42 | #include <stdint.h> | ||
43 | #include <stdbool.h> | ||
44 | #include "ctoolsprof.h" | ||
45 | #include "error_handler.h" | ||
46 | #include "logging.h" | ||
47 | #include "etb_handler.h" | ||
48 | #include "ETBInterface.h" | ||
49 | #include "socket.h" | ||
50 | #include <arpa/inet.h> | ||
51 | |||
52 | /***************************************************************************** | ||
53 | * Note - The etb_handler is an abstraction layer between ctprof and ETBLib. | ||
54 | * | ||
55 | *****************************************************************************/ | ||
56 | |||
57 | |||
58 | /***************************************************************************** | ||
59 | * Definitions, Constants and Statics | ||
60 | * | ||
61 | *****************************************************************************/ | ||
62 | static ETBHandle* etb_handle = NULL; | ||
63 | |||
64 | struct etb_queue_t { | ||
65 | uint32_t * buf_start; /* Start of the buffer - constant for life of queue element. Used to free the buffer. */ | ||
66 | uint32_t * buf_ptr; /* Initialized with start of buffer, but is used to schedule partially sent buffers. */ | ||
67 | int byte_cnt; | ||
68 | struct etb_queue_t * next; | ||
69 | }; | ||
70 | |||
71 | static struct etb_queue_t * etb_queue_head = NULL; | ||
72 | static struct etb_queue_t * etb_queue_tail = NULL; | ||
73 | static int etb_queue_cnt = 0; | ||
74 | |||
75 | static uint32_t etb_size; /* ETB size in uint32_t elements*/ | ||
76 | static int etb_socket; /* Socket ETB data is sent to host with */ | ||
77 | |||
78 | static const int max_queue_depth = 1024; | ||
79 | |||
80 | #ifdef TEST_MODE | ||
81 | #include "remote_commands.h" | ||
82 | static FILE * test_fp; | ||
83 | static long test_fp_recpos = 0; | ||
84 | static long test_fp_maxpos = 0; | ||
85 | static long test_fp_dtat2send = 0; | ||
86 | static const int etb_word_size = sizeof(uint32_t); | ||
87 | #endif | ||
88 | |||
89 | static bool etb_is_enabled = false; | ||
90 | static int etb_words_queued = 0; | ||
91 | |||
92 | /***************************************************************************** | ||
93 | * Internal Function Prototypes | ||
94 | * - See Private Function section below for implementations ) | ||
95 | *****************************************************************************/ | ||
96 | static void etb_process_data(int etb_word_cnt); | ||
97 | static int etb_data_available(bool * wrapped); | ||
98 | |||
99 | /***************************************************************************** | ||
100 | * Public Functions | ||
101 | * | ||
102 | *****************************************************************************/ | ||
103 | /***************************************************************************** | ||
104 | * etb_init() | ||
105 | * | ||
106 | * Initialize the etb handler with a socket. The etb_socket is used to send | ||
107 | * queued ETB Trace data back to the client. | ||
108 | * | ||
109 | *****************************************************************************/ | ||
110 | void etb_init(int socket) | ||
111 | { | ||
112 | LOGFUNC(); | ||
113 | etb_socket = socket; | ||
114 | } | ||
115 | |||
116 | /***************************************************************************** | ||
117 | * etb_config() | ||
118 | * | ||
119 | * Config ETBLib for the ETB type and operating mode. | ||
120 | * | ||
121 | * - Determine the etb mode and core id. | ||
122 | * - If TEST_MODE not defined open the ETBLib. | ||
123 | * - If TEST_MODE set open the trace data bin file, figure out the number of | ||
124 | * bytes in the file and then setup a random number generator to size the | ||
125 | * amount of ETB data that is available as the ETB is recording. | ||
126 | * | ||
127 | *****************************************************************************/ | ||
128 | void etb_config(etb_bufmode_t mode, etb_core_id_t core_id) | ||
129 | { | ||
130 | eETB_Error etb_ret; | ||
131 | eETB_Mode etb_mode; | ||
132 | uint8_t etb_core_id; | ||
133 | |||
134 | LOGFUNC(); | ||
135 | |||
136 | switch (mode) { | ||
137 | case ETB_CIRCULAR: | ||
138 | etb_mode = eETB_TI_Mode; | ||
139 | break; | ||
140 | case ETB_FIXED: | ||
141 | if (core_id == SYS_TIETB) { | ||
142 | etb_mode = eETB_TI_Mode_AND_Stop_Buffer; | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | LOGMSG1("%s:ETB only supports circular mode", __func__, etb_ret); | ||
147 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
148 | } | ||
149 | |||
150 | switch (core_id) { | ||
151 | case SYS_TIETB: | ||
152 | etb_core_id = SYS_ETB; | ||
153 | break; | ||
154 | case ARM_CSETB: | ||
155 | etb_core_id = SYS_ETB; | ||
156 | break; | ||
157 | } | ||
158 | |||
159 | /* Initialize ETB | ||
160 | * Note - ETB_open will call cTools_memMap to map the ETB address | ||
161 | * space to the ctoolsprof virtual space. | ||
162 | */ | ||
163 | { | ||
164 | #ifndef TEST_MODE | ||
165 | LOGMSG1("%s:Calling ETB_open, mode is %d, core id is %d", __func__, etb_mode, etb_core_id); | ||
166 | ETB_errorCallback etb_err_callback = NULL; | ||
167 | etb_ret = ETB_open(etb_err_callback, etb_mode, etb_core_id, | ||
168 | &etb_handle, &etb_size); | ||
169 | #else | ||
170 | test_fp = fopen("cpt_etbdata.bin", "r"); | ||
171 | if (test_fp != NULL) { | ||
172 | /* Get the position of the last byte in the file */ | ||
173 | fseek(test_fp, 0, SEEK_END); | ||
174 | test_fp_maxpos = ftell(test_fp); | ||
175 | fseek(test_fp, 0, SEEK_SET); | ||
176 | |||
177 | srand(1); | ||
178 | LOGMSG1("%s:Test file size is %d, random size max is %d", __func__, | ||
179 | test_fp_maxpos, RAND_MAX); | ||
180 | etb_ret = eETB_Success; | ||
181 | } else { | ||
182 | etb_ret = eETB_Error_Bad_Param; | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | if (etb_ret != eETB_Success) { | ||
187 | LOGMSG1("%s:ETB_open error %d", __func__, etb_ret); | ||
188 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
189 | } else { | ||
190 | LOGMSG1("%s:ETB_open successful, size of etb is %d", __func__, etb_size); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /***************************************************************************** | ||
196 | * etb_term() | ||
197 | * | ||
198 | * Close ETBLib. | ||
199 | * | ||
200 | *****************************************************************************/ | ||
201 | void etb_term() | ||
202 | { | ||
203 | eETB_Error etb_ret; | ||
204 | |||
205 | LOGFUNC(); | ||
206 | |||
207 | #ifdef TEST_MODE | ||
208 | return; | ||
209 | #endif | ||
210 | |||
211 | etb_ret = ETB_close(etb_handle); | ||
212 | if (etb_ret != eETB_Success) { | ||
213 | |||
214 | LOGMSG1("%s:ETB_close error %d", __func__, etb_ret); | ||
215 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
216 | } | ||
217 | |||
218 | } | ||
219 | |||
220 | |||
221 | /***************************************************************************** | ||
222 | * etb_status() | ||
223 | * | ||
224 | * - Returns the number of words available, if the ETB is enabled, | ||
225 | * and if it has wrapped. | ||
226 | * - If etb mode is ONESHOT and recording return number of bytes available, if | ||
227 | * not recording then return the number of words queued to transfer. | ||
228 | * - If etb mode is DRAIN then always return the number of words currently | ||
229 | * queued. | ||
230 | * | ||
231 | *****************************************************************************/ | ||
232 | int etb_status(bool * is_enabled, bool * is_wrapped) | ||
233 | { | ||
234 | |||
235 | int available_etb_words = 0; | ||
236 | |||
237 | #if DEBUG | ||
238 | if (is_wrapped == NULL) { | ||
239 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | if (is_enabled != NULL) { | ||
244 | *is_enabled = etb_is_enabled; | ||
245 | } | ||
246 | |||
247 | if (global_state.recording == STATE_UNINITIALIZED) { | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | switch (global_state.etb_mode) { | ||
252 | case ETB_MODE_ONESHOT_FIXED: | ||
253 | case ETB_MODE_ONESHOT_CIRCULAR: | ||
254 | { | ||
255 | |||
256 | if (global_state.recording == STATE_RECORDING) { | ||
257 | available_etb_words = etb_data_available(is_wrapped); | ||
258 | } else { | ||
259 | /* Must be STATE_STOPPED */ | ||
260 | etb_data_available(is_wrapped); | ||
261 | available_etb_words = etb_words_queued; | ||
262 | etb_words_queued = 0; | ||
263 | } | ||
264 | break; | ||
265 | } | ||
266 | case ETB_MODE_DRAIN: | ||
267 | { | ||
268 | available_etb_words = etb_words_queued; | ||
269 | etb_words_queued = 0; | ||
270 | break; | ||
271 | } | ||
272 | }/* End of switch */ | ||
273 | |||
274 | return available_etb_words; | ||
275 | } | ||
276 | |||
277 | /***************************************************************************** | ||
278 | * etb_enable() | ||
279 | * | ||
280 | * - Simply enable the ETB to collect data. | ||
281 | * | ||
282 | *****************************************************************************/ | ||
283 | void etb_enable() | ||
284 | { | ||
285 | eETB_Error etb_ret; | ||
286 | |||
287 | LOGFUNC(); | ||
288 | |||
289 | #ifndef TEST_MODE | ||
290 | etb_ret = ETB_enable(etb_handle, 0); | ||
291 | if(etb_ret != eETB_Success) { | ||
292 | |||
293 | LOGMSG1("%s:ETB_enable error %d", __func__, etb_ret); | ||
294 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | etb_is_enabled = true; | ||
299 | } | ||
300 | |||
301 | /***************************************************************************** | ||
302 | * etb_disable() | ||
303 | * | ||
304 | * - Simply disable the ETB. | ||
305 | * | ||
306 | *****************************************************************************/ | ||
307 | void etb_disable() | ||
308 | { | ||
309 | eETB_Error etb_ret; | ||
310 | |||
311 | LOGFUNC(); | ||
312 | |||
313 | #ifndef TEST_MODE | ||
314 | etb_ret = ETB_disable(etb_handle); | ||
315 | if(etb_ret != eETB_Success) { | ||
316 | |||
317 | LOGMSG1("%s:ETB_disable error %d", __func__, etb_ret); | ||
318 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
319 | } | ||
320 | #endif | ||
321 | etb_is_enabled = false; | ||
322 | } | ||
323 | |||
324 | /***************************************************************************** | ||
325 | * etb_add_queue() | ||
326 | * | ||
327 | * This function queues available ETB data (all the heavy lifting is done in | ||
328 | * etb_process_data()). | ||
329 | * | ||
330 | * - Check that the queue depth has not been exceeded - if so something is really | ||
331 | * wrong. Should only ever be a problem for drain mode. | ||
332 | * - If limit is ETB_QUEUE_ALL then all ETB data is sent (). If limit is set to | ||
333 | * ETB_QUEUE_LIMIT then data is only sent if the amount of data available has | ||
334 | * reached 1/4 of the ETB (which for SYS_ETB is 8K). | ||
335 | *****************************************************************************/ | ||
336 | void etb_add_queue(etb_queue_limit_t limit) | ||
337 | { | ||
338 | LOGFUNC(); | ||
339 | |||
340 | bool is_wrapped; | ||
341 | int etb_word_cnt = etb_data_available(&is_wrapped); | ||
342 | |||
343 | if (etb_queue_cnt == max_queue_depth) { | ||
344 | LOGMSG1("%s:Max queue depth reached - this most likely indicates the trace data capture rate is to high. Try decreasing the sample rate", __func__); | ||
345 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
346 | } | ||
347 | |||
348 | /* As we read the data with etb_process_data the etb rd pointer | ||
349 | * will advance toward the etb write pointer so the next time | ||
350 | * we check the number of words available should be much less | ||
351 | */ | ||
352 | |||
353 | if ( ((limit == ETB_QUEUE_LIMIT) && (etb_word_cnt > etb_size/4)) | ||
354 | || ((limit == ETB_QUEUE_ALL) && (etb_word_cnt > 0))) { | ||
355 | |||
356 | LOGMSG1("%s:process %d ETB words", __func__, etb_word_cnt); | ||
357 | etb_process_data(etb_word_cnt); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | LOGMSG1("%s:No ETB data to process", __func__); | ||
362 | |||
363 | } | ||
364 | |||
365 | /***************************************************************************** | ||
366 | * etb_send_from_queue() | ||
367 | * | ||
368 | * This function takes etb data from the queue and sends it out the etb_socket. | ||
369 | * | ||
370 | * - Get the etb buffer from the head of the queue. | ||
371 | * - Send the data to the etb_socket. Note that socket_send_data() may not send | ||
372 | * all the requested data on the first try. If socket_send_data() returns non-zero | ||
373 | * the a retry is required, so the buffer pointer and bytes to send of the queue | ||
374 | * element are simply updated. | ||
375 | * - Update the queue head. | ||
376 | *****************************************************************************/ | ||
377 | void etb_send_from_queue() | ||
378 | { | ||
379 | LOGFUNC(); | ||
380 | |||
381 | struct etb_queue_t * etb_queue_element; | ||
382 | size_t bytes_sent; | ||
383 | int retry; | ||
384 | |||
385 | uint8_t * send_buf; | ||
386 | size_t bytes_to_send; | ||
387 | |||
388 | /* Get the etb buffer from the head of the queue. */ | ||
389 | if (etb_queue_head != NULL) { | ||
390 | etb_queue_element = etb_queue_head; | ||
391 | } else { | ||
392 | #if DEBUG | ||
393 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
394 | #else | ||
395 | return; | ||
396 | #endif | ||
397 | } | ||
398 | |||
399 | etb_queue_cnt--; | ||
400 | |||
401 | send_buf = (uint8_t *)etb_queue_element->buf_ptr; | ||
402 | bytes_to_send = etb_queue_element->byte_cnt; | ||
403 | |||
404 | /* Send the data to the etb_socket. */ | ||
405 | do { | ||
406 | #if DEBUG | ||
407 | LOGMSG1("%s:sending from buf at 0x%x, %d bytes", __func__, | ||
408 | (uint32_t)send_buf, bytes_to_send); | ||
409 | #endif | ||
410 | |||
411 | retry = socket_send_data(etb_socket, send_buf, bytes_to_send, | ||
412 | 0, &bytes_sent); | ||
413 | |||
414 | if (retry) { | ||
415 | /* Reschedule what's left */ | ||
416 | etb_queue_element->buf_ptr = (uint32_t *)send_buf; | ||
417 | etb_queue_element->byte_cnt = bytes_to_send; | ||
418 | return; | ||
419 | } | ||
420 | |||
421 | send_buf += bytes_sent; | ||
422 | bytes_to_send -= bytes_sent; | ||
423 | #if DEBUG | ||
424 | LOGMSG1("%s: bytes actually sent %d, bytes remaining %d", __func__, | ||
425 | bytes_sent, bytes_to_send); | ||
426 | #endif | ||
427 | } while(bytes_to_send > 0); | ||
428 | |||
429 | /* Update the queue head */ | ||
430 | etb_queue_head = etb_queue_head->next; | ||
431 | free(etb_queue_element->buf_start); | ||
432 | free(etb_queue_element); | ||
433 | |||
434 | /* if queue is empty then remove socket from list. */ | ||
435 | if (etb_queue_head == NULL) { | ||
436 | socket_remove_list(etb_socket); | ||
437 | } | ||
438 | |||
439 | } | ||
440 | |||
441 | /***************************************************************************** | ||
442 | * Private functions | ||
443 | * | ||
444 | *****************************************************************************/ | ||
445 | /***************************************************************************** | ||
446 | * etb_data_available() | ||
447 | * | ||
448 | * - If not TEST_MODE then get the number of words available from ETB_status() | ||
449 | * and determine if the ETB has wrapped. | ||
450 | * - If TEST_MODE then get a random number of words. | ||
451 | * | ||
452 | *****************************************************************************/ | ||
453 | static int etb_data_available(bool * wrapped) | ||
454 | { | ||
455 | ETBStatus etb_status; | ||
456 | |||
457 | LOGFUNC(); | ||
458 | |||
459 | if (global_state.recording == STATE_UNINITIALIZED) { | ||
460 | LOGMSG1("%s:Recording state is STATE_UNINITIALIZED so returning 0", | ||
461 | __func__); | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | #ifndef TEST_MODE | ||
466 | { | ||
467 | eETB_Error etb_ret; | ||
468 | etb_ret = ETB_status(etb_handle, &etb_status); | ||
469 | if (etb_ret != eETB_Success) { | ||
470 | |||
471 | LOGMSG1("%s:ETB_status error %d", __func__, etb_ret); | ||
472 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
473 | } | ||
474 | LOGMSG1("%s:etb status is:", __func__); | ||
475 | LOGMSG1("%s: canRead %d", __func__, etb_status.canRead); | ||
476 | LOGMSG1("%s: isWrapped %d", __func__, etb_status.isWrapped); | ||
477 | LOGMSG1("%s: availableWords %d", __func__, etb_status.availableWords); | ||
478 | LOGMSG1("%s: ETB_TraceCaptureEn 0x%x", __func__, etb_status.ETB_TraceCaptureEn); | ||
479 | LOGMSG1("%s: overflow 0x%x", __func__, etb_status.overflow); | ||
480 | } | ||
481 | |||
482 | *wrapped = (etb_status.isWrapped) ? true : false; | ||
483 | |||
484 | if ((global_state.etb_mode == ETB_MODE_DRAIN) && (etb_status.overflow)) { | ||
485 | |||
486 | LOGMSG1("%s:ETB_status call detected a ETB buffer overflow\n", __func__); | ||
487 | //TODO An overflow error should not kill the server - should | ||
488 | // respond with zero data available, and if called from status_command_handler | ||
489 | // it needs to return "overflow" as the state so the client knows an overflow occurred | ||
490 | // and it will not get any more data. An overflow also needs to terminate the current | ||
491 | // recording session. | ||
492 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_OVERFLOW); | ||
493 | |||
494 | } | ||
495 | |||
496 | #else /* Test mode - simulate etb data */ | ||
497 | |||
498 | |||
499 | if (global_state.recording == STATE_RECORDING) { | ||
500 | |||
501 | /* Get number of bytes available to read */ | ||
502 | int size = rand(); | ||
503 | if ( (size < 0) || (size > 16384) ) { | ||
504 | size &= 0x3FFF; | ||
505 | }; | ||
506 | /* Round down to the nearest ETB word size in bytes */ | ||
507 | size -= size % etb_word_size; | ||
508 | if ((size + test_fp_recpos) > test_fp_maxpos) { | ||
509 | size = test_fp_maxpos - test_fp_recpos; | ||
510 | } | ||
511 | test_fp_recpos += size; | ||
512 | etb_status.availableWords = size/etb_word_size; | ||
513 | } | ||
514 | |||
515 | switch (global_state.etb_mode) { | ||
516 | case ETB_MODE_ONESHOT_FIXED: | ||
517 | case ETB_MODE_ONESHOT_CIRCULAR: | ||
518 | { | ||
519 | if (global_state.recording == STATE_RECORDING) { | ||
520 | etb_status.availableWords = test_fp_recpos/etb_word_size; | ||
521 | } else { | ||
522 | /* Must be STATE_STOPPED */ | ||
523 | if ((test_fp_recpos > 0) && (test_fp_dtat2send == 0)){ | ||
524 | test_fp_dtat2send = test_fp_maxpos; | ||
525 | etb_status.availableWords = test_fp_maxpos/etb_word_size; | ||
526 | test_fp_recpos = 0; | ||
527 | } | ||
528 | /* No data recorded and no data to read */ | ||
529 | if ((test_fp_recpos == 0) && (test_fp_dtat2send == 0)){ | ||
530 | etb_status.availableWords = 0; | ||
531 | } | ||
532 | /* Recorded data being read */ | ||
533 | if ((test_fp_recpos == 0) && (test_fp_dtat2send > 0)){ | ||
534 | etb_status.availableWords = test_fp_dtat2send/etb_word_size; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | *wrapped = true; | ||
539 | |||
540 | LOGMSG1("%s:Oneshot mode - found %d etb words available",__func__, | ||
541 | etb_status.availableWords); | ||
542 | break; | ||
543 | } | ||
544 | case ETB_MODE_DRAIN: | ||
545 | { | ||
546 | if (global_state.recording == STATE_STOPPED) { | ||
547 | etb_status.availableWords = (test_fp_maxpos - test_fp_recpos)/etb_word_size; | ||
548 | test_fp_recpos = 0; | ||
549 | } | ||
550 | |||
551 | *wrapped = true; | ||
552 | |||
553 | LOGMSG1("%s:Drain mode - found %d etb words available",__func__, | ||
554 | etb_status.availableWords); | ||
555 | |||
556 | break; | ||
557 | } | ||
558 | } /* End of switch */ | ||
559 | |||
560 | #endif | ||
561 | |||
562 | LOGMSG1("%s:etb words available %d", __func__, etb_status.availableWords); | ||
563 | return etb_status.availableWords; | ||
564 | |||
565 | } | ||
566 | |||
567 | /***************************************************************************** | ||
568 | * etb_process_data() | ||
569 | * | ||
570 | * This function Reads the ETB data and puts it into a buffer. The buffer is | ||
571 | * saved in a link list (etb_queue_t). | ||
572 | * | ||
573 | * - Malloc a queue element. | ||
574 | * - Malloc a buffer to hold the ETB data. | ||
575 | * - If not TEST_MODE Read the ETB Data into the buffer. | ||
576 | * - If TEST_MODE then read the ETB data from the binary file. | ||
577 | * - Coverted the ETB Data to network endianess. | ||
578 | * - Add the buffer to the queue. | ||
579 | * - Since data is queued add the etb_socket to the list of | ||
580 | * write sockets to test for ready. | ||
581 | *****************************************************************************/ | ||
582 | static void etb_process_data(int etb_word_cnt) | ||
583 | { | ||
584 | LOGFUNC(); | ||
585 | |||
586 | eETB_Error etb_ret = eETB_Success; | ||
587 | uint32_t read_size; | ||
588 | struct etb_queue_t * etb_queue_element; | ||
589 | |||
590 | /* Malloc a queue element. */ | ||
591 | etb_queue_element = malloc(sizeof(struct etb_queue_t)); | ||
592 | if (etb_queue_element == NULL) { | ||
593 | err_handler(ERR_TYPE_LOCAL, ERR_MEM_ALLOC); | ||
594 | } | ||
595 | |||
596 | /* Malloc a buffer to hold the ETB data. */ | ||
597 | etb_queue_element->byte_cnt = etb_word_cnt * sizeof(uint32_t); | ||
598 | if (etb_queue_element->byte_cnt == 0) { | ||
599 | LOGMSG1("%s:No ETB data available"); | ||
600 | return; | ||
601 | } | ||
602 | |||
603 | etb_queue_element->buf_start = malloc(etb_queue_element->byte_cnt); | ||
604 | if (etb_queue_element->buf_start == NULL) { | ||
605 | free(etb_queue_element); | ||
606 | err_handler(ERR_TYPE_LOCAL, ERR_MEM_ALLOC); | ||
607 | } | ||
608 | etb_queue_element->buf_ptr = etb_queue_element->buf_start; | ||
609 | |||
610 | /* Read the ETB Data into the buffer. */ | ||
611 | #ifndef TEST_MODE | ||
612 | etb_ret = ETB_read(etb_handle, etb_queue_element->buf_start, etb_word_cnt, 0, | ||
613 | etb_word_cnt, &read_size); | ||
614 | #else | ||
615 | read_size = fread(etb_queue_element->buf_start, sizeof(uint32_t), | ||
616 | (size_t)etb_word_cnt, test_fp); | ||
617 | //TODO Remove to optimize | ||
618 | LOGMSG1("%s:Test Mode, requested %d words, read %d words", __func__,etb_word_cnt, read_size); | ||
619 | if ((read_size < etb_word_cnt) && (ferror(test_fp))) { | ||
620 | etb_ret = eETB_Error_Cannot_Read; | ||
621 | |||
622 | } | ||
623 | |||
624 | test_fp_dtat2send -= etb_word_cnt * sizeof(uint32_t); | ||
625 | #endif | ||
626 | if(etb_ret != eETB_Success) { | ||
627 | |||
628 | LOGMSG1("%s:ETB_read error %d", __func__, etb_ret); | ||
629 | err_handler(ERR_TYPE_LOCAL, ERR_ETB_ISSUE); | ||
630 | } | ||
631 | |||
632 | /* The ETB data is a buffer of 32-bit values. As such | ||
633 | * it must be converted to network endianess. | ||
634 | */ | ||
635 | { | ||
636 | uint32_t * pdata_etb = etb_queue_element->buf_start; | ||
637 | for (int i = 0; i < read_size; i++) { | ||
638 | *pdata_etb = htonl(*pdata_etb); | ||
639 | pdata_etb++; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* Add the buffer to the queue. */ | ||
644 | LOGMSG1("%s:queuing buf at 0x%x, %d bytes", __func__, | ||
645 | (uint32_t)etb_queue_element->buf_start, etb_queue_element->byte_cnt); | ||
646 | |||
647 | etb_queue_element->next = NULL; | ||
648 | if (etb_queue_head == NULL) { | ||
649 | etb_queue_head = etb_queue_element; | ||
650 | etb_queue_tail = etb_queue_element; | ||
651 | } else { | ||
652 | etb_queue_tail->next = etb_queue_element; | ||
653 | etb_queue_tail = etb_queue_element; | ||
654 | } | ||
655 | |||
656 | etb_queue_cnt++; | ||
657 | etb_words_queued += etb_word_cnt; | ||
658 | |||
659 | /* Since data is queued add the etb_socket to the list of | ||
660 | * write sockets to test for ready. | ||
661 | */ | ||
662 | socket_add_list(etb_socket, false); /* 2nd argument is_read */ | ||
663 | |||
664 | } | ||
665 | |||
666 | |||
diff --git a/server/etb_handler.h b/server/etb_handler.h new file mode 100644 index 0000000..d34cc06 --- /dev/null +++ b/server/etb_handler.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * etb_handler.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef ETB_HANDLER_H | ||
40 | #define ETB_HANDLER_H | ||
41 | |||
42 | typedef enum {ETB_CIRCULAR, ETB_FIXED} etb_bufmode_t; | ||
43 | typedef enum {ARM_CSETB, SYS_TIETB} etb_core_id_t; | ||
44 | typedef enum {ETB_QUEUE_LIMIT, ETB_QUEUE_ALL} etb_queue_limit_t; | ||
45 | |||
46 | void etb_init(int socket); | ||
47 | void etb_config(etb_bufmode_t mode, etb_core_id_t core_id); | ||
48 | void etb_term(); | ||
49 | void etb_enable(); | ||
50 | void etb_disable(); | ||
51 | int etb_status(bool * is_enabled, bool * is_wrapped); | ||
52 | void etb_add_queue(etb_queue_limit_t limit); | ||
53 | void etb_send_from_queue(); | ||
54 | |||
55 | #endif | ||
56 | |||
diff --git a/server/makefile b/server/makefile new file mode 100644 index 0000000..8e529ea --- /dev/null +++ b/server/makefile | |||
@@ -0,0 +1,89 @@ | |||
1 | # | ||
2 | # makefile for ctprof_srv | ||
3 | # | ||
4 | # examples: | ||
5 | # make debug arm install | ||
6 | # make release arm install | ||
7 | # make clean debug arm install | ||
8 | # make clean release arm install OR make all | ||
9 | # make debug arm test - Replaces ETBLib with a simulation of the ETB using a bin trace file | ||
10 | |||
11 | ifeq ($(findstring arm, $(MAKECMDGOALS)), arm) | ||
12 | CC= $(CROSS_COMPILE)gcc --static | ||
13 | else | ||
14 | CC = gcc | ||
15 | endif | ||
16 | ifeq ($(findstring test, $(MAKECMDGOALS)), test) | ||
17 | TEST = -D TEST_MODE | ||
18 | else | ||
19 | TEST = | ||
20 | endif | ||
21 | |||
22 | ifeq ($(findstring debug, $(MAKECMDGOALS)), debug) | ||
23 | CFLAGS= -std=c99 -c -g -Wall $(INC_PATH) -D DEBUG -D SERVER -D TCI6614 -D _GNU_SOURCE $(TEST) | ||
24 | OBJDIR= ./debug | ||
25 | else | ||
26 | CFLAGS= -std=c99 -c -O2 $(INC_PATH) -D SERVER -D TCI6614 -D _GNU_SOURCE | ||
27 | OBJDIR= ./release | ||
28 | endif | ||
29 | COMMON = ../common | ||
30 | LFLAGS = | ||
31 | LIBS= -lpthread | ||
32 | LIB_PATH= | ||
33 | INCLUDE_PATH = -I $(COMMON) -I ../server | ||
34 | |||
35 | INCLUDE_FILES = ctoolsprof.h error.h error_handler.h logging.h socket.h command_handler.h remote_commands.h signal_handler.h etb_handler.h | ||
36 | |||
37 | VPATH = $(COMMON) | ||
38 | |||
39 | .PHONY: clean debug release install arm | ||
40 | |||
41 | all: clean release install | ||
42 | |||
43 | # | ||
44 | # Declare.c and .h dependencies | ||
45 | # | ||
46 | ctoolsprof_srv.o: ctoolsprof_srv_main.c $(INCLUDE_FILES) | ||
47 | socket.o: socket.c $(INCLUDE_FILES) | ||
48 | error_handler.o : error_handler.c $(INCLUDE_FILES) | ||
49 | logging.o : logging.c $(INCLUDE_FILES) | ||
50 | error.o : error.c $(INCLUDE_FILES) | ||
51 | command_handler.o : command_handler.c $(INCLUDE_FILES) | ||
52 | remote_commands.o : remote_commands.c $(INCLUDE_FILES) | ||
53 | signal_handler.o : signal_handler.c $(INCLUDE_FILES) | ||
54 | etb_handler.o : etb_handler.c $(INCLUDE_FILES) | ||
55 | TIETB.o : TIETB.c ETBAddr.h ETBInterface.h | ||
56 | |||
57 | # | ||
58 | # Add objects | ||
59 | # | ||
60 | |||
61 | OBJECTS = $(addprefix $(OBJDIR)/, ctoolsprof_srv_main.o socket.o error_handler.o logging.o error.o command_handler.o remote_commands.o signal_handler.o etb_handler.o TIETB.o) | ||
62 | |||
63 | $(OBJDIR)/%.o: %.c | ||
64 | @echo "Compiling" $< | ||
65 | @mkdir -p $(OBJDIR) | ||
66 | $(CC) $(CFLAGS) $(INCLUDE_PATH) -o $@ $< | ||
67 | |||
68 | ctprof_srv: $(OBJECTS) | ||
69 | @echo "Building target" $@ | ||
70 | $(CC) $(LFLAGS) $(LIBS_PATH) -o $(OBJDIR)/$@ $(OBJECTS) $(LIBS) | ||
71 | |||
72 | debug: ctprof_srv | ||
73 | @echo "debug build complete" | ||
74 | |||
75 | release: ctprof_srv | ||
76 | @echo "release build complete" | ||
77 | |||
78 | arm: ctprof_srv | ||
79 | @echo "ARM version built" | ||
80 | |||
81 | test: ctprof_srv | ||
82 | @echo "Test version built - ETB file simulation" | ||
83 | |||
84 | install: | ||
85 | mv ctprof_srv ~/bin/ctprof_srv | ||
86 | |||
87 | clean: | ||
88 | -rm $(OBJECTS) | ||
89 | |||
diff --git a/server/remote_commands.c b/server/remote_commands.c new file mode 100644 index 0000000..151c845 --- /dev/null +++ b/server/remote_commands.c | |||
@@ -0,0 +1,1397 @@ | |||
1 | /* | ||
2 | * remote_commands.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <stdbool.h> | ||
41 | #include <string.h> | ||
42 | #include <stdint.h> | ||
43 | #include <signal.h> | ||
44 | #include <unistd.h> | ||
45 | #include <fcntl.h> | ||
46 | #include <sys/mman.h> | ||
47 | #include <sys/time.h> | ||
48 | #include <errno.h> | ||
49 | #include "error_handler.h" | ||
50 | #include "logging.h" | ||
51 | #include "ctoolsprof.h" | ||
52 | #include "remote_commands.h" | ||
53 | #include "etb_handler.h" | ||
54 | |||
55 | |||
56 | /***************************************************************************** | ||
57 | * Remote RSP Command Definitions | ||
58 | * | ||
59 | * Note - All remote command handlers return 0 for success | ||
60 | * and -1 for failure. Returning 0 causes the command_process() | ||
61 | * function (see command_handler.c) to return rsp message "OK". | ||
62 | * Returning -1 causes the command_handler to issue a rsp error packet. | ||
63 | * The error handler may be called to generate a local error but these | ||
64 | * must be non-fatal so the rsp communications with the client can be | ||
65 | * completed. | ||
66 | *****************************************************************************/ | ||
67 | |||
68 | struct set_element_table_t { | ||
69 | char * element; | ||
70 | bool is_valid; | ||
71 | int value; | ||
72 | }; | ||
73 | |||
74 | static struct set_element_table_t set_element_table[] = { | ||
75 | [OP_MODE] = {"op-mode", false, 0}, | ||
76 | [DURATION] = {"duration", false, 0}, | ||
77 | [START_DELAY] = {"start-delay", false, 0}, | ||
78 | [ETB_ENABLE] = {"etb_enable", false, 0}, | ||
79 | [ETB_MODE] = {"etb", false, 0} | ||
80 | }; | ||
81 | |||
82 | typedef enum { | ||
83 | OP_MODE_TIME, | ||
84 | OP_MODE_SIGNAL, | ||
85 | OP_MODE_TRIGGER, | ||
86 | OP_MODE_LAST | ||
87 | } op_mode_t; | ||
88 | |||
89 | static char * op_mode_table[] = { | ||
90 | [OP_MODE_TIME] = "time", | ||
91 | [OP_MODE_SIGNAL] = "signal", | ||
92 | [OP_MODE_TRIGGER] = "trigger" | ||
93 | }; | ||
94 | |||
95 | static char * etb_mode_table[] = { | ||
96 | [ETB_MODE_ONESHOT_FIXED] = "fixed", | ||
97 | [ETB_MODE_ONESHOT_CIRCULAR] = "circular", | ||
98 | [ETB_MODE_DRAIN] = "drain" | ||
99 | }; | ||
100 | |||
101 | static const char msg_recording[] = "ctprof recording\n"; | ||
102 | static const char msg_stopped[] = "ctprof stopped\n"; | ||
103 | static const char msg_ready[] = "ctprof ready\n"; | ||
104 | |||
105 | /***************************************************************************** | ||
106 | * Internal Function Prototypes | ||
107 | * - See Private Function section below for implementations ) | ||
108 | *****************************************************************************/ | ||
109 | void * cTools_memMap(uint32_t map_addr, uint32_t map_size); | ||
110 | void cTools_memUnMap(uint32_t map_addr, uint32_t map_size); | ||
111 | static void respond_ok(char * rbuf, size_t rsp_size); | ||
112 | static void * is_memory_mapped(uint32_t addr, size_t byte_cnt, void ** v_start, size_t * len); | ||
113 | |||
114 | /***************************************************************************** | ||
115 | * Public Functions | ||
116 | *****************************************************************************/ | ||
117 | |||
118 | /***************************************************************************** | ||
119 | * get_set_value() | ||
120 | * | ||
121 | * - Provide the value for the requested element and if the value | ||
122 | * is valid(has been set). | ||
123 | *****************************************************************************/ | ||
124 | void get_set_value(set_element_t element, unsigned int *value, bool *is_valid) | ||
125 | { | ||
126 | |||
127 | #if DEBUG | ||
128 | if (element >= LAST_SET_ELEMENT) { | ||
129 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
130 | } | ||
131 | |||
132 | if ((value == NULL) || (is_valid == NULL)) { | ||
133 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
134 | } | ||
135 | #endif | ||
136 | |||
137 | *is_valid = set_element_table[element].is_valid; | ||
138 | *value = set_element_table[element].value; | ||
139 | |||
140 | } | ||
141 | |||
142 | /***************************************************************************** | ||
143 | * set_command_handler() | ||
144 | * | ||
145 | * - Set a value for the requested element | ||
146 | * - argv definition: | ||
147 | * argv[0] should always be "set". | ||
148 | * argv[1] is element to set (ie "op_mode") | ||
149 | * argv[2] is the string value. | ||
150 | * - argv elements are by definition always strings | ||
151 | * - Based on the element, the element value is converted to either an | ||
152 | * int or an enumeration and stored in set_table[n].value. | ||
153 | *****************************************************************************/ | ||
154 | void set_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
155 | { | ||
156 | int set_index; | ||
157 | size_t set_element_cnt = sizeof(set_element_table) | ||
158 | /sizeof(struct set_element_table_t); | ||
159 | |||
160 | LOGFUNC(); | ||
161 | |||
162 | #if DEBUG | ||
163 | if ((argv == NULL) || (rbuf == NULL)) { | ||
164 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
165 | } | ||
166 | #endif | ||
167 | |||
168 | /* Search the command table*/ | ||
169 | for (set_index = 0; set_index < set_element_cnt; set_index++) { | ||
170 | if (!strcmp(argv[1], set_element_table[set_index].element)) { | ||
171 | break; | ||
172 | } | ||
173 | } | ||
174 | #if DEBUG | ||
175 | if (set_index == set_element_cnt) { | ||
176 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
177 | } | ||
178 | #endif | ||
179 | |||
180 | switch(set_index) { | ||
181 | int i; | ||
182 | case OP_MODE: | ||
183 | for (i = 0; i < OP_MODE_LAST; i++) { | ||
184 | if (!strcmp(argv[2], op_mode_table[i])) { | ||
185 | set_element_table[OP_MODE].value = i; | ||
186 | set_element_table[OP_MODE].is_valid = true; | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | #if DEBUG | ||
191 | if (i == OP_MODE_LAST) { | ||
192 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
193 | } | ||
194 | #endif | ||
195 | break; | ||
196 | case DURATION: | ||
197 | set_element_table[DURATION].value = atoi(argv[2]); | ||
198 | set_element_table[DURATION].is_valid = true; | ||
199 | break; | ||
200 | case START_DELAY: | ||
201 | set_element_table[START_DELAY].value = atoi(argv[2]); | ||
202 | set_element_table[START_DELAY].is_valid = true; | ||
203 | break; | ||
204 | case ETB_ENABLE: | ||
205 | set_element_table[ETB_ENABLE].value = atoi(argv[2]); | ||
206 | set_element_table[ETB_ENABLE].is_valid = true; | ||
207 | break; | ||
208 | case ETB_MODE: | ||
209 | for (i = 0; i < ETB_MODE_LAST; i++) { | ||
210 | if (!strcmp(argv[2], etb_mode_table[i])) { | ||
211 | set_element_table[ETB_MODE].value = i; | ||
212 | set_element_table[ETB_MODE].is_valid = true; | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | #if DEBUG | ||
217 | if (i == ETB_MODE_LAST) { | ||
218 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
219 | } | ||
220 | #endif | ||
221 | break; | ||
222 | } | ||
223 | |||
224 | respond_ok(rbuf, rsp_size); | ||
225 | |||
226 | LOGMSG1("%s: set %s to %d", __func__, set_element_table[set_index].element, | ||
227 | set_element_table[set_index].value); | ||
228 | |||
229 | } | ||
230 | |||
231 | /***************************************************************************** | ||
232 | * version_command_handler() | ||
233 | * | ||
234 | * - Fill the response buffer with the version of the server. | ||
235 | * | ||
236 | *****************************************************************************/ | ||
237 | void version_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
238 | { | ||
239 | int sn_size; | ||
240 | |||
241 | #if DEBUG | ||
242 | if ((argv == NULL) || (rbuf == NULL)) { | ||
243 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
244 | } | ||
245 | #endif | ||
246 | |||
247 | sn_size = snprintf(rbuf, rsp_size,"%d.%d", g_major_version, g_minor_version); | ||
248 | #if DEBUG | ||
249 | if (sn_size > rsp_size) { | ||
250 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
251 | } | ||
252 | #endif | ||
253 | |||
254 | } | ||
255 | |||
256 | /***************************************************************************** | ||
257 | * mmap_command_handler() | ||
258 | * | ||
259 | * - Fill the response buffer with the version of the server. | ||
260 | * - argv definition: | ||
261 | * argv[0] should always be "mmap". | ||
262 | * argv[1] address string value. | ||
263 | * argv[2] size to map value. | ||
264 | * - argv elements are by definition always strings | ||
265 | * | ||
266 | *****************************************************************************/ | ||
267 | void mmap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
268 | { | ||
269 | LOGFUNC(); | ||
270 | |||
271 | #if DEBUG | ||
272 | if ((argv == NULL) || (rbuf == NULL)) { | ||
273 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
274 | } | ||
275 | #endif | ||
276 | |||
277 | uint32_t map_addr = strtoul(argv[1], NULL, 16); | ||
278 | uint32_t map_size = strtoul(argv[2], NULL, 16); | ||
279 | |||
280 | LOGMSG1("%s:physical address to map is 0x%x, size %d",__func__, | ||
281 | map_addr, map_size); | ||
282 | |||
283 | cTools_memMap(map_addr, map_size); | ||
284 | |||
285 | respond_ok(rbuf, rsp_size); | ||
286 | |||
287 | } | ||
288 | |||
289 | /***************************************************************************** | ||
290 | * ummap_command_handler() | ||
291 | * | ||
292 | * - Fill the response buffer with the version of the server. | ||
293 | * - argv definition: | ||
294 | * argv[0] should always be "ummap". | ||
295 | * argv[1] address string value. | ||
296 | * argv[2] size to ummap value. | ||
297 | * - argv elements are by definition always strings | ||
298 | * | ||
299 | * - Address from the client is always physical address so must | ||
300 | * be converted to virtual address first. | ||
301 | * | ||
302 | *****************************************************************************/ | ||
303 | void ummap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
304 | { | ||
305 | LOGFUNC(); | ||
306 | |||
307 | #if DEBUG | ||
308 | if (argc < 3) { | ||
309 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
310 | } | ||
311 | |||
312 | if ((argv == NULL) || (rbuf == NULL)) { | ||
313 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
314 | } | ||
315 | #endif | ||
316 | |||
317 | uint32_t map_addr = strtoul(argv[1], NULL, 16); | ||
318 | size_t byte_cnt = strtoul(argv[2], NULL, 16); | ||
319 | |||
320 | void * v_start_addr; | ||
321 | size_t len; | ||
322 | |||
323 | void * v_addr = is_memory_mapped(map_addr, byte_cnt, &v_start_addr, &len); | ||
324 | |||
325 | cTools_memUnMap((uint32_t)v_addr, 0); | ||
326 | |||
327 | respond_ok(rbuf, rsp_size); | ||
328 | |||
329 | } | ||
330 | |||
331 | |||
332 | /****************************************************************************** | ||
333 | * Commands Specific Definitions for arm and disarm commands | ||
334 | * | ||
335 | *****************************************************************************/ | ||
336 | |||
337 | struct modcntl_t { | ||
338 | uint32_t addr; | ||
339 | size_t value; | ||
340 | struct modcntl_t * prev_modcntl; | ||
341 | struct modcntl_t * next_modcntl; | ||
342 | }; | ||
343 | |||
344 | static struct modcntl_t * arm_table_head = NULL; // Map Object Link List head | ||
345 | static struct modcntl_t * disarm_table_head = NULL; // Map Object Link List head | ||
346 | |||
347 | |||
348 | /***************************************************************************** | ||
349 | * modcntl_add_command_handler() | ||
350 | * | ||
351 | * - Add a arm or disarm command to the arm or disarm | ||
352 | * module control (modcntl_t) link lists | ||
353 | * - argv definition: | ||
354 | * argv[0] should always be "arm" or "disarm". | ||
355 | * argv[1] address string. | ||
356 | * argv[2] value to write for arm or disarm operation | ||
357 | * - argv elements are by definition always strings | ||
358 | * | ||
359 | *****************************************************************************/ | ||
360 | void modcntl_add_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
361 | { | ||
362 | struct modcntl_t *this_modcntl = NULL; | ||
363 | struct modcntl_t **modcntl_head = NULL; | ||
364 | |||
365 | LOGFUNC(); | ||
366 | |||
367 | #if DEBUG | ||
368 | if ((argv == NULL) || (rbuf == NULL)) { | ||
369 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
370 | } | ||
371 | #endif | ||
372 | |||
373 | /* Decide which table to add arm (enable) or disarm (disable) values to. */ | ||
374 | if (!strcmp(argv[0], "arm")) { | ||
375 | modcntl_head = &arm_table_head; | ||
376 | LOGMSG1("%s:modcntl add arm address", __func__); | ||
377 | |||
378 | } else if (!strcmp(argv[0], "disarm")) { | ||
379 | modcntl_head = &disarm_table_head; | ||
380 | LOGMSG1("%s:modcntl add disarm address", __func__); | ||
381 | } | ||
382 | #if DEBUG | ||
383 | else { | ||
384 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
385 | } | ||
386 | #endif | ||
387 | |||
388 | /* Allocate space for the map element */ | ||
389 | this_modcntl = (struct modcntl_t *)malloc(sizeof(struct modcntl_t)); | ||
390 | if (this_modcntl == NULL) { | ||
391 | err_handler(ERR_TYPE_LOCAL, ERR_MEM_ALLOC); | ||
392 | } | ||
393 | |||
394 | this_modcntl->addr = strtoul(argv[1], NULL, 16); | ||
395 | this_modcntl->value = strtoul(argv[2], NULL, 16); | ||
396 | LOGMSG1("%s:add address 0x%x, value 0x%x", __func__,this_modcntl->addr, | ||
397 | this_modcntl->value); | ||
398 | |||
399 | /* Add element to end of link list */ | ||
400 | this_modcntl->next_modcntl = NULL; | ||
401 | |||
402 | if (*modcntl_head == NULL) { | ||
403 | |||
404 | *modcntl_head = this_modcntl; | ||
405 | this_modcntl->prev_modcntl = NULL; | ||
406 | } else { | ||
407 | /* Search for the last element */ | ||
408 | struct modcntl_t * modcntl_element = *modcntl_head; | ||
409 | while (modcntl_element->next_modcntl != NULL) { | ||
410 | modcntl_element = modcntl_element->next_modcntl; | ||
411 | } | ||
412 | |||
413 | modcntl_element->next_modcntl = this_modcntl; | ||
414 | this_modcntl->prev_modcntl = modcntl_element; | ||
415 | } | ||
416 | |||
417 | respond_ok(rbuf, rsp_size); | ||
418 | |||
419 | } | ||
420 | |||
421 | /***************************************************************************** | ||
422 | * modcntl_remove_command_handler() | ||
423 | * | ||
424 | * - Add a arm or disarm command to the arm or disarm | ||
425 | * module control (modcntl_t) link lists | ||
426 | * - argv definition: | ||
427 | * argv[0] should always be "rm_arm" or "rm_disarm". | ||
428 | * argv[1] address string. | ||
429 | * - argv elements are by definition always strings | ||
430 | * | ||
431 | *****************************************************************************/ | ||
432 | void modcntl_remove_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
433 | { | ||
434 | |||
435 | struct modcntl_t *this_modcntl = NULL; | ||
436 | struct modcntl_t **modcntl_head = NULL; | ||
437 | |||
438 | LOGFUNC(); | ||
439 | |||
440 | #if DEBUG | ||
441 | if ((argv == NULL) || (rbuf == NULL)) { | ||
442 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
443 | } | ||
444 | #endif | ||
445 | |||
446 | uint32_t addr = strtoul(argv[1], NULL, 16); | ||
447 | |||
448 | /* Decide which table to remove arm (enable) or disarm (disable) values */ | ||
449 | if (!strcmp(argv[0], "rm_arm")) { | ||
450 | modcntl_head = &arm_table_head; | ||
451 | LOGMSG1("%s:remove arm address 0x%x", __func__, addr); | ||
452 | |||
453 | } else if (!strcmp(argv[0], "rm_disarm")) { | ||
454 | modcntl_head = &disarm_table_head; | ||
455 | LOGMSG1("%s:remove disarm address 0x%x", __func__, addr); | ||
456 | } | ||
457 | #if DEBUG | ||
458 | else { | ||
459 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
460 | } | ||
461 | |||
462 | if (*modcntl_head == NULL) { | ||
463 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
464 | } | ||
465 | #endif | ||
466 | |||
467 | this_modcntl = *modcntl_head; | ||
468 | |||
469 | while (this_modcntl->addr != addr) { | ||
470 | this_modcntl = this_modcntl->next_modcntl; | ||
471 | if (this_modcntl == NULL) break; | ||
472 | } | ||
473 | |||
474 | #if DEBUG | ||
475 | if (this_modcntl == NULL) { | ||
476 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
477 | } | ||
478 | #endif | ||
479 | |||
480 | /* Only element in link list */ | ||
481 | if ((this_modcntl->next_modcntl == NULL) | ||
482 | && (this_modcntl->prev_modcntl == NULL)) { | ||
483 | |||
484 | LOGMSG2("%s:only one element in list", __func__); | ||
485 | *modcntl_head = NULL; | ||
486 | } | ||
487 | |||
488 | /* First element in link list */ | ||
489 | if ((this_modcntl->next_modcntl != NULL) | ||
490 | && (this_modcntl->prev_modcntl == NULL)) { | ||
491 | |||
492 | LOGMSG2("%s:first element in list", __func__); | ||
493 | *modcntl_head = this_modcntl->next_modcntl; | ||
494 | this_modcntl->next_modcntl->prev_modcntl = NULL; | ||
495 | } | ||
496 | |||
497 | /* Last element in link list */ | ||
498 | if ((this_modcntl->next_modcntl == NULL) | ||
499 | && (this_modcntl->prev_modcntl != NULL)) { | ||
500 | |||
501 | LOGMSG2("%s:last element in list", __func__); | ||
502 | this_modcntl->prev_modcntl->next_modcntl = NULL; | ||
503 | } | ||
504 | |||
505 | /* Middle element in link list */ | ||
506 | if ((this_modcntl->next_modcntl != NULL) | ||
507 | && (this_modcntl->prev_modcntl != NULL)) { | ||
508 | |||
509 | LOGMSG2("%s:element in middle of list", __func__); | ||
510 | this_modcntl->prev_modcntl->next_modcntl = | ||
511 | this_modcntl->next_modcntl; | ||
512 | this_modcntl->next_modcntl->prev_modcntl = | ||
513 | this_modcntl->prev_modcntl; | ||
514 | |||
515 | } | ||
516 | |||
517 | free(this_modcntl); | ||
518 | |||
519 | respond_ok(rbuf, rsp_size); | ||
520 | |||
521 | } | ||
522 | |||
523 | /***************************************************************************** | ||
524 | * modcntl_get_element() | ||
525 | * | ||
526 | * - Retrieve the next address/value pair for a arm or disarm table element. | ||
527 | * - The calling function sets table to either arm_table_head or disarm_table_head | ||
528 | * to start retrieving address/value pairs at the beginning of a table, or NULL | ||
529 | * when it wants to get the next value pair in the list. | ||
530 | * | ||
531 | *****************************************************************************/ | ||
532 | static struct modcntl_t *next_table_element = NULL; | ||
533 | bool modcntl_get_element(struct modcntl_t *table, uint32_t *addr, uint32_t *value) | ||
534 | { | ||
535 | |||
536 | LOGFUNC(); | ||
537 | |||
538 | #if DEBUG | ||
539 | if ((addr == NULL) || (value == NULL)) { | ||
540 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
541 | } | ||
542 | #endif | ||
543 | |||
544 | if (table != NULL) { | ||
545 | LOGMSG1("%s:First time so initialize next_table_element",__func__); | ||
546 | next_table_element = table; | ||
547 | } | ||
548 | |||
549 | if (next_table_element != NULL) { | ||
550 | *addr = next_table_element->addr; | ||
551 | *value = next_table_element->value; | ||
552 | LOGMSG1("%s:Found addr 0x%x, value 0x%x",__func__, *addr, *value); | ||
553 | next_table_element = next_table_element->next_modcntl; | ||
554 | return true; | ||
555 | } | ||
556 | |||
557 | return false; | ||
558 | } | ||
559 | |||
560 | /***************************************************************************** | ||
561 | * start_recording() | ||
562 | * | ||
563 | * - If not recording and duration_active is true then setup the timer | ||
564 | * to generate a signal when the duration is complete, terminating the | ||
565 | * recording session. | ||
566 | * - If not recording: | ||
567 | * - Enable the ETB if required. | ||
568 | * - Arm all trace sources. | ||
569 | * - Send the recording message to the app if the fifo is enabled. | ||
570 | * - Set the global recording state to recording. | ||
571 | *****************************************************************************/ | ||
572 | void start_recording() | ||
573 | { | ||
574 | unsigned int duration; | ||
575 | bool duration_valid; | ||
576 | |||
577 | LOGFUNC(); | ||
578 | |||
579 | if ((global_state.recording != STATE_RECORDING) | ||
580 | && (global_state.duration_active == true)) { | ||
581 | |||
582 | get_set_value(DURATION, &duration, &duration_valid); | ||
583 | if (duration_valid == false) { | ||
584 | duration = 0; | ||
585 | } | ||
586 | |||
587 | if (duration > 0) { | ||
588 | int err; | ||
589 | /* Setup the interval timer */ | ||
590 | |||
591 | struct itimerval duration_timer; //delay; | ||
592 | struct timeval duration_time, intraval_time; | ||
593 | |||
594 | LOGMSG1("%s:setting ITIMER_REAL for duration %d", __func__, duration); | ||
595 | /* Set the delay time: | ||
596 | * start_delay is microseconds so divide by 1000 to get seconds | ||
597 | * and then multiply the remainder by 1000 to get micro seconds remaining | ||
598 | */ | ||
599 | duration_time.tv_sec = duration/1000; | ||
600 | duration_time.tv_usec = (duration % 1000) * 1000; | ||
601 | |||
602 | intraval_time.tv_sec = 0; | ||
603 | intraval_time.tv_usec = 0; | ||
604 | |||
605 | duration_timer.it_interval = intraval_time; /* Set up time for one shot */ | ||
606 | duration_timer.it_value = duration_time; | ||
607 | |||
608 | err = setitimer(ITIMER_REAL, &duration_timer, NULL); | ||
609 | |||
610 | /* Note the signal handler for setitimer has already been | ||
611 | * by the call to signal_handler_init() from main. | ||
612 | */ | ||
613 | #if DEBUG | ||
614 | if (err == -1) { | ||
615 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
616 | } | ||
617 | #endif | ||
618 | } | ||
619 | } | ||
620 | |||
621 | /* Enable the ETB and start all modules that have an arm command registered */ | ||
622 | if (global_state.recording != STATE_RECORDING) { | ||
623 | |||
624 | if (global_state.etb_active) { | ||
625 | LOGMSG1("%s:ETB enabled", __func__); | ||
626 | etb_enable(); | ||
627 | } | ||
628 | |||
629 | |||
630 | { | ||
631 | uint32_t addr, value; | ||
632 | bool is_valid = modcntl_get_element(arm_table_head, &addr, &value); | ||
633 | LOGMSG1("%s:Starting armed modules", __func__); | ||
634 | while (is_valid) { | ||
635 | LOGMSG1("%s:arming addr 0x%x, with value 0x%x", __func__,addr, value); | ||
636 | remote_memory_write(addr, sizeof(uint32_t), &value); | ||
637 | is_valid = modcntl_get_element(NULL, &addr, &value); | ||
638 | } | ||
639 | } | ||
640 | |||
641 | if (g_fifo_enabled) { | ||
642 | size_t wr_bytecnt; | ||
643 | |||
644 | LOGMSG2("%s:write msg_recording to pipe", __func__); | ||
645 | |||
646 | wr_bytecnt = write(g_fifo_fd, msg_recording, sizeof(msg_recording)); | ||
647 | if ((wr_bytecnt == -1) && (errno == EPIPE)) { | ||
648 | fprintf(g_stdout,"%s:WARNING - pipe reading end closed when sending recording status.\n" | ||
649 | "%s: This can be caused by early termination of the task that\n" | ||
650 | "%s: opened the pipe's reading end.\n", | ||
651 | g_whoami, g_whoami, g_whoami); | ||
652 | } | ||
653 | } | ||
654 | |||
655 | fprintf(g_stdout, "\r%s:Recording started\n", g_whoami); | ||
656 | fflush(g_stdout); | ||
657 | |||
658 | global_state.recording = STATE_RECORDING; | ||
659 | |||
660 | return; | ||
661 | } | ||
662 | |||
663 | #if DEBUG | ||
664 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
665 | #endif | ||
666 | |||
667 | } | ||
668 | |||
669 | /***************************************************************************** | ||
670 | * stop_recording() | ||
671 | * | ||
672 | * - If recording: | ||
673 | * - Disarm all trace sources. | ||
674 | * - Disable the ETB if required. | ||
675 | * - Send the stop recording message to the app if the fifo is enabled. | ||
676 | * - Set the global recording state to stopped. | ||
677 | *****************************************************************************/ | ||
678 | void stop_recording() | ||
679 | { | ||
680 | LOGFUNC(); | ||
681 | |||
682 | if (global_state.recording == STATE_RECORDING) { | ||
683 | /* Stop all modules that have a disarm command registered */ | ||
684 | uint32_t addr, value; | ||
685 | bool is_valid = modcntl_get_element(disarm_table_head, &addr, &value); | ||
686 | while (is_valid) { | ||
687 | LOGMSG1("%s:disarming addr 0x%x, with value 0x%x", __func__,addr, value); | ||
688 | remote_memory_write(addr, sizeof(uint32_t), &value); | ||
689 | is_valid = modcntl_get_element(NULL, &addr, &value); | ||
690 | } | ||
691 | |||
692 | global_state.recording = STATE_STOPPED; | ||
693 | |||
694 | /* If we are not draining the ETB then need to send it's data back. | ||
695 | * Note - While TEST_MODE active must change state to STATE_STOPPED before | ||
696 | * a non-zero etb element count is reported. | ||
697 | * Note - regardless of the mode (FIXED or DRAIN) we are going to | ||
698 | * add all the current ETB data to the queue. | ||
699 | */ | ||
700 | if (global_state.etb_active) { | ||
701 | LOGMSG1("%s:ETB disabled", __func__); | ||
702 | etb_disable(); | ||
703 | etb_add_queue(ETB_QUEUE_ALL); | ||
704 | } | ||
705 | |||
706 | if (g_fifo_enabled) { | ||
707 | size_t wr_bytecnt; | ||
708 | |||
709 | LOGMSG2("%s:write msg_stopped to pipe", __func__); | ||
710 | |||
711 | wr_bytecnt = write(g_fifo_fd, msg_stopped, sizeof(msg_stopped)); | ||
712 | if ((wr_bytecnt == -1) && (errno == EPIPE)) { | ||
713 | fprintf(g_stdout,"%s:WARNING - pipe reading end closed when sending stopped status.\n" | ||
714 | "%s: This can be caused by early termination of the task that\n" | ||
715 | "%s: opened the pipe's reading end.\n", | ||
716 | g_whoami, g_whoami, g_whoami); | ||
717 | } | ||
718 | |||
719 | g_fifo_enabled = false; | ||
720 | } | ||
721 | |||
722 | fprintf(g_stdout, "\r%s:Recording stopped\n", g_whoami); | ||
723 | fflush(g_stdout); | ||
724 | |||
725 | return; | ||
726 | } | ||
727 | |||
728 | } | ||
729 | |||
730 | /***************************************************************************** | ||
731 | * start_command_handler() | ||
732 | * | ||
733 | * The client is telling the server it can start the recording process: | ||
734 | * | ||
735 | * - Initialize the global_state elements based on the operation mode (op-mode). | ||
736 | * - If ETB is enabled, process the ETB parameters and setup global_state | ||
737 | * etb elements. Configure the ETB. | ||
738 | * - If global_state.delay_active is true setup the timer to delay recording, | ||
739 | * else start recording. | ||
740 | * - if global_state.signal_active is true send the ready message to the app. | ||
741 | * | ||
742 | *****************************************************************************/ | ||
743 | void start_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
744 | { | ||
745 | |||
746 | unsigned int op_mode; | ||
747 | bool op_mode_valid; | ||
748 | unsigned int duration; | ||
749 | bool duration_valid; | ||
750 | unsigned int start_delay; | ||
751 | bool start_delay_valid; | ||
752 | unsigned int etb_value; | ||
753 | bool etb_value_valid; | ||
754 | |||
755 | LOGFUNC(); | ||
756 | |||
757 | #if DEBUG | ||
758 | if (rbuf == NULL) { | ||
759 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
760 | } | ||
761 | #endif | ||
762 | |||
763 | if (global_state.recording == STATE_RECORDING) { | ||
764 | #if DEBUG | ||
765 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
766 | } | ||
767 | #else | ||
768 | respond_ok(rbuf, rsp_size); | ||
769 | return; | ||
770 | } | ||
771 | #endif | ||
772 | |||
773 | /* Initialize the global state elements based on the operation mode. */ | ||
774 | get_set_value(OP_MODE, &op_mode, &op_mode_valid); | ||
775 | if (op_mode_valid == false) { | ||
776 | /* The default is OP_MODE_TIME with 0 delay and ~ duration | ||
777 | * (must send end command to stop) | ||
778 | */ | ||
779 | op_mode = OP_MODE_TIME; | ||
780 | } | ||
781 | |||
782 | LOGMSG1("%s:start recording with operation mode %s", __func__, op_mode_table[op_mode]); | ||
783 | |||
784 | global_state.delay_active = false; | ||
785 | global_state.duration_active = false; | ||
786 | global_state.signal_active = false; | ||
787 | global_state.etb_active = false; | ||
788 | global_state.recording = STATE_WAITING; | ||
789 | |||
790 | switch (op_mode) { | ||
791 | case OP_MODE_TIME: | ||
792 | case OP_MODE_TRIGGER: | ||
793 | get_set_value(DURATION, &duration, &duration_valid); | ||
794 | if (duration_valid == false) { | ||
795 | duration = 0; | ||
796 | } | ||
797 | get_set_value(START_DELAY, &start_delay, &start_delay_valid); | ||
798 | if (start_delay_valid == false) { | ||
799 | start_delay = 0; | ||
800 | } | ||
801 | if (start_delay > 0) { | ||
802 | global_state.delay_active = true; | ||
803 | } else { | ||
804 | global_state.duration_active = true; | ||
805 | } | ||
806 | break; | ||
807 | case OP_MODE_SIGNAL: | ||
808 | duration = 0; | ||
809 | start_delay = 0; | ||
810 | global_state.signal_active = true; | ||
811 | break; | ||
812 | } | ||
813 | |||
814 | |||
815 | LOGMSG1("%s:start with duration %d ms, start delay %d, signal mode %d", | ||
816 | __func__, duration, start_delay, global_state.signal_active); | ||
817 | |||
818 | /* If ETB is enabled, process the ETB parameters and setup global_state | ||
819 | * etb elements. | ||
820 | */ | ||
821 | get_set_value(ETB_ENABLE, &etb_value, &etb_value_valid); | ||
822 | if ((etb_value_valid == true) && (etb_value != 0)) { | ||
823 | etb_bufmode_t etb_mode; | ||
824 | global_state.etb_active = true; | ||
825 | |||
826 | get_set_value(ETB_MODE, &etb_value, &etb_value_valid); | ||
827 | if (etb_value_valid == true) { | ||
828 | global_state.etb_mode = etb_value; | ||
829 | } else { | ||
830 | global_state.etb_mode = ETB_MODE_ONESHOT_FIXED; | ||
831 | } | ||
832 | |||
833 | switch (global_state.etb_mode) { | ||
834 | case ETB_MODE_ONESHOT_FIXED: | ||
835 | etb_mode = ETB_FIXED; | ||
836 | break; | ||
837 | case ETB_MODE_ONESHOT_CIRCULAR: | ||
838 | case ETB_MODE_DRAIN: | ||
839 | etb_mode = ETB_CIRCULAR; | ||
840 | break; | ||
841 | case ETB_MODE_LAST: /* This avoids a compiler warning */ | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | /* All requirements for TCI6614 can be handled with SYS_TIETB */ | ||
846 | etb_config(etb_mode, SYS_TIETB); | ||
847 | |||
848 | LOGMSG1("%s:start with etb enable, etb mode is %s", __func__, | ||
849 | etb_mode_table[global_state.etb_mode]); | ||
850 | } else { | ||
851 | LOGMSG1("%s:start with etb disabled", __func__); | ||
852 | } | ||
853 | |||
854 | /* If global_state.delay_active is true setup the timer to delay recording. */ | ||
855 | if (global_state.delay_active == true) { | ||
856 | int err; | ||
857 | /* Setup the interval timer */ | ||
858 | |||
859 | struct itimerval delay; | ||
860 | struct timeval delay_time, intraval; | ||
861 | |||
862 | LOGMSG1("%s:setting ITIMER_REAL for start delay", __func__); | ||
863 | /* Set the delay time: | ||
864 | * start_delay is microseconds so divide by 1000 to get seconds | ||
865 | * and then multiply the remainder by 1000 to get micro seconds remaining | ||
866 | */ | ||
867 | delay_time.tv_sec = start_delay/1000; | ||
868 | delay_time.tv_usec = (start_delay % 1000) * 1000; | ||
869 | |||
870 | intraval.tv_sec = 0; | ||
871 | intraval.tv_usec = 0; | ||
872 | |||
873 | delay.it_interval = intraval; /* Set up time for one shot */ | ||
874 | delay.it_value = delay_time; | ||
875 | |||
876 | err = setitimer(ITIMER_REAL, &delay, NULL); | ||
877 | |||
878 | /* Note the signal handler for setitimer has already been | ||
879 | * by the call to signal_handler_init() from main. | ||
880 | */ | ||
881 | #if DEBUG | ||
882 | if (err == -1) { | ||
883 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
884 | } | ||
885 | #endif | ||
886 | |||
887 | } else { | ||
888 | if (global_state.duration_active == true) { | ||
889 | start_recording(); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | respond_ok(rbuf, rsp_size); | ||
894 | |||
895 | /* If signal_active is true send the ready message to the app. */ | ||
896 | if ((global_state.signal_active == true) && (g_fifo_enabled)) { | ||
897 | size_t wr_bytecnt; | ||
898 | |||
899 | wr_bytecnt = write(g_fifo_fd, msg_ready, sizeof(msg_ready)); | ||
900 | |||
901 | LOGMSG2("%s:write msg_ready to pipe - write return value is %d errno" | ||
902 | " is %d", __func__, wr_bytecnt, errno); | ||
903 | if ((wr_bytecnt == -1) && (errno == EPIPE)) { | ||
904 | fprintf(g_stdout,"%s:WARNING - pipe reading end closed when sending ready status.\n" | ||
905 | "%s: This can be caused by issuing a client operation before\n" | ||
906 | "%s: starting the task that opens the pipe's reading end.\n", | ||
907 | g_whoami, g_whoami, g_whoami); | ||
908 | } | ||
909 | |||
910 | } | ||
911 | |||
912 | } | ||
913 | |||
914 | /***************************************************************************** | ||
915 | * end_command_handler() | ||
916 | * | ||
917 | * The client is telling the server to stop recording: | ||
918 | * | ||
919 | * - If delay_active is true then terminate the timer. | ||
920 | * - Call stop_recording(). | ||
921 | * | ||
922 | *****************************************************************************/ | ||
923 | void end_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
924 | { | ||
925 | LOGFUNC(); | ||
926 | |||
927 | #if DEBUG | ||
928 | if (rbuf == NULL) { | ||
929 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
930 | } | ||
931 | #endif | ||
932 | |||
933 | /* If delay_active is true then terminate the timer */ | ||
934 | if (global_state.delay_active == true) { | ||
935 | int err; | ||
936 | struct timeval delay_time, intraval; | ||
937 | struct itimerval delay; | ||
938 | |||
939 | intraval.tv_sec = 0; | ||
940 | intraval.tv_usec = 0; | ||
941 | delay_time.tv_sec = 0; | ||
942 | delay_time.tv_usec = 0; | ||
943 | |||
944 | delay.it_interval = intraval; | ||
945 | delay.it_value = delay_time; | ||
946 | |||
947 | err = setitimer(ITIMER_REAL, &delay, NULL); | ||
948 | |||
949 | #if DEBUG | ||
950 | if (err == -1) { | ||
951 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
952 | } | ||
953 | #endif | ||
954 | |||
955 | global_state.delay_active = false; | ||
956 | |||
957 | } | ||
958 | stop_recording(); | ||
959 | |||
960 | respond_ok(rbuf, rsp_size); | ||
961 | |||
962 | } | ||
963 | |||
964 | /***************************************************************************** | ||
965 | * status_command_handler() | ||
966 | * | ||
967 | * The client is requesting status: | ||
968 | * | ||
969 | * - The status format is: | ||
970 | * recording or stopped, etb_bytes_available, server version x.y, copyright year, wrapped | ||
971 | * | ||
972 | * TODO - Separate version and copyright into a separate command (just ran out of time)! | ||
973 | *****************************************************************************/ | ||
974 | void status_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
975 | { | ||
976 | LOGFUNC(); | ||
977 | |||
978 | #if DEBUG | ||
979 | if (rbuf == NULL) { | ||
980 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
981 | } | ||
982 | #endif | ||
983 | |||
984 | char * msg; | ||
985 | int sn_size; | ||
986 | int etb_bytes_avaiable; | ||
987 | bool is_wrapped = false; | ||
988 | |||
989 | if (global_state.recording == STATE_RECORDING) { | ||
990 | msg = "recording"; | ||
991 | } | ||
992 | else { | ||
993 | if ((global_state.delay_active == true) || (global_state.signal_active == true)) { | ||
994 | msg = "recording"; | ||
995 | } else { | ||
996 | msg = "stopped"; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | if (set_element_table[ETB_MODE].is_valid == true) { | ||
1001 | /* etb_data_available returns the number of uint32_t words available*/ | ||
1002 | etb_bytes_avaiable = etb_status(NULL, &is_wrapped) * sizeof(uint32_t); | ||
1003 | } else { | ||
1004 | etb_bytes_avaiable = 0; | ||
1005 | } | ||
1006 | |||
1007 | sn_size = snprintf(rbuf, rsp_size,"%s, %d, server version %d.%d, copyright %d,", | ||
1008 | msg, etb_bytes_avaiable, g_major_version, g_minor_version, g_copyright_year); | ||
1009 | |||
1010 | |||
1011 | if (is_wrapped) { | ||
1012 | sn_size += snprintf(rbuf + sn_size, rsp_size - sn_size," wrapped"); | ||
1013 | } | ||
1014 | |||
1015 | #if DEBUG | ||
1016 | if (sn_size > rsp_size) { | ||
1017 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1018 | } | ||
1019 | #endif | ||
1020 | |||
1021 | } | ||
1022 | |||
1023 | /***************************************************************************** | ||
1024 | * debug_command_handler() | ||
1025 | * | ||
1026 | * This is a dummy command handler that can be used for developing new commands. | ||
1027 | * | ||
1028 | *****************************************************************************/ | ||
1029 | void debug_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size) | ||
1030 | { | ||
1031 | LOGFUNC(); | ||
1032 | |||
1033 | #if DEBUG | ||
1034 | if (rbuf == NULL) { | ||
1035 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1036 | } | ||
1037 | #endif | ||
1038 | |||
1039 | for (int i=0; i < argc; i++) { | ||
1040 | fprintf(g_stdout, "%s:argv[%d] is:%s\n", __func__, i, argv[i]); | ||
1041 | } | ||
1042 | |||
1043 | respond_ok(rbuf, rsp_size); | ||
1044 | |||
1045 | } | ||
1046 | |||
1047 | /***************************************************************************** | ||
1048 | * remote_memory_write() | ||
1049 | * | ||
1050 | * This function performs the physical memory write. | ||
1051 | * | ||
1052 | * - Get the virtual address | ||
1053 | * - Write the data to the virtual address, 1 32-bit word per access. | ||
1054 | *****************************************************************************/ | ||
1055 | int remote_memory_write(uint32_t addr, size_t byte_cnt, uint32_t * pbuf) | ||
1056 | { | ||
1057 | LOGFUNC(); | ||
1058 | |||
1059 | #if DEBUG | ||
1060 | if (pbuf == NULL) { | ||
1061 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1062 | } | ||
1063 | #endif | ||
1064 | |||
1065 | void * v_start_addr; | ||
1066 | size_t len; | ||
1067 | void * v_addr = is_memory_mapped(addr, byte_cnt, &v_start_addr, &len); | ||
1068 | int err; | ||
1069 | #if DEBUG | ||
1070 | if ((byte_cnt % 4) != 0) { | ||
1071 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1072 | } | ||
1073 | #endif | ||
1074 | while (byte_cnt > 0) { | ||
1075 | LOGMSG1("%s:Writing phy addr 0x%x, vir addr 0x%x, data is:0x%x", | ||
1076 | __func__, addr, v_addr, *pbuf); | ||
1077 | *(volatile uint32_t *)v_addr++ = *pbuf++; | ||
1078 | byte_cnt -= 4; | ||
1079 | } | ||
1080 | |||
1081 | #if DEBUG | ||
1082 | if ( err == -1) { | ||
1083 | err_handler(ERR_TYPE_SYSTEM, ERR_DEBUG); | ||
1084 | } | ||
1085 | #endif | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | /***************************************************************************** | ||
1090 | * remote_memory_read() | ||
1091 | * | ||
1092 | * This function performs the physical memory read. | ||
1093 | * | ||
1094 | * - Get the virtual address | ||
1095 | * - Read the data from the virtual address, 1 32-bit word per access. | ||
1096 | *****************************************************************************/ | ||
1097 | int remote_memory_read(uint32_t addr, size_t byte_cnt, uint32_t * pbuf) | ||
1098 | { | ||
1099 | LOGFUNC(); | ||
1100 | |||
1101 | #if DEBUG | ||
1102 | if (pbuf == NULL) { | ||
1103 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1104 | } | ||
1105 | #endif | ||
1106 | |||
1107 | void * v_start_addr; | ||
1108 | size_t len; | ||
1109 | volatile uint32_t * v_addr = (uint32_t *)is_memory_mapped(addr, byte_cnt, &v_start_addr, &len); | ||
1110 | #if DEBUG | ||
1111 | if ((byte_cnt % 4) != 0) { | ||
1112 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1113 | } | ||
1114 | #endif | ||
1115 | |||
1116 | while (byte_cnt > 0) { | ||
1117 | |||
1118 | *pbuf = *(volatile uint32_t *)v_addr; | ||
1119 | |||
1120 | LOGMSG1("%s:Reading phy addr 0x%x, vir addr 0x%x, data is:0x%x", | ||
1121 | __func__, addr, v_addr, *pbuf); | ||
1122 | byte_cnt -= 4; | ||
1123 | pbuf++; | ||
1124 | v_addr++; | ||
1125 | } | ||
1126 | |||
1127 | return 0; | ||
1128 | } | ||
1129 | |||
1130 | /***************************************************************************** | ||
1131 | * Private Functions | ||
1132 | *****************************************************************************/ | ||
1133 | |||
1134 | /****************************************************************************** | ||
1135 | * Commands Specific Definitions for cTools_memMap and cTools_memUnMap | ||
1136 | * | ||
1137 | *****************************************************************************/ | ||
1138 | /* Only need to open mem_fd once */ | ||
1139 | static int mem_fd = 0; | ||
1140 | |||
1141 | struct map_element_t { | ||
1142 | void * v_map_addr; /* Virtual address */ | ||
1143 | size_t v_map_size; /* Mapped size in bytes - may be whole number of pages */ | ||
1144 | uint32_t phy_addr; /* Used to request adj_v_addr */ | ||
1145 | struct map_element_t * prev_map_element; | ||
1146 | struct map_element_t * next_map_element; | ||
1147 | }; | ||
1148 | |||
1149 | static struct map_element_t * map_table_head = NULL; // Map Object Link List head | ||
1150 | |||
1151 | /***************************************************************************** | ||
1152 | * cTools_memMap() | ||
1153 | * | ||
1154 | * This function performs the physical memory mapping to this virtual space. | ||
1155 | * | ||
1156 | * - Mapped memory blocks are kept in a link list, so first check the list | ||
1157 | * if the map already exist. This is common if the client is re-started. | ||
1158 | * - Open /dev/mem if not already open. | ||
1159 | * - Allocate space for the map element. | ||
1160 | * - Adjust the size to a whole number of pages. | ||
1161 | * - Map the physical address to the virtual space. Align the physical address | ||
1162 | * to a page boundary if necessary. | ||
1163 | * - Add map element to end of link list. | ||
1164 | * | ||
1165 | * Note: Even though this is a private function to ctprof_srv, it is also | ||
1166 | * used by ETBLib (which is statically linked with ctprof_srv). For this | ||
1167 | * reason the function prototype is required to be compatible with | ||
1168 | * the cToolsHelper version that may be used with ETBLib. | ||
1169 | *****************************************************************************/ | ||
1170 | void * cTools_memMap(uint32_t map_addr, uint32_t map_size) | ||
1171 | { | ||
1172 | |||
1173 | struct map_element_t * map_element; | ||
1174 | uint32_t page_size = sysconf(_SC_PAGE_SIZE); | ||
1175 | |||
1176 | /* Check if map_addr already mapped. | ||
1177 | * Could make this more general purpose by checking | ||
1178 | * if the address is in a mapped range, but this works fine | ||
1179 | * as a simple check of debug ip mapping. | ||
1180 | */ | ||
1181 | struct map_element_t * this_map_element = map_table_head; | ||
1182 | while (this_map_element != NULL) { | ||
1183 | |||
1184 | if ((this_map_element->phy_addr == map_addr) | ||
1185 | && (this_map_element->v_map_size >= map_size)) { | ||
1186 | |||
1187 | LOGMSG1("%s:0x%x already mapped", __func__, map_addr); | ||
1188 | return this_map_element->v_map_addr; | ||
1189 | } | ||
1190 | this_map_element = this_map_element->next_map_element; | ||
1191 | } | ||
1192 | |||
1193 | if(mem_fd == 0) { | ||
1194 | mem_fd = open("/dev/mem", O_RDWR | O_SYNC | O_RSYNC ); | ||
1195 | if (mem_fd == -1) { | ||
1196 | err_handler(ERR_TYPE_SYSTEM, ERR_MMAP_OPEN); | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | /* Allocate space for the map element */ | ||
1201 | map_element = (struct map_element_t *)malloc(sizeof(struct map_element_t)); | ||
1202 | if (map_element == NULL) { | ||
1203 | err_handler(ERR_TYPE_LOCAL, ERR_MEM_ALLOC); | ||
1204 | } | ||
1205 | |||
1206 | /* Note: the physical address (map_addr) may need to be aligned to a | ||
1207 | * PAGE_SIZE and map_size may need to be a multiple of PAGE_SIZE. | ||
1208 | * This means the virtual address may need to be adjusted by the page mask | ||
1209 | * to get the same physical address (adj_v_addr). | ||
1210 | */ | ||
1211 | if ((map_size % page_size) != 0) { | ||
1212 | map_element->v_map_size = ((map_size / page_size) + 1) * page_size; | ||
1213 | } else { | ||
1214 | map_element->v_map_size = map_size; | ||
1215 | } | ||
1216 | |||
1217 | map_element->v_map_addr = mmap(0, map_element->v_map_size, | ||
1218 | PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, | ||
1219 | map_addr & ~(map_element->v_map_size -1)); | ||
1220 | |||
1221 | mlock(map_element->v_map_addr, map_element->v_map_size); | ||
1222 | |||
1223 | map_element->phy_addr = map_addr; | ||
1224 | |||
1225 | LOGMSG1("%s:phy addr: 0x%08x, phy size: %d", __func__, map_addr, map_size); | ||
1226 | LOGMSG1("%s:mapping phy addr 0x%08x",__func__, | ||
1227 | map_addr & ~(map_element->v_map_size -1)); | ||
1228 | LOGMSG1("%s:vir addr: 0x%08x, vir size: %d",__func__, | ||
1229 | map_element->v_map_addr, map_element->v_map_size); | ||
1230 | |||
1231 | if (map_element->v_map_addr == MAP_FAILED) { | ||
1232 | free(map_element); | ||
1233 | /* Fatal so error handler exits */ | ||
1234 | err_handler(ERR_TYPE_SYSTEM, ERR_MMAP_FAIL); | ||
1235 | } | ||
1236 | |||
1237 | /* Add map element to end of link list */ | ||
1238 | map_element->next_map_element = NULL; | ||
1239 | if (map_table_head == NULL) { | ||
1240 | map_table_head = map_element; | ||
1241 | map_element->prev_map_element = NULL; | ||
1242 | } else { | ||
1243 | /* Search for the last element */ | ||
1244 | struct map_element_t * this_map_element = map_table_head; | ||
1245 | while (this_map_element->next_map_element != NULL) { | ||
1246 | this_map_element = this_map_element->next_map_element; | ||
1247 | } | ||
1248 | |||
1249 | this_map_element->next_map_element = map_element; | ||
1250 | map_element->prev_map_element = this_map_element; | ||
1251 | } | ||
1252 | |||
1253 | return map_element->v_map_addr; | ||
1254 | } | ||
1255 | |||
1256 | /***************************************************************************** | ||
1257 | * cTools_memUnMap() | ||
1258 | * | ||
1259 | * This function performs the virtual memory un-mapping. | ||
1260 | * | ||
1261 | * - Find the virtual address in the link list. | ||
1262 | * - Unmap the virtual block. | ||
1263 | * - Remove it from the link list. | ||
1264 | * | ||
1265 | * Note: Eventhough this is a private function to ctprof_srv, it is also | ||
1266 | * used by ETBLib (which is statically linked with ctprof_srv). For this | ||
1267 | * reason the function prototype is required to be compatible with | ||
1268 | * the cToolsHelper version that may be used with ETBLib. | ||
1269 | *****************************************************************************/ | ||
1270 | void cTools_memUnMap(uint32_t v_map_addr, uint32_t map_size) | ||
1271 | { | ||
1272 | LOGFUNC(); | ||
1273 | |||
1274 | struct map_element_t * map_element; | ||
1275 | /* Search for the element */ | ||
1276 | struct map_element_t * this_map_element = map_table_head; | ||
1277 | |||
1278 | #if DEBUG | ||
1279 | if (this_map_element == NULL) { | ||
1280 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1281 | } | ||
1282 | #endif | ||
1283 | |||
1284 | while (this_map_element->v_map_addr != (void *)v_map_addr) { | ||
1285 | this_map_element = this_map_element->next_map_element; | ||
1286 | if (this_map_element == NULL) break; | ||
1287 | } | ||
1288 | |||
1289 | #if DEBUG | ||
1290 | if (this_map_element == NULL) { | ||
1291 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1292 | } | ||
1293 | #endif | ||
1294 | |||
1295 | int ret_val = munmap(this_map_element->v_map_addr, | ||
1296 | this_map_element->v_map_size); | ||
1297 | |||
1298 | if (ret_val == (int)MAP_FAILED) { | ||
1299 | free(map_element); | ||
1300 | /* Fatal so error handler exits */ | ||
1301 | err_handler(ERR_TYPE_SYSTEM, ERR_MUNMAP_FAIL); | ||
1302 | } | ||
1303 | |||
1304 | /* Only element in link list */ | ||
1305 | if ((this_map_element->next_map_element == NULL) | ||
1306 | && (this_map_element->prev_map_element == NULL)) { | ||
1307 | |||
1308 | map_table_head = NULL; | ||
1309 | close(mem_fd); | ||
1310 | mem_fd = 0; | ||
1311 | } | ||
1312 | |||
1313 | /* First element in link list */ | ||
1314 | if ((this_map_element->next_map_element != NULL) | ||
1315 | && (this_map_element->prev_map_element == NULL)) { | ||
1316 | |||
1317 | map_table_head = this_map_element->next_map_element; | ||
1318 | map_table_head->prev_map_element = NULL; | ||
1319 | } | ||
1320 | |||
1321 | /* Last element in link list */ | ||
1322 | if ((this_map_element->next_map_element == NULL) | ||
1323 | && (this_map_element->prev_map_element != NULL)) { | ||
1324 | |||
1325 | this_map_element->prev_map_element->next_map_element = NULL; | ||
1326 | } | ||
1327 | |||
1328 | /* Middle element in link list */ | ||
1329 | if ((this_map_element->next_map_element != NULL) | ||
1330 | && (this_map_element->prev_map_element != NULL)) { | ||
1331 | |||
1332 | this_map_element->prev_map_element->next_map_element = | ||
1333 | this_map_element->next_map_element; | ||
1334 | this_map_element->next_map_element->prev_map_element = | ||
1335 | this_map_element->prev_map_element; | ||
1336 | |||
1337 | } | ||
1338 | |||
1339 | free(this_map_element); | ||
1340 | |||
1341 | } | ||
1342 | |||
1343 | /***************************************************************************** | ||
1344 | * is_memory_mapped() | ||
1345 | * | ||
1346 | * Return virtual version of address if mapped | ||
1347 | * | ||
1348 | * - Find the physical address in the link list and return it's virtual address. | ||
1349 | *****************************************************************************/ | ||
1350 | static void * is_memory_mapped(uint32_t addr, size_t byte_cnt, void ** v_start, size_t * len) | ||
1351 | { | ||
1352 | LOGFUNC(); | ||
1353 | |||
1354 | uint32_t page_size = sysconf(_SC_PAGE_SIZE); | ||
1355 | uint32_t page_mask = page_size -1; | ||
1356 | |||
1357 | /*Search map table for match */ | ||
1358 | struct map_element_t * this_map_element = map_table_head; | ||
1359 | while (this_map_element != NULL) { | ||
1360 | |||
1361 | if ((this_map_element->phy_addr == (addr & ~(this_map_element->v_map_size - 1))) | ||
1362 | && ((addr + byte_cnt - 1) <= (this_map_element->phy_addr | ||
1363 | + this_map_element->v_map_size - 1)) ) { | ||
1364 | |||
1365 | LOGMSG1("%s:Map element found, returning address 0x%x", __func__, | ||
1366 | this_map_element->v_map_addr + (addr & page_mask)); | ||
1367 | *v_start = this_map_element->v_map_addr; | ||
1368 | *len = this_map_element->v_map_size; | ||
1369 | return this_map_element->v_map_addr + (addr & page_mask); | ||
1370 | |||
1371 | } | ||
1372 | this_map_element = this_map_element->next_map_element; | ||
1373 | } | ||
1374 | #if DEBUG | ||
1375 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1376 | #endif | ||
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | /***************************************************************************** | ||
1381 | * respond_ok() | ||
1382 | * | ||
1383 | * Provide the RSP "OK" response. | ||
1384 | * | ||
1385 | *****************************************************************************/ | ||
1386 | static void respond_ok(char * rbuf, size_t rsp_size) | ||
1387 | { | ||
1388 | int sn_size = snprintf(rbuf, rsp_size,"OK"); | ||
1389 | #if DEBUG | ||
1390 | if (sn_size > rsp_size) { | ||
1391 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
1392 | } | ||
1393 | #endif | ||
1394 | } | ||
1395 | |||
1396 | |||
1397 | |||
diff --git a/server/remote_commands.h b/server/remote_commands.h new file mode 100644 index 0000000..1d29d42 --- /dev/null +++ b/server/remote_commands.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * remote_commands.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #ifndef REMOTE_COMMANDS_H | ||
40 | #define REMOET_COMMANDS_H | ||
41 | |||
42 | typedef enum { | ||
43 | OP_MODE, | ||
44 | DURATION, | ||
45 | START_DELAY, | ||
46 | ETB_ENABLE, | ||
47 | ETB_MODE, | ||
48 | LAST_SET_ELEMENT | ||
49 | } set_element_t; | ||
50 | |||
51 | /* Note: all *_command_handler functions are meant to be called only by the command_handler. */ | ||
52 | /* All other functions may be used anywhere needed */ | ||
53 | void set_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
54 | void mmap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
55 | void ummap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
56 | void version_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
57 | void modcntl_add_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
58 | void modcntl_remove_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
59 | void start_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
60 | void end_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
61 | void status_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
62 | void debug_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size); | ||
63 | |||
64 | |||
65 | void get_set_value(set_element_t element, unsigned int *value, bool *is_valid); | ||
66 | int remote_memory_write(uint32_t addr, size_t byte_cnt, uint32_t * pbuf); | ||
67 | int remote_memory_read(uint32_t addr, size_t byte_cnt, uint32_t * pbuf); | ||
68 | |||
69 | void start_recording(); | ||
70 | void stop_recording(); | ||
71 | #endif | ||
diff --git a/server/signal_handler.c b/server/signal_handler.c new file mode 100644 index 0000000..728ae36 --- /dev/null +++ b/server/signal_handler.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * signal_handler.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <stdio.h> | ||
40 | #include <stdlib.h> | ||
41 | #include <string.h> | ||
42 | #include <stdint.h> | ||
43 | #include <signal.h> | ||
44 | #include "error_handler.h" | ||
45 | #include "logging.h" | ||
46 | #include "ctoolsprof.h" | ||
47 | #include "signal_handler.h" | ||
48 | |||
49 | static recording_op start_recording; | ||
50 | static recording_op stop_recording; | ||
51 | |||
52 | struct sigaction action; | ||
53 | |||
54 | /***************************************************************************** | ||
55 | * Private Functions | ||
56 | *****************************************************************************/ | ||
57 | /***************************************************************************** | ||
58 | * signal_handler() | ||
59 | * | ||
60 | * This is a common signal handler for all signals | ||
61 | * | ||
62 | * - If the signal is not expected then generate a fatal error and exit. | ||
63 | * - Handle the signal. | ||
64 | * - If SIGALRM and delay_active true, then start recording. | ||
65 | * - If SIGALRM and duration_active true, then stop recording. | ||
66 | * - If SIGUSR1 and signal_active true, then start recording. | ||
67 | * - If SIGUSR2 and signal_active true, then stop recording. | ||
68 | * - if SIGINT and recording then stop recording. | ||
69 | * | ||
70 | *****************************************************************************/ | ||
71 | void signal_handler(int sig) { | ||
72 | |||
73 | LOGFUNC(); | ||
74 | |||
75 | LOGMSG1("%s:Caught signal %d", __func__, sig); | ||
76 | |||
77 | /* If the signal is not expected then generate a fatal error and exit. */ | ||
78 | if ((global_state.delay_active == false) | ||
79 | && (global_state.recording == STATE_UNINITIALIZED)) { | ||
80 | |||
81 | LOGMSG1("%s:caught signal %d while in uninitialized state", __func__, | ||
82 | signal); | ||
83 | err_handler(ERR_TYPE_LOCAL, ERR_INVALID_SIGNAL_CAUGHT); | ||
84 | |||
85 | } | ||
86 | |||
87 | /* Handle the signal */ | ||
88 | switch (sig) { | ||
89 | case SIGALRM: | ||
90 | if (global_state.delay_active == true) { | ||
91 | LOGMSG1("%s:caught SIGALRM - calling start_recording()", __func__); | ||
92 | global_state.delay_active = false; | ||
93 | global_state.duration_active = true; | ||
94 | sigaction(SIGALRM, &action, NULL); | ||
95 | start_recording(); | ||
96 | } else if (global_state.duration_active == true) { | ||
97 | LOGMSG1("%s:caught SIGALRM - calling end_recording()", __func__); | ||
98 | global_state.duration_active = false; | ||
99 | sigaction(SIGALRM, &action, NULL); | ||
100 | stop_recording(); | ||
101 | } | ||
102 | break; | ||
103 | case SIGUSR1: | ||
104 | if ((global_state.recording != STATE_RECORDING) | ||
105 | && (global_state.signal_active == true)) { | ||
106 | LOGMSG1("%s:caught SIGUSR1 - calling start_recording()", __func__); | ||
107 | sigaction(SIGUSR1, &action, NULL); | ||
108 | start_recording(); | ||
109 | } | ||
110 | break; | ||
111 | case SIGUSR2: | ||
112 | if ((global_state.recording == STATE_RECORDING) | ||
113 | && (global_state.signal_active == true)) { | ||
114 | LOGMSG1("%s:caught SIGUSR2 - calling end_recording()", __func__); | ||
115 | sigaction(SIGUSR2, &action, NULL); | ||
116 | stop_recording(); | ||
117 | global_state.signal_active = false; | ||
118 | } | ||
119 | break; | ||
120 | case SIGINT: | ||
121 | if (global_state.recording == STATE_RECORDING) { | ||
122 | LOGMSG1("%s:caught SIGINT - calling end_recording()", __func__); | ||
123 | sigaction(SIGINT, &action, NULL); | ||
124 | stop_recording(); | ||
125 | } | ||
126 | break; | ||
127 | case SIGPIPE: | ||
128 | /* Client has broken the pipe - so simply stop using it */ | ||
129 | LOGMSG1("%s:caught SIGPIP - close the pipe", __func__); | ||
130 | g_fifo_enabled = false; | ||
131 | if (g_fifo_fd != -1) { | ||
132 | close(g_fifo_fd); | ||
133 | g_fifo_fd = -1; | ||
134 | } | ||
135 | break; | ||
136 | default: | ||
137 | LOGMSG1("%s:caught invalid signal %d", __func__, signal); | ||
138 | err_handler(ERR_TYPE_LOCAL, ERR_INVALID_SIGNAL_CAUGHT); | ||
139 | |||
140 | } /* End of switch */ | ||
141 | } | ||
142 | |||
143 | /***************************************************************************** | ||
144 | * Public Functions | ||
145 | *****************************************************************************/ | ||
146 | /***************************************************************************** | ||
147 | * signal_handler_init() | ||
148 | * | ||
149 | * Initialize the signal handling | ||
150 | * | ||
151 | * Note: This function takes the start_recording and stop_recording functions | ||
152 | * as inputs eliminating the need to include remote_commands.h. | ||
153 | * | ||
154 | *****************************************************************************/ | ||
155 | void signal_handler_init(recording_op start_op, recording_op stop_op) | ||
156 | { | ||
157 | LOGFUNC(); | ||
158 | |||
159 | sigset_t block_mask; | ||
160 | |||
161 | start_recording = start_op; | ||
162 | stop_recording = stop_op; | ||
163 | |||
164 | memset(&action, 0, sizeof(struct sigaction)); | ||
165 | |||
166 | /* Setup signals to be masked while servicing a signal*/ | ||
167 | sigemptyset(&block_mask); | ||
168 | sigaddset(&block_mask, SIGALRM); | ||
169 | sigaddset(&block_mask, SIGUSR1); | ||
170 | sigaddset(&block_mask, SIGUSR2); | ||
171 | sigaddset(&block_mask, SIGINT); | ||
172 | |||
173 | action.sa_handler = signal_handler; | ||
174 | action.sa_mask = block_mask; | ||
175 | |||
176 | /*Register signal handlers */ | ||
177 | sigaction(SIGALRM, &action, NULL); | ||
178 | sigaction(SIGUSR1, &action, NULL); | ||
179 | sigaction(SIGUSR2, &action, NULL); | ||
180 | sigaction(SIGINT, &action, NULL); | ||
181 | sigaction(SIGPIPE, &action, NULL); | ||
182 | |||
183 | } | ||
184 | |||
185 | /***************************************************************************** | ||
186 | * signal_handler_block() | ||
187 | * | ||
188 | * Sets signals to block. | ||
189 | * | ||
190 | * Note: This function saves the original signal blocking mask in orig_mask. | ||
191 | * | ||
192 | *****************************************************************************/ | ||
193 | static sigset_t orig_mask; | ||
194 | static bool signals_blocked = false; | ||
195 | |||
196 | void signal_handler_block() | ||
197 | { | ||
198 | if (signals_blocked == true) { | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | sigset_t block_mask; | ||
203 | |||
204 | sigemptyset(&block_mask); | ||
205 | sigaddset(&block_mask, SIGALRM); | ||
206 | sigaddset(&block_mask, SIGUSR1); | ||
207 | sigaddset(&block_mask, SIGUSR2); | ||
208 | sigaddset(&block_mask, SIGINT); | ||
209 | |||
210 | if (sigprocmask(SIG_BLOCK, &block_mask, &orig_mask) < 0) { | ||
211 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
212 | } | ||
213 | |||
214 | signals_blocked = true; | ||
215 | |||
216 | } | ||
217 | /***************************************************************************** | ||
218 | * signal_handler_unblock() | ||
219 | * | ||
220 | * Restores original signal state prior to blocking. | ||
221 | * | ||
222 | * Note: Do not call this function without calling signal_handler_block() first. | ||
223 | * | ||
224 | *****************************************************************************/ | ||
225 | void signal_handler_unblock() | ||
226 | { | ||
227 | if (signals_blocked == false) { | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) { | ||
232 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
233 | } | ||
234 | |||
235 | signals_blocked = false; | ||
236 | |||
237 | } | ||
238 | |||
diff --git a/server/signal_handler.h b/server/signal_handler.h new file mode 100644 index 0000000..85b4d94 --- /dev/null +++ b/server/signal_handler.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * signal_handler.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #ifndef SIGNAL_HANDLER_H | ||
39 | #define SIGNAL_HANDLER_H | ||
40 | |||
41 | typedef void (*recording_op)(void); | ||
42 | |||
43 | void signal_handler_init(recording_op start_recording, recording_op stop_recording); | ||
44 | void signal_handler_block(); | ||
45 | void signal_handler_unblock(); | ||
46 | |||
47 | #endif | ||
diff --git a/server/socket.c b/server/socket.c new file mode 100644 index 0000000..3f0a707 --- /dev/null +++ b/server/socket.c | |||
@@ -0,0 +1,483 @@ | |||
1 | /* | ||
2 | * socket.c | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <string.h> | ||
41 | #include <stdbool.h> | ||
42 | #include <errno.h> | ||
43 | #include <unistd.h> | ||
44 | #include <sys/socket.h> | ||
45 | #include <sys/select.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <netinet/in.h> | ||
48 | #include <netinet/tcp.h> | ||
49 | #include <sys/time.h> | ||
50 | #include "error_handler.h" | ||
51 | #include "logging.h" | ||
52 | #include "socket.h" | ||
53 | #include "ctoolsprof.h" | ||
54 | |||
55 | /* Define empty set of socket file descriptors for select */ | ||
56 | static fd_set read_fds; | ||
57 | static fd_set write_fds; | ||
58 | static int socket_cnt = 0; | ||
59 | |||
60 | /* Define socket registration table */ | ||
61 | struct socket_table_t { | ||
62 | int fd; | ||
63 | bool is_read; /* True for read fd, false for write fd */ | ||
64 | bool is_valid; | ||
65 | }; | ||
66 | |||
67 | /* Command, logging and 9 ETBs */ | ||
68 | #define MAX_SOCKETS 11 | ||
69 | |||
70 | static struct socket_table_t socket_table[MAX_SOCKETS]; | ||
71 | |||
72 | /***************************************************************************** | ||
73 | * Public functions | ||
74 | *****************************************************************************/ | ||
75 | |||
76 | /***************************************************************************** | ||
77 | * socket_open() | ||
78 | * | ||
79 | * This function needs to be called once to initialize the socket interface. | ||
80 | * | ||
81 | * - Initialize the read and write file descriptor sets | ||
82 | * - Initialize the socket table. | ||
83 | * | ||
84 | *****************************************************************************/ | ||
85 | void socket_open() | ||
86 | { | ||
87 | LOGFUNC(); | ||
88 | #if DEBUG | ||
89 | if (MAX_SOCKETS >= FD_SETSIZE) { | ||
90 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
91 | } | ||
92 | #endif | ||
93 | |||
94 | FD_ZERO(&read_fds); | ||
95 | FD_ZERO(&write_fds); | ||
96 | |||
97 | for (int i = 0; i < MAX_SOCKETS; i++) { | ||
98 | socket_table[i].is_valid = false; | ||
99 | } | ||
100 | |||
101 | } | ||
102 | |||
103 | /***************************************************************************** | ||
104 | * socket_server_create() | ||
105 | * | ||
106 | * Create a socket between this server and a client | ||
107 | * | ||
108 | * - Create and initialize the socket. | ||
109 | * - Bind the socket to the port. | ||
110 | * - Listen for a connection from the client to the socket. | ||
111 | * - Accept the connection. | ||
112 | * - Close the listening socket. | ||
113 | * - Return the client socket file descriptor. | ||
114 | * | ||
115 | * - If an error on the socket operation is detected the error handler is called. | ||
116 | * Note: All socket errors are fatal, which causes the server to exit. | ||
117 | * | ||
118 | *****************************************************************************/ | ||
119 | int socket_server_create(int port) | ||
120 | { | ||
121 | LOGFUNC(); | ||
122 | LOGMSG2("%s:Create socket for port %d", __func__, port); | ||
123 | |||
124 | int socket_fd, client_socket_fd; | ||
125 | struct sockaddr_in server, client; | ||
126 | socklen_t client_size = sizeof(client); | ||
127 | int reuse_addr = 1; | ||
128 | |||
129 | if (socket_cnt == MAX_SOCKETS) { | ||
130 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_MAX); | ||
131 | } | ||
132 | |||
133 | /* Create and initialize the socket. */ | ||
134 | socket_fd = socket(PF_INET, SOCK_STREAM, 0); | ||
135 | if (socket_fd < 0) { | ||
136 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_CREATE); | ||
137 | } | ||
138 | |||
139 | if(setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof reuse_addr) == -1) { | ||
140 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_OPTION); | ||
141 | } | ||
142 | |||
143 | LOGMSG2("%s:socket file descriptor opened for AF_INET & SOCK_STERAM", __func__); | ||
144 | |||
145 | memset(&server,0,sizeof(struct sockaddr_in)); | ||
146 | server.sin_family = AF_INET; | ||
147 | server.sin_addr.s_addr = htonl(INADDR_ANY); | ||
148 | server.sin_port = htons((uint16_t)port); | ||
149 | |||
150 | /* Bind the socket to the port. */ | ||
151 | if(bind(socket_fd, (struct sockaddr *)&server, sizeof(server)) < 0) { | ||
152 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_BIND); | ||
153 | } | ||
154 | |||
155 | /* Listen for a connection from the client to the socket. */ | ||
156 | if (listen(socket_fd, 1) < 0) { | ||
157 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_LISTEN); | ||
158 | |||
159 | } | ||
160 | |||
161 | /* Accept the connection. */ | ||
162 | memset(&client,0,sizeof(struct sockaddr_in)); | ||
163 | client_socket_fd = accept(socket_fd, (struct sockaddr *)&client, | ||
164 | &client_size); | ||
165 | if(-1 == client_socket_fd) { | ||
166 | LOGMSG2("%s:client accept error is %d", __func__, client_socket_fd); | ||
167 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_ACCEPT); | ||
168 | } | ||
169 | |||
170 | LOGMSG2("%s:client connect accepted client_socket_fd is %d", __func__, client_socket_fd); | ||
171 | |||
172 | /* Close the listening socket. */ | ||
173 | close(socket_fd); | ||
174 | |||
175 | /* Increment the socket count */ | ||
176 | socket_cnt++; | ||
177 | |||
178 | /* Return the client socket file descriptor. */ | ||
179 | return client_socket_fd; | ||
180 | } | ||
181 | |||
182 | /***************************************************************************** | ||
183 | * socket_command_optimize() | ||
184 | * | ||
185 | * Optimize the command socket. | ||
186 | *****************************************************************************/ | ||
187 | void socket_command_optimize(int socket_fd) | ||
188 | { | ||
189 | int on = 1; | ||
190 | |||
191 | if(setsockopt(socket_fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) == -1) { | ||
192 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_OPTION); | ||
193 | } | ||
194 | |||
195 | } | ||
196 | |||
197 | |||
198 | /***************************************************************************** | ||
199 | * socket_recv_data() | ||
200 | * | ||
201 | * Get a buffer of data from a socket file descriptor. | ||
202 | * | ||
203 | * Note: This function is non-blocking safe. | ||
204 | * | ||
205 | * - If the call to recv() executes successfully buf_retlen will be non-zero | ||
206 | * and the function returns 0. | ||
207 | * - If socket_fd has been set to non-blocking and no data is available | ||
208 | * EAGAIN is returned. | ||
209 | * - If an error on the socket is detected the error handler is called. | ||
210 | * Note: All socket errors are fatal, which causes the server to exit. | ||
211 | * - If a client disconnect is detected, the global disconnect state is set, | ||
212 | * buf_retlen is set to 0, and the function returns 0. | ||
213 | * | ||
214 | *****************************************************************************/ | ||
215 | int socket_recv_data(int socket_fd, uint8_t* buf, size_t buf_len, | ||
216 | size_t buf_offset, size_t* buf_retlen) | ||
217 | { | ||
218 | char* pbuf = (char*)buf + buf_offset; | ||
219 | int length = buf_len - buf_offset; | ||
220 | |||
221 | #if DEBUG | ||
222 | if ((buf == NULL) || (buf_retlen == NULL)) { | ||
223 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
224 | } | ||
225 | #endif | ||
226 | |||
227 | *buf_retlen = recv(socket_fd, pbuf, (int)length, 0); | ||
228 | |||
229 | if ((-1 == (int) *buf_retlen ) | ||
230 | && ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))) { | ||
231 | return EAGAIN; | ||
232 | } | ||
233 | |||
234 | if ((-1 == (int) *buf_retlen ) | ||
235 | && ((errno == ECONNRESET) || (errno == ECONNABORTED) || errno == EPIPE)) { | ||
236 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_CONNECT); | ||
237 | } | ||
238 | |||
239 | if (-1 == (int) *buf_retlen ) { | ||
240 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_RECV); | ||
241 | } | ||
242 | |||
243 | if(0 == *buf_retlen) { | ||
244 | LOGMSG2("%s:disconnect detected - setting global_state.socket_disconnect true", __func__); | ||
245 | global_state.socket_disconnect = true; | ||
246 | } | ||
247 | |||
248 | return 0; | ||
249 | |||
250 | } | ||
251 | |||
252 | /***************************************************************************** | ||
253 | * socket_send_data() | ||
254 | * | ||
255 | * Send a buffer of data to a socket file descriptor. | ||
256 | * | ||
257 | * Note: This function is non-blocking safe. | ||
258 | * | ||
259 | * - If the call to send() executes successfully buf_retlen will indicate the | ||
260 | * number of bytes sent from buf and the function returns 0. | ||
261 | * - If socket_fd has been set to non-blocking and data can not be sent | ||
262 | * EAGAIN is returned. | ||
263 | * - If an error on the socket is detected the error handler is called. | ||
264 | * Note: All socket errors are fatal, which causes the server to exit. | ||
265 | * | ||
266 | *****************************************************************************/ | ||
267 | int socket_send_data(int socket_fd, uint8_t* buf, size_t buf_len, | ||
268 | size_t buf_offset, size_t* buf_retlen) | ||
269 | { | ||
270 | const char* pbuf = (const char*)buf + buf_offset; | ||
271 | *buf_retlen =0; | ||
272 | |||
273 | #if DEBUG | ||
274 | if ((buf == NULL) || (buf_retlen == NULL)) { | ||
275 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
276 | } | ||
277 | #endif | ||
278 | |||
279 | *buf_retlen = send(socket_fd, pbuf, (int)buf_len, 0); | ||
280 | |||
281 | if ((-1 == (int) *buf_retlen ) | ||
282 | && ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))) { | ||
283 | return EAGAIN; | ||
284 | } | ||
285 | |||
286 | if ((-1 == (int) *buf_retlen ) | ||
287 | && ((errno == ECONNRESET) || (errno == ECONNABORTED) || errno == EPIPE)) { | ||
288 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_CONNECT); | ||
289 | } | ||
290 | |||
291 | if (-1 == (int) *buf_retlen ) { | ||
292 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_SEND); | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | |||
297 | } | ||
298 | |||
299 | /***************************************************************************** | ||
300 | * socket_add_list() | ||
301 | * | ||
302 | * - Add a socket file descriptor to the socket table. | ||
303 | * | ||
304 | *****************************************************************************/ | ||
305 | void socket_add_list(int socket_fd, bool is_read) | ||
306 | { | ||
307 | LOGFUNC(); | ||
308 | |||
309 | int i, first_invalid; | ||
310 | bool first_invalid_found = false; | ||
311 | |||
312 | #if DEBUG | ||
313 | if (socket_fd >= FD_SETSIZE) { | ||
314 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
315 | } | ||
316 | #endif | ||
317 | |||
318 | for (i = 0; i < MAX_SOCKETS; i++) { | ||
319 | |||
320 | if ((socket_table[i].is_valid) && (socket_table[i].fd == socket_fd)){ | ||
321 | return; | ||
322 | } | ||
323 | if ((!socket_table[i].is_valid) && (!first_invalid_found)) { | ||
324 | first_invalid = i; | ||
325 | first_invalid_found = true; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | #if DEBUG | ||
330 | if (!first_invalid_found) { | ||
331 | err_handler(ERR_TYPE_LOCAL, ERR_DEBUG); | ||
332 | } | ||
333 | #endif | ||
334 | |||
335 | socket_table[first_invalid].is_valid = true; | ||
336 | socket_table[first_invalid].is_read = is_read; | ||
337 | socket_table[first_invalid].fd = socket_fd; | ||
338 | |||
339 | LOGMSG1("%s:add socket %d to socket_table position %d", __func__, socket_fd, first_invalid); | ||
340 | |||
341 | } | ||
342 | |||
343 | /***************************************************************************** | ||
344 | * socket_remove_list() | ||
345 | * | ||
346 | * - Remove a socket file descriptor from the socket table. | ||
347 | * | ||
348 | *****************************************************************************/ | ||
349 | void socket_remove_list(int socket_fd) | ||
350 | { | ||
351 | LOGFUNC(); | ||
352 | int i; | ||
353 | |||
354 | for (i = 0; i < MAX_SOCKETS; i++) { | ||
355 | if ((socket_table[i].is_valid) && (socket_table[i].fd == socket_fd)){ | ||
356 | socket_table[i].is_valid = false; | ||
357 | LOGMSG1("%s:remove socket %d from socket_table position %d", __func__, socket_fd, i); | ||
358 | break; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | if (i == MAX_SOCKETS) { | ||
363 | LOGMSG1("%s:Did not find socket in list - this may not be a problem", __func__); | ||
364 | } | ||
365 | |||
366 | } | ||
367 | |||
368 | /***************************************************************************** | ||
369 | * socket_check_read_list() | ||
370 | * | ||
371 | * - Return true if this socket is in the set of read sockets that have | ||
372 | * data available. | ||
373 | * | ||
374 | *****************************************************************************/ | ||
375 | int socket_check_read_list(int socket_fd) | ||
376 | { | ||
377 | return FD_ISSET (socket_fd, &read_fds); | ||
378 | |||
379 | } | ||
380 | |||
381 | /***************************************************************************** | ||
382 | * socket_check_write_list() | ||
383 | * | ||
384 | * - Return true if this socket is in the set of write sockets that are ready | ||
385 | * to send more data. | ||
386 | * | ||
387 | *****************************************************************************/ | ||
388 | int socket_check_write_list(int socket_fd) | ||
389 | { | ||
390 | return FD_ISSET (socket_fd, &write_fds); | ||
391 | |||
392 | } | ||
393 | |||
394 | /***************************************************************************** | ||
395 | * socket_set_nonblocking() | ||
396 | * | ||
397 | * - Set the socket file descriptor non-blocking. | ||
398 | * | ||
399 | *****************************************************************************/ | ||
400 | void socket_set_nonblocking(int socket_fd) | ||
401 | { | ||
402 | LOGFUNC(); | ||
403 | int flags = fcntl(socket_fd, F_GETFL, 0); | ||
404 | if (flags < 0) { | ||
405 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_FLAGS); | ||
406 | } | ||
407 | |||
408 | flags = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK); | ||
409 | if (flags < 0) { | ||
410 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_FLAGS); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | /***************************************************************************** | ||
415 | * socket_wait() | ||
416 | * | ||
417 | * Wait for either a 1 msec timeout or for a read socket with data available | ||
418 | * or a write socket that is ready for data. | ||
419 | * | ||
420 | * - Set the timeout struct. | ||
421 | * - Set the read and write file descriptor sets. | ||
422 | * - Wait for a file descriptor event or timeout. | ||
423 | * - Returns 0 for timeout, or the number of file descriptors with events pending | ||
424 | * (number of read_fds with data ready to read and write_fds that are ready for | ||
425 | * more data). | ||
426 | * | ||
427 | *****************************************************************************/ | ||
428 | int socket_wait() | ||
429 | { | ||
430 | int activity, high_socket = 0; | ||
431 | |||
432 | /* Set the timeout struct */ | ||
433 | struct timeval timeout; | ||
434 | timeout.tv_sec = 0; | ||
435 | timeout.tv_usec = 1000; | ||
436 | |||
437 | FD_ZERO(&read_fds); | ||
438 | FD_ZERO(&write_fds); | ||
439 | |||
440 | /* Set the read and write file descriptor sets. */ | ||
441 | for (int i = 0; i < MAX_SOCKETS; i++) { | ||
442 | if ((socket_table[i].is_valid) && (socket_table[i].is_read)) { | ||
443 | FD_SET(socket_table[i].fd, &read_fds); | ||
444 | if (socket_table[i].fd > high_socket) { | ||
445 | high_socket = socket_table[i].fd; | ||
446 | } | ||
447 | } | ||
448 | if ((socket_table[i].is_valid) && (!socket_table[i].is_read)) { | ||
449 | FD_SET(socket_table[i].fd, &write_fds); | ||
450 | if (socket_table[i].fd > high_socket) { | ||
451 | high_socket = socket_table[i].fd; | ||
452 | } | ||
453 | } | ||
454 | } | ||
455 | |||
456 | /* Wait for a file descriptor event or timeout. */ | ||
457 | do { | ||
458 | activity = select(high_socket+1, &read_fds, &write_fds, NULL, &timeout); | ||
459 | } while( activity == -1 && errno == EINTR); | ||
460 | |||
461 | if (activity < 0) { | ||
462 | err_handler(ERR_TYPE_SYSTEM, ERR_SOCKET_READY); | ||
463 | } | ||
464 | |||
465 | /* if activity 0 timeout, else activity must be => 1 - number of read_fds and write_fds | ||
466 | ready to read */ | ||
467 | return activity; | ||
468 | } | ||
469 | |||
470 | /***************************************************************************** | ||
471 | * socket_close() | ||
472 | * | ||
473 | * - All done so close the socket. | ||
474 | * | ||
475 | *****************************************************************************/ | ||
476 | void socket_close(int fd) | ||
477 | { | ||
478 | LOGFUNC(); | ||
479 | /* Decrement the socket count */ | ||
480 | socket_cnt--; | ||
481 | close(fd); | ||
482 | } | ||
483 | |||
diff --git a/server/socket.h b/server/socket.h new file mode 100644 index 0000000..b914b0c --- /dev/null +++ b/server/socket.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * socket.h | ||
3 | * | ||
4 | * Ctools Profiler Server Implementation | ||
5 | * | ||
6 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * Neither the name of Texas Instruments Incorporated nor the names of | ||
22 | * its contributors may be used to endorse or promote products derived | ||
23 | * from this software without specific prior written permission. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
31 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | * | ||
37 | */ | ||
38 | #ifndef CTOOLS_SOCKET_H | ||
39 | #define CTOOLS_SOCKET_H | ||
40 | |||
41 | void socket_open(); | ||
42 | int socket_server_create(int port); | ||
43 | void socket_command_optimize(int socket_fd); | ||
44 | int socket_recv_data(int socket_fd, uint8_t* buf, size_t buf_len, | ||
45 | size_t buf_offset, size_t* buf_retlen); | ||
46 | int socket_send_data(int socket_fd, uint8_t* buf, size_t buf_len, | ||
47 | size_t buf_offset, size_t* buf_retlen); | ||
48 | void socket_add_list(int socket_fd, bool is_read); | ||
49 | void socket_remove_list(int socket_fd); | ||
50 | int socket_check_read_list(int socket_fd); | ||
51 | int socket_check_write_list(int socket_fd); | ||
52 | void socket_set_nonblocking(int socket_fd); | ||
53 | int socket_wait(); | ||
54 | void socket_close(int fd); | ||
55 | |||
56 | #endif | ||