diff packages/redboot/current/src/io.c @ 115:6ed91473a1cd ecos-sw-2000-08-21

Merge from eCos master repository on 2000-08-21-22:40:54-BST
author jlarmour
date Fri, 25 Aug 2000 17:32:38 +0000
parents
children 518f42066aba
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/redboot/current/src/io.c
@@ -0,0 +1,308 @@
+//==========================================================================
+//
+//      io.c
+//
+//      RedBoot I/O support
+//
+//==========================================================================
+//####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 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####
+//
+//==========================================================================
+
+#include "redboot.h"
+
+// GDB interface functions
+extern void ungetDebugChar(char c);
+
+void 
+mon_write_char(char c)
+{
+    hal_virtual_comm_table_t *__chan;
+
+#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
+    if (!console_selected) {
+        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+        int i;
+        // Send output to all channels
+        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
+            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+            __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+            CYGACC_COMM_IF_PUTC(*__chan, c);
+        }
+        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+    } else 
+#endif
+    {
+        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+        if (__chan)
+            CYGACC_COMM_IF_PUTC(*__chan, c);
+        else {
+            __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+            CYGACC_COMM_IF_PUTC(*__chan, c);
+        }
+    }
+}
+
+static void 
+mon_read_char(char *c)
+{
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+    
+    if (__chan)
+        *c = CYGACC_COMM_IF_GETC(*__chan);
+    else {
+        __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+        *c = CYGACC_COMM_IF_GETC(*__chan);
+    }
+}
+
+static bool
+mon_read_char_with_timeout(char *c)
+{
+    bool res;
+    hal_virtual_comm_table_t *__chan;
+
+#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
+    if (!console_selected) {
+        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+        int i;
+        // Try input from all channels
+        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
+            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+            __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
+            if (res) {
+                // Input available on this channel, make it be the console
+                console_selected = true;
+                CYGACC_CALL_IF_SET_DEBUG_COMM(i);
+                return res;
+            }
+        }
+        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);        
+    } else 
+#endif
+    {
+        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+        if (__chan)
+            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
+        else {
+            __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
+        }
+    }
+    return res;
+}
+
+static void
+mon_set_read_char_timeout(int ms)
+{
+    hal_virtual_comm_table_t *__chan;
+
+#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
+    if (!console_selected) {
+        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+        int i;
+        // Set timeout on each channel so total amounts to desired value
+        ms = ms / CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;
+        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
+            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+            if ((__chan = CYGACC_CALL_IF_CONSOLE_PROCS()) != 0) {
+                CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms);
+            }
+        }
+        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);        
+    } else 
+#endif
+    if ((__chan = CYGACC_CALL_IF_CONSOLE_PROCS()) != 0) {
+        CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms);
+    }
+    if ((__chan = CYGACC_CALL_IF_DEBUG_PROCS()) != 0) {
+        CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms);
+    }
+}
+
+//
+// Read a line of input from the user
+// Return:
+//    n: 'n' valid characters received
+//    0: '$' (GDB lead-in)
+//   -1: No input before timeout
+//   -2: ^C typed
+//
+int
+gets(char *buf, int buflen, int timeout)
+{
+    char *ptr = buf;
+    char c;
+    bool res = false;
+    static char last_ch = '\0';
+
+    while (true) {
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+        if (script && *script) {
+            c = *script++;
+        } else
+#endif
+        if ((timeout > 0) && (ptr == buf)) {
+            mon_set_read_char_timeout(50);
+            while (timeout > 0) {
+                res = mon_read_char_with_timeout(&c);
+                if (res) {
+                    // Got a character
+                    break;
+                }
+                timeout -= 50;
+            }
+            if (res == false) {
+                return -1;  // Input timed out
+            }
+        } else {
+            mon_read_char(&c);
+        }
+        *ptr = '\0';
+        switch (c) {
+        case 0x03: // ^C
+            if (ptr == buf) {
+                printf("^C\n");
+                return -2;
+            }
+            *ptr++ = c;
+            break;
+        case '\n':
+        case '\r':
+            // If previous character was the "other" end-of-line, ignore this one
+            if (((c == '\n') && (last_ch == '\r')) ||
+                ((c == '\r') && (last_ch == '\n'))) {
+                break;
+            }
+            // End of line
+            mon_write_char('\r');
+            mon_write_char('\n');
+            last_ch = c;
+            return 1;
+        case '\b':
+        case 0x7F:  // DEL
+            if (ptr != buf) {
+                mon_write_char('\b');
+                mon_write_char(' ');
+                mon_write_char('\b');
+                ptr--;
+            }
+            break;
+        case '+':
+        case '$':
+            if (ptr == buf) {
+                // Give up and try GDB protocol
+                ungetDebugChar(c);  // Push back character so stubs will see it
+                return 0;
+            }
+            // Fall through - accept '$' at other than start of line
+        default:
+            mon_write_char(c);
+            *ptr++ = c;
+        }
+        last_ch = c;
+    }
+}
+
+void
+dump_buf_with_offset(cyg_uint8     *p, 
+                     CYG_ADDRWORD   s, 
+                     cyg_uint8     *base)
+{
+    int i, c;
+    if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
+        s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
+    }
+    while ((int)s > 0) {
+        if (base) {
+            printf("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
+        } else {
+            printf("0x%08X: ", (CYG_ADDRWORD)p);
+        }
+        for (i = 0;  i < 16;  i++) {
+            if (i < (int)s) {
+                printf("%02X", p[i] & 0xFF);
+            } else {
+                printf("  ");
+            }
+            if ((i % 2) == 1) printf(" ");
+            if ((i % 8) == 7) printf(" ");
+        }
+        printf(" |");
+        for (i = 0;  i < 16;  i++) {
+            if (i < (int)s) {
+                c = p[i] & 0xFF;
+                if ((c < 0x20) || (c >= 0x7F)) c = '.';
+            } else {
+                c = ' ';
+            }
+            printf("%c", c);
+        }
+        printf("|\n");
+        s -= 16;
+        p += 16;
+    }
+}
+
+void
+dump_buf(void *p, CYG_ADDRWORD s)
+{
+   dump_buf_with_offset((cyg_uint8 *)p, s, 0);
+}
+
+bool
+verify_action(char *fmt, ...)
+{
+    va_list ap;
+    char ans[8];
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+    unsigned char *hold_script = script;
+#endif
+
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    printf(" - are you sure (y/n)? ");
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+    script = (unsigned char *)0;
+#endif
+    gets(ans, sizeof(ans), 0);
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+    script = hold_script;
+#endif
+    return ((ans[0] == 'y') || (ans[0] == 'Y'));
+}