⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++
Copyright (c) 1997  Microsoft Corporation

Module Name:

    monitor.c

Abstract:

    This file contains the monitor for the firmware.

Author:

    Lluis Abello (lluis) 09-Sep-91

Revision History:

    Jun Liu 8/6/96 Modified for Puzzle
    John Cooper (johncoop) 97-Oct-21: Modified for LC2


--*/

#include <windows.h>
#include <halether.h>

#include "workitem.h"

#ifdef MONITOR_USED

#include "monitor.h"

#define BYTE_SIZE 1
#define HALF_SIZE 2
#define WORD_SIZE 4

extern PCHAR RegisterNameTable[];

//
// declare static variables.
//
ULONG Argc;
ULONG CurrentArg;

COMMAND_NAME_ID CurrentCommand;

ULONG DataSize;
ULONG DataSizeMask;
ULONG DataSizeShift;

ULONG DefaultAddress;


PCHAR CommandNameTable[(COMMAND_NAME_ID)invalidcommand] = {
    "d",
    "db",
    "dw",
    "dd",
    "e",
    "eb",
    "ew",
    "ed",
    "o",
    "ob",
    "ow",
    "od",
    "i",
    "ib",
    "iw",
    "id",
    "r",
    "z",
    "f",
    "a",
    "rm",
    "tlb",
    "cache",
    "h",
    "?",
    "q",
    "j"
	};


REGISTER_NAME_ID
GetRegister(
    IN PCHAR RegName
    )

/*++

Routine Description:

    This routine returns the index in the register table for the
    given register. Or invalid if the given register name doesn't
    match any register.

Arguments:

    RegName  - Null terminated string that contains the name of the register.

Return Value:

    Index on the Register Table for the requested register.

--*/

{
    REGISTER_NAME_ID RegId;

    //for (RegId = 0; RegId < MON_INVALID_REGISTER_MSG; RegId++) {
    for (RegId = 0; RegId < invalidregister; RegId++) {
        if (strcmp(RegisterNameTable[RegId],RegName) == 0) {
            break;
        }
    }
    return RegId;
}


ULONG
StrToUlong(
    IN PCHAR String,
    OUT CHAR ** Terminator
    )
/*++

Routine Description:

    This routine converts an ascii string to an unsigned long

Arguments:

    String  - Null terminated string that contains the value to convert.
    Terminator - Address of a pointer to a character. This routine
                 sets it to point to the cahracter in String that terminated
                 the conversion. This is '\0' in a normal case or whatever
                 garbage the string contained.


Return Value:

    Returns the converted string

--*/
{
    ULONG Ulong = 0;
    ULONG Index;
    for (Index=0;String[Index]; Index++) {

        if ((String[Index] >= '0') && (String[Index] <= '9')) {
            Ulong <<= 4;
            Ulong |= String[Index] - '0';
            continue;
        }

        //
        // Strings are always lower case so this is not needed.
        //
        //if ((String[Index] >= 'A') && (String[Index] <= 'F')) {
        //    Ulong <<= 4;
        //    Ulong |= String[Index] - 'A' + 10;
        //    continue;
        //}

        if ((String[Index] >= 'a') && (String[Index] <= 'f')) {
            Ulong <<= 4;
            Ulong |= String[Index] - 'a' + 10;
            continue;
        }
        *Terminator = &String[Index];
        return 0xFFFFFFF;
    }

    //
    // Check for overflow
    //
    if (Index > 8) {
        *Terminator = &String[0];
    } else {
        *Terminator = &String[Index];
    }
    return Ulong;
}


BOOLEAN
GetAddress(
    IN PUCHAR   String,
    OUT PULONG Address,
    PULONG pRegTable
    )

/*++

Routine Description:

    This routine converts an ascii string to an address. The string
    is the form:
    [@reg | value]

Arguments:

    String  -  Null terminated string that contains the address to convert.
    Address - Supplies a pointer to where the converted address is stored

Return Value:

    Returns TRUE if the string can be converted.
            FALSE otherwise.

--*/

{
    PUCHAR   Terminator;
    //UCHAR    Delimiter;
    REGISTER_NAME_ID RegId;
    if (*String == '@') {
        String++;               // skip @
        if ((RegId = GetRegister(String)) == invalidregister) {
            EdbgOutputDebugString(String);
            EdbgOutputDebugString(MON_INVALID_REGISTER_MSG);
            return FALSE;
        } else {
                *Address = *(pRegTable+RegId);
        }
    } else {
        *Address=StrToUlong(String,&Terminator);
        if (*Terminator != '\0') {
            //
            // Not the whole string was converted.
            //
            EdbgOutputDebugString(Terminator);
            EdbgOutputDebugString(MON_NOT_VALID_ADDRESS_MSG);
            return FALSE;
        }
    }
    return TRUE;
}

BOOLEAN
GetAddressRange(
    IN PCHAR   Argv[],
    OUT PULONG StartAddress,
    OUT PULONG EndAddress,
    IN PULONG pregTable
    )

/*++

Routine Description:

    This routine converts an ascii string to a range, returning the starting
    and end address.

    The syntax for an address range is one of the following

        startaddress endaddres
        startaddress l numberofelements

Arguments:

    Argv - array of zero terminated argument strings.
    StartAddress - Supplies a pointer to where the Start address is stored
    EndAddress - Supplies a pointer to where the End address is stored

Return Value:

    Returns TRUE if Argv specifies a valid address range.
            FALSE otherwise.

--*/

{
    //PCHAR Tmp;
    //CHAR  Delimiter;

    if (CurrentArg == Argc) {
        return TRUE;
    }
    if (GetAddress(Argv[CurrentArg],StartAddress,pregTable) == FALSE) {
        return FALSE;
    }
    CurrentArg++;
    if (CurrentArg == Argc) {
        *EndAddress = *StartAddress+128;
        return TRUE;
    }
    //if (strcmp(Argv[CurrentArg],"l") == 0 ) {
    if ( Argv[CurrentArg][0] == 'l' && Argv[CurrentArg][1] == '\0') {
        //
        // this is a range of the form "startaddress l count"
        //
        CurrentArg++;
        if (CurrentArg == Argc) {
            EdbgOutputDebugString(MON_INVALID_ARGUMENT_COUNT_MSG);
            return FALSE;
        }
        if (GetAddress(Argv[CurrentArg],EndAddress,pregTable) == FALSE) {
            return FALSE;
        }
        CurrentArg++;
        *EndAddress = (*EndAddress<<DataSizeShift) + *StartAddress;
    } else {
        if (GetAddress(Argv[CurrentArg],EndAddress,pregTable) == FALSE) {
            //
            // the argument didn't convert the range is Start+128
            //
            *EndAddress = *StartAddress+128;
        } else {
            CurrentArg++;
        }
    }
    //
    // Check that the range is correct End > Start
    //
    if (*EndAddress <= *StartAddress) {
        EdbgOutputDebugString(MON_INVALID_ADDRESS_RANGE_MSG);
         return FALSE;
    }
    return TRUE;
}
COMMAND_NAME_ID
GetCommand(
    IN PCHAR CommandName
    )

/*++

Routine Description:

    This routine tries to match the supplied string
    with one of the recognized commands.

Arguments:

    CommandName - Supplies a string to be matched with one of the monitor commands.

Return Value:

    Returns a value that identifies the command.

--*/
{
    COMMAND_NAME_ID Index;
    for (Index=0;Index<invalidcommand;Index++) {
        if (strcmp(CommandNameTable[Index],CommandName) == 0) {
            break;
        }
    }
    return Index;
}


BOOLEAN
ModifyRegisterCommand(
    IN PCHAR Argv[], IN PULONG pRegTable
    )

/*++

Routine Description:

    This routine will implement the REGISTER MODIFY command given the
    arguments in the argc,Argv form.

Arguments:

    Argv - array of zero terminated argument strings.

Return Value:

    Returns TRUE if the command is valid, FALSE otherwise.

--*/
{

    REGISTER_NAME_ID RegId;
    PCHAR Terminator;
    ULONG Value;
    GETSTRING_ACTION Action;
    CHAR  ValueStr[128];
    PCHAR pValueStr = ValueStr;


    switch(Argc) {

        case 2:
           if ((RegId = GetRegister(Argv[1])) == invalidregister) {
               EdbgOutputDebugString(Argv[1]);
               EdbgOutputDebugString(MON_INVALID_REGISTER_MSG);
               return FALSE;
           }
           EdbgOutputDebugString(FW_CRLF_MSG);
           //EdbgOutputDebugString("%s: %08lx", RegisterNameTable[RegId],*(pRegTable+RegId)); 
           EdbgOutputDebugString("%s: %x", RegisterNameTable[RegId],*(pRegTable+RegId)); 
           EdbgOutputDebugString(FW_CRLF_MSG);
           EdbgOutputDebugString(":");
           Action = FwGetString(ValueStr,128,NULL);
           if (Action != GetStringSuccess) return FALSE;
           break;

        case 3:
           if ((RegId = GetRegister(Argv[1])) == invalidregister) {
               EdbgOutputDebugString(Argv[1]);
               EdbgOutputDebugString(MON_INVALID_REGISTER_MSG);
               return FALSE;
           }
           pValueStr = Argv[2];
           break;

        default:
           return FALSE;

    }


    Value = StrToUlong(pValueStr,&Terminator);

    if (*Terminator != '\0') {
        EdbgOutputDebugString(Terminator);
        EdbgOutputDebugString(MON_INVALID_VALUE_MSG);
        return FALSE;
    }

    *(pRegTable+RegId) = Value;
    EdbgOutputDebugString(FW_CRLF_MSG);

    return TRUE;

}


BOOLEAN
RegisterCommand(
    IN PCHAR Argv[], IN PULONG pRegTable
    )

/*++

Routine Description:

    This routine will implement the REGISTER command given the
    arguments in the argc,Argv form.

Arguments:

    Argv - array of zero terminated argument strings.

Return Value:

    Returns TRUE if the command is valid, FALSE otherwise.

--*/
{
    REGISTER_NAME_ID RegId;
    switch(Argc) {
        case 1:
            //
            // Dump the value of all the registers
            //

#ifdef MIPS
            for (RegId=1;RegId<32;RegId++) {
                EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[RegId],*(pRegTable+RegId));
                if ((RegId%6) == 0) {
                    EdbgOutputDebugString(FW_CRLF_MSG);
                }
            }
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[psr],*(pRegTable+psr));
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[epc],*(pRegTable+epc));
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[cause],*(pRegTable+cause));
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[errorepc],*(pRegTable+errorepc));
            EdbgOutputDebugString(FW_CRLF_MSG);
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[badvaddr],*(pRegTable+badvaddr));
#endif /* MIPS */

#ifdef SHx

            for (RegId=r0RegTable; RegId>=spcRegTable; RegId--) {
                EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[RegId],*(pRegTable+RegId));
                if (((r0RegTable-RegId+1)%5) == 0) {
                    EdbgOutputDebugString(FW_CRLF_MSG);
                }
            }

            for (RegId=ar0RegTable; RegId>=ar7RegTable; RegId--) {
                EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[RegId],*(pRegTable+RegId));
                if (((r0RegTable-RegId+1)%4) == 0) {
                    EdbgOutputDebugString(FW_CRLF_MSG);
                }
            }

            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[gbrRegTable],*(pRegTable+gbrRegTable));
            EdbgOutputDebugString(MON_FORMAT1_MSG,RegisterNameTable[vbrRegTable],*(pRegTable+vbrRegTable));


#endif /* SH3 */
            EdbgOutputDebugString(FW_CRLF_MSG);
            return TRUE;
        case 2:
            //
            // Dump the value of the specified register.
            //
            if ((RegId = GetRegister(Argv[1])) == invalidregister) {
                EdbgOutputDebugString(Argv[1]);
                EdbgOutputDebugString(MON_INVALID_REGISTER_MSG);
                return FALSE;
            } else {
                //EdbgOutputDebugString("%s = %08lx\r\n",RegisterNameTable[RegId],*(pRegTable+RegId));
                EdbgOutputDebugString("%s = %x\r\n",RegisterNameTable[RegId],*(pRegTable+RegId));
                return TRUE;
            }
        default:
                EdbgOutputDebugString(MON_INVALID_ARGUMENT_COUNT_MSG);
                return FALSE;
    }
}

VOID
InputValue(
    IN ULONG Address,
    OUT PVOID Value
    )
/*++

Routine Description:

    This routine reads a value from the supplied address and displays
    it. DataSize is set to the size of the value to read.

Arguments:

    Address  - Supplies the address where the value is to be read from.
    Value    - Pointer to where the value read is stored.

Return Value:

    None.

--*/
{

    switch(DataSize) {
        case    BYTE_SIZE:
                    *(PUCHAR)Value = *(volatile PUCHAR)Address;   // read byte
                    //EdbgOutputDebugString("%02x ",*(PUCHAR)Value);
                    EdbgOutputDebugString("%x ",*(PUCHAR)Value);
                    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -