* [RFC] Generic serial 8250/16x50 diagnostics support
@ 2005-09-19 14:58 David Vrabel
2005-10-07 13:55 ` David Vrabel
0 siblings, 1 reply; 2+ messages in thread
From: David Vrabel @ 2005-09-19 14:58 UTC (permalink / raw)
To: ecos-devel
[-- Attachment #1: Type: text/plain, Size: 1439 bytes --]
Hi,
Currently, every platform copies and pastes the diagnostic support for
8250/16x50 compatible UARTs. This is less than ideal, so I've
implemented generic support for diagnostics via 8250 UARTs.
The platform just needs to provide characteristics of the UARTs (base
address, clock frequency, interrupt vector, any quirks for the UART,
etc.). As an example, I've converted the ixp4xx hal and the pc hal to
use it.
A couple of points I could use feedback on:
1. uart_write(), uart_read() may not be sufficiently generic (the .base
and .regshift scheme is what the Linux 8250 driver uses so it's probably
good for most platforms). Should a mechanism be provided for the
platform to provide it's own function to read/write to UART registers?
e.g., function pointers in the serial_8250_channel_data_t structure?
2. Regarding the package name: CYGHWR_HAL_COMMON_8250_SERIAL_DIAG since
it's hardware related or CYGINT_HAL_COMMON_8250_SERIAL_DIAG since it's
an interface?
The attached patches are:
hal-common-serial-8250-diag:
- The generic 8250 diagnostics driver.
hal-arm-xscale-ixp4xx-use-generic-diag:
- update the ixp4xx HAL to use the generic diagnostics driver.
hal-i386-pc-use-generic-diag:
- update the pc HAL to use the generic diagnostics driver.
David Vrabel
--
David Vrabel, Design Engineer
Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/
[-- Attachment #2: hal-common-serial-8250-diag --]
[-- Type: text/plain, Size: 16317 bytes --]
Index: ecos-working/packages/hal/common/current/cdl/common.cdl
===================================================================
--- ecos-working.orig/packages/hal/common/current/cdl/common.cdl 2005-09-19 15:14:36.000000000 +0100
+++ ecos-working/packages/hal/common/current/cdl/common.cdl 2005-09-19 15:23:37.000000000 +0100
@@ -150,3 +150,9 @@
}
}
+cdl_interface CYGHWR_HAL_COMMON_8250_SERIAL_DIAG {
+ display "Use the generic 8250 serial diagnostics routines"
+
+ compile hal_serial_8250_diag.c
+}
+
Index: ecos-working/packages/hal/common/current/include/hal_serial_8250_diag.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ecos-working/packages/hal/common/current/include/hal_serial_8250_diag.h 2005-09-19 15:23:37.000000000 +0100
@@ -0,0 +1,69 @@
+#ifndef CYGONCE_HAL_8250_SERIAL_DIAG_H
+#define CYGONCE_HAL_8250_SERIAL_DIAG_H
+/*=============================================================================
+//
+// hal_8250_serial_diag.h
+//
+// HAL Support for Kernel Diagnostic Routines for 8250/16x50 UARTs
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2005 Arcom Control Systems Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): <knud.woehler@microplex.de>
+// Date: 2002-09-03
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+/*
+ * UART features
+ */
+#define UART_FEATURE_HAVE_UUE 0x1 /* Have UART Unit Enable bit in IER */
+
+typedef struct {
+ unsigned freq; /* frequeny of UART clock in Hz */
+ unsigned base; /* MMIO address or I/O port */
+ int regshift; /* shift to register offset */
+ int isr_vector;
+ unsigned uart_features;
+ int baud_rate;
+ cyg_bool valid;
+ cyg_int32 msec_timeout;
+} serial_8250_channel_data_t;
+
+externC void cyg_hal_serial_8250_diag_init(serial_8250_channel_data_t *channels, int num);
+
+#endif //CYGONCE_HAL_8250_SERIAL_DIAG_H
Index: ecos-working/packages/hal/common/current/src/hal_serial_8250_diag.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ecos-working/packages/hal/common/current/src/hal_serial_8250_diag.c 2005-09-19 15:54:56.000000000 +0100
@@ -0,0 +1,386 @@
+//=============================================================================
+//
+// hal_serial_8250_diag.c
+//
+// HAL diagnostic output code for 8250/16x50 UARTs
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2005 Arcom Control Systems Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): <dvrabel@arcom.com>
+// Date: 2005-09-15
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h> // base types
+
+#include <cyg/hal/hal_arch.h> // basic machine info
+#include <cyg/hal/hal_intr.h> // interrupt macros
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h> // interface API
+#include <cyg/hal/hal_misc.h>
+
+#include <cyg/hal/hal_serial_8250_diag.h>
+
+
+/* 8250/16x50 UART registers */
+#define UART_RBR 0x00 // Receive Buffer Register
+
+#define UART_THR 0x00 // Transmit Holding Register
+
+#define UART_IER 0x01 // Interrupt Enable Register
+# define UART_IER_RCV 0x01
+# define UART_IER_XMT 0x02
+# define UART_IER_LS 0x04
+# define UART_IER_MS 0x08
+# define UART_IER_UUE 0x40 // UART Unit Enable bit
+
+#define UART_IIR 0x02 // Interrupt Identification Register
+
+#define UART_FCR 0x02 // FIFO Control Register
+
+#define UART_LCR 0x03 // Line Control Register
+# define UART_LCR_WLS0 0x01 // word length select bit 0
+# define UART_LCR_WLS1 0x02 // word length select bit 1
+# define UART_LCR_STB 0x04 // number of stop bits
+# define UART_LCR_PEN 0x08 // parity enable
+# define UART_LCR_EPS 0x10 // even parity select
+# define UART_LCR_SP 0x20 // stick parity
+# define UART_LCR_SB 0x40 // set break
+# define UART_LCR_DLAB 0x80 // divisor latch access bit
+
+#define UART_MCR 0x04 // Modem Control Register
+# define UART_MCR_DTR 0x01
+# define UART_MCR_RTS 0x02
+# define UART_MCR_INT 0x08 // Enable interrupts
+
+#define UART_LSR 0x05 // Line Status Register
+# define UART_LSR_DR 0x01 // data ready
+# define UART_LSR_OE 0x02 // overrun error
+# define UART_LSR_PE 0x04 // parity error
+# define UART_LSR_FE 0x08 // framing error
+# define UART_LSR_BI 0x10 // break interrupt
+# define UART_LSR_THRE 0x20 // transmitter holding register empty
+# define UART_LSR_TEMT 0x40 // transmitter register empty
+# define UART_LSR_ERR 0x80 // any error condition
+
+#define UART_MSR 0x06 // Modem Status Register
+# define UART_MSR_DCTS 0x01 // delta clear to send
+# define UART_MSR_DDSR 0x02 // delta data set ready
+# define UART_MSR_TERI 0x04 // trailing edge ring indicator
+# define UART_MSR_DDCD 0x08 // delta data carrier detect
+# define UART_MSR_CTS 0x10 // clear to send
+# define UART_MSR_DSR 0x20 // data set ready
+# define UART_MSR_RI 0x40 // ring indicator
+# define UART_MSR_DCD 0x80 // data carrier detect
+
+#define UART_DLL 0x00 // Divisor Latch LSB (if DLAB = 1)
+#define UART_DLM 0x01 // Divisor Latch MSB (if DLAB = 1)
+
+
+static void uart_write(serial_8250_channel_data_t *chan, int reg, cyg_uint8 data)
+{
+ HAL_WRITE_UINT8(chan->base + (reg << chan->regshift), data);
+}
+
+static cyg_uint8 uart_read(serial_8250_channel_data_t *chan, int reg)
+{
+ cyg_uint8 data;
+ HAL_READ_UINT8(chan->base + (reg << chan->regshift), data);
+ return data;
+}
+
+static void set_baud(serial_8250_channel_data_t *chan)
+{
+ unsigned divisor;
+ cyg_uint32 lcr;
+
+ divisor = (chan->freq + 8*chan->baud_rate) / (16*chan->baud_rate);
+
+ lcr = uart_read(chan, UART_LCR);
+ uart_write(chan, UART_LCR, lcr | UART_LCR_DLAB);
+ uart_write(chan, UART_DLL, divisor & 0xff);
+ uart_write(chan, UART_DLM, (divisor >> 8) & 0xff);
+ uart_write(chan, UART_LCR, lcr);
+}
+
+static void init_channel(serial_8250_channel_data_t *chan)
+{
+ cyg_uint8 ier, lsr;
+
+ ier = 0;
+ if (chan->uart_features & UART_FEATURE_HAVE_UUE)
+ ier |= UART_IER_UUE;
+ uart_write(chan, UART_IER, ier);
+ uart_write(chan, UART_MCR, 0);
+
+ set_baud(chan);
+
+ // 8-1-no parity.
+ uart_write(chan, UART_LCR, UART_LCR_WLS0 | UART_LCR_WLS1);
+
+ // Test whether the channel is valid or not. If the status
+ // register reads back all ones, its a fair bet that it is not
+ // actually there!
+ lsr = uart_read(chan, UART_LSR);
+ chan->valid = (lsr != 0xFF);
+
+ uart_write(chan, UART_FCR, 0x07); // Enable & clear FIFO
+}
+
+static void cyg_hal_serial_8250_diag_putc(void *__ch_data, char c)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ cyg_uint8 lsr;
+
+ if (!chan->valid)
+ return;
+
+ CYGARC_HAL_SAVE_GP();
+ do {
+ lsr = uart_read(chan, UART_LSR);
+ } while ((lsr & UART_LSR_THRE) == 0);
+
+ uart_write(chan, UART_THR, c);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool cyg_hal_serial_8250_diag_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ cyg_uint8 lsr;
+
+ if (!chan->valid)
+ return false;
+
+ lsr = uart_read(chan, UART_LSR);
+ if ((lsr & UART_LSR_DR) == 0)
+ return false;
+
+ *ch = uart_read(chan, UART_RBR);
+
+ return true;
+}
+
+static cyg_uint8 cyg_hal_serial_8250_diag_getc(void* __ch_data)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ cyg_uint8 ch;
+
+ if (!chan->valid)
+ return '\n';
+
+ CYGARC_HAL_SAVE_GP();
+
+ while (!cyg_hal_serial_8250_diag_getc_nonblock(__ch_data, &ch));
+
+ CYGARC_HAL_RESTORE_GP();
+
+ return ch;
+}
+
+static void cyg_hal_serial_8250_diag_write(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_serial_8250_diag_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void cyg_hal_serial_8250_diag_read(void* __ch_data, cyg_uint8 *__buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_serial_8250_diag_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool cyg_hal_serial_8250_diag_getc_timeout(void* __ch_data, cyg_uint8 *ch)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ int delay_count;
+ cyg_bool res;
+
+ CYGARC_HAL_SAVE_GP();
+
+ delay_count = chan->msec_timeout * 10; // delay in 0.1 ms steps
+
+ for(;;) {
+ res = cyg_hal_serial_8250_diag_getc_nonblock(__ch_data, ch);
+ if (res || 0 == delay_count--)
+ break;
+
+ CYGACC_CALL_IF_DELAY_US(100);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+
+static int cyg_hal_serial_8250_diag_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ static int irq_state = 0;
+ int ret = 0;
+ cyg_uint8 ier;
+ cyg_uint32 b;
+ va_list ap;
+
+ CYGARC_HAL_SAVE_GP();
+
+ switch (__func) {
+ case __COMMCTL_GETBAUD:
+ ret = chan->baud_rate;
+ break;
+ case __COMMCTL_SETBAUD:
+ chan->baud_rate = va_arg(ap, cyg_int32);
+ /* FIXME: Should check that the baud rate is valid? */
+ set_baud(chan);
+ break;
+ case __COMMCTL_IRQ_ENABLE:
+ irq_state = 1;
+
+ ier = UART_IER_RCV;
+ if (chan->uart_features & UART_FEATURE_HAVE_UUE)
+ ier |= UART_IER_UUE;
+ uart_write(chan, UART_IER, ier);
+ uart_write(chan, UART_MCR, UART_MCR_INT | UART_MCR_DTR | UART_MCR_RTS);
+
+ HAL_INTERRUPT_UNMASK(chan->isr_vector);
+ break;
+ case __COMMCTL_IRQ_DISABLE:
+ ret = irq_state;
+ irq_state = 0;
+
+ ier = 0;
+ if (chan->uart_features & UART_FEATURE_HAVE_UUE)
+ ier |= UART_IER_UUE;
+ uart_write(chan, UART_IER, ier);
+
+ HAL_INTERRUPT_MASK(chan->isr_vector);
+ break;
+ case __COMMCTL_DBG_ISR_VECTOR:
+ ret = chan->isr_vector;
+ break;
+ case __COMMCTL_SET_TIMEOUT:
+ {
+ va_list ap;
+
+ va_start(ap, __func);
+
+ ret = chan->msec_timeout;
+ chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+ va_end(ap);
+ }
+ default:
+ break;
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return ret;
+}
+
+static int cyg_hal_serial_8250_diag_isr(void *__ch_data, int *__ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+ serial_8250_channel_data_t *chan = (serial_8250_channel_data_t *)__ch_data;
+ int res = 0;
+ char c;
+ cyg_uint8 lsr;
+
+ CYGARC_HAL_SAVE_GP();
+
+ cyg_drv_interrupt_acknowledge(chan->isr_vector);
+
+ *__ctrlc = 0;
+ lsr = uart_read(chan, UART_LSR);
+ if ( (lsr & UART_LSR_DR) != 0 ) {
+ c = uart_read(chan, UART_RBR);
+ if (cyg_hal_is_break(&c , 1))
+ *__ctrlc = 1;
+ }
+
+ res = CYG_ISR_HANDLED;
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+void cyg_hal_serial_8250_diag_init(serial_8250_channel_data_t *channels, int num)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (channels[i].baud_rate == 0)
+ channels[i].baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
+
+ HAL_INTERRUPT_MASK(channels[i].isr_vector);
+
+ init_channel(&channels[i]);
+
+ // Setup procs in the vector table
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[i]);
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_serial_8250_diag_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_serial_8250_diag_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_serial_8250_diag_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_serial_8250_diag_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_serial_8250_diag_control);
+ CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_serial_8250_diag_isr);
+ CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_serial_8250_diag_getc_timeout);
+ }
+
+ // Restore original console
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_serial_8250_diag.c
[-- Attachment #3: hal-arm-xscale-ixp4xx-use-generic-diag --]
[-- Type: text/plain, Size: 13067 bytes --]
Index: ecos-working/packages/hal/arm/xscale/ixp425/current/cdl/hal_arm_xscale_ixp425.cdl
===================================================================
--- ecos-working.orig/packages/hal/arm/xscale/ixp425/current/cdl/hal_arm_xscale_ixp425.cdl 2005-05-04 10:33:00.000000000 +0100
+++ ecos-working/packages/hal/arm/xscale/ixp425/current/cdl/hal_arm_xscale_ixp425.cdl 2005-09-19 11:09:34.000000000 +0100
@@ -55,6 +55,8 @@
implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
implements CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+ implements CYGHWR_HAL_COMMON_8250_SERIAL_DIAG
+
hardware
include_dir cyg/hal
define_header hal_arm_xscale_ixp425.h
Index: ecos-working/packages/hal/arm/xscale/ixp425/current/src/ixp425_diag.c
===================================================================
--- ecos-working.orig/packages/hal/arm/xscale/ixp425/current/src/ixp425_diag.c 2003-03-18 13:10:04.000000000 +0000
+++ ecos-working/packages/hal/arm/xscale/ixp425/current/src/ixp425_diag.c 2005-09-19 11:25:59.000000000 +0100
@@ -66,348 +66,41 @@
#include <cyg/hal/hal_if.h> // interface API
#include <cyg/hal/hal_misc.h> // Helper functions
-#if !defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && !defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
-#define IXP425_NUM_UARTS 0
-#elif defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
-#define IXP425_NUM_UARTS 2
-#else
-#define IXP425_NUM_UARTS 1
-#endif
-
-#if IXP425_NUM_UARTS > 0
-
-/*---------------------------------------------------------------------------*/
-/* 16550 compatible UARTS */
+#include <cyg/hal/hal_8250_serial_diag.h>
-// Define the serial registers.
-#define CYG_DEV_RBR 0x00 // receiver buffer register, read, dlab = 0
-#define CYG_DEV_THR 0x00 // transmitter holding register, write, dlab = 0
-#define CYG_DEV_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
-#define CYG_DEV_IER 0x01 // interrupt enable register, read/write, dlab = 0
-#define CYG_DEV_DLM 0x01 // divisor latch (MS), read/write, dlab = 1
-#define CYG_DEV_IIR 0x02 // interrupt identification register, read, dlab = 0
-#define CYG_DEV_FCR 0x02 // fifo control register, write, dlab = 0
-#define CYG_DEV_LCR 0x03 // line control register, write
-#define CYG_DEV_MCR 0x04 // modem control register, write
-#define CYG_DEV_LSR 0x05 // line status register, read
-#define CYG_DEV_MSR 0x06 // modem status register, read
-#define CYG_DEV_SCR 0x07 // scratch pad register
-
-// Interrupt Enable Register
-#define SIO_IER_RCV 0x01
-#define SIO_IER_XMT 0x02
-#define SIO_IER_LS 0x04
-#define SIO_IER_MS 0x08
-#define SIO_IER_UUE 0x40 // UART Unit Enable
-
-// 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
-
-// Modem Control Register
-#define SIO_MCR_DTR 0x01
-#define SIO_MCR_RTS 0x02
-#define SIO_MCR_OUT1 0x04
-#define SIO_MCR_OUT2 0x08
-#define SIO_MCR_LOOP 0x10
-#define SIO_MCR_AFE 0x20
-
-#define UART1_BASE 0xC8000000
-#define UART2_BASE 0xC8001000
-
-//-----------------------------------------------------------------------------
-typedef struct {
- cyg_uint32* base;
- cyg_int32 msec_timeout;
- int isr_vector;
- cyg_int32 baud_rate;
-} channel_data_t;
-
-
-//-----------------------------------------------------------------------------
-// Based on 14.7456 MHz xtal
-static int
-set_baud( channel_data_t *chan )
-{
- cyg_uint32* base = chan->base;
- cyg_uint16 div = 921600 / chan->baud_rate;
- cyg_uint32 lcr;
-
- HAL_READ_UINT32(base+CYG_DEV_LCR, lcr);
- HAL_WRITE_UINT32(base+CYG_DEV_LCR, lcr|SIO_LCR_DLAB);
- HAL_WRITE_UINT32(base+CYG_DEV_DLL, div & 0xff);
- HAL_WRITE_UINT32(base+CYG_DEV_DLM, (div >> 8) & 0xff);
- HAL_WRITE_UINT32(base+CYG_DEV_LCR, lcr);
- return 1;
-}
-
-static void
-cyg_hal_plf_serial_init_channel(void* __ch_data)
-{
- cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
- channel_data_t* chan = (channel_data_t*)__ch_data;
-
- HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_UUE);
-
- // 8-1-no parity.
- HAL_WRITE_UINT32(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
- chan->baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
- set_baud( chan );
- HAL_WRITE_UINT32(base+CYG_DEV_FCR, 0x07); // Enable & clear FIFO
- HAL_WRITE_UINT32(base+CYG_DEV_MCR, SIO_MCR_OUT2); // Enable interrupt to core
-}
-
-void
-cyg_hal_plf_serial_putc(void *__ch_data, char c)
-{
- cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
- cyg_uint32 lsr, val;
- CYGARC_HAL_SAVE_GP();
-
- do {
- HAL_READ_UINT32(base+CYG_DEV_LSR, lsr);
- } while ((lsr & SIO_LSR_THRE) == 0);
-
- val = c;
- HAL_WRITE_UINT32(base+CYG_DEV_THR, val);
-
- CYGARC_HAL_RESTORE_GP();
-}
-
-static cyg_bool
-cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
-{
- cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
- cyg_uint32 lsr, val;
+#define UART1_BASE 0xC8000000
+#define UART2_BASE 0xC8001000
- HAL_READ_UINT32(base+CYG_DEV_LSR, lsr);
- if ((lsr & SIO_LSR_DR) == 0)
- return false;
-
- HAL_READ_UINT32(base+CYG_DEV_RBR, val);
- *ch = val;
-
- return true;
-}
-
-cyg_uint8
-cyg_hal_plf_serial_getc(void* __ch_data)
-{
- cyg_uint8 ch;
- CYGARC_HAL_SAVE_GP();
-
- while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
-
- CYGARC_HAL_RESTORE_GP();
- return ch;
-}
-
-static channel_data_t plf_ser_channels[] = {
-#if defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && !defined(HAL_PLATFORM_UART2_FIRST)
- { (cyg_uint32*)UART1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1 },
-#endif
-#if defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
- { (cyg_uint32*)UART2_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART2 }
-#endif
-#if defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && defined(HAL_PLATFORM_UART2_FIRST)
- { (cyg_uint32*)UART1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1 },
+#ifdef __ARMEB__
+#define REG_OFFSET 3
+#else
+#define REG_OFFSET 0
#endif
-};
-
-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();
-}
-
-cyg_bool
-cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
-{
- int delay_count;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- cyg_bool res;
- CYGARC_HAL_SAVE_GP();
-
- delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
-
- for(;;) {
- res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
- if (res || 0 == delay_count--)
- break;
-
- CYGACC_CALL_IF_DELAY_US(100);
- }
-
- CYGARC_HAL_RESTORE_GP();
- return res;
-}
-
-static int
-cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
-{
- static int irq_state = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- int ret = 0;
- CYGARC_HAL_SAVE_GP();
-
- switch (__func) {
- case __COMMCTL_IRQ_ENABLE:
- irq_state = 1;
-
- HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_RCV | SIO_IER_UUE);
- HAL_INTERRUPT_UNMASK(chan->isr_vector);
- break;
- case __COMMCTL_IRQ_DISABLE:
- ret = irq_state;
- irq_state = 0;
-
- HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_UUE);
- HAL_INTERRUPT_MASK(chan->isr_vector);
- break;
- case __COMMCTL_DBG_ISR_VECTOR:
- ret = chan->isr_vector;
- break;
- case __COMMCTL_SET_TIMEOUT:
+static channel_data_t ixp4xx_serial_channels[] = {
+#ifdef CYGSEM_HAL_IXP425_PLF_USES_UART1
{
- va_list ap;
-
- va_start(ap, __func);
-
- ret = chan->msec_timeout;
- chan->msec_timeout = va_arg(ap, cyg_uint32);
-
- va_end(ap);
- }
- case __COMMCTL_GETBAUD:
- ret = chan->baud_rate;
- break;
- case __COMMCTL_SETBAUD:
+ .freq = 14745600,
+ .base = UART1_BASE + REG_OFFSET,
+ .regshift = 2,
+ .uart_features = UART_FEATURE_HAVE_UUE,
+ .isr_vector = CYGNUM_HAL_INTERRUPT_UART1,
+ },
+#endif
+#ifdef CYGSEM_HAL_IXP425_PLF_USES_UART2
{
- cyg_uint32 b;
- va_list ap;
-
- va_start(ap, __func);
- b = va_arg(ap, cyg_int32);
- va_end(ap);
-
- if (b < 300 || b > 115200)
- ret = -1;
- else {
- chan->baud_rate = b;
- ret = set_baud(chan);
- }
- break;
- }
- default:
- break;
- }
- CYGARC_HAL_RESTORE_GP();
- return ret;
-}
-
-static int
-cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
- CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
-{
- int res = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- char c;
- cyg_uint8 lsr;
- CYGARC_HAL_SAVE_GP();
-
- cyg_drv_interrupt_acknowledge(chan->isr_vector);
-
- *__ctrlc = 0;
- HAL_READ_UINT32(chan->base+CYG_DEV_LSR, lsr);
- if ( (lsr & SIO_LSR_DR) != 0 ) {
-
- HAL_READ_UINT32(chan->base+CYG_DEV_RBR, c);
- if( cyg_hal_is_break( &c , 1 ) )
- *__ctrlc = 1;
-
- res = CYG_ISR_HANDLED;
- }
-
- CYGARC_HAL_RESTORE_GP();
- return res;
-}
-
-void
-cyg_hal_ixp425_serial_init(void)
-{
- hal_virtual_comm_table_t* comm;
- int i, cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-
- for (i = 0; i < IXP425_NUM_UARTS; i++) {
-
- // Disable interrupts.
- HAL_INTERRUPT_MASK(plf_ser_channels[i].isr_vector);
+ .freq = 14745600,
+ .base = UART2_BASE + REG_OFFSET,
+ .regshift = 2,
+ .uart_features = UART_FEATURE_HAVE_UUE,
+ .isr_vector = CYGNUM_HAL_INTERRUPT_UART2,
+ },
+#endif
+};
- // Init channels
- cyg_hal_plf_serial_init_channel(&plf_ser_channels[i]);
-
- // Setup procs in the vector table
- CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
- comm = CYGACC_CALL_IF_CONSOLE_PROCS();
- CYGACC_COMM_IF_CH_DATA_SET(*comm, &plf_ser_channels[i]);
- 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);
- CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
- CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
- }
- // Restore original console
- CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
-}
+/* FIXME: Move somewhere common */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-// If the platform provides some channels of its own, then this function will be
-// provided by that platform.
-#if !defined(CYGNUM_HAL_IXP425_PLF_SERIAL_CHANNELS) || !CYGNUM_HAL_IXP425_PLF_SERIAL_CHANNELS
void
cyg_hal_plf_comms_init(void)
{
@@ -418,11 +111,8 @@
initialized = 1;
- cyg_hal_ixp425_serial_init();
+ cyg_hal_8250_serial_diag_init(ixp4xx_serial_channels, ARRAY_SIZE(ixp4xx_serial_channels));
}
-#endif
-
-#endif // IXP425_NUM_UARTS > 0
/*---------------------------------------------------------------------------*/
[-- Attachment #4: hal-i386-pc-use-generic-diag --]
[-- Type: text/plain, Size: 27289 bytes --]
Index: ecos-working/packages/hal/i386/pc/current/cdl/hal_i386_pc.cdl
===================================================================
--- ecos-working.orig/packages/hal/i386/pc/current/cdl/hal_i386_pc.cdl 2005-09-05 16:22:55.000000000 +0100
+++ ecos-working/packages/hal/i386/pc/current/cdl/hal_i386_pc.cdl 2005-09-16 15:51:07.000000000 +0100
@@ -64,6 +64,7 @@
implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT_GUARANTEED
+ implements CYGINT_HAL_COMMON_8250_SERIAL_DIAG
define_proc {
puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_i386.h>"
Index: ecos-working/packages/hal/i386/pc/current/src/hal_diag.c
===================================================================
--- ecos-working.orig/packages/hal/i386/pc/current/src/hal_diag.c 2002-05-24 00:03:13.000000000 +0100
+++ ecos-working/packages/hal/i386/pc/current/src/hal_diag.c 2005-09-19 14:16:30.000000000 +0100
@@ -70,54 +70,62 @@
#include <cyg/hal/hal_if.h> // interface API
#include <cyg/hal/hal_misc.h> // Helper functions
-#include <cyg/hal/pcmb_serial.h>
+#include <cyg/hal/hal_serial_8250_diag.h>
+#include <cyg/hal/pcmb_screen.h>
//=============================================================================
#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
|| defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-channel_data_t pc_ser_channels[CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS];
+static serial_8250_channel_data_t pc_ser_channels[] = {
+#if (defined(CYGSEM_HAL_I386_PC_DIAG_SCREEN) && CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS >= 2) \
+ || (!defined(CYGSEM_HAL_I386_PC_DIAG_SCREEN) && CYGNUM_HAL_VIRTUAL_VECTORS >= 1)
+ {
+ .freq = 1843200,
+ .base = 0x3f8,
+ .msec_timeout = 1000,
+ .isr_vector = 36,
+ },
+#endif
+#if (defined(CYGSEM_HAL_I386_PC_DIAG_SCREEN) && CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS >= 3) \
+ || (!defined(CYGSEM_HAL_I386_PC_DIAG_SCREEN) && CYGNUM_HAL_VIRTUAL_VECTORS >= 2)
+ {
+ .freq = 1843200,
+ .base = 0x2f8,
+ .msec_timeout = 1000,
+ .isr_vector = 35,
+ },
+#endif
+};
+
+#ifdef CYGSEM_HAL_I386_PC_DIAG_SCREEN
+static pcmb_screen_channel_data_t pc_screen_channel = {
+ .isr_vector = 33,
+ .msec_timeout = 1000,
+};
+#endif
+
+/* FIXME: Move somewhere common */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
void
cyg_hal_plf_comms_init(void)
{
static int initialized = 0;
- int num_serial;
if (initialized)
return;
initialized = 1;
- num_serial = CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;
-#ifdef CYGSEM_HAL_I386_PC_DIAG_SCREEN
- --num_serial;
-#endif
- if (num_serial > 0) {
- // COM1
- pc_ser_channels[0].base = 0x3F8;
- pc_ser_channels[0].msec_timeout = 1000;
- pc_ser_channels[0].isr_vector = 36;
- }
- if (num_serial > 1) {
- // COM2
- pc_ser_channels[1].base = 0x2F8;
- pc_ser_channels[1].msec_timeout = 1000;
- pc_ser_channels[1].isr_vector = 35;
- }
-
- cyg_hal_plf_serial_init();
+ cyg_hal_serial_8250_diag_init(pc_ser_channels, ARRAY_SIZE(pc_ser_channels));
#ifdef CYGSEM_HAL_I386_PC_DIAG_SCREEN
-
- pc_ser_channels[num_serial].base = 0x060;
- pc_ser_channels[num_serial].msec_timeout = 1000;
- pc_ser_channels[num_serial].isr_vector = 33;
- cyg_hal_plf_screen_init();
+ cyg_hal_plf_screen_init(&pc_screen_channel);
-#endif
+#endif
}
//=============================================================================
Index: ecos-working/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl
===================================================================
--- ecos-working.orig/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl 2005-05-04 10:33:29.000000000 +0100
+++ ecos-working/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl 2005-09-16 16:19:22.000000000 +0100
@@ -66,7 +66,7 @@
found on modern motherboards, such as ethernet, sound and
video devices. These are supported by drivers elsewhere."
- compile pcmb_misc.c pcmb_serial.c
+ compile pcmb_misc.c
implements CYGINT_HAL_I386_MEM_REAL_REGION_TOP
implements CYGINT_HAL_PLF_IF_IDE
Index: ecos-working/packages/hal/i386/pcmb/current/include/pcmb_screen.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ ecos-working/packages/hal/i386/pcmb/current/include/pcmb_screen.h 2005-09-19 14:07:58.000000000 +0100
@@ -0,0 +1,50 @@
+#ifndef CYGONCE_HAL_PCMB_SCREEN_H
+#define CYGONCE_HAL_PCMB_SCREEN_H
+
+//==========================================================================
+//
+// pcmb_screen.h
+//
+// i386/pc Motherboard screen device support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+typedef struct {
+ int isr_vector;
+ cyg_int32 msec_timeout;
+} pcmb_screen_channel_data_t;
+
+#endif /* CYGONCE_HAL_PCMB_SCREEN_H */
Index: ecos-working/packages/hal/i386/pcmb/current/include/pcmb_serial.h
===================================================================
--- ecos-working.orig/packages/hal/i386/pcmb/current/include/pcmb_serial.h 2005-01-22 15:11:31.000000000 +0000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,96 +0,0 @@
-#ifndef CYGONCE_HAL_PCMB_SERIAL_H
-#define CYGONCE_HAL_PCMB_SERIAL_H
-
-//==========================================================================
-//
-// pcmb_serial.h
-//
-// i386/pc Motherboard serial device support
-//
-//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s): nickg
-// Contributors:
-// Date: 2001-03-07
-// Purpose: PC serial support
-// Description:
-//
-//
-//
-//
-//
-//
-// Usage:
-// #include <cyg/hal/pcmb_serial.h>
-// ...
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
-
-#include <pkgconf/hal.h>
-#include <pkgconf/hal_i386.h>
-#include <pkgconf/hal_i386_pcmb.h>
-
-#include <cyg/infra/cyg_type.h>
-
-//---------------------------------------------------------------------------
-
-//=============================================================================
-
-typedef struct {
- cyg_uint16 base;
- cyg_uint16 valid;
- cyg_int32 msec_timeout;
- cyg_int32 isr_vector;
-} channel_data_t;
-
-__externC channel_data_t pc_ser_channels[];
-
-//=============================================================================
-
-__externC void cyg_hal_plf_serial_init(void);
-
-#if CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT > 0
-
-__externC void cyg_hal_plf_screen_init(void);
-__externC void cyg_hal_plf_screen_position(int *x, int *y);
-#endif
-
-//---------------------------------------------------------------------------
-#endif // ifndef CYGONCE_HAL_PCMB_SERIAL_H
-// End of pcmb_serial.h
Index: ecos-working/packages/hal/i386/pcmb/current/src/pcmb_screen.c
===================================================================
--- ecos-working.orig/packages/hal/i386/pcmb/current/src/pcmb_screen.c 2005-01-22 15:11:31.000000000 +0000
+++ ecos-working/packages/hal/i386/pcmb/current/src/pcmb_screen.c 2005-09-19 14:09:14.000000000 +0100
@@ -64,10 +64,9 @@
#include <cyg/hal/hal_if.h> // interface API
#include <cyg/hal/hal_misc.h>
-#include <cyg/hal/pcmb_serial.h>
+#include <cyg/hal/pcmb_screen.h>
-// Index into pc_ser_channels[] for screen entry.
-#define PCMB_PORT_INDEX (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS - 1)
+#define SCREEN_CHANNEL_IDX (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS - 1)
//-----------------------------------------------------------------------------
// Screen output definitions...
@@ -728,7 +727,7 @@
cyg_hal_plf_screen_getc_timeout(void* __ch_data, cyg_uint8* ch)
{
int delay_count;
- channel_data_t* chan = (channel_data_t*)__ch_data;
+ pcmb_screen_channel_data_t* chan = (pcmb_screen_channel_data_t*)__ch_data;
cyg_bool res;
CYGARC_HAL_SAVE_GP();
@@ -750,7 +749,7 @@
cyg_hal_plf_screen_control(void *__ch_data, __comm_control_cmd_t __func, ...)
{
static int irq_state = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
+ pcmb_screen_channel_data_t* chan = (pcmb_screen_channel_data_t*)__ch_data;
int ret = 0;
CYGARC_HAL_SAVE_GP();
@@ -792,7 +791,7 @@
CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
{
int res = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
+ pcmb_screen_channel_data_t* chan = (pcmb_screen_channel_data_t*)__ch_data;
char c;
CYGARC_HAL_SAVE_GP();
@@ -815,23 +814,23 @@
return res;
}
-void cyg_hal_plf_screen_init(void)
+void cyg_hal_plf_screen_init(pcmb_screen_channel_data_t *chan)
{
hal_virtual_comm_table_t* comm;
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
// Disable interrupts.
- HAL_INTERRUPT_MASK(pc_ser_channels[PCMB_PORT_INDEX].isr_vector);
+ HAL_INTERRUPT_MASK(chan->isr_vector);
// Init channels
- cyg_hal_plf_screen_init_channel(&pc_ser_channels[PCMB_PORT_INDEX]);
+ cyg_hal_plf_screen_init_channel(chan);
// Setup procs in the vector table
// Set channel 2
- CYGACC_CALL_IF_SET_CONSOLE_COMM(PCMB_PORT_INDEX);
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(SCREEN_CHANNEL_IDX);
comm = CYGACC_CALL_IF_CONSOLE_PROCS();
- CYGACC_COMM_IF_CH_DATA_SET(*comm, &pc_ser_channels[PCMB_PORT_INDEX]);
+ CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_screen_write);
CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_screen_read);
CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_screen_putc);
Index: ecos-working/packages/hal/i386/pcmb/current/src/pcmb_serial.c
===================================================================
--- ecos-working.orig/packages/hal/i386/pcmb/current/src/pcmb_serial.c 2005-06-16 16:05:11.000000000 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,404 +0,0 @@
-//=============================================================================
-//
-// pcmb_serial.c
-//
-// HAL diagnostic output code
-//
-//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//=============================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s): proven
-// Contributors:proven
-// Date: 1998-10-05
-// Purpose: HAL diagnostic output
-// Description: Implementations of HAL diagnostic output support.
-//
-//####DESCRIPTIONEND####
-//
-//=============================================================================
-
-#include <pkgconf/hal.h>
-
-#include <cyg/infra/cyg_type.h> // base types
-
-#include <cyg/hal/hal_arch.h> // basic machine info
-#include <cyg/hal/hal_intr.h> // interrupt macros
-#include <cyg/hal/hal_io.h> // IO macros
-#include <cyg/hal/drv_api.h>
-#include <cyg/hal/hal_if.h> // interface API
-#include <cyg/hal/hal_misc.h>
-
-#include <cyg/hal/pcmb_serial.h>
-
-
-/*---------------------------------------------------------------------------*/
-/* From serial_16550.h */
-#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==9600
-#define CYG_DEVICE_SERIAL_BAUD_MSB 0x00
-#define CYG_DEVICE_SERIAL_BAUD_LSB 0x0C
-#endif
-#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==19200
-#define CYG_DEVICE_SERIAL_BAUD_MSB 0x00
-#define CYG_DEVICE_SERIAL_BAUD_LSB 0x06
-#endif
-#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==38400
-#define CYG_DEVICE_SERIAL_BAUD_MSB 0x00
-#define CYG_DEVICE_SERIAL_BAUD_LSB 0x03
-#endif
-#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==57600
-#define CYG_DEVICE_SERIAL_BAUD_MSB 0x00
-#define CYG_DEVICE_SERIAL_BAUD_LSB 0x02
-#endif
-#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==115200
-#define CYG_DEVICE_SERIAL_BAUD_MSB 0x00
-#define CYG_DEVICE_SERIAL_BAUD_LSB 0x01
-#endif
-
-#ifndef CYG_DEVICE_SERIAL_BAUD_MSB
-#error Missing/incorrect serial baud rate defined - CDL error?
-#endif
-
-// Define the serial registers.
-#define CYG_DEV_RBR 0x00 // receiver buffer register, read, dlab = 0
-#define CYG_DEV_THR 0x00 // transmitter holding register, write, dlab = 0
-#define CYG_DEV_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
-#define CYG_DEV_IER 0x01 // interrupt enable register, read/write, dlab = 0
-#define CYG_DEV_DLM 0x01 // divisor latch (MS), read/write, dlab = 1
-#define CYG_DEV_IIR 0x02 // interrupt identification register, read, dlab = 0
-#define CYG_DEV_FCR 0x02 // fifo control register, write, dlab = 0
-#define CYG_DEV_LCR 0x03 // line control register, read/write
-#define CYG_DEV_MCR 0x04 // modem control register, read/write
-#define CYG_DEV_LSR 0x05 // line status register, read
-#define CYG_DEV_MSR 0x06 // modem status register, read
-
-// Interrupt Enable Register
-#define SIO_IER_RCV 0x01
-#define SIO_IER_XMT 0x02
-#define SIO_IER_LS 0x04
-#define SIO_IER_MS 0x08
-
-// 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
-
-// Modem Control Register
-#define SIO_MCR_DTR 0x01
-#define SIO_MCR_RTS 0x02
-#define SIO_MCR_INT 0x08 // Enable interrupts
-
-//=============================================================================
-// Basic channel functions
-
-static void
-cyg_hal_plf_serial_init_channel(void* __ch_data)
-{
- cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
- cyg_uint8 lsr;
-
- HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);
- HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);
- HAL_WRITE_UINT8(base+CYG_DEV_MCR, 0);
-
- HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_DLAB);
- HAL_WRITE_UINT8(base+CYG_DEV_DLL, CYG_DEVICE_SERIAL_BAUD_LSB);
- HAL_WRITE_UINT8(base+CYG_DEV_DLM, CYG_DEVICE_SERIAL_BAUD_MSB);
- // 8-1-no parity.
- HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
-
- // Test whether the channel is valid or not. If the status
- // register reads back all ones, its a fair bet that it is not
- // actually there!
- HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
- ((channel_data_t*)__ch_data)->valid = (lsr != 0xFF);
-
- HAL_WRITE_UINT8(base+CYG_DEV_FCR, 0x07); // Enable & clear FIFO
-}
-
-//-----------------------------------------------------------------------------
-
-void
-cyg_hal_plf_serial_putc(void *__ch_data, char c)
-{
- cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
- cyg_uint8 lsr;
-
- if( !((channel_data_t*)__ch_data)->valid )
- return;
-
- CYGARC_HAL_SAVE_GP();
- do {
- HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
- } while ((lsr & SIO_LSR_THRE) == 0);
-
- HAL_WRITE_UINT8(base+CYG_DEV_THR, c);
-
- CYGARC_HAL_RESTORE_GP();
-}
-
-//-----------------------------------------------------------------------------
-
-static cyg_bool
-cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
-{
- cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
- cyg_uint8 lsr;
-
- if( !((channel_data_t*)__ch_data)->valid )
- return false;
-
- HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
- if ((lsr & SIO_LSR_DR) == 0)
- return false;
-
- HAL_READ_UINT8(base+CYG_DEV_RBR, *ch);
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-
-cyg_uint8
-cyg_hal_plf_serial_getc(void* __ch_data)
-{
- cyg_uint8 ch;
-
- if( !((channel_data_t*)__ch_data)->valid )
- return '\n';
-
- CYGARC_HAL_SAVE_GP();
-
- while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
-
- CYGARC_HAL_RESTORE_GP();
-
- return ch;
-}
-
-//=============================================================================
-// Call IF support
-
-#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 cyg_bool
-cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
-{
- int delay_count;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- cyg_bool res;
- CYGARC_HAL_SAVE_GP();
-
- delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
-
- for(;;) {
- res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
- if (res || 0 == delay_count--)
- break;
-
- CYGACC_CALL_IF_DELAY_US(100);
- }
-
- CYGARC_HAL_RESTORE_GP();
- return res;
-}
-
-
-static int
-cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
-{
- static int irq_state = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- int ret = 0;
- CYGARC_HAL_SAVE_GP();
-
- switch (__func) {
- case __COMMCTL_IRQ_ENABLE:
- irq_state = 1;
-
- HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, SIO_IER_RCV);
- HAL_WRITE_UINT8(chan->base+CYG_DEV_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS);
-
- HAL_INTERRUPT_UNMASK(chan->isr_vector);
- break;
- case __COMMCTL_IRQ_DISABLE:
- ret = irq_state;
- irq_state = 0;
-
- HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, 0);
-
- HAL_INTERRUPT_MASK(chan->isr_vector);
- break;
- case __COMMCTL_DBG_ISR_VECTOR:
- ret = chan->isr_vector;
- break;
- case __COMMCTL_SET_TIMEOUT:
- {
- va_list ap;
-
- va_start(ap, __func);
-
- ret = chan->msec_timeout;
- chan->msec_timeout = va_arg(ap, cyg_uint32);
-
- va_end(ap);
- }
- default:
- break;
- }
-
-
- CYGARC_HAL_RESTORE_GP();
- return ret;
-}
-
-static int
-cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
- CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
-{
- int res = 0;
- channel_data_t* chan = (channel_data_t*)__ch_data;
- char c;
- cyg_uint8 lsr;
- CYGARC_HAL_SAVE_GP();
-
- cyg_drv_interrupt_acknowledge(chan->isr_vector);
-
- *__ctrlc = 0;
- HAL_READ_UINT8(chan->base+CYG_DEV_LSR, lsr);
- if ( (lsr & SIO_LSR_DR) != 0 ) {
-
- HAL_READ_UINT8(chan->base+CYG_DEV_RBR, c);
- if( cyg_hal_is_break( &c , 1 ) )
- *__ctrlc = 1;
-
- }
-
- res = CYG_ISR_HANDLED;
-
- CYGARC_HAL_RESTORE_GP();
- return res;
-}
-
-void cyg_hal_plf_serial_init(void)
-{
- hal_virtual_comm_table_t* comm;
- int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
- int i, num_serial = CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;
-
-#ifdef CYGSEM_HAL_I386_PC_DIAG_SCREEN
- --num_serial;
-#endif
-
- for (i = 0; i < num_serial; i++) {
- // Disable interrupts.
- HAL_INTERRUPT_MASK(pc_ser_channels[i].isr_vector);
-
- // Init
- cyg_hal_plf_serial_init_channel(&pc_ser_channels[i]);
-
- // Setup procs in the vector table
-
- // Set channel 0
- CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
- comm = CYGACC_CALL_IF_CONSOLE_PROCS();
- CYGACC_COMM_IF_CH_DATA_SET(*comm, &pc_ser_channels[i]);
- 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);
- CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
- CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
- }
-
- // Restore original console
- CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
-}
-
-#endif //defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
- // || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-
-//-----------------------------------------------------------------------------
-// End of pcmb_serial.c
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [RFC] Generic serial 8250/16x50 diagnostics support
2005-09-19 14:58 [RFC] Generic serial 8250/16x50 diagnostics support David Vrabel
@ 2005-10-07 13:55 ` David Vrabel
0 siblings, 0 replies; 2+ messages in thread
From: David Vrabel @ 2005-10-07 13:55 UTC (permalink / raw)
To: ecos
David Vrabel wrote:
>
> ...implemented generic support for diagnostics via 8250 UARTs.
I there really no interest in this? I've found it useful.
David Vrabel
--
David Vrabel, Design Engineer
Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2005-10-07 13:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-19 14:58 [RFC] Generic serial 8250/16x50 diagnostics support David Vrabel
2005-10-07 13:55 ` David Vrabel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).