OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [redboot/] [current/] [src/] [main.c] - Blame information for rev 838

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      main.c
4
//
5
//      RedBoot main routine
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    gthomas
43
// Contributors: gthomas, tkoeller, eCosCentric
44
// Date:         2000-07-14
45
// Purpose:      
46
// Description:  
47
//              
48
// This code is part of RedBoot (tm).
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#define  DEFINE_VARS
55
#include <redboot.h>
56
#include <cyg/hal/hal_arch.h>
57
#include <cyg/hal/hal_intr.h>
58
#include <cyg/hal/hal_if.h>
59
#include <cyg/hal/hal_cache.h>
60
#include CYGHWR_MEMORY_LAYOUT_H
61
 
62
#ifdef CYGPKG_IO_ETH_DRIVERS
63
#include <cyg/io/eth/eth_drv.h>            // Logical driver interfaces
64
#endif
65
 
66
#include <cyg/hal/hal_tables.h>
67
#include <cyg/infra/cyg_ass.h>         // assertion macros
68
#include <cyg/infra/cyg_type.h>
69
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
70
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
71
#include CYGBLD_HAL_PLATFORM_STUB_H
72
#else
73
#include <cyg/hal/plf_stub.h>
74
#endif
75
// GDB interfaces
76
extern void breakpoint(void);
77
#endif
78
 
79
// Builtin Self Test (BIST)
80
externC void bist(void);
81
 
82
// Path to code run from a go command or to GDB stubs
83
static void trampoline(unsigned long entry);
84
 
85
// Return path for code run from a go command or for GDB stubs
86
static void return_to_redboot(int status);
87
 
88
// Address of area where current context is saved before executing
89
// trampoline procedure
90
static void * saved_context;
91
 
92
// Status returned after trampoline execution
93
static int return_status;
94
 
95
 
96
// CLI command processing (defined in this file)
97
RedBoot_cmd("version",
98
            "Display RedBoot version information",
99
            "",
100
            do_version
101
    );
102
RedBoot_cmd("help",
103
            "Help about help?",
104
            "[<topic>]",
105
            do_help
106
    );
107
 
108
static char go_usage[] = "[-w <timeout>] [-c] "
109
#ifdef CYGPKG_IO_ETH_DRIVERS
110
                      "[-n] "
111
#endif
112
                      "[entry]";
113
 
114
RedBoot_cmd("go",
115
            "Execute code at a location",
116
            go_usage,
117
            do_go
118
    );
119
#ifdef HAL_PLATFORM_RESET
120
RedBoot_cmd("reset",
121
            "Reset the system",
122
            "",
123
            do_reset
124
    );
125
#endif
126
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
127
RedBoot_cmd("baudrate",
128
            "Set/Query the system console baud rate",
129
            "[-b <rate>]",
130
            do_baud_rate
131
    );
132
#endif
133
 
134
// Define table boundaries
135
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
136
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
137
extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;
138
 
139
CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
140
CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
141
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
142
 
143
CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
144
CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
145
extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;
146
 
147
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
148
extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
149
#endif
150
 
151
// 
152
// [Null] Builtin [Power On] Self Test
153
//
154
void bist(void) CYGBLD_ATTRIB_WEAK;
155
 
156
void
157
bist(void)
158
{
159
}
160
 
161
//
162
// 'version' command
163
//
164
void
165
do_version(int argc, char *argv[])
166
{
167
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
168
    int seg;
169
#endif
170
#ifdef CYGPKG_REDBOOT_FLASH
171
    externC void _flash_info(void);
172
#endif
173
    char *version = CYGACC_CALL_IF_MONITOR_VERSION();
174
 
175
    diag_printf(version);
176
    diag_printf("Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009\nFree Software Foundation, Inc.\n");
177
    /* The following line fulfils requirement 2(c) of the GPL. If you modify it, ensure
178
     * you remain compliant with the GPL requirements. Removing it entirely constitutes
179
     * a breach of the GPL, and you should note section 4 of the GPL as to what that means!
180
     */
181
    diag_printf("RedBoot is free software, covered by the eCos license, derived from the\n"
182
                "GNU General Public License. You are welcome to change it and/or distribute\n"
183
                "copies of it under certain conditions. Under the license terms, RedBoot's\n"
184
                "source code and full license terms must have been made available to you.\n"
185
                "Redboot comes with ABSOLUTELY NO WARRANTY.\n\n");
186
#ifdef HAL_PLATFORM_CPU
187
    diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
188
#endif
189
    diag_printf("RAM: %p-%p ", (void*)ram_start, (void*)ram_end);
190
    diag_printf("[%p-%p available]\n", mem_segments[0].start, mem_segments[0].end);
191
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
192
    for (seg = 1;  seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS;  seg++) {
193
        if (mem_segments[seg].start != NO_MEMORY) {
194
            diag_printf("     %p-%p ", mem_segments[seg].start, mem_segments[seg].end);
195
            diag_printf("[%p-%p available]\n", mem_segments[seg].start, mem_segments[seg].end);
196
        }
197
    }
198
#endif
199
#ifdef CYGPKG_REDBOOT_FLASH
200
    _flash_info();
201
#endif
202
}
203
 
204
//
205
// This function is called when RedBoot is idle (waiting for user
206
// input).  It will call any registered "idle" routines, e.g. scan
207
// for incoming network connections, blank an LCD screen, etc.
208
//
209
void
210
do_idle(bool is_idle)
211
{
212
    struct idle_tab_entry *idle_entry;
213
 
214
    for (idle_entry = __RedBoot_IDLE_TAB__;
215
         idle_entry != &__RedBoot_IDLE_TAB_END__;  idle_entry++) {
216
        (*idle_entry->fun)(is_idle);
217
    }
218
}
219
 
220
// Wrapper used by diag_printf()
221
static void
222
_mon_write_char(char c, void **param)
223
{
224
    if (c == '\n') {
225
        mon_write_char('\r');
226
    }
227
    mon_write_char(c);
228
}
229
 
230
//
231
// Handle illegal memory accesses (and other abort conditions)
232
//
233
static hal_jmp_buf error_jmpbuf;
234
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
235
__externC void* volatile __mem_fault_handler;
236
 
237
static void error_handler(void)
238
{
239
    hal_longjmp(error_jmpbuf, 1);
240
}
241
#endif
242
 
243
 
244
//
245
// This is the main entry point for RedBoot
246
//
247
 
248
void
249
cyg_start(void)
250
{
251
    int res = 0;
252
    bool prompt = true;
253
    static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
254
    char *command;
255
    struct cmd *cmd;
256
    int cur;
257
    struct init_tab_entry *init_entry;
258
    extern char RedBoot_version[];
259
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
260
    int seg;
261
#endif
262
 
263
    // Export version information
264
    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
265
 
266
    CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
267
 
268
    // Make sure the channels are properly initialized.
269
    diag_init_putc(_mon_write_char);
270
    hal_if_diag_init();
271
 
272
    // Force console to output raw text - but remember the old setting
273
    // so it can be restored if interaction with a debugger is
274
    // required.
275
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
276
    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
277
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
278
    console_selected = false;
279
#endif
280
    console_echo = true;
281
 
282
    ram_start = (unsigned char *)CYGMEM_REGION_ram;
283
    ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
284
#ifdef HAL_MEM_REAL_REGION_TOP
285
    {
286
        unsigned char *ram_end_tmp = ram_end;
287
        ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
288
    }
289
#endif
290
#ifdef CYGMEM_SECTION_heap1
291
    workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
292
    workspace_end = (unsigned char *)CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE;
293
#else
294
    workspace_start = (unsigned char *)CYGMEM_REGION_ram;
295
    workspace_end = (unsigned char *)CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
296
#endif
297
 
298
    if ( ram_end < workspace_end ) {
299
        // when *less* SDRAM is installed than the possible maximum,
300
        // but the heap1 region remains greater...
301
        workspace_end = ram_end;
302
    }
303
 
304
#if defined(CYGMEM_REDBOOT_WORKSPACE_HEAP)
305
    {
306
        extern cyg_bool cyg_memalloc_heap_reinit( cyg_uint8 *base, cyg_uint32 size );
307
 
308
        workspace_end -= CYGMEM_REDBOOT_WORKSPACE_HEAP_SIZE;
309
 
310
        if( !cyg_memalloc_heap_reinit( (cyg_uint8 *)workspace_end, CYGMEM_REDBOOT_WORKSPACE_HEAP_SIZE ) )
311
            diag_printf("Heap reinitialization failed\n");
312
    }
313
#endif
314
 
315
    workspace_end_init=workspace_end;
316
 
317
    // Nothing has ever been loaded into memory
318
    entry_address = (unsigned long)NO_MEMORY;
319
 
320
    bist();
321
 
322
#if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER)
323
    fis_zlib_common_buffer =
324
    workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
325
#endif
326
 
327
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
328
    script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
329
#endif
330
 
331
    for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__;  init_entry++) {
332
        (*init_entry->fun)();
333
    }
334
 
335
    mem_segments[0].start = workspace_start;
336
    mem_segments[0].end = workspace_end;
337
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
338
    for (seg = 1;  seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS;  seg++) {
339
        cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end);
340
    }
341
#endif
342
 
343
#ifdef CYGSEM_REDBOOT_PLF_STARTUP
344
 
345
    cyg_plf_redboot_startup();
346
#endif
347
    do_version(0,0);
348
 
349
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
350
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
351
    if (!script) {
352
      script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
353
    }
354
# endif
355
    if (script) {
356
        // Give the guy a chance to abort any boot script
357
        char *hold_script = script;
358
        int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
359
        diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
360
                    script_timeout_ms/1000, script_timeout_ms%1000);
361
        script = NULL;
362
        res = _GETS_CTRLC;  // Treat 0 timeout as ^C
363
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
364
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
365
            if (res >= _GETS_OK) {
366
                diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
367
                            script_timeout_ms/1000, script_timeout_ms%1000);
368
                continue;  // Ignore anything but ^C
369
            }
370
            if (res != _GETS_TIMEOUT) break;
371
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
372
        }
373
        if (res == _GETS_CTRLC) {
374
            script = NULL;  // Disable script
375
        } else {
376
            script = hold_script;  // Re-enable script
377
        }
378
    }
379
#endif
380
    CYG_ASSERT(workspace_start < workspace_end,
381
               "negative workspace size");
382
    while (true) {
383
        if (prompt) {
384
            diag_printf("RedBoot> ");
385
            prompt = false;
386
        }
387
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
388
        cmd_history = true;  // Enable history collection
389
#endif
390
        res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
391
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
392
        cmd_history = false;  // Enable history collection
393
#endif
394
        if (res == _GETS_TIMEOUT) {
395
            // No input arrived
396
        } else {
397
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
398
            if (res == _GETS_GDB) {
399
                int dbgchan;
400
                hal_virtual_comm_table_t *__chan;
401
                int i;
402
                CYG_ADDRESS gdb_stack_sp;
403
 
404
                // Special case of '$' - need to start GDB protocol
405
                gdb_active = true;
406
                // Mask interrupts on all channels
407
                for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
408
                    CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
409
                    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
410
                    CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
411
                }
412
 
413
                CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
414
 
415
                gdb_stack_sp = (CYG_ADDRESS)workspace_end;
416
                // set up a temporary context that will take us to the trampoline
417
                HAL_THREAD_INIT_CONTEXT(gdb_stack_sp,
418
                                        breakpoint, trampoline,0);
419
 
420
                // switch context to trampoline (get GDB stubs started)
421
                HAL_THREAD_SWITCH_CONTEXT(&saved_context, &gdb_stack_sp);
422
 
423
                gdb_active = false;
424
 
425
                dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
426
                CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
427
            } else
428
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
429
            {
430
                expand_aliases(line, sizeof(line));
431
                command = (char *)&line;
432
                if ((*command == '#') || (*command == '=')) {
433
                    // Special cases
434
                    if (*command == '=') {
435
                        // Print line on console
436
                        diag_printf("%s\n", &line[2]);
437
                    }
438
                } else {
439
                    while (strlen(command) > 0) {
440
                        if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
441
                            // Try to handle aborts - messy because of the stack unwinding...
442
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
443
                            __mem_fault_handler = error_handler;
444
#endif
445
                            if (hal_setjmp(error_jmpbuf)) {
446
                                diag_printf("** command abort - illegal memory access?\n");
447
                            } else {
448
                                (cmd->fun)(argc, argv);
449
                            }
450
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
451
                            __mem_fault_handler = 0;
452
#endif
453
                        } else {
454
                            diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
455
                        }
456
                    }
457
                }
458
                prompt = true;
459
            }
460
        }
461
    }
462
}
463
 
464
void
465
show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre)
466
{
467
    bool show;
468
    int len = 0;
469
 
470
    if (which) {
471
        len = strlen(which);
472
    }
473
    while (cmd != cmd_end) {
474
        show = true;
475
        if (which && (strncasecmp(which, cmd->str, len) != 0)) {
476
            show = false;
477
        }
478
        if (show) {
479
            diag_printf("%s\n  %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage);
480
            if ((cmd->sub_cmds != (struct cmd *)0) && (which != (char *)0)) {
481
                show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);
482
            }
483
        }
484
        cmd++;
485
    }
486
}
487
 
488
void
489
do_help(int argc, char *argv[])
490
{
491
    struct cmd *cmd;
492
    char *which = (char *)0;
493
 
494
    if (!scan_opts(argc, argv, 1, 0, 0, (void *)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
495
        diag_printf("Invalid argument\n");
496
        return;
497
    }
498
    cmd = __RedBoot_CMD_TAB__;
499
    show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
500
    return;
501
}
502
 
503
static void
504
trampoline(unsigned long entry)
505
{
506
    typedef void code_fun(void);
507
    code_fun *fun = (code_fun *)entry;
508
    unsigned long oldints;
509
 
510
    HAL_DISABLE_INTERRUPTS(oldints);
511
 
512
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
513
    HAL_ARCH_PROGRAM_NEW_STACK(fun);
514
#else
515
    (*fun)();
516
#endif
517
 
518
    HAL_THREAD_LOAD_CONTEXT(&saved_context);
519
}
520
 
521
static void
522
return_to_redboot(int status)
523
{
524
    CYGARC_HAL_SAVE_GP();
525
 
526
    return_status = status;
527
    HAL_THREAD_LOAD_CONTEXT(&saved_context);
528
    // never returns
529
 
530
    // need this to balance above CYGARC_HAL_SAVE_GP on
531
    // some platforms. It will never run, though.
532
    CYGARC_HAL_RESTORE_GP();
533
}
534
 
535
void
536
do_go(int argc, char *argv[])
537
{
538
    int i, cur, num_options;
539
    unsigned long entry;
540
    unsigned long oldints;
541
    bool wait_time_set;
542
    int  wait_time, res;
543
    bool cache_enabled = false;
544
#ifdef CYGPKG_IO_ETH_DRIVERS
545
    bool stop_net = false;
546
#endif
547
    struct option_info opts[3];
548
    char line[8];
549
    hal_virtual_comm_table_t *__chan;
550
    CYG_ADDRESS trampoline_stack_sp;
551
 
552
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
553
    __mem_fault_handler = 0; // Let GDB handle any faults directly
554
#endif
555
    entry = entry_address;  // Default from last 'load' operation
556
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
557
              (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
558
    init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
559
              (void *)&cache_enabled, (bool *)0, "go with caches enabled");
560
    num_options = 2;
561
#ifdef CYGPKG_IO_ETH_DRIVERS
562
    init_opts(&opts[2], 'n', false, OPTION_ARG_TYPE_FLG,
563
              (void *)&stop_net, (bool *)0, "go with network driver stopped");
564
    num_options++;
565
#endif
566
 
567
    CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");
568
 
569
    if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
570
    {
571
        return;
572
    }
573
    if (entry == (unsigned long)NO_MEMORY) {
574
        err_printf("No entry point known - aborted\n");
575
        return;
576
    }
577
    if (wait_time_set) {
578
        int script_timeout_ms = wait_time * 1000;
579
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
580
        char *hold_script = script;
581
        script = NULL;
582
#endif
583
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
584
                    (void *)entry, wait_time);
585
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
586
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
587
            if (res == _GETS_CTRLC) {
588
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
589
                script = hold_script;  // Re-enable script
590
#endif
591
                return;
592
            }
593
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
594
        }
595
    }
596
 
597
    // Mask interrupts on all channels
598
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
599
    for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
600
        CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
601
        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
602
        CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
603
    }
604
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
605
 
606
    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
607
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
608
 
609
#ifdef CYGPKG_IO_ETH_DRIVERS
610
    if (stop_net)
611
        eth_drv_stop();
612
#endif
613
 
614
    HAL_DISABLE_INTERRUPTS(oldints);
615
    HAL_DCACHE_SYNC();
616
    if (!cache_enabled) {
617
        HAL_ICACHE_DISABLE();
618
        HAL_DCACHE_DISABLE();
619
        HAL_DCACHE_SYNC();
620
    }
621
    HAL_ICACHE_INVALIDATE_ALL();
622
    HAL_DCACHE_INVALIDATE_ALL();
623
    trampoline_stack_sp = (CYG_ADDRESS)workspace_end;
624
    // set up a temporary context that will take us to the trampoline
625
    HAL_THREAD_INIT_CONTEXT(trampoline_stack_sp, entry, trampoline, 0);
626
 
627
    // switch context to trampoline
628
    HAL_THREAD_SWITCH_CONTEXT(&saved_context, &trampoline_stack_sp);
629
 
630
    // we get back here by way of return_to_redboot()
631
 
632
    // undo the changes we made before switching context
633
    if (!cache_enabled) {
634
        HAL_ICACHE_ENABLE();
635
        HAL_DCACHE_ENABLE();
636
    }
637
 
638
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
639
 
640
    HAL_RESTORE_INTERRUPTS(oldints);
641
 
642
    diag_printf("\nProgram completed with status %d\n", return_status);
643
}
644
 
645
#ifdef HAL_PLATFORM_RESET
646
void
647
do_reset(int argc, char *argv[])
648
{
649
    diag_printf("... Resetting.");
650
    CYGACC_CALL_IF_DELAY_US(2*100000);
651
    diag_printf("\n");
652
    CYGACC_CALL_IF_RESET();
653
    diag_printf("!! oops, RESET not working on this platform\n");
654
}
655
#endif
656
 
657
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
658
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
659
#include <flash_config.h>
660
#endif
661
 
662
static int
663
set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate)
664
{
665
    int current_rate;
666
 
667
    current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD);
668
    if (rate != current_rate)
669
        return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
670
 
671
    return 0;
672
}
673
 
674
int
675
set_console_baud_rate(int rate)
676
{
677
    int ret = -1;
678
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
679
    if (!console_selected) {
680
        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
681
        int i;
682
        // Set baud for all channels
683
        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
684
            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
685
            ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
686
            if (ret < 0)
687
                break;
688
        }
689
        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
690
    } else
691
#endif
692
    ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
693
 
694
    if (ret < 0)
695
        diag_printf("Setting console baud rate to %d failed\n", rate);
696
 
697
    return ret;
698
}
699
 
700
static void
701
_sleep(int ms)
702
{
703
    int i;
704
    for (i = 0;  i < ms;  i++) {
705
        CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);
706
    }
707
}
708
 
709
void
710
do_baud_rate(int argc, char *argv[])
711
{
712
    int new_rate, ret, old_rate;
713
    bool new_rate_set;
714
    hal_virtual_comm_table_t *__chan;
715
    struct option_info opts[1];
716
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
717
    struct config_option opt;
718
#endif
719
 
720
    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
721
              (void *)&new_rate, (bool *)&new_rate_set, "new baud rate");
722
    if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
723
        return;
724
    }
725
    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
726
    if (new_rate_set) {
727
        diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);
728
        _sleep(500);  // Give serial time to flush
729
        old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
730
        ret = set_console_baud_rate(new_rate);
731
        if (ret < 0) {
732
            if (old_rate > 0) {
733
                // Try to restore
734
                set_console_baud_rate(old_rate);
735
                _sleep(500);  // Give serial time to flush
736
                diag_printf("\nret = %d\n", ret);
737
            }
738
            return;  // Couldn't set the desired rate
739
        }
740
        // Make sure this new rate works or back off to previous value
741
        // Sleep for a few seconds, then prompt to see if it works
742
        _sleep(10000);  // Give serial time to flush
743
        if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {
744
            _sleep(500);  // Give serial time to flush
745
            set_console_baud_rate(old_rate);
746
            _sleep(500);  // Give serial time to flush
747
            return;
748
        }
749
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
750
        opt.type = CONFIG_INT;
751
        opt.enable = (char *)0;
752
        opt.enable_sense = 1;
753
        opt.key = "console_baud_rate";
754
        opt.dflt = new_rate;
755
        flash_add_config(&opt, true);
756
#endif
757
    } else {
758
        ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
759
        diag_printf("Baud rate = ");
760
        if (ret <= 0) {
761
            diag_printf("unknown\n");
762
        } else {
763
            diag_printf("%d\n", ret);
764
        }
765
    }
766
}
767
#endif
768
 
769
//
770
// Validate an address to see if it is within any known RAM area
771
//
772
bool
773
valid_address(unsigned char *addr)
774
{
775
    int seg;
776
 
777
    for (seg = 0;  seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS;  seg++) {
778
        if (mem_segments[seg].start != NO_MEMORY) {
779
            if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) {
780
                return true;
781
            }
782
        }
783
    }
784
    return false;
785
}
786
 
787
/* EOF main.c */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.