mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-24 12:54:24 +08:00
LEON3: new Console driver, APBUART driver using Driver Manager
This patch reimplements the console driver of the LEON3 BSP, it has split up the console driver in two parts: Console driver and UART driver. Before the only UART supported was APBUART and only on-chip APBUARTs found during startup. However splitting the driver in two allows any UART interface to reuse the termios attach code of the console driver, pratically this has always been a problem when discovering APBUARTs after startup for example the PCI board GR-RASTA-IO has APBUARTs and must wait until after PCI has been setup. Since the only current driver that supports the new console driver uses the Driver Manager, the new console driver is only enabled when Driver Manager is initialized during startup. The new APBUART driver supports: * polling mode * interrupt mode * task-driven mode * set UART attributes * read UART attributes (system console inherit settings from boot loader) * Driver manager for finding/initialization of the hardware
This commit is contained in:
@@ -49,7 +49,10 @@ EXTRA_DIST += shared/include/grspw.h
|
||||
EXTRA_DIST += shared/include/grspw_pci.h
|
||||
EXTRA_DIST += shared/include/grspw_rasta.h
|
||||
|
||||
# UART (APBUART)
|
||||
# UART
|
||||
EXTRA_DIST += shared/uart/cons.c
|
||||
EXTRA_DIST += shared/uart/apbuart_cons.c
|
||||
EXTRA_DIST += shared/include/cons.h
|
||||
EXTRA_DIST += shared/uart/apbuart.c
|
||||
EXTRA_DIST += shared/uart/apbuart_pci.c
|
||||
EXTRA_DIST += shared/uart/apbuart_rasta.c
|
||||
|
||||
@@ -79,6 +79,9 @@ libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
|
||||
# console
|
||||
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
libbsp_a_SOURCES += console/console.c
|
||||
libbsp_a_SOURCES += ../../sparc/shared/uart/cons.c
|
||||
libbsp_a_SOURCES += ../../sparc/shared/uart/apbuart_cons.c
|
||||
include_HEADERS += ../../sparc/shared/include/cons.h
|
||||
# debugio
|
||||
libbsp_a_SOURCES += console/printk_support.c
|
||||
|
||||
|
||||
@@ -255,6 +255,7 @@ extern const unsigned char LEON3_irq_to_cpu[32];
|
||||
* image bigger.
|
||||
*/
|
||||
#define AMBAPPBUS_INFO_AVAIL /* AMBAPP Bus driver */
|
||||
#define APBUART_INFO_AVAIL /* APBUART Console driver */
|
||||
#define GPTIMER_INFO_AVAIL /* GPTIMER Timer driver */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -86,6 +86,43 @@ extern "C" {
|
||||
#define LEON_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */
|
||||
/* 0 = no function */
|
||||
|
||||
/*
|
||||
* The following defines the bits in the UART Control Registers.
|
||||
*/
|
||||
|
||||
#define LEON_REG_UART_CONTROL_RTD 0x000000FF /* RX/TX data */
|
||||
|
||||
/*
|
||||
* The following defines the bits in the LEON UART Status Register.
|
||||
*/
|
||||
|
||||
#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
|
||||
#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
|
||||
#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
|
||||
#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
|
||||
#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
|
||||
#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
|
||||
#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
|
||||
#define LEON_REG_UART_STATUS_TF 0x00000200 /* FIFO Full */
|
||||
#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
|
||||
|
||||
/*
|
||||
* The following defines the bits in the LEON UART Control Register.
|
||||
*/
|
||||
|
||||
#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
|
||||
#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
|
||||
#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
|
||||
#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
|
||||
#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
|
||||
#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
|
||||
#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
|
||||
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
|
||||
#define LEON_REG_UART_CTRL_DB 0x00000800 /* Debug FIFO enable */
|
||||
#define LEON_REG_UART_CTRL_SI 0x00004000 /* TX shift register empty IRQ enable */
|
||||
#define LEON_REG_UART_CTRL_FA 0x80000000 /* FIFO Available */
|
||||
#define LEON_REG_UART_CTRL_FA_BIT 31
|
||||
|
||||
/*
|
||||
* The following defines the bits in the LEON Cache Control Register.
|
||||
*/
|
||||
|
||||
@@ -109,6 +109,10 @@ $(PROJECT_INCLUDE)/tlib.h: ../../sparc/shared/include/tlib.h $(PROJECT_INCLUDE)/
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tlib.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tlib.h
|
||||
|
||||
$(PROJECT_INCLUDE)/cons.h: ../../sparc/shared/include/cons.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/cons.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/cons.h
|
||||
|
||||
$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Console driver interface to UART drivers
|
||||
*
|
||||
* - First console device that has System Console flag set will be
|
||||
* system console.
|
||||
* - If none of the registered console devices has system console set,
|
||||
* the first is registered device is used, unless it has
|
||||
*
|
||||
* COPYRIGHT (c) 2010.
|
||||
* Cobham Gaisler AB.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef __CONS_H__
|
||||
#define __CONS_H__
|
||||
|
||||
struct console_dev;
|
||||
|
||||
#define CONSOLE_FLAG_SYSCON 0x01
|
||||
|
||||
struct console_cons_ops {
|
||||
void (*get_uart_attrs)(struct console_dev *, struct termios *t);
|
||||
};
|
||||
|
||||
struct console_dev {
|
||||
/* Set to non-zero if this UART should be system console and/or
|
||||
* debug console.
|
||||
*/
|
||||
int flags;
|
||||
char *fsname; /* File system prefix */
|
||||
const struct rtems_termios_callbacks *callbacks; /* TERMIOS Callbacks */
|
||||
struct console_cons_ops ops;
|
||||
};
|
||||
|
||||
extern void console_dev_register(struct console_dev *dev);
|
||||
#if 0
|
||||
extern void console_dev_unregister(struct console_dev *dev);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@ extern "C" {
|
||||
DRIVER_ID(DRVMGR_BUS_TYPE_AMBAPP, ((((vendor) & 0xff) << 16) | ((device) & 0xfff)))
|
||||
|
||||
/*** Gaisler Hardware Device Driver IDs ***/
|
||||
#define DRIVER_AMBAPP_GAISLER_APBUART_ID DRIVER_AMBAPP_ID(VENDOR_GAISLER, GAISLER_APBUART)
|
||||
#define DRIVER_AMBAPP_GAISLER_GPTIMER_ID DRIVER_AMBAPP_ID(VENDOR_GAISLER, GAISLER_GPTIMER)
|
||||
|
||||
struct amba_dev_id {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,189 @@
|
||||
/* This file contains the TTY driver for the serial ports. The driver
|
||||
* is layered so that different UART hardware can be used. It is implemented
|
||||
* using the Driver Manager.
|
||||
*
|
||||
* This driver uses the termios pseudo driver.
|
||||
*
|
||||
* COPYRIGHT (c) 2010.
|
||||
* Cobham Gaisler AB.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <cons.h>
|
||||
|
||||
#ifdef RTEMS_DRVMGR_STARTUP
|
||||
|
||||
/* Note that it is not possible to use the interrupt mode of the driver
|
||||
* together with the "old" APBUART and -u to GRMON. However the new
|
||||
* APBUART core (from 1.0.17-b2710) has the GRMON debug bit and can
|
||||
* handle interrupts.
|
||||
*/
|
||||
|
||||
int console_initialized = 0;
|
||||
rtems_device_major_number console_major = 0;
|
||||
|
||||
#define FLAG_SYSCON 0x01
|
||||
struct console_priv {
|
||||
unsigned char flags; /* 0x1=SystemConsole */
|
||||
unsigned char minor;
|
||||
struct console_dev *dev;
|
||||
};
|
||||
|
||||
#define CONSOLE_MAX BSP_NUMBER_OF_TERMIOS_PORTS
|
||||
struct console_priv cons[CONSOLE_MAX] = {{0,0},};
|
||||
|
||||
/* Register Console to TERMIOS layer and initialize it */
|
||||
void console_dev_init(struct console_priv *con, int minor)
|
||||
{
|
||||
char name[16], *fsname;
|
||||
rtems_status_code status;
|
||||
|
||||
if (!con->dev->fsname) {
|
||||
strcpy(name, "/dev/console_a");
|
||||
/* Special console name and MINOR for SYSTEM CONSOLE */
|
||||
if (minor == 0)
|
||||
name[12] = '\0'; /* /dev/console */
|
||||
name[13] += minor; /* when minor=0, this has no effect... */
|
||||
fsname = name;
|
||||
} else {
|
||||
fsname = con->dev->fsname;
|
||||
}
|
||||
status = rtems_io_register_name(fsname, console_major, minor);
|
||||
if ((minor == 0) && (status != RTEMS_SUCCESSFUL))
|
||||
rtems_fatal_error_occurred(status);
|
||||
}
|
||||
|
||||
void console_dev_register(struct console_dev *dev)
|
||||
{
|
||||
int i, minor = 0;
|
||||
struct console_priv *con = NULL;
|
||||
|
||||
if ((dev->flags & CONSOLE_FLAG_SYSCON) && !cons[0].dev) {
|
||||
con = &cons[0];
|
||||
con->flags = FLAG_SYSCON;
|
||||
} else {
|
||||
for (i=1; i<CONSOLE_MAX; i++) {
|
||||
if (!cons[i].dev) {
|
||||
con = &cons[i];
|
||||
con->flags = 0;
|
||||
minor = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (con == NULL) {
|
||||
/* Not enough console structures */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Assign Console */
|
||||
con->dev = dev;
|
||||
con->minor = minor;
|
||||
|
||||
/* Console layer is already initialized, that means that we can
|
||||
* register termios interface directly.
|
||||
*/
|
||||
if (console_initialized)
|
||||
console_dev_init(con, minor);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void console_dev_unregister(struct console_dev *dev)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
console_major = major;
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
/* Register all Console a file system device node */
|
||||
for (i=0; i<CONSOLE_MAX; i++) {
|
||||
if (cons[i].dev)
|
||||
console_dev_init(&cons[i], i);
|
||||
}
|
||||
|
||||
console_initialized = 1;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
rtems_status_code status;
|
||||
struct termios term;
|
||||
|
||||
if ((minor >= CONSOLE_MAX) || !cons[minor].dev)
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
status = rtems_termios_open(
|
||||
major,
|
||||
(int)cons[minor].dev,
|
||||
arg,
|
||||
cons[minor].dev->callbacks);
|
||||
|
||||
/* Inherit UART hardware parameters from bootloader on system console */
|
||||
if ((status == RTEMS_SUCCESSFUL) && (cons[minor].flags & FLAG_SYSCON) &&
|
||||
(cons[minor].dev->ops.get_uart_attrs != NULL)) {
|
||||
if (tcgetattr(STDIN_FILENO, &term) >= 0) {
|
||||
cons[minor].dev->ops.get_uart_attrs(cons[minor].dev,
|
||||
&term);
|
||||
term.c_oflag |= ONLCR;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &term);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return rtems_termios_close(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return rtems_termios_read(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return rtems_termios_write(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return rtems_termios_ioctl(arg);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user