public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* RE: [ECOS] Adding commands to RedBoot
@ 2001-09-19 11:22 Warren Jasper
  2001-09-19 13:38 ` Jonathan Larmour
  0 siblings, 1 reply; 7+ messages in thread
From: Warren Jasper @ 2001-09-19 11:22 UTC (permalink / raw)
  To: ecos-discuss

[-- Attachment #1: Type: text/plain, Size: 2118 bytes --]

Here is a version of redboot/current/src/main.c that supports 2 new
functions:

edit -b <address> -v <value> [-s <size>]
fill -b <address> -l <length> -v <value>

size is the size in bytes of the value, either 1, 2, or 4 (sorry, no 64 bit
support yet).
If the -s option is omitted, the default is 4 (32 bits)

The function that does all the work is called diag_edit().  I'm not sure it
should
go in main.c, so I've just included it here.  I put it in
infra/current/src/diag.cxx at the bottom, next to the dump utilities. From
the email
Jonathan suggests otherwise.

#include <cyg/hal/hal_io.h>

externC void
diag_edit(void *p, unsigned long x, unsigned long s)
{
  switch(s) {
    case 1:
      HAL_WRITE_UINT8(p,(unsigned char) x);
      break;
    case 2:
      HAL_WRITE_UINT16(p,(unsigned short) x);
      break;
    case 4:
      HAL_WRITE_UINT32(p,(unsigned long) x);
      break;
  }
}

Enjoy,

Warren

-----Original Message-----
From: Jonathan Larmour [ mailto:jlarmour@redhat.com ]
Sent: Tuesday, September 18, 2001 4:30 PM
To: Warren Jasper
Cc: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] Adding commands to RedBoot


Warren Jasper wrote:
> 
> What is the preferred way to add/extend commands to RedBoot?

If you've looked at the sources, you've probably already seen RedBoot_Cmd.

> Specifically, it would be nice to have 2 command to augment dump, namely:
> 
> edit -b <location> -v <value>
> 
> fill -b <location> -l <length> -v <value>
> 
> Should these functions reside in diag.cxx and just put the calls in
> /redboot/current/main.c?

diag.cxx? Surely not. Put them in main.c beside dump. Although once we
reach that point, we may choose to break some of the commands out of main.c
as it's getting quite big...

> Somewhere they should call the macro HAL_WRITE_UINT32.

Yep, or whatever HAL macros are appropriate. There should probably be a
size argument to edit (byte, halfword, word, or perhaps instead just the
length in bytes).

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine


[-- Attachment #2: main.c --]
[-- Type: text/x-c, Size: 20558 bytes --]

//==========================================================================
//
//      main.c
//
//      RedBoot main routine
//
//==========================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    gthomas
// Contributors: gthomas
// Date:         2000-07-14
// Purpose:      
// Description:  
//              
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================

#define  DEFINE_VARS
#include <redboot.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_if.h>
#include <cyg/hal/hal_cache.h>
#include CYGHWR_MEMORY_LAYOUT_H

#include <cyg/hal/hal_tables.h>

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
#include CYGBLD_HAL_PLATFORM_STUB_H
#else
#include <cyg/hal/plf_stub.h>
#endif
#endif

// Builtin Self Test (BIST)
externC void bist(void);

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
// GDB interfaces
extern void breakpoint(void);
#endif

// CLI command processing (defined in this file)
RedBoot_cmd("version", 
            "Display RedBoot version information",
            "",
            do_version
    );
RedBoot_cmd("help", 
            "Help about help?", 
            "[<topic>]",
            do_help 
    );
RedBoot_cmd("go", 
            "Execute code at a location", 
            "[-w <timeout>] [entry]",
            do_go 
    );
RedBoot_cmd("dump", 
            "Display (hex dump) a range of memory", 
            "-b <location> [-l <length>]",
            do_dump 
    );
RedBoot_cmd("edit", 
            "Edit the contents of memory", 
            "-b <location> -v <value> [-s <size>]",
            do_edit 
    );
RedBoot_cmd("fill", 
            "Fill the contents of memory", 
            "-b <location> -l <length> -v <value>",
            do_fill 
    );
RedBoot_cmd("cksum", 
            "Compute a 32bit checksum [POSIX algorithm] for a range of memory", 
            "-b <location> -l <length>",
            do_cksum
    );
RedBoot_cmd("cache", 
            "Manage machine caches", 
            "[ON | OFF]",
            do_caches 
    );
#ifdef HAL_PLATFORM_RESET
RedBoot_cmd("reset", 
            "Reset the system", 
            "",
            do_reset 
    );
#endif
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
RedBoot_cmd("baudrate", 
            "Set/Query the system console baud rate", 
            "[-b <rate>]",
            do_baud_rate
    );
#endif

// Define table boundaries
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;

CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;

CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;

#ifdef HAL_ARCH_PROGRAM_NEW_STACK
extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
#endif

#ifdef CYGSEM_REDBOOT_FLASH_ALIASES
externC void expand_aliases(char *line, int len);
#endif

void
do_version(int argc, char *argv[])
{
    extern char RedBoot_version[];
#ifdef CYGPKG_IO_FLASH
    externC void _flash_info(void);
#endif

    diag_printf(RedBoot_version);
#ifdef HAL_PLATFORM_CPU
    diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
#endif
    diag_printf("Copyright (C) 2000, 2001, Red Hat, Inc.\n\n");
    diag_printf("RAM: %p-%p, %p-%p available\n", 
                (void*)ram_start, (void*)ram_end,
                (void*)user_ram_start, (void *)user_ram_end);
#ifdef CYGPKG_IO_FLASH
    _flash_info();
#endif
}

void
do_idle(bool is_idle)
{
    struct idle_tab_entry *idle_entry;

    for (idle_entry = __RedBoot_IDLE_TAB__; 
         idle_entry != &__RedBoot_IDLE_TAB_END__;  idle_entry++) {
        (*idle_entry->fun)(is_idle);
    }
}

// Wrapper used by diag_printf()
static void
_mon_write_char(char c, void **param)
{
    mon_write_char(c);
}

//
// This is the main entry point for RedBoot
//
void
cyg_start(void)
{
    int res = 0;
    bool prompt = true;
    static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
    char *command;
    struct cmd *cmd;
    int cur;
    struct init_tab_entry *init_entry;

    // Make sure the channels are properly initialized.
    diag_init_putc(_mon_write_char);
    hal_if_diag_init();

    // Force console to output raw text - but remember the old setting
    // so it can be restored if interaction with a debugger is
    // required.
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
    console_selected = false;
#endif
    console_echo = true;
    CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);

    ram_start = (unsigned char *)CYGMEM_REGION_ram;
    ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
#ifdef HAL_MEM_REAL_REGION_TOP
    {
        unsigned char *ram_end_tmp = ram_end;
        ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
    }
#endif
#ifdef CYGMEM_SECTION_heap1
    workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
    workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
    workspace_size = CYGMEM_SECTION_heap1_SIZE;
#else
    workspace_start = (unsigned char *)CYGMEM_REGION_ram;
    workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
    workspace_size = CYGMEM_REGION_ram_SIZE;
#endif

    if ( ram_end < workspace_end ) {
        // when *less* SDRAM is installed than the possible maximum,
        // but the heap1 region remains greater...
        workspace_end = ram_end;
        workspace_size = workspace_end - workspace_start;
    }

    bist();

    for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__;  init_entry++) {
        (*init_entry->fun)();
    }

#ifdef CYGPKG_COMPRESS_ZLIB
#define ZLIB_COMPRESSION_OVERHEAD 0xB800
#else
#define ZLIB_COMPRESSION_OVERHEAD 0
#endif
    user_ram_start = workspace_start + ZLIB_COMPRESSION_OVERHEAD;
    user_ram_end = workspace_end;
    do_version(0,0);

#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
    if (!script) {
      script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
#  ifndef CYGSEM_REDBOOT_FLASH_CONFIG
      script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
#  endif
    }
# endif
    if (script) {
        // Give the guy a chance to abort any boot script
        unsigned char *hold_script = script;
        int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
        diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                    script_timeout_ms/1000, script_timeout_ms%1000);
        script = (unsigned char *)0;
        res = _GETS_CTRLC;  // Treat 0 timeout as ^C
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res >= _GETS_OK) {
                diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                            script_timeout_ms/1000, script_timeout_ms%1000);
                continue;  // Ignore anything but ^C
            }
            if (res != _GETS_TIMEOUT) break;
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
        if (res == _GETS_CTRLC) {
            script = (unsigned char *)0;  // Disable script
        } else {
            script = hold_script;  // Re-enable script
        }
    }
#endif

    while (true) {
        if (prompt) {
            diag_printf("RedBoot> ");
            prompt = false;
        }
        res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
        if (res == _GETS_TIMEOUT) {
            // No input arrived
        } else {
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            if (res == _GETS_GDB) {
		int dbgchan;
                hal_virtual_comm_table_t *__chan;
                int i;
                // Special case of '$' - need to start GDB protocol
                gdb_active = true;
                // Mask interrupts on all channels
                for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
                    CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
                    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
                    CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
                }
    
                CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
                HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
#else
                breakpoint();  // Get GDB stubs started, with a proper environment, etc.
#endif
		dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
		CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
            } else 
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            {
#ifdef CYGSEM_REDBOOT_FLASH_ALIASES
                expand_aliases(line, sizeof(line));
#endif
		command = (char *)&line;
                while (strlen(command) > 0) {                    
                    if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
                        (cmd->fun)(argc, argv);
                    } else {
                        diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
                    }
                }
                prompt = true;
            }
        }
    }
}

void
do_caches(int argc, char *argv[])
{
    unsigned long oldints;
    int dcache_on=0, icache_on=0;

    if (argc == 2) {
        if (strcasecmp(argv[1], "on") == 0) {
            HAL_DISABLE_INTERRUPTS(oldints);
            HAL_ICACHE_ENABLE();
            HAL_DCACHE_ENABLE();
            HAL_RESTORE_INTERRUPTS(oldints);
        } else if (strcasecmp(argv[1], "off") == 0) {
            HAL_DISABLE_INTERRUPTS(oldints);
            HAL_DCACHE_SYNC();
            HAL_ICACHE_DISABLE();
            HAL_DCACHE_DISABLE();
            HAL_DCACHE_SYNC();
            HAL_ICACHE_INVALIDATE_ALL();
            HAL_DCACHE_INVALIDATE_ALL();
            HAL_RESTORE_INTERRUPTS(oldints);
        } else {
            diag_printf("Invalid cache mode: %s\n", argv[1]);
        }
    } else {
#ifdef HAL_DCACHE_IS_ENABLED
        HAL_DCACHE_IS_ENABLED(dcache_on);
#endif
#ifdef HAL_ICACHE_IS_ENABLED
        HAL_ICACHE_IS_ENABLED(icache_on);
#endif
        diag_printf("Data cache: %s, Instruction cache: %s\n", 
                    dcache_on?"On":"Off", icache_on?"On":"Off");
    }
}


void
do_help(int argc, char *argv[])
{
    struct cmd *cmd;
    char *which = (char *)0;
    bool show;
    int len = 0;

    if (!scan_opts(argc, argv, 1, 0, 0, (void **)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
        diag_printf("Invalid argument\n");
        return;
    }
    if (which) {
        len = strlen(which);
    }
    cmd = __RedBoot_CMD_TAB__;
    while (cmd != &__RedBoot_CMD_TAB_END__) {
        show = true;
        if (which && (strncasecmp(which, cmd->str, len) != 0)) {
            show = false;
        }
        if (show) {
            diag_printf("%s\n   %s %s\n", cmd->help, cmd->str, cmd->usage);
        }
        cmd++;
    }
    return;
}

void
do_dump(int argc, char *argv[])
{
    struct option_info opts[2];
    unsigned long base, len;
    bool base_set, len_set;
    static unsigned long _base, _len;

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&base, (bool *)&base_set, "base address");
    init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
              (void **)&len, (bool *)&len_set, "length");
    if (!scan_opts(argc, argv, 1, opts, 2, 0, 0, "")) {
        return;
    }
    if (!base_set) {
        if (_base == 0) {
            diag_printf("Dump what [location]?\n");
            return;
        }
        base = _base;
        if (!len_set) {
            len = _len;
            len_set = true;
        }
    }
    if (!len_set) {
        len = 32;
    }
    diag_dump_buf((void *)base, len);
    _base = base + len;
    _len = len;
}

void
do_edit(int argc, char *argv[])
{
    struct option_info opts[3];
    unsigned long base, value, size;
    bool base_set, value_set, size_set;
    static unsigned long _base;
    
    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&base, (bool *)&base_set, "base address");
    init_opts(&opts[1], 'v', true, OPTION_ARG_TYPE_NUM, 
              (void **)&value, (bool *)&value_set, "value");
    init_opts(&opts[2], 's', true, OPTION_ARG_TYPE_NUM, 
              (void **)&size, (bool *)&size_set, "size");
    if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, "")) {
        return;
    }

    if (!base_set) {
        if (_base == 0) {
            diag_printf("Edit what [location]?\n");
            return;
        }
        base = _base;
    }

    if (!value_set) {
          diag_printf("Edit what [value]?\n");
          return;
    }
    if (!size_set) {
        size = 4;
    }

     diag_edit((void*)base, value, size);
    _base += size;
}

void
do_fill(int argc, char *argv[])
{
    struct option_info opts[3];
    unsigned long base, len, value;
    bool base_set, len_set, value_set;
    unsigned long i;
    
    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&base, (bool *)&base_set, "base address");
    init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
              (void **)&len, (bool *)&len_set, "length");
    init_opts(&opts[2], 'v', true, OPTION_ARG_TYPE_NUM, 
              (void **)&value, (bool *)&value_set, "value");
    if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, "")) {
        return;
    }

    if (!base_set) {
        diag_printf("Fill what [location]?\n");
        return;
    }

    if (!len_set) {
        diag_printf("Fill what [length]?\n");
        return;
    }

    if (!value_set) {
        diag_printf("Fill what [value]?\n");
        return;
    }

    for ( i = 0; i < len; i++ ) {
      diag_edit((void*)base, value, 4);
      base += sizeof(long);
    }
}

void
do_cksum(int argc, char *argv[])
{
    // Compute a CRC, using the POSIX 1003 definition
    extern unsigned long 
        posix_crc32(unsigned char *s, int len);

    struct option_info opts[2];
    unsigned long base, len, crc;
    bool base_set, len_set;

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&base, (bool *)&base_set, "base address");
    init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
              (void **)&len, (bool *)&len_set, "length");
    if (!scan_opts(argc, argv, 1, opts, 2, 0, 0, "")) {
        return;
    }
    if (!base_set || !len_set) {
        diag_printf("usage: cksum -b <addr> -l <length>\n");
        return;
    }
    crc = posix_crc32((unsigned char *)base, len);
    diag_printf("POSIX cksum = 0x%08lx (%lu)\n", crc, crc);
}

void
do_go(int argc, char *argv[])
{
    typedef void code_fun(void);
    unsigned long entry;
    unsigned long oldints;
    code_fun *fun;
    bool wait_time_set;
    int  wait_time, res;
    struct option_info opts[1];
    char line[8];

    entry = (unsigned long)entry_address;  // Default from last 'load' operation
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, 
              (void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
    if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
    {
        return;
    }
    if (wait_time_set) {
        int script_timeout_ms = wait_time * 1000;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
        unsigned char *hold_script = script;
        script = (unsigned char *)0;
#endif
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
                    (void *)entry, wait_time);
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res == _GETS_CTRLC) {
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
                script = hold_script;  // Re-enable script
#endif
                return;
            }
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
    }
    fun = (code_fun *)entry;
    HAL_DISABLE_INTERRUPTS(oldints);
    HAL_DCACHE_SYNC();
    HAL_ICACHE_DISABLE();
    HAL_DCACHE_DISABLE();
    HAL_DCACHE_SYNC();
    HAL_ICACHE_INVALIDATE_ALL();
    HAL_DCACHE_INVALIDATE_ALL();
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
    HAL_ARCH_PROGRAM_NEW_STACK(fun);
#else
    (*fun)();
#endif
}

#ifdef HAL_PLATFORM_RESET
void
do_reset(int argc, char *argv[])
{
    diag_printf("... Resetting.");
    CYGACC_CALL_IF_DELAY_US(2*100000);
    diag_printf("\n");
    CYGACC_CALL_IF_RESET();
    diag_printf("!! oops, RESET not working on this platform\n");
}
#endif

#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <flash_config.h>
#endif

void
set_console_baud_rate(int rate)
{
    hal_virtual_comm_table_t *__chan;
    int ret;
    static int current_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;

    if (rate != current_rate) {
        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
        ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SETBAUD, rate);
        if (ret <= 0) {
            diag_printf("Failed\n");
        }
        current_rate = rate;
    }
}

void
do_baud_rate(int argc, char *argv[])
{
    int new_rate, ret;
    bool new_rate_set;
    hal_virtual_comm_table_t *__chan;
    struct option_info opts[1];
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
    struct config_option opt;
#endif

    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&new_rate, (bool *)&new_rate_set, "new baud rate");
    if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
        return;
    }
    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
    if (new_rate_set) {
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
        opt.type = CONFIG_INT;
        opt.enable = (char *)0;
        opt.enable_sense = 1;
        opt.key = "console_baud_rate";
        opt.dflt = new_rate;
        flash_add_config(&opt, true);
#endif
        set_console_baud_rate(new_rate);
    } else {
        ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
        diag_printf("Baud rate = ");
        if (ret <= 0) {
            diag_printf("unknown\n");
        } else {
            diag_printf("%d\n", ret);
        }
    }
}
#endif

// 
// [Null] Builtin [Power On] Self Test
//
void bist(void) CYGBLD_ATTRIB_WEAK;

void
bist(void) 
{
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ECOS] Adding commands to RedBoot
  2001-09-19 11:22 [ECOS] Adding commands to RedBoot Warren Jasper
@ 2001-09-19 13:38 ` Jonathan Larmour
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Larmour @ 2001-09-19 13:38 UTC (permalink / raw)
  To: Warren Jasper; +Cc: ecos-discuss

Warren Jasper wrote:
> 
> Here is a version of redboot/current/src/main.c that supports 2 new
> functions:
> 
> edit -b <address> -v <value> [-s <size>]
> fill -b <address> -l <length> -v <value>

Thanks! Could you supply it as a diff generated by "cvs diff -u -p" please?
And a ChangeLog entry would be even better, thanks!
 
Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [ECOS] Adding commands to RedBoot
       [not found] <6476CB7C06B86D46A0C5BF34EACD383303730C@rtpsrv001.rtp.bops.com>
@ 2001-12-06  7:03 ` Jesper Skov
  0 siblings, 0 replies; 7+ messages in thread
From: Jesper Skov @ 2001-12-06  7:03 UTC (permalink / raw)
  To: Warren Jasper; +Cc: 'ecos-discuss@sources.redhat.com'

On Fri, 2001-11-02 at 21:23, Warren Jasper wrote:
> Hi Jesper,
> 
> I modified dump to include word and long dumps with an optional -L or -W.
> If you want
> bytes back, use a -B option.  
> 
> dump -b <location> [-l <length>] [-B|W|L]

Warren, sorry for taking so long with this.

I've made some changes to the code, and made it use -1|2|4 instead to
avoid confusion about the terms word and long (as suggested by Jifl in
private mail).

I have not included the edit or fill commands as I'd like to do them
differently (I haven't taken the time to think about how I'd like to see
it done, sorry).

Jesper


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ECOS] Adding commands to RedBoot
  2001-10-17  7:09 Warren Jasper
@ 2001-10-18  2:16 ` Jesper Skov
  0 siblings, 0 replies; 7+ messages in thread
From: Jesper Skov @ 2001-10-18  2:16 UTC (permalink / raw)
  To: Warren Jasper; +Cc: ecos-discuss

>>>>> "Warren" == Warren Jasper <Warren.Jasper@bops.com> writes:

Warren> The dump command in redboot only does byte addressing.  There
Warren> are some busses that only do 32 bit (long ) addressing (word
Warren> aligned).  I've added a new command to redboot called dumpl,
Warren> which works almost like dump, (without the characters), that
Warren> dumps words.  Here are the patches for your enjoyment. I've
Warren> found it very useful for debugging.

I haven't looked at the code, but would you mind rewriting it so the
existing dump command takes (optional) -w and -l flags, selecting word
(16 bit) and long (32 bit) dumps?

Jesper

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [ECOS] Adding commands to RedBoot
@ 2001-10-17  7:09 Warren Jasper
  2001-10-18  2:16 ` Jesper Skov
  0 siblings, 1 reply; 7+ messages in thread
From: Warren Jasper @ 2001-10-17  7:09 UTC (permalink / raw)
  To: ecos-discuss

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

The dump command in redboot only does byte addressing.  There are some
busses that only do 32 bit (long ) addressing (word aligned).  I've added
a new command to redboot called dumpl, which works almost
like dump, (without the characters), that dumps words.
Here are the patches for your enjoyment. I've found it very useful
for debugging.

Warren

The Change log entries are:

ecos/packages/infra/current/Changelog
2001-10-17  Warren Jasper  <warrenj@bops.com>
	* src/diag.cxx added diag_buf_with_offset_long and
diag_dump_buf_long
        to do 32 bit assigned reads.

ecos/packages/redboot/current/Changelog
2001-10-17  Warren Jasper <warrenj@bops.com>
	* src/main.c  added dumpl to display 32 bit quantities.



[-- Attachment #2: diag.cxx.patch --]
[-- Type: text/x-diff, Size: 2010 bytes --]

Index: diag.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/infra/current/src/diag.cxx,v
retrieving revision 1.9
diff -u -p -r1.9 diag.cxx
--- diag.cxx	2001/09/12 04:21:15	1.9
+++ diag.cxx	2001/10/17 13:55:19
@@ -51,6 +51,7 @@
 #include <cyg/hal/hal_arch.h>           // architectural stuff for...
 #include <cyg/hal/hal_intr.h>           // interrupt control
 #include <cyg/hal/hal_diag.h>           // diagnostic output routines
+#include <cyg/hal/hal_io.h>             // io read/write to memory
 #include <stdarg.h>
 #include <limits.h>
   
@@ -596,6 +597,57 @@ diag_dump_buf(void *p, CYG_ADDRWORD s)
 {
    diag_dump_buf_with_offset((cyg_uint8 *)p, s, 0);
 }
+
+void
+diag_dump_buf_with_offset_long(cyg_uint32 *p, 
+                          CYG_ADDRWORD     s, 
+                          cyg_uint32      *base)
+{
+    int i, c;
+    if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
+        s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
+    }
+    while ((int)s > 0) {
+        if (base) {
+            diag_printf("%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
+        } else {
+            diag_printf("%08X: ", p);
+        }
+        for (i = 0;  i < 4;  i++) {
+            if (i < (int)s/4) {
+                diag_printf("%08X ", p[i] );
+            } else {
+                diag_printf("         ");
+            }
+        }
+        diag_printf("\n");
+        s -= 16;
+        p += 4;
+    }
+}
+
+externC void
+diag_dump_buf_long(void *p, CYG_ADDRWORD s)
+{
+   diag_dump_buf_with_offset_long((cyg_uint32 *)p, s, 0);
+}
+
+externC void
+diag_edit(void *p, unsigned long x, unsigned long s)
+{
+  switch(s) {
+    case 1:
+      HAL_WRITE_UINT8(p,(unsigned char) x);
+      break;
+    case 2:
+      HAL_WRITE_UINT16(p,(unsigned short) x);
+      break;
+    case 4:
+      HAL_WRITE_UINT32(p,(unsigned long) x);
+      break;
+  }
+}
+
 
 /*-----------------------------------------------------------------------*/
 /* EOF infra/diag.c */

[-- Attachment #3: main.patch --]
[-- Type: text/x-diff, Size: 4253 bytes --]

Index: main.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/main.c,v
retrieving revision 1.24
diff -b -p -r1.24 main.c
*** main.c	2001/09/12 04:21:16	1.24
--- main.c	2001/10/17 13:53:02
*************** RedBoot_cmd("dump", 
*** 90,95 ****
--- 90,110 ----
              "-b <location> [-l <length>]",
              do_dump 
      );
+ RedBoot_cmd("dumpl", 
+             "Display (hex dump) a range of memory", 
+             "-b <location> [-l <length>]",
+             do_dumpl 
+     );
+ RedBoot_cmd("edit", 
+             "Edit the contents of memory", 
+             "-b <location> -v <value> [-s <size>]",
+             do_edit 
+     );
+ RedBoot_cmd("fill", 
+             "Fill the contents of memory", 
+             "-b <location> -l <length> -v <value>",
+             do_fill 
+     );
  RedBoot_cmd("cksum", 
              "Compute a 32bit checksum [POSIX algorithm] for a range of memory", 
              "-b <location> -l <length>",
*************** do_dump(int argc, char *argv[])
*** 428,433 ****
--- 443,559 ----
      diag_dump_buf((void *)base, len);
      _base = base + len;
      _len = len;
+ }
+ 
+ void
+ do_dumpl(int argc, char *argv[])
+ {
+     struct option_info opts[2];
+     unsigned long base, len;
+     bool base_set, len_set;
+     static unsigned long _base, _len;
+ 
+     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&base, (bool *)&base_set, "base address");
+     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&len, (bool *)&len_set, "length");
+     if (!scan_opts(argc, argv, 1, opts, 2, 0, 0, "")) {
+         return;
+     }
+     if (!base_set) {
+         if (_base == 0) {
+             diag_printf("Dump what [location]?\n");
+             return;
+         }
+         base = _base;
+         if (!len_set) {
+             len = _len;
+             len_set = true;
+         }
+     }
+     if (!len_set) {
+         len = 32;
+     }
+     diag_dump_buf_long((void *)base, len);
+     _base = base + len;
+     _len = len;
+ }
+ 
+ void
+ do_edit(int argc, char *argv[])
+ {
+     struct option_info opts[3];
+     unsigned long base, value, size;
+     bool base_set, value_set, size_set;
+     static unsigned long _base;
+     
+     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&base, (bool *)&base_set, "base address");
+     init_opts(&opts[1], 'v', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&value, (bool *)&value_set, "value");
+     init_opts(&opts[2], 's', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&size, (bool *)&size_set, "size");
+     if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, "")) {
+         return;
+     }
+ 
+     if (!base_set) {
+         if (_base == 0) {
+             diag_printf("Edit what [location]?\n");
+             return;
+         }
+         base = _base;
+     }
+ 
+     if (!value_set) {
+           diag_printf("Edit what [value]?\n");
+           return;
+     }
+     if (!size_set) {
+         size = 4;
+     }
+ 
+      diag_edit((void*)base, value, size);
+     _base += size;
+ }
+ 
+ void
+ do_fill(int argc, char *argv[])
+ {
+     struct option_info opts[3];
+     unsigned long base, len, value;
+     bool base_set, len_set, value_set;
+     unsigned long i;
+     
+     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&base, (bool *)&base_set, "base address");
+     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&len, (bool *)&len_set, "length");
+     init_opts(&opts[2], 'v', true, OPTION_ARG_TYPE_NUM, 
+               (void **)&value, (bool *)&value_set, "value");
+     if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, "")) {
+         return;
+     }
+ 
+     if (!base_set) {
+         diag_printf("Fill what [location]?\n");
+         return;
+     }
+ 
+     if (!len_set) {
+         diag_printf("Fill what [length]?\n");
+         return;
+     }
+ 
+     if (!value_set) {
+         diag_printf("Fill what [value]?\n");
+         return;
+     }
+ 
+     for ( i = 0; i < len; i++ ) {
+       diag_edit((void*)base, value, 4);
+       base += sizeof(long);
+     }
  }
  
  void

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [ECOS] Adding commands to RedBoot
  2001-09-17  5:58 Warren Jasper
@ 2001-09-18 13:29 ` Jonathan Larmour
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Larmour @ 2001-09-18 13:29 UTC (permalink / raw)
  To: Warren Jasper; +Cc: ecos-discuss

Warren Jasper wrote:
> 
> What is the preferred way to add/extend commands to RedBoot?

If you've looked at the sources, you've probably already seen RedBoot_Cmd.

> Specifically, it would be nice to have 2 command to augment dump, namely:
> 
> edit -b <location> -v <value>
> 
> fill -b <location> -l <length> -v <value>
> 
> Should these functions reside in diag.cxx and just put the calls in
> /redboot/current/main.c?

diag.cxx? Surely not. Put them in main.c beside dump. Although once we
reach that point, we may choose to break some of the commands out of main.c
as it's getting quite big...

> Somewhere they should call the macro HAL_WRITE_UINT32.

Yep, or whatever HAL macros are appropriate. There should probably be a
size argument to edit (byte, halfword, word, or perhaps instead just the
length in bytes).

Jifl
-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ECOS] Adding commands to RedBoot
@ 2001-09-17  5:58 Warren Jasper
  2001-09-18 13:29 ` Jonathan Larmour
  0 siblings, 1 reply; 7+ messages in thread
From: Warren Jasper @ 2001-09-17  5:58 UTC (permalink / raw)
  To: ecos-discuss

What is the preferred way to add/extend commands to RedBoot?

Specifically, it would be nice to have 2 command to augment dump, namely:

edit -b <location> -v <value>

fill -b <location> -l <length> -v <value>

Should these functions reside in diag.cxx and just put the calls in
/redboot/current/main.c?

Somewhere they should call the macro HAL_WRITE_UINT32.

If you think it's a good idea and these are the right places, I'll give it a
shot.

Warren

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2001-12-06 15:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-19 11:22 [ECOS] Adding commands to RedBoot Warren Jasper
2001-09-19 13:38 ` Jonathan Larmour
     [not found] <6476CB7C06B86D46A0C5BF34EACD383303730C@rtpsrv001.rtp.bops.com>
2001-12-06  7:03 ` Jesper Skov
  -- strict thread matches above, loose matches on Subject: below --
2001-10-17  7:09 Warren Jasper
2001-10-18  2:16 ` Jesper Skov
2001-09-17  5:58 Warren Jasper
2001-09-18 13:29 ` Jonathan Larmour

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).