mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
MFp4: These will migrate to the boot specific directories because they
are too hard to share between the different boot loaders.
This commit is contained in:
parent
98de821987
commit
592c5848a6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=161194
@ -1,207 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: env_vars.c
|
||||
*
|
||||
* Instantiation of environment variables, structures, and other globals.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
*
|
||||
* BEGIN_KBDD_BLOCK
|
||||
* No warranty, expressed or implied, is included with this software. It is
|
||||
* provided "AS IS" and no warranty of any kind including statutory or aspects
|
||||
* relating to merchantability or fitness for any purpose is provided. All
|
||||
* intellectual property rights of others is maintained with the respective
|
||||
* owners. This software is not copyrighted and is intended for reference
|
||||
* only.
|
||||
* END_BLOCK
|
||||
*
|
||||
* $FreeBSD$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "env_vars.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "p_string.h"
|
||||
#include "eeprom.h"
|
||||
#include "lib.h"
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
char boot_commands[MAX_BOOT_COMMANDS][MAX_INPUT_SIZE];
|
||||
|
||||
char env_table[MAX_ENV_SIZE_BYTES];
|
||||
|
||||
extern char BootCommandSection;
|
||||
|
||||
/************************** PRIVATE FUNCTIONS ********************************/
|
||||
|
||||
|
||||
static int currentIndex;
|
||||
static int currentOffset;
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int ReadCharFromEnvironment(char *)
|
||||
* This private function reads characters from the enviroment variables
|
||||
* to service the command prompt during auto-boot or just to setup the
|
||||
* default environment. Returns positive value if valid character was
|
||||
* set in the pointer. Returns negative value to signal input stream
|
||||
* terminated. Returns 0 to indicate _wait_ condition.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
ReadCharFromEnvironment(int timeout)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (currentIndex < MAX_BOOT_COMMANDS) {
|
||||
ch = boot_commands[currentIndex][currentOffset++];
|
||||
if (ch == '\0' || (currentOffset >= MAX_INPUT_SIZE)) {
|
||||
currentOffset = 0;
|
||||
++currentIndex;
|
||||
}
|
||||
return (ch);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/*************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void WriteCommandTable(void)
|
||||
* This global function write the current command table to the non-volatile
|
||||
* memory.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
WriteCommandTable(void)
|
||||
{
|
||||
int i, size = MAX_ENV_SIZE_BYTES, copySize;
|
||||
char *cPtr = env_table;
|
||||
|
||||
p_memset(env_table, 0, sizeof(env_table));
|
||||
|
||||
for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
|
||||
|
||||
copySize = p_strlen(boot_commands[i]);
|
||||
size -= copySize + 1;
|
||||
|
||||
if (size < 0) {
|
||||
continue;
|
||||
}
|
||||
p_memcpy(cPtr, boot_commands[i], copySize);
|
||||
cPtr += copySize;
|
||||
*cPtr++ = 0;
|
||||
}
|
||||
|
||||
WriteEEPROM((unsigned)&BootCommandSection, env_table,
|
||||
sizeof(env_table));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void SetBootCommand(int index, char *command)
|
||||
* This global function replaces the specified index with the string residing
|
||||
* at command. Execute this function with a NULL string to clear the
|
||||
* associated command index.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
SetBootCommand(int index, char *command)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((unsigned)index < MAX_BOOT_COMMANDS) {
|
||||
|
||||
p_memset(boot_commands[index], 0, MAX_INPUT_SIZE);
|
||||
|
||||
if (!command)
|
||||
return ;
|
||||
|
||||
for (i = 0; i < MAX_INPUT_SIZE; ++i) {
|
||||
boot_commands[index][i] = command[i];
|
||||
if (!(boot_commands[index][i]))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void DumpBootCommands(void)
|
||||
* This global function displays the current boot commands.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
DumpBootCommands(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < MAX_BOOT_COMMANDS; ++i) {
|
||||
printf("0x%x : ", i);
|
||||
for (j = 0; j < MAX_INPUT_SIZE; ++j) {
|
||||
putchar(boot_commands[i][j]);
|
||||
if (!(boot_commands[i][j]))
|
||||
break;
|
||||
}
|
||||
printf("[E]\n\r");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void LoadBootCommands(void)
|
||||
* This global function loads the existing boot commands from raw format and
|
||||
* coverts it to the standard, command-index format. Notice, the processed
|
||||
* boot command table has much more space allocated than the actual table
|
||||
* stored in non-volatile memory. This is because the processed table
|
||||
* exists in RAM which is larger than the non-volatile space.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
LoadBootCommands(void)
|
||||
{
|
||||
int index, j, size;
|
||||
char *cPtr;
|
||||
|
||||
p_memset((char*)boot_commands, 0, sizeof(boot_commands));
|
||||
|
||||
cPtr = &BootCommandSection;
|
||||
|
||||
size = MAX_ENV_SIZE_BYTES;
|
||||
|
||||
for (index = 0; (index < MAX_BOOT_COMMANDS) && size; ++index) {
|
||||
for (j = 0; (j < MAX_INPUT_SIZE) && size; ++j) {
|
||||
size--;
|
||||
boot_commands[index][j] = *cPtr++;
|
||||
if (!(boot_commands[index][j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ExecuteEnvironmentFunctions(void)
|
||||
* This global function executes applicable entries in the environment.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
ExecuteEnvironmentFunctions(void)
|
||||
{
|
||||
currentIndex = 0;
|
||||
currentOffset = 0;
|
||||
|
||||
DumpBootCommands();
|
||||
Bootloader(ReadCharFromEnvironment);
|
||||
}
|
@ -1,426 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: loader_prompt.c
|
||||
*
|
||||
* Instantiation of the interactive loader functions.
|
||||
*
|
||||
* Revision information:
|
||||
*
|
||||
* 20AUG2004 kb_admin initial creation
|
||||
* 12JAN2005 kb_admin massive changes for tftp, strings, and more
|
||||
* 05JUL2005 kb_admin save tag address, and set registers on boot
|
||||
*
|
||||
* BEGIN_KBDD_BLOCK
|
||||
* No warranty, expressed or implied, is included with this software. It is
|
||||
* provided "AS IS" and no warranty of any kind including statutory or aspects
|
||||
* relating to merchantability or fitness for any purpose is provided. All
|
||||
* intellectual property rights of others is maintained with the respective
|
||||
* owners. This software is not copyrighted and is intended for reference
|
||||
* only.
|
||||
* END_BLOCK
|
||||
*
|
||||
* $FreeBSD$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "at91rm9200_lowlevel.h"
|
||||
#include "p_string.h"
|
||||
#include "eeprom.h"
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
#include "tag_list.h"
|
||||
#endif
|
||||
#include "emac.h"
|
||||
#include "loader_prompt.h"
|
||||
#include "env_vars.h"
|
||||
#include "lib.h"
|
||||
|
||||
|
||||
/******************************* GLOBALS *************************************/
|
||||
|
||||
|
||||
/*********************** PRIVATE FUNCTIONS/DATA ******************************/
|
||||
|
||||
static char inputBuffer[MAX_INPUT_SIZE];
|
||||
static int buffCount;
|
||||
|
||||
// argv pointer are either NULL or point to locations in inputBuffer
|
||||
static char *argv[MAX_COMMAND_PARAMS];
|
||||
|
||||
static char backspaceString[] = {0x8, ' ', 0x8, 0};
|
||||
|
||||
static command_entry_t CommandTable[] = {
|
||||
{COMMAND_COPY, "c"},
|
||||
{COMMAND_DUMP, "d"},
|
||||
{COMMAND_EXEC, "e"},
|
||||
{COMMAND_HELP, "?"},
|
||||
{COMMAND_LOCAL_IP, "ip"},
|
||||
{COMMAND_MAC, "m"},
|
||||
{COMMAND_SERVER_IP, "server_ip"},
|
||||
{COMMAND_SET, "s"},
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
{COMMAND_TAG, "t"},
|
||||
#endif
|
||||
{COMMAND_TFTP, "tftp"},
|
||||
{COMMAND_WRITE, "w"},
|
||||
{COMMAND_XMODEM, "x"},
|
||||
{COMMAND_FINAL_FLAG, 0}
|
||||
};
|
||||
|
||||
static unsigned tagAddress;
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* unsigned BuildIP(void)
|
||||
* This private function packs the test IP info to an unsigned value.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static unsigned
|
||||
BuildIP(void)
|
||||
{
|
||||
return ((p_ASCIIToDec(argv[1]) << 24) |
|
||||
(p_ASCIIToDec(argv[2]) << 16) |
|
||||
(p_ASCIIToDec(argv[3]) << 8) |
|
||||
p_ASCIIToDec(argv[4]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int StringToCommand(char *cPtr)
|
||||
* This private function converts a command string to a command code.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
StringToCommand(char *cPtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; CommandTable[i].command != COMMAND_FINAL_FLAG; ++i)
|
||||
if (!p_strcmp(CommandTable[i].c_string, cPtr))
|
||||
return (CommandTable[i].command);
|
||||
|
||||
return (COMMAND_INVALID);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void RestoreSpace(int)
|
||||
* This private function restores NULL characters to spaces in order to
|
||||
* process the remaining args as a string. The number passed is the argc
|
||||
* of the first entry to begin restoring space in the inputBuffer.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
RestoreSpace(int startArgc)
|
||||
{
|
||||
char *cPtr;
|
||||
|
||||
for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) {
|
||||
if ((cPtr = argv[startArgc]))
|
||||
*(cPtr - 1) = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* int BreakCommand(char *)
|
||||
* This private function splits the buffer into separate strings as pointed
|
||||
* by argv and returns the number of parameters (< 0 on failure).
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static int
|
||||
BreakCommand(char *buffer)
|
||||
{
|
||||
int pCount, cCount, state;
|
||||
|
||||
state = pCount = 0;
|
||||
p_memset((char*)argv, 0, sizeof(argv));
|
||||
|
||||
for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
|
||||
|
||||
if (!state) {
|
||||
/* look for next command */
|
||||
if (!p_IsWhiteSpace(buffer[cCount])) {
|
||||
argv[pCount++] = &buffer[cCount];
|
||||
state = 1;
|
||||
} else {
|
||||
buffer[cCount] = 0;
|
||||
}
|
||||
} else {
|
||||
/* in command, find next white space */
|
||||
if (p_IsWhiteSpace(buffer[cCount])) {
|
||||
buffer[cCount] = 0;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCount >= MAX_COMMAND_PARAMS) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (pCount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ParseCommand(char *)
|
||||
* This private function executes matching functions.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void
|
||||
ParseCommand(char *buffer)
|
||||
{
|
||||
int argc;
|
||||
|
||||
if ((argc = BreakCommand(buffer)) < 1) {
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (StringToCommand(argv[0])) {
|
||||
|
||||
case COMMAND_COPY:
|
||||
{
|
||||
// "c <to> <from> <size in bytes>"
|
||||
// copy memory
|
||||
|
||||
char *to, *from;
|
||||
unsigned size;
|
||||
|
||||
if (argc > 3) {
|
||||
to = (char *)p_ASCIIToHex(argv[1]);
|
||||
from = (char *)p_ASCIIToHex(argv[2]);
|
||||
size = p_ASCIIToHex(argv[3]);
|
||||
p_memcpy(to, from, size);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_DUMP:
|
||||
// display boot commands
|
||||
DumpBootCommands();
|
||||
break;
|
||||
|
||||
case COMMAND_EXEC:
|
||||
{
|
||||
// "e <address>"
|
||||
// execute at address
|
||||
|
||||
void (*execAddr)(unsigned, unsigned, unsigned);
|
||||
|
||||
if (argc > 1) {
|
||||
/* in future, include machtypes (MACH_KB9200 = 612) */
|
||||
execAddr = (void (*)(unsigned, unsigned, unsigned))
|
||||
p_ASCIIToHex(argv[1]);
|
||||
(*execAddr)(0, 612, tagAddress);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TFTP:
|
||||
{
|
||||
// "tftp <local_dest_addr filename>"
|
||||
// tftp download
|
||||
|
||||
unsigned address = 0;
|
||||
|
||||
if (argc > 2)
|
||||
address = p_ASCIIToHex(argv[1]);
|
||||
|
||||
TFTP_Download(address, argv[2]);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_SERVER_IP:
|
||||
// "server_ip <server IP 192 200 1 20>"
|
||||
// set download server address
|
||||
|
||||
if (argc > 4)
|
||||
SetServerIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_HELP:
|
||||
// dump command info
|
||||
printf("Commands:\r\n"
|
||||
"\tc\r\n"
|
||||
"\td\r\n"
|
||||
"\te\r\n"
|
||||
"\tip\r\n"
|
||||
"\tserver_ip\r\n"
|
||||
"\tm\r\n"
|
||||
"\ttftp\r\n"
|
||||
"\ts\r\n"
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
"\tt\r\n"
|
||||
#endif
|
||||
"\tw\r\n"
|
||||
"\tx\r\n");
|
||||
break;
|
||||
|
||||
case COMMAND_LOCAL_IP:
|
||||
// "local_ip <local IP 192 200 1 21>
|
||||
// set ip of this module
|
||||
|
||||
if (argc > 4)
|
||||
SetLocalIPAddress(BuildIP());
|
||||
break;
|
||||
|
||||
case COMMAND_MAC:
|
||||
{
|
||||
// "m <mac address 12 34 56 78 9a bc>
|
||||
// set mac address using 6 byte values
|
||||
|
||||
unsigned low_addr, high_addr;
|
||||
|
||||
if (argc > 6) {
|
||||
|
||||
low_addr = (p_ASCIIToHex(argv[4]) << 24) |
|
||||
(p_ASCIIToHex(argv[3]) << 16) |
|
||||
(p_ASCIIToHex(argv[2]) << 8) |
|
||||
p_ASCIIToHex(argv[1]);
|
||||
high_addr =
|
||||
(p_ASCIIToHex(argv[6]) << 8) |
|
||||
p_ASCIIToHex(argv[5]);
|
||||
SetMACAddress(low_addr, high_addr);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_SET:
|
||||
{
|
||||
// s <index> <new boot command>
|
||||
// set the boot command at index (0-based)
|
||||
|
||||
unsigned index;
|
||||
|
||||
if (argc > 1) {
|
||||
RestoreSpace(2);
|
||||
index = p_ASCIIToHex(argv[1]);
|
||||
SetBootCommand(index, argv[2]);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef SUPPORT_TAG_LIST
|
||||
case COMMAND_TAG:
|
||||
{
|
||||
// t <address> <boot command line>
|
||||
// create tag-list for linux boot
|
||||
|
||||
if (argc > 2) {
|
||||
RestoreSpace(2);
|
||||
tagAddress = p_ASCIIToHex(argv[1]);
|
||||
InitTagList(argv[2], (void*)tagAddress);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COMMAND_WRITE:
|
||||
// write the command table to non-volatile
|
||||
|
||||
WriteCommandTable();
|
||||
break;
|
||||
|
||||
case COMMAND_XMODEM:
|
||||
{
|
||||
// "x <address>"
|
||||
// download X-modem record at address
|
||||
|
||||
char *destAddr = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
destAddr = (char *)p_ASCIIToHex(argv[1]);
|
||||
xmodem_rx(destAddr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void ServicePrompt(char)
|
||||
* This private function process each character checking for valid commands.
|
||||
* This function is only executed if the character is considered valid.
|
||||
* Each command is terminated with NULL (0) or '\r'.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
static void ServicePrompt(char p_char) {
|
||||
|
||||
if (p_char == '\r') {
|
||||
p_char = 0;
|
||||
|
||||
}
|
||||
|
||||
if (p_char != 0x8) {
|
||||
if (buffCount < MAX_INPUT_SIZE-1) {
|
||||
|
||||
inputBuffer[buffCount] = p_char;
|
||||
++buffCount;
|
||||
putchar(p_char);
|
||||
}
|
||||
|
||||
} else if (buffCount) {
|
||||
|
||||
/* handle backspace BS */
|
||||
--buffCount;
|
||||
inputBuffer[buffCount] = 0;
|
||||
printf(backspaceString);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!p_char) {
|
||||
printf("\r\n");
|
||||
ParseCommand(inputBuffer);
|
||||
p_memset(inputBuffer, 0, MAX_INPUT_SIZE);
|
||||
buffCount = 0;
|
||||
printf("\r\n>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************** GLOBAL FUNCTIONS ********************************/
|
||||
|
||||
|
||||
/*
|
||||
* .KB_C_FN_DEFINITION_START
|
||||
* void Bootloader(void *inputFunction)
|
||||
* This global function is the entry point for the bootloader. If the
|
||||
* inputFunction pointer is NULL, the loader input will be serviced from
|
||||
* the uart. Otherwise, inputFunction is called to get characters which
|
||||
* the loader will parse.
|
||||
* .KB_C_FN_DEFINITION_END
|
||||
*/
|
||||
void
|
||||
Bootloader(int(*inputFunction)(int))
|
||||
{
|
||||
int ch = 0;
|
||||
|
||||
p_memset((void*)inputBuffer, 0, sizeof(inputBuffer));
|
||||
|
||||
buffCount = 0;
|
||||
if (!inputFunction) {
|
||||
inputFunction = getc;
|
||||
}
|
||||
|
||||
printf("\r\n>");
|
||||
|
||||
while (1)
|
||||
if ((ch = ((*inputFunction)(0))) > 0)
|
||||
ServicePrompt(ch);
|
||||
}
|
Loading…
Reference in New Issue
Block a user