diff packages/devs/gdb/current/src/gdb_1.cxx @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/devs/gdb/current/src/gdb_1.cxx
@@ -0,0 +1,245 @@
+//=================================================================
+//
+//        gdb_1.cxx
+//
+//        Pseudo Driver for GDB
+//
+//=================================================================
+//####COPYRIGHTBEGIN####
+//
+// -------------------------------------------
+// The contents of this file are subject to the Cygnus eCos Public License
+// Version 1.0 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://sourceware.cygnus.com/ecos
+// 
+// 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 Cygnus Operating System, released
+// September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Cygnus.  Portions created
+// by Cygnus are Copyright (C) 1998 Cygnus Solutions.  All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     proven
+// Contributors:    proven
+// Date:          1998-05-30
+// Description:   Class methods for class Cyg_Device_GDB_1
+//####DESCRIPTIONEND####
+
+#include <pkgconf/devs.h>		// To see if we need to bother
+#ifdef CYG_DEVICE_GDB_1 		// Do we need to build this file
+
+#define CYG_DEVICE_INTERNAL
+#include <cyg/devs/gdb/gdb_1.hxx>
+#include <cyg/kernel/sema.hxx>          // Cyg_Binary_Semaphore
+#include <stddef.h>			// NULL
+
+#ifdef CYG_DEVICE_GDB_1_NAME // Only construct object if there is a name
+CYG_CLASS_DEVICE_GDB_1 CYG_DEVICE_GDB_1_NAME;
+#endif
+
+// ------------------------------------------------------------------------
+// Constructor for GDB device                 
+//
+CYG_CLASS_DEVICE_GDB_1::CYG_CLASS_DEVICE_GDB_1()
+    : CYG_DEVICE_GDB_1_CLASS()
+{
+    CYG_REPORT_FUNCTION();
+
+    // Initialize any data
+
+    // write_buffers = NULL; 
+
+}
+
+// ------------------------------------------------------------------------
+// Routines to deal with the new iorb
+//
+
+static const char hexchars[] = "0123456789abcdef";
+
+static cyg_uint32 
+iorb_compute(char * in_data, cyg_uint32 length, Cyg_IORB * out)
+{
+    cyg_uint8 csum = 0;
+    cyg_ucount8 i;
+    char * data;
+
+    data = (char *)out->buffer;
+
+    if (length > CYGNUM_DEVICE_GDB_BUFFER_SIZE) {
+	length = CYGNUM_DEVICE_GDB_BUFFER_SIZE;
+    }
+
+    data[0] = '$';
+    data[1] = 'O';
+    csum += data[1];
+    for (i = 0; i < length; i++) {
+	data[(i*2)+2] = hexchars[(in_data[i] >> 4) & 0x0f];
+	data[(i*2)+3] = hexchars[in_data[i] & 0x0f];
+        csum += data[(i*2)+2];
+        csum += data[(i*2)+3];
+    }
+    data[(i*2)+2] = '#';
+    data[(i*2)+3] = hexchars[csum >> 4];
+    data[(i*2)+4] = hexchars[csum & 0x0f];
+
+    out->buffer_length = (i * 2) + 5;
+    return (length);
+}
+
+void
+CYG_CLASS_DEVICE_GDB_1::iorb_setup(CYG_CLASS_DEVICE_GDB_1 * data)
+{
+    Cyg_IORB * iorb;
+
+    iorb = data->gdb_write_buffer_first;
+
+    /* set up gdb_write_iorb */
+    data->gdb_write_iorb.buffer = data->gdb_write_buf;
+    data->gdb_write_iorb.callback = iorb_callback;
+    data->gdb_write_iorb.callback_data = (CYG_ADDRWORD)data;
+    iorb->xferred_length = iorb_compute((char *)iorb->buffer, iorb->buffer_length, &data->gdb_write_iorb);
+
+    /* Save the length of the original data that still needs to be sent */
+    data->gdb_write_length = iorb->buffer_length - iorb->xferred_length;
+
+    /* Start the write process */
+    data->io_write(&data->gdb_write_iorb);
+}
+
+void
+CYG_CLASS_DEVICE_GDB_1::iorb_callback(Cyg_IORB *iorb)
+{
+    CYG_CLASS_DEVICE_GDB_1 * foo = (CYG_CLASS_DEVICE_GDB_1 *)iorb->callback_data;
+    cyg_uint32 length;
+
+    if (foo->gdb_write_length) {
+        /* Compute the offset into the original data */
+        length = iorb_compute ((char *)foo->gdb_write_buffer_first->buffer + 
+          foo->gdb_write_buffer_first->xferred_length, foo->gdb_write_length, 
+          &foo->gdb_write_iorb);
+
+        foo->gdb_write_buffer_first->xferred_length += length;
+        foo->gdb_write_length -= length;
+
+        foo->io_write(&foo->gdb_write_iorb);
+        
+    } else {
+	Cyg_IORB * done;
+
+	/* Get the next iorb */
+	done = foo->gdb_write_buffer_first;
+	foo->gdb_write_buffer_first = foo->gdb_write_buffer_first->next;
+	if (foo->gdb_write_buffer_first == NULL) {
+            foo->gdb_write_buffer_last = NULL;
+	} else {
+            foo->iorb_setup(foo);
+        }
+	if (done->callback) {
+            done->callback(done);
+	}
+    }
+}
+
+// ------------------------------------------------------------------------
+// Asynchronous write
+//
+
+cyg_int32
+CYG_CLASS_DEVICE_GDB_1::io_write_asynchronous(Cyg_IORB * iorb)
+{
+    iorb->next = NULL;
+    Cyg_Scheduler::lock();
+    if (gdb_write_buffer_first == NULL) {
+        gdb_write_buffer_first = iorb;
+        gdb_write_buffer_last = iorb;
+        Cyg_Scheduler::unlock();
+        iorb_setup(this);
+    } else {
+        gdb_write_buffer_last->next = iorb;
+        gdb_write_buffer_last = iorb;
+        Cyg_Scheduler::unlock();
+    }
+    return 0;    
+}
+
+// ------------------------------------------------------------------------
+// Synchronous write
+//
+
+static void
+callback(Cyg_IORB *iorb)
+{
+    Cyg_Binary_Semaphore * data = (Cyg_Binary_Semaphore *)iorb->callback_data;
+    data->post();
+}
+
+cyg_int32
+CYG_CLASS_DEVICE_GDB_1::io_write_blocking(Cyg_IORB * iorb)
+{
+    Cyg_Binary_Semaphore write(0);
+
+    // We need a callback routine to wake us up
+    iorb->callback_data = (CYG_ADDRESS)&write;
+    iorb->callback = callback;
+    iorb->next = NULL;
+
+    Cyg_Scheduler::lock();
+    if (gdb_write_buffer_first == NULL) {
+        gdb_write_buffer_last = iorb;
+        gdb_write_buffer_first = iorb;
+    } else {
+        gdb_write_buffer_last->next = iorb;
+        gdb_write_buffer_last = iorb;
+        Cyg_Scheduler::unlock();
+        write.wait();
+        return 0;
+    }
+
+    Cyg_Scheduler::unlock();
+    iorb_setup(this);
+    write.wait();
+    return 0;
+}
+
+// ------------------------------------------------------------------------
+// Assert versions. These versions bypass most of the driver code.
+// These are to be used by the BSP or asserts. Only use them once
+// start_sync() is called and when done normal operations is
+// restarted with the end_sync() mode.
+//
+// Note DO NOT DO LOCKING IN THIS ROUTINE!!!
+//
+
+cyg_int32
+CYG_CLASS_DEVICE_GDB_1::io_write_assert(Cyg_IORB * iorb)
+{
+    Cyg_IORB assert_iorb;
+    char assert_buffer[256];
+    cyg_uint32 length, length_left;
+
+    assert_iorb.callback = NULL;
+    assert_iorb.callback_data = 0;
+    assert_iorb.buffer = assert_buffer;
+    for (length_left = iorb->buffer_length; length_left; length_left -= length) {
+        length = iorb_compute((char *)iorb->buffer + iorb->xferred_length,
+          length_left, &assert_iorb);
+	iorb->xferred_length += length;
+        (CYG_DEVICE_GDB_1_CLASS *)this->io_write_assert(&assert_iorb);
+    }
+
+    return 0;
+}
+
+#endif // #ifdef CYG_DEVICE_GDB_1
+// EOF gdb_1.cxx