diff packages/hal/common/current/src/hal_stub.c @ 101:c37d3a9e1b28 ecos-sw-2000-06-16

Merge from eCos master repository on 2000-06-16-07:47:03-BST
author jlarmour
date Fri, 16 Jun 2000 16:43:59 +0000
parents 435cced73e2f
children 95f3e12a6327
line wrap: on
line diff
--- a/packages/hal/common/current/src/hal_stub.c
+++ b/packages/hal/common/current/src/hal_stub.c
@@ -56,11 +56,13 @@
 #include <cyg/hal/hal_cache.h>          // HAL_xCACHE_x
 #include <cyg/hal/hal_intr.h>           // interrupt disable/restore
 
+#include <cyg/hal/hal_if.h>             // ROM calling interface
+#include <cyg/hal/hal_misc.h>           // Helper functions
+
 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
 #include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
 #endif
 
-
 //-----------------------------------------------------------------------------
 // Extra eCos data.
 
@@ -103,7 +105,10 @@ extern char ecos_bsp_console_getc(void);
 void 
 putDebugChar (int c)
 {
-#ifdef CYGPKG_CYGMON
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+    CYGACC_COMM_IF_PUTC(*__debug_procs)(__debug_procs, c);
+#elif defined(CYGPKG_CYGMON)
     ecos_bsp_console_putc(c);
 #else
     HAL_STUB_PLATFORM_PUT_CHAR(c);
@@ -114,7 +119,10 @@ putDebugChar (int c)
 int 
 getDebugChar (void)
 {
-#ifdef CYGPKG_CYGMON
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+    return CYGACC_COMM_IF_GETC(*__debug_procs)(__debug_procs);
+#elif defined(CYGPKG_CYGMON)
     return ecos_bsp_console_getc();
 #else
     return HAL_STUB_PLATFORM_GET_CHAR();
@@ -125,7 +133,10 @@ getDebugChar (void)
 void 
 __set_baud_rate (int baud) 
 {
-#ifdef CYGPKG_CYGMON
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+    CYGACC_COMM_IF_CONTROL(*__debug_procs)(__debug_procs, __COMMCTL_SETBAUD, baud);
+#elif defined(CYGPKG_CYGMON)
     // FIXME!
 #else
     HAL_STUB_PLATFORM_SET_BAUD_RATE(baud);
@@ -168,6 +179,8 @@ cyg_hal_gdb_place_break (target_register
 void 
 cyg_hal_gdb_interrupt (target_register_t pc)
 {
+    CYGARC_HAL_SAVE_GP();
+
     // Clear flag that we Continued instead of Stepping
     cyg_hal_gdb_running_step = 0;
     // and override existing break? So that a ^C takes effect...
@@ -182,6 +195,8 @@ cyg_hal_gdb_interrupt (target_register_t
         __data_cache(CACHE_FLUSH);
         __instruction_cache(CACHE_FLUSH);
     }
+
+    CYGARC_HAL_RESTORE_GP();
 }
 
 int 
@@ -240,6 +255,135 @@ interruptible(int state)
     }
 }
 
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+//-----------------------------------------------------------------------------
+// GDB O-packetizer function.
+
+// This gets called via the virtual vector debug comms entry and
+// handles O-packetization. The debug comms entries are used for the
+// actual device IO.
+
+static cyg_uint8
+cyg_hal_gdb_diag_getc(void* __ch_data)
+{
+    cyg_uint8 __ch;
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+    CYGARC_HAL_SAVE_GP();
+
+    __ch = CYGACC_COMM_IF_GETC(*__chan)(*__chan);
+
+    CYGARC_HAL_RESTORE_GP();
+
+    return __ch;
+}
+
+
+static void
+cyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c)
+{
+    static char line[100];
+    static int pos = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    // No need to send CRs
+    if( c == '\r' ) return;
+
+    line[pos++] = c;
+
+    if( c == '\n' || pos == sizeof(line) )
+    {
+        CYG_INTERRUPT_STATE old;
+        hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+        // Disable interrupts. This prevents GDB trying to interrupt us
+        // while we are in the middle of sending a packet. The serial
+        // receive interrupt will be seen when we re-enable interrupts
+        // later.
+        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
+        
+        while(1)
+        {
+            static const char hex[] = "0123456789ABCDEF";
+            cyg_uint8 csum = 0, c1;
+            int i;
+        
+            CYGACC_COMM_IF_PUTC(*__chan)(*__chan, '$');
+            CYGACC_COMM_IF_PUTC(*__chan)(*__chan, 'O');
+            csum += 'O';
+            for( i = 0; i < pos; i++ )
+            {
+                char ch = line[i];
+                char h = hex[(ch>>4)&0xF];
+                char l = hex[ch&0xF];
+                CYGACC_COMM_IF_PUTC(*__chan)(*__chan, h);
+                CYGACC_COMM_IF_PUTC(*__chan)(*__chan, l);
+                csum += h;
+                csum += l;
+            }
+            CYGACC_COMM_IF_PUTC(*__chan)(*__chan, '#');
+            CYGACC_COMM_IF_PUTC(*__chan)(*__chan, hex[(csum>>4)&0xF]);
+            CYGACC_COMM_IF_PUTC(*__chan)(*__chan, hex[csum&0xF]);
+
+            c1 = CYGACC_COMM_IF_GETC(*__chan)(*__chan);
+            if( c1 == '+' ) break;
+
+            if( cyg_hal_is_break( &c1 , 1 ) ) {
+                // Caller's responsibility to react on this.
+                CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
+                break;
+            }
+        }
+
+        pos = 0;
+        // And re-enable interrupts
+        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_gdb_diag_write(void* __ch_data, const cyg_uint8* __buf, 
+                       cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_gdb_diag_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_gdb_diag_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = CYGACC_COMM_IF_GETC(*__chan)(*__chan);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static int
+cyg_hal_gdb_diag_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    // Do nothing (yet).
+    return 0;
+}
+
+hal_virtual_comm_table_t cyg_hal_gdb_console_procs = {
+    0,
+    (CYG_ADDRWORD) &cyg_hal_gdb_diag_write,
+    (CYG_ADDRWORD) &cyg_hal_gdb_diag_read,
+    (CYG_ADDRWORD) &cyg_hal_gdb_diag_putc,
+    (CYG_ADDRWORD) &cyg_hal_gdb_diag_getc,
+    (CYG_ADDRWORD) &cyg_hal_gdb_diag_control};
+
+#endif
+
+
 //-----------------------------------------------------------------------------
 // eCos stub entry and exit magic.
 
@@ -281,10 +425,7 @@ handle_exception_cleanup( void )
     // FIXME: (there may be a better way to do this)
     // If we hit a breakpoint set by the gdb interrupt stub, make it
     // seem like an interrupt rather than having hit a breakpoint.
-    if (cyg_hal_gdb_remove_break(get_register (PC)))
-        cyg_hal_gdb_break = 1;
-    else
-        cyg_hal_gdb_break = 0;
+    cyg_hal_gdb_break = cyg_hal_gdb_remove_break(get_register (PC));
 #endif
 }
 
@@ -338,24 +479,36 @@ initHardware (void)
 {
     static int initialized = 0;
 
-    if (!initialized) {
-        initialized = 1;
+    if (initialized++)
+        return;
 
 #if !defined(CYGPKG_CYGMON)
 #ifdef HAL_STUB_PLATFORM_INIT
-        // If the platform defines any initialization code, call it here.
-        HAL_STUB_PLATFORM_INIT();
+    // If the platform defines any initialization code, call it here.
+    HAL_STUB_PLATFORM_INIT();
 #endif        
                 
-        // Get serial port initialized.
-        HAL_STUB_PLATFORM_INIT_SERIAL();
+    // Get serial port initialized.
+    HAL_STUB_PLATFORM_INIT_SERIAL();
 
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    // This should really be done during handle_exception_init (at
+    // stub exit), but that makes it impossible a stub to be included
+    // in the application without breaking things. So do it here
+    // instead - stub initialization happens after
+    // constructors/hal_diag_init anyway.
+    if (NULL == CYGACC_CALL_IF_CONSOLE_PROCS())
+        CYGACC_CALL_IF_CONSOLE_PROCS_SET(cyg_hal_gdb_console_procs);
+#endif
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-        // Get interrupt handler initialized.
-        HAL_STUB_PLATFORM_INIT_BREAK_IRQ();
+    // Get interrupt handler initialized.
+    HAL_STUB_PLATFORM_INIT_BREAK_IRQ();
 #endif
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 #endif // CYGPKG_CYGMON
-    }
+
 }
 
 // Reset the board.
@@ -363,8 +516,14 @@ void
 __reset (void)
 {
 #if !defined(CYGPKG_CYGMON)
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    __call_if_reset_t __rom_reset = CYGACC_CALL_IF_RESET();
+    if (__rom_reset)
+        __rom_reset();
+#else
     HAL_STUB_PLATFORM_RESET();
 #endif
+#endif
 }
 
 //-----------------------------------------------------------------------------