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 REG DUMP MODULE
15 * Author:
16 * Create: 2020-09-15
17 */
18
19 #include "log_reg_dump.h"
20 #include "chip_io.h"
21 #include "panic.h"
22 #include "log_oam_logger.h"
23 #include "log_oml_exception.h"
24 #include "log_trigger.h"
25
26 #if (defined (BUILD_APPLICATION_STANDARD) || defined (TEST_SUITE) || defined(BUILD_SENSOR_STANDARD))
27 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == NO)
28 typedef struct {
29 uint32_t start_addr;
30 uint32_t end_addr;
31 } log_reg_dump_t;
32
33 // Dump register address config
34 static log_reg_dump_t g_dump_addr[] = {
35 { 0x57004000, 0x570047e0 }, // PMU1_CTL
36 { 0x57008000, 0x57008490 }, // PMU2_CTL
37 { 0x5702c000, 0x5702c418 }, // ULP_AON_CTL
38 };
39
40 #define FLAG_COUNT_SIZE 4
41 #define REG_OFFSET 4
42 #define FLAG_COUNT_OFFSET (FLAG_COUNT_SIZE - 1)
43 // ram_size = reg len + g_dump_reg_separate_flag size
44 #define RAM_SIZE_LEN (FLAG_COUNT_SIZE + 2)
45 #define RAM_SIZE_CALCULATION 2
46 // This is the index of the log dump
47 static uint8_t g_dump_reg_separate_flag[FLAG_COUNT_SIZE] = { 0xAA, 0xBB, 0xCC, 0x0 };
48 static bool g_dump_table_check_success = false;
49
log_exception_dump_reg_check(void)50 void log_exception_dump_reg_check(void)
51 {
52 uint32_t start_addr_check, end_addr_check, len_check;
53 uint16_t count = (uint16_t)sizeof(g_dump_addr) / (uint16_t)sizeof(g_dump_addr[0]);
54
55 for (uint16_t i = 0; i < count; i++) {
56 start_addr_check = (g_dump_addr[i].start_addr & 0xf) % REG_OFFSET;
57 end_addr_check = (g_dump_addr[i].end_addr & 0xf) % REG_OFFSET;
58 len_check = (g_dump_addr[i].end_addr - g_dump_addr[i].start_addr) % REG_OFFSET;
59 if ((start_addr_check != 0) || (end_addr_check != 0) || (len_check != 0)) {
60 panic(PANIC_LOG_DUMP, __LINE__);
61 }
62 }
63
64 g_dump_table_check_success = true;
65 }
66
log_exception_dump_print(uint32_t start_addr,uint32_t end_addr)67 static void log_exception_dump_print(uint32_t start_addr, uint32_t end_addr)
68 {
69 om_msg_header_stru_t msg_header = { 0 };
70 uint8_t msg_tail = OM_FRAME_DELIMITER;
71 // ram_size = reg len + g_dump_reg_separate_flag size
72 uint16_t ram_size = (uint16_t)((end_addr - start_addr) / RAM_SIZE_CALCULATION + RAM_SIZE_LEN);
73 uint16_t reg_value, length;
74 bool is_first = true;
75 uint32_t start_addr_tmp = start_addr;
76
77 msg_header.frame_start = OM_FRAME_DELIMITER;
78 msg_header.func_type = OM_MSG_TYPE_LAST;
79 msg_header.prime_id = OM_LOG_SAVE_STACK;
80
81 while (ram_size > 0) {
82 length = MIN(ram_size, DUMP_MAX_LENGTH_PER_TRANS);
83 msg_header.frame_len = (uint16_t)(sizeof(om_msg_header_stru_t) + length + sizeof(msg_tail));
84 /* Send exception stack */
85 log_exception_send_data((uint8_t *)(&msg_header), sizeof(om_msg_header_stru_t));
86 if (is_first) {
87 // Send g_dump_reg_separate_flag
88 log_exception_send_data((uint8_t *)(uintptr_t)g_dump_reg_separate_flag, sizeof(g_dump_reg_separate_flag));
89 is_first = false;
90 length -= (uint16_t)sizeof(g_dump_reg_separate_flag);
91 ram_size -= (uint16_t)sizeof(g_dump_reg_separate_flag);
92 }
93 for (uint16_t i = 0; i < length;) {
94 // Send register value
95 reg_value = readw(start_addr_tmp);
96 log_exception_send_data((uint8_t *)®_value, sizeof(reg_value));
97 // Next reg addr
98 start_addr_tmp += REG_OFFSET;
99 i += (uint16_t)sizeof(reg_value);
100 }
101 log_exception_send_data((uint8_t *)(&msg_tail), sizeof(msg_tail));
102
103 ram_size -= length;
104 }
105
106 // Flush log before reboot.
107 log_trigger();
108 }
109
log_exception_dump_reg(void)110 void log_exception_dump_reg(void)
111 {
112 if (!g_dump_table_check_success) {
113 return;
114 }
115
116 uint16_t count = (uint16_t)sizeof(g_dump_addr) / (uint16_t)sizeof(log_reg_dump_t);
117
118 for (uint8_t i = 0; i < count; i++) {
119 // Count flag value
120 g_dump_reg_separate_flag[FLAG_COUNT_OFFSET] = i;
121 log_exception_dump_print(g_dump_addr[i].start_addr, g_dump_addr[i].end_addr);
122 }
123 }
124 #endif
125 #endif