• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "platform_dumper.h"
9 #include "hdf_log.h"
10 #include "osal_io.h"
11 #include "osal_mem.h"
12 #include "osal_sem.h"
13 #include "securec.h"
14 
15 struct DumperDataMgrNode {
16     struct PlatformDumperData data;
17     const char *printFormat;
18     void (*printFunc)(const struct DumperDataMgrNode *data);
19     struct DListHead node;
20 };
21 
22 struct PlatformDumper {
23     const char *name;
24     struct DListHead dumperDatas;
25     OsalSpinlock spin;
26     struct PlatformDumperMethod *ops;
27 };
28 
29 #define DUMPER_INFO_FILE_LEN 256
30 #ifdef __LITEOS__
31 #define DUMPER_PRINT(fmt, args...) dprintf(fmt, ##args)
32 #else
33 #define DUMPER_PRINT(fmt, args...) printk(fmt, ##args)
34 #endif
35 
OutputDumperInfo(const char * info)36 static void OutputDumperInfo(const char *info)
37 {
38     HDF_LOGE("%s", info);
39 #if defined(LOSCFG_DRIVERS_HDF_PLATFORM_DUMPER_PRINT) || defined(CONFIG_DRIVERS_HDF_PLATFORM_DUMPER_PRINT)
40     DUMPER_PRINT("%s\r\n", info);
41 #endif
42 }
43 
DumperPrintUint8Info(const struct DumperDataMgrNode * data)44 static void DumperPrintUint8Info(const struct DumperDataMgrNode *data)
45 {
46     uint8_t *val = (uint8_t *)(data->data.paddr);
47     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
48     int ret =
49         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
50     if (ret > 0) {
51         OutputDumperInfo(info);
52     }
53 }
54 
DumperPrintUint16Info(const struct DumperDataMgrNode * data)55 static void DumperPrintUint16Info(const struct DumperDataMgrNode *data)
56 {
57     uint16_t *val = (uint16_t *)(data->data.paddr);
58     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
59     int ret =
60         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
61     if (ret > 0) {
62         OutputDumperInfo(info);
63     }
64 }
65 
DumperPrintUint32Info(const struct DumperDataMgrNode * data)66 static void DumperPrintUint32Info(const struct DumperDataMgrNode *data)
67 {
68     uint32_t *val = (uint32_t *)(data->data.paddr);
69     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
70     int ret =
71         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
72     if (ret > 0) {
73         OutputDumperInfo(info);
74     }
75 }
76 
DumperPrintUint64Info(const struct DumperDataMgrNode * data)77 static void DumperPrintUint64Info(const struct DumperDataMgrNode *data)
78 {
79     uint64_t *val = (uint64_t *)(data->data.paddr);
80     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
81     int ret =
82         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
83     if (ret > 0) {
84         OutputDumperInfo(info);
85     }
86 }
87 
DumperPrintInt8Info(const struct DumperDataMgrNode * data)88 static void DumperPrintInt8Info(const struct DumperDataMgrNode *data)
89 {
90     int8_t *val = (int8_t *)(data->data.paddr);
91     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
92     int ret =
93         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
94     if (ret > 0) {
95         OutputDumperInfo(info);
96     }
97 }
98 
DumperPrintInt16Info(const struct DumperDataMgrNode * data)99 static void DumperPrintInt16Info(const struct DumperDataMgrNode *data)
100 {
101     int16_t *val = (int16_t *)(data->data.paddr);
102     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
103     int ret =
104         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
105     if (ret > 0) {
106         OutputDumperInfo(info);
107     }
108 }
109 
DumperPrintInt32Info(const struct DumperDataMgrNode * data)110 static void DumperPrintInt32Info(const struct DumperDataMgrNode *data)
111 {
112     int32_t *val = (int32_t *)(data->data.paddr);
113     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
114     int ret =
115         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
116     if (ret > 0) {
117         OutputDumperInfo(info);
118     }
119 }
120 
DumperPrintInt64Info(const struct DumperDataMgrNode * data)121 static void DumperPrintInt64Info(const struct DumperDataMgrNode *data)
122 {
123     int64_t *val = (int64_t *)(data->data.paddr);
124     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
125     int ret =
126         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
127     if (ret > 0) {
128         OutputDumperInfo(info);
129     }
130 }
131 
DumperPrintFloatInfo(const struct DumperDataMgrNode * data)132 static void DumperPrintFloatInfo(const struct DumperDataMgrNode *data)
133 {
134 #ifdef __LITEOS__
135     float *val = (float *)(data->data.paddr);
136     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
137     int ret =
138         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
139     if (ret > 0) {
140         OutputDumperInfo(info);
141     }
142 #endif
143 }
144 
DumperPrintDoubleInfo(const struct DumperDataMgrNode * data)145 static void DumperPrintDoubleInfo(const struct DumperDataMgrNode *data)
146 {
147 #ifdef __LITEOS__
148     double *val = (double *)(data->data.paddr);
149     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
150     int ret =
151         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
152     if (ret > 0) {
153         OutputDumperInfo(info);
154     }
155 #endif
156 }
157 
DumperPrintCharInfo(const struct DumperDataMgrNode * data)158 static void DumperPrintCharInfo(const struct DumperDataMgrNode *data)
159 {
160     char *val = (char *)(data->data.paddr);
161     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
162 
163     int ret =
164         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, *val);
165     if (ret > 0) {
166         OutputDumperInfo(info);
167     }
168 }
169 
DumperPrintStringInfo(const struct DumperDataMgrNode * data)170 static void DumperPrintStringInfo(const struct DumperDataMgrNode *data)
171 {
172     char *val = (char *)(data->data.paddr);
173     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
174     int ret = snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat,
175         data->data.name, val);
176     if (ret > 0) {
177         OutputDumperInfo(info);
178     }
179 }
180 
DumperPrintRegisterInfo(const struct DumperDataMgrNode * data)181 static void DumperPrintRegisterInfo(const struct DumperDataMgrNode *data)
182 {
183     unsigned long value;
184     volatile uint8_t *regAddr = (volatile uint8_t *)data->data.paddr;
185     if (data->data.type == PLATFORM_DUMPER_REGISTERL) {
186         value = OSAL_READL(regAddr);
187     } else if (data->data.type == PLATFORM_DUMPER_REGISTERW) {
188         value = OSAL_READW(regAddr);
189     } else if (data->data.type == PLATFORM_DUMPER_REGISTERB) {
190         value = OSAL_READB(regAddr);
191     } else {
192         HDF_LOGE("DumperPrintRegisterInfo: illegal type: %d!", data->data.type);
193         return;
194     }
195 
196     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
197     int ret =
198         snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, data->printFormat, data->data.name, value);
199     if (ret > 0) {
200         OutputDumperInfo(info);
201     }
202 }
203 
204 struct PlatformDumperDataFormatter {
205     enum PlatformDumperDataType type;
206     const char *printFormat; // type/name/value
207     void (*printFunc)(const struct DumperDataMgrNode *data);
208 };
209 
210 static const struct PlatformDumperDataFormatter g_printInfos[] = {
211     {PLATFORM_DUMPER_UINT8,     "uint8           %-32s\t       %hhu\r\n", DumperPrintUint8Info   },
212     {PLATFORM_DUMPER_UINT16,    "uint16          %-32s\t       %hu\r\n",  DumperPrintUint16Info  },
213     {PLATFORM_DUMPER_UINT32,    "uint32          %-32s\t       %u\r\n",   DumperPrintUint32Info  },
214     {PLATFORM_DUMPER_UINT64,    "uint64          %-32s\t       %llu\r\n", DumperPrintUint64Info  },
215     {PLATFORM_DUMPER_INT8,      "int8            %-32s\t       %hhd\r\n",   DumperPrintInt8Info    },
216     {PLATFORM_DUMPER_INT16,     "int16           %-32s\t       %hd\r\n",   DumperPrintInt16Info   },
217     {PLATFORM_DUMPER_INT32,     "int32           %-32s\t       %d\r\n",   DumperPrintInt32Info   },
218     {PLATFORM_DUMPER_INT64,     "int64           %-32s\t       %lld\r\n",  DumperPrintInt64Info   },
219     {PLATFORM_DUMPER_CHAR,      "char            %-32s\t       %c\r\n",   DumperPrintCharInfo    },
220     {PLATFORM_DUMPER_STRING,    "string          %-32s\t       %s\r\n",   DumperPrintStringInfo  },
221     {PLATFORM_DUMPER_FLOAT,     "float           %-32s\t       %f\r\n",   DumperPrintFloatInfo   },
222     {PLATFORM_DUMPER_DOUBLE,    "double          %-32s\t       %lf\r\n",  DumperPrintDoubleInfo  },
223     {PLATFORM_DUMPER_REGISTERL, "registerL       %-32s\t       %u\r\n",   DumperPrintRegisterInfo},
224     {PLATFORM_DUMPER_REGISTERW, "registerW       %-32s\t       %hu\r\n",  DumperPrintRegisterInfo},
225     {PLATFORM_DUMPER_REGISTERB, "registerB       %-32s\t       %hhu\r\n", DumperPrintRegisterInfo},
226 };
227 
DumperNodeSetPrintInfo(struct DumperDataMgrNode * node)228 static int32_t DumperNodeSetPrintInfo(struct DumperDataMgrNode *node)
229 {
230     int i;
231     for (i = 0; i < sizeof(g_printInfos) / sizeof(g_printInfos[0]); i++) {
232         if (node->data.type == g_printInfos[i].type) {
233             node->printFormat = g_printInfos[i].printFormat;
234             node->printFunc = g_printInfos[i].printFunc;
235             return HDF_SUCCESS;
236         }
237     }
238 
239     HDF_LOGE("DumperNodeSetPrintInfo: node [%s] type [%d] not find!", node->data.name, node->data.type);
240     return HDF_FAILURE;
241 }
242 
PlatformDumperCreate(const char * name)243 struct PlatformDumper *PlatformDumperCreate(const char *name)
244 {
245     struct PlatformDumper *dumper = NULL;
246     int32_t ret;
247 
248     if (name == NULL) {
249         HDF_LOGE("PlatformDumperCreate: name is null!");
250         return NULL;
251     }
252     dumper = OsalMemAlloc(sizeof(struct PlatformDumper));
253     if (dumper == NULL) {
254         HDF_LOGE("PlatformDumperCreate: malloc dumper for %s fail!", name);
255         return NULL;
256     }
257 
258     dumper->name = name;
259     dumper->ops = NULL;
260     DListHeadInit(&dumper->dumperDatas);
261     ret = OsalSpinInit(&dumper->spin);
262     if (ret != HDF_SUCCESS) {
263         HDF_LOGE("PlatformDumperCreate: dumper %s OsalSpinInit fail, ret: %d!", name, ret);
264         OsalMemFree(dumper);
265         return NULL;
266     }
267 
268     HDF_LOGD("PlatformDumperCreate: create dumper for %s success!", name);
269     return dumper;
270 }
271 
DumperAddNode(struct PlatformDumper * dumper,const struct PlatformDumperData * data)272 static int32_t DumperAddNode(struct PlatformDumper *dumper, const struct PlatformDumperData *data)
273 {
274     struct DumperDataMgrNode *pos = NULL;
275     struct DumperDataMgrNode *node = NULL;
276 
277     if (data == NULL || data->name == NULL || data->paddr == NULL) {
278         HDF_LOGE("DumperAddNode: input param illegal!");
279         return HDF_FAILURE;
280     }
281 
282     DLIST_FOR_EACH_ENTRY(pos, &dumper->dumperDatas, struct DumperDataMgrNode, node) {
283         if ((strcmp(pos->data.name, data->name) == 0) && (pos->data.type == data->type)) {
284             HDF_LOGE("DumperAddNode: node [%s][%d] existed!", data->name, data->type);
285             return HDF_FAILURE;
286         }
287     }
288 
289     node = OsalMemAlloc(sizeof(struct DumperDataMgrNode));
290     if (node == NULL) {
291         HDF_LOGE("DumperAddNode: OsalMemAlloc node [%s] fail!", data->name);
292         return HDF_FAILURE;
293     }
294 
295     node->data.name = data->name;
296     node->data.type = data->type;
297     node->data.paddr = data->paddr;
298     if (DumperNodeSetPrintInfo(node) == HDF_FAILURE) {
299         HDF_LOGE("DumperAddNode: SetPrintInfo node [%s] fail", data->name);
300         OsalMemFree(node);
301         return HDF_FAILURE;
302     }
303     DListInsertTail(&node->node, &dumper->dumperDatas);
304 
305     return HDF_SUCCESS;
306 }
307 
PlatformDumperAddData(struct PlatformDumper * dumper,const struct PlatformDumperData * data)308 int32_t PlatformDumperAddData(struct PlatformDumper *dumper, const struct PlatformDumperData *data)
309 {
310     int32_t ret;
311 
312     if (dumper == NULL) {
313         HDF_LOGE("PlatformDumperAddData: input param illegal!");
314         return HDF_FAILURE;
315     }
316     (void)OsalSpinLock(&dumper->spin);
317     ret = DumperAddNode(dumper, data);
318     (void)OsalSpinUnlock(&dumper->spin);
319 
320     return ret;
321 }
322 
PlatformDumperAddDatas(struct PlatformDumper * dumper,struct PlatformDumperData datas[],int size)323 int32_t PlatformDumperAddDatas(struct PlatformDumper *dumper, struct PlatformDumperData datas[], int size)
324 {
325     int i;
326 
327     if (dumper == NULL || datas == NULL) {
328         HDF_LOGE("PlatformDumperAddDatas: input param illegal!");
329         return HDF_FAILURE;
330     }
331     (void)OsalSpinLock(&dumper->spin);
332     for (i = 0; i < size; i++) {
333         if (DumperAddNode(dumper, &datas[i]) != HDF_SUCCESS) {
334             HDF_LOGE("PlatformDumperAddDatas: [%s] add data [%s] fail", dumper->name, datas[i].name);
335             (void)OsalSpinUnlock(&dumper->spin);
336             return HDF_FAILURE;
337         }
338     }
339     (void)OsalSpinUnlock(&dumper->spin);
340 
341     return HDF_SUCCESS;
342 }
343 
PlatformDumperDelData(struct PlatformDumper * dumper,const char * name,enum PlatformDumperDataType type)344 int32_t PlatformDumperDelData(struct PlatformDumper *dumper, const char *name, enum PlatformDumperDataType type)
345 {
346     struct DumperDataMgrNode *pos = NULL;
347     struct DumperDataMgrNode *tmp = NULL;
348 
349     if (dumper == NULL || name == NULL) {
350         HDF_LOGE("PlatformDumperDelData: input param illegal!");
351         return HDF_FAILURE;
352     }
353 
354     (void)OsalSpinLock(&dumper->spin);
355     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &dumper->dumperDatas, struct DumperDataMgrNode, node) {
356         if ((strcmp(pos->data.name, name) == 0) && (pos->data.type == type)) {
357             HDF_LOGD("PlatformDumperDelData: node [%s][%d] find, then del", name, type);
358             DListRemove(&pos->node);
359             OsalMemFree(pos);
360             (void)OsalSpinUnlock(&dumper->spin);
361             return HDF_SUCCESS;
362         }
363     }
364 
365     (void)OsalSpinUnlock(&dumper->spin);
366     return HDF_SUCCESS;
367 }
368 
PlatformDumperClearDatas(struct PlatformDumper * dumper)369 int32_t PlatformDumperClearDatas(struct PlatformDumper *dumper)
370 {
371     struct DumperDataMgrNode *pos = NULL;
372     struct DumperDataMgrNode *tmp = NULL;
373 
374     if (dumper == NULL) {
375         HDF_LOGE("PlatformDumperClearDatas: dumper is null!");
376         return HDF_FAILURE;
377     }
378 
379     (void)OsalSpinLock(&dumper->spin);
380     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &dumper->dumperDatas, struct DumperDataMgrNode, node) {
381         DListRemove(&pos->node);
382         OsalMemFree(pos);
383     }
384 
385     (void)OsalSpinUnlock(&dumper->spin);
386     return HDF_SUCCESS;
387 }
388 
PlatformDumperDestroy(struct PlatformDumper * dumper)389 void PlatformDumperDestroy(struct PlatformDumper *dumper)
390 {
391     int32_t ret;
392 
393     if (dumper == NULL) {
394         HDF_LOGE("PlatformDumperDestroy: dumper is null!");
395         return;
396     }
397 
398     PlatformDumperClearDatas(dumper);
399     ret = OsalSpinDestroy(&dumper->spin);
400     if (ret != HDF_SUCCESS) {
401         HDF_LOGE("PlatformDumperDestroy: dumper %s OsalSpinDestroy fail, ret: %d!", dumper->name, ret);
402     }
403 
404     OsalMemFree(dumper);
405 }
406 
PlatformDumperSetMethod(struct PlatformDumper * dumper,struct PlatformDumperMethod * ops)407 int32_t PlatformDumperSetMethod(struct PlatformDumper *dumper, struct PlatformDumperMethod *ops)
408 {
409     if (dumper == NULL || ops == NULL) {
410         HDF_LOGE("PlatformDumperSetMethod: input param null!");
411         return HDF_FAILURE;
412     }
413     (void)OsalSpinLock(&dumper->spin);
414     dumper->ops = ops;
415     (void)OsalSpinUnlock(&dumper->spin);
416     return HDF_SUCCESS;
417 }
418 
PlatformGetDumperOpsInfo(const struct PlatformDumperMethod * ops)419 static void PlatformGetDumperOpsInfo(const struct PlatformDumperMethod *ops)
420 {
421     if (ops == NULL) {
422         return;
423     }
424     if (ops->dumperCfgInfo != NULL) {
425         ops->dumperCfgInfo();
426     }
427     if (ops->dumperStatusInfo != NULL) {
428         ops->dumperStatusInfo();
429     }
430     if (ops->dumperRegisterInfo != NULL) {
431         ops->dumperRegisterInfo();
432     }
433     if (ops->dumperStatisInfo != NULL) {
434         ops->dumperStatisInfo();
435     }
436 }
437 
PlatformDumperDump(struct PlatformDumper * dumper)438 int32_t PlatformDumperDump(struct PlatformDumper *dumper)
439 {
440     struct DumperDataMgrNode *pos = NULL;
441     char info[DUMPER_INFO_FILE_LEN + 1] = {0};
442     int ret;
443 
444     if (dumper == NULL) {
445         HDF_LOGE("PlatformDumperDump: dumper null!");
446         return HDF_FAILURE;
447     }
448 
449     PlatformGetDumperOpsInfo(dumper->ops);
450 
451     ret = snprintf_s(info, DUMPER_INFO_FILE_LEN + 1, DUMPER_INFO_FILE_LEN, "The dumper %s's data list as follows:\r\n",
452         dumper->name);
453     if (ret > 0) {
454         OutputDumperInfo(info);
455     }
456     OutputDumperInfo("type               name                              value\r\n");
457 
458     (void)OsalSpinLock(&dumper->spin);
459     DLIST_FOR_EACH_ENTRY(pos, &dumper->dumperDatas, struct DumperDataMgrNode, node) {
460         pos->printFunc(pos);
461     }
462     (void)OsalSpinUnlock(&dumper->spin);
463     return HDF_SUCCESS;
464 }
465