summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Deao2013-08-04 00:42:02 -0500
committerDoug Deao2013-08-04 00:46:07 -0500
commit656421425b7ca41064d4e726d8c6e6f453d83851 (patch)
tree45f734c6ed2afe248711f63be474a4e07916a336
downloadctprof_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_NOTES91
-rw-r--r--common/error_handler.c123
-rw-r--r--common/error_handler.h56
-rw-r--r--common/logging.c154
-rw-r--r--common/logging.h82
-rw-r--r--ctprofsrv_1.0_Manifest.htm1826
-rw-r--r--example_app/ctprof_ex.c207
-rw-r--r--example_app/ctprof_utility.c184
-rw-r--r--example_app/ctprof_utility.h56
-rw-r--r--example_app/makefile71
-rw-r--r--server/ETBAddr.h418
-rw-r--r--server/ETBInterface.h506
-rw-r--r--server/TIETB.c2739
-rw-r--r--server/command_handler.c653
-rw-r--r--server/command_handler.h45
-rw-r--r--server/ctoolsprof.h92
-rw-r--r--server/ctoolsprof_srv_main.c439
-rw-r--r--server/error.c73
-rw-r--r--server/error.h82
-rw-r--r--server/etb_handler.c666
-rw-r--r--server/etb_handler.h56
-rw-r--r--server/makefile89
-rw-r--r--server/remote_commands.c1397
-rw-r--r--server/remote_commands.h71
-rw-r--r--server/signal_handler.c238
-rw-r--r--server/signal_handler.h47
-rw-r--r--server/socket.c483
-rw-r--r--server/socket.h56
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 @@
1ctprof_srv
2
3Version 1.0
4Release Date: 7/32/2013
5
6Description
7===========
8
9Ctprof provides system level bus profiling use cases for any slave in the
10device that has a CP Tracer. Ctprof is made up of two components; ctprof
11which is the host client application, and ctprof_srv which is the target
12server application. The client is delivered with TI's CCS emupacks (see
13System Requirements for minimum emupack revision for this release) and can be
14installed independent of CCS. The server is delivered as source with an example
15application which also contains a small "C" file that can be integrated with
16your application for coordinating collection activity with ctprof_srv.
17
18Organization
19============
20
21The ctools_srv project is delivered as source in three directories:
22
23 server
24 common
25 example_app
26
27Both the server and example_app have makefiles.
28
29Make & Installation
30===================
31
32If using SC-MCSDK 02.02.00 then ctprof_srv and ctprof_ex should be
33pre-installed in the /usr directory. Otherwise:
34
35The server and example_app directories contain makefiles that utilizes the
36CROSS_COMPILE environment variable. Both release and debug versions can be made.
37The executable is saved in the release or debug directories.
38
39Examples:
40
41make clean debug
42make clean release
43make clean release install DESTDIR=/your/favorite/utility/dir
44make clean all (make both the debug and release versions)
45
46Typically the executable files will need to be copied to the appropriate target
47system's Linux bin directory.
48
49System 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
57Documentation
58=============
59
60The server should simply be run in the background from the console:
61
62$ctprof_srv &
63
64Use -h to see options.
65
66The client is then used from a host to connect to the server and issue
67use case commands (like measure utilized bandwidth or latency of a specific
68slave) that are serviced by ctprof_srv through a socket interface.
69
70See http://processors.wiki.ti.com/index.php/CToolsLib/ctoolsprof for
71documentation and examples.
72
73History
74=======
75
76July 31/2013 - First release
77
78
79Known Deficiencies
80==================
81
82Enhancements & New Features
83===========================
84
85Bug Fixes
86=========
87
88End 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 *****************************************************************************/
54char * error_type[] = {
55 /* [ERR_TYPE_SYSTEM] = */ "system",
56 /* [ERR_TYPE_LOCAL] = */ "ctoolsprof"
57};
58
59typedef enum {FATAL, NON_FATAL} error_prefix_t;
60
61char * 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
74void error_handler(error_type_t err_type, err_id_t err_id, const char * file,
75 const char * func, int line )
76#else
77void 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
43typedef enum { ERR_TYPE_SYSTEM, ERR_TYPE_LOCAL} error_type_t;
44
45#if DEBUG
46void 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
51void 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
47bool g_log_enable = false;
48int g_log_level = 0;
49
50static FILE *logout;
51
52#define time_buf_size 16
53static char time_buf[time_buf_size];
54/*****************************************************************************
55 * Internal Function Prototypes
56 * - See Private Function section below for implementations )
57 *****************************************************************************/
58char * 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 *****************************************************************************/
68void 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 *****************************************************************************/
100void 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 *****************************************************************************/
137char * 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
42extern bool g_log_enable;
43extern 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
52typedef enum {LOG_MSG, LOG_ERR, LOG_FUNC} log_type_t;
53
54void log_handler(void **notused, int argc);
55void 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"
2xmlns:o="urn:schemas-microsoft-com:office:office"
3xmlns:w="urn:schemas-microsoft-com:office:word"
4xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
5xmlns="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>
16v\:* {behavior:url(#default#VML);}
17o\:* {behavior:url(#default#VML);}
18w\:* {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
53href="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="&#45;-"/>
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;}
318p.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;}
329p.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;}
340p.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;}
351span.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;}
359p.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;}
371p.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;}
382a:link, span.MsoHyperlink
383 {mso-style-priority:99;
384 mso-style-unhide:no;
385 color:blue;
386 text-decoration:underline;
387 text-underline:single;}
388a:visited, span.MsoHyperlinkFollowed
389 {mso-style-unhide:no;
390 color:purple;
391 mso-themecolor:followedhyperlink;
392 text-decoration:underline;
393 text-underline:single;}
394p.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;}
406pre
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;}
417p.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;}
428span.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";}
440span.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;}
451span.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;}
462span.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;}
473span.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;}
484span.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;}
496span.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;}
508p.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;}
524p.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;}
540span.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;}
553p.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;}
570span.SpellE
571 {mso-style-name:"";
572 mso-spl-e:yes;}
573span.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;}
589div.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";}
610table.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>&nbsp;</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
668style='mso-spacerun:yes'>                                                                                   
669</span><span style='mso-spacerun:yes'>                     </span><span
670style='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:
673normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
674
675<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
676normal'><span style='font-size:12.0pt'><o:p>&nbsp;</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:
685normal'><span style='font-size:12.0pt'>ctprof_srv</span></b></span></span><b
686style='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>&nbsp;</o:p></p>
689
690<p class=MsoNormal><o:p>&nbsp;</o:p></p>
691
692<p class=MsoNormal><o:p>&nbsp;</o:p></p>
693
694<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
695normal'><span style='font-size:12.0pt'>Legend <o:p></o:p></span></b></p>
696
697<p class=MsoNormal><o:p>&nbsp;</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.&nbsp; 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>&nbsp;</o:p></p>
851
852<p class=MsoNormal><o:p>&nbsp;</o:p></p>
853
854<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
855normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
856
857<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
858normal'><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>&nbsp;</o:p></p>
861
862<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
863normal'><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>&nbsp;</o:p></p>
866
867<p class=MsoNormal style='margin-left:.5in;mso-outline-level:1'>Any use of ECCNs
868listed in the Manifest is at the user’s risk and without recourse to TI.<span
869style='mso-spacerun:yes'>   </span>Your company, as the exporter of record, is
870responsible for determining the correct classification of any item at the time
871of export. Any export classification by TI of Software is for TI’s internal use
872only and shall not be construed as a representation or warranty regarding the
873proper export classification for such Software or whether an export license or
874other documentation is required for exporting such Software<b style='mso-bidi-font-weight:
875normal'><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:
879normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
880
881<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
882normal'><u>Links in the Manifest<o:p></o:p></u></b></p>
883
884<p class=MsoNormal style='mso-outline-level:1'><o:p>&nbsp;</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
888Manifest was created. TI makes no guarantee that any listed links will remain
889active in the future.</p>
890
891<p class=1Para><b style='mso-bidi-font-weight:normal'><u>Open Source License
892References<o:p></o:p></u></b></p>
893
894<p class=1Para style='margin-left:.5in'>Your company is responsible for
895confirming the applicable license terms for any open source Software listed in
896this 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
898not “Obtained from” TI is for TI’s internal use only and shall not be construed
899as a representation or warranty regarding the proper open source license terms
900for such Software.</p>
901
902<b style='mso-bidi-font-weight:normal'><span style='font-size:12.0pt;
903font-family:"Arial","sans-serif";mso-fareast-font-family:"Times New Roman";
904mso-font-kerning:11.0pt;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
905mso-bidi-language:AR-SA'><br clear=all style='mso-special-character:line-break;
906page-break-before:always'>
907</span></b>
908
909<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
910normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
911
912<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
913normal'><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:
916normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
917
918<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
9190pt;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
922Available</span><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
9230pt;mso-fareast-language:JA'>&nbsp; <o:p></o:p></span></p>
924
925<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
9260pt;mso-fareast-language:JA'><o:p>&nbsp;</o:p></span></p>
927
928<p class=MsoNormal><span style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:
9290pt;mso-fareast-language:JA'>ECCN for Technology (e.g., user documentation,
930specifications) 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
933style='mso-fareast-font-family:"MS Mincho";mso-font-kerning:0pt;mso-fareast-language:
934JA'><o:p></o:p></span></p>
935
936<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
937normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
938
939<p class=MsoNormal style='mso-outline-level:1'><o:p>&nbsp;</o:p></p>
940
941<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
942normal'><span style='font-size:12.0pt'>Manifest<o:p></o:p></span></b></p>
943
944<p class=MsoNormal><o:p>&nbsp;</o:p></p>
945
946<p class=MsoNormal>See Legend above for a description of the columns and
947possible values.</p>
948
949<p class=MsoNormal><o:p>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</o:p></p>
1642 </td>
1643 </tr>
1644</table>
1645
1646<p class=MsoNormal><o:p>&nbsp;</o:p></p>
1647
1648<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
1649normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
1650
1651<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
1652normal'><span style='font-size:12.0pt'><o:p>&nbsp;</o:p></span></b></p>
1653
1654<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
1655normal'><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>&nbsp;</o:p></span></p>
1658
1659<p class=MsoNormal style='mso-outline-level:1'><o:p>&nbsp;</o:p></p>
1660
1661<p class=MsoNormal style='mso-outline-level:1'><b style='mso-bidi-font-weight:
1662normal'><span style='font-size:12.0pt'>Licenses <o:p></o:p></span></b></p>
1663
1664<p class=MsoNormal><o:p>&nbsp;</o:p></p>
1665
1666<p class=MsoNormal><o:p>&nbsp;</o:p></p>
1667
1668<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
16690pt'>/*<o:p></o:p></span></p>
1670
1671<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
16720pt'><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:
16750pt'><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:
16780pt'><span style='mso-spacerun:yes'> </span>* <span class=SpellE>Ctools</span>
1679Profiler Server Implementation<o:p></o:p></span></p>
1680
1681<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
16820pt'><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:
16850pt'><span style='mso-spacerun:yes'> </span>* Copyright (C) 2013 Texas
1686Instruments 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:
16890pt'><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:
16920pt'><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:
16950pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1696style='mso-spacerun:yes'>  </span>Redistribution</span> and use in source and
1697binary 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:
17000pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1701style='mso-spacerun:yes'>  </span>modification</span>, are permitted provided
1702that the following conditions <o:p></o:p></span></p>
1703
1704<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17050pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1706style='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:
17090pt'><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:
17120pt'><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:
17160pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'>   
1717</span><span class=GramE>notice</span>, this list of conditions and the
1718following disclaimer.<o:p></o:p></span></p>
1719
1720<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17210pt'><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:
17240pt'><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:
17280pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'>   
1729</span><span class=GramE>notice</span>, this list of conditions and the
1730following disclaimer in the <o:p></o:p></span></p>
1731
1732<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17330pt'><span style='mso-spacerun:yes'> </span>*<span style='mso-spacerun:yes'>   
1734</span><span class=GramE>documentation</span> and/or other materials provided
1735with 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:
17380pt'><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:
17420pt'><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:
17450pt'><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:
17490pt'><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
1751promote products derived<o:p></o:p></span></p>
1752
1753<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17540pt'><span style='mso-spacerun:yes'> </span>* <span
1755style='mso-spacerun:yes'>   </span><span class=GramE>from</span> this software
1756without 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:
17590pt'><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:
17620pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1763style='mso-spacerun:yes'>  </span>THIS</span> SOFTWARE IS PROVIDED BY THE
1764COPYRIGHT HOLDERS AND CONTRIBUTORS <o:p></o:p></span></p>
1765
1766<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17670pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1768style='mso-spacerun:yes'>  </span>&quot;</span>AS IS&quot; AND ANY EXPRESS OR
1769IMPLIED 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:
17720pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1773style='mso-spacerun:yes'>  </span>LIMITED</span> TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1774AND FITNESS FOR<o:p></o:p></span></p>
1775
1776<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17770pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1778style='mso-spacerun:yes'>  </span>A</span> PARTICULAR PURPOSE ARE DISCLAIMED.
1779IN 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:
17820pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1783style='mso-spacerun:yes'>  </span>OWNER</span> OR CONTRIBUTORS BE LIABLE FOR
1784ANY DIRECT, INDIRECT, INCIDENTAL, <o:p></o:p></span></p>
1785
1786<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17870pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1788style='mso-spacerun:yes'>  </span>SPECIAL</span>, EXEMPLARY, OR CONSEQUENTIAL
1789DAMAGES (INCLUDING, BUT NOT <o:p></o:p></span></p>
1790
1791<p class=MsoNormal><span style='font-family:Consolas;color:#3F7F5F;mso-font-kerning:
17920pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1793style='mso-spacerun:yes'>  </span>LIMITED</span> TO, PROCUREMENT OF SUBSTITUTE
1794GOODS 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:
17970pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1798style='mso-spacerun:yes'>  </span>DATA</span>, OR PROFITS; OR BUSINESS
1799INTERRUPTION) 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:
18020pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1803style='mso-spacerun:yes'>  </span>THEORY</span> OF LIABILITY, WHETHER IN
1804CONTRACT, 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:
18070pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1808style='mso-spacerun:yes'>  </span>(</span>INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
1809IN 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:
18120pt'><span style='mso-spacerun:yes'> </span><span class=GramE>*<span
1813style='mso-spacerun:yes'>  </span>OF</span> THIS SOFTWARE, EVEN IF ADVISED OF
1814THE 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:
18170pt'><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:
18200pt'>*/<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
48const int g_major_version = 0;
49const int g_minor_version = 1;
50const int g_copyright_year = 2013;
51
52FILE *g_stdout;
53FILE *g_stderr;
54char * g_whoami;
55
56struct memory_blk_t{
57 char * name;
58 uint32_t phy_addr;
59 void * v_addr;
60 size_t phy_size;
61};
62
63struct 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
70const int zero_test_words = 65536;
71const int memory_table_elements = sizeof(memory_table)/sizeof(struct memory_blk_t);
72
73static 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
80static char * short_options = "i:qhv";
81
82static int test_iterations = 1;
83
84
85#define USE_SIGNALS 1
86
87int 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
48static char * fifo_filename = "ctprof_fifo";
49//static FILE * fp;
50static int ctprof_pipe_fd;
51static bool fifo_opened = false;
52static 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 */
59static const char msg_recording[] = "ctprof recording\n";
60static const char msg_stopped[] = "ctprof stopped\n";
61static 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
71static pid_t ctprof_srv_pid;
72
73int 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
87void ctprof_pipe_close(void)
88{
89 if (fifo_opened) {
90 close(ctprof_pipe_fd);
91 fifo_opened = false;
92 }
93
94}
95
96static pid_t ctprof_get_pid(void)
97{
98 if (fifo_opened) {
99 return ctprof_srv_pid;
100 } else {
101 return -1;
102 }
103}
104
105ctprof_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
128void 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
143void 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
158void 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*/
174void ctprof_start_recording()
175{
176 kill(ctprof_get_pid(), SIGUSR1);
177}
178
179/* End recording for this session*/
180void 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
41typedef enum {
42 CTPROF_READY,
43 CTPROF_STOPPED,
44 CTPROF_RECORDING,
45} ctprof_state_t;
46
47int ctprof_pipe_open(void);
48void ctprof_pipe_close(void);
49ctprof_state_t ctprof_get_state(void);
50void ctprof_ready_wait();
51void ctprof_recording_wait();
52void ctprof_stopped_wait();
53void ctprof_start_recording();
54void 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
10ifeq ($(findstring arm, $(MAKECMDGOALS)), arm)
11 CC= $(CROSS_COMPILE)gcc --static
12else
13 CC = gcc
14endif
15
16ifeq ($(findstring debug, $(MAKECMDGOALS)), debug)
17 CFLAGS= -std=c99 -c -g -Wall $(INC_PATH) -D DEBUG -D _GNU_SOURCE $(TEST)
18 OBJDIR= ./debug
19else
20 CFLAGS= -std=c99 -c -O2 $(INC_PATH) -D SERVER -D _GNU_SOURCE $(TEST)
21 OBJDIR= ./release
22endif
23LFLAGS =
24LIBS=
25LIB_PATH=
26INCLUDE_PATH = -I ../example_app
27
28.PHONY: clean debug release install arm
29
30all: clean release install
31
32#
33# Declare.c and .h dependencies
34#
35ctprof_ex.o: ctprof_ex.c
36ctprof_utility.o : ctprof_utility.h ctprof_utility.c
37
38#
39# Add objects
40#
41
42OBJECTS = $(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
53ctprof_ex: $(OBJECTS)
54 @echo "Building target" $@
55 $(CC) $(LFLAGS) $(LIBS_PATH) -o $@ $(OBJECTS) $(LIBS)
56
57debug: ctprof_ex
58 @echo "debug build complete"
59
60release: ctprof_ex
61 @echo "release build complete"
62
63arm: ctprof_ex
64 @echo "ARM version built"
65
66install:
67 mv ctprof_ex ~/bin/ctprof_ex
68
69clean:
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/****************************************************************************
2CToolsLib - ETB Library
3
4Copyright (c) 2009-2012 Texas Instruments Inc. (www.ti.com)
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions
9are met:
101. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
122. 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.
153. 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
18THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
19IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27THIS 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
33extern "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
38extern "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*/
76typedef 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*/
103typedef 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*/
110typedef 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*/
123typedef 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*/
132typedef 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*/
143typedef 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*/
186typedef 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
207typedef struct _ETBHandle_t ETBHandle;
208
209/*! \par ETBHandle_Pntr
210 Pointer to a ETB Handle object
211*/
212
213typedef ETBHandle * ETBHandle_Pntr;
214
215/*! \par ETBStatus
216 \brief ETB status structure definition.
217*/
218typedef 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*/
231typedef 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*/
254eETB_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*/
269eETB_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*/
283eETB_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*/
297eETB_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*/
322eETB_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*/
335eETB_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*/
360eETB_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
388eETB_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*/
415eETB_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*/
430void 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*/
443void 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
456The ETB Library provides an application interface to program and drain the
457Embedded Trace Buffer (ETB). There are two kinds of ETB in TI devices, CSETB and
458TIETB. The ETBLib contains CCSv5 projects in the ETBLib/project directory
459specifying the supported devices and rules to pickup specific files and flags
460for different devices. \n\n
461For C66xx devices using the TIETB in TI mode (enabling the ETB to be read while
462enabled and actively getting written) there is also an option to use the EDMA3
463to drain the ETB to specified memory buffer.
464
465\par EDMA3 Drain Buffer
466The DMA drain buffer is used to increase the amount of storage used for
467trace data beyond the size of the ETB. The DMA uses the half-full and full
468interrupt from the ETB as a trigger to start a transaction that will read half
469of the ETB for each interrupt. For all Keystone1 devices except C6657, The ETB
470interrupts must get routed through the chip-level interrupt controller (INTCx)
471to interface with the EDMA3 controller. Where as in case of all keystone2 and
472C6657, 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
477a 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/****************************************************************************
2CToolsLib - ETB Library
3
4Copyright (c) 2009-2010 Texas Instruments Inc. (www.ti.com)
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions
9are met:
101. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
122. 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.
153. 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
18THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
19IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27THIS 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*/
69typedef 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
91struct _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
115static uint32_t virtural_ETB_BaseAddress[NUM_ETB_INSTANCES] = {0};
116static uint32_t virtural_DTF_BaseAddress[NUM_ETB_INSTANCES] = {0};
117static 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 */
124static ETBHandle stHandle[NUM_ETB_INSTANCES];
125
126/* Enumeration to define the options available to the internal flush function */
127typedef 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 */
134typedef 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 */
141static 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");
156volatile uint32_t etbLib_buffer_start_addr[NUM_ETB_INSTANCES]; //start of ETB buffer
157volatile uint32_t etbLib_buffer_size[NUM_ETB_INSTANCES]; //number of Bytes
158volatile 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");
163volatile 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
185static 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
210static 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
217static 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
243static uint32_t etbLib_cpCicEventClearIndexReg[2] = {CIC2_STATUS_CLR_INDEX_REG, CIC3_STATUS_CLR_INDEX_REG};
244
245#endif
246
247static uint32_t etbLib_bufferWrapped[NUM_ETB_INSTANCES][2];
248
249#pragma DATA_SECTION(etb_disable,"ETBLib_dmaData");
250static 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*/
257static 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*/
271static 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*/
286static 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*/
312static 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*/
336static 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*/
348eETB_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
440static 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
500eETB_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*/
648eETB_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*/
675eETB_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*/
700eETB_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*/
816eETB_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*/
898eETB_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*/
1044eETB_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*/
1272eETB_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*/
1324eETB_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*/
1352static 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 */
1717eETB_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 */
2238eETB_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 */
2708void 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 */
2725void 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 *****************************************************************************/
52static inline uint8_t calculate_checksum( uint8_t *buf, unsigned int len );
53static inline uint8_t int_to_hexdigit(unsigned val);
54static inline void send_response(uint8_t * response);
55static void command_dispatch(char * cmd, int cmd_len, char * response, size_t rsp_size);
56static void command_clr_buf(uint8_t * pbuf);
57
58static void get_memory_arguments(char * cbuf, uint32_t * addr, size_t * len, char ** data);
59static void process_memory_write(char * cbuf, char * rbuf, size_t rsp_size);
60static void process_memory_read(char * cbuf, char * rbuf, size_t rsp_size);
61static void process_remote(char * cbuf, char * rbuf, size_t rsp_size);
62static 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 */
72typedef enum {
73 READ_MEMORY_CMD,
74 WRITE_MEMORY_CMD,
75 REMOTE_CMD,
76 DISABLE_ACK_CMD
77} rsp_cmd_t;
78
79typedef void (* proc_func_t)(char * cbuf, char * rbuf, size_t rbuf_size);
80
81struct rsp_command_table_t {
82 char * cmd;
83 proc_func_t process;
84};
85
86static 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 */
94typedef void (* rmt_func_t)(int argc, char *argv[], char * rbuf, size_t rsp_size);
95
96struct 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 */
102static 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 */
117static bool rsp_ack_enabled = true;
118static const char *ACK = "+";
119static const char *NACK = "-";
120static const char *rsp_msg_ok = "OK";
121
122/* RSP State */
123typedef enum {AWAITING_COMMAND, AWAITING_ACK} command_state_t;
124static command_state_t command_state = AWAITING_COMMAND;
125
126/* RSP buffers*/
127#define MAX_COMMAND_SIZE 256
128static uint8_t cmd_buf[MAX_COMMAND_SIZE];
129static uint8_t rsp_buf[MAX_COMMAND_SIZE];
130
131/*****************************************************************************
132 * Statics
133 *
134 *****************************************************************************/
135static 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 *****************************************************************************/
147void 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 *****************************************************************************/
176void 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 *****************************************************************************/
301void 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 *****************************************************************************/
312static 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 *****************************************************************************/
327static const uint8_t inttohex_table[] = {
328 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
329};
330
331static 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 *****************************************************************************/
346static 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 *****************************************************************************/
366void 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 *****************************************************************************/
407static 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 *****************************************************************************/
458static 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 *****************************************************************************/
514static 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 *****************************************************************************/
583static 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
641static 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
42void command_init(int socket);
43void 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 */
43extern const int g_major_version;
44extern const int g_minor_version;
45extern const int g_copyright_year;
46
47extern FILE *g_stdout;
48//extern FILE *g_logout;
49extern FILE *g_stderr;
50extern char * g_whoami;
51
52extern bool g_fifo_used;
53extern bool g_fifo_enabled;
54extern int g_fifo_fd;
55
56extern 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 */
64typedef enum {
65 STATE_UNINITIALIZED,
66 STATE_WAITING,
67 STATE_STOPPED,
68 STATE_RECORDING
69} recording_state_t;
70
71typedef enum {
72 ETB_MODE_ONESHOT_FIXED,
73 ETB_MODE_ONESHOT_CIRCULAR,
74 ETB_MODE_DRAIN,
75 ETB_MODE_LAST
76} etb_mode_t;
77
78typedef 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
88extern monitor_state_t global_state;
89
90void 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
58const int g_major_version = 1;
59const int g_minor_version = 0;
60const int g_copyright_year = 2013;
61
62FILE *g_stdout;
63FILE *g_stderr;
64char * 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 */
69bool g_interactive_mode = false;
70
71/* This is used to enable sending the server state over a named pipe */
72bool g_fifo_used = false;
73bool g_fifo_enabled = false;
74int g_fifo_fd = -1;
75static char * fifo_filename = "ctprof_fifo";
76
77static int cmd_port = 54242;
78static int etb_port = 54243;
79//static int log_port = 54244;
80
81/* Global server state initialization*/
82monitor_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
92static int cmd_socket;
93static 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
114static 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 *****************************************************************************/
164static 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
191int 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 *****************************************************************************/
423void 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
41struct 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
43struct error_info_t {
44 char *msg;
45 bool fatal;
46};
47
48typedef 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
80extern 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 *****************************************************************************/
62static ETBHandle* etb_handle = NULL;
63
64struct 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
71static struct etb_queue_t * etb_queue_head = NULL;
72static struct etb_queue_t * etb_queue_tail = NULL;
73static int etb_queue_cnt = 0;
74
75static uint32_t etb_size; /* ETB size in uint32_t elements*/
76static int etb_socket; /* Socket ETB data is sent to host with */
77
78static const int max_queue_depth = 1024;
79
80#ifdef TEST_MODE
81#include "remote_commands.h"
82static FILE * test_fp;
83static long test_fp_recpos = 0;
84static long test_fp_maxpos = 0;
85static long test_fp_dtat2send = 0;
86static const int etb_word_size = sizeof(uint32_t);
87#endif
88
89static bool etb_is_enabled = false;
90static int etb_words_queued = 0;
91
92/*****************************************************************************
93 * Internal Function Prototypes
94 * - See Private Function section below for implementations )
95 *****************************************************************************/
96static void etb_process_data(int etb_word_cnt);
97static 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 *****************************************************************************/
110void 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 *****************************************************************************/
128void 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 *****************************************************************************/
201void 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 *****************************************************************************/
232int 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 *****************************************************************************/
283void 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 *****************************************************************************/
307void 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 *****************************************************************************/
336void 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 *****************************************************************************/
377void 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 *****************************************************************************/
453static 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 *****************************************************************************/
582static 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
42typedef enum {ETB_CIRCULAR, ETB_FIXED} etb_bufmode_t;
43typedef enum {ARM_CSETB, SYS_TIETB} etb_core_id_t;
44typedef enum {ETB_QUEUE_LIMIT, ETB_QUEUE_ALL} etb_queue_limit_t;
45
46void etb_init(int socket);
47void etb_config(etb_bufmode_t mode, etb_core_id_t core_id);
48void etb_term();
49void etb_enable();
50void etb_disable();
51int etb_status(bool * is_enabled, bool * is_wrapped);
52void etb_add_queue(etb_queue_limit_t limit);
53void 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
11ifeq ($(findstring arm, $(MAKECMDGOALS)), arm)
12 CC= $(CROSS_COMPILE)gcc --static
13else
14 CC = gcc
15endif
16ifeq ($(findstring test, $(MAKECMDGOALS)), test)
17 TEST = -D TEST_MODE
18else
19 TEST =
20endif
21
22ifeq ($(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
25else
26 CFLAGS= -std=c99 -c -O2 $(INC_PATH) -D SERVER -D TCI6614 -D _GNU_SOURCE
27 OBJDIR= ./release
28endif
29COMMON = ../common
30LFLAGS =
31LIBS= -lpthread
32LIB_PATH=
33INCLUDE_PATH = -I $(COMMON) -I ../server
34
35INCLUDE_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
37VPATH = $(COMMON)
38
39.PHONY: clean debug release install arm
40
41all: clean release install
42
43#
44# Declare.c and .h dependencies
45#
46ctoolsprof_srv.o: ctoolsprof_srv_main.c $(INCLUDE_FILES)
47socket.o: socket.c $(INCLUDE_FILES)
48error_handler.o : error_handler.c $(INCLUDE_FILES)
49logging.o : logging.c $(INCLUDE_FILES)
50error.o : error.c $(INCLUDE_FILES)
51command_handler.o : command_handler.c $(INCLUDE_FILES)
52remote_commands.o : remote_commands.c $(INCLUDE_FILES)
53signal_handler.o : signal_handler.c $(INCLUDE_FILES)
54etb_handler.o : etb_handler.c $(INCLUDE_FILES)
55TIETB.o : TIETB.c ETBAddr.h ETBInterface.h
56
57#
58# Add objects
59#
60
61OBJECTS = $(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
68ctprof_srv: $(OBJECTS)
69 @echo "Building target" $@
70 $(CC) $(LFLAGS) $(LIBS_PATH) -o $(OBJDIR)/$@ $(OBJECTS) $(LIBS)
71
72debug: ctprof_srv
73 @echo "debug build complete"
74
75release: ctprof_srv
76 @echo "release build complete"
77
78arm: ctprof_srv
79 @echo "ARM version built"
80
81test: ctprof_srv
82 @echo "Test version built - ETB file simulation"
83
84install:
85 mv ctprof_srv ~/bin/ctprof_srv
86
87clean:
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
68struct set_element_table_t {
69 char * element;
70 bool is_valid;
71 int value;
72};
73
74static 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
82typedef enum {
83 OP_MODE_TIME,
84 OP_MODE_SIGNAL,
85 OP_MODE_TRIGGER,
86 OP_MODE_LAST
87} op_mode_t;
88
89static char * op_mode_table[] = {
90 [OP_MODE_TIME] = "time",
91 [OP_MODE_SIGNAL] = "signal",
92 [OP_MODE_TRIGGER] = "trigger"
93};
94
95static char * etb_mode_table[] = {
96 [ETB_MODE_ONESHOT_FIXED] = "fixed",
97 [ETB_MODE_ONESHOT_CIRCULAR] = "circular",
98 [ETB_MODE_DRAIN] = "drain"
99};
100
101static const char msg_recording[] = "ctprof recording\n";
102static const char msg_stopped[] = "ctprof stopped\n";
103static const char msg_ready[] = "ctprof ready\n";
104
105/*****************************************************************************
106 * Internal Function Prototypes
107 * - See Private Function section below for implementations )
108 *****************************************************************************/
109void * cTools_memMap(uint32_t map_addr, uint32_t map_size);
110void cTools_memUnMap(uint32_t map_addr, uint32_t map_size);
111static void respond_ok(char * rbuf, size_t rsp_size);
112static 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 *****************************************************************************/
124void 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 *****************************************************************************/
154void 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 *****************************************************************************/
237void 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 *****************************************************************************/
267void 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 *****************************************************************************/
303void 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
337struct modcntl_t {
338 uint32_t addr;
339 size_t value;
340 struct modcntl_t * prev_modcntl;
341 struct modcntl_t * next_modcntl;
342};
343
344static struct modcntl_t * arm_table_head = NULL; // Map Object Link List head
345static 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 *****************************************************************************/
360void 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 *****************************************************************************/
432void 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 *****************************************************************************/
532static struct modcntl_t *next_table_element = NULL;
533bool 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 *****************************************************************************/
572void 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 *****************************************************************************/
678void 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 *****************************************************************************/
743void 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 *****************************************************************************/
923void 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 *****************************************************************************/
974void 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 *****************************************************************************/
1029void 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 *****************************************************************************/
1055int 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 *****************************************************************************/
1097int 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 */
1139static int mem_fd = 0;
1140
1141struct 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
1149static 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 *****************************************************************************/
1170void * 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 *****************************************************************************/
1270void 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 *****************************************************************************/
1350static 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 *****************************************************************************/
1386static 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
42typedef 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 */
53void set_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
54void mmap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
55void ummap_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
56void version_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
57void modcntl_add_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
58void modcntl_remove_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
59void start_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
60void end_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
61void status_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
62void debug_command_handler(int argc, char *argv[], char * rbuf, size_t rsp_size);
63
64
65void get_set_value(set_element_t element, unsigned int *value, bool *is_valid);
66int remote_memory_write(uint32_t addr, size_t byte_cnt, uint32_t * pbuf);
67int remote_memory_read(uint32_t addr, size_t byte_cnt, uint32_t * pbuf);
68
69void start_recording();
70void 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
49static recording_op start_recording;
50static recording_op stop_recording;
51
52struct 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 *****************************************************************************/
71void 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 *****************************************************************************/
155void 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 *****************************************************************************/
193static sigset_t orig_mask;
194static bool signals_blocked = false;
195
196void 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 *****************************************************************************/
225void 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
41typedef void (*recording_op)(void);
42
43void signal_handler_init(recording_op start_recording, recording_op stop_recording);
44void signal_handler_block();
45void 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 */
56static fd_set read_fds;
57static fd_set write_fds;
58static int socket_cnt = 0;
59
60/* Define socket registration table */
61struct 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
70static 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 *****************************************************************************/
85void 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 *****************************************************************************/
119int 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 *****************************************************************************/
187void 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 *****************************************************************************/
215int 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 *****************************************************************************/
267int 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 *****************************************************************************/
305void 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 *****************************************************************************/
349void 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 *****************************************************************************/
375int 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 *****************************************************************************/
388int 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 *****************************************************************************/
400void 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 *****************************************************************************/
428int 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 *****************************************************************************/
476void 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
41void socket_open();
42int socket_server_create(int port);
43void socket_command_optimize(int socket_fd);
44int socket_recv_data(int socket_fd, uint8_t* buf, size_t buf_len,
45 size_t buf_offset, size_t* buf_retlen);
46int socket_send_data(int socket_fd, uint8_t* buf, size_t buf_len,
47 size_t buf_offset, size_t* buf_retlen);
48void socket_add_list(int socket_fd, bool is_read);
49void socket_remove_list(int socket_fd);
50int socket_check_read_list(int socket_fd);
51int socket_check_write_list(int socket_fd);
52void socket_set_nonblocking(int socket_fd);
53int socket_wait();
54void socket_close(int fd);
55
56#endif