1 /*
2 Copyright (c) 2018, MIPI Alliance, Inc.
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 * Redistributions of source code must retain the above copyright
10   notice, this list of conditions and the following disclaimer.
11 
12 * Redistributions in binary form must reproduce the above copyright
13   notice, this list of conditions and the following disclaimer in
14   the documentation and/or other materials provided with the
15   distribution.
16 
17 * Neither the name of the copyright holder nor the names of its
18   contributors may be used to endorse or promote products derived
19   from this software without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 /*
35  * Contributors:
36  * Norbert Schulz (Intel Corporation) - Initial API and implementation
37  */
38 
39 #include <gtest/gtest.h>
40 #include <string>
41 
42 #define MIPI_SYST_UNIT_TEST
43 
44 #include "mipi_syst.h"
45 
46 /* hard code compiler dependend standard defines to fixed values for
47 * unit test support. Regression tests expect to see these values.
48 */
49 #undef MIPI_SYST_FUNCTION_NAME
50 #define MIPI_SYST_FUNCTION_NAME "0123456789"
51 
52 #undef MIPI_SYST_LINE
53 #define MIPI_SYST_LINE          0x12345678
54 
55 #undef MIPI_SYST_FILE
56 #define MIPI_SYST_FILE          "unittest.c"
57 
58 
59 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
60 #define mipi_syst_return_addr() (void*)0x12345678aabbccdd
61 #else
62 #define mipi_syst_return_addr() (void*)0x12345678
63 #endif
64 
65 
66 /* replace output handlers with unit test versions
67 */
68 #undef MIPI_SYST_OUTPUT_D32MTS
69 #undef MIPI_SYST_OUTPUT_D64MTS
70 #undef MIPI_SYST_OUTPUT_D32TS
71 #undef MIPI_SYST_OUTPUT_D8
72 #undef MIPI_SYST_OUTPUT_D16
73 #undef MIPI_SYST_OUTPUT_D32
74 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
75 #undef MIPI_SYST_OUTPUT_D64
76 #endif
77 #undef MIPI_SYST_OUTPUT_FLAG
78 
79 #if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA)
80 #define MIPI_SYST_OUTPUT_D32MTS(syst_handle, data) \
81 	MipiSysTFixtureOutput::d32mts((syst_handle), (data))
82 #define MIPI_SYST_OUTPUT_D64MTS(syst_handle, data) \
83 	MipiSysTFixtureOutput::d64mts((syst_handle), (data))
84 #define MIPI_SYST_OUTPUT_D32TS(syst_handle, data) \
85 	MipiSysTFixtureOutput::d32ts((syst_handle), (data))
86 #define MIPI_SYST_OUTPUT_D8(syst_handle, data) \
87 	MipiSysTFixtureOutput::d8((syst_handle), (data))
88 #define MIPI_SYST_OUTPUT_D16(syst_handle, data) \
89 	MipiSysTFixtureOutput::d16((syst_handle), (data))
90 #define MIPI_SYST_OUTPUT_D32(syst_handle, data) \
91 	MipiSysTFixtureOutput::d32((syst_handle), (data))
92 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
93 #define MIPI_SYST_OUTPUT_D64(syst_handle, data) \
94 	MipiSysTFixtureOutput::d64((syst_handle), (data))
95 #endif
96 #define MIPI_SYST_OUTPUT_FLAG(syst_handle) \
97 	MipiSysTFixtureOutput::flag((syst_handle))
98 #else
99 #define MIPI_SYST_OUTPUT_D32MTS(syst_handle, data)
100 #define MIPI_SYST_OUTPUT_D32TS(syst_handle, data)
101 #define MIPI_SYST_OUTPUT_D8(syst_handle, data)
102 #define MIPI_SYST_OUTPUT_D16(syst_handle, data)
103 #define MIPI_SYST_OUTPUT_D32(syst_handle, data)
104 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
105 #define MIPI_SYST_OUTPUT_D64(syst_handle, data)
106 #endif
107 #define MIPI_SYST_OUTPUT_FLAG(syst_handle)
108 #endif // MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA
109 
110 class MipiSysTFixtureBase : public testing::Test
111 {
112 public:
SetUp()113 	void SetUp() {
114 		MIPI_SYST_INIT(mipi_syst_platform_init, (void*)0);}
115 
TearDown()116 	void TearDown(){
117 		MIPI_SYST_SHUTDOWN(mipi_syst_platform_destroy);
118 	}
119 
120 	static struct mipi_syst_origin origin;
121 };
122 
123 class MipiSysTFixtureOutput : public MipiSysTFixtureBase
124 {
125 public:
SetUp()126 	void SetUp() {
127 		MipiSysTFixtureBase::SetUp();
128 
129 		ph = MIPI_SYST_INIT_HANDLE(&sh, &origin);
130 		MIPI_SYST_SET_HANDLE_MODULE_UNIT(ph, 1,2);
131 		MIPI_SYST_ENABLE_HANDLE_LENGTH(ph, 1);
132 
133 		sstr.str("");
134 	}
135 
TearDown()136 	void TearDown(){
137 		MIPI_SYST_DELETE_HANDLE(ph);
138 
139 		MipiSysTFixtureBase::TearDown();
140 	}
141 
142 public:
143 	struct mipi_syst_handle sh;
144 	struct mipi_syst_handle* ph;
145 
146 	static std::stringstream sstr;
147 	std::string x4m;
148 
149 	/* unit test IO driver function to print the access output into local string */
d64(struct mipi_syst_handle * systh,mipi_syst_u64 v)150 	static void d64(struct mipi_syst_handle* systh, mipi_syst_u64 v)
151 	{ sstr << "<D64>"<< std::hex << std::setfill('0') << std::setw(16) << v; }
d32(struct mipi_syst_handle * systh,mipi_syst_u32 v)152 	static void d32(struct mipi_syst_handle* systh, mipi_syst_u32 v)
153 	{ sstr << "<D32>"<< std::hex << std::setfill('0') << std::setw(8) << v; }
d16(struct mipi_syst_handle * systh,mipi_syst_u16 v)154 	static void d16(struct mipi_syst_handle* systh, mipi_syst_u16 v)
155 	{ sstr << "<D16>"<< std::hex << std::setfill('0') << std::setw(4) << v; }
d8(struct mipi_syst_handle * systh,mipi_syst_u8 v)156 	static void d8(struct mipi_syst_handle* systh, mipi_syst_u8 v)
157 	{ sstr << "<D8>"<< std::hex << std::setfill('0') << std::setw(2) << (mipi_syst_u16)v; }
d32ts(struct mipi_syst_handle * systh,mipi_syst_u32 v)158 	static void d32ts(struct mipi_syst_handle* systh, mipi_syst_u32 v)
159 	{
160 		sstr << "<D32TS>"<< std::hex << std::setfill('0') << std::setw(8) << v;
161 		union {
162 			mipi_syst_u32 val;
163 			struct mipi_syst_msg_tag tag;
164 		}u = { v };
165 
166 		sstr << "[typ=" << u.tag.et_type << ":"   << u.tag.et_subtype
167 			<< " mu=" << (u.tag.et_modunit >> 4) << ":" << (u.tag.et_modunit & 0xF)
168 			<< " sev=" << u.tag.et_severity;
169 
170 		if (u.tag.et_res7) sstr << " res7";
171 		if (u.tag.et_location) sstr << " loc";
172 		if (u.tag.et_res30) sstr << " res30";
173 		if (u.tag.et_length) sstr << " len";
174 		if (u.tag.et_chksum) sstr << " chk";
175 		sstr << "]";
176 	}
d32mts(struct mipi_syst_handle * systh,mipi_syst_u32 v)177 	static void d32mts(struct mipi_syst_handle* systh, mipi_syst_u32 v)
178 	{ sstr << "<D32MTS>"<< std::hex << std::setfill('0') << std::setw(8) << v; }
d64mts(struct mipi_syst_handle * systh,mipi_syst_u64 v)179 	static void d64mts(struct mipi_syst_handle* systh, mipi_syst_u64 v)
180 	{ sstr << "<D64MTS>"<< std::hex << std::setfill('0') << std::setw(16) << v; }
flag(struct mipi_syst_handle * systh)181 	static void flag(struct mipi_syst_handle* systh)
182 	{ sstr << "<FLAG>"; }
183 
184 	/* output string transformation to match platform properties */
xform(const char * input)185 	const char* xform(const char* input)
186 	{
187 		size_t pos(0);
188 		x4m=input;
189 #if !defined(MIPI_SYST_PCFG_ENABLE_64BIT_IO)
190 		pos = std::string::npos;
191 		while((pos=x4m.find("<D64>")) != std::string::npos){
192 			std::string val = x4m.substr(pos+5,16);
193 			std::string upperVal = val.substr(8,8);
194 			std::string lowerVal = val.substr(0,8);
195 			std::string replacement = "<D32>";
196 			replacement += upperVal;
197 			replacement += "<D32>";
198 			replacement += lowerVal;
199 			x4m.erase(pos,21);
200 			x4m.insert(pos,replacement);
201 		}
202 #endif
203 #if defined(MIPI_SYST_PCFG_ENABLE_64BIT_ADDR)
204 		/* need to adapt 32bit catalog type for 64bit packing settings */
205 		pos = x4m.find("[typ=3:1 ");
206 		if (pos != std::string::npos) {
207 			x4m.replace(pos, 9, std::string("[typ=3:5 "));
208 			x4m.replace(0, 9, std::string("<D32TS>05"));
209 		}
210 
211 		/* need to adapt 64bit catalog type for 64bit packing settings */
212 		pos = x4m.find("[typ=3:2 ");
213 		if (pos != std::string::npos) {
214 			x4m.replace(pos, 9, std::string("[typ=3:6 "));
215 			x4m.replace(0, 9, std::string("<D32TS>06"));
216 		}
217 
218 		pos = x4m.find("[typ=2:b ");
219 		if (pos != std::string::npos) {
220 			x4m.replace(pos, 9, std::string("[typ=2:c "));
221 			x4m.replace(0, 9, std::string("<D32TS>0c"));
222 		}
223 #endif
224 #if !defined(MIPI_SYST_PCFG_LENGTH_FIELD)
225 		/* take out len parts from comparsion string */
226 		pos = x4m.find(" len");
227 		if (pos != std::string::npos) {
228 			x4m.replace(pos, 4, "");
229 
230 			std::stringstream sstr(x4m.substr(7, 8));
231 			mipi_syst_u32 tag;
232 			sstr >> std::hex >> tag;
233 			tag &= ~(1 << 9);
234 			sstr.str(std::string());
235 			sstr.clear();
236 			sstr << std::hex << std::setfill('0') << std::setw(8)
237 			     << std::noshowbase << tag;
238 			x4m.replace(7, 8, sstr.str());
239 
240 			pos = x4m.find("<D16>");
241 			if (pos != std::string::npos) {
242 				x4m.replace(pos, 9, "");
243 			}
244 		}
245 #endif
246 
247 		return x4m.c_str();
248 	}
249 };
250