• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description:  LOG BUFFER MODULE.
15  * Author:
16  * Create:  2018-10-15
17  */
18 
19 #include "securec.h"
20 #include "non_os.h"
21 #include "panic.h"
22 #include "soc_osal.h"
23 #include "log_buffer.h"
24 
25 /*
26  *  Private definitions
27  */
28 #define index_in_cbuff(x) ((x) < g_log_buffer_size)
29 
30 /*
31  *  Private variables
32  */
33 static uint8_t *g_log_buffer_start;
34 static uint32_t g_log_buffer_size;
35 static volatile log_memory_section_control_t *g_log_section_control;
36 
37 volatile massdata_memory_section_control_t *g_mass_section_control = NULL;
38 
39 /**
40  * Read an index with overflow.
41  * @param index_in index in the limits of the circular buffer or up to buffer_size longer
42  * @return index in the circular buffer limits
43  */
circled_index(uint32_t index_in)44 static uint32_t circled_index(uint32_t index_in)
45 {
46     uint32_t index_out;
47 
48     if (index_in < g_log_buffer_size) {
49         index_out = index_in;
50     } else {
51         index_out = index_in - g_log_buffer_size;
52     }
53     if (!index_in_cbuff(index_out)) {
54         panic(PANIC_LOG, __LINE__);
55         return 0;
56     }
57     return index_out;
58 }
59 
log_buffer_get_used(uint32_t read_i,uint32_t write_i)60 static uint32_t log_buffer_get_used(uint32_t read_i, uint32_t write_i)
61 {
62     uint32_t in_use;
63     /* Check how much space is used. Use -1 to ensure the g_log_section_control->write ==
64      * g_log_section_control->read means the buffer is EMPTY.
65      * Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
66     if (read_i <= write_i) {
67         in_use = write_i - read_i;
68     } else {
69         /* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
70         in_use = (g_log_buffer_size - read_i) + write_i;
71     }
72     return in_use;
73 }
74 
75 /**
76  * Get the available space in the buffer
77  * @param av if return is LOG_RET_OK the available data will be stored in the pointer given
78  * @return LOG_RET_OK or an error value
79  */
log_buffer_get_available(uint32_t * av)80 static inline log_ret_t log_buffer_get_available(uint32_t *av)
81 {
82     uint32_t l_read_i = g_log_section_control->read;
83     uint32_t l_write_i = g_log_section_control->write;
84 
85     /* Check how much space is available. Use -1 to ensure the g_log_section_control->write ==
86      * g_log_section_control->read means the buffer is EMPTY.
87      * Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
88     if (!index_in_cbuff(l_read_i) || !index_in_cbuff(l_write_i)) { return LOG_RET_ERROR_CORRUPT_SHARED_MEMORY; }
89 
90     if (l_read_i <= l_write_i) {
91         // l_read_i and l_write_i has been checked to be in safe boundaries.
92         *av = (g_log_buffer_size - 1u) - (l_write_i - l_read_i);
93     /* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
94     // l_read_i and l_write_i has been checked to be in safe boundaries.
95     } else { *av = (l_read_i - l_write_i) - 1u; }
96     return LOG_RET_OK;
97 }
98 
99 /**
100  * Add data to the circular buffer with updating the write index.
101  * @param data buffer with the data to store
102  * @param data_len data length in bytes
103  */
log_buffer_helper_add(const uint8_t * data,const uint32_t data_len)104 static void log_buffer_helper_add(const uint8_t *data, const uint32_t data_len)
105 {
106     errno_t sec_ret;
107     uint32_t l_write = g_log_section_control->write;
108     size_t to_end = g_log_buffer_size - l_write;
109 
110     if (to_end >= data_len) {
111         /* Entire message fits. */
112         sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, data_len);
113     } else {
114         /* Message needs to be segmented. Write to end of buffer and then the remainder from the beginning. */
115         sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, to_end);
116         if (sec_ret != EOK) {
117             return;
118         }
119         sec_ret = memcpy_s((void *)g_log_buffer_start, g_log_section_control->read, &data[to_end], data_len - to_end);
120     }
121     if (sec_ret != EOK) {
122         return;
123     }
124 
125     g_log_section_control->write = circled_index(l_write + data_len);
126 }
127 
128 /**
129  * Scatter gather write to log_buffer.
130  * @param length array of lengths for the different buffers, it admits 0 as a value of one of them
131  * @param buffer array of values containig the buffers to the data to save in the log buffer
132  * @param was_empty if a pointer != NULL is given it will store a return value
133  *        indicating the buffer was empty when the write was done.
134  * @return LOG_RET_OK or an error value
135  */
log_buffer_write(const log_buffer_header_t * lb_header,const uint8_t * buffer,bool * was_empty)136 void log_buffer_write(const log_buffer_header_t *lb_header, const uint8_t *buffer, bool *was_empty)
137 {
138     uint32_t l_read_i;
139     uint32_t l_write_i;
140     // Add the header
141     log_buffer_helper_add((const uint8_t *)lb_header, sizeof(log_buffer_header_t));
142 
143     // Add the buffer
144     log_buffer_helper_add(buffer, lb_header->length - sizeof(log_buffer_header_t));
145 
146     l_read_i = g_log_section_control->read;
147     l_write_i = g_log_section_control->write;
148 
149     *was_empty = (log_buffer_get_used(l_read_i, l_write_i) <= lb_header->length);
150 }
151 #ifdef FEATURE_PLT_LB_CHECK
152 
153 uint8_t *g_p_log_buf_sdt_cur = NULL;
154 uint8_t *g_p_log_buf_sdt_beg = NULL;
155 uint8_t *g_p_log_buf_sdt_end = NULL;
156 
log_buffer_check_rlw(uint8_t * beg,uint8_t * end)157 static uint8_t log_buffer_check_rlw(uint8_t *beg, uint8_t *end)
158 {
159     uint8_t *cur = NULL;
160     log_buffer_header_t *hdr = NULL;
161 
162     if ((beg == NULL) || (end == NULL)) {
163         return 0xFF;
164     }
165 
166     if (beg >= end) {
167         return 0xFE;
168     }
169 
170     cur = beg;
171     while (cur < end) {
172         hdr = (log_buffer_header_t *)(cur);
173         if (!lb_magic_check(hdr)) {
174             g_p_log_buf_sdt_beg = beg;
175             g_p_log_buf_sdt_cur = cur;
176             g_p_log_buf_sdt_end = end;
177 
178             return LOG_BUF_RLW_MAGIC_ERROR;
179         }
180 
181         cur += hdr->length;
182     }
183 
184     return LOG_BUF_RET_OK;
185 }
186 
187 #define MAX_ONE_LOG_CPY_LENGTH 100
188 #define G_LB_BUF_LEN 200
189 static uint8_t g_lb_buf[G_LB_BUF_LEN] = { 0 };
190 
log_buffer_check_last_one(uint8_t ** beg,uint8_t * end,uint8_t ** cur,log_buffer_header_t * hdr)191 static uint8_t log_buffer_check_last_one(uint8_t **beg, uint8_t *end, uint8_t **cur, log_buffer_header_t *hdr)
192 {
193     uint32_t last_len = end - (*cur);
194     uint8_t *buf = g_lb_buf;
195     memset_s(buf, sizeof(g_lb_buf), 0, G_LB_BUF_LEN);
196     if (memcpy_s(buf, sizeof(g_lb_buf), *cur, last_len) != EOK) {
197         return LOG_RET_MEMCPY_ERROR;
198     }
199     *beg = (uint8_t *)(g_log_buffer_start);
200     if (memcpy_s(buf + last_len, sizeof(g_lb_buf) - last_len, *beg, MAX_ONE_LOG_CPY_LENGTH) != EOK) {
201         return LOG_RET_MEMCPY_ERROR;
202     }
203     hdr = (log_buffer_header_t *)(buf);
204 
205     /* magic check */
206     if (!lb_magic_check(hdr)) {
207         g_p_log_buf_sdt_beg = *beg;
208         g_p_log_buf_sdt_cur = *cur;
209         g_p_log_buf_sdt_end = end;
210         return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
211     }
212     *cur = (*beg) + ((log_buffer_header_t)(*hdr)).length - last_len;
213     return LOG_BUF_RET_OK;
214 }
215 
log_buffer_check_rgw(uint8_t * ori_beg,uint8_t * ori_end)216 static uint8_t log_buffer_check_rgw(uint8_t *ori_beg, uint8_t *ori_end)
217 {
218     uint8_t *beg = ori_beg;
219     uint8_t *end = ori_end;
220     uint8_t *cur = NULL;
221     log_buffer_header_t *hdr = NULL;
222     uint8_t last_one = 0;
223 
224     if ((beg == NULL) || (end == NULL)) { return 0xFF; }
225     if (beg <= end) { return 0xFE; }
226     cur = beg;
227     end = (uint8_t *)(g_log_buffer_start + g_log_buffer_size);
228     while (cur < end) {
229         if ((cur + sizeof(log_buffer_header_t)) >= end) { // judge last one
230             last_one = 1;
231             break;
232         }
233         hdr = (log_buffer_header_t *)(cur);
234         if ((cur + hdr->length) > end) {
235             last_one = 1;
236             break;
237         }
238         if (!lb_magic_check(hdr)) { // magic check
239             g_p_log_buf_sdt_beg = beg;
240             g_p_log_buf_sdt_cur = cur;
241             g_p_log_buf_sdt_end = end;
242             return LOG_RET_RGW_TOEND_MAGIC_ERROR;
243         }
244         if ((cur + hdr->length) == end) { // to end
245             cur = (uint8_t *)(g_log_buffer_start);
246             break;
247         }
248         cur += hdr->length;
249     }
250     if (last_one && log_buffer_check_last_one(&beg, end, &cur, hdr) == LOG_RET_RGW_LASTONE_MAGIC_ERROR) { // last one
251         return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
252     }
253     end = ori_end; // from head
254     while (cur < end) {
255         hdr = (log_buffer_header_t *)(cur);
256         if (!lb_magic_check(hdr)) { // magic check
257             g_p_log_buf_sdt_beg = beg;
258             g_p_log_buf_sdt_cur = cur;
259             g_p_log_buf_sdt_end = end;
260             return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
261         }
262         cur += hdr->length;
263     }
264     return LOG_BUF_RET_OK;
265 }
266 
log_buffer_check(void)267 uint8_t log_buffer_check(void)
268 {
269     uint8_t *beg = (uint8_t *)(g_log_buffer_start + g_log_section_control->read);
270     uint8_t *end = (uint8_t *)(g_log_buffer_start + g_log_section_control->write);
271 
272     if (beg == end) {
273         return 0;
274     } else if (beg < end) {
275         return log_buffer_check_rlw(beg, end);
276     } else {
277         return log_buffer_check_rgw(beg, end);
278     }
279 }
280 #endif
281 
282 /*
283  *  Public function definitions
284  */
log_buffer_init(log_memory_region_section_t logsec)285 void log_buffer_init(log_memory_region_section_t logsec)
286 {
287     /* Init the buffer limits */
288     log_memory_section_params_t ms_params;
289     log_memory_section_get(logsec, &ms_params);
290     if (pointer_in_log_memory_region((uintptr_t)ms_params.start) &&
291         pointer_in_log_memory_region((uint32_t)((uintptr_t)ms_params.start) + ms_params.length - 1)) {
292         g_log_buffer_start = ms_params.start;  // first element
293         g_log_buffer_size = ms_params.length;  // buffer size
294 
295         g_log_section_control = log_memory_section_get_control(logsec);
296     } else {
297         panic(PANIC_LOG, __LINE__);
298     }
299 }
300 
log_buffer_get_available_for_next_message(uint32_t * av)301 log_ret_t log_buffer_get_available_for_next_message(uint32_t *av)
302 {
303     log_ret_t ret_val;
304     uint32_t available = 0;
305 
306     ret_val = log_buffer_get_available(&available);
307     if (ret_val == LOG_RET_OK) {
308         if (available <= sizeof(log_buffer_header_t)) {
309             *av = 0;
310         } else {
311             *av = available - (uint32_t)sizeof(log_buffer_header_t);
312         }
313     }
314     return ret_val;
315 }
316 
317 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
318 #include "log_trigger.h"
319 
compress_log_write(const uint8_t * data,uint32_t length)320 log_ret_t compress_log_write(const uint8_t *data, uint32_t length)
321 {
322     uint32_t available;
323     log_ret_t ret_val;
324     bool trigger_flag = false;
325 
326     // Check the message length is as much the buffer size
327     if ((data == NULL) || (length > (g_log_buffer_size - 1))) {
328         return LOG_RET_ERROR_IN_PARAMETERS;
329     }
330 
331     uint32_t irq = osal_irq_lock();
332     available = 0;
333     // if it fits in the buffer add it
334     ret_val = log_buffer_get_available(&available);
335     if (ret_val == LOG_RET_OK) {
336         if (available > length) {
337             // Get the read and write indexes
338             uint32_t l_read_i = g_log_section_control->read;
339             uint32_t l_write_i = g_log_section_control->write;
340 
341             // Add the buffer & update g_log_section_control->write
342             log_buffer_helper_add(data, length);
343             // get the new write index
344             uint32_t new_write_index = g_log_section_control->write;
345             if (!((l_write_i < l_read_i) || ((new_write_index > l_write_i) || (new_write_index < l_read_i)))) {
346                 osal_irq_restore(irq);
347                 panic(PANIC_LOG, __LINE__);
348                 return LOG_RET_ERROR_OVERFLOW;
349             }
350             if (!((l_write_i >= l_read_i) || (new_write_index < l_read_i))) {
351                 osal_irq_restore(irq);
352                 panic(PANIC_LOG, __LINE__);
353 
354                 return LOG_RET_ERROR_OVERFLOW;
355             }
356             if (available >= g_log_buffer_size) {
357                 osal_irq_restore(irq);
358                 panic(PANIC_LOG, __LINE__);
359                 return LOG_RET_ERROR_OVERFLOW;
360             }
361         } else {
362             ret_val = LOG_RET_ERROR_NOT_ENOUGH_SPACE;
363         }
364         if ((g_log_buffer_size - available) > COMPRESS_LOG_TRIGGER_THRESHOLD) {
365             trigger_flag = true;
366         }
367     }
368     osal_irq_restore(irq);
369 
370     if (trigger_flag) {
371         log_trigger();
372     }
373     return ret_val;
374 }
375 #endif /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
376 
377 #ifdef BUILD_APPLICATION_STANDARD
378 
379 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
380 static uint32_t g_mass_share_mem_size;
381 static uint32_t g_mass_share_mem_start;
382 #if (BTH_WITH_SMART_WEAR == NO) && defined(SUPPORT_IPC)
383 #include "ipc.h"
384 static uint32_t g_version_number;
mass_receive_remote_info(ipc_action_t message,const volatile ipc_payload * payload,cores_t src,uint32_t id)385 static bool mass_receive_remote_info(ipc_action_t message, const volatile ipc_payload *payload,
386                                      cores_t src, uint32_t id)
387 {
388     UNUSED(message);
389     UNUSED(src);
390     UNUSED(id);
391 
392     if (payload != NULL) {
393         g_version_number = *(uint32_t *)(uintptr_t)payload;
394     }
395     return true;
396 }
397 #endif
398 
mass_buffer_init(mass_data_memory_region_section_t sec)399 void mass_buffer_init(mass_data_memory_region_section_t sec)
400 {
401     if (sec != MASS_MEMORY_REGION_SECTION_0 && sec != MASS_MEMORY_REGION_SECTION_1) {
402         return;
403     }
404     massdata_memory_region_control_t *mass_ctrl = (massdata_memory_region_control_t *)(uintptr_t)MASSDATA_REGION_START;
405     g_mass_section_control = &(mass_ctrl->section_control[sec]);
406 
407     g_mass_share_mem_start = g_mass_section_control->region_start;
408     g_mass_share_mem_size = g_mass_section_control->region_len;
409     g_mass_section_control->water_line = g_mass_share_mem_size / CHR_BUFFER_WL_RATIO;
410 #if (BTH_WITH_SMART_WEAR == NO)
411     ipc_register_handler(IPC_ACTION_MASS_DATA_INFORM, mass_receive_remote_info);
412 #endif
413 }
414 #endif
415 
416 #if (BTH_WITH_SMART_WEAR == YES) && defined(SUPPORT_IPC)
417 #include "ipc.h"
418 #include "ipc_actions.h"
419 
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint8_t info3)420 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
421 {
422 #if (CORE == BT)
423     ipc_payload_mass_data_type chr_info;
424     chr_info.type = MASS_ERROR_POINT;
425     chr_info.event_id = event_id;
426     chr_info.info1 = info1;
427     chr_info.info2 = info2;
428     chr_info.info3 = info3;
429 
430     (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
431                                         IPC_ACTION_MASS_DATA_INFORM,
432                                         (ipc_payload *)((void *)&chr_info),
433                                         sizeof(chr_info),
434                                         IPC_PRIORITY_LOWEST,
435                                         false,
436                                         0);
437 #else
438     UNUSED(event_id);
439     UNUSED(info1);
440     UNUSED(info2);
441     UNUSED(info3);
442 #endif
443 }
444 
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint8_t info3)445 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
446 {
447 #if (CORE == BT)
448     ipc_payload_mass_data_type chr_info;
449     chr_info.type = MASS_EVENT_POINT;
450     chr_info.event_id = event_id;
451     chr_info.info1 = info1;
452     chr_info.info2 = info2;
453     chr_info.info3 = info3;
454 
455     (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
456                                         IPC_ACTION_MASS_DATA_INFORM,
457                                         (ipc_payload *)((void *)&chr_info),
458                                         sizeof(chr_info),
459                                         IPC_PRIORITY_LOWEST,
460                                         false,
461                                         0);
462 #else
463     UNUSED(event_id);
464     UNUSED(info1);
465     UNUSED(info2);
466     UNUSED(info3);
467 #endif
468 }
469 
massdata_record_system_info_with_extend(chr_extend_data_t * extend_data)470 void massdata_record_system_info_with_extend(chr_extend_data_t *extend_data)
471 {
472     if ((extend_data == NULL) ||
473         (extend_data->type != MASS_EVENT_POINT_EXTEND && extend_data->type != MASS_ERROR_POINT_EXTEND)) {
474         panic(PANIC_LOG, MASS_EVENT_POINT_EXTEND);
475         return ;
476     }
477     ipc_payload_mass_data_extend_type chr_data = { 0 };
478     chr_data.mass_data.type = extend_data->type;
479     chr_data.mass_data.event_id = extend_data->event_id;
480     chr_data.mass_data.info1 = extend_data->info1;
481     chr_data.mass_data.info2 = extend_data->info2;
482     chr_data.mass_data.info3 = extend_data->info3;
483     chr_data.data_len = extend_data->data_len;
484     if (memcpy_s(chr_data.data, CHR_EXTEND_PARAM_MAX_LEN, extend_data->data, extend_data->data_len) != EOK) {
485         panic(PANIC_LOG, __LINE__);
486         return ;
487     }
488 
489     (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
490                                         IPC_ACTION_MASS_DATA_INFORM_WITH_EXTEND,
491                                         (ipc_payload *)((void *)&chr_data),
492                                         sizeof(ipc_payload_mass_data_extend_type),
493                                         IPC_PRIORITY_LOWEST,
494                                         false,
495                                         0);
496 }
497 
498 #else
499 #include "log_trigger.h"
500 #include "systick.h"
501 #include "log_printf.h"
502 
503 #define TWS_MASSDATA_MAGIC_NUMBER 0xAA
504 
505 #if (CORE == APPS)
506 #if (ENABLE_MASSDATA_RECORD == YES)
507 static uint32_t g_version_number;
508 #endif
chr_record_ue(uint8_t eid,uint8_t sub_eid,uint8_t code,uint32_t sub_code)509 void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
510 {
511 #if (ENABLE_MASSDATA_RECORD == YES)
512 #define MS_PER_SECOND 1000
513     uint32_t ret;
514     size_t size;
515     uint8_t eid_shift = 8;
516 
517     system_event_s_t ue_point;
518     ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
519     ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
520     ue_point.event_info = code;
521     ue_point.sub_event_info = sub_code;
522     ue_point.chr_up_type = CHR_UE_JSON;
523     ue_point.version = g_version_number;
524     ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
525 
526     size = sizeof(system_event_s_t);
527     ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, (uint32_t)size);
528     if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
529         massdata_triger_queue((uint8_t *)&ue_point, MASS_EVENT_POINT);
530     }
531 #undef MS_PER_SECOND
532 #else
533     UNUSED(eid);
534     UNUSED(sub_eid);
535     UNUSED(code);
536     UNUSED(sub_code);
537 #endif
538 }
539 
massdata_triger_queue(const uint8_t * pay_i,uint32_t type)540 uint32_t massdata_triger_queue(const uint8_t *pay_i, uint32_t type)
541 {
542     UNUSED(pay_i);
543     UNUSED(type);
544     return 0;
545 }
546 
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)547 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
548 {
549 #if (ENABLE_MASSDATA_RECORD == YES)
550 #define MS_PER_SECOND 1000
551     uint32_t ret;
552     size_t size;
553 
554     system_error_s_t error_seg;
555     error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
556     error_seg.event_id = get_event_id(event_id, info1);
557     error_seg.event_info = info2;
558     error_seg.sub_event_info = info3;
559     error_seg.chr_up_type = CHR_DFT;
560     error_seg.version = g_version_number;
561     error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
562 
563     size = sizeof(system_error_s_t);
564     ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, (uint32_t)size);
565     if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
566         massdata_triger_queue((uint8_t *)&error_seg, MASS_EVENT_POINT);
567     }
568 #undef MS_PER_SECOND
569     return;
570 #else
571     UNUSED(event_id);
572     UNUSED(info1);
573     UNUSED(info2);
574     UNUSED(info3);
575 #endif
576 }
577 
578 
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)579 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
580 {
581 #if (ENABLE_MASSDATA_RECORD == YES)
582 #define MS_PER_SECOND 1000
583     uint32_t ret;
584     system_event_s_t event_seg;
585     size_t size;
586 
587     event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
588     event_seg.event_id = get_event_id(event_id, info1);
589     event_seg.event_info = info2;
590     event_seg.sub_event_info = info3;
591     event_seg.chr_up_type = CHR_DFT;
592     event_seg.version = g_version_number;
593     event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
594 
595     size = sizeof(system_event_s_t);
596 
597     ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, (uint32_t)size);
598     if (ret == MASS_OVER_BUFFER_THD || ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE) {
599         massdata_triger_queue((uint8_t *)&event_seg, MASS_EVENT_POINT);
600     }
601 #undef MS_PER_SECOND
602     return;
603 #else
604     UNUSED(event_id);
605     UNUSED(info1);
606     UNUSED(info2);
607     UNUSED(info3);
608 #endif
609 }
610 
611 #elif (CORE == BT)
612 static uint8_t g_role_state;
613 static uint32_t g_mass_write_psn = 0;
614 
massdata_set_role(uint8_t role)615 void massdata_set_role(uint8_t role)
616 {
617     g_role_state = role;
618 }
619 
chr_record_ue(uint8_t eid,uint8_t sub_eid,uint8_t code,uint32_t sub_code)620 void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
621 {
622 #define MS_PER_SECOND 1000
623     uint32_t ret;
624     uint32_t size;
625     uint8_t eid_shift = 8;
626 
627     system_event_s_t ue_point;
628     ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
629     ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
630     ue_point.event_info = code;
631     ue_point.sub_event_info = (uint32_t)sub_code;
632     ue_point.chr_up_type = CHR_UE_JSON;
633     ue_point.version = g_version_number;
634     ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
635     ue_point.role = g_role_state;
636 
637     uint32_t irq = osal_irq_lock();
638     ue_point.psn = g_mass_write_psn++;
639     osal_irq_restore(irq);
640 
641     size = sizeof(system_event_s_t);
642     ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, size);
643     if (ret == MASS_OVER_BUFFER_THD) {
644         massdata_trigger((void *)&ue_point, CORE, MASS_EVENT_POINT);
645     }
646 
647 #undef MS_PER_SECOND
648 }
649 
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)650 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
651 {
652 #define MS_PER_SECOND 1000
653     uint32_t ret;
654     uint32_t size;
655 
656     system_error_s_t error_seg;
657     error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
658     error_seg.event_id = get_event_id(event_id, info1);
659     error_seg.event_info = info2;
660     error_seg.sub_event_info = (uint32_t)info3;
661     error_seg.chr_up_type = CHR_DFT;
662     error_seg.version = g_version_number;
663     error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
664     error_seg.role = g_role_state;
665 
666     uint32_t irq = osal_irq_lock();
667     error_seg.psn = g_mass_write_psn++;
668     osal_irq_restore(irq);
669 
670     size = sizeof(system_error_s_t);
671     ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, size);
672     if (ret == MASS_OVER_BUFFER_THD) {
673         massdata_trigger((void *)&error_seg, CORE, MASS_EVENT_POINT);
674     }
675 
676 #undef MS_PER_SECOND
677 
678     return;
679 }
680 
681 
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)682 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
683 {
684 #define MS_PER_SECOND 1000
685     uint32_t ret;
686     uint16_t size;
687 
688     system_event_s_t event_seg;
689     event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
690     event_seg.event_id = get_event_id(event_id, info1);
691     event_seg.event_info = info2;
692     event_seg.sub_event_info = (uint32_t)info3;
693     event_seg.chr_up_type = CHR_DFT;
694     event_seg.version = g_version_number;
695     event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
696     event_seg.role = g_role_state;
697 
698     uint32_t irq = osal_irq_lock();
699     event_seg.psn = g_mass_write_psn++;
700     osal_irq_restore(irq);
701 
702     size = sizeof(system_event_s_t);
703 
704     ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, size);
705     if (ret == MASS_OVER_BUFFER_THD) {
706         massdata_trigger((void *)&event_seg, CORE, MASS_EVENT_POINT);
707     }
708 
709 #undef MS_PER_SECOND
710     return;
711 }
712 
713 #endif
714 #endif
715 
716 // write mass data to share mem roll buffer, index by core type
717 #if (ENABLE_MASSDATA_RECORD == YES)
mass_data_write_roll_buffer(const uint8_t * data,uint32_t length)718 uint32_t mass_data_write_roll_buffer(const uint8_t *data, uint32_t length)
719 {
720     uint32_t remain_size, to_end, read, write, size, water_line;
721     errno_t ret;
722 
723     // check the message length is as much the buffer size
724     if ((data == NULL) || (g_mass_section_control == NULL)) { return MASS_RET_ERROR_IN_PARAMETERS; }
725 
726     uint32_t irq = osal_irq_lock();
727     read = g_mass_section_control->read;
728     write = g_mass_section_control->write;
729     size = g_mass_section_control->region_len;
730     to_end = size - write;
731 
732     // check if mem overflow
733     if ((read > g_mass_share_mem_size) || (write > g_mass_share_mem_size) || (size > g_mass_share_mem_size) ||
734         (g_mass_section_control->region_start != g_mass_share_mem_start)) {
735         // recorvy mem offset
736         g_mass_section_control->read = 0;
737         g_mass_section_control->write = 0;
738         g_mass_section_control->region_start = g_mass_share_mem_start;
739         g_mass_section_control->region_len = g_mass_share_mem_size;
740         osal_irq_restore(irq);
741         return MASS_RET_ERROR_CORRUPT_SHARED_MEMORY;
742     }
743 
744     remain_size = (read <= write) ? (size - (write - read + 1)) : (read - write - 1);
745     water_line = g_mass_section_control->water_line;
746 
747     if (remain_size < length) {
748         osal_irq_restore(irq);
749         return MASS_RET_ERROR_NOT_ENOUGH_SPACE;
750     }
751 
752     if (length <= to_end) {
753         ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, length);
754         if (ret != EOK) {
755             osal_irq_restore(irq);
756             return MASS_MEM_COPY_FAIL;
757         }
758     } else {
759         ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, to_end);
760         if (ret != EOK) {
761             osal_irq_restore(irq);
762             return MASS_MEM_COPY_FAIL;
763         }
764         ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start)),
765             length - to_end, data + to_end, length - to_end);
766         if (ret != EOK) {
767             osal_irq_restore(irq);
768             return MASS_MEM_COPY_FAIL;
769         }
770     }
771 
772     write = (write + length) % size;
773 
774     g_mass_section_control->write = write;
775 
776     osal_irq_restore(irq);
777 
778     if (remain_size < water_line) { return MASS_OVER_BUFFER_THD; }
779 
780     return MASS_RET_OK;
781 }
782 
log_buffer_record_system_event(uint32_t chr_event)783 void log_buffer_record_system_event(uint32_t chr_event)
784 {
785     if (chr_event == CHR_VALUE_NULL) {
786         return;
787     }
788 
789     uint8_t event_id;
790     uint8_t info1;
791     uint8_t info2;
792     uint8_t info3;
793 
794     event_id = (chr_event >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
795     info1 = (chr_event >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
796     info2 = (chr_event >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
797     info3 = chr_event & CHR_VALUE_MASK;
798 
799     massdata_record_system_event(event_id, info1, info2, info3);
800 }
801 
log_buffer_record_system_error(uint32_t chr_error)802 void log_buffer_record_system_error(uint32_t chr_error)
803 {
804     if (chr_error == CHR_VALUE_NULL) {
805         return;
806     }
807 
808     uint8_t error_id;
809     uint8_t info1;
810     uint8_t info2;
811     uint8_t info3;
812 
813     error_id = (chr_error >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
814     info1 = (chr_error >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
815     info2 = (chr_error >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
816     info3 = chr_error & CHR_VALUE_MASK;
817 
818     massdata_record_system_error(error_id, info1, info2, info3);
819 }
820 #endif
821 #endif
822