1 /*
2  *  Routines to access hardware
3  *
4  *  Copyright (c) 2013 Realtek Semiconductor Corp.
5  *
6  *  This module is a confidential and proprietary property of RealTek and
7  *  possession or use of this module requires written permission of RealTek.
8  */
9 
10 #include "ameba_soc.h"
11 
12 #pragma GCC diagnostic push
13 #pragma GCC diagnostic ignored "-Wunused-parameter"
14 
15 //======================================================
16 //<Function>:  CmdTest
17 //<Usage   >:  This function is a demo test function.
18 //<Argus    >:  argc --> number of argus
19 //                   argv --> pointer to a cmd parameter array
20 //<Return   >:  VOID
21 //<Notes    >:  NA
22 //======================================================
23 
24 static u32 cmd_rom_help(u16 argc, u8  *argv[]);
25 
26 SHELL_ROM_TEXT_SECTION
cmd_dump_word(u16 argc,u8 * argv[])27 u32 cmd_dump_word(u16 argc, u8  *argv[])
28 {
29 	u32 Src;
30 	//u32 Len,LenIndex;
31 	u32 OTF_Enable = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG3) & BIT_SYS_FLASH_ENCRYPT_EN;
32 
33 	if(argc<1)
34 	{
35 		MONITOR_LOG("Wrong argument number!\r\n");
36 		return _FALSE;
37 	}
38 
39 	if(argv[0]) {
40 		Src= _strtoul((const char*)(argv[0]), (char **)NULL, 16);
41 	} else {
42 		MONITOR_LOG("Wrong argument number!\r\n");
43 		return _FALSE;
44 	}
45 
46 	//if(!argv[1])
47 	//	Len = 1;
48 	//else
49 	//	Len = _strtoul((const char*)(argv[1]), (char **)NULL, 10);
50 
51 	Src &= ~(0x03);
52 
53 	/* read encrypt image for FW protection */
54 	if ((Src & 0x08000000) != 0) {
55 		if (OTF_Enable != 0) {
56 			RSIP_OTF_Cmd(DISABLE);
57 		}
58 	}
59 
60 	MONITOR_LOG("%08X: %08X \n", Src, *(u32 *)(Src));
61 
62 	if ((Src & 0x08000000) != 0) {
63 		if (OTF_Enable != 0) {
64 			RSIP_OTF_Cmd(ENABLE);
65 			Cache_Flush();
66 		}
67 	}
68 
69 	return _TRUE;
70 
71 }
72 
73 SHELL_ROM_TEXT_SECTION
cmd_write_word(u16 argc,u8 * argv[])74 u32 cmd_write_word(u16 argc, u8  *argv[])
75 {
76 
77 	u32 Src;
78 	u32 Value;
79 
80 	Src = _strtoul((const char*)(argv[0]), (char **)NULL, 16);
81 
82 	Src &= ~(0x03);
83 
84 	Value= _strtoul((const char*)(argv[1]), (char **)NULL, 16);
85 	MONITOR_LOG("%08X: %08X \n", Src, Value);
86 
87 	*(volatile u32 *)(Src) = Value;
88 
89 	return 0;
90 }
91 
92 SHELL_ROM_TEXT_SECTION
cmd_flash(u16 argc,u8 * argv[])93 u32 cmd_flash(u16 argc,  u8  *argv[])
94 {
95 	if (_strcmp((const char*)argv[0], "erase") == 0) {/* SPI Flash Chip Erase Command */
96 		u32 AddrTemp = 0;
97 
98 		MONITOR_LOG("Erase Falsh Start\n");
99 
100 		AddrTemp = _strtoul((const char*)(argv[2]), (char **)NULL, 16);
101 
102 		if (_strcmp((const char*)argv[1], "chip") == 0) {
103 			MONITOR_LOG("Erase Chip start!!\n");
104 
105 			FLASH_Erase(EraseChip, 0);
106 
107 			MONITOR_LOG("Erase Chip success!!\n");
108 		} else if (_strcmp((const char*)argv[1], "block") == 0) {
109 			MONITOR_LOG("Erase block = %x\n",(AddrTemp));
110 
111 			FLASH_Erase(EraseBlock, AddrTemp);
112 
113 			MONITOR_LOG("Erase block success!!\n");
114 		} else if (_strcmp((const char*)argv[1], "sector") == 0) {
115 			MONITOR_LOG("Erase Sector = %x\n",(AddrTemp));
116 
117 			FLASH_Erase(EraseSector, AddrTemp);
118 
119 			MONITOR_LOG("Erase Sector success!!\n");
120 		}
121 
122 		/* for calibration use */
123 		FLASH_TxData12B(0, 4, (u8*)SPIC_CALIB_PATTERN);
124 		Cache_Flush();
125 
126 		MONITOR_LOG("Erase Falsh End\n");
127 	}
128 
129 	if (_strcmp((const char*)argv[0], "read") == 0) {
130 		u32 address = 0;
131 		u32 len = 0;
132 		u32 idx = 0;
133 		u32 OTF_Enable = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG3) & BIT_SYS_FLASH_ENCRYPT_EN;
134 
135 		MONITOR_LOG("Falsh read\n");
136 
137 		/* read encrypt image for FW protection */
138 		if (OTF_Enable) {
139 			RSIP_OTF_Cmd(DISABLE);
140 		}
141 
142 		address = _strtoul((const char*)(argv[1]), (char **)NULL, 16);
143 		len = _strtoul((const char*)(argv[2]), (char **)NULL, 10)/4;
144 
145 		for (idx = 0; idx < len; idx++) {
146 			MONITOR_LOG("%08x: %08x %08x  %08x %08x \n", address, HAL_READ32(SPI_FLASH_BASE, address),
147 				HAL_READ32(SPI_FLASH_BASE, address+4), HAL_READ32(SPI_FLASH_BASE, address+8),
148 				HAL_READ32(SPI_FLASH_BASE, address+12));
149 			address = address + 16;
150 		}
151 
152 		if (OTF_Enable) {
153 			RSIP_OTF_Cmd(ENABLE);
154 			Cache_Flush();
155 		}
156 	}
157 
158 	if (_strcmp((const char*)argv[0], "write") == 0) {
159 		u32 address = 0;
160 		u32 data = 0;
161 
162 		address = _strtoul((const char*)(argv[1]), (char **)NULL, 16);
163 		data = _strtoul((const char*)(argv[2]), (char **)NULL, 16);
164 
165 		MONITOR_LOG("Falsh write addr:%x data:%x \n", address, data);
166 
167 		FLASH_TxData12B(address, 4, (u8*)&data); //max is 12
168 		Cache_Flush();
169 	}
170 
171 	if (_strcmp((const char*)argv[0], "status") == 0) {
172 		u8 status[2];
173 		u8 wstatus = _strtoul((const char*)(argv[2]), (char **)NULL, 16);
174 
175 		if (_strcmp((const char*)argv[1], "get") == 0) {
176 			FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_status, 1, &status[0]);
177 			if (flash_init_para.FLASH_Status2_exist) {
178 				FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_status2, 1, &status[1]);
179 			}
180 
181 			MONITOR_LOG("status: %x %x\n", status[0], status[1]);
182 		}
183 
184 		if (_strcmp((const char*)argv[1], "set1") == 0) {
185 			FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status, 1, &wstatus);
186 		}
187 
188 		if (_strcmp((const char*)argv[1], "set2") == 0) {
189 			if(!flash_init_para.FLASH_cmd_wr_status2){
190 				FLASH_RxCmd(flash_init_para.FLASH_cmd_rd_status, 1, &status[0]);
191 				status[1] = wstatus;
192 
193 				FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status, 2, status);
194 			}else{
195 				FLASH_SetStatus(flash_init_para.FLASH_cmd_wr_status2, 1, &wstatus);
196 			}
197 		}
198 	}
199 
200 	if (_strcmp((const char*)argv[0], "cache") == 0) {
201 		if (_strcmp((const char*)argv[1], "disable") == 0) {
202 			MONITOR_LOG("cache disable \n");
203 			Cache_Enable(DISABLE);
204 		} else if (_strcmp((const char*)argv[1], "enable") == 0) {
205 			MONITOR_LOG("cache enable \n");
206 			Cache_Enable(ENABLE);
207 		} else if (_strcmp((const char*)argv[1], "flush") == 0) {
208 			MONITOR_LOG("cache flush \n");
209 			Cache_Flush();
210 		}
211 	}
212 
213 	return 0;
214 }
215 
216 SHELL_ROM_TEXT_SECTION
cmd_efuse(u16 argc,u8 * argv[])217 u32 cmd_efuse(u16 argc, u8  *argv[])
218 {
219 	u8 EfuseBuf[1024];
220 	u32 index;
221 	u8 ret = 0;
222 
223 	/* efuse wmap 0x0 2 2187 */
224 	/* efuse wmap 0x18 4 01020304 */
225 	if (_strcmp((const char*)argv[0], "wmap") == 0) {
226 		u32 Addr = _strtoul((const char*)(argv[1]), (char **)NULL, 16);
227 		u32 Len = _strtoul((const char*)(argv[2]), (char **)NULL, 16);
228 		char* DString = (char*)argv[3];
229 		u32 Cnt;
230 
231 		Cnt = _strlen(DString);
232 		if (Cnt%2) {
233 			MONITOR_LOG("string length(%d) should be odd \n", Cnt);
234 			return FALSE;
235 		}
236 
237 		Cnt = Cnt/2;
238 		if (Cnt != Len) {
239 			MONITOR_LOG("Oops: write lenth not match input string lentg, choose smaller one\n");
240 			Len = (Cnt < Len) ? Cnt:Len;
241 		}
242 
243 		MONITOR_LOG("efuse wmap write len:%d, string len:%d\n", Len, Cnt << 1);
244 
245 		for (index= 0; index < Len; index++) {
246 			EfuseBuf[index] = _2char2hex(DString[index*2], DString[index*2+1]);
247 		}
248 
249 		EFUSE_LMAP_WRITE(Addr, Len, (u8 *)(EfuseBuf));
250 	}
251 
252 	if (_strcmp((const char*)argv[0], "rmap") == 0) {
253 		MONITOR_LOG("efuse rmap \n");
254 
255 		ret = EFUSE_LogicalMap_Read(EfuseBuf);
256 		if (ret == _FAIL) {
257 			MONITOR_LOG("EFUSE_LogicalMap_Read fail \n");
258 		}
259 
260 		for (index = 0; index < 1024; index+=16) {
261 			MONITOR_LOG("EFUSE[%03x]: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", index,
262 				EfuseBuf[index], EfuseBuf[index+1], EfuseBuf[index+2], EfuseBuf[index+3],
263 				EfuseBuf[index+4], EfuseBuf[index+5], EfuseBuf[index+6], EfuseBuf[index+7],
264 				EfuseBuf[index+8], EfuseBuf[index+9], EfuseBuf[index+10], EfuseBuf[index+11],
265 				EfuseBuf[index+12], EfuseBuf[index+13], EfuseBuf[index+14], EfuseBuf[index+15]);
266 		}
267 	}
268 
269 	if (_strcmp((const char*)argv[0], "rraw") == 0) {
270 		MONITOR_LOG("efuse rraw\n");
271 
272 		for (index = 0; index< EFUSE_REAL_CONTENT_LEN; index++) {
273 			if ((index < EFUSE_SECURE_START) || (index > EFUSE_SECURE_END)) {
274 				EFUSERead8(0, index, EfuseBuf + index, L25EOUTVOLTAGE);
275 			} else {
276 				EfuseBuf[index] = 0xFF;
277 			}
278 		}
279 
280 		for (index= 0; index < EFUSE_REAL_CONTENT_LEN; index+=16) {
281 			MONITOR_LOG("RawMap[%03x]: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", index,
282 				EfuseBuf[index], EfuseBuf[index+1], EfuseBuf[index+2], EfuseBuf[index+3],
283 				EfuseBuf[index+4], EfuseBuf[index+5], EfuseBuf[index+6], EfuseBuf[index+7],
284 				EfuseBuf[index+8], EfuseBuf[index+9], EfuseBuf[index+10], EfuseBuf[index+11],
285 				EfuseBuf[index+12], EfuseBuf[index+13], EfuseBuf[index+14], EfuseBuf[index+15]);
286 		}
287 	}
288 
289 	/* efuse wraw 0xA0 1 aa */
290 	/* efuse wraw 0xA0 2 aabb */
291 	/* efuse wraw 0xA0 4 aabbccdd */
292 	if (_strcmp((const char*)argv[0], "wraw") == 0) {
293 		u32 Addr = _strtoul((const char*)(argv[1]), (char **)NULL, 16);
294 		u32 Len = _strtoul((const char*)(argv[2]), (char **)NULL, 16);
295 		char* DString = (char*)argv[3];
296 		u32 Cnt;
297 
298 		Cnt = _strlen(DString);
299 		if (Cnt%2) {
300 			MONITOR_LOG("string length(%d) should be odd \n", Cnt);
301 			return FALSE;
302 		}
303 
304 		Cnt = Cnt/2;
305 		if (Cnt != Len) {
306 			MONITOR_LOG("Oops: write lenth not match input string lentg, choose smaller one\n");
307 			Len = (Cnt < Len) ? Cnt:Len;
308 		}
309 
310 		for (index= 0; index < Len; index++) {
311 			EfuseBuf[index] = _2char2hex(DString[index*2], DString[index*2+1]);
312 		}
313 
314 		MONITOR_LOG("efuse wraw write len:%d, string len:%d\n", Len, Cnt << 1);
315 
316 		for (index = 0; index < Len; index++) {
317 			MONITOR_LOG("wraw: %x %x \n", Addr + index, EfuseBuf[index]);
318 			EFUSEWrite8(0, Addr + index, EfuseBuf[index], L25EOUTVOLTAGE);
319 		}
320 	}
321 
322 	return 0;
323 }
324 
325 SHELL_ROM_TEXT_SECTION
326 static u32
cmd_reboot(IN u16 argc,IN u8 * argv[])327 cmd_reboot(
328     IN  u16 argc,
329     IN  u8  *argv[]
330 )
331 {
332 	if (_strcmp((const char*)argv[0], "uartburn") == 0){
333 		BKUP_Set(0, BIT_UARTBURN_BOOT);
334 	}
335 
336 	MONITOR_LOG("\n\rRebooting ...\n\r");
337 	NVIC_SystemReset();
338 
339 	return _TRUE;
340 }
341 
342 SHELL_ROM_DATA_SECTION
343 static COMMAND_TABLE   shell_cmd_table_rom[] = {
344 	{(const u8*)"?",		0, cmd_rom_help,		(const u8*)"\tHELP (?) \n"
345 											"\t\t Print this help messag\n"},
346 	{(const u8*)"DW",	4, CmdDumpWord,	(const u8*)"\tDW \n"
347 											"\t\t <Address, Hex> <Len, Dec>: \n"
348 											"\t\t Dump memory word or Read Hw word register"},
349 	{(const u8*)"EW",	4, CmdWriteWord,	(const u8*)"\tEW \n"
350 											"\t\t <Address, Hex> <Value, Hex>: \n"
351 											"\t\t Write memory word or Write Hw word register \n"
352 											"\t\t Can write one word at the same time \n"
353 											"\t\t Ex: EW Address Value0 Value1"},
354 	{(const u8*)"FLASH",	8, cmd_flash,			(const u8*)"\tFLASH \n"
355 											"\t\t erase chip \n"
356 											"\t\t erase sector addr \n"
357 											"\t\t erase block addr \n"
358 											"\t\t read addr len \n"
359 											"\t\t write addr data \n"},
360 	{(const u8*)"EFUSE",	8, cmd_efuse,			(const u8*)"\tEFUSE \n"
361 											"\t\t wmap addr len data\n"
362 											"\t\t rmap \n"
363 											"\t\t autoload \n"},
364 	{(const u8*)"REBOOT",	4, cmd_reboot,		(const u8*)"\tREBOOT \n"
365 											"\t\t <item, string> : \n"
366 											"\t\t item: uartburn or N/A \n"
367 											"\t\t \n"},
368 };
369 
370 SHELL_ROM_TEXT_SECTION
cmd_rom_table(void ** PTable)371 u32 cmd_rom_table(void** PTable)
372 {
373 	*PTable = (void*)&shell_cmd_table_rom;
374 
375 	return (sizeof(shell_cmd_table_rom)/sizeof(COMMAND_TABLE));
376 }
377 
378 SHELL_ROM_TEXT_SECTION
cmd_rom_help(u16 argc,u8 * argv[])379 static u32 cmd_rom_help(u16 argc, u8  *argv[])
380 {
381 	u32	LoopINdex ;
382 
383 	MONITOR_LOG("----------------- COMMAND MODE HELP ------------------\n");
384 	for( LoopINdex=0  ; LoopINdex < (sizeof(shell_cmd_table_rom) / sizeof(COMMAND_TABLE)) ; LoopINdex++ )
385 	{
386 		if( shell_cmd_table_rom[LoopINdex].msg )
387 		{
388 			MONITOR_LOG( "%s\n",shell_cmd_table_rom[LoopINdex].msg );
389 		}
390 	}
391 	MONITOR_LOG("----------------- COMMAND MODE END  ------------------\n");
392 
393 	return _TRUE ;
394 }
395 
396 #pragma GCC diagnostic pop