diff packages/hal/powerpc/cogent/current/src/hal_diag.c @ 103:95f3e12a6327 ecos-sw-2000-06-23

Merge from eCos master repository on 2000-06-23-16:41:10-BST
author jlarmour
date Fri, 23 Jun 2000 17:06:31 +0000
parents 2085233a121a
children 5a0cc6c243a9
line wrap: on
line diff
--- a/packages/hal/powerpc/cogent/current/src/hal_diag.c
+++ b/packages/hal/powerpc/cogent/current/src/hal_diag.c
@@ -42,85 +42,560 @@
 //=============================================================================
 
 #include <pkgconf/hal.h>
-#include <pkgconf/hal_powerpc_cogent.h> // CYGHWR_HAL_POWERPC_COGENT_DIAG_PORT
 
 #include <cyg/hal/hal_diag.h>           // our header.
 
 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
-#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
+#include <cyg/hal/hal_stub.h>           // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION
 #endif
 
 #include <cyg/infra/cyg_type.h>         // base types, externC
 #include <cyg/hal/hal_io.h>             // IO macros
 #include <cyg/hal/hal_intr.h>           // Interrupt macros
 
-//-----------------------------------------------------------------------------
-// Select default diag channel to use
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP
+#include <cyg/hal/hal_if.h>             // Calling-if API
+
+
+static void cyg_hal_plf_serial_init(void);
+static void cyg_hal_plf_lcd_init(void);
 
-//#define CYG_KERNEL_DIAG_ROMART
-//#define CYG_KERNEL_DIAG_LCD
-//#define CYG_KERNEL_DIAG_SERIAL
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
 
-#if !defined(CYG_KERNEL_DIAG_SERIAL) && \
-    !defined(CYG_KERNEL_DIAG_LCD)    && \
-    !defined(CYG_KERNEL_DIAG_ROMART)
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+    cyg_hal_plf_lcd_init();
+}
 
-#define CYG_KERNEL_DIAG_SERIAL
-
+#if 0
+#ifdef CYGSEM_HAL_ROM_MONITOR
+    // It's handy to have the LCD initialized at reset when using it
+    // for debugging output.
+    {
+        diag_write_string ("eCos ROM   " __TIME__ "\n");
+        diag_write_string (__DATE__ "\n");
+    }
+#endif
 #endif
 
-// Always use LCD when building a GDB stub ROM.
-#ifdef CYGSEM_HAL_ROM_MONITOR
-#undef CYG_KERNEL_DIAG_SERIAL
-#undef CYG_KERNEL_DIAG_ROMART
+//=============================================================================
+// Serial driver
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// There are two serial ports.
+#define CYG_DEV_SERIAL_BASE_A    0xe900047 // port A
+#define CYG_DEV_SERIAL_BASE_B    0xe900007 // port B
+
+//-----------------------------------------------------------------------------
+// Default baud rate is 38400
+#define CYG_DEV_SERIAL_RS232_T1_VALUE_B38400         0x00
+#define CYG_DEV_SERIAL_RS232_T2_VALUE_B38400         0x06
+
+//-----------------------------------------------------------------------------
+// Define the serial registers. The Cogent board is equipped with a 16552
+// serial chip.
+#define CYG_DEV_SERIAL_RBR   0x00  // receiver buffer register, read, dlab = 0
+#define CYG_DEV_SERIAL_THR   0x00 // transmitter holding register, write, dlab = 0
+#define CYG_DEV_SERIAL_DLL   0x00 // divisor latch (LS), read/write, dlab = 1
+#define CYG_DEV_SERIAL_IER   0x08 // interrupt enable register, read/write, dlab = 0
+#define CYG_DEV_SERIAL_DLM   0x08 // divisor latch (MS), read/write, dlab = 1
+#define CYG_DEV_SERIAL_IIR   0x10 // interrupt identification register, read, dlab = 0
+#define CYG_DEV_SERIAL_FCR   0x10 // fifo control register, write, dlab = 0
+#define CYG_DEV_SERIAL_AFR   0x10 // alternate function register, read/write, dlab = 1
+#define CYG_DEV_SERIAL_LCR   0x18 // line control register, read/write
+#define CYG_DEV_SERIAL_MCR   0x20
+#define CYG_DEV_SERIAL_MCR_A 0x20
+#define CYG_DEV_SERIAL_MCR_B 0x20
+#define CYG_DEV_SERIAL_LSR   0x28 // line status register, read
+#define CYG_DEV_SERIAL_MSR   0x30 // modem status register, read
+#define CYG_DEV_SERIAL_SCR   0x38 // scratch pad register
+
+// The interrupt enable register bits.
+#define SIO_IER_ERDAI   0x01            // enable received data available irq
+#define SIO_IER_ETHREI  0x02            // enable THR empty interrupt
+#define SIO_IER_ELSI    0x04            // enable receiver line status irq
+#define SIO_IER_EMSI    0x08            // enable modem status interrupt
+
+// The interrupt identification register bits.
+#define SIO_IIR_IP      0x01            // 0 if interrupt pending
+#define SIO_IIR_ID_MASK 0x0e            // mask for interrupt ID bits
+
+// The line status register bits.
+#define SIO_LSR_DR      0x01            // data ready
+#define SIO_LSR_OE      0x02            // overrun error
+#define SIO_LSR_PE      0x04            // parity error
+#define SIO_LSR_FE      0x08            // framing error
+#define SIO_LSR_BI      0x10            // break interrupt
+#define SIO_LSR_THRE    0x20            // transmitter holding register empty
+#define SIO_LSR_TEMT    0x40            // transmitter register empty
+#define SIO_LSR_ERR     0x80            // any error condition
+
+// The modem status register bits.
+#define SIO_MSR_DCTS  0x01              // delta clear to send
+#define SIO_MSR_DDSR  0x02              // delta data set ready
+#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
+#define SIO_MSR_DDCD  0x08              // delta data carrier detect
+#define SIO_MSR_CTS   0x10              // clear to send
+#define SIO_MSR_DSR   0x20              // data set ready
+#define SIO_MSR_RI    0x40              // ring indicator
+#define SIO_MSR_DCD   0x80              // data carrier detect
+
+// The line control register bits.
+#define SIO_LCR_WLS0   0x01             // word length select bit 0
+#define SIO_LCR_WLS1   0x02             // word length select bit 1
+#define SIO_LCR_STB    0x04             // number of stop bits
+#define SIO_LCR_PEN    0x08             // parity enable
+#define SIO_LCR_EPS    0x10             // even parity select
+#define SIO_LCR_SP     0x20             // stick parity
+#define SIO_LCR_SB     0x40             // set break
+#define SIO_LCR_DLAB   0x80             // divisor latch access bit
+
+// The FIFO control register
+#define SIO_FCR_FCR0   0x01             // enable xmit and rcvr fifos
+#define SIO_FCR_FCR1   0x02             // clear RCVR FIFO
+#define SIO_FCR_FCR2   0x04             // clear XMIT FIFO
+
+
+static void
+init_serial_channel( cyg_uint8* base )
+{
+    cyg_uint8 lcr;
+
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, 0);
+
+    // Disable and clear FIFOs (need to enable to clear).
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR,
+                    (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2));
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR, 0);
+
+    // 8-1-no parity.
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
+
+    // Set speed to 38400.
+    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
+    lcr |= SIO_LCR_DLAB;
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
+
+
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLL,
+                    CYG_DEV_SERIAL_RS232_T2_VALUE_B38400);
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLM,
+                    CYG_DEV_SERIAL_RS232_T1_VALUE_B38400);
+    lcr &= ~SIO_LCR_DLAB;
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
+
+    {
+        // Special initialization for ST16C552 on CMA102
+        cyg_uint8 mcr;
+        
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_MCR_A, mcr);
+        mcr |= 8;
+        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_MCR_A, mcr);
+
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_MCR_B, mcr);
+        mcr |= 8;
+        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_MCR_B, mcr);
+    }
+
+    // Enable FIFOs (and clear them).
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR,
+                    (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2));
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    cyg_uint8 c, lsr;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
+    } while ((lsr & SIO_LSR_DR) == 0);
+
+    HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, c);
+
+    CYGARC_HAL_RESTORE_GP();
+    return c;
+}
+
+void
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c)
+{
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    cyg_uint8 lsr;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
+    } while ((lsr & SIO_LSR_THRE) == 0);
+
+    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_THR, c);
+
+    // Hang around until the character has been safely sent.
+    do {
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
+    } while ((lsr & SIO_LSR_THRE) == 0);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    // Do nothing (yet).
+    return 0;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    // Disable interrupts.
+    HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1);
+
+    // Init channels
+    init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_A);
+    init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_B);
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+    {
+        // Setup procs in the vector table
+        hal_virtual_comm_table_t* comm;
+        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+        // Set channel 0
+        CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);
+        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+        CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_A);
+        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
 
-#define CYG_KERNEL_DIAG_LCD
+        // Set channel 1
+        CYGACC_CALL_IF_SET_CONSOLE_COMM()(1);
+        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+        CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_B);
+        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+     
+        // Restore original console
+        CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+    }
 #endif
+}
 
+
+//=============================================================================
+// LCD driver
+//=============================================================================
+// FEMA 162B 16 character x 2 line LCD
+// base addresses and register offsets *
+
+#define MBD_BASE 0
+
+#define LCD_BASE                (MBD_BASE + 0xEB00007)
+
+#define LCD_DATA                0x00 // read/write lcd data
+#define LCD_STAT                0x08 // read lcd busy status
+#define LCD_CMD                 0x08 // write lcd command
+
+// status register bit definitions
+#define LCD_STAT_BUSY   0x80    // 1 = display busy
+#define LCD_STAT_ADD    0x7F    // bits 0-6 return current display address
+
+// command register definitions
+#define LCD_CMD_RST             0x01    // clear entire display and reset display address
+#define LCD_CMD_HOME            0x02    // reset display address and reset any shifting
+#define LCD_CMD_ECL             0x04    // move cursor left one position on next data write
+#define LCD_CMD_ESL             0x05    // shift display left one position on next data write
+#define LCD_CMD_ECR             0x06    // move cursor right one position on next data write
+#define LCD_CMD_ESR             0x07    // shift display right one position on next data write
+#define LCD_CMD_DOFF            0x08    // display off, cursor off, blinking off
+#define LCD_CMD_BL              0x09    // blink character at current cursor position
+#define LCD_CMD_CUR             0x0A    // enable cursor on
+#define LCD_CMD_DON             0x0C    // turn display on
+#define LCD_CMD_CL              0x10    // move cursor left one position
+#define LCD_CMD_SL              0x14    // shift display left one position
+#define LCD_CMD_CR              0x18    // move cursor right one position
+#define LCD_CMD_SR              0x1C    // shift display right one position
+#define LCD_CMD_MODE            0x38    // sets 8 bits, 2 lines, 5x7 characters
+#define LCD_CMD_ACG             0x40    // bits 0-5 sets the character generator address
+#define LCD_CMD_ADD             0x80    // bits 0-6 sets the display data address to line 1 +
+
+// LCD status values
+#define LCD_OK                  0x00
+#define LCD_ERR                 0x01
+
+#define LCD_LINE0       0x00
+#define LCD_LINE1       0x40
+
+#define LCD_LINE_LENGTH 16
+
+static char lcd_line0[LCD_LINE_LENGTH+1];
+static char lcd_line1[LCD_LINE_LENGTH+1];
+static char *lcd_line[2] = { lcd_line0, lcd_line1 };
+static int lcd_curline = 0;
+static int lcd_linepos = 0;
+
+
+static void lcd_dis(int add, char *s, cyg_uint8* base);
+
+static void
+init_lcd_channel(cyg_uint8* base)
+{
+    cyg_uint8 stat;
+    int i;
+    
+    // wait for not busy
+    // Note: It seems that the LCD isn't quite ready to process commands
+    // when it clears the BUSY flag. Reading the status address an extra
+    // time seems to give it enough breathing room.
+    do { HAL_READ_UINT8(base+LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
+    HAL_READ_UINT8(base+LCD_STAT, stat);
+
+    // configure the lcd for 8 bits/char, 2 lines
+    // and 5x7 dot matrix
+    HAL_WRITE_UINT8(base+LCD_CMD, LCD_CMD_MODE);
+
+    // wait for not busy
+    do { HAL_READ_UINT8(base+LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
+    HAL_READ_UINT8(base+LCD_STAT, stat);
+
+    // turn the LCD display on
+    HAL_WRITE_UINT8(base+LCD_CMD, LCD_CMD_DON);
+
+    lcd_curline = 0;
+    lcd_linepos = 0;
+
+    for( i = 0; i < LCD_LINE_LENGTH; i++ )
+        lcd_line[0][i] = lcd_line[1][i] = ' ';
+
+    lcd_line[0][LCD_LINE_LENGTH] = lcd_line[1][LCD_LINE_LENGTH] = 0;
+
+    lcd_dis(LCD_LINE0, lcd_line[0], base);
+    lcd_dis(LCD_LINE1, lcd_line[1], base);
+}
+
+// this routine writes the string to the LCD
+// display after setting the address to add
+static void
+lcd_dis(int add, char *s, cyg_uint8* base)
+{
+    cyg_uint8 stat;
+    int i;
+
+    // wait for not busy (see Note in hal_diag_init above)
+    do { HAL_READ_UINT8(base+LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
+    HAL_READ_UINT8(base+LCD_STAT, stat);
+
+    // write the address
+    HAL_WRITE_UINT8(base+LCD_CMD, (LCD_CMD_ADD + add));
+
+    // write the string out to the display stopping when we reach 0
+    for (i = 0; *s != '\0'; i++)
+    {
+        // wait for not busy
+        do { HAL_READ_UINT8(base+LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
+        HAL_READ_UINT8(base+LCD_STAT, stat);
+
+        // write the data
+        HAL_WRITE_UINT8(base+LCD_DATA, *s++);
+    }
+}
+
+void
+cyg_hal_plf_lcd_putc(void* __ch_data, cyg_uint8 c)
+{
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    unsigned long __state;
+    int i;
+    CYGARC_HAL_SAVE_GP();
+
+    // ignore CR
+    if( c == '\r' ) return;
+    
+    HAL_DISABLE_INTERRUPTS(__state);
+    if( c == '\n' )
+    {
+        lcd_dis(LCD_LINE0, &lcd_line[lcd_curline^1][0], base);
+        lcd_dis(LCD_LINE1, &lcd_line[lcd_curline][0], base);
+
+        // Do a line feed
+        lcd_curline ^= 1;
+        lcd_linepos = 0;
+        
+        for( i = 0; i < LCD_LINE_LENGTH; i++ )
+            lcd_line[lcd_curline][i] = ' ';
+
+        HAL_RESTORE_INTERRUPTS(__state);
+        return;
+    }
+
+    // Only allow to be output if there is room on the LCD line
+    if( lcd_linepos < LCD_LINE_LENGTH )
+        lcd_line[lcd_curline][lcd_linepos++] = c;
+
+    HAL_RESTORE_INTERRUPTS(__state);
+}
+
+cyg_uint8
+cyg_hal_plf_lcd_getc(void* __ch_data)
+{
+    return 0;
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static void
+cyg_hal_plf_lcd_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_lcd_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_lcd_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_lcd_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static int
+cyg_hal_plf_lcd_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    // Do nothing (yet).
+    return 0;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+static void
+cyg_hal_plf_lcd_init(void)
+{
+    // Init channel
+    init_lcd_channel((cyg_uint8*)LCD_BASE);
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+    {
+        // Setup procs in the vector table
+        hal_virtual_comm_table_t* comm;
+        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+        // Set channel 2
+        CYGACC_CALL_IF_SET_CONSOLE_COMM()(2);
+        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+        CYGACC_COMM_IF_CH_DATA_SET(*comm, LCD_BASE);
+        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_lcd_write);
+        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_lcd_read);
+        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_lcd_putc);
+        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_lcd_getc);
+        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_lcd_control);
+
+        // Restore original console
+        CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+    }
+#endif
+}
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+//-----------------------------------------------------------------------------
 // Assumption: all diagnostic output must be GDB packetized unless
 // this is a configuration for a stand-alone ROM system.
 #if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGSEM_HAL_ROM_MONITOR)
 # define HAL_DIAG_USES_HARDWARE
 #endif
 
-
-//-----------------------------------------------------------------------------
-// Serial diag functions.
-#ifdef CYG_KERNEL_DIAG_SERIAL
-
-// Include the serial driver.
-#define CYG_CMA_PORT CYGHWR_HAL_POWERPC_COGENT_DIAG_PORT
-#include <cma_ser.inl>
+#if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)
+# define __BASE ((cyg_uint8*)CYG_DEV_SERIAL_BASE_A)
+#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)
+# define __BASE ((cyg_uint8*)CYG_DEV_SERIAL_BASE_B)
+#else
+# error "Cannot use LCD"
+#endif
 
 #ifdef HAL_DIAG_USES_HARDWARE
 
 void hal_diag_init(void)
 {
-    hal_cma_init_serial();
+    cyg_hal_plf_comms_init();
 }
 
 void hal_diag_write_char(char __c)
 {
-    hal_cma_put_char(__c);
+    cyg_hal_plf_serial_putc(__BASE, __c);
 }
 
 void hal_diag_read_char(char *c)
 {
-    *c = (char) hal_cma_get_char();
+    *c = cyg_hal_plf_serial_getc(__BASE);
 }
 
 #else  // ifdef HAL_DIAG_USES_HARDWARE
 
 // Initialize diag port
-void hal_diag_init(void)
+void
+hal_diag_init(void)
 {
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-    // assume GDB channel is already set up.
-    if (0) hal_cma_init_serial();       // avoids compiler warning
-#else
-    hal_cma_init_serial();
-#endif
-      
+    // Init devices
+    cyg_hal_plf_comms_init();
 }
 
 void 
@@ -128,14 +603,14 @@ hal_diag_write_char_serial( char c )
 {
     unsigned long __state;
     HAL_DISABLE_INTERRUPTS(__state);
-    hal_cma_put_char(c);
+    cyg_hal_plf_serial_putc(__BASE, c);
     HAL_RESTORE_INTERRUPTS(__state);
 }
 
 void
 hal_diag_read_char(char *c)
 {
-    *c = (char) hal_cma_get_char();
+    *c = cyg_hal_plf_serial_getc(__BASE);
 }
 
 void 
@@ -219,266 +694,11 @@ hal_diag_write_char(char c)
     }
 }
 
-#endif // ifdef HAL_DIAG_USES_HARDWARE
-
-#endif // ifdef CYG_KERNEL_DIAG_SERIAL
-
-//-----------------------------------------------------------------------------
-// Cogent board specific LCD code
-
-#if defined(CYG_KERNEL_DIAG_LCD)
-
-// FEMA 162B 16 character x 2 line LCD
-// base addresses and register offsets *
-
-#define MBD_BASE 0
-
-#define LCD_BASE                (MBD_BASE + 0xEB00007)
-
-#define LCD_DATA                (LCD_BASE + 0x00) // read/write lcd data
-#define LCD_STAT                (LCD_BASE + 0x08) // read lcd busy status
-#define LCD_CMD                 (LCD_BASE + 0x08) // write lcd command
-
-// status register bit definitions
-#define LCD_STAT_BUSY   0x80    // 1 = display busy
-#define LCD_STAT_ADD    0x7F    // bits 0-6 return current display address
-
-// command register definitions
-#define LCD_CMD_RST             0x01    // clear entire display and reset display address
-#define LCD_CMD_HOME            0x02    // reset display address and reset any shifting
-#define LCD_CMD_ECL             0x04    // move cursor left one position on next data write
-#define LCD_CMD_ESL             0x05    // shift display left one position on next data write
-#define LCD_CMD_ECR             0x06    // move cursor right one position on next data write
-#define LCD_CMD_ESR             0x07    // shift display right one position on next data write
-#define LCD_CMD_DOFF            0x08    // display off, cursor off, blinking off
-#define LCD_CMD_BL              0x09    // blink character at current cursor position
-#define LCD_CMD_CUR             0x0A    // enable cursor on
-#define LCD_CMD_DON             0x0C    // turn display on
-#define LCD_CMD_CL              0x10    // move cursor left one position
-#define LCD_CMD_SL              0x14    // shift display left one position
-#define LCD_CMD_CR              0x18    // move cursor right one position
-#define LCD_CMD_SR              0x1C    // shift display right one position
-#define LCD_CMD_MODE            0x38    // sets 8 bits, 2 lines, 5x7 characters
-#define LCD_CMD_ACG             0x40    // bits 0-5 sets the character generator address
-#define LCD_CMD_ADD             0x80    // bits 0-6 sets the display data address to line 1 +
-
-// LCD status values
-#define LCD_OK                  0x00
-#define LCD_ERR                 0x01
-
-#define LCD_LINE0       0x00
-#define LCD_LINE1       0x40
-
-#define LCD_LINE_LENGTH 16
-
-static char lcd_line0[LCD_LINE_LENGTH+1];
-static char lcd_line1[LCD_LINE_LENGTH+1];
-static char *lcd_line[2] = { lcd_line0, lcd_line1 };
-static int lcd_curline = 0;
-static int lcd_linepos = 0;
-
-
-static void lcd_dis(int add, char *string);
-
-externC void diag_write_string (const char*);
-
-void hal_diag_init()
-{
-    cyg_uint8 stat;
-    int i;
-    
-    // wait for not busy
-    // Note: It seems that the LCD isn't quite ready to process commands
-    // when it clears the BUSY flag. Reading the status address an extra
-    // time seems to give it enough breathing room.
-    do { HAL_READ_UINT8 (LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
-    HAL_READ_UINT8 (LCD_STAT, stat);
-
-    // configure the lcd for 8 bits/char, 2 lines
-    // and 5x7 dot matrix
-    HAL_WRITE_UINT8 (LCD_CMD, LCD_CMD_MODE);
-
-    // wait for not busy
-    do { HAL_READ_UINT8 (LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
-    HAL_READ_UINT8 (LCD_STAT, stat);
-
-    // turn the LCD display on
-    HAL_WRITE_UINT8 (LCD_CMD, LCD_CMD_DON);
-
-    lcd_curline = 0;
-    lcd_linepos = 0;
-
-    for( i = 0; i < LCD_LINE_LENGTH; i++ )
-        lcd_line[0][i] = lcd_line[1][i] = ' ';
-
-    lcd_line[0][LCD_LINE_LENGTH] = lcd_line[1][LCD_LINE_LENGTH] = 0;
-
-    lcd_dis( LCD_LINE0, lcd_line[0] );
-    lcd_dis( LCD_LINE1, lcd_line[1] );
-
-
-#ifdef CYGSEM_HAL_ROM_MONITOR
-    // It's handy to have the LCD initialized at reset when using it
-    // for debugging output.
-    {
-        diag_write_string ("eCos ROM   " __TIME__ "\n");
-        diag_write_string (__DATE__ "\n");
-    }
-#endif
-}
-
-// this routine writes the string to the LCD
-// display after setting the address to add
-static void lcd_dis(int add, char *string)
-{
-    cyg_uint8 stat;
-    int i;
-
-    // wait for not busy (see Note in hal_diag_init above)
-    do { HAL_READ_UINT8 (LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
-    HAL_READ_UINT8 (LCD_STAT, stat);
-
-    // write the address
-    HAL_WRITE_UINT8 (LCD_CMD, (LCD_CMD_ADD + add));
-
-    // write the string out to the display stopping when we reach 0
-    for (i = 0; *string != '\0'; i++)
-    {
-        // wait for not busy
-        do { HAL_READ_UINT8 (LCD_STAT, stat); } while (stat & LCD_STAT_BUSY);
-        HAL_READ_UINT8 (LCD_STAT, stat);
+#endif  // ifdef HAL_DIAG_USES_HARDWARE
 
-        // write the data
-        HAL_WRITE_UINT8 (LCD_DATA, *string++);
-    }
-}
-
-void hal_diag_write_char(char c)
-{
-    unsigned long __state;
-    int i;
-    
-    // ignore CR
-    if( c == '\r' ) return;
-    
-    HAL_DISABLE_INTERRUPTS(__state);
-    if( c == '\n' )
-    {
-        lcd_dis( LCD_LINE0, &lcd_line[lcd_curline^1][0] );
-        lcd_dis( LCD_LINE1, &lcd_line[lcd_curline][0] );            
-
-        // Do a line feed
-        lcd_curline ^= 1;
-        lcd_linepos = 0;
-        
-        for( i = 0; i < LCD_LINE_LENGTH; i++ )
-            lcd_line[lcd_curline][i] = ' ';
-
-        HAL_RESTORE_INTERRUPTS(__state);
-        return;
-    }
-
-    // Only allow to be output if there is room on the LCD line
-    if( lcd_linepos < LCD_LINE_LENGTH )
-        lcd_line[lcd_curline][lcd_linepos++] = c;
-
-    HAL_RESTORE_INTERRUPTS(__state);
-}
-
-void hal_diag_read_char(char* c) {}
-
-#endif
-
-
-//---------------------------------------------------------------------------*/
-// PromICE AI interface
-
-
-#if defined(CYG_KERNEL_DIAG_ROMART)
-
-#ifdef CYGPKG_HAL_POWERPC_COGENT
-#define PROMICE_AILOC           0xfff00020
-#endif
-
-// Add this to the LoadICE config file: ailoc 20 19200
-// Note: I couldn't get this to work. jskov
-
-#define PROMICE_BUS_SIZE        16
-#define PROMICE_BURST_SIZE      1
-
-#if PROMICE_BUS_SIZE == 16
+#undef __BASE
 
-typedef volatile struct
-{
-    volatile cyg_uint16 zero;
-//    cyg_uint16          pad1[PROMICE_BURST_SIZE];
-    volatile cyg_uint16 one;
-//    cyg_uint16          pad2[PROMICE_BURST_SIZE];
-    volatile cyg_uint16 data;
-//    cyg_uint16          pad3[PROMICE_BURST_SIZE];
-    volatile cyg_uint16 status;
-
-} AISTRUCT;
-
-#endif
-
-AISTRUCT *AI = (AISTRUCT *)PROMICE_AILOC;
-
-#define PROMICE_STATUS_TDA      0x01
-#define PROMICE_STATUS_HDA      0x02
-#define PROMICE_STATUS_OVR      0x04
-
-void hal_diag_init()
-{
-    volatile cyg_uint8 junk;
- 
-    while( AI->status == 0xCC )
-        continue;
-
-    junk = AI->data;
-}
-
-static void ai_write_char(cyg_uint8 data)
-{
-    volatile cyg_uint8 junk;
-    int i;
-    unsigned long __state;
-    
-    HAL_DISABLE_INTERRUPTS(__state);
-
-    // Wait for tda == 0
-    while( (AI->status & PROMICE_STATUS_TDA) == PROMICE_STATUS_TDA )
-        continue;
-
-    // Send start bit
-    junk = AI->one;
-
-    for( i = 0; i < 8; i++ )
-    {
-        // send ls bit of data
-        if( (data & 1) == 1 )
-            junk = AI->one;
-        else
-            junk = AI->zero;
-
-        // shift down for next bit
-        data >>= 1;
-    }
-
-    // Send stop bit
-    junk = AI->one;
-
-    HAL_RESTORE_INTERRUPTS(__state);
-
-    // all done
-}
-
-void hal_diag_write_char(char c)
-{
-    ai_write_char((cyg_uint8)c);
-}
-
-#endif
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
 //-----------------------------------------------------------------------------
 // End of hal_diag.c