source: SVN/cambria/redboot/packages/redboot/current/src/main.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

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