• 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: diag memory read and write
15  * This file should be changed only infrequently and with great care.
16  */
17 
18 #include "diag_cmd_mem_read_write.h"
19 #include "securec.h"
20 #include "diag_cmd_mem_read_write_st.h"
21 #include "soc_diag_cmd_id.h"
22 #include "errcode.h"
23 
24 #define REPORT_DATA_PER_SIZE 64
25 
26 typedef struct {
27     mem_read_ind_head_t head;
28     uint8_t data[REPORT_DATA_PER_SIZE];
29 } mem_read_ind_common_t;
30 
diag_cmd_permit_read(uintptr_t start_addr,uintptr_t end_addr)31 __attribute__((weak)) bool diag_cmd_permit_read(uintptr_t start_addr, uintptr_t end_addr)
32 {
33     unused(start_addr);
34     unused(end_addr);
35     return true;
36 }
37 
diag_cmd_permit_write(uintptr_t start_addr,uintptr_t end_addr)38 __attribute__((weak)) bool diag_cmd_permit_write(uintptr_t start_addr, uintptr_t end_addr)
39 {
40     unused(start_addr);
41     unused(end_addr);
42     return true;
43 }
44 
diag_cmd_mem32(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)45 errcode_t diag_cmd_mem32(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
46 {
47     unused(cmd_param_size);
48     mem_read_cmd_t cmd;
49     mem_read32_ind_t ind;
50     uint32_t num = 0;
51     (void)memcpy_s(&cmd, sizeof(mem_read_cmd_t), cmd_param, sizeof(mem_read_cmd_t));
52     (void)memset_s(&ind, sizeof(mem_read32_ind_t), 0, sizeof(mem_read32_ind_t));
53     uintptr_t end_addr = cmd.start_addr + (cmd.cnt * sizeof(uint32_t));
54     if (diag_cmd_permit_read(cmd.start_addr, end_addr) == false) {
55         return ERRCODE_FAIL;
56     }
57 
58     ind.head.start_addr = cmd.start_addr;
59     while (ind.head.start_addr < end_addr) {
60         ind.head.start_addr = ind.head.start_addr + num * sizeof(uint32_t);
61         ind.head.size = uapi_min(end_addr - ind.head.start_addr, REPORT_DATA_PER_SIZE);
62         num = ind.head.size / (uint32_t)sizeof(uint32_t);
63         for (uint32_t c = 0; c < num; c++) {
64             uintptr_t addr = ind.head.start_addr + (c * sizeof(uint32_t));
65             uapi_reg_read32(addr, ind.data[c]);
66         }
67         (void)uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind,
68                                       (uint16_t)sizeof(mem_read_ind_head_t) + (uint16_t)ind.head.size, true);
69     }
70     return ERRCODE_SUCC;
71 }
72 
diag_cmd_mem16(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)73 errcode_t diag_cmd_mem16(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
74 {
75     mem_read_cmd_t cmd;
76     mem_read16_ind_t ind;
77     uint32_t num = 0;
78     (void)memcpy_s(&cmd, sizeof(mem_read_cmd_t), cmd_param, sizeof(mem_read_cmd_t));
79     (void)memset_s(&ind, sizeof(mem_read16_ind_t), 0, sizeof(mem_read16_ind_t));
80     uintptr_t end_addr = cmd.start_addr + (cmd.cnt * sizeof(uint16_t));
81     if (diag_cmd_permit_read(cmd.start_addr, end_addr) == false) {
82         return ERRCODE_FAIL;
83     }
84     unused(cmd_param_size);
85     ind.head.start_addr = cmd.start_addr;
86     while (ind.head.start_addr < end_addr) {
87         ind.head.start_addr = ind.head.start_addr + num * sizeof(uint16_t);
88         ind.head.size = uapi_min(end_addr - ind.head.start_addr, REPORT_DATA_PER_SIZE);
89         num = ind.head.size / (uint32_t)sizeof(uint16_t);
90         for (uint32_t c = 0; c < num; c++) {
91             uintptr_t addr = ind.head.start_addr + (c * sizeof(uint16_t));
92             uapi_reg_read16(addr, ind.data[c]);
93         }
94         (void)uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind,
95                                       (uint16_t)sizeof(mem_read_ind_head_t) + (uint16_t)ind.head.size, true);
96     }
97     return ERRCODE_SUCC;
98 }
99 
diag_cmd_mem8(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)100 errcode_t diag_cmd_mem8(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
101 {
102     mem_read_cmd_t cmd;
103     mem_read8_ind_t ind;
104     uint32_t num = 0;
105     (void)memcpy_s(&cmd, sizeof(mem_read_cmd_t), cmd_param, sizeof(mem_read_cmd_t));
106     (void)memset_s(&ind, sizeof(mem_read8_ind_t), 0, sizeof(mem_read8_ind_t));
107     uintptr_t end_addr = cmd.start_addr + (cmd.cnt * sizeof(uint8_t));
108     if (diag_cmd_permit_read(cmd.start_addr, end_addr) == false) {
109         return ERRCODE_FAIL;
110     }
111     unused(cmd_param_size);
112     ind.head.start_addr = cmd.start_addr;
113     while (ind.head.start_addr < end_addr) {
114         ind.head.start_addr = ind.head.start_addr + num * sizeof(uint8_t);
115         ind.head.size = uapi_min(end_addr - ind.head.start_addr, REPORT_DATA_PER_SIZE);
116         num = ind.head.size / (uint32_t)sizeof(uint8_t);
117         for (uint32_t c = 0; c < num; c++) {
118             uintptr_t addr = ind.head.start_addr + (c * sizeof(uint8_t));
119             uapi_reg_read8(addr, ind.data[c]);
120         }
121         (void)uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind,
122                                       (uint16_t)sizeof(mem_read_ind_head_t) + (uint16_t)ind.head.size, true);
123     }
124     return ERRCODE_SUCC;
125 }
126 
diag_cmd_w1(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)127 errcode_t diag_cmd_w1(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
128 {
129     mem_write_cmd_t cmd;
130     mem_write_ind_t ind;
131     unused(cmd_param_size);
132 
133     (void)memcpy_s(&cmd, sizeof(mem_write_cmd_t), cmd_param, sizeof(mem_read_cmd_t));
134     uapi_reg_write8(cmd.start_addr, (uint8_t)cmd.val);
135 
136     ind.ret = ERRCODE_SUCC;
137     uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind, (uint16_t)sizeof(mem_write_ind_t), true);
138     return ERRCODE_SUCC;
139 }
140 
diag_cmd_w2(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)141 errcode_t diag_cmd_w2(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
142 {
143     mem_write_cmd_t cmd;
144     mem_write_ind_t ind;
145     unused(cmd_param_size);
146 
147     (void)memcpy_s(&cmd, sizeof(mem_write_cmd_t), cmd_param, sizeof(mem_write_cmd_t));
148     uapi_reg_write16(cmd.start_addr, (uint16_t)cmd.val);
149 
150     ind.ret = ERRCODE_SUCC;
151     uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind, (uint16_t)sizeof(mem_write_ind_t), true);
152     return ERRCODE_SUCC;
153 }
154 
diag_cmd_w4(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)155 errcode_t diag_cmd_w4(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
156 {
157     mem_write_cmd_t cmd;
158     mem_write_ind_t ind;
159     unused(cmd_param_size);
160 
161     (void)memcpy_s(&cmd, sizeof(mem_write_cmd_t), cmd_param, sizeof(mem_write_cmd_t));
162     uapi_reg_write32(cmd.start_addr, cmd.val);
163 
164     ind.ret = ERRCODE_SUCC;
165     uapi_diag_report_packet(cmd_id, option, (uint8_t *)&ind, (uint16_t)sizeof(mem_write_ind_t), true);
166     return ERRCODE_SUCC;
167 }
168 
diag_cmd_mem_operate(uint16_t cmd_id,void * cmd_param,uint16_t cmd_param_size,diag_option_t * option)169 errcode_t diag_cmd_mem_operate(uint16_t cmd_id, void *cmd_param, uint16_t cmd_param_size, diag_option_t *option)
170 {
171     switch (cmd_id) {
172         case DIAG_CMD_MEM_MEM32:
173             return diag_cmd_mem32(cmd_id, cmd_param, cmd_param_size, option);
174         case DIAG_CMD_MEM_MEM16:
175             return diag_cmd_mem16(cmd_id, cmd_param, cmd_param_size, option);
176         case DIAG_CMD_MEM_MEM8:
177             return diag_cmd_mem8(cmd_id, cmd_param, cmd_param_size, option);
178         case DIAG_CMD_MEM_W1:
179             return diag_cmd_w1(cmd_id, cmd_param, cmd_param_size, option);
180         case DIAG_CMD_MEM_W2:
181             return diag_cmd_w2(cmd_id, cmd_param, cmd_param_size, option);
182         case DIAG_CMD_MEM_W4:
183             return diag_cmd_w4(cmd_id, cmd_param, cmd_param_size, option);
184         default:
185             return ERRCODE_NOT_SUPPORT;
186     }
187 }
188