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 #include "at91rm9200.h"
28 #include "loader_prompt.h"
31 #include "spi_flash.h"
34 /******************************* GLOBALS *************************************/
37 /*********************** PRIVATE FUNCTIONS/DATA ******************************/
39 static char inputBuffer[MAX_INPUT_SIZE];
42 // argv pointer are either NULL or point to locations in inputBuffer
43 static char *argv[MAX_COMMAND_PARAMS];
45 #define FLASH_OFFSET (0 * FLASH_PAGE_SIZE)
46 #define KERNEL_OFFSET (220 * FLASH_PAGE_SIZE)
47 #define KERNEL_LEN (6 * 1024 * FLASH_PAGE_SIZE)
48 static const char *backspaceString = "\010 \010";
50 static const command_entry_t CommandTable[] = {
53 {COMMAND_LOCAL_IP, "ip"},
55 {COMMAND_SERVER_IP, "server_ip"},
56 {COMMAND_TFTP, "tftp"},
57 {COMMAND_XMODEM, "x"},
59 {COMMAND_LOAD_SPI_KERNEL, "k"},
60 {COMMAND_REPLACE_KERNEL_VIA_XMODEM, "K"},
61 {COMMAND_REPLACE_FLASH_VIA_XMODEM, "I"},
62 {COMMAND_REPLACE_ID_EEPROM, "E"},
63 {COMMAND_FINAL_FLAG, 0}
67 * .KB_C_FN_DEFINITION_START
68 * unsigned BuildIP(void)
69 * This private function packs the test IP info to an unsigned value.
70 * .KB_C_FN_DEFINITION_END
75 return ((p_ASCIIToDec(argv[1]) << 24) |
76 (p_ASCIIToDec(argv[2]) << 16) |
77 (p_ASCIIToDec(argv[3]) << 8) |
78 p_ASCIIToDec(argv[4]));
83 * .KB_C_FN_DEFINITION_START
84 * int StringToCommand(char *cPtr)
85 * This private function converts a command string to a command code.
86 * .KB_C_FN_DEFINITION_END
89 StringToCommand(char *cPtr)
93 for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
94 if (!strcmp(CommandTable[i].c_string, cPtr))
95 return (CommandTable[i].command);
97 return (COMMAND_INVALID);
102 * .KB_C_FN_DEFINITION_START
103 * int BreakCommand(char *)
104 * This private function splits the buffer into separate strings as pointed
105 * by argv and returns the number of parameters (< 0 on failure).
106 * .KB_C_FN_DEFINITION_END
109 BreakCommand(char *buffer)
111 int pCount, cCount, state;
114 p_memset((char*)argv, 0, sizeof(argv));
116 for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
119 /* look for next command */
120 if (!p_IsWhiteSpace(buffer[cCount])) {
121 argv[pCount++] = &buffer[cCount];
127 /* in command, find next white space */
128 if (p_IsWhiteSpace(buffer[cCount])) {
134 if (pCount >= MAX_COMMAND_PARAMS) {
144 UpdateEEProm(int eeaddr)
146 char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
149 while ((len = xmodem_rx(addr)) == -1)
151 printf("\nDownloaded %u bytes.\n", len);
152 WriteEEPROM(eeaddr, 0, addr, len);
157 UpdateFlash(int offset)
159 char *addr = (char *)SDRAM_BASE + (1 << 20); /* Load to base + 1MB */
162 while ((len = xmodem_rx(addr)) == -1)
164 printf("\nDownloaded %u bytes.\n", len);
165 for (i = 0; i < len; i+= FLASH_PAGE_SIZE) {
167 SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE);
172 LoadKernelFromSpi(char *addr)
176 for (i = 0; i < KERNEL_LEN; i+= FLASH_PAGE_SIZE) {
177 off = i + KERNEL_OFFSET;
178 SPI_ReadFlash(off, addr + i, FLASH_PAGE_SIZE);
183 * .KB_C_FN_DEFINITION_START
184 * void ParseCommand(char *)
185 * This private function executes matching functions.
186 * .KB_C_FN_DEFINITION_END
189 ParseCommand(char *buffer)
193 if ((argc = BreakCommand(buffer)) < 1)
196 switch (StringToCommand(argv[0])) {
198 // display boot commands
205 // execute at address
206 void (*execAddr)(unsigned, unsigned);
209 /* in future, include machtypes (MACH_KB9200 = 612) */
210 execAddr = (void (*)(unsigned, unsigned))
211 p_ASCIIToHex(argv[1]);
219 // "tftp <local_dest_addr filename>"
221 unsigned address = 0;
224 address = p_ASCIIToHex(argv[1]);
225 TFTP_Download(address, argv[2]);
229 case COMMAND_SERVER_IP:
230 // "server_ip <server IP 192 200 1 20>"
231 // set download server address
233 SetServerIPAddress(BuildIP());
236 case COMMAND_LOCAL_IP:
237 // "local_ip <local IP 192 200 1 21>
238 // set ip of this module
240 SetLocalIPAddress(BuildIP());
245 // "m <mac address 12 34 56 78 9a bc>
246 // set mac address using 6 byte values
247 unsigned char mac[6];
250 for (i = 0; i < 6; i++)
251 mac[i] = p_ASCIIToHex(argv[i + 1]);
252 EMAC_SetMACAddress(mac);
257 case COMMAND_LOAD_SPI_KERNEL:
260 LoadKernelFromSpi((char *)p_ASCIIToHex(argv[1]));
265 // download X-modem record at address
267 xmodem_rx((char *)p_ASCIIToHex(argv[1]));
276 case COMMAND_REPLACE_KERNEL_VIA_XMODEM:
277 printf("Updating KERNEL image\n");
278 UpdateFlash(KERNEL_OFFSET);
280 case COMMAND_REPLACE_FLASH_VIA_XMODEM:
281 printf("Updating FLASH image\n");
282 UpdateFlash(FLASH_OFFSET);
285 case COMMAND_REPLACE_ID_EEPROM:
288 printf("Testing Config EEPROM\n");
289 EEWrite(0, "This is a test", 15);
291 printf("Found '%s'\n", buf);
303 * .KB_C_FN_DEFINITION_START
304 * void ServicePrompt(char)
305 * This private function process each character checking for valid commands.
306 * This function is only executed if the character is considered valid.
307 * Each command is terminated with NULL (0) or ''.
308 * .KB_C_FN_DEFINITION_END
311 ServicePrompt(char p_char)
316 if (p_char == '\010') {
318 /* handle backspace BS */
319 inputBuffer[--buffCount] = 0;
320 printf(backspaceString);
324 if (buffCount < MAX_INPUT_SIZE - 1) {
325 inputBuffer[buffCount++] = p_char;
330 ParseCommand(inputBuffer);
331 p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
338 /* ************************** GLOBAL FUNCTIONS ********************************/
342 * .KB_C_FN_DEFINITION_START
343 * void Bootloader(void *inputFunction)
344 * This global function is the entry point for the bootloader. If the
345 * inputFunction pointer is NULL, the loader input will be serviced from
346 * the uart. Otherwise, inputFunction is called to get characters which
347 * the loader will parse.
348 * .KB_C_FN_DEFINITION_END
351 Bootloader(int(*inputFunction)(int))
355 p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
361 if ((ch = ((*inputFunction)(0))) > 0)