1 /******************************************************************************
3 * Filename: loader_prompt.c
5 * Instantiation of the interactive loader functions.
7 * Revision information:
9 * 20AUG2004 kb_admin initial creation
10 * 12JAN2005 kb_admin massive changes for tftp, strings, and more
11 * 05JUL2005 kb_admin save tag address, and set registers on boot
14 * No warranty, expressed or implied, is included with this software. It is
15 * provided "AS IS" and no warranty of any kind including statutory or aspects
16 * relating to merchantability or fitness for any purpose is provided. All
17 * intellectual property rights of others is maintained with the respective
18 * owners. This software is not copyrighted and is intended for reference
23 *****************************************************************************/
25 #include "at91rm9200_lowlevel.h"
26 #ifdef SUPPORT_TAG_LIST
30 #include "loader_prompt.h"
35 /******************************* GLOBALS *************************************/
38 /*********************** PRIVATE FUNCTIONS/DATA ******************************/
40 static char inputBuffer[MAX_INPUT_SIZE];
43 // argv pointer are either NULL or point to locations in inputBuffer
44 static char *argv[MAX_COMMAND_PARAMS];
46 static const char *backspaceString = "\010 \010";
48 static const command_entry_t CommandTable[] = {
53 {COMMAND_LOCAL_IP, "ip"},
55 {COMMAND_SERVER_IP, "server_ip"},
57 #ifdef SUPPORT_TAG_LIST
60 {COMMAND_TFTP, "tftp"},
62 {COMMAND_XMODEM, "x"},
63 {COMMAND_FINAL_FLAG, 0}
66 static unsigned tagAddress;
69 * .KB_C_FN_DEFINITION_START
70 * unsigned BuildIP(void)
71 * This private function packs the test IP info to an unsigned value.
72 * .KB_C_FN_DEFINITION_END
77 return ((p_ASCIIToDec(argv[1]) << 24) |
78 (p_ASCIIToDec(argv[2]) << 16) |
79 (p_ASCIIToDec(argv[3]) << 8) |
80 p_ASCIIToDec(argv[4]));
85 * .KB_C_FN_DEFINITION_START
86 * int StringToCommand(char *cPtr)
87 * This private function converts a command string to a command code.
88 * .KB_C_FN_DEFINITION_END
91 StringToCommand(char *cPtr)
95 for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
96 if (!strcmp(CommandTable[i].c_string, cPtr))
97 return (CommandTable[i].command);
99 return (COMMAND_INVALID);
104 * .KB_C_FN_DEFINITION_START
105 * void RestoreSpace(int)
106 * This private function restores NULL characters to spaces in order to
107 * process the remaining args as a string. The number passed is the argc
108 * of the first entry to begin restoring space in the inputBuffer.
109 * .KB_C_FN_DEFINITION_END
112 RestoreSpace(int startArgc)
116 for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) {
117 if ((cPtr = argv[startArgc]))
124 * .KB_C_FN_DEFINITION_START
125 * int BreakCommand(char *)
126 * This private function splits the buffer into separate strings as pointed
127 * by argv and returns the number of parameters (< 0 on failure).
128 * .KB_C_FN_DEFINITION_END
131 BreakCommand(char *buffer)
133 int pCount, cCount, state;
136 p_memset((char*)argv, 0, sizeof(argv));
138 for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
141 /* look for next command */
142 if (!p_IsWhiteSpace(buffer[cCount])) {
143 argv[pCount++] = &buffer[cCount];
149 /* in command, find next white space */
150 if (p_IsWhiteSpace(buffer[cCount])) {
156 if (pCount >= MAX_COMMAND_PARAMS) {
166 * .KB_C_FN_DEFINITION_START
167 * void ParseCommand(char *)
168 * This private function executes matching functions.
169 * .KB_C_FN_DEFINITION_END
172 ParseCommand(char *buffer)
176 if ((argc = BreakCommand(buffer)) < 1)
179 switch (StringToCommand(argv[0])) {
182 // "c <to> <from> <size in bytes>"
188 to = (char *)p_ASCIIToHex(argv[1]);
189 from = (char *)p_ASCIIToHex(argv[2]);
190 size = p_ASCIIToHex(argv[3]);
191 memcpy(to, from, size);
197 // display boot commands
204 // execute at address
205 void (*execAddr)(unsigned, unsigned, unsigned);
208 /* in future, include machtypes (MACH_KB9200 = 612) */
209 execAddr = (void (*)(unsigned, unsigned, unsigned))
210 p_ASCIIToHex(argv[1]);
211 (*execAddr)(0, 612, tagAddress);
218 // "tftp <local_dest_addr filename>"
220 unsigned address = 0;
223 address = p_ASCIIToHex(argv[1]);
224 TFTP_Download(address, argv[2]);
228 case COMMAND_SERVER_IP:
229 // "server_ip <server IP 192 200 1 20>"
230 // set download server address
232 SetServerIPAddress(BuildIP());
246 #ifdef SUPPORT_TAG_LIST
253 case COMMAND_LOCAL_IP:
254 // "local_ip <local IP 192 200 1 21>
255 // set ip of this module
257 SetLocalIPAddress(BuildIP());
262 // "m <mac address 12 34 56 78 9a bc>
263 // set mac address using 6 byte values
264 unsigned char mac[6];
267 for (i = 0; i < 6; i++)
268 mac[i] = p_ASCIIToHex(argv[i + 1]);
269 EMAC_SetMACAddress(mac);
276 // s <index> <new boot command>
277 // set the boot command at index (0-based)
282 index = p_ASCIIToHex(argv[1]);
283 SetBootCommand(index, argv[2]);
288 #ifdef SUPPORT_TAG_LIST
290 // t <address> <boot command line>
291 // create tag-list for linux boot
294 tagAddress = p_ASCIIToHex(argv[1]);
295 InitTagList(argv[2], (void*)tagAddress);
301 // write the command table to non-volatile
308 // download X-modem record at address
310 xmodem_rx((char *)p_ASCIIToHex(argv[1]));
323 * .KB_C_FN_DEFINITION_START
324 * void ServicePrompt(char)
325 * This private function process each character checking for valid commands.
326 * This function is only executed if the character is considered valid.
327 * Each command is terminated with NULL (0) or ''.
328 * .KB_C_FN_DEFINITION_END
331 ServicePrompt(char p_char)
336 if (p_char == '\010') {
338 /* handle backspace BS */
339 inputBuffer[--buffCount] = 0;
340 printf(backspaceString);
344 if (buffCount < MAX_INPUT_SIZE - 1) {
345 inputBuffer[buffCount++] = p_char;
350 ParseCommand(inputBuffer);
351 p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
358 /* ************************** GLOBAL FUNCTIONS ********************************/
362 * .KB_C_FN_DEFINITION_START
363 * void Bootloader(void *inputFunction)
364 * This global function is the entry point for the bootloader. If the
365 * inputFunction pointer is NULL, the loader input will be serviced from
366 * the uart. Otherwise, inputFunction is called to get characters which
367 * the loader will parse.
368 * .KB_C_FN_DEFINITION_END
371 Bootloader(int(*inputFunction)(int))
375 p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
378 if (!inputFunction) {
379 inputFunction = getc;
385 if ((ch = ((*inputFunction)(0))) > 0)