📄 monitor.c
字号:
/******************************************************************************
* File: monitor.c
* Author: Naresh Gupta (nkgupta@hotmail.com)
* Date: Wednesday June 16, 1999
* Organization: Hitachi Semiconductor America Inc.
* Purpose: Preliminary Debugger interface for the boot monitor.
*
* Copyright (C) 1999 Hitachi Semiconductor America Inc.
******************************************************************************/
/* Note:-
* To properly view this file, you need to set tabstop=4 in your editor
*/
#ifdef __GNUC__
#include "types.h"
#endif __GNUC__
#include "platform.h"
#include "StandAlone.h"
#include "sh4.h"
#define DIRECT_JUMP 1 // bypass command process, director jump to eboot.
/*****************************************************************************
*** User modifiable variables
****************************************************************************/
/* If this variable is defined, then only the commands that have been tested
* are built into the executable. This is needed when releasing a binary
*/
#define BUILD_RELEASE_COMMANDS
/*****************************************************************************
* STAND_ALONE is defined if you want to test this debugger independently and
* not in conjunction with the Boot Monitor. Useful for prelim debugging.
****************************************************************************/
// #define STAND_ALONE
/*****************************************************************************
* If AUTO_DOWNLOAD is defined, as soon as you power up, the monitor will
* try to download a file thru parallel port. This provides you the
* functionality similar to WINCE bootloader.
*****************************************************************************/
// #define AUTO_DOWNLOAD
/*****************************************************************************
* If RUN_QNX is defined, a check is made for a qnx OS being located at a
* known location in flash. If it is located, the OS is copied to RAM and
* control is transferred to the OS..
*****************************************************************************/
// #define RUN_QNX
/*****************************************************************************
* If NK_DEMO is defined, the image on Wince OS is copied from flash to 8d020000
* and run from there.
* To make such an image you need to do the following :-
* in ce.bib: set SRE=ON
* set NK 8d020000 00FF0000 RAMIMAGE
* Do romimage ce.bib
* I had to put in this option when images from RAM were running while those
* from flash were not running.
*****************************************************************************/
// #define NK_DEMO
/*****************************************************************************
* Define this if you want to try out receiving data from the ps2 keybd/mouse.
*****************************************************************************/
// #define TEST_KBD
/*****************************************************************************
*** End of User modifiable variables
****************************************************************************/
#define DELIM_STR " ,\n\t;@+-" // Delimiters in debugger commands.
#define CMD_LINE_SIZE 80 // Max Size of a Command Line.
#define MAX_ARGS 20 // Max number of arguments to be paased to monitor commands.
#define OEM_DEBUG_READ_NODATA (-1)
/* Temporarily hard code the size of the program. would later be
* read from the image
*/
#define TEXT_START 0x8d100000
#define TEXT_END 0x8d200000
/*****************************************************************************
*** Function prototypes
****************************************************************************/
/* There are two ways to pass the arguments to a command :-
*
* 1. Let the command itself parse the arguments from cur_line. This
* is useful for eg. if the command expects a string as a command
* line argument. The command can just call strtok repeatedly and
* get subsequent command line arguments
* StrTok(NULL, DELIM_STR);
*
* 2. Parse them before calling the command in parse_line and send them to
* the command. All arguments are converted to hex before sending.
* cmd(unsigned sub_commands, unsigned expected_argc, unsigned argc, unsigned *argv);
*
* It is upto the called command, which way it uses.
*
*/
void Command_Copy(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Fill(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Scan(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_RCD(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Disasm(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Test_Memory(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Go(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Eth_Mem_RW(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Eth_EPROM_RW(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Eth_Mem_Test(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_SetBaud(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
int DownloadImage(const unsigned char * pPathName,unsigned int * pStartingAddr,int fLaunch);
void OEM_ReadConfigDword( DWORD dwBusNo, DWORD dwDevNo, DWORD dwFuncNo, DWORD dwOffset, DWORD *pwData );
void SDBTEST_Single(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_CheckSum(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_SelfTest(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
void Command_Exit(void);
void Command_Load(int pport);
void Command_Ether(int dummy);
void Command_InitDisplay(void);
void Command_Erase(void);
void Command_Display(int size);
void Command_Write(int size);
void Command_Test(void);
void Command_Identify(void);
void Command_Help(void);
void Command_ParallelDownload(void);
void Command_Register(void);
void Command_TestVM(void);
void enable_cache(void);
void disable_cache(void);
void Command_cache_state(void);
BOOL ReadEEPROMData(DWORD *pdwIP, DWORD *pdwSubnetMask);
BOOL UpdateEEPROMData(DWORD dwIP, DWORD dwSubnetMask);
int ParseLine(void);
void SDBTEST_main(void);
int ReadInput(char *line);
char * StrTok(char *string, register const char *delim);
int StrICmp(const char *s1, const char *s2);
int OEMReadDebugByte(void);
int OEMSetDebugSerialBaudRate(unsigned baud);
unsigned DownloadSreFile(int pport);
ADDR Disasm (ADDR address, unsigned char *data, int pad);
int OEMParallelPortGetByte(void);
void DispDrvrInitialize (void);
void Command_Eth_Dump(void);
int TestWriteVideoMem(void);
void OEM_InitPCIHostBridge( void ) ;
extern unsigned get_sr(void);
extern void set_sr(unsigned val);
void ProcessCommands(void);
unsigned ToHex(char *str);
unsigned ToDec(char *str);
int ToStr(unsigned num, char *str);
int Write_LED_Data(char *str, unsigned value);
USB_DumpRegisters(void);
int mq200_init(void);
int RIO_Initialize(unsigned sub_command, unsigned expected_argc, unsigned argc, unsigned *argv);
short TestRAM(short mode);
short TestFlash(short mode);
unsigned int OEMFlashWrite(unsigned int ulAddress, unsigned int ulValue);
unsigned int OEMFlashWriteBegin(unsigned int ulPhysStart, unsigned int ulPhysLen);
char *strcpy( char *strDestination, const char *strSource );
int TestRAMRegion(/* */);
void OutputString(const unsigned char *s);
void DbgPrintf(char *format, ...);
#ifdef TEST_KBD
int Command_GetKbdMouse(void);
extern void Command_KbdMouseInit(void);
#endif TEST_KBD
#ifdef RUN_QNX
int nano_main(int arg, unsigned argc, unsigned *argv); /* arg == 1: look for executable at 80010000.
* 0: look at specified address. */
#endif RUN_QNX
/* Global variables. */
static char ledstr[8]; // Temporary string useful to write to LED.
static int CurrentLine=0;
static int tmp; // Temporary variable for loops etc, to make sure that the loops are not optimized.
void (*printFunc)();
char errorText[512];
extern unsigned ulRamBufStart, ulRamBufEnd;
unsigned user_ram, user_ram_end;
int to_flash = 0; // 0: RAM Image, 1: Flash image
// Table of Commands supported by this monitor
static const struct CmdTableType {
char *name;
void (*func)();
int sub_command;
int expected_argc;
int basic_command; // Is it a Basic/required command, or extended.
char *help_string;
} CmdTable[] = {
/* Keep them alphabetical */
{ "B", Command_SetBaud, 0, 1, 1, "B <Baud Rate> Set Baud Rate (in decimal) of debug serial port." },
{ "CB", Command_Copy, 0, 3, 0, "Cb src dst count Copy count bytes from src to dst address" },
{ "CD", disable_cache, 0, 0, 0, "CD Cache Disable"},
{ "CE", enable_cache, 0, 0, 0, "Ce Cache Enable"},
{ "CS", Command_CheckSum, 0, 0, 0, "Cs Checksum an area of memory." },
{ "CP", Command_cache_state, 0, 0, 0, "Cp Display cache state"},
{ "D", Command_Display, 0, 0, 1, "D addr Display 8 dwords starting at specified address" },
{ "DB", Command_Display, 1, 0, 0, "Db addr [count] Display count bytes from the specified address" },
{ "DW", Command_Display, 2, 0, 0, "Dw addr [count] Display count shorts from the specified address" },
{ "DL", Command_Display, 4, 0, 0, "Dl addr [count] Display count longs from the specified address"},
{ "DIS", Command_Disasm, 0, 0, 0, "Dis addr [count] Disassemble count insns from the specified addr."},
{ "E", Command_Erase, 0, 0, 1, "E Erase all system Flash" },
{ "ED", Command_Eth_Dump, 0, 0, 0, "ED Dump Ethernet registers" },
{ "EMRL", Command_Eth_Mem_RW, 0, 1, 0, "EMRL addr Ethernet Memory Read Long" },
{ "EMWL", Command_Eth_Mem_RW, 1, 2, 0, "EMWL addr data Ethernet Memory Write Long" },
{ "EMT", Command_Eth_Mem_Test, 0, 0, 0, "EMT Ethernet Memory Test" },
{ "ERSE", Command_Eth_EPROM_RW, 0, 0, 0, "ERSE Read Serial EEPROM on Ethernet Chip" },
{ "EWSE", Command_Eth_EPROM_RW, 1, 2, 0, "ERSE Read Serial EEPROM on Ethernet Chip" },
{ "EMT", Command_Eth_Mem_Test, 0, 0, 0, "EMT Ethernet Memory Test" },
{ "FL", Command_Fill, 0, 3, 0, "Fl addr long_data count Fill count bytes from the specified address with data" },
{ "G", Command_Go, 0, 1, 0, "G addr Jumps execution to specified address" },
{ "H", Command_Help, 0, 0, 0, "h or ? Print help" },
{ "I", Command_Identify, 0, 0, 1, "I Identify. Prints SDB information" },
#ifndef BUILD_RELEASE_COMMANDS
{ "ID", Command_InitDisplay, 0, 0, 0, "ID Initialize Display device." },
#endif BUILD_RELEASE_COMMANDS
#ifdef TEST_KBD
{ "K", Command_GetKbdMouse, 0, 0, 0, "K Get one key data from keyboard/mouse."},
{ "KI", Command_KbdMouseInit, 0, 0, 0, "KI Initialize keyboard/mouse."},
#endif TEST_KBD
{ "L", Command_Load, 0, 0, 1, "L Load subsequent serial data as s-record file." },
{ "LP", Command_Load, 1, 0, 0, "LP Load subsequent parallel data as s-record file" },
{ "LS", Command_Load, 0, 0, 0, "LS Load subsequent serial data as s-record file" },
{ "LE", Command_Ether, 2, 0, 0, "LE Load a file thru Ethernet interface" },
{ "MT", Command_Test_Memory, 0, 2, 0, "MT start end Test memory from start addr to end addr" },
#ifndef BUILD_RELEASE_COMMANDS
{ "MQI", mq200_init, 0, 2, 0, "MQI Initialize the MQ200 device" },
#ifdef RUN_QNX
{ "NTO", nano_main, 0, 1, 0, "NTO address Hitachi internal command. Please do not use" },
#endif RUN_QNX
#endif BUILD_RELEASE_COMMANDS
{ "OI", OEM_InitPCIHostBridge,0, 0, 0, "OI OEM Routine to Initialize Host PCI Bridge." },
#ifndef BUILD_RELEASE_COMMANDS
{ "R", Command_Register, 0, 0, 0, "R register [new_value] Read/modify register." },
#endif BUILD_RELEASE_COMMANDS
{ "RCD", Command_RCD, 0, 4, 0, "RCD Bus Device Fun Off Read Configuration Dword"},
{ "RIOI", RIO_Initialize, 0, 0, 0, "RIOI Initialize the RIO card for PCI memory accesses."},
{ "USBD", USB_DumpRegisters, 0, 0, 0, "USBD Dump USB Registers"},
{ "WCD", Command_RCD, 1, 5, 0, "WCD Bus Device Fun Off Write Configuration Dword"},
{ "S", Command_Scan, 0, 0, 0, "S Scan the devices on PCI bus. Return Device/Vendor ID" },
{ "WB", Command_Write, 1, 0, 0, "Wb addr [data] Write a byte of data at the specified address" },
{ "WW", Command_Write, 2, 0, 0, "Ww addr [data] Write short data at the specified address" },
{ "WL", Command_Write, 4, 0, 0, "Wl addr [data] Write long data at the specified address" },
{ "T", Command_SelfTest, 0, 0, 1, "T Run Self Test" },
{ "ST", SDBTEST_main, 0, 0, 0, "ST Run SDB Tests" },
#ifndef BUILD_RELEASE_COMMANDS
{ "STS", SDBTEST_Single, 0, 2, 0, "STS Size Phase Run single phase of Mem tests. Size:1,2,4 bytes, Phase:1,2,3" },
{ "TV", Command_TestVM, 0, 0, 0, "TV Test Video Memory" },
#endif BUILD_RELEASE_COMMANDS
{ "X", Command_Exit, 0, 0, 0, "X Exit the Tests" },
{ "?", Command_Help, 0, 0, 0, NULL },
{ 0, 0, 0, 0 }
};
/******************************************************************************
* Function: StartMonitor
* Input: None
* Output: Error Value
* Synopsis: Entry point for the Monitor program.
* For Stand_alone operations, you need to compile this with
* another file. The other file will just define the main function,
* which would call StartMonitor.
*****************************************************************************/
int StartMonitor(void)
{
Write_LED_Data("StartMon", 0x200);
WriteOutput("Type h for help.\n");
#ifdef STAND_ALONE
WriteOutput("Address of Scratch Buffer = 0x%x\r\n", Buf);
#endif
/* initialize keybd/mouse if TEST_KBD is defined. */
#ifdef TEST_KBD
KbdMouseInit();
#endif TEST_KBD
#ifdef AUTO_DOWNLOAD
// Start downloading the file thru parallel port.
Command_Load(1);
#endif AUTO_DOWNLOAD
// For BigSur, read the settings of Switch SW1 to see whether Automatic
// Download should be performed.
#if (SH_PLATFORM == PLATFORM_BIGSUR)
{
if( !( BIGSUR_SW1_MISCSW_N & REG8(BIGSUR_SW1, 0) ) ){
unsigned char SW2 = (REG8(BIGSUR_SW2, 0) >> 4);
WriteOutput("MISCSW switch set, SW1 = 0x%x, SW2 = 0x%x...\r\n\n", REG8(BIGSUR_SW1, 0), SW2);
switch(SW2) {
case BIGSUR_SW2_LM_ETHERNET:
WriteOutput("Downloading via Ethernet...\r\n");
Command_Ether(0);
break;
case BIGSUR_SW2_LM_SERIAL:
WriteOutput("Downloading via Serial...\r\n");
Command_Load(0);
break;
case BIGSUR_SW2_LM_PARALLEL:
WriteOutput("Downloading via Parallel...\r\n");
Command_Load(1);
break;
default:
WriteOutput("This setting of SW2 is not supported right now.\r\n");
break;
}
}
}
#endif // (SH_PLATFORM == PLATFORM_BIGSUR)
// See comments above for NK_DEMO
#ifdef NK_DEMO
{
unsigned src, dst, count;
unsigned argv[3];
void (*run)();
// TBD Need to make sure that the stack of the monitor does not get overwritten
src = 0x80020000;
dst = 0x8D020000;
count = 0x00FD0000; // Maximum possbile size
/* Copy 0x00FF0000 bytes from Flash address 0x80020000 to 0x8d020000
* and then jump to 8d020000
*/
WriteOutput("Copying 0x%x bytes from 0x%x to 0x%x\n", count, src, dst);
argv[0] = src;
argv[1] = dst;
argv[2] = count;
Command_Copy(0, 3, 3, argv);
WriteOutput("Jumping to 0x%x\n", dst);
#if 0
run = (dst+4);
run();
#else
argv[0] = (dst+4);
Command_Go(0, 1, 1, argv);
#endif
}
#endif NK_DEMO
#ifdef RUN_QNX
/* First see whether an image is located at the standard address.
* if yes, run that image. */
nano_main(0, 0, 0);
#endif RUN_QNX
/* The self test routines need the printFunc pointer to point to the print
* routine. */
printFunc = OutputFormatString;
user_ram = ulRamBufStart;
user_ram_end = ulRamBufEnd;
#ifdef DIRECT_JUMP
Command_Ether(0);
#endif
ProcessCommands();
return TRUE;
}
/******************************************************************************
* Function: ProcessCommands
* Input: None
* Output: None
* Synopsis: This routine will infinitely take a line as input and process it.
*****************************************************************************/
void ProcessCommands()
{
int done = 0;
while(!done) {
CurrentLine ++;
done = ParseLine();
}
}
/******************************************************************************
* Function: ParseLine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -