1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "codegen/c_service_driver_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 #include "util/options.h"
13
14 namespace OHOS {
15 namespace HDI {
CServiceDriverCodeEmitter()16 CServiceDriverCodeEmitter::CServiceDriverCodeEmitter() : CCodeEmitter()
17 {
18 hostName_ = StringHelper::StrToLower(baseName_) + "Host";
19 }
20
ResolveDirectory(const std::string & targetDirectory)21 bool CServiceDriverCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
22 {
23 if (ast_->GetASTFileType() != ASTFileType::AST_IFACE) {
24 return false;
25 }
26
27 directory_ = GetFileParentPath(targetDirectory);
28 if (!File::CreateParentDir(directory_)) {
29 Logger::E("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.c_str());
30 return false;
31 }
32
33 return true;
34 }
35
EmitCode()36 void CServiceDriverCodeEmitter::EmitCode()
37 {
38 if (Options::GetInstance().DoPassthrough()) {
39 return;
40 }
41
42 // the callback interface or interface as method parameter have no driver file.
43 if (isKernelCode_ || !interface_->IsSerializable()) {
44 EmitDriverSourceFile();
45 }
46 }
47
EmitDriverSourceFile()48 void CServiceDriverCodeEmitter::EmitDriverSourceFile()
49 {
50 std::string filePath =
51 File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_ + "Driver").c_str()));
52 File file(filePath, File::WRITE);
53 StringBuilder sb;
54
55 EmitLicense(sb);
56 EmitDriverInclusions(sb);
57 sb.Append("\n");
58 EmitLogTagMacro(sb, FileName(baseName_ + "Driver"));
59 sb.Append("\n");
60 EmitDriverServiceDecl(sb);
61 sb.Append("\n");
62 if (isKernelCode_) {
63 EmitKernelDriverDispatch(sb);
64 sb.Append("\n");
65 EmitDriverInit(sb);
66 sb.Append("\n");
67 EmitKernelDriverBind(sb);
68 sb.Append("\n");
69 EmitKernelDriverRelease(sb);
70 } else {
71 EmitDriverDispatch(sb);
72 sb.Append("\n");
73 EmitDriverInit(sb);
74 sb.Append("\n");
75 EmitDriverBind(sb);
76 sb.Append("\n");
77 EmitDriverRelease(sb);
78 }
79 sb.Append("\n");
80 EmitDriverEntryDefinition(sb);
81
82 std::string data = sb.ToString();
83 file.WriteData(data.c_str(), data.size());
84 file.Flush();
85 file.Close();
86 }
87
EmitDriverInclusions(StringBuilder & sb)88 void CServiceDriverCodeEmitter::EmitDriverInclusions(StringBuilder &sb)
89 {
90 HeaderFile::HeaderFileSet headerFiles;
91
92 if (isKernelCode_) {
93 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_));
94 } else {
95 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
96 }
97
98 GetDriverSourceOtherLibInclusions(headerFiles);
99
100 for (const auto &file : headerFiles) {
101 sb.AppendFormat("%s\n", file.ToString().c_str());
102 }
103 }
104
GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)105 void CServiceDriverCodeEmitter::GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
106 {
107 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
108 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
109 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
110 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc");
111 if (!isKernelCode_) {
112 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_object");
113 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service");
114 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
115 }
116 }
117
EmitDriverServiceDecl(StringBuilder & sb)118 void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder &sb)
119 {
120 sb.AppendFormat("struct Hdf%sHost {\n", baseName_.c_str());
121 sb.Append(TAB).AppendFormat("struct IDeviceIoService ioService;\n");
122 if (isKernelCode_) {
123 sb.Append(TAB).AppendFormat("struct %s *service;\n", implName_.c_str());
124 } else {
125 sb.Append(TAB).AppendFormat("struct %s *service;\n", interfaceName_.c_str());
126 sb.Append(TAB).Append("struct HdfRemoteService **stubObject;\n");
127 }
128 sb.Append("};\n");
129 }
130
EmitKernelDriverDispatch(StringBuilder & sb)131 void CServiceDriverCodeEmitter::EmitKernelDriverDispatch(StringBuilder &sb)
132 {
133 sb.AppendFormat(
134 "static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
135 sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
136 sb.Append("{\n");
137 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(\n", baseName_.c_str(), hostName_.c_str());
138 sb.Append(TAB).Append(TAB).AppendFormat(
139 "client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
140 sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->service->stub.OnRemoteRequest == NULL) {\n",
141 hostName_.c_str(), hostName_.c_str());
142 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
143 sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
144 sb.Append(TAB).Append("}\n\n");
145 sb.Append(TAB).AppendFormat("return %s->service->stub.OnRemoteRequest(", hostName_.c_str());
146 sb.AppendFormat("&%s->service->stub.interface, cmdId, data, reply);\n", hostName_.c_str());
147 sb.Append("}\n");
148 }
149
EmitDriverDispatch(StringBuilder & sb)150 void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder &sb)
151 {
152 sb.AppendFormat(
153 "static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
154 sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
155 sb.Append("{\n");
156 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
157 sb.AppendFormat("client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
158 sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->stubObject == NULL) {\n",
159 hostName_.c_str(), hostName_.c_str());
160 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
161 sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
162 sb.Append(TAB).Append("}\n\n");
163 sb.Append(TAB).AppendFormat("struct HdfRemoteService *stubObj = *%s->stubObject;\n", hostName_.c_str());
164 sb.Append(TAB).AppendFormat("if (stubObj == NULL || stubObj->dispatcher == NULL || ");
165 sb.Append("stubObj->dispatcher->Dispatch == NULL) {\n");
166 sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
167 sb.Append(TAB).Append("}\n\n");
168 sb.Append(TAB).Append("return stubObj->dispatcher->Dispatch(");
169 sb.Append("(struct HdfRemoteService *)stubObj->target, cmdId, data, reply);\n");
170 sb.Append("}\n");
171 }
172
EmitDriverInit(StringBuilder & sb)173 void CServiceDriverCodeEmitter::EmitDriverInit(StringBuilder &sb)
174 {
175 sb.AppendFormat("static int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
176 sb.Append("{\n");
177 sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver init start\", __func__);\n");
178 sb.Append(TAB).Append("return HDF_SUCCESS;\n");
179 sb.Append("}\n");
180 }
181
EmitKernelDriverBind(StringBuilder & sb)182 void CServiceDriverCodeEmitter::EmitKernelDriverBind(StringBuilder &sb)
183 {
184 sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
185 sb.Append("{\n");
186 sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
187 sb.Append("\n");
188
189 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
190 hostName_.c_str(), baseName_.c_str());
191 sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
192 sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
193 sb.Append(TAB).Append(TAB).AppendFormat(
194 "HDF_LOGE(\"Hdf%sDriverBind create Hdf%sHost object failed!\");\n", baseName_.c_str(), baseName_.c_str());
195 sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
196 sb.Append(TAB).Append("}\n");
197 sb.Append("\n");
198 sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
199 sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
200 sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
201 sb.Append(TAB).AppendFormat("%s->service = %sServiceGet();\n", hostName_.c_str(), baseName_.c_str());
202 sb.Append(TAB).AppendFormat("if (%s->service == NULL) {\n", hostName_.c_str());
203 sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
204 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get service object\", __func__);\n");
205 sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
206 sb.Append(TAB).Append("}\n");
207 sb.Append("\n");
208 sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
209 sb.Append(TAB).Append("return HDF_SUCCESS;\n");
210 sb.Append("}\n");
211 }
212
EmitDriverBind(StringBuilder & sb)213 void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb)
214 {
215 sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
216 sb.Append("{\n");
217 sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
218 sb.Append(TAB).AppendFormat("int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, %s);\n",
219 interface_->EmitDescMacroName().c_str());
220 sb.Append(TAB).Append("if (ret != HDF_SUCCESS) {\n");
221 sb.Append(TAB).Append(TAB).Append(
222 "HDF_LOGE(\"%{public}s: failed to set interface descriptor of device object\", __func__);\n");
223 sb.Append(TAB).Append(TAB).Append("return ret;\n");
224 sb.Append(TAB).Append("}\n\n");
225
226 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
227 hostName_.c_str(), baseName_.c_str());
228 sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
229 sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
230 sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: create Hdf%sHost object failed!\", __func__);\n",
231 baseName_.c_str());
232 sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
233 sb.Append(TAB).Append("}\n\n");
234 sb.Append(TAB).AppendFormat("struct %s *serviceImpl = %sGet(true);\n", interfaceName_.c_str(),
235 interfaceName_.c_str());
236 sb.Append(TAB).Append("if (serviceImpl == NULL) {\n");
237 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: create serviceImpl failed!\", __func__);\n");
238 sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
239 sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
240 sb.Append(TAB).Append("}\n\n");
241 sb.Append(TAB).AppendFormat("struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(");
242 sb.AppendFormat("%s, serviceImpl);\n", interface_->EmitDescMacroName().c_str());
243 sb.Append(TAB).Append("if (stubObj == NULL) {\n");
244 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get stub object\", __func__);\n");
245 sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
246 sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(serviceImpl, true);\n", interfaceName_.c_str());
247 sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
248 sb.Append(TAB).Append("}\n\n");
249
250 sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
251 sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
252 sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
253 sb.Append(TAB).AppendFormat("%s->service = serviceImpl;\n", hostName_.c_str());
254 sb.Append(TAB).AppendFormat("%s->stubObject = stubObj;\n", hostName_.c_str());
255 sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
256 sb.Append(TAB).Append("return HDF_SUCCESS;\n");
257 sb.Append("}\n");
258 }
259
EmitKernelDriverRelease(StringBuilder & sb)260 void CServiceDriverCodeEmitter::EmitKernelDriverRelease(StringBuilder &sb)
261 {
262 sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
263 sb.Append("{\n");
264 sb.Append(TAB).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n", baseName_.c_str());
265 sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
266 sb.Append(TAB).Append(TAB).Append("return;\n");
267 sb.Append(TAB).Append("}\n\n");
268 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
269 sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
270 sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
271 sb.Append(TAB).Append(TAB).AppendFormat("%sServiceRelease(%s->service);\n", baseName_.c_str(), hostName_.c_str());
272 sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
273 sb.Append(TAB).Append("}\n");
274 sb.Append("}\n");
275 }
276
EmitDriverRelease(StringBuilder & sb)277 void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder &sb)
278 {
279 sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
280 sb.Append("{\n");
281 sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
282
283 sb.Append(TAB).Append("if (deviceObject->service == NULL) {\n");
284 sb.Append(TAB).Append(TAB).Append("return;\n");
285 sb.Append(TAB).Append("}\n\n");
286
287 sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
288 sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
289 sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
290 sb.Append(TAB).Append(TAB).AppendFormat("StubCollectorRemoveObject(%s, %s->service);\n",
291 interface_->EmitDescMacroName().c_str(), hostName_.c_str());
292 sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(%s->service, true);\n", interfaceName_.c_str(),
293 hostName_.c_str());
294 sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
295 sb.Append(TAB).Append("}\n");
296 sb.Append("}\n");
297 }
298
EmitDriverEntryDefinition(StringBuilder & sb)299 void CServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder &sb)
300 {
301 sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", StringHelper::StrToLower(baseName_).c_str());
302 sb.Append(TAB).Append(".moduleVersion = 1,\n");
303 sb.Append(TAB).AppendFormat(".moduleName = \"%s\",\n", Options::GetInstance().GetModuleName().c_str());
304 sb.Append(TAB).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.c_str());
305 sb.Append(TAB).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.c_str());
306 sb.Append(TAB).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.c_str());
307 sb.Append("};\n\n");
308 sb.AppendFormat("HDF_INIT(g_%sDriverEntry);\n", StringHelper::StrToLower(baseName_).c_str());
309 }
310 } // namespace HDI
311 } // namespace OHOS